Merge branch 'master' of github.com:grpc/grpc
diff --git a/BUILD b/BUILD
index aa12700..9fee908 100644
--- a/BUILD
+++ b/BUILD
@@ -527,13 +527,13 @@
         "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/bdp_estimator.c",
         "src/core/lib/transport/service_config.c",
         "src/core/lib/transport/static_metadata.c",
         "src/core/lib/transport/status_conversion.c",
@@ -634,6 +634,7 @@
         "src/core/lib/surface/lame_client.h",
         "src/core/lib/surface/server.h",
         "src/core/lib/surface/validate_metadata.h",
+        "src/core/lib/transport/bdp_estimator.h",
         "src/core/lib/transport/byte_stream.h",
         "src/core/lib/transport/connectivity_state.h",
         "src/core/lib/transport/error_utils.h",
@@ -641,7 +642,6 @@
         "src/core/lib/transport/metadata.h",
         "src/core/lib/transport/metadata_batch.h",
         "src/core/lib/transport/pid_controller.h",
-        "src/core/lib/transport/bdp_estimator.h",
         "src/core/lib/transport/service_config.h",
         "src/core/lib/transport/static_metadata.h",
         "src/core/lib/transport/status_conversion.h",
@@ -657,6 +657,7 @@
         "include/grpc/byte_buffer.h",
         "include/grpc/byte_buffer_reader.h",
         "include/grpc/compression.h",
+        "include/grpc/load_reporting.h",
         "include/grpc/grpc.h",
         "include/grpc/grpc_posix.h",
         "include/grpc/grpc_security_constants.h",
@@ -870,8 +871,8 @@
         "src/core/lib/security/credentials/plugin/plugin_credentials.c",
         "src/core/lib/security/credentials/ssl/ssl_credentials.c",
         "src/core/lib/security/transport/client_auth_filter.c",
-        "src/core/lib/security/transport/secure_endpoint.c",
         "src/core/lib/security/transport/lb_targets_info.c",
+        "src/core/lib/security/transport/secure_endpoint.c",
         "src/core/lib/security/transport/security_connector.c",
         "src/core/lib/security/transport/security_handshaker.c",
         "src/core/lib/security/transport/server_auth_filter.c",
@@ -894,8 +895,8 @@
         "src/core/lib/security/credentials/plugin/plugin_credentials.h",
         "src/core/lib/security/credentials/ssl/ssl_credentials.h",
         "src/core/lib/security/transport/auth_filters.h",
-        "src/core/lib/security/transport/secure_endpoint.h",
         "src/core/lib/security/transport/lb_targets_info.h",
+        "src/core/lib/security/transport/secure_endpoint.h",
         "src/core/lib/security/transport/security_connector.h",
         "src/core/lib/security/transport/security_handshaker.h",
         "src/core/lib/security/transport/tsi_error.h",
@@ -1132,6 +1133,10 @@
         "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",
@@ -1148,6 +1153,8 @@
         "src/cpp/client/create_channel_internal.h",
         "src/cpp/common/channel_filter.h",
         "src/cpp/server/dynamic_thread_pool.h",
+        "src/cpp/server/health/default_health_check_service.h",
+        "src/cpp/server/health/health.pb.h",
         "src/cpp/server/thread_pool_interface.h",
         "src/cpp/thread_manager/thread_manager.h",
     ],
@@ -1159,9 +1166,11 @@
         "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",
@@ -1269,13 +1278,13 @@
 
 grpc_cc_library(
     name = "grpc++_config_proto",
+    external_deps = [
+        "protobuf",
+    ],
     language = "c++",
     public_hdrs = [
         "include/grpc++/impl/codegen/config_protobuf.h",
     ],
-    external_deps = [
-        "protobuf",
-    ],
 )
 
 grpc_cc_library(
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 87e0382..aa09707 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -597,6 +597,7 @@
 add_dependencies(buildtests_cxx grpc_tool_test)
 add_dependencies(buildtests_cxx grpclb_api_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)
 add_dependencies(buildtests_cxx http2_client)
 endif()
@@ -1089,6 +1090,7 @@
   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
@@ -1366,6 +1368,7 @@
   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
@@ -1589,6 +1592,7 @@
   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
@@ -1911,6 +1915,7 @@
   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
@@ -2057,6 +2062,10 @@
   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
@@ -2110,9 +2119,11 @@
   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
@@ -2237,6 +2248,10 @@
   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
@@ -2474,9 +2489,11 @@
   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
@@ -2565,6 +2582,7 @@
   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
@@ -2706,46 +2724,6 @@
 
 if (gRPC_BUILD_TESTS)
 
-add_library(grpc++_test
-  src/cpp/test/server_context_test_spouse.cc
-)
-
-if(WIN32 AND MSVC)
-  set_target_properties(grpc++_test PROPERTIES COMPILE_PDB_NAME "grpc++_test"
-    COMPILE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}"
-  )
-  if (gRPC_INSTALL)
-    install(FILES ${CMAKE_CURRENT_BINARY_DIR}/grpc++_test.pdb
-      DESTINATION ${CMAKE_INSTALL_LIBDIR} OPTIONAL
-    )
-  endif()
-endif()
-
-
-target_include_directories(grpc++_test
-  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 ${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++_test
-  ${_gRPC_PROTOBUF_LIBRARIES}
-  ${_gRPC_ALLTARGETS_LIBRARIES}
-  grpc++
-)
-
-
-endif (gRPC_BUILD_TESTS)
-if (gRPC_BUILD_TESTS)
-
 add_library(grpc++_test_config
   test/cpp/util/test_config_cc.cc
 )
@@ -2786,6 +2764,10 @@
 if (gRPC_BUILD_TESTS)
 
 add_library(grpc++_test_util
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/health/v1/health.pb.cc
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/health/v1/health.grpc.pb.cc
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/health/v1/health.pb.h
+  ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/health/v1/health.grpc.pb.h
   ${_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
@@ -2819,6 +2801,9 @@
 endif()
 
 protobuf_generate_grpc_cpp(
+  src/proto/grpc/health/v1/health.proto
+)
+protobuf_generate_grpc_cpp(
   src/proto/grpc/testing/echo_messages.proto
 )
 protobuf_generate_grpc_cpp(
@@ -2934,6 +2919,10 @@
   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
@@ -2987,9 +2976,11 @@
   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
@@ -8541,6 +8532,41 @@
 
 endif (gRPC_BUILD_TESTS)
 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
+)
+
+
+target_include_directories(health_service_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 ${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(health_service_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)
 if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
 
 add_executable(http2_client
@@ -9373,7 +9399,6 @@
   ${_gRPC_PROTOBUF_LIBRARIES}
   ${_gRPC_ALLTARGETS_LIBRARIES}
   grpc_test_util
-  grpc++_test
   grpc++
   grpc
   gpr_test_util
diff --git a/Makefile b/Makefile
index 84a60d5..8f92816 100644
--- a/Makefile
+++ b/Makefile
@@ -1072,6 +1072,7 @@
 grpc_tool_test: $(BINDIR)/$(CONFIG)/grpc_tool_test
 grpclb_api_test: $(BINDIR)/$(CONFIG)/grpclb_api_test
 grpclb_test: $(BINDIR)/$(CONFIG)/grpclb_test
+health_service_end2end_test: $(BINDIR)/$(CONFIG)/health_service_end2end_test
 http2_client: $(BINDIR)/$(CONFIG)/http2_client
 hybrid_end2end_test: $(BINDIR)/$(CONFIG)/hybrid_end2end_test
 interop_client: $(BINDIR)/$(CONFIG)/interop_client
@@ -1258,9 +1259,9 @@
 pc_cxx_unsecure: $(LIBDIR)/$(CONFIG)/pkgconfig/grpc++_unsecure.pc
 
 ifeq ($(EMBED_OPENSSL),true)
-privatelibs_cxx:  $(LIBDIR)/$(CONFIG)/libgrpc++_proto_reflection_desc_db.a $(LIBDIR)/$(CONFIG)/libgrpc++_test.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libhttp2_client_main.a $(LIBDIR)/$(CONFIG)/libinterop_client_helper.a $(LIBDIR)/$(CONFIG)/libinterop_client_main.a $(LIBDIR)/$(CONFIG)/libinterop_server_helper.a $(LIBDIR)/$(CONFIG)/libinterop_server_lib.a $(LIBDIR)/$(CONFIG)/libinterop_server_main.a $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl_aes_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_asn1_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_base64_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_bio_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_bn_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_bytestring_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_chacha_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_aead_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_cipher_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_cmac_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ed25519_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_spake25519_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_x25519_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_dh_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_digest_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ec_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ecdh_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ecdsa_sign_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ecdsa_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ecdsa_verify_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_err_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_evp_extra_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_evp_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_pbkdf_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_hmac_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_gcm_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_newhope_statistical_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_newhope_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_newhope_vectors_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_obj_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_pkcs12_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_pkcs8_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_poly1305_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_rsa_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_x509_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ssl_test_lib.a $(LIBDIR)/$(CONFIG)/libbenchmark.a
+privatelibs_cxx:  $(LIBDIR)/$(CONFIG)/libgrpc++_proto_reflection_desc_db.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libhttp2_client_main.a $(LIBDIR)/$(CONFIG)/libinterop_client_helper.a $(LIBDIR)/$(CONFIG)/libinterop_client_main.a $(LIBDIR)/$(CONFIG)/libinterop_server_helper.a $(LIBDIR)/$(CONFIG)/libinterop_server_lib.a $(LIBDIR)/$(CONFIG)/libinterop_server_main.a $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl_aes_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_asn1_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_base64_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_bio_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_bn_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_bytestring_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_chacha_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_aead_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_cipher_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_cmac_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ed25519_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_spake25519_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_x25519_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_dh_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_digest_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ec_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ecdh_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ecdsa_sign_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ecdsa_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ecdsa_verify_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_err_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_evp_extra_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_evp_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_pbkdf_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_hmac_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_gcm_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_newhope_statistical_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_newhope_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_newhope_vectors_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_obj_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_pkcs12_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_pkcs8_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_poly1305_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_rsa_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_x509_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ssl_test_lib.a $(LIBDIR)/$(CONFIG)/libbenchmark.a
 else
-privatelibs_cxx:  $(LIBDIR)/$(CONFIG)/libgrpc++_proto_reflection_desc_db.a $(LIBDIR)/$(CONFIG)/libgrpc++_test.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libhttp2_client_main.a $(LIBDIR)/$(CONFIG)/libinterop_client_helper.a $(LIBDIR)/$(CONFIG)/libinterop_client_main.a $(LIBDIR)/$(CONFIG)/libinterop_server_helper.a $(LIBDIR)/$(CONFIG)/libinterop_server_lib.a $(LIBDIR)/$(CONFIG)/libinterop_server_main.a $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libbenchmark.a
+privatelibs_cxx:  $(LIBDIR)/$(CONFIG)/libgrpc++_proto_reflection_desc_db.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libhttp2_client_main.a $(LIBDIR)/$(CONFIG)/libinterop_client_helper.a $(LIBDIR)/$(CONFIG)/libinterop_client_main.a $(LIBDIR)/$(CONFIG)/libinterop_server_helper.a $(LIBDIR)/$(CONFIG)/libinterop_server_lib.a $(LIBDIR)/$(CONFIG)/libinterop_server_main.a $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libbenchmark.a
 endif
 
 
@@ -1472,6 +1473,7 @@
   $(BINDIR)/$(CONFIG)/grpc_tool_test \
   $(BINDIR)/$(CONFIG)/grpclb_api_test \
   $(BINDIR)/$(CONFIG)/grpclb_test \
+  $(BINDIR)/$(CONFIG)/health_service_end2end_test \
   $(BINDIR)/$(CONFIG)/http2_client \
   $(BINDIR)/$(CONFIG)/hybrid_end2end_test \
   $(BINDIR)/$(CONFIG)/interop_client \
@@ -1577,6 +1579,7 @@
   $(BINDIR)/$(CONFIG)/grpc_tool_test \
   $(BINDIR)/$(CONFIG)/grpclb_api_test \
   $(BINDIR)/$(CONFIG)/grpclb_test \
+  $(BINDIR)/$(CONFIG)/health_service_end2end_test \
   $(BINDIR)/$(CONFIG)/http2_client \
   $(BINDIR)/$(CONFIG)/hybrid_end2end_test \
   $(BINDIR)/$(CONFIG)/interop_client \
@@ -1860,8 +1863,6 @@
 
 
 flaky_test_c: buildtests_c
-	$(E) "[RUN]     Testing lb_policies_test"
-	$(Q) $(BINDIR)/$(CONFIG)/lb_policies_test || ( echo test lb_policies_test failed ; exit 1 )
 	$(E) "[RUN]     Testing mlog_test"
 	$(Q) $(BINDIR)/$(CONFIG)/mlog_test || ( echo test mlog_test failed ; exit 1 )
 
@@ -1913,6 +1914,8 @@
 	$(Q) $(BINDIR)/$(CONFIG)/grpclb_api_test || ( echo test grpclb_api_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 mock_test"
@@ -2062,6 +2065,21 @@
 	$(Q) echo "$(GRPCXX_UNSECURE_PC_FILE)" | tr , '\n' >$@
 
 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 $@`
+	$(Q) $(PROTOC) -Ithird_party/protobuf/src -I. --cpp_out=$(GENDIR) $<
+
+$(GENDIR)/src/proto/grpc/health/v1/health.grpc.pb.cc: src/proto/grpc/health/v1/health.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/lb/v1/load_balancer.pb.cc: protoc_dep_error
 $(GENDIR)/src/proto/grpc/lb/v1/load_balancer.grpc.pb.cc: protoc_dep_error
 else
@@ -2887,6 +2905,7 @@
     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 \
@@ -3168,6 +3187,7 @@
     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 \
@@ -3394,6 +3414,7 @@
     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 \
@@ -3697,6 +3718,7 @@
     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 \
@@ -3862,6 +3884,10 @@
     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 \
@@ -3882,9 +3908,11 @@
     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 \
@@ -4055,6 +4083,10 @@
     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 \
@@ -4258,9 +4290,11 @@
     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 \
@@ -4349,6 +4383,7 @@
     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 \
@@ -4542,55 +4577,6 @@
 $(OBJDIR)/$(CONFIG)/src/cpp/ext/proto_server_reflection_plugin.o: $(GENDIR)/src/proto/grpc/reflection/v1alpha/reflection.pb.cc $(GENDIR)/src/proto/grpc/reflection/v1alpha/reflection.grpc.pb.cc
 
 
-LIBGRPC++_TEST_SRC = \
-    src/cpp/test/server_context_test_spouse.cc \
-
-PUBLIC_HEADERS_CXX += \
-
-LIBGRPC++_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC++_TEST_SRC))))
-
-
-ifeq ($(NO_SECURE),true)
-
-# You can't build secure libraries if you don't have OpenSSL.
-
-$(LIBDIR)/$(CONFIG)/libgrpc++_test.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++_test.a: protobuf_dep_error
-
-
-else
-
-$(LIBDIR)/$(CONFIG)/libgrpc++_test.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(PROTOBUF_DEP) $(LIBGRPC++_TEST_OBJS) 
-	$(E) "[AR]      Creating $@"
-	$(Q) mkdir -p `dirname $@`
-	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc++_test.a
-	$(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libgrpc++_test.a $(LIBGRPC++_TEST_OBJS) 
-ifeq ($(SYSTEM),Darwin)
-	$(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libgrpc++_test.a
-endif
-
-
-
-
-endif
-
-endif
-
-ifneq ($(NO_SECURE),true)
-ifneq ($(NO_DEPS),true)
--include $(LIBGRPC++_TEST_OBJS:.o=.dep)
-endif
-endif
-
-
 LIBGRPC++_TEST_CONFIG_SRC = \
     test/cpp/util/test_config_cc.cc \
 
@@ -4641,6 +4627,7 @@
 
 
 LIBGRPC++_TEST_UTIL_SRC = \
+    $(GENDIR)/src/proto/grpc/health/v1/health.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.grpc.pb.cc \
     $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc \
     $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc \
     $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc \
@@ -4749,13 +4736,13 @@
 -include $(LIBGRPC++_TEST_UTIL_OBJS:.o=.dep)
 endif
 endif
-$(OBJDIR)/$(CONFIG)/test/cpp/end2end/test_service_impl.o: $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc
-$(OBJDIR)/$(CONFIG)/test/cpp/util/byte_buffer_proto_helper.o: $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc
-$(OBJDIR)/$(CONFIG)/test/cpp/util/create_test_channel.o: $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc
-$(OBJDIR)/$(CONFIG)/test/cpp/util/string_ref_helper.o: $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc
-$(OBJDIR)/$(CONFIG)/test/cpp/util/subprocess.o: $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc
-$(OBJDIR)/$(CONFIG)/test/cpp/util/test_credentials_provider.o: $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc
-$(OBJDIR)/$(CONFIG)/src/cpp/codegen/codegen_init.o: $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc
+$(OBJDIR)/$(CONFIG)/test/cpp/end2end/test_service_impl.o: $(GENDIR)/src/proto/grpc/health/v1/health.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc
+$(OBJDIR)/$(CONFIG)/test/cpp/util/byte_buffer_proto_helper.o: $(GENDIR)/src/proto/grpc/health/v1/health.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc
+$(OBJDIR)/$(CONFIG)/test/cpp/util/create_test_channel.o: $(GENDIR)/src/proto/grpc/health/v1/health.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc
+$(OBJDIR)/$(CONFIG)/test/cpp/util/string_ref_helper.o: $(GENDIR)/src/proto/grpc/health/v1/health.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc
+$(OBJDIR)/$(CONFIG)/test/cpp/util/subprocess.o: $(GENDIR)/src/proto/grpc/health/v1/health.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc
+$(OBJDIR)/$(CONFIG)/test/cpp/util/test_credentials_provider.o: $(GENDIR)/src/proto/grpc/health/v1/health.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc
+$(OBJDIR)/$(CONFIG)/src/cpp/codegen/codegen_init.o: $(GENDIR)/src/proto/grpc/health/v1/health.pb.cc $(GENDIR)/src/proto/grpc/health/v1/health.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc
 
 
 LIBGRPC++_UNSECURE_SRC = \
@@ -4779,6 +4766,10 @@
     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 \
@@ -4799,9 +4790,11 @@
     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 \
@@ -13614,6 +13607,49 @@
 $(OBJDIR)/$(CONFIG)/test/cpp/grpclb/grpclb_test.o: $(GENDIR)/src/proto/grpc/lb/v1/load_balancer.pb.cc $(GENDIR)/src/proto/grpc/lb/v1/load_balancer.grpc.pb.cc
 
 
+HEALTH_SERVICE_END2END_TEST_SRC = \
+    test/cpp/end2end/health_service_end2end_test.cc \
+
+HEALTH_SERVICE_END2END_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(HEALTH_SERVICE_END2END_TEST_SRC))))
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure targets if you don't have OpenSSL.
+
+$(BINDIR)/$(CONFIG)/health_service_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)/health_service_end2end_test: protobuf_dep_error
+
+else
+
+$(BINDIR)/$(CONFIG)/health_service_end2end_test: $(PROTOBUF_DEP) $(HEALTH_SERVICE_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) $(HEALTH_SERVICE_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)/health_service_end2end_test
+
+endif
+
+endif
+
+$(OBJDIR)/$(CONFIG)/test/cpp/end2end/health_service_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_health_service_end2end_test: $(HEALTH_SERVICE_END2END_TEST_OBJS:.o=.dep)
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(HEALTH_SERVICE_END2END_TEST_OBJS:.o=.dep)
+endif
+endif
+
+
 ifeq ($(NO_SECURE),true)
 
 # You can't build secure targets if you don't have OpenSSL.
@@ -14528,16 +14564,16 @@
 
 else
 
-$(BINDIR)/$(CONFIG)/server_context_test_spouse_test: $(PROTOBUF_DEP) $(SERVER_CONTEXT_TEST_SPOUSE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_test.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(BINDIR)/$(CONFIG)/server_context_test_spouse_test: $(PROTOBUF_DEP) $(SERVER_CONTEXT_TEST_SPOUSE_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) $(SERVER_CONTEXT_TEST_SPOUSE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_test.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)/server_context_test_spouse_test
+	$(Q) $(LDXX) $(LDFLAGS) $(SERVER_CONTEXT_TEST_SPOUSE_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)/server_context_test_spouse_test
 
 endif
 
 endif
 
-$(OBJDIR)/$(CONFIG)/test/cpp/test/server_context_test_spouse_test.o:  $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_test.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(OBJDIR)/$(CONFIG)/test/cpp/test/server_context_test_spouse_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_server_context_test_spouse_test: $(SERVER_CONTEXT_TEST_SPOUSE_TEST_OBJS:.o=.dep)
 
@@ -17850,7 +17886,6 @@
 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/test/server_context_test_spouse.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)
diff --git a/WORKSPACE b/WORKSPACE
index 9883109..4f90f06 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -28,6 +28,11 @@
     actual = "@submodule_protobuf//:protoc",
 )
 
+bind(
+    name = "gtest",
+    actual = "@submodule_gtest//:gtest",
+)
+
 new_local_repository(
     name = "submodule_boringssl",
     path = "third_party/boringssl-with-bazel",
@@ -45,3 +50,9 @@
     path = "third_party/protobuf",
     build_file = "third_party/protobuf/BUILD",
 )
+
+new_local_repository(
+    name = "submodule_gtest",
+    path = "third_party/googletest",
+    build_file = "third_party/gtest.BUILD",
+)
diff --git a/build.yaml b/build.yaml
index 48fe927..141526c 100644
--- a/build.yaml
+++ b/build.yaml
@@ -165,6 +165,7 @@
   - 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
@@ -768,9 +769,11 @@
   - 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
@@ -808,6 +811,8 @@
   - src/cpp/client/create_channel_internal.h
   - src/cpp/common/channel_filter.h
   - src/cpp/server/dynamic_thread_pool.h
+  - src/cpp/server/health/default_health_check_service.h
+  - src/cpp/server/health/health.pb.h
   - src/cpp/server/thread_pool_interface.h
   - src/cpp/thread_manager/thread_manager.h
   src:
@@ -828,6 +833,10 @@
   - 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
@@ -897,6 +906,12 @@
   language: c++
   src:
   - src/proto/grpc/reflection/v1alpha/reflection.proto
+- name: grpc++_test
+  language: c++
+  public_headers:
+  - include/grpc++/test/server_context_test_spouse.h
+  deps:
+  - grpc++
 - name: thrift_util
   language: c++
   public_headers:
@@ -1144,15 +1159,6 @@
   - grpc++
   filegroups:
   - grpc++_reflection_proto
-- name: grpc++_test
-  build: private
-  language: c++
-  headers:
-  - include/grpc++/test/server_context_test_spouse.h
-  src:
-  - src/cpp/test/server_context_test_spouse.cc
-  deps:
-  - grpc++
 - name: grpc++_test_config
   build: private
   language: c++
@@ -1171,6 +1177,7 @@
   - test/cpp/util/subprocess.h
   - test/cpp/util/test_credentials_provider.h
   src:
+  - 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
@@ -2350,8 +2357,8 @@
   - gpr
 - name: lb_policies_test
   cpu_cost: 0.1
-  flaky: true
   build: test
+  run: false
   language: c
   src:
   - test/core/client_channel/lb_policies_test.c
@@ -3351,6 +3358,19 @@
   - grpc
   - gpr_test_util
   - gpr
+- name: health_service_end2end_test
+  gtest: true
+  build: test
+  language: c++
+  src:
+  - test/cpp/end2end/health_service_end2end_test.cc
+  deps:
+  - grpc++_test_util
+  - grpc_test_util
+  - grpc++
+  - grpc
+  - gpr_test_util
+  - gpr
 - name: http2_client
   build: test
   run: false
@@ -3684,11 +3704,12 @@
   - test/cpp/test/server_context_test_spouse_test.cc
   deps:
   - grpc_test_util
-  - grpc++_test
   - grpc++
   - grpc
   - gpr_test_util
   - gpr
+  uses:
+  - grpc++_test
 - name: server_crash_test
   gtest: true
   cpu_cost: 0.1
diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec
index 8f9db71..7593103 100644
--- a/gRPC-Core.podspec
+++ b/gRPC-Core.podspec
@@ -162,6 +162,7 @@
                       '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',
diff --git a/grpc.def b/grpc.def
index 5ef59ab..e387c8b 100644
--- a/grpc.def
+++ b/grpc.def
@@ -69,6 +69,7 @@
     grpc_channel_create_registered_call
     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
diff --git a/grpc.gemspec b/grpc.gemspec
index 335021f..82c9d68 100755
--- a/grpc.gemspec
+++ b/grpc.gemspec
@@ -143,6 +143,7 @@
   s.files += %w( include/grpc/grpc.h )
   s.files += %w( include/grpc/grpc_posix.h )
   s.files += %w( include/grpc/grpc_security_constants.h )
+  s.files += %w( include/grpc/load_reporting.h )
   s.files += %w( include/grpc/slice.h )
   s.files += %w( include/grpc/slice_buffer.h )
   s.files += %w( include/grpc/status.h )
diff --git a/src/cpp/test/server_context_test_spouse.cc b/include/grpc++/ext/health_check_service_server_builder_option.h
similarity index 62%
copy from src/cpp/test/server_context_test_spouse.cc
copy to include/grpc++/ext/health_check_service_server_builder_option.h
index b812d16..4861daa 100644
--- a/src/cpp/test/server_context_test_spouse.cc
+++ b/include/grpc++/ext/health_check_service_server_builder_option.h
@@ -31,23 +31,32 @@
  *
  */
 
-#include <grpc++/test/server_context_test_spouse.h>
+#ifndef GRPCXX_EXT_HEALTH_CHECK_SERVICE_SERVER_BUILDER_OPTION_H
+#define GRPCXX_EXT_HEALTH_CHECK_SERVICE_SERVER_BUILDER_OPTION_H
+
+#include <memory>
+
+#include <grpc++/health_check_service_interface.h>
+#include <grpc++/impl/server_builder_option.h>
+#include <grpc++/support/config.h>
 
 namespace grpc {
-namespace testing {
 
-void ServerContextTestSpouse::AddClientMetadata(const grpc::string& key,
-                                                const grpc::string& value) {
-  client_metadata_storage_.insert(
-      std::pair<grpc::string, grpc::string>(key, value));
-  ctx_->client_metadata_.map()->clear();
-  for (auto iter = client_metadata_storage_.begin();
-       iter != client_metadata_storage_.end(); ++iter) {
-    ctx_->client_metadata_.map()->insert(
-        std::pair<grpc::string_ref, grpc::string_ref>(iter->first.c_str(),
-                                                      iter->second.c_str()));
-  }
-}
+class HealthCheckServiceServerBuilderOption : public ServerBuilderOption {
+ public:
+  // The ownership of hc will be taken and transferred to the grpc server.
+  // To explicitly disable default service, pass in a nullptr.
+  explicit HealthCheckServiceServerBuilderOption(
+      std::unique_ptr<HealthCheckServiceInterface> hc);
+  ~HealthCheckServiceServerBuilderOption() override {}
+  void UpdateArguments(ChannelArguments* args) override;
+  void UpdatePlugins(
+      std::vector<std::unique_ptr<ServerBuilderPlugin>>* plugins) override;
 
-}  // namespace testing
+ private:
+  std::unique_ptr<HealthCheckServiceInterface> hc_;
+};
+
 }  // namespace grpc
+
+#endif  // GRPCXX_EXT_HEALTH_CHECK_SERVICE_SERVER_BUILDER_OPTION_H
diff --git a/include/grpc++/health_check_service_interface.h b/include/grpc++/health_check_service_interface.h
new file mode 100644
index 0000000..0eed702
--- /dev/null
+++ b/include/grpc++/health_check_service_interface.h
@@ -0,0 +1,68 @@
+/*
+ *
+ * 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_HEALTH_CHECK_SERVICE_INTERFACE_H
+#define GRPCXX_HEALTH_CHECK_SERVICE_INTERFACE_H
+
+#include <grpc++/support/config.h>
+
+namespace grpc {
+
+const char kHealthCheckServiceInterfaceArg[] =
+    "grpc.health_check_service_interface";
+
+// The gRPC server uses this interface to expose the health checking service
+// without depending on protobuf.
+class HealthCheckServiceInterface {
+ public:
+  virtual ~HealthCheckServiceInterface() {}
+
+  // Set or change the serving status of the given service_name.
+  virtual void SetServingStatus(const grpc::string& service_name,
+                                bool serving) = 0;
+  // Apply to all registered service names.
+  virtual void SetServingStatus(bool serving) = 0;
+};
+
+// Enable/disable the default health checking service. This applies to all C++
+// servers created afterwards. For each server, user can override the default
+// with a HealthCheckServiceServerBuilderOption.
+// NOT thread safe.
+void EnableDefaultHealthCheckService(bool enable);
+
+// NOT thread safe.
+bool DefaultHealthCheckServiceEnabled();
+
+}  // namespace grpc
+
+#endif  // GRPCXX_HEALTH_CHECK_SERVICE_INTERFACE_H
diff --git a/include/grpc++/impl/codegen/call.h b/include/grpc++/impl/codegen/call.h
index a17cdf9..19a5ca2 100644
--- a/include/grpc++/impl/codegen/call.h
+++ b/include/grpc++/impl/codegen/call.h
@@ -618,7 +618,17 @@
  public:
   /* call is owned by the caller */
   Call(grpc_call* call, CallHook* call_hook, CompletionQueue* cq)
-      : call_hook_(call_hook), cq_(cq), call_(call) {}
+      : call_hook_(call_hook),
+        cq_(cq),
+        call_(call),
+        max_receive_message_size_(-1) {}
+
+  Call(grpc_call* call, CallHook* call_hook, CompletionQueue* cq,
+       int max_receive_message_size)
+      : call_hook_(call_hook),
+        cq_(cq),
+        call_(call),
+        max_receive_message_size_(max_receive_message_size) {}
 
   void PerformOps(CallOpSetInterface* ops) {
     call_hook_->PerformOpsOnCall(ops, this);
@@ -627,10 +637,13 @@
   grpc_call* call() const { return call_; }
   CompletionQueue* cq() const { return cq_; }
 
+  int max_receive_message_size() const { return max_receive_message_size_; }
+
  private:
   CallHook* call_hook_;
   CompletionQueue* cq_;
   grpc_call* call_;
+  int max_receive_message_size_;
 };
 
 }  // namespace grpc
diff --git a/include/grpc++/impl/codegen/server_context.h b/include/grpc++/impl/codegen/server_context.h
index 8c7fe08..43bbff6 100644
--- a/include/grpc++/impl/codegen/server_context.h
+++ b/include/grpc++/impl/codegen/server_context.h
@@ -36,6 +36,10 @@
 
 #include <map>
 #include <memory>
+#include <vector>
+
+#include <grpc/impl/codegen/compression_types.h>
+#include <grpc/load_reporting.h>
 
 #include <grpc++/impl/codegen/config.h>
 #include <grpc++/impl/codegen/create_auth_context.h>
@@ -43,14 +47,12 @@
 #include <grpc++/impl/codegen/security/auth_context.h>
 #include <grpc++/impl/codegen/string_ref.h>
 #include <grpc++/impl/codegen/time.h>
-#include <grpc/impl/codegen/compression_types.h>
 
 struct grpc_metadata;
 struct grpc_call;
 struct census_context;
 
 namespace grpc {
-
 class ClientContext;
 template <class W, class R>
 class ServerAsyncReader;
@@ -143,6 +145,9 @@
   }
   void set_compression_algorithm(grpc_compression_algorithm algorithm);
 
+  // Set the load reporting costs in \a cost_data for the call.
+  void SetLoadReportingCosts(const std::vector<grpc::string>& cost_data);
+
   std::shared_ptr<const AuthContext> auth_context() const {
     if (auth_context_.get() == nullptr) {
       auth_context_ = CreateAuthContext(call_);
diff --git a/include/grpc++/impl/codegen/sync_stream.h b/include/grpc++/impl/codegen/sync_stream.h
index 1f7708b..4d9b074 100644
--- a/include/grpc++/impl/codegen/sync_stream.h
+++ b/include/grpc++/impl/codegen/sync_stream.h
@@ -160,7 +160,7 @@
   }
 
   bool NextMessageSize(uint32_t* sz) override {
-    *sz = INT_MAX;
+    *sz = call_.max_receive_message_size();
     return true;
   }
 
@@ -310,7 +310,7 @@
   }
 
   bool NextMessageSize(uint32_t* sz) override {
-    *sz = INT_MAX;
+    *sz = call_.max_receive_message_size();
     return true;
   }
 
@@ -382,7 +382,7 @@
   }
 
   bool NextMessageSize(uint32_t* sz) override {
-    *sz = INT_MAX;
+    *sz = call_->max_receive_message_size();
     return true;
   }
 
@@ -474,7 +474,7 @@
   }
 
   bool NextMessageSize(uint32_t* sz) {
-    *sz = INT_MAX;
+    *sz = call_->max_receive_message_size();
     return true;
   }
 
diff --git a/include/grpc++/server.h b/include/grpc++/server.h
index 002f252..3e54405 100644
--- a/include/grpc++/server.h
+++ b/include/grpc++/server.h
@@ -55,12 +55,10 @@
 
 namespace grpc {
 
-class GenericServerContext;
 class AsyncGenericService;
-class ServerAsyncStreamingInterface;
+class HealthCheckServiceInterface;
 class ServerContext;
 class ServerInitializer;
-class ThreadPoolInterface;
 
 /// Models a gRPC server.
 ///
@@ -99,6 +97,11 @@
   // Returns a \em raw pointer to the underlying grpc_server instance.
   grpc_server* c_server();
 
+  /// Returns the health check service.
+  HealthCheckServiceInterface* GetHealthCheckService() const {
+    return health_check_service_.get();
+  }
+
  private:
   friend class AsyncGenericService;
   friend class ServerBuilder;
@@ -216,6 +219,9 @@
   grpc_server* server_;
 
   std::unique_ptr<ServerInitializer> server_initializer_;
+
+  std::unique_ptr<HealthCheckServiceInterface> health_check_service_;
+  bool health_check_service_disabled_;
 };
 
 }  // namespace grpc
diff --git a/include/grpc++/test/server_context_test_spouse.h b/include/grpc++/test/server_context_test_spouse.h
index b248285..bac0db7 100644
--- a/include/grpc++/test/server_context_test_spouse.h
+++ b/include/grpc++/test/server_context_test_spouse.h
@@ -48,10 +48,23 @@
 
   // Inject client metadata to the ServerContext for the test. The test spouse
   // must be alive when ServerContext::client_metadata is called.
-  void AddClientMetadata(const grpc::string& key, const grpc::string& value);
+  void AddClientMetadata(const grpc::string& key, const grpc::string& value) {
+    client_metadata_storage_.insert(
+        std::pair<grpc::string, grpc::string>(key, value));
+    ctx_->client_metadata_.map()->clear();
+    for (auto iter = client_metadata_storage_.begin();
+         iter != client_metadata_storage_.end(); ++iter) {
+      ctx_->client_metadata_.map()->insert(
+          std::pair<grpc::string_ref, grpc::string_ref>(
+              iter->first.c_str(),
+              grpc::string_ref(iter->second.data(), iter->second.size())));
+    }
+  }
+
   std::multimap<grpc::string, grpc::string> GetInitialMetadata() const {
     return ctx_->initial_metadata_;
   }
+
   std::multimap<grpc::string, grpc::string> GetTrailingMetadata() const {
     return ctx_->trailing_metadata_;
   }
diff --git a/include/grpc/grpc.h b/include/grpc/grpc.h
index 37b823a..1b33d48 100644
--- a/include/grpc/grpc.h
+++ b/include/grpc/grpc.h
@@ -229,14 +229,20 @@
     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
+/** Set census context for a call; Must be called before first call to
    grpc_call_start_batch(). */
 GRPCAPI void grpc_census_call_set_context(grpc_call *call,
                                           struct census_context *context);
 
-/* Retrieve the calls current census context. */
+/** Retrieve the calls current census context. */
 GRPCAPI struct census_context *grpc_census_call_get_context(grpc_call *call);
 
 /** Return a newly allocated string representing the target a channel was
diff --git a/src/cpp/test/server_context_test_spouse.cc b/include/grpc/load_reporting.h
similarity index 63%
copy from src/cpp/test/server_context_test_spouse.cc
copy to include/grpc/load_reporting.h
index b812d16..c833ce5 100644
--- a/src/cpp/test/server_context_test_spouse.cc
+++ b/include/grpc/load_reporting.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,23 +31,33 @@
  *
  */
 
-#include <grpc++/test/server_context_test_spouse.h>
+#ifndef GRPC_LOAD_REPORTING_H
+#define GRPC_LOAD_REPORTING_H
 
-namespace grpc {
-namespace testing {
+#include <grpc/impl/codegen/port_platform.h>
+#include <grpc/slice.h>
 
-void ServerContextTestSpouse::AddClientMetadata(const grpc::string& key,
-                                                const grpc::string& value) {
-  client_metadata_storage_.insert(
-      std::pair<grpc::string, grpc::string>(key, value));
-  ctx_->client_metadata_.map()->clear();
-  for (auto iter = client_metadata_storage_.begin();
-       iter != client_metadata_storage_.end(); ++iter) {
-    ctx_->client_metadata_.map()->insert(
-        std::pair<grpc::string_ref, grpc::string_ref>(iter->first.c_str(),
-                                                      iter->second.c_str()));
-  }
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Metadata key for the gRPC LB load balancer token.
+ *
+ * The value corresponding to this key is an opaque token that is given to the
+ * frontend as part of each pick; the frontend sends this token to the backend
+ * in each request it sends when using that pick. The token is used by the
+ * backend to verify the request and to allow the backend to report load to the
+ * 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;
+
+#ifdef __cplusplus
 }
+#endif
 
-}  // namespace testing
-}  // namespace grpc
+#endif /* GRPC_LOAD_REPORTING_H */
diff --git a/include/grpc/support/useful.h b/include/grpc/support/useful.h
index 003e096..9d8314e 100644
--- a/include/grpc/support/useful.h
+++ b/include/grpc/support/useful.h
@@ -74,4 +74,7 @@
 
 #define GPR_ICMP(a, b) ((a) < (b) ? -1 : ((a) > (b) ? 1 : 0))
 
+#define GPR_HASH_POINTER(x, range) \
+  ((((size_t)x) >> 4) ^ (((size_t)x) >> 9) ^ (((size_t)x) >> 14)) % (range)
+
 #endif /* GRPC_SUPPORT_USEFUL_H */
diff --git a/package.xml b/package.xml
index 6250c78..e4db6a7 100644
--- a/package.xml
+++ b/package.xml
@@ -152,6 +152,7 @@
     <file baseinstalldir="/" name="include/grpc/grpc.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/grpc_posix.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/grpc_security_constants.h" role="src" />
+    <file baseinstalldir="/" name="include/grpc/load_reporting.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/slice.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/slice_buffer.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/status.h" role="src" />
diff --git a/src/core/ext/client_channel/client_channel.c b/src/core/ext/client_channel/client_channel.c
index 06038bb..62fb061 100644
--- a/src/core/ext/client_channel/client_channel.c
+++ b/src/core/ext/client_channel/client_channel.c
@@ -51,6 +51,7 @@
 #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"
 #include "src/core/lib/profiling/timers.h"
@@ -160,13 +161,10 @@
   /** client channel factory */
   grpc_client_channel_factory *client_channel_factory;
 
-  /** mutex protecting all variables below in this data structure */
-  gpr_mu mu;
+  /** combiner protecting all variables below in this data structure */
+  grpc_combiner *combiner;
   /** currently active load balancer */
-  char *lb_policy_name;
   grpc_lb_policy *lb_policy;
-  /** service config in JSON form */
-  char *service_config_json;
   /** maps method names to method_parameters structs */
   grpc_slice_hash_table *method_params_table;
   /** incoming resolver result - set by resolver.next() */
@@ -183,6 +181,13 @@
   grpc_channel_stack *owning_stack;
   /** interested parties (owned) */
   grpc_pollset_set *interested_parties;
+
+  /* the following properties are guarded by a mutex since API's require them
+     to be instantaniously available */
+  gpr_mu info_mu;
+  char *info_lb_policy_name;
+  /** service config in JSON form */
+  char *info_service_config_json;
 } channel_data;
 
 /** We create one watcher for each new lb_policy that is returned from a
@@ -218,32 +223,23 @@
 }
 
 static void on_lb_policy_state_changed_locked(grpc_exec_ctx *exec_ctx,
-                                              lb_policy_connectivity_watcher *w,
-                                              grpc_error *error) {
-  grpc_connectivity_state publish_state = w->state;
-  /* check if the notification is for a stale policy */
-  if (w->lb_policy != w->chand->lb_policy) return;
-
-  if (publish_state == GRPC_CHANNEL_SHUTDOWN && w->chand->resolver != NULL) {
-    publish_state = GRPC_CHANNEL_TRANSIENT_FAILURE;
-    grpc_resolver_channel_saw_error(exec_ctx, w->chand->resolver);
-    GRPC_LB_POLICY_UNREF(exec_ctx, w->chand->lb_policy, "channel");
-    w->chand->lb_policy = NULL;
-  }
-  set_channel_connectivity_state_locked(exec_ctx, w->chand, publish_state,
-                                        GRPC_ERROR_REF(error), "lb_changed");
-  if (w->state != GRPC_CHANNEL_SHUTDOWN) {
-    watch_lb_policy(exec_ctx, w->chand, w->lb_policy, w->state);
-  }
-}
-
-static void on_lb_policy_state_changed(grpc_exec_ctx *exec_ctx, void *arg,
-                                       grpc_error *error) {
+                                              void *arg, grpc_error *error) {
   lb_policy_connectivity_watcher *w = arg;
-
-  gpr_mu_lock(&w->chand->mu);
-  on_lb_policy_state_changed_locked(exec_ctx, w, error);
-  gpr_mu_unlock(&w->chand->mu);
+  grpc_connectivity_state publish_state = w->state;
+  /* check if the notification is for the latest policy */
+  if (w->lb_policy == w->chand->lb_policy) {
+    if (publish_state == GRPC_CHANNEL_SHUTDOWN && w->chand->resolver != NULL) {
+      publish_state = GRPC_CHANNEL_TRANSIENT_FAILURE;
+      grpc_resolver_channel_saw_error(exec_ctx, w->chand->resolver);
+      GRPC_LB_POLICY_UNREF(exec_ctx, w->chand->lb_policy, "channel");
+      w->chand->lb_policy = NULL;
+    }
+    set_channel_connectivity_state_locked(exec_ctx, w->chand, publish_state,
+                                          GRPC_ERROR_REF(error), "lb_changed");
+    if (w->state != GRPC_CHANNEL_SHUTDOWN) {
+      watch_lb_policy(exec_ctx, w->chand, w->lb_policy, w->state);
+    }
+  }
 
   GRPC_CHANNEL_STACK_UNREF(exec_ctx, w->chand->owning_stack, "watch_lb_policy");
   gpr_free(w);
@@ -256,16 +252,16 @@
   GRPC_CHANNEL_STACK_REF(chand->owning_stack, "watch_lb_policy");
 
   w->chand = chand;
-  grpc_closure_init(&w->on_changed, on_lb_policy_state_changed, w,
-                    grpc_schedule_on_exec_ctx);
+  grpc_closure_init(&w->on_changed, on_lb_policy_state_changed_locked, w,
+                    grpc_combiner_scheduler(chand->combiner, false));
   w->state = current_state;
   w->lb_policy = lb_policy;
   grpc_lb_policy_notify_on_state_change(exec_ctx, lb_policy, &w->state,
                                         &w->on_changed);
 }
 
-static void on_resolver_result_changed(grpc_exec_ctx *exec_ctx, void *arg,
-                                       grpc_error *error) {
+static void on_resolver_result_changed_locked(grpc_exec_ctx *exec_ctx,
+                                              void *arg, grpc_error *error) {
   channel_data *chand = arg;
   char *lb_policy_name = NULL;
   grpc_lb_policy *lb_policy = NULL;
@@ -353,17 +349,18 @@
                                      chand->interested_parties);
   }
 
-  gpr_mu_lock(&chand->mu);
+  gpr_mu_lock(&chand->info_mu);
   if (lb_policy_name != NULL) {
-    gpr_free(chand->lb_policy_name);
-    chand->lb_policy_name = lb_policy_name;
+    gpr_free(chand->info_lb_policy_name);
+    chand->info_lb_policy_name = lb_policy_name;
   }
   old_lb_policy = chand->lb_policy;
   chand->lb_policy = lb_policy;
   if (service_config_json != NULL) {
-    gpr_free(chand->service_config_json);
-    chand->service_config_json = service_config_json;
+    gpr_free(chand->info_service_config_json);
+    chand->info_service_config_json = service_config_json;
   }
+  gpr_mu_unlock(&chand->info_mu);
   if (chand->method_params_table != NULL) {
     grpc_slice_hash_table_unref(exec_ctx, chand->method_params_table);
   }
@@ -391,7 +388,6 @@
     GRPC_CHANNEL_STACK_REF(chand->owning_stack, "resolver");
     grpc_resolver_next(exec_ctx, chand->resolver, &chand->resolver_result,
                        &chand->on_resolver_result_changed);
-    gpr_mu_unlock(&chand->mu);
   } else {
     if (chand->resolver != NULL) {
       grpc_resolver_shutdown(exec_ctx, chand->resolver);
@@ -404,7 +400,6 @@
         GRPC_ERROR_CREATE_REFERENCING("Got config after disconnection", refs,
                                       GPR_ARRAY_SIZE(refs)),
         "resolver_gone");
-    gpr_mu_unlock(&chand->mu);
   }
 
   if (exit_idle) {
@@ -426,20 +421,12 @@
   GRPC_ERROR_UNREF(state_error);
 }
 
-static void cc_start_transport_op(grpc_exec_ctx *exec_ctx,
-                                  grpc_channel_element *elem,
-                                  grpc_transport_op *op) {
+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];
   channel_data *chand = elem->channel_data;
 
-  grpc_closure_sched(exec_ctx, op->on_consumed, GRPC_ERROR_NONE);
-
-  GPR_ASSERT(op->set_accept_stream == false);
-  if (op->bind_pollset != NULL) {
-    grpc_pollset_set_add_pollset(exec_ctx, chand->interested_parties,
-                                 op->bind_pollset);
-  }
-
-  gpr_mu_lock(&chand->mu);
   if (op->on_connectivity_state_change != NULL) {
     grpc_connectivity_state_notify_on_state_change(
         exec_ctx, &chand->state_tracker, op->connectivity_state,
@@ -482,25 +469,48 @@
     }
     GRPC_ERROR_UNREF(op->disconnect_with_error);
   }
-  gpr_mu_unlock(&chand->mu);
+  GRPC_CHANNEL_STACK_UNREF(exec_ctx, chand->owning_stack, "start_transport_op");
+
+  grpc_closure_sched(exec_ctx, op->on_consumed, GRPC_ERROR_NONE);
+}
+
+static void cc_start_transport_op(grpc_exec_ctx *exec_ctx,
+                                  grpc_channel_element *elem,
+                                  grpc_transport_op *op) {
+  channel_data *chand = elem->channel_data;
+
+  GPR_ASSERT(op->set_accept_stream == false);
+  if (op->bind_pollset != NULL) {
+    grpc_pollset_set_add_pollset(exec_ctx, chand->interested_parties,
+                                 op->bind_pollset);
+  }
+
+  op->transport_private.args[0] = 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)),
+      GRPC_ERROR_NONE);
 }
 
 static void cc_get_channel_info(grpc_exec_ctx *exec_ctx,
                                 grpc_channel_element *elem,
                                 const grpc_channel_info *info) {
   channel_data *chand = elem->channel_data;
-  gpr_mu_lock(&chand->mu);
+  gpr_mu_lock(&chand->info_mu);
   if (info->lb_policy_name != NULL) {
-    *info->lb_policy_name = chand->lb_policy_name == NULL
+    *info->lb_policy_name = chand->info_lb_policy_name == NULL
                                 ? NULL
-                                : gpr_strdup(chand->lb_policy_name);
+                                : gpr_strdup(chand->info_lb_policy_name);
   }
   if (info->service_config_json != NULL) {
-    *info->service_config_json = chand->service_config_json == NULL
-                                     ? NULL
-                                     : gpr_strdup(chand->service_config_json);
+    *info->service_config_json =
+        chand->info_service_config_json == NULL
+            ? NULL
+            : gpr_strdup(chand->info_service_config_json);
   }
-  gpr_mu_unlock(&chand->mu);
+  gpr_mu_unlock(&chand->info_mu);
 }
 
 /* Constructor for channel_data */
@@ -512,11 +522,12 @@
   GPR_ASSERT(args->is_last);
   GPR_ASSERT(elem->filter == &grpc_client_channel_filter);
   // Initialize data members.
-  gpr_mu_init(&chand->mu);
+  chand->combiner = grpc_combiner_create(NULL);
+  gpr_mu_init(&chand->info_mu);
   chand->owning_stack = args->channel_stack;
   grpc_closure_init(&chand->on_resolver_result_changed,
-                    on_resolver_result_changed, chand,
-                    grpc_schedule_on_exec_ctx);
+                    on_resolver_result_changed_locked, chand,
+                    grpc_combiner_scheduler(chand->combiner, false));
   chand->interested_parties = grpc_pollset_set_create();
   grpc_connectivity_state_init(&chand->state_tracker, GRPC_CHANNEL_IDLE,
                                "client_channel");
@@ -565,14 +576,15 @@
                                      chand->interested_parties);
     GRPC_LB_POLICY_UNREF(exec_ctx, chand->lb_policy, "channel");
   }
-  gpr_free(chand->lb_policy_name);
-  gpr_free(chand->service_config_json);
+  gpr_free(chand->info_lb_policy_name);
+  gpr_free(chand->info_service_config_json);
   if (chand->method_params_table != NULL) {
     grpc_slice_hash_table_unref(exec_ctx, chand->method_params_table);
   }
   grpc_connectivity_state_destroy(exec_ctx, &chand->state_tracker);
-  grpc_pollset_set_destroy(chand->interested_parties);
-  gpr_mu_destroy(&chand->mu);
+  grpc_pollset_set_destroy(exec_ctx, chand->interested_parties);
+  GRPC_COMBINER_UNREF(exec_ctx, chand->combiner, "client_channel");
+  gpr_mu_destroy(&chand->info_mu);
 }
 
 /*************************************************************************
@@ -615,8 +627,6 @@
       grpc_subchannel_call */
   gpr_atm subchannel_call;
 
-  gpr_mu mu;
-
   subchannel_creation_phase creation_phase;
   grpc_connected_subchannel *connected_subchannel;
   grpc_polling_entity *pollent;
@@ -661,52 +671,32 @@
   GRPC_ERROR_UNREF(error);
 }
 
-typedef struct {
-  grpc_transport_stream_op **ops;
-  size_t nops;
-  grpc_subchannel_call *call;
-} retry_ops_args;
-
-static void retry_ops(grpc_exec_ctx *exec_ctx, void *args, grpc_error *error) {
-  retry_ops_args *a = args;
-  size_t i;
-  for (i = 0; i < a->nops; i++) {
-    grpc_subchannel_call_process_op(exec_ctx, a->call, a->ops[i]);
-  }
-  GRPC_SUBCHANNEL_CALL_UNREF(exec_ctx, a->call, "retry_ops");
-  gpr_free(a->ops);
-  gpr_free(a);
-}
-
 static void retry_waiting_locked(grpc_exec_ctx *exec_ctx, call_data *calld) {
   if (calld->waiting_ops_count == 0) {
     return;
   }
 
-  retry_ops_args *a = gpr_malloc(sizeof(*a));
-  a->ops = calld->waiting_ops;
-  a->nops = calld->waiting_ops_count;
-  a->call = GET_CALL(calld);
-  if (a->call == CANCELLED_CALL) {
-    gpr_free(a);
+  grpc_subchannel_call *call = GET_CALL(calld);
+  grpc_transport_stream_op **ops = calld->waiting_ops;
+  size_t nops = calld->waiting_ops_count;
+  if (call == CANCELLED_CALL) {
     fail_locked(exec_ctx, calld, GRPC_ERROR_CANCELLED);
     return;
   }
   calld->waiting_ops = NULL;
   calld->waiting_ops_count = 0;
   calld->waiting_ops_capacity = 0;
-  GRPC_SUBCHANNEL_CALL_REF(a->call, "retry_ops");
-  grpc_closure_sched(
-      exec_ctx, grpc_closure_create(retry_ops, a, grpc_schedule_on_exec_ctx),
-      GRPC_ERROR_NONE);
+  for (size_t i = 0; i < nops; i++) {
+    grpc_subchannel_call_process_op(exec_ctx, call, ops[i]);
+  }
+  gpr_free(ops);
 }
 
-static void subchannel_ready(grpc_exec_ctx *exec_ctx, void *arg,
-                             grpc_error *error) {
+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_mu_lock(&calld->mu);
   GPR_ASSERT(calld->creation_phase ==
              GRPC_SUBCHANNEL_CALL_HOLDER_PICKING_SUBCHANNEL);
   grpc_polling_entity_del_from_pollset_set(exec_ctx, calld->pollent,
@@ -742,7 +732,6 @@
                       (gpr_atm)(uintptr_t)subchannel_call);
     retry_waiting_locked(exec_ctx, calld);
   }
-  gpr_mu_unlock(&calld->mu);
   GRPC_CALL_STACK_UNREF(exec_ctx, calld->owning_call, "pick_subchannel");
 }
 
@@ -768,37 +757,35 @@
 /** Return true if subchannel is available immediately (in which case on_ready
     should not be called), or false otherwise (in which case on_ready should be
     called when the subchannel is available). */
-static bool pick_subchannel(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);
+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);
 
-static void continue_picking(grpc_exec_ctx *exec_ctx, void *arg,
-                             grpc_error *error) {
+static void continue_picking_locked(grpc_exec_ctx *exec_ctx, void *arg,
+                                    grpc_error *error) {
   continue_picking_args *cpa = arg;
   if (cpa->connected_subchannel == NULL) {
     /* cancelled, do nothing */
   } else if (error != GRPC_ERROR_NONE) {
     grpc_closure_sched(exec_ctx, cpa->on_ready, GRPC_ERROR_REF(error));
   } else {
-    call_data *calld = cpa->elem->call_data;
-    gpr_mu_lock(&calld->mu);
-    if (pick_subchannel(exec_ctx, cpa->elem, cpa->initial_metadata,
-                        cpa->initial_metadata_flags, cpa->connected_subchannel,
-                        cpa->on_ready, GRPC_ERROR_NONE)) {
+    if (pick_subchannel_locked(exec_ctx, cpa->elem, cpa->initial_metadata,
+                               cpa->initial_metadata_flags,
+                               cpa->connected_subchannel, cpa->on_ready,
+                               GRPC_ERROR_NONE)) {
       grpc_closure_sched(exec_ctx, cpa->on_ready, GRPC_ERROR_NONE);
     }
-    gpr_mu_unlock(&calld->mu);
   }
   gpr_free(cpa);
 }
 
-static bool pick_subchannel(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) {
+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) {
   GPR_TIMER_BEGIN("pick_subchannel", 0);
 
   channel_data *chand = elem->channel_data;
@@ -808,7 +795,6 @@
 
   GPR_ASSERT(connected_subchannel);
 
-  gpr_mu_lock(&chand->mu);
   if (initial_metadata == NULL) {
     if (chand->lb_policy != NULL) {
       grpc_lb_policy_cancel_pick(exec_ctx, chand->lb_policy,
@@ -824,7 +810,6 @@
             GRPC_ERROR_CREATE_REFERENCING("Pick cancelled", &error, 1));
       }
     }
-    gpr_mu_unlock(&chand->mu);
     GPR_TIMER_END("pick_subchannel", 0);
     GRPC_ERROR_UNREF(error);
     return true;
@@ -833,7 +818,6 @@
   if (chand->lb_policy != NULL) {
     grpc_lb_policy *lb_policy = chand->lb_policy;
     GRPC_LB_POLICY_REF(lb_policy, "pick_subchannel");
-    gpr_mu_unlock(&chand->mu);
     // If the application explicitly set wait_for_ready, use that.
     // Otherwise, if the service config specified a value for this
     // method, use that.
@@ -872,88 +856,66 @@
     cpa->connected_subchannel = connected_subchannel;
     cpa->on_ready = on_ready;
     cpa->elem = elem;
-    grpc_closure_init(&cpa->closure, continue_picking, cpa,
-                      grpc_schedule_on_exec_ctx);
+    grpc_closure_init(&cpa->closure, continue_picking_locked, cpa,
+                      grpc_combiner_scheduler(chand->combiner, true));
     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"));
   }
-  gpr_mu_unlock(&chand->mu);
 
   GPR_TIMER_END("pick_subchannel", 0);
   return false;
 }
 
-// The logic here is fairly complicated, due to (a) the fact that we
-// need to handle the case where we receive the send op before the
-// initial metadata op, and (b) the need for efficiency, especially in
-// the streaming case.
-// TODO(ctiller): Explain this more thoroughly.
-static void cc_start_transport_stream_op(grpc_exec_ctx *exec_ctx,
-                                         grpc_call_element *elem,
-                                         grpc_transport_stream_op *op) {
-  call_data *calld = elem->call_data;
+static void start_transport_stream_op_locked_inner(grpc_exec_ctx *exec_ctx,
+                                                   grpc_transport_stream_op *op,
+                                                   grpc_call_element *elem) {
   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);
-  /* try to (atomically) get the call */
-  grpc_subchannel_call *call = GET_CALL(calld);
-  GPR_TIMER_BEGIN("cc_start_transport_stream_op", 0);
-  if (call == CANCELLED_CALL) {
-    grpc_transport_stream_op_finish_with_failure(
-        exec_ctx, op, GRPC_ERROR_REF(calld->cancel_error));
-    GPR_TIMER_END("cc_start_transport_stream_op", 0);
-    return;
-  }
-  if (call != NULL) {
-    grpc_subchannel_call_process_op(exec_ctx, call, op);
-    GPR_TIMER_END("cc_start_transport_stream_op", 0);
-    return;
-  }
-  /* we failed; lock and figure out what to do */
-  gpr_mu_lock(&calld->mu);
-retry:
+  call_data *calld = elem->call_data;
+  grpc_subchannel_call *call;
+
   /* need to recheck that another thread hasn't set the call */
   call = GET_CALL(calld);
   if (call == CANCELLED_CALL) {
-    gpr_mu_unlock(&calld->mu);
     grpc_transport_stream_op_finish_with_failure(
         exec_ctx, op, GRPC_ERROR_REF(calld->cancel_error));
-    GPR_TIMER_END("cc_start_transport_stream_op", 0);
+    /* early out */
     return;
   }
   if (call != NULL) {
-    gpr_mu_unlock(&calld->mu);
     grpc_subchannel_call_process_op(exec_ctx, call, op);
-    GPR_TIMER_END("cc_start_transport_stream_op", 0);
+    /* early out */
     return;
   }
   /* if this is a cancellation, then we can raise our cancelled flag */
   if (op->cancel_error != GRPC_ERROR_NONE) {
     if (!gpr_atm_rel_cas(&calld->subchannel_call, 0,
                          (gpr_atm)(uintptr_t)CANCELLED_CALL)) {
-      goto retry;
+      /* recurse to retry */
+      start_transport_stream_op_locked_inner(exec_ctx, op, elem);
+      /* early out */
+      return;
     } else {
-      // Stash a copy of cancel_error in our call data, so that we can use
-      // it for subsequent operations.  This ensures that if the call is
-      // 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.
+      /* Stash a copy of cancel_error in our call data, so that we can use
+         it for subsequent operations.  This ensures that if the call is
+         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(exec_ctx, elem, NULL, 0, &calld->connected_subchannel,
-                          NULL, GRPC_ERROR_REF(op->cancel_error));
+          pick_subchannel_locked(exec_ctx, elem, NULL, 0,
+                                 &calld->connected_subchannel, NULL,
+                                 GRPC_ERROR_REF(op->cancel_error));
           break;
       }
-      gpr_mu_unlock(&calld->mu);
       grpc_transport_stream_op_finish_with_failure(
           exec_ctx, op, GRPC_ERROR_REF(op->cancel_error));
-      GPR_TIMER_END("cc_start_transport_stream_op", 0);
+      /* early out */
       return;
     }
   }
@@ -962,16 +924,16 @@
       calld->connected_subchannel == NULL &&
       op->send_initial_metadata != NULL) {
     calld->creation_phase = GRPC_SUBCHANNEL_CALL_HOLDER_PICKING_SUBCHANNEL;
-    grpc_closure_init(&calld->next_step, subchannel_ready, elem,
-                      grpc_schedule_on_exec_ctx);
+    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(exec_ctx, elem, op->send_initial_metadata,
-                        op->send_initial_metadata_flags,
-                        &calld->connected_subchannel, &calld->next_step,
-                        GRPC_ERROR_NONE)) {
+    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;
       GRPC_CALL_STACK_UNREF(exec_ctx, calld->owning_call, "pick_subchannel");
     } else {
@@ -994,31 +956,89 @@
     gpr_atm_rel_store(&calld->subchannel_call,
                       (gpr_atm)(uintptr_t)subchannel_call);
     retry_waiting_locked(exec_ctx, calld);
-    goto retry;
+    /* recurse to retry */
+    start_transport_stream_op_locked_inner(exec_ctx, op, elem);
+    /* early out */
+    return;
   }
   /* nothing to be done but wait */
   add_waiting_locked(calld, op);
-  gpr_mu_unlock(&calld->mu);
+}
+
+static void cc_start_transport_stream_op_locked(grpc_exec_ctx *exec_ctx,
+                                                void *arg,
+                                                grpc_error *error_ignored) {
+  GPR_TIMER_BEGIN("cc_start_transport_stream_op_locked", 0);
+
+  grpc_transport_stream_op *op = arg;
+  grpc_call_element *elem = op->handler_private.args[0];
+  call_data *calld = elem->call_data;
+
+  start_transport_stream_op_locked_inner(exec_ctx, op, elem);
+
+  GRPC_CALL_STACK_UNREF(exec_ctx, calld->owning_call,
+                        "start_transport_stream_op");
+  GPR_TIMER_END("cc_start_transport_stream_op_locked", 0);
+}
+
+/* The logic here is fairly complicated, due to (a) the fact that we
+   need to handle the case where we receive the send op before the
+   initial metadata op, and (b) the need for efficiency, especially in
+   the streaming case.
+
+   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) {
+  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);
+  /* try to (atomically) get the call */
+  grpc_subchannel_call *call = GET_CALL(calld);
+  GPR_TIMER_BEGIN("cc_start_transport_stream_op", 0);
+  if (call == CANCELLED_CALL) {
+    grpc_transport_stream_op_finish_with_failure(
+        exec_ctx, op, GRPC_ERROR_REF(calld->cancel_error));
+    GPR_TIMER_END("cc_start_transport_stream_op", 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);
+    /* 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_closure_sched(
+      exec_ctx,
+      grpc_closure_init(&op->handler_private.closure,
+                        cc_start_transport_stream_op_locked, op,
+                        grpc_combiner_scheduler(chand->combiner, false)),
+      GRPC_ERROR_NONE);
   GPR_TIMER_END("cc_start_transport_stream_op", 0);
 }
 
 // Gets data from the service config.  Invoked when the resolver returns
 // its initial result.
-static void read_service_config(grpc_exec_ctx *exec_ctx, void *arg,
-                                grpc_error *error) {
+static void read_service_config_locked(grpc_exec_ctx *exec_ctx, void *arg,
+                                       grpc_error *error) {
   grpc_call_element *elem = arg;
   channel_data *chand = elem->channel_data;
   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) {
     // Get the method config table from channel data.
-    gpr_mu_lock(&chand->mu);
     grpc_slice_hash_table *method_params_table = NULL;
     if (chand->method_params_table != NULL) {
       method_params_table =
           grpc_slice_hash_table_ref(chand->method_params_table);
     }
-    gpr_mu_unlock(&chand->mu);
     // If the method config table was present, use it.
     if (method_params_table != NULL) {
       const method_parameters *method_params = grpc_method_config_table_get(
@@ -1028,7 +1048,6 @@
             gpr_time_cmp(method_params->timeout, gpr_time_0(GPR_TIMESPAN)) != 0;
         if (have_method_timeout ||
             method_params->wait_for_ready != WAIT_FOR_READY_UNSET) {
-          gpr_mu_lock(&calld->mu);
           if (have_method_timeout) {
             const gpr_timespec per_method_deadline =
                 gpr_time_add(calld->call_start_time, method_params->timeout);
@@ -1042,7 +1061,6 @@
             calld->wait_for_ready_from_service_config =
                 method_params->wait_for_ready;
           }
-          gpr_mu_unlock(&calld->mu);
         }
       }
       grpc_slice_hash_table_unref(exec_ctx, method_params_table);
@@ -1051,6 +1069,57 @@
   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.
+  // TODO(roth): This code is almost but not quite identical to the code
+  // in read_service_config() above.  It would be nice to find a way to
+  // combine them, to avoid having to maintain it twice.
+  if (chand->lb_policy != NULL) {
+    // We already have a resolver result, so check for service config.
+    if (chand->method_params_table != NULL) {
+      grpc_slice_hash_table *method_params_table =
+          grpc_slice_hash_table_ref(chand->method_params_table);
+      method_parameters *method_params = grpc_method_config_table_get(
+          exec_ctx, method_params_table, calld->path);
+      if (method_params != NULL) {
+        if (gpr_time_cmp(method_params->timeout,
+                         gpr_time_0(GPR_CLOCK_MONOTONIC)) != 0) {
+          gpr_timespec per_method_deadline =
+              gpr_time_add(calld->call_start_time, method_params->timeout);
+          calld->deadline = gpr_time_min(calld->deadline, per_method_deadline);
+        }
+        if (method_params->wait_for_ready != WAIT_FOR_READY_UNSET) {
+          calld->wait_for_ready_from_service_config =
+              method_params->wait_for_ready;
+        }
+      }
+      grpc_slice_hash_table_unref(exec_ctx, method_params_table);
+    }
+  } 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");
+}
+
 /* Constructor for call_data */
 static grpc_error *cc_init_call_elem(grpc_exec_ctx *exec_ctx,
                                      grpc_call_element *elem,
@@ -1065,7 +1134,6 @@
   calld->wait_for_ready_from_service_config = WAIT_FOR_READY_UNSET;
   calld->cancel_error = GRPC_ERROR_NONE;
   gpr_atm_rel_store(&calld->subchannel_call, 0);
-  gpr_mu_init(&calld->mu);
   calld->connected_subchannel = NULL;
   calld->waiting_ops = NULL;
   calld->waiting_ops_count = 0;
@@ -1073,52 +1141,13 @@
   calld->creation_phase = GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING;
   calld->owning_call = args->call_stack;
   calld->pollent = NULL;
-  // 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.
-  // TODO(roth): This code is almost but not quite identical to the code
-  // in read_service_config() above.  It would be nice to find a way to
-  // combine them, to avoid having to maintain it twice.
-  gpr_mu_lock(&chand->mu);
-  if (chand->lb_policy != NULL) {
-    // We already have a resolver result, so check for service config.
-    if (chand->method_params_table != NULL) {
-      grpc_slice_hash_table *method_params_table =
-          grpc_slice_hash_table_ref(chand->method_params_table);
-      gpr_mu_unlock(&chand->mu);
-      method_parameters *method_params = grpc_method_config_table_get(
-          exec_ctx, method_params_table, args->path);
-      if (method_params != NULL) {
-        if (gpr_time_cmp(method_params->timeout,
-                         gpr_time_0(GPR_CLOCK_MONOTONIC)) != 0) {
-          gpr_timespec per_method_deadline =
-              gpr_time_add(calld->call_start_time, method_params->timeout);
-          calld->deadline = gpr_time_min(calld->deadline, per_method_deadline);
-        }
-        if (method_params->wait_for_ready != WAIT_FOR_READY_UNSET) {
-          calld->wait_for_ready_from_service_config =
-              method_params->wait_for_ready;
-        }
-      }
-      grpc_slice_hash_table_unref(exec_ctx, method_params_table);
-    } else {
-      gpr_mu_unlock(&chand->mu);
-    }
-  } 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, elem,
-                      grpc_schedule_on_exec_ctx);
-    grpc_closure_list_append(&chand->waiting_for_config_closures,
-                             &calld->read_service_config, GRPC_ERROR_NONE);
-    gpr_mu_unlock(&chand->mu);
-  }
-  // 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_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);
   return GRPC_ERROR_NONE;
 }
 
@@ -1136,7 +1165,6 @@
     GRPC_SUBCHANNEL_CALL_UNREF(exec_ctx, call, "client_channel_destroy_call");
   }
   GPR_ASSERT(calld->creation_phase == GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING);
-  gpr_mu_destroy(&calld->mu);
   GPR_ASSERT(calld->waiting_ops_count == 0);
   if (calld->connected_subchannel != NULL) {
     GRPC_CONNECTED_SUBCHANNEL_UNREF(exec_ctx, calld->connected_subchannel,
@@ -1172,26 +1200,36 @@
     "client-channel",
 };
 
+static void try_to_connect_locked(grpc_exec_ctx *exec_ctx, void *arg,
+                                  grpc_error *error_ignored) {
+  channel_data *chand = arg;
+  if (chand->lb_policy != NULL) {
+    grpc_lb_policy_exit_idle(exec_ctx, chand->lb_policy);
+  } else {
+    chand->exit_idle_when_lb_policy_arrives = true;
+    if (!chand->started_resolving && chand->resolver != NULL) {
+      GRPC_CHANNEL_STACK_REF(chand->owning_stack, "resolver");
+      chand->started_resolving = true;
+      grpc_resolver_next(exec_ctx, chand->resolver, &chand->resolver_result,
+                         &chand->on_resolver_result_changed);
+    }
+  }
+  GRPC_CHANNEL_STACK_UNREF(exec_ctx, chand->owning_stack, "try_to_connect");
+}
+
 grpc_connectivity_state grpc_client_channel_check_connectivity_state(
     grpc_exec_ctx *exec_ctx, grpc_channel_element *elem, int try_to_connect) {
   channel_data *chand = elem->channel_data;
-  grpc_connectivity_state out;
-  gpr_mu_lock(&chand->mu);
-  out = grpc_connectivity_state_check(&chand->state_tracker, NULL);
+  grpc_connectivity_state out =
+      grpc_connectivity_state_check(&chand->state_tracker);
   if (out == GRPC_CHANNEL_IDLE && try_to_connect) {
-    if (chand->lb_policy != NULL) {
-      grpc_lb_policy_exit_idle(exec_ctx, chand->lb_policy);
-    } else {
-      chand->exit_idle_when_lb_policy_arrives = true;
-      if (!chand->started_resolving && chand->resolver != NULL) {
-        GRPC_CHANNEL_STACK_REF(chand->owning_stack, "resolver");
-        chand->started_resolving = true;
-        grpc_resolver_next(exec_ctx, chand->resolver, &chand->resolver_result,
-                           &chand->on_resolver_result_changed);
-      }
-    }
+    GRPC_CHANNEL_STACK_REF(chand->owning_stack, "try_to_connect");
+    grpc_closure_sched(
+        exec_ctx,
+        grpc_closure_create(try_to_connect_locked, chand,
+                            grpc_combiner_scheduler(chand->combiner, false)),
+        GRPC_ERROR_NONE);
   }
-  gpr_mu_unlock(&chand->mu);
   return out;
 }
 
@@ -1199,6 +1237,7 @@
   channel_data *chand;
   grpc_pollset *pollset;
   grpc_closure *on_complete;
+  grpc_connectivity_state *state;
   grpc_closure my_closure;
 } external_connectivity_watcher;
 
@@ -1211,7 +1250,16 @@
   GRPC_CHANNEL_STACK_UNREF(exec_ctx, w->chand->owning_stack,
                            "external_connectivity_watcher");
   gpr_free(w);
-  follow_up->cb(exec_ctx, follow_up->cb_arg, error);
+  grpc_closure_run(exec_ctx, follow_up, GRPC_ERROR_REF(error));
+}
+
+static void watch_connectivity_state_locked(grpc_exec_ctx *exec_ctx, void *arg,
+                                            grpc_error *error_ignored) {
+  external_connectivity_watcher *w = arg;
+  grpc_closure_init(&w->my_closure, on_external_watch_complete, w,
+                    grpc_schedule_on_exec_ctx);
+  grpc_connectivity_state_notify_on_state_change(
+      exec_ctx, &w->chand->state_tracker, w->state, &w->my_closure);
 }
 
 void grpc_client_channel_watch_connectivity_state(
@@ -1222,13 +1270,13 @@
   w->chand = chand;
   w->pollset = pollset;
   w->on_complete = on_complete;
+  w->state = state;
   grpc_pollset_set_add_pollset(exec_ctx, chand->interested_parties, pollset);
-  grpc_closure_init(&w->my_closure, on_external_watch_complete, w,
-                    grpc_schedule_on_exec_ctx);
   GRPC_CHANNEL_STACK_REF(w->chand->owning_stack,
                          "external_connectivity_watcher");
-  gpr_mu_lock(&chand->mu);
-  grpc_connectivity_state_notify_on_state_change(
-      exec_ctx, &chand->state_tracker, state, &w->my_closure);
-  gpr_mu_unlock(&chand->mu);
+  grpc_closure_sched(
+      exec_ctx,
+      grpc_closure_init(&w->my_closure, watch_connectivity_state_locked, w,
+                        grpc_combiner_scheduler(chand->combiner, true)),
+      GRPC_ERROR_NONE);
 }
diff --git a/src/core/ext/client_channel/lb_policy.c b/src/core/ext/client_channel/lb_policy.c
index 45ee72e..90401b5 100644
--- a/src/core/ext/client_channel/lb_policy.c
+++ b/src/core/ext/client_channel/lb_policy.c
@@ -94,7 +94,7 @@
   gpr_atm old_val =
       ref_mutate(policy, -(gpr_atm)1, 1 REF_MUTATE_PASS_ARGS("WEAK_UNREF"));
   if (old_val == 1) {
-    grpc_pollset_set_destroy(policy->interested_parties);
+    grpc_pollset_set_destroy(exec_ctx, policy->interested_parties);
     policy->vtable->destroy(exec_ctx, policy);
   }
 }
diff --git a/src/core/ext/client_channel/subchannel.c b/src/core/ext/client_channel/subchannel.c
index aa036e8..09c68a9 100644
--- a/src/core/ext/client_channel/subchannel.c
+++ b/src/core/ext/client_channel/subchannel.c
@@ -217,7 +217,7 @@
   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(c->pollset_set);
+  grpc_pollset_set_destroy(exec_ctx, c->pollset_set);
   grpc_subchannel_key_destroy(exec_ctx, c->key);
   gpr_free(c);
 }
@@ -419,7 +419,7 @@
                                                            grpc_error **error) {
   grpc_connectivity_state state;
   gpr_mu_lock(&c->mu);
-  state = grpc_connectivity_state_check(&c->state_tracker, error);
+  state = grpc_connectivity_state_get(&c->state_tracker, error);
   gpr_mu_unlock(&c->mu);
   return state;
 }
diff --git a/src/core/ext/lb_policy/grpclb/grpclb.c b/src/core/ext/lb_policy/grpclb/grpclb.c
index ab62e5e..8a2af48 100644
--- a/src/core/ext/lb_policy/grpclb/grpclb.c
+++ b/src/core/ext/lb_policy/grpclb/grpclb.c
@@ -492,9 +492,8 @@
 static bool update_lb_connectivity_status_locked(
     grpc_exec_ctx *exec_ctx, glb_lb_policy *glb_policy,
     grpc_connectivity_state new_rr_state, grpc_error *new_rr_state_error) {
-  grpc_error *curr_state_error;
-  const grpc_connectivity_state curr_glb_state = grpc_connectivity_state_check(
-      &glb_policy->state_tracker, &curr_state_error);
+  const grpc_connectivity_state curr_glb_state =
+      grpc_connectivity_state_check(&glb_policy->state_tracker);
 
   /* The new connectivity status is a function of the previous one and the new
    * input coming from the status of the RR policy.
@@ -1098,8 +1097,8 @@
   glb_lb_policy *glb_policy = (glb_lb_policy *)pol;
   grpc_connectivity_state st;
   gpr_mu_lock(&glb_policy->mu);
-  st = grpc_connectivity_state_check(&glb_policy->state_tracker,
-                                     connectivity_error);
+  st = grpc_connectivity_state_get(&glb_policy->state_tracker,
+                                   connectivity_error);
   gpr_mu_unlock(&glb_policy->mu);
   return st;
 }
diff --git a/src/core/ext/lb_policy/pick_first/pick_first.c b/src/core/ext/lb_policy/pick_first/pick_first.c
index 9f2aa46..1b96518 100644
--- a/src/core/ext/lb_policy/pick_first/pick_first.c
+++ b/src/core/ext/lb_policy/pick_first/pick_first.c
@@ -398,7 +398,7 @@
   pick_first_lb_policy *p = (pick_first_lb_policy *)pol;
   grpc_connectivity_state st;
   gpr_mu_lock(&p->mu);
-  st = grpc_connectivity_state_check(&p->state_tracker, error);
+  st = grpc_connectivity_state_get(&p->state_tracker, error);
   gpr_mu_unlock(&p->mu);
   return st;
 }
diff --git a/src/core/ext/lb_policy/round_robin/round_robin.c b/src/core/ext/lb_policy/round_robin/round_robin.c
index 3e060d1..63e3d03 100644
--- a/src/core/ext/lb_policy/round_robin/round_robin.c
+++ b/src/core/ext/lb_policy/round_robin/round_robin.c
@@ -655,7 +655,7 @@
   round_robin_lb_policy *p = (round_robin_lb_policy *)pol;
   grpc_connectivity_state st;
   gpr_mu_lock(&p->mu);
-  st = grpc_connectivity_state_check(&p->state_tracker, error);
+  st = grpc_connectivity_state_get(&p->state_tracker, error);
   gpr_mu_unlock(&p->mu);
   return st;
 }
diff --git a/src/core/ext/load_reporting/load_reporting.c b/src/core/ext/load_reporting/load_reporting.c
index 37b06a7..942aea4 100644
--- a/src/core/ext/load_reporting/load_reporting.c
+++ b/src/core/ext/load_reporting/load_reporting.c
@@ -34,14 +34,34 @@
 #include <limits.h>
 #include <string.h>
 
+#include <grpc/load_reporting.h>
 #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/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++) {
diff --git a/src/core/ext/load_reporting/load_reporting.h b/src/core/ext/load_reporting/load_reporting.h
index a157844..22859a5 100644
--- a/src/core/ext/load_reporting/load_reporting.h
+++ b/src/core/ext/load_reporting/load_reporting.h
@@ -35,24 +35,9 @@
 #define GRPC_CORE_EXT_LOAD_REPORTING_LOAD_REPORTING_H
 
 #include <grpc/impl/codegen/grpc_types.h>
+
 #include "src/core/lib/channel/channel_stack.h"
 
-/** Metadata key for the gRPC LB load balancer token.
- *
- * The value corresponding to this key is an opaque token that is given to the
- * frontend as part of each pick; the frontend sends this token to the backend
- * in each request it sends when using that pick. The token is used by the
- * backend to verify the request and to allow the backend to report load to the
- * gRPC LB system. */
-#define GRPC_LB_TOKEN_MD_KEY "lb-token"
-
-/** 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"
-
 /** Identifiers for the invocation point of the users LR callback */
 typedef enum grpc_load_reporting_source {
   GRPC_LR_POINT_UNKNOWN = 0,
diff --git a/src/core/ext/load_reporting/load_reporting_filter.c b/src/core/ext/load_reporting/load_reporting_filter.c
index 8af6191..7fc88db 100644
--- a/src/core/ext/load_reporting/load_reporting_filter.c
+++ b/src/core/ext/load_reporting/load_reporting_filter.c
@@ -31,11 +31,13 @@
  *
  */
 
+#include <string.h>
+
+#include <grpc/load_reporting.h>
 #include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
 #include <grpc/support/string_util.h>
 #include <grpc/support/sync.h>
-#include <string.h>
 
 #include "src/core/ext/load_reporting/load_reporting.h"
 #include "src/core/ext/load_reporting/load_reporting_filter.h"
@@ -46,8 +48,6 @@
 
 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;
@@ -142,9 +142,6 @@
   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);
   }
@@ -201,15 +198,6 @@
     /* 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;
-  } else if (op->send_trailing_metadata) {
-    if (op->send_trailing_metadata->idx.named.lb_cost_bin != NULL) {
-      calld->trailing_md_string = grpc_slice_ref_internal(
-          GRPC_MDVALUE(op->send_trailing_metadata->idx.named.lb_cost_bin->md));
-      calld->have_trailing_md_string = true;
-      grpc_metadata_batch_remove(
-          exec_ctx, op->send_trailing_metadata,
-          op->send_trailing_metadata->idx.named.lb_cost_bin);
-    }
   }
   grpc_call_next_op(exec_ctx, elem, op);
 
diff --git a/src/core/ext/resolver/dns/native/dns_resolver.c b/src/core/ext/resolver/dns/native/dns_resolver.c
index 2c96232..c08b53e 100644
--- a/src/core/ext/resolver/dns/native/dns_resolver.c
+++ b/src/core/ext/resolver/dns/native/dns_resolver.c
@@ -244,7 +244,7 @@
   if (r->resolved_result != NULL) {
     grpc_channel_args_destroy(exec_ctx, r->resolved_result);
   }
-  grpc_pollset_set_destroy(r->interested_parties);
+  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);
diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c
index ddbc656..d1fab25 100644
--- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c
+++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c
@@ -1041,8 +1041,8 @@
   GPR_TIMER_BEGIN("perform_stream_op_locked", 0);
 
   grpc_transport_stream_op *op = stream_op;
-  grpc_chttp2_transport *t = op->transport_private.args[0];
-  grpc_chttp2_stream *s = op->transport_private.args[1];
+  grpc_chttp2_transport *t = op->handler_private.args[0];
+  grpc_chttp2_stream *s = op->handler_private.args[1];
 
   if (grpc_http_trace) {
     char *str = grpc_transport_stream_op_string(op);
@@ -1263,13 +1263,13 @@
     gpr_free(str);
   }
 
-  op->transport_private.args[0] = gt;
-  op->transport_private.args[1] = gs;
+  op->handler_private.args[0] = gt;
+  op->handler_private.args[1] = gs;
   GRPC_CHTTP2_STREAM_REF(s, "perform_stream_op");
   grpc_closure_sched(
       exec_ctx,
       grpc_closure_init(
-          &op->transport_private.closure, perform_stream_op_locked, op,
+          &op->handler_private.closure, perform_stream_op_locked, op,
           grpc_combiner_scheduler(t->combiner, op->covered_by_poller)),
       GRPC_ERROR_NONE);
   GPR_TIMER_END("perform_stream_op", 0);
diff --git a/src/core/lib/channel/compress_filter.c b/src/core/lib/channel/compress_filter.c
index c860d60..22781c7 100644
--- a/src/core/lib/channel/compress_filter.c
+++ b/src/core/lib/channel/compress_filter.c
@@ -105,7 +105,6 @@
 static grpc_error *process_send_initial_metadata(
     grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
     grpc_metadata_batch *initial_metadata) {
-  grpc_error *error;
   call_data *calld = elem->call_data;
   channel_data *channeld = elem->channel_data;
   /* Parse incoming request for compression. If any, it'll be available
@@ -144,10 +143,13 @@
     calld->has_compression_algorithm = 1; /* GPR_TRUE */
   }
 
+  grpc_error *error = GRPC_ERROR_NONE;
   /* hint compression algorithm */
-  error = grpc_metadata_batch_add_tail(
-      exec_ctx, initial_metadata, &calld->compression_algorithm_storage,
-      grpc_compression_encoding_mdelem(calld->compression_algorithm));
+  if (calld->compression_algorithm != GRPC_COMPRESS_NONE) {
+    error = grpc_metadata_batch_add_tail(
+        exec_ctx, initial_metadata, &calld->compression_algorithm_storage,
+        grpc_compression_encoding_mdelem(calld->compression_algorithm));
+  }
 
   if (error != GRPC_ERROR_NONE) return error;
 
diff --git a/src/core/lib/channel/context.h b/src/core/lib/channel/context.h
index 6c931ad..2c1174c 100644
--- a/src/core/lib/channel/context.h
+++ b/src/core/lib/channel/context.h
@@ -50,6 +50,9 @@
   /// Reserved for traffic_class_context.
   GRPC_CONTEXT_TRAFFIC,
 
+  /// Costs for Load Reporting.
+  GRPC_CONTEXT_LR_COST,
+
   GRPC_CONTEXT_COUNT
 } grpc_context_index;
 
diff --git a/src/core/lib/http/httpcli.c b/src/core/lib/http/httpcli.c
index fb21089..6d7aa43 100644
--- a/src/core/lib/http/httpcli.c
+++ b/src/core/lib/http/httpcli.c
@@ -93,8 +93,9 @@
   context->pollset_set = grpc_pollset_set_create();
 }
 
-void grpc_httpcli_context_destroy(grpc_httpcli_context *context) {
-  grpc_pollset_set_destroy(context->pollset_set);
+void grpc_httpcli_context_destroy(grpc_exec_ctx *exec_ctx,
+                                  grpc_httpcli_context *context) {
+  grpc_pollset_set_destroy(exec_ctx, context->pollset_set);
 }
 
 static void next_address(grpc_exec_ctx *exec_ctx, internal_request *req,
diff --git a/src/core/lib/http/httpcli.h b/src/core/lib/http/httpcli.h
index 11e03b4..8ae03ee 100644
--- a/src/core/lib/http/httpcli.h
+++ b/src/core/lib/http/httpcli.h
@@ -83,7 +83,8 @@
 typedef struct grpc_http_response grpc_httpcli_response;
 
 void grpc_httpcli_context_init(grpc_httpcli_context *context);
-void grpc_httpcli_context_destroy(grpc_httpcli_context *context);
+void grpc_httpcli_context_destroy(grpc_exec_ctx *exec_ctx,
+                                  grpc_httpcli_context *context);
 
 /* Asynchronously perform a HTTP GET.
    'context' specifies the http context under which to do the get
diff --git a/src/core/lib/iomgr/ev_epoll_linux.c b/src/core/lib/iomgr/ev_epoll_linux.c
index fc56843..fac3705 100644
--- a/src/core/lib/iomgr/ev_epoll_linux.c
+++ b/src/core/lib/iomgr/ev_epoll_linux.c
@@ -1842,13 +1842,12 @@
   return pss;
 }
 
-static void pollset_set_destroy(grpc_pollset_set *pss) {
+static void pollset_set_destroy(grpc_exec_ctx *exec_ctx,
+                                grpc_pollset_set *pss) {
   gpr_mu_destroy(&pss->po.mu);
 
   if (pss->po.pi != NULL) {
-    grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
-    PI_UNREF(&exec_ctx, pss->po.pi, "pss_destroy");
-    grpc_exec_ctx_finish(&exec_ctx);
+    PI_UNREF(exec_ctx, pss->po.pi, "pss_destroy");
   }
 
   gpr_free(pss);
diff --git a/src/core/lib/iomgr/ev_poll_posix.c b/src/core/lib/iomgr/ev_poll_posix.c
index 21eb627..c03fada 100644
--- a/src/core/lib/iomgr/ev_poll_posix.c
+++ b/src/core/lib/iomgr/ev_poll_posix.c
@@ -149,7 +149,7 @@
 static bool fd_is_orphaned(grpc_fd *fd);
 
 /* Reference counting for fds */
-/*#define GRPC_FD_REF_COUNT_DEBUG*/
+//#define GRPC_FD_REF_COUNT_DEBUG
 #ifdef GRPC_FD_REF_COUNT_DEBUG
 static void fd_ref(grpc_fd *fd, const char *reason, const char *file, int line);
 static void fd_unref(grpc_fd *fd, const char *reason, const char *file,
@@ -191,6 +191,7 @@
   int kicked_without_pollers;
   grpc_closure *shutdown_done;
   grpc_closure_list idle_jobs;
+  int pollset_set_count;
   /* all polled fds */
   size_t fd_count;
   size_t fd_capacity;
@@ -228,7 +229,7 @@
 
 /* Return 1 if the pollset has active threads in pollset_work (pollset must
  * be locked) */
-static int pollset_has_workers(grpc_pollset *pollset);
+static bool pollset_has_workers(grpc_pollset *pollset);
 
 /*******************************************************************************
  * pollset_set definitions
@@ -282,8 +283,8 @@
 static void ref_by(grpc_fd *fd, int n, const char *reason, const char *file,
                    int line) {
   gpr_log(GPR_DEBUG, "FD %d %p   ref %d %d -> %d [%s; %s:%d]", fd->fd, fd, n,
-          gpr_atm_no_barrier_load(&fd->refst),
-          gpr_atm_no_barrier_load(&fd->refst) + n, reason, file, line);
+          (int)gpr_atm_no_barrier_load(&fd->refst),
+          (int)gpr_atm_no_barrier_load(&fd->refst) + n, reason, file, line);
 #else
 #define REF_BY(fd, n, reason) ref_by(fd, n)
 #define UNREF_BY(fd, n, reason) unref_by(fd, n)
@@ -297,8 +298,8 @@
                      int line) {
   gpr_atm old;
   gpr_log(GPR_DEBUG, "FD %d %p unref %d %d -> %d [%s; %s:%d]", fd->fd, fd, n,
-          gpr_atm_no_barrier_load(&fd->refst),
-          gpr_atm_no_barrier_load(&fd->refst) - n, reason, file, line);
+          (int)gpr_atm_no_barrier_load(&fd->refst),
+          (int)gpr_atm_no_barrier_load(&fd->refst) - n, reason, file, line);
 #else
 static void unref_by(grpc_fd *fd, int n) {
   gpr_atm old;
@@ -658,10 +659,18 @@
   worker->next->prev = worker->prev;
 }
 
-static int pollset_has_workers(grpc_pollset *p) {
+static bool pollset_has_workers(grpc_pollset *p) {
   return p->root_worker.next != &p->root_worker;
 }
 
+static bool pollset_in_pollset_sets(grpc_pollset *p) {
+  return p->pollset_set_count;
+}
+
+static bool pollset_has_observers(grpc_pollset *p) {
+  return pollset_has_workers(p) || pollset_in_pollset_sets(p);
+}
+
 static grpc_pollset_worker *pop_front_worker(grpc_pollset *p) {
   if (pollset_has_workers(p)) {
     grpc_pollset_worker *w = p->root_worker.next;
@@ -800,6 +809,7 @@
   pollset->fd_count = 0;
   pollset->fd_capacity = 0;
   pollset->fds = NULL;
+  pollset->pollset_set_count = 0;
 }
 
 static void pollset_destroy(grpc_pollset *pollset) {
@@ -1061,7 +1071,7 @@
   if (pollset->shutting_down) {
     if (pollset_has_workers(pollset)) {
       pollset_kick(pollset, NULL);
-    } else if (!pollset->called_shutdown) {
+    } else if (!pollset->called_shutdown && !pollset_has_observers(pollset)) {
       pollset->called_shutdown = 1;
       gpr_mu_unlock(&pollset->mu);
       finish_shutdown(exec_ctx, pollset);
@@ -1093,7 +1103,7 @@
   if (!pollset_has_workers(pollset)) {
     grpc_closure_list_sched(exec_ctx, &pollset->idle_jobs);
   }
-  if (!pollset->called_shutdown && !pollset_has_workers(pollset)) {
+  if (!pollset->called_shutdown && !pollset_has_observers(pollset)) {
     pollset->called_shutdown = 1;
     finish_shutdown(exec_ctx, pollset);
   }
@@ -1127,12 +1137,27 @@
   return pollset_set;
 }
 
-static void pollset_set_destroy(grpc_pollset_set *pollset_set) {
+static void pollset_set_destroy(grpc_exec_ctx *exec_ctx,
+                                grpc_pollset_set *pollset_set) {
   size_t i;
   gpr_mu_destroy(&pollset_set->mu);
   for (i = 0; i < pollset_set->fd_count; i++) {
     GRPC_FD_UNREF(pollset_set->fds[i], "pollset_set");
   }
+  for (i = 0; i < pollset_set->pollset_count; i++) {
+    grpc_pollset *pollset = pollset_set->pollsets[i];
+    gpr_mu_lock(&pollset->mu);
+    pollset->pollset_set_count--;
+    /* check shutdown */
+    if (pollset->shutting_down && !pollset->called_shutdown &&
+        !pollset_has_observers(pollset)) {
+      pollset->called_shutdown = 1;
+      gpr_mu_unlock(&pollset->mu);
+      finish_shutdown(exec_ctx, pollset);
+    } else {
+      gpr_mu_unlock(&pollset->mu);
+    }
+  }
   gpr_free(pollset_set->pollsets);
   gpr_free(pollset_set->pollset_sets);
   gpr_free(pollset_set->fds);
@@ -1143,6 +1168,9 @@
                                     grpc_pollset_set *pollset_set,
                                     grpc_pollset *pollset) {
   size_t i, j;
+  gpr_mu_lock(&pollset->mu);
+  pollset->pollset_set_count++;
+  gpr_mu_unlock(&pollset->mu);
   gpr_mu_lock(&pollset_set->mu);
   if (pollset_set->pollset_count == pollset_set->pollset_capacity) {
     pollset_set->pollset_capacity =
@@ -1178,6 +1206,17 @@
     }
   }
   gpr_mu_unlock(&pollset_set->mu);
+  gpr_mu_lock(&pollset->mu);
+  pollset->pollset_set_count--;
+  /* check shutdown */
+  if (pollset->shutting_down && !pollset->called_shutdown &&
+      !pollset_has_observers(pollset)) {
+    pollset->called_shutdown = 1;
+    gpr_mu_unlock(&pollset->mu);
+    finish_shutdown(exec_ctx, pollset);
+  } else {
+    gpr_mu_unlock(&pollset->mu);
+  }
 }
 
 static void pollset_set_add_pollset_set(grpc_exec_ctx *exec_ctx,
diff --git a/src/core/lib/iomgr/ev_posix.c b/src/core/lib/iomgr/ev_posix.c
index 95b1d99..b5be550 100644
--- a/src/core/lib/iomgr/ev_posix.c
+++ b/src/core/lib/iomgr/ev_posix.c
@@ -215,8 +215,9 @@
   return g_event_engine->pollset_set_create();
 }
 
-void grpc_pollset_set_destroy(grpc_pollset_set *pollset_set) {
-  g_event_engine->pollset_set_destroy(pollset_set);
+void grpc_pollset_set_destroy(grpc_exec_ctx *exec_ctx,
+                              grpc_pollset_set *pollset_set) {
+  g_event_engine->pollset_set_destroy(exec_ctx, pollset_set);
 }
 
 void grpc_pollset_set_add_pollset(grpc_exec_ctx *exec_ctx,
diff --git a/src/core/lib/iomgr/ev_posix.h b/src/core/lib/iomgr/ev_posix.h
index 1aea7d6..1a9e5c1 100644
--- a/src/core/lib/iomgr/ev_posix.h
+++ b/src/core/lib/iomgr/ev_posix.h
@@ -74,7 +74,8 @@
                          struct grpc_fd *fd);
 
   grpc_pollset_set *(*pollset_set_create)(void);
-  void (*pollset_set_destroy)(grpc_pollset_set *pollset_set);
+  void (*pollset_set_destroy)(grpc_exec_ctx *exec_ctx,
+                              grpc_pollset_set *pollset_set);
   void (*pollset_set_add_pollset)(grpc_exec_ctx *exec_ctx,
                                   grpc_pollset_set *pollset_set,
                                   grpc_pollset *pollset);
diff --git a/src/core/lib/iomgr/network_status_tracker.c b/src/core/lib/iomgr/network_status_tracker.c
index 1601a39..4104bf9 100644
--- a/src/core/lib/iomgr/network_status_tracker.c
+++ b/src/core/lib/iomgr/network_status_tracker.c
@@ -31,95 +31,18 @@
  *
  */
 
-#include <grpc/support/alloc.h>
-#include <grpc/support/log.h>
 #include "src/core/lib/iomgr/endpoint.h"
 
-typedef struct endpoint_ll_node {
-  grpc_endpoint *ep;
-  struct endpoint_ll_node *next;
-} endpoint_ll_node;
-
-static endpoint_ll_node *head = NULL;
-static gpr_mu g_endpoint_mutex;
-
-void grpc_network_status_shutdown(void) {
-  if (head != NULL) {
-    gpr_log(GPR_ERROR,
-            "Memory leaked as not all network endpoints were shut down");
-  }
-  gpr_mu_destroy(&g_endpoint_mutex);
-}
+void grpc_network_status_shutdown(void) {}
 
 void grpc_network_status_init(void) {
-  gpr_mu_init(&g_endpoint_mutex);
   // TODO(makarandd): Install callback with OS to monitor network status.
 }
 
-void grpc_destroy_network_status_monitor() {
-  for (endpoint_ll_node *curr = head; curr != NULL;) {
-    endpoint_ll_node *next = curr->next;
-    gpr_free(curr);
-    curr = next;
-  }
-  gpr_mu_destroy(&g_endpoint_mutex);
-}
+void grpc_destroy_network_status_monitor() {}
 
-void grpc_network_status_register_endpoint(grpc_endpoint *ep) {
-  gpr_mu_lock(&g_endpoint_mutex);
-  if (head == NULL) {
-    head = (endpoint_ll_node *)gpr_malloc(sizeof(endpoint_ll_node));
-    head->ep = ep;
-    head->next = NULL;
-  } else {
-    endpoint_ll_node *prev_head = head;
-    head = (endpoint_ll_node *)gpr_malloc(sizeof(endpoint_ll_node));
-    head->ep = ep;
-    head->next = prev_head;
-  }
-  gpr_mu_unlock(&g_endpoint_mutex);
-}
+void grpc_network_status_register_endpoint(grpc_endpoint *ep) { (void)ep; }
 
-void grpc_network_status_unregister_endpoint(grpc_endpoint *ep) {
-  gpr_mu_lock(&g_endpoint_mutex);
-  GPR_ASSERT(head);
-  bool found = false;
-  endpoint_ll_node *prev = head;
-  // if we're unregistering the head, just move head to the next
-  if (ep == head->ep) {
-    head = head->next;
-    gpr_free(prev);
-    found = true;
-  } else {
-    for (endpoint_ll_node *curr = head->next; curr != NULL; curr = curr->next) {
-      if (ep == curr->ep) {
-        prev->next = curr->next;
-        gpr_free(curr);
-        found = true;
-        break;
-      }
-      prev = curr;
-    }
-  }
-  gpr_mu_unlock(&g_endpoint_mutex);
-  GPR_ASSERT(found);
-}
+void grpc_network_status_unregister_endpoint(grpc_endpoint *ep) { (void)ep; }
 
-// Walk the linked-list from head and execute shutdown. It is possible that
-// other threads might be in the process of shutdown as well, but that has
-// no side effect since endpoint shutdown is idempotent.
-void grpc_network_status_shutdown_all_endpoints() {
-  gpr_mu_lock(&g_endpoint_mutex);
-  if (head == NULL) {
-    gpr_mu_unlock(&g_endpoint_mutex);
-    return;
-  }
-  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
-
-  for (endpoint_ll_node *curr = head; curr != NULL; curr = curr->next) {
-    curr->ep->vtable->shutdown(&exec_ctx, curr->ep,
-                               GRPC_ERROR_CREATE("Network unavailable"));
-  }
-  gpr_mu_unlock(&g_endpoint_mutex);
-  grpc_exec_ctx_finish(&exec_ctx);
-}
+void grpc_network_status_shutdown_all_endpoints() {}
diff --git a/src/core/lib/iomgr/pollset_set.h b/src/core/lib/iomgr/pollset_set.h
index 34bb728..d11801d 100644
--- a/src/core/lib/iomgr/pollset_set.h
+++ b/src/core/lib/iomgr/pollset_set.h
@@ -44,7 +44,8 @@
 typedef struct grpc_pollset_set grpc_pollset_set;
 
 grpc_pollset_set *grpc_pollset_set_create(void);
-void grpc_pollset_set_destroy(grpc_pollset_set *pollset_set);
+void grpc_pollset_set_destroy(grpc_exec_ctx *exec_ctx,
+                              grpc_pollset_set *pollset_set);
 void grpc_pollset_set_add_pollset(grpc_exec_ctx *exec_ctx,
                                   grpc_pollset_set *pollset_set,
                                   grpc_pollset *pollset);
diff --git a/src/core/lib/iomgr/pollset_set_uv.c b/src/core/lib/iomgr/pollset_set_uv.c
index e5ef8b2..836cfee 100644
--- a/src/core/lib/iomgr/pollset_set_uv.c
+++ b/src/core/lib/iomgr/pollset_set_uv.c
@@ -41,7 +41,8 @@
   return (grpc_pollset_set*)((intptr_t)0xdeafbeef);
 }
 
-void grpc_pollset_set_destroy(grpc_pollset_set* pollset_set) {}
+void grpc_pollset_set_destroy(grpc_exec_ctx* exec_ctx,
+                              grpc_pollset_set* pollset_set) {}
 
 void grpc_pollset_set_add_pollset(grpc_exec_ctx* exec_ctx,
                                   grpc_pollset_set* pollset_set,
diff --git a/src/core/lib/iomgr/pollset_set_windows.c b/src/core/lib/iomgr/pollset_set_windows.c
index 645650d..ae18c8a 100644
--- a/src/core/lib/iomgr/pollset_set_windows.c
+++ b/src/core/lib/iomgr/pollset_set_windows.c
@@ -42,7 +42,8 @@
   return (grpc_pollset_set*)((intptr_t)0xdeafbeef);
 }
 
-void grpc_pollset_set_destroy(grpc_pollset_set* pollset_set) {}
+void grpc_pollset_set_destroy(grpc_exec_ctx* exec_ctx,
+                              grpc_pollset_set* pollset_set) {}
 
 void grpc_pollset_set_add_pollset(grpc_exec_ctx* exec_ctx,
                                   grpc_pollset_set* pollset_set,
diff --git a/src/core/lib/iomgr/timer_generic.c b/src/core/lib/iomgr/timer_generic.c
index 40c8351..8a5617e 100644
--- a/src/core/lib/iomgr/timer_generic.c
+++ b/src/core/lib/iomgr/timer_generic.c
@@ -121,12 +121,6 @@
   g_initialized = false;
 }
 
-/* This is a cheap, but good enough, pointer hash for sharding the tasks: */
-static size_t shard_idx(const grpc_timer *info) {
-  size_t x = (size_t)info;
-  return ((x >> 4) ^ (x >> 9) ^ (x >> 14)) & (NUM_SHARDS - 1);
-}
-
 static double ts_to_dbl(gpr_timespec ts) {
   return (double)ts.tv_sec + 1e-9 * ts.tv_nsec;
 }
@@ -181,7 +175,7 @@
                      gpr_timespec deadline, grpc_closure *closure,
                      gpr_timespec now) {
   int is_first_timer = 0;
-  shard_type *shard = &g_shards[shard_idx(timer)];
+  shard_type *shard = &g_shards[GPR_HASH_POINTER(timer, NUM_SHARDS)];
   GPR_ASSERT(deadline.clock_type == g_clock_type);
   GPR_ASSERT(now.clock_type == g_clock_type);
   timer->closure = closure;
@@ -247,7 +241,7 @@
     return;
   }
 
-  shard_type *shard = &g_shards[shard_idx(timer)];
+  shard_type *shard = &g_shards[GPR_HASH_POINTER(timer, NUM_SHARDS)];
   gpr_mu_lock(&shard->mu);
   if (!timer->triggered) {
     grpc_closure_sched(exec_ctx, timer->closure, GRPC_ERROR_CANCELLED);
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 a098741..ecd26de 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
@@ -154,7 +154,7 @@
   }
   gpr_mu_unlock(g_polling_mu);
 
-  grpc_httpcli_context_destroy(&context);
+  grpc_httpcli_context_destroy(exec_ctx, &context);
   grpc_closure_init(&destroy_closure, destroy_pollset,
                     grpc_polling_entity_pollset(&detector.pollent),
                     grpc_schedule_on_exec_ctx);
diff --git a/src/core/lib/security/credentials/jwt/jwt_verifier.c b/src/core/lib/security/credentials/jwt/jwt_verifier.c
index 2270be8..f128177 100644
--- a/src/core/lib/security/credentials/jwt/jwt_verifier.c
+++ b/src/core/lib/security/credentials/jwt/jwt_verifier.c
@@ -898,10 +898,10 @@
   return v;
 }
 
-void grpc_jwt_verifier_destroy(grpc_jwt_verifier *v) {
+void grpc_jwt_verifier_destroy(grpc_exec_ctx *exec_ctx, grpc_jwt_verifier *v) {
   size_t i;
   if (v == NULL) return;
-  grpc_httpcli_context_destroy(&v->http_ctx);
+  grpc_httpcli_context_destroy(exec_ctx, &v->http_ctx);
   if (v->mappings != NULL) {
     for (i = 0; i < v->num_mappings; i++) {
       gpr_free(v->mappings[i].email_domain);
diff --git a/src/core/lib/security/credentials/jwt/jwt_verifier.h b/src/core/lib/security/credentials/jwt/jwt_verifier.h
index 4fa320a..5c3d2a7 100644
--- a/src/core/lib/security/credentials/jwt/jwt_verifier.h
+++ b/src/core/lib/security/credentials/jwt/jwt_verifier.h
@@ -109,7 +109,8 @@
     size_t num_mappings);
 
 /*The verifier must not be destroyed if there are still outstanding callbacks.*/
-void grpc_jwt_verifier_destroy(grpc_jwt_verifier *verifier);
+void grpc_jwt_verifier_destroy(grpc_exec_ctx *exec_ctx,
+                               grpc_jwt_verifier *verifier);
 
 /* User provided callback that will be called when the verification of the JWT
    is done (maybe in another thread).
diff --git a/src/core/lib/security/credentials/oauth2/oauth2_credentials.c b/src/core/lib/security/credentials/oauth2/oauth2_credentials.c
index 1b0e43a..c0f260f 100644
--- a/src/core/lib/security/credentials/oauth2/oauth2_credentials.c
+++ b/src/core/lib/security/credentials/oauth2/oauth2_credentials.c
@@ -124,7 +124,7 @@
       (grpc_oauth2_token_fetcher_credentials *)creds;
   grpc_credentials_md_store_unref(exec_ctx, c->access_token_md);
   gpr_mu_destroy(&c->mu);
-  grpc_httpcli_context_destroy(&c->httpcli_context);
+  grpc_httpcli_context_destroy(exec_ctx, &c->httpcli_context);
 }
 
 grpc_credentials_status
diff --git a/src/core/lib/support/cpu_posix.c b/src/core/lib/support/cpu_posix.c
index 667bde7..245f12f 100644
--- a/src/core/lib/support/cpu_posix.c
+++ b/src/core/lib/support/cpu_posix.c
@@ -41,6 +41,7 @@
 
 #include <grpc/support/log.h>
 #include <grpc/support/sync.h>
+#include <grpc/support/useful.h>
 
 static __thread char magic_thread_local;
 
@@ -60,18 +61,12 @@
   return (unsigned)ncpus;
 }
 
-/* This is a cheap, but good enough, pointer hash for sharding things: */
-static size_t shard_ptr(const void *info) {
-  size_t x = (size_t)info;
-  return ((x >> 4) ^ (x >> 9) ^ (x >> 14)) % gpr_cpu_num_cores();
-}
-
 unsigned gpr_cpu_current_cpu(void) {
   /* NOTE: there's no way I know to return the actual cpu index portably...
      most code that's using this is using it to shard across work queues though,
      so here we use thread identity instead to achieve a similar though not
      identical effect */
-  return (unsigned)shard_ptr(&magic_thread_local);
+  return (unsigned)GPR_HASH_POINTER(&magic_thread_local, gpr_cpu_num_cores());
 }
 
 #endif /* GPR_CPU_POSIX */
diff --git a/src/core/lib/surface/call.c b/src/core/lib/surface/call.c
index 3352e42..48a1e58 100644
--- a/src/core/lib/surface/call.c
+++ b/src/core/lib/surface/call.c
@@ -481,7 +481,10 @@
   c->destroy_called = 1;
   cancel = !c->received_final_op;
   gpr_mu_unlock(&c->mu);
-  if (cancel) grpc_call_cancel(c, NULL);
+  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);
@@ -490,8 +493,11 @@
 grpc_call_error grpc_call_cancel(grpc_call *call, void *reserved) {
   GRPC_API_TRACE("grpc_call_cancel(call=%p, reserved=%p)", 2, (call, reserved));
   GPR_ASSERT(!reserved);
-  return grpc_call_cancel_with_status(call, GRPC_STATUS_CANCELLED, "Cancelled",
-                                      NULL);
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+  cancel_with_error(&exec_ctx, call, STATUS_FROM_API_OVERRIDE,
+                    GRPC_ERROR_CANCELLED);
+  grpc_exec_ctx_finish(&exec_ctx);
+  return GRPC_CALL_OK;
 }
 
 static void execute_op(grpc_exec_ctx *exec_ctx, grpc_call *call,
diff --git a/src/core/lib/surface/call.h b/src/core/lib/surface/call.h
index b70343d..7d4d0db 100644
--- a/src/core/lib/surface/call.h
+++ b/src/core/lib/surface/call.h
@@ -110,6 +110,7 @@
 
 /* Set a context pointer.
    No thread safety guarantees are made wrt this value. */
+/* TODO(#9731): add exec_ctx to destroy */
 void grpc_call_context_set(grpc_call *call, grpc_context_index elem,
                            void *value, void (*destroy)(void *value));
 /* Get a context pointer. */
diff --git a/src/core/lib/transport/connectivity_state.c b/src/core/lib/transport/connectivity_state.c
index 8fc5bf3..afe1f61 100644
--- a/src/core/lib/transport/connectivity_state.c
+++ b/src/core/lib/transport/connectivity_state.c
@@ -62,7 +62,7 @@
 void grpc_connectivity_state_init(grpc_connectivity_state_tracker *tracker,
                                   grpc_connectivity_state init_state,
                                   const char *name) {
-  tracker->current_state = init_state;
+  gpr_atm_no_barrier_store(&tracker->current_state_atm, init_state);
   tracker->current_error = GRPC_ERROR_NONE;
   tracker->watchers = NULL;
   tracker->name = gpr_strdup(name);
@@ -89,15 +89,30 @@
 }
 
 grpc_connectivity_state grpc_connectivity_state_check(
-    grpc_connectivity_state_tracker *tracker, grpc_error **error) {
+    grpc_connectivity_state_tracker *tracker) {
+  grpc_connectivity_state cur =
+      (grpc_connectivity_state)gpr_atm_no_barrier_load(
+          &tracker->current_state_atm);
   if (grpc_connectivity_state_trace) {
     gpr_log(GPR_DEBUG, "CONWATCH: %p %s: get %s", tracker, tracker->name,
-            grpc_connectivity_state_name(tracker->current_state));
+            grpc_connectivity_state_name(cur));
+  }
+  return cur;
+}
+
+grpc_connectivity_state grpc_connectivity_state_get(
+    grpc_connectivity_state_tracker *tracker, grpc_error **error) {
+  grpc_connectivity_state cur =
+      (grpc_connectivity_state)gpr_atm_no_barrier_load(
+          &tracker->current_state_atm);
+  if (grpc_connectivity_state_trace) {
+    gpr_log(GPR_DEBUG, "CONWATCH: %p %s: get %s", tracker, tracker->name,
+            grpc_connectivity_state_name(cur));
   }
   if (error != NULL) {
     *error = GRPC_ERROR_REF(tracker->current_error);
   }
-  return tracker->current_state;
+  return cur;
 }
 
 bool grpc_connectivity_state_has_watchers(
@@ -108,6 +123,9 @@
 bool grpc_connectivity_state_notify_on_state_change(
     grpc_exec_ctx *exec_ctx, grpc_connectivity_state_tracker *tracker,
     grpc_connectivity_state *current, grpc_closure *notify) {
+  grpc_connectivity_state cur =
+      (grpc_connectivity_state)gpr_atm_no_barrier_load(
+          &tracker->current_state_atm);
   if (grpc_connectivity_state_trace) {
     if (current == NULL) {
       gpr_log(GPR_DEBUG, "CONWATCH: %p %s: unsubscribe notify=%p", tracker,
@@ -115,7 +133,7 @@
     } else {
       gpr_log(GPR_DEBUG, "CONWATCH: %p %s: from %s [cur=%s] notify=%p", tracker,
               tracker->name, grpc_connectivity_state_name(*current),
-              grpc_connectivity_state_name(tracker->current_state), notify);
+              grpc_connectivity_state_name(cur), notify);
     }
   }
   if (current == NULL) {
@@ -138,8 +156,8 @@
     }
     return false;
   } else {
-    if (tracker->current_state != *current) {
-      *current = tracker->current_state;
+    if (cur != *current) {
+      *current = cur;
       grpc_closure_sched(exec_ctx, notify,
                          GRPC_ERROR_REF(tracker->current_error));
     } else {
@@ -149,7 +167,7 @@
       w->next = tracker->watchers;
       tracker->watchers = w;
     }
-    return tracker->current_state == GRPC_CHANNEL_IDLE;
+    return cur == GRPC_CHANNEL_IDLE;
   }
 }
 
@@ -157,11 +175,14 @@
                                  grpc_connectivity_state_tracker *tracker,
                                  grpc_connectivity_state state,
                                  grpc_error *error, const char *reason) {
+  grpc_connectivity_state cur =
+      (grpc_connectivity_state)gpr_atm_no_barrier_load(
+          &tracker->current_state_atm);
   grpc_connectivity_state_watcher *w;
   if (grpc_connectivity_state_trace) {
     const char *error_string = grpc_error_string(error);
     gpr_log(GPR_DEBUG, "SET: %p %s: %s --> %s [%s] error=%p %s", tracker,
-            tracker->name, grpc_connectivity_state_name(tracker->current_state),
+            tracker->name, grpc_connectivity_state_name(cur),
             grpc_connectivity_state_name(state), reason, error, error_string);
   }
   switch (state) {
@@ -178,13 +199,13 @@
   }
   GRPC_ERROR_UNREF(tracker->current_error);
   tracker->current_error = error;
-  if (tracker->current_state == state) {
+  if (cur == state) {
     return;
   }
-  GPR_ASSERT(tracker->current_state != GRPC_CHANNEL_SHUTDOWN);
-  tracker->current_state = state;
+  GPR_ASSERT(cur != GRPC_CHANNEL_SHUTDOWN);
+  gpr_atm_no_barrier_store(&tracker->current_state_atm, state);
   while ((w = tracker->watchers) != NULL) {
-    *w->current = tracker->current_state;
+    *w->current = state;
     tracker->watchers = w->next;
     if (grpc_connectivity_state_trace) {
       gpr_log(GPR_DEBUG, "NOTIFY: %p %s: %p", tracker, tracker->name,
diff --git a/src/core/lib/transport/connectivity_state.h b/src/core/lib/transport/connectivity_state.h
index 769c675..c9604c3 100644
--- a/src/core/lib/transport/connectivity_state.h
+++ b/src/core/lib/transport/connectivity_state.h
@@ -47,8 +47,8 @@
 } grpc_connectivity_state_watcher;
 
 typedef struct {
-  /** current connectivity state */
-  grpc_connectivity_state current_state;
+  /** current grpc_connectivity_state */
+  gpr_atm current_state_atm;
   /** error associated with state */
   grpc_error *current_error;
   /** all our watchers */
@@ -59,6 +59,7 @@
 
 extern int grpc_connectivity_state_trace;
 
+/** enum --> string conversion */
 const char *grpc_connectivity_state_name(grpc_connectivity_state state);
 
 void grpc_connectivity_state_init(grpc_connectivity_state_tracker *tracker,
@@ -68,22 +69,31 @@
                                      grpc_connectivity_state_tracker *tracker);
 
 /** Set connectivity state; not thread safe; access must be serialized with an
- * external lock */
+ *  external lock */
 void grpc_connectivity_state_set(grpc_exec_ctx *exec_ctx,
                                  grpc_connectivity_state_tracker *tracker,
                                  grpc_connectivity_state state,
                                  grpc_error *associated_error,
                                  const char *reason);
 
+/** Return true if this connectivity state has watchers.
+    Access must be serialized with an external lock. */
 bool grpc_connectivity_state_has_watchers(
     grpc_connectivity_state_tracker *tracker);
 
+/** Return the last seen connectivity state. No need to synchronize access. */
 grpc_connectivity_state grpc_connectivity_state_check(
-    grpc_connectivity_state_tracker *tracker, grpc_error **current_error);
+    grpc_connectivity_state_tracker *tracker);
+
+/** Return the last seen connectivity state, and the associated error.
+    Access must be serialized with an external lock. */
+grpc_connectivity_state grpc_connectivity_state_get(
+    grpc_connectivity_state_tracker *tracker, grpc_error **error);
 
 /** Return 1 if the channel should start connecting, 0 otherwise.
     If current==NULL cancel notify if it is already queued (success==0 in that
-    case) */
+    case).
+    Access must be serialized with an external lock. */
 bool grpc_connectivity_state_notify_on_state_change(
     grpc_exec_ctx *exec_ctx, grpc_connectivity_state_tracker *tracker,
     grpc_connectivity_state *current, grpc_closure *notify);
diff --git a/src/core/lib/transport/static_metadata.c b/src/core/lib/transport/static_metadata.c
index 750711b..c13ba23 100644
--- a/src/core/lib/transport/static_metadata.c
+++ b/src/core/lib/transport/static_metadata.c
@@ -55,64 +55,63 @@
     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, 108, 98,  45,  99,  111, 115,
-    116, 45,  98,  105, 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};
+    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};
 
 static void static_ref(void *unused) {}
 static void static_unref(grpc_exec_ctx *exec_ctx, void *unused) {}
@@ -221,7 +220,6 @@
     {&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] = {
@@ -258,188 +256,186 @@
     {.refcount = &grpc_static_metadata_refcounts[15],
      .data.refcounted = {g_bytes + 166, 8}},
     {.refcount = &grpc_static_metadata_refcounts[16],
-     .data.refcounted = {g_bytes + 174, 11}},
+     .data.refcounted = {g_bytes + 174, 12}},
     {.refcount = &grpc_static_metadata_refcounts[17],
-     .data.refcounted = {g_bytes + 185, 12}},
+     .data.refcounted = {g_bytes + 186, 16}},
     {.refcount = &grpc_static_metadata_refcounts[18],
-     .data.refcounted = {g_bytes + 197, 16}},
+     .data.refcounted = {g_bytes + 202, 14}},
     {.refcount = &grpc_static_metadata_refcounts[19],
-     .data.refcounted = {g_bytes + 213, 14}},
+     .data.refcounted = {g_bytes + 216, 0}},
     {.refcount = &grpc_static_metadata_refcounts[20],
-     .data.refcounted = {g_bytes + 227, 0}},
+     .data.refcounted = {g_bytes + 216, 19}},
     {.refcount = &grpc_static_metadata_refcounts[21],
-     .data.refcounted = {g_bytes + 227, 19}},
+     .data.refcounted = {g_bytes + 235, 12}},
     {.refcount = &grpc_static_metadata_refcounts[22],
-     .data.refcounted = {g_bytes + 246, 12}},
+     .data.refcounted = {g_bytes + 247, 30}},
     {.refcount = &grpc_static_metadata_refcounts[23],
-     .data.refcounted = {g_bytes + 258, 30}},
+     .data.refcounted = {g_bytes + 277, 31}},
     {.refcount = &grpc_static_metadata_refcounts[24],
-     .data.refcounted = {g_bytes + 288, 31}},
+     .data.refcounted = {g_bytes + 308, 36}},
     {.refcount = &grpc_static_metadata_refcounts[25],
-     .data.refcounted = {g_bytes + 319, 36}},
+     .data.refcounted = {g_bytes + 344, 1}},
     {.refcount = &grpc_static_metadata_refcounts[26],
-     .data.refcounted = {g_bytes + 355, 1}},
+     .data.refcounted = {g_bytes + 345, 1}},
     {.refcount = &grpc_static_metadata_refcounts[27],
-     .data.refcounted = {g_bytes + 356, 1}},
+     .data.refcounted = {g_bytes + 346, 1}},
     {.refcount = &grpc_static_metadata_refcounts[28],
-     .data.refcounted = {g_bytes + 357, 1}},
+     .data.refcounted = {g_bytes + 347, 8}},
     {.refcount = &grpc_static_metadata_refcounts[29],
-     .data.refcounted = {g_bytes + 358, 8}},
+     .data.refcounted = {g_bytes + 355, 4}},
     {.refcount = &grpc_static_metadata_refcounts[30],
-     .data.refcounted = {g_bytes + 366, 4}},
+     .data.refcounted = {g_bytes + 359, 7}},
     {.refcount = &grpc_static_metadata_refcounts[31],
-     .data.refcounted = {g_bytes + 370, 7}},
+     .data.refcounted = {g_bytes + 366, 8}},
     {.refcount = &grpc_static_metadata_refcounts[32],
-     .data.refcounted = {g_bytes + 377, 8}},
+     .data.refcounted = {g_bytes + 374, 16}},
     {.refcount = &grpc_static_metadata_refcounts[33],
-     .data.refcounted = {g_bytes + 385, 16}},
+     .data.refcounted = {g_bytes + 390, 4}},
     {.refcount = &grpc_static_metadata_refcounts[34],
-     .data.refcounted = {g_bytes + 401, 4}},
+     .data.refcounted = {g_bytes + 394, 3}},
     {.refcount = &grpc_static_metadata_refcounts[35],
-     .data.refcounted = {g_bytes + 405, 3}},
+     .data.refcounted = {g_bytes + 397, 3}},
     {.refcount = &grpc_static_metadata_refcounts[36],
-     .data.refcounted = {g_bytes + 408, 3}},
+     .data.refcounted = {g_bytes + 400, 4}},
     {.refcount = &grpc_static_metadata_refcounts[37],
-     .data.refcounted = {g_bytes + 411, 4}},
+     .data.refcounted = {g_bytes + 404, 5}},
     {.refcount = &grpc_static_metadata_refcounts[38],
-     .data.refcounted = {g_bytes + 415, 5}},
+     .data.refcounted = {g_bytes + 409, 4}},
     {.refcount = &grpc_static_metadata_refcounts[39],
-     .data.refcounted = {g_bytes + 420, 4}},
+     .data.refcounted = {g_bytes + 413, 3}},
     {.refcount = &grpc_static_metadata_refcounts[40],
-     .data.refcounted = {g_bytes + 424, 3}},
+     .data.refcounted = {g_bytes + 416, 3}},
     {.refcount = &grpc_static_metadata_refcounts[41],
-     .data.refcounted = {g_bytes + 427, 3}},
+     .data.refcounted = {g_bytes + 419, 1}},
     {.refcount = &grpc_static_metadata_refcounts[42],
-     .data.refcounted = {g_bytes + 430, 1}},
+     .data.refcounted = {g_bytes + 420, 11}},
     {.refcount = &grpc_static_metadata_refcounts[43],
-     .data.refcounted = {g_bytes + 431, 11}},
+     .data.refcounted = {g_bytes + 431, 3}},
     {.refcount = &grpc_static_metadata_refcounts[44],
-     .data.refcounted = {g_bytes + 442, 3}},
+     .data.refcounted = {g_bytes + 434, 3}},
     {.refcount = &grpc_static_metadata_refcounts[45],
-     .data.refcounted = {g_bytes + 445, 3}},
+     .data.refcounted = {g_bytes + 437, 3}},
     {.refcount = &grpc_static_metadata_refcounts[46],
-     .data.refcounted = {g_bytes + 448, 3}},
+     .data.refcounted = {g_bytes + 440, 3}},
     {.refcount = &grpc_static_metadata_refcounts[47],
-     .data.refcounted = {g_bytes + 451, 3}},
+     .data.refcounted = {g_bytes + 443, 3}},
     {.refcount = &grpc_static_metadata_refcounts[48],
-     .data.refcounted = {g_bytes + 454, 3}},
+     .data.refcounted = {g_bytes + 446, 14}},
     {.refcount = &grpc_static_metadata_refcounts[49],
-     .data.refcounted = {g_bytes + 457, 14}},
+     .data.refcounted = {g_bytes + 460, 15}},
     {.refcount = &grpc_static_metadata_refcounts[50],
-     .data.refcounted = {g_bytes + 471, 15}},
+     .data.refcounted = {g_bytes + 475, 13}},
     {.refcount = &grpc_static_metadata_refcounts[51],
-     .data.refcounted = {g_bytes + 486, 13}},
+     .data.refcounted = {g_bytes + 488, 15}},
     {.refcount = &grpc_static_metadata_refcounts[52],
-     .data.refcounted = {g_bytes + 499, 15}},
+     .data.refcounted = {g_bytes + 503, 13}},
     {.refcount = &grpc_static_metadata_refcounts[53],
-     .data.refcounted = {g_bytes + 514, 13}},
+     .data.refcounted = {g_bytes + 516, 6}},
     {.refcount = &grpc_static_metadata_refcounts[54],
-     .data.refcounted = {g_bytes + 527, 6}},
+     .data.refcounted = {g_bytes + 522, 27}},
     {.refcount = &grpc_static_metadata_refcounts[55],
-     .data.refcounted = {g_bytes + 533, 27}},
+     .data.refcounted = {g_bytes + 549, 3}},
     {.refcount = &grpc_static_metadata_refcounts[56],
-     .data.refcounted = {g_bytes + 560, 3}},
+     .data.refcounted = {g_bytes + 552, 5}},
     {.refcount = &grpc_static_metadata_refcounts[57],
-     .data.refcounted = {g_bytes + 563, 5}},
+     .data.refcounted = {g_bytes + 557, 13}},
     {.refcount = &grpc_static_metadata_refcounts[58],
-     .data.refcounted = {g_bytes + 568, 13}},
+     .data.refcounted = {g_bytes + 570, 13}},
     {.refcount = &grpc_static_metadata_refcounts[59],
-     .data.refcounted = {g_bytes + 581, 13}},
+     .data.refcounted = {g_bytes + 583, 19}},
     {.refcount = &grpc_static_metadata_refcounts[60],
-     .data.refcounted = {g_bytes + 594, 19}},
+     .data.refcounted = {g_bytes + 602, 16}},
     {.refcount = &grpc_static_metadata_refcounts[61],
-     .data.refcounted = {g_bytes + 613, 16}},
+     .data.refcounted = {g_bytes + 618, 16}},
     {.refcount = &grpc_static_metadata_refcounts[62],
-     .data.refcounted = {g_bytes + 629, 16}},
+     .data.refcounted = {g_bytes + 634, 14}},
     {.refcount = &grpc_static_metadata_refcounts[63],
-     .data.refcounted = {g_bytes + 645, 14}},
+     .data.refcounted = {g_bytes + 648, 16}},
     {.refcount = &grpc_static_metadata_refcounts[64],
-     .data.refcounted = {g_bytes + 659, 16}},
+     .data.refcounted = {g_bytes + 664, 13}},
     {.refcount = &grpc_static_metadata_refcounts[65],
-     .data.refcounted = {g_bytes + 675, 13}},
+     .data.refcounted = {g_bytes + 677, 6}},
     {.refcount = &grpc_static_metadata_refcounts[66],
-     .data.refcounted = {g_bytes + 688, 6}},
+     .data.refcounted = {g_bytes + 683, 4}},
     {.refcount = &grpc_static_metadata_refcounts[67],
-     .data.refcounted = {g_bytes + 694, 4}},
+     .data.refcounted = {g_bytes + 687, 4}},
     {.refcount = &grpc_static_metadata_refcounts[68],
-     .data.refcounted = {g_bytes + 698, 4}},
+     .data.refcounted = {g_bytes + 691, 6}},
     {.refcount = &grpc_static_metadata_refcounts[69],
-     .data.refcounted = {g_bytes + 702, 6}},
+     .data.refcounted = {g_bytes + 697, 7}},
     {.refcount = &grpc_static_metadata_refcounts[70],
-     .data.refcounted = {g_bytes + 708, 7}},
+     .data.refcounted = {g_bytes + 704, 4}},
     {.refcount = &grpc_static_metadata_refcounts[71],
-     .data.refcounted = {g_bytes + 715, 4}},
+     .data.refcounted = {g_bytes + 708, 8}},
     {.refcount = &grpc_static_metadata_refcounts[72],
-     .data.refcounted = {g_bytes + 719, 8}},
+     .data.refcounted = {g_bytes + 716, 17}},
     {.refcount = &grpc_static_metadata_refcounts[73],
-     .data.refcounted = {g_bytes + 727, 17}},
+     .data.refcounted = {g_bytes + 733, 13}},
     {.refcount = &grpc_static_metadata_refcounts[74],
-     .data.refcounted = {g_bytes + 744, 13}},
+     .data.refcounted = {g_bytes + 746, 8}},
     {.refcount = &grpc_static_metadata_refcounts[75],
-     .data.refcounted = {g_bytes + 757, 8}},
+     .data.refcounted = {g_bytes + 754, 19}},
     {.refcount = &grpc_static_metadata_refcounts[76],
-     .data.refcounted = {g_bytes + 765, 19}},
+     .data.refcounted = {g_bytes + 773, 13}},
     {.refcount = &grpc_static_metadata_refcounts[77],
-     .data.refcounted = {g_bytes + 784, 13}},
+     .data.refcounted = {g_bytes + 786, 4}},
     {.refcount = &grpc_static_metadata_refcounts[78],
-     .data.refcounted = {g_bytes + 797, 4}},
+     .data.refcounted = {g_bytes + 790, 8}},
     {.refcount = &grpc_static_metadata_refcounts[79],
-     .data.refcounted = {g_bytes + 801, 8}},
+     .data.refcounted = {g_bytes + 798, 12}},
     {.refcount = &grpc_static_metadata_refcounts[80],
-     .data.refcounted = {g_bytes + 809, 12}},
+     .data.refcounted = {g_bytes + 810, 18}},
     {.refcount = &grpc_static_metadata_refcounts[81],
-     .data.refcounted = {g_bytes + 821, 18}},
+     .data.refcounted = {g_bytes + 828, 19}},
     {.refcount = &grpc_static_metadata_refcounts[82],
-     .data.refcounted = {g_bytes + 839, 19}},
+     .data.refcounted = {g_bytes + 847, 5}},
     {.refcount = &grpc_static_metadata_refcounts[83],
-     .data.refcounted = {g_bytes + 858, 5}},
+     .data.refcounted = {g_bytes + 852, 7}},
     {.refcount = &grpc_static_metadata_refcounts[84],
-     .data.refcounted = {g_bytes + 863, 7}},
+     .data.refcounted = {g_bytes + 859, 7}},
     {.refcount = &grpc_static_metadata_refcounts[85],
-     .data.refcounted = {g_bytes + 870, 7}},
+     .data.refcounted = {g_bytes + 866, 11}},
     {.refcount = &grpc_static_metadata_refcounts[86],
-     .data.refcounted = {g_bytes + 877, 11}},
+     .data.refcounted = {g_bytes + 877, 6}},
     {.refcount = &grpc_static_metadata_refcounts[87],
-     .data.refcounted = {g_bytes + 888, 6}},
+     .data.refcounted = {g_bytes + 883, 10}},
     {.refcount = &grpc_static_metadata_refcounts[88],
-     .data.refcounted = {g_bytes + 894, 10}},
+     .data.refcounted = {g_bytes + 893, 25}},
     {.refcount = &grpc_static_metadata_refcounts[89],
-     .data.refcounted = {g_bytes + 904, 25}},
+     .data.refcounted = {g_bytes + 918, 17}},
     {.refcount = &grpc_static_metadata_refcounts[90],
-     .data.refcounted = {g_bytes + 929, 17}},
+     .data.refcounted = {g_bytes + 935, 4}},
     {.refcount = &grpc_static_metadata_refcounts[91],
-     .data.refcounted = {g_bytes + 946, 4}},
+     .data.refcounted = {g_bytes + 939, 3}},
     {.refcount = &grpc_static_metadata_refcounts[92],
-     .data.refcounted = {g_bytes + 950, 3}},
+     .data.refcounted = {g_bytes + 942, 16}},
     {.refcount = &grpc_static_metadata_refcounts[93],
-     .data.refcounted = {g_bytes + 953, 16}},
+     .data.refcounted = {g_bytes + 958, 16}},
     {.refcount = &grpc_static_metadata_refcounts[94],
-     .data.refcounted = {g_bytes + 969, 16}},
+     .data.refcounted = {g_bytes + 974, 13}},
     {.refcount = &grpc_static_metadata_refcounts[95],
-     .data.refcounted = {g_bytes + 985, 13}},
+     .data.refcounted = {g_bytes + 987, 12}},
     {.refcount = &grpc_static_metadata_refcounts[96],
-     .data.refcounted = {g_bytes + 998, 12}},
-    {.refcount = &grpc_static_metadata_refcounts[97],
-     .data.refcounted = {g_bytes + 1010, 21}},
+     .data.refcounted = {g_bytes + 999, 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, 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, 2, 4, 4, 6, 6, 8, 8};
 
 static const int8_t elems_r[] = {
-    10, 8,   -3,  0,  9,   21,  -76, 22,  0,   10,  -7,  20, 0,  19, 18, 17,
-    16, 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,  -49, -50, 16, -52, -53, -54, -54, -55, -56, -57, 0,  38, 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,  15,  14,  13,  12,  11, 10, 9,  8,  0};
+    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};
 static uint32_t elems_phash(uint32_t i) {
-  i -= 42;
-  uint32_t x = i % 96;
-  uint32_t y = i / 96;
+  i -= 41;
+  uint32_t x = i % 95;
+  uint32_t y = i / 95;
   uint32_t h = x;
   if (y < GPR_ARRAY_SIZE(elems_r)) {
     uint32_t delta = (uint32_t)elems_r[y];
@@ -449,30 +445,29 @@
 }
 
 static const uint16_t elem_keys[] = {
-    1009, 1010, 1011, 240,  241,  242,  243,  244,  138,  139,  42,   43,
-    429,  430,  431,  911,  912,  913,  712,  713,  1098, 522,  714,  1294,
-    1392, 1490, 1588, 4822, 4920, 4951, 5116, 5214, 5312, 1111, 5410, 5508,
-    5606, 5704, 5802, 5900, 5998, 6096, 6194, 6292, 6390, 6488, 6586, 6684,
-    6782, 6880, 6978, 7076, 7174, 7272, 7370, 7468, 7566, 7664, 7762, 7860,
-    7958, 8056, 8154, 8252, 8350, 1074, 1075, 1076, 1077, 8448, 8546, 8644,
-    8742, 8840, 8938, 9036, 9134, 314,  0,    0,    0,    0,    0,    0,
+    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,
     0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-    0,    0,    0,    0,    132,  231,  232,  0,    0,    0,    0,    0,
+    0,    0,    0,    130,  228,  229,  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};
 static const uint8_t elem_idxs[] = {
-    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,  56,  24,  25,  26,
-    27,  28,  29,  7,   30,  31,  32,  33,  34,  35,  36,  37,  38,  39,  40,
-    42,  43,  44,  45,  46,  47,  49,  50,  51,  52,  53,  54,  57,  58,  59,
-    60,  61,  62,  63,  64,  76,  78,  79,  80,  65,  66,  67,  68,  69,  71,
-    72,  73,  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};
+    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,
+    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};
 
 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 * 98 + b);
+  uint32_t k = (uint32_t)(a * 97 + 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]],
@@ -483,328 +478,324 @@
 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 + 355, 1}}},
+      .data.refcounted = {g_bytes + 345, 1}}},
     {{.refcount = &grpc_static_metadata_refcounts[7],
       .data.refcounted = {g_bytes + 50, 11}},
      {.refcount = &grpc_static_metadata_refcounts[27],
-      .data.refcounted = {g_bytes + 356, 1}}},
-    {{.refcount = &grpc_static_metadata_refcounts[7],
-      .data.refcounted = {g_bytes + 50, 11}},
+      .data.refcounted = {g_bytes + 346, 1}}},
+    {{.refcount = &grpc_static_metadata_refcounts[9],
+      .data.refcounted = {g_bytes + 77, 13}},
      {.refcount = &grpc_static_metadata_refcounts[28],
-      .data.refcounted = {g_bytes + 357, 1}}},
+      .data.refcounted = {g_bytes + 347, 8}}},
     {{.refcount = &grpc_static_metadata_refcounts[9],
       .data.refcounted = {g_bytes + 77, 13}},
      {.refcount = &grpc_static_metadata_refcounts[29],
-      .data.refcounted = {g_bytes + 358, 8}}},
+      .data.refcounted = {g_bytes + 355, 4}}},
     {{.refcount = &grpc_static_metadata_refcounts[9],
       .data.refcounted = {g_bytes + 77, 13}},
      {.refcount = &grpc_static_metadata_refcounts[30],
-      .data.refcounted = {g_bytes + 366, 4}}},
-    {{.refcount = &grpc_static_metadata_refcounts[9],
-      .data.refcounted = {g_bytes + 77, 13}},
-     {.refcount = &grpc_static_metadata_refcounts[31],
-      .data.refcounted = {g_bytes + 370, 7}}},
+      .data.refcounted = {g_bytes + 359, 7}}},
     {{.refcount = &grpc_static_metadata_refcounts[5],
       .data.refcounted = {g_bytes + 36, 2}},
-     {.refcount = &grpc_static_metadata_refcounts[32],
-      .data.refcounted = {g_bytes + 377, 8}}},
+     {.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[33],
-      .data.refcounted = {g_bytes + 385, 16}}},
+     {.refcount = &grpc_static_metadata_refcounts[32],
+      .data.refcounted = {g_bytes + 374, 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 + 401, 4}}},
+      .data.refcounted = {g_bytes + 394, 3}}},
     {{.refcount = &grpc_static_metadata_refcounts[2],
       .data.refcounted = {g_bytes + 12, 7}},
      {.refcount = &grpc_static_metadata_refcounts[35],
-      .data.refcounted = {g_bytes + 405, 3}}},
-    {{.refcount = &grpc_static_metadata_refcounts[2],
-      .data.refcounted = {g_bytes + 12, 7}},
+      .data.refcounted = {g_bytes + 397, 3}}},
+    {{.refcount = &grpc_static_metadata_refcounts[4],
+      .data.refcounted = {g_bytes + 29, 7}},
      {.refcount = &grpc_static_metadata_refcounts[36],
-      .data.refcounted = {g_bytes + 408, 3}}},
+      .data.refcounted = {g_bytes + 400, 4}}},
     {{.refcount = &grpc_static_metadata_refcounts[4],
       .data.refcounted = {g_bytes + 29, 7}},
      {.refcount = &grpc_static_metadata_refcounts[37],
-      .data.refcounted = {g_bytes + 411, 4}}},
+      .data.refcounted = {g_bytes + 404, 5}}},
     {{.refcount = &grpc_static_metadata_refcounts[4],
       .data.refcounted = {g_bytes + 29, 7}},
      {.refcount = &grpc_static_metadata_refcounts[38],
-      .data.refcounted = {g_bytes + 415, 5}}},
-    {{.refcount = &grpc_static_metadata_refcounts[4],
-      .data.refcounted = {g_bytes + 29, 7}},
-     {.refcount = &grpc_static_metadata_refcounts[39],
-      .data.refcounted = {g_bytes + 420, 4}}},
+      .data.refcounted = {g_bytes + 409, 4}}},
     {{.refcount = &grpc_static_metadata_refcounts[3],
       .data.refcounted = {g_bytes + 19, 10}},
-     {.refcount = &grpc_static_metadata_refcounts[20],
-      .data.refcounted = {g_bytes + 227, 0}}},
+     {.refcount = &grpc_static_metadata_refcounts[19],
+      .data.refcounted = {g_bytes + 216, 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[1],
       .data.refcounted = {g_bytes + 5, 7}},
      {.refcount = &grpc_static_metadata_refcounts[40],
-      .data.refcounted = {g_bytes + 424, 3}}},
-    {{.refcount = &grpc_static_metadata_refcounts[1],
-      .data.refcounted = {g_bytes + 5, 7}},
+      .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 + 427, 3}}},
+      .data.refcounted = {g_bytes + 419, 1}}},
     {{.refcount = &grpc_static_metadata_refcounts[0],
       .data.refcounted = {g_bytes + 0, 5}},
      {.refcount = &grpc_static_metadata_refcounts[42],
-      .data.refcounted = {g_bytes + 430, 1}}},
-    {{.refcount = &grpc_static_metadata_refcounts[0],
-      .data.refcounted = {g_bytes + 0, 5}},
+      .data.refcounted = {g_bytes + 420, 11}}},
+    {{.refcount = &grpc_static_metadata_refcounts[2],
+      .data.refcounted = {g_bytes + 12, 7}},
      {.refcount = &grpc_static_metadata_refcounts[43],
-      .data.refcounted = {g_bytes + 431, 11}}},
+      .data.refcounted = {g_bytes + 431, 3}}},
     {{.refcount = &grpc_static_metadata_refcounts[2],
       .data.refcounted = {g_bytes + 12, 7}},
      {.refcount = &grpc_static_metadata_refcounts[44],
-      .data.refcounted = {g_bytes + 442, 3}}},
+      .data.refcounted = {g_bytes + 434, 3}}},
     {{.refcount = &grpc_static_metadata_refcounts[2],
       .data.refcounted = {g_bytes + 12, 7}},
      {.refcount = &grpc_static_metadata_refcounts[45],
-      .data.refcounted = {g_bytes + 445, 3}}},
+      .data.refcounted = {g_bytes + 437, 3}}},
     {{.refcount = &grpc_static_metadata_refcounts[2],
       .data.refcounted = {g_bytes + 12, 7}},
      {.refcount = &grpc_static_metadata_refcounts[46],
-      .data.refcounted = {g_bytes + 448, 3}}},
+      .data.refcounted = {g_bytes + 440, 3}}},
     {{.refcount = &grpc_static_metadata_refcounts[2],
       .data.refcounted = {g_bytes + 12, 7}},
      {.refcount = &grpc_static_metadata_refcounts[47],
-      .data.refcounted = {g_bytes + 451, 3}}},
-    {{.refcount = &grpc_static_metadata_refcounts[2],
-      .data.refcounted = {g_bytes + 12, 7}},
-     {.refcount = &grpc_static_metadata_refcounts[48],
-      .data.refcounted = {g_bytes + 454, 3}}},
+      .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 + 457, 14}},
-     {.refcount = &grpc_static_metadata_refcounts[20],
-      .data.refcounted = {g_bytes + 227, 0}}},
-    {{.refcount = &grpc_static_metadata_refcounts[50],
-      .data.refcounted = {g_bytes + 471, 15}},
-     {.refcount = &grpc_static_metadata_refcounts[20],
-      .data.refcounted = {g_bytes + 227, 0}}},
-    {{.refcount = &grpc_static_metadata_refcounts[50],
-      .data.refcounted = {g_bytes + 471, 15}},
-     {.refcount = &grpc_static_metadata_refcounts[51],
-      .data.refcounted = {g_bytes + 486, 13}}},
+      .data.refcounted = {g_bytes + 460, 15}},
+     {.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[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}}},
     {{.refcount = &grpc_static_metadata_refcounts[52],
-      .data.refcounted = {g_bytes + 499, 15}},
-     {.refcount = &grpc_static_metadata_refcounts[20],
-      .data.refcounted = {g_bytes + 227, 0}}},
+      .data.refcounted = {g_bytes + 503, 13}},
+     {.refcount = &grpc_static_metadata_refcounts[19],
+      .data.refcounted = {g_bytes + 216, 0}}},
     {{.refcount = &grpc_static_metadata_refcounts[53],
-      .data.refcounted = {g_bytes + 514, 13}},
-     {.refcount = &grpc_static_metadata_refcounts[20],
-      .data.refcounted = {g_bytes + 227, 0}}},
+      .data.refcounted = {g_bytes + 516, 6}},
+     {.refcount = &grpc_static_metadata_refcounts[19],
+      .data.refcounted = {g_bytes + 216, 0}}},
     {{.refcount = &grpc_static_metadata_refcounts[54],
-      .data.refcounted = {g_bytes + 527, 6}},
-     {.refcount = &grpc_static_metadata_refcounts[20],
-      .data.refcounted = {g_bytes + 227, 0}}},
+      .data.refcounted = {g_bytes + 522, 27}},
+     {.refcount = &grpc_static_metadata_refcounts[19],
+      .data.refcounted = {g_bytes + 216, 0}}},
     {{.refcount = &grpc_static_metadata_refcounts[55],
-      .data.refcounted = {g_bytes + 533, 27}},
-     {.refcount = &grpc_static_metadata_refcounts[20],
-      .data.refcounted = {g_bytes + 227, 0}}},
+      .data.refcounted = {g_bytes + 549, 3}},
+     {.refcount = &grpc_static_metadata_refcounts[19],
+      .data.refcounted = {g_bytes + 216, 0}}},
     {{.refcount = &grpc_static_metadata_refcounts[56],
-      .data.refcounted = {g_bytes + 560, 3}},
-     {.refcount = &grpc_static_metadata_refcounts[20],
-      .data.refcounted = {g_bytes + 227, 0}}},
+      .data.refcounted = {g_bytes + 552, 5}},
+     {.refcount = &grpc_static_metadata_refcounts[19],
+      .data.refcounted = {g_bytes + 216, 0}}},
     {{.refcount = &grpc_static_metadata_refcounts[57],
-      .data.refcounted = {g_bytes + 563, 5}},
-     {.refcount = &grpc_static_metadata_refcounts[20],
-      .data.refcounted = {g_bytes + 227, 0}}},
+      .data.refcounted = {g_bytes + 557, 13}},
+     {.refcount = &grpc_static_metadata_refcounts[19],
+      .data.refcounted = {g_bytes + 216, 0}}},
     {{.refcount = &grpc_static_metadata_refcounts[58],
-      .data.refcounted = {g_bytes + 568, 13}},
-     {.refcount = &grpc_static_metadata_refcounts[20],
-      .data.refcounted = {g_bytes + 227, 0}}},
+      .data.refcounted = {g_bytes + 570, 13}},
+     {.refcount = &grpc_static_metadata_refcounts[19],
+      .data.refcounted = {g_bytes + 216, 0}}},
     {{.refcount = &grpc_static_metadata_refcounts[59],
-      .data.refcounted = {g_bytes + 581, 13}},
-     {.refcount = &grpc_static_metadata_refcounts[20],
-      .data.refcounted = {g_bytes + 227, 0}}},
+      .data.refcounted = {g_bytes + 583, 19}},
+     {.refcount = &grpc_static_metadata_refcounts[19],
+      .data.refcounted = {g_bytes + 216, 0}}},
     {{.refcount = &grpc_static_metadata_refcounts[60],
-      .data.refcounted = {g_bytes + 594, 19}},
-     {.refcount = &grpc_static_metadata_refcounts[20],
-      .data.refcounted = {g_bytes + 227, 0}}},
+      .data.refcounted = {g_bytes + 602, 16}},
+     {.refcount = &grpc_static_metadata_refcounts[19],
+      .data.refcounted = {g_bytes + 216, 0}}},
     {{.refcount = &grpc_static_metadata_refcounts[61],
-      .data.refcounted = {g_bytes + 613, 16}},
-     {.refcount = &grpc_static_metadata_refcounts[20],
-      .data.refcounted = {g_bytes + 227, 0}}},
+      .data.refcounted = {g_bytes + 618, 16}},
+     {.refcount = &grpc_static_metadata_refcounts[19],
+      .data.refcounted = {g_bytes + 216, 0}}},
     {{.refcount = &grpc_static_metadata_refcounts[62],
-      .data.refcounted = {g_bytes + 629, 16}},
-     {.refcount = &grpc_static_metadata_refcounts[20],
-      .data.refcounted = {g_bytes + 227, 0}}},
+      .data.refcounted = {g_bytes + 634, 14}},
+     {.refcount = &grpc_static_metadata_refcounts[19],
+      .data.refcounted = {g_bytes + 216, 0}}},
     {{.refcount = &grpc_static_metadata_refcounts[63],
-      .data.refcounted = {g_bytes + 645, 14}},
-     {.refcount = &grpc_static_metadata_refcounts[20],
-      .data.refcounted = {g_bytes + 227, 0}}},
+      .data.refcounted = {g_bytes + 648, 16}},
+     {.refcount = &grpc_static_metadata_refcounts[19],
+      .data.refcounted = {g_bytes + 216, 0}}},
     {{.refcount = &grpc_static_metadata_refcounts[64],
-      .data.refcounted = {g_bytes + 659, 16}},
-     {.refcount = &grpc_static_metadata_refcounts[20],
-      .data.refcounted = {g_bytes + 227, 0}}},
-    {{.refcount = &grpc_static_metadata_refcounts[65],
-      .data.refcounted = {g_bytes + 675, 13}},
-     {.refcount = &grpc_static_metadata_refcounts[20],
-      .data.refcounted = {g_bytes + 227, 0}}},
+      .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[20],
-      .data.refcounted = {g_bytes + 227, 0}}},
+     {.refcount = &grpc_static_metadata_refcounts[19],
+      .data.refcounted = {g_bytes + 216, 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}}},
     {{.refcount = &grpc_static_metadata_refcounts[66],
-      .data.refcounted = {g_bytes + 688, 6}},
-     {.refcount = &grpc_static_metadata_refcounts[20],
-      .data.refcounted = {g_bytes + 227, 0}}},
+      .data.refcounted = {g_bytes + 683, 4}},
+     {.refcount = &grpc_static_metadata_refcounts[19],
+      .data.refcounted = {g_bytes + 216, 0}}},
     {{.refcount = &grpc_static_metadata_refcounts[67],
-      .data.refcounted = {g_bytes + 694, 4}},
-     {.refcount = &grpc_static_metadata_refcounts[20],
-      .data.refcounted = {g_bytes + 227, 0}}},
+      .data.refcounted = {g_bytes + 687, 4}},
+     {.refcount = &grpc_static_metadata_refcounts[19],
+      .data.refcounted = {g_bytes + 216, 0}}},
     {{.refcount = &grpc_static_metadata_refcounts[68],
-      .data.refcounted = {g_bytes + 698, 4}},
-     {.refcount = &grpc_static_metadata_refcounts[20],
-      .data.refcounted = {g_bytes + 227, 0}}},
+      .data.refcounted = {g_bytes + 691, 6}},
+     {.refcount = &grpc_static_metadata_refcounts[19],
+      .data.refcounted = {g_bytes + 216, 0}}},
     {{.refcount = &grpc_static_metadata_refcounts[69],
-      .data.refcounted = {g_bytes + 702, 6}},
-     {.refcount = &grpc_static_metadata_refcounts[20],
-      .data.refcounted = {g_bytes + 227, 0}}},
+      .data.refcounted = {g_bytes + 697, 7}},
+     {.refcount = &grpc_static_metadata_refcounts[19],
+      .data.refcounted = {g_bytes + 216, 0}}},
     {{.refcount = &grpc_static_metadata_refcounts[70],
-      .data.refcounted = {g_bytes + 708, 7}},
-     {.refcount = &grpc_static_metadata_refcounts[20],
-      .data.refcounted = {g_bytes + 227, 0}}},
-    {{.refcount = &grpc_static_metadata_refcounts[71],
-      .data.refcounted = {g_bytes + 715, 4}},
-     {.refcount = &grpc_static_metadata_refcounts[20],
-      .data.refcounted = {g_bytes + 227, 0}}},
+      .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[20],
-      .data.refcounted = {g_bytes + 227, 0}}},
+     {.refcount = &grpc_static_metadata_refcounts[19],
+      .data.refcounted = {g_bytes + 216, 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}}},
     {{.refcount = &grpc_static_metadata_refcounts[72],
-      .data.refcounted = {g_bytes + 719, 8}},
-     {.refcount = &grpc_static_metadata_refcounts[20],
-      .data.refcounted = {g_bytes + 227, 0}}},
+      .data.refcounted = {g_bytes + 716, 17}},
+     {.refcount = &grpc_static_metadata_refcounts[19],
+      .data.refcounted = {g_bytes + 216, 0}}},
     {{.refcount = &grpc_static_metadata_refcounts[73],
-      .data.refcounted = {g_bytes + 727, 17}},
-     {.refcount = &grpc_static_metadata_refcounts[20],
-      .data.refcounted = {g_bytes + 227, 0}}},
+      .data.refcounted = {g_bytes + 733, 13}},
+     {.refcount = &grpc_static_metadata_refcounts[19],
+      .data.refcounted = {g_bytes + 216, 0}}},
     {{.refcount = &grpc_static_metadata_refcounts[74],
-      .data.refcounted = {g_bytes + 744, 13}},
-     {.refcount = &grpc_static_metadata_refcounts[20],
-      .data.refcounted = {g_bytes + 227, 0}}},
+      .data.refcounted = {g_bytes + 746, 8}},
+     {.refcount = &grpc_static_metadata_refcounts[19],
+      .data.refcounted = {g_bytes + 216, 0}}},
     {{.refcount = &grpc_static_metadata_refcounts[75],
-      .data.refcounted = {g_bytes + 757, 8}},
-     {.refcount = &grpc_static_metadata_refcounts[20],
-      .data.refcounted = {g_bytes + 227, 0}}},
+      .data.refcounted = {g_bytes + 754, 19}},
+     {.refcount = &grpc_static_metadata_refcounts[19],
+      .data.refcounted = {g_bytes + 216, 0}}},
     {{.refcount = &grpc_static_metadata_refcounts[76],
-      .data.refcounted = {g_bytes + 765, 19}},
-     {.refcount = &grpc_static_metadata_refcounts[20],
-      .data.refcounted = {g_bytes + 227, 0}}},
-    {{.refcount = &grpc_static_metadata_refcounts[77],
-      .data.refcounted = {g_bytes + 784, 13}},
-     {.refcount = &grpc_static_metadata_refcounts[20],
-      .data.refcounted = {g_bytes + 227, 0}}},
+      .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[20],
-      .data.refcounted = {g_bytes + 227, 0}}},
-    {{.refcount = &grpc_static_metadata_refcounts[16],
-      .data.refcounted = {g_bytes + 174, 11}},
-     {.refcount = &grpc_static_metadata_refcounts[20],
-      .data.refcounted = {g_bytes + 227, 0}}},
+     {.refcount = &grpc_static_metadata_refcounts[19],
+      .data.refcounted = {g_bytes + 216, 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}}},
     {{.refcount = &grpc_static_metadata_refcounts[78],
-      .data.refcounted = {g_bytes + 797, 4}},
-     {.refcount = &grpc_static_metadata_refcounts[20],
-      .data.refcounted = {g_bytes + 227, 0}}},
+      .data.refcounted = {g_bytes + 790, 8}},
+     {.refcount = &grpc_static_metadata_refcounts[19],
+      .data.refcounted = {g_bytes + 216, 0}}},
     {{.refcount = &grpc_static_metadata_refcounts[79],
-      .data.refcounted = {g_bytes + 801, 8}},
-     {.refcount = &grpc_static_metadata_refcounts[20],
-      .data.refcounted = {g_bytes + 227, 0}}},
+      .data.refcounted = {g_bytes + 798, 12}},
+     {.refcount = &grpc_static_metadata_refcounts[19],
+      .data.refcounted = {g_bytes + 216, 0}}},
     {{.refcount = &grpc_static_metadata_refcounts[80],
-      .data.refcounted = {g_bytes + 809, 12}},
-     {.refcount = &grpc_static_metadata_refcounts[20],
-      .data.refcounted = {g_bytes + 227, 0}}},
+      .data.refcounted = {g_bytes + 810, 18}},
+     {.refcount = &grpc_static_metadata_refcounts[19],
+      .data.refcounted = {g_bytes + 216, 0}}},
     {{.refcount = &grpc_static_metadata_refcounts[81],
-      .data.refcounted = {g_bytes + 821, 18}},
-     {.refcount = &grpc_static_metadata_refcounts[20],
-      .data.refcounted = {g_bytes + 227, 0}}},
+      .data.refcounted = {g_bytes + 828, 19}},
+     {.refcount = &grpc_static_metadata_refcounts[19],
+      .data.refcounted = {g_bytes + 216, 0}}},
     {{.refcount = &grpc_static_metadata_refcounts[82],
-      .data.refcounted = {g_bytes + 839, 19}},
-     {.refcount = &grpc_static_metadata_refcounts[20],
-      .data.refcounted = {g_bytes + 227, 0}}},
+      .data.refcounted = {g_bytes + 847, 5}},
+     {.refcount = &grpc_static_metadata_refcounts[19],
+      .data.refcounted = {g_bytes + 216, 0}}},
     {{.refcount = &grpc_static_metadata_refcounts[83],
-      .data.refcounted = {g_bytes + 858, 5}},
-     {.refcount = &grpc_static_metadata_refcounts[20],
-      .data.refcounted = {g_bytes + 227, 0}}},
+      .data.refcounted = {g_bytes + 852, 7}},
+     {.refcount = &grpc_static_metadata_refcounts[19],
+      .data.refcounted = {g_bytes + 216, 0}}},
     {{.refcount = &grpc_static_metadata_refcounts[84],
-      .data.refcounted = {g_bytes + 863, 7}},
-     {.refcount = &grpc_static_metadata_refcounts[20],
-      .data.refcounted = {g_bytes + 227, 0}}},
+      .data.refcounted = {g_bytes + 859, 7}},
+     {.refcount = &grpc_static_metadata_refcounts[19],
+      .data.refcounted = {g_bytes + 216, 0}}},
     {{.refcount = &grpc_static_metadata_refcounts[85],
-      .data.refcounted = {g_bytes + 870, 7}},
-     {.refcount = &grpc_static_metadata_refcounts[20],
-      .data.refcounted = {g_bytes + 227, 0}}},
+      .data.refcounted = {g_bytes + 866, 11}},
+     {.refcount = &grpc_static_metadata_refcounts[19],
+      .data.refcounted = {g_bytes + 216, 0}}},
     {{.refcount = &grpc_static_metadata_refcounts[86],
-      .data.refcounted = {g_bytes + 877, 11}},
-     {.refcount = &grpc_static_metadata_refcounts[20],
-      .data.refcounted = {g_bytes + 227, 0}}},
+      .data.refcounted = {g_bytes + 877, 6}},
+     {.refcount = &grpc_static_metadata_refcounts[19],
+      .data.refcounted = {g_bytes + 216, 0}}},
     {{.refcount = &grpc_static_metadata_refcounts[87],
-      .data.refcounted = {g_bytes + 888, 6}},
-     {.refcount = &grpc_static_metadata_refcounts[20],
-      .data.refcounted = {g_bytes + 227, 0}}},
+      .data.refcounted = {g_bytes + 883, 10}},
+     {.refcount = &grpc_static_metadata_refcounts[19],
+      .data.refcounted = {g_bytes + 216, 0}}},
     {{.refcount = &grpc_static_metadata_refcounts[88],
-      .data.refcounted = {g_bytes + 894, 10}},
-     {.refcount = &grpc_static_metadata_refcounts[20],
-      .data.refcounted = {g_bytes + 227, 0}}},
+      .data.refcounted = {g_bytes + 893, 25}},
+     {.refcount = &grpc_static_metadata_refcounts[19],
+      .data.refcounted = {g_bytes + 216, 0}}},
     {{.refcount = &grpc_static_metadata_refcounts[89],
-      .data.refcounted = {g_bytes + 904, 25}},
-     {.refcount = &grpc_static_metadata_refcounts[20],
-      .data.refcounted = {g_bytes + 227, 0}}},
-    {{.refcount = &grpc_static_metadata_refcounts[90],
-      .data.refcounted = {g_bytes + 929, 17}},
-     {.refcount = &grpc_static_metadata_refcounts[20],
-      .data.refcounted = {g_bytes + 227, 0}}},
+      .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[20],
-      .data.refcounted = {g_bytes + 227, 0}}},
+     {.refcount = &grpc_static_metadata_refcounts[19],
+      .data.refcounted = {g_bytes + 216, 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}}},
     {{.refcount = &grpc_static_metadata_refcounts[91],
-      .data.refcounted = {g_bytes + 946, 4}},
-     {.refcount = &grpc_static_metadata_refcounts[20],
-      .data.refcounted = {g_bytes + 227, 0}}},
+      .data.refcounted = {g_bytes + 939, 3}},
+     {.refcount = &grpc_static_metadata_refcounts[19],
+      .data.refcounted = {g_bytes + 216, 0}}},
     {{.refcount = &grpc_static_metadata_refcounts[92],
-      .data.refcounted = {g_bytes + 950, 3}},
-     {.refcount = &grpc_static_metadata_refcounts[20],
-      .data.refcounted = {g_bytes + 227, 0}}},
-    {{.refcount = &grpc_static_metadata_refcounts[93],
-      .data.refcounted = {g_bytes + 953, 16}},
-     {.refcount = &grpc_static_metadata_refcounts[20],
-      .data.refcounted = {g_bytes + 227, 0}}},
+      .data.refcounted = {g_bytes + 942, 16}},
+     {.refcount = &grpc_static_metadata_refcounts[19],
+      .data.refcounted = {g_bytes + 216, 0}}},
     {{.refcount = &grpc_static_metadata_refcounts[10],
       .data.refcounted = {g_bytes + 90, 20}},
-     {.refcount = &grpc_static_metadata_refcounts[29],
-      .data.refcounted = {g_bytes + 358, 8}}},
-    {{.refcount = &grpc_static_metadata_refcounts[10],
-      .data.refcounted = {g_bytes + 90, 20}},
-     {.refcount = &grpc_static_metadata_refcounts[31],
-      .data.refcounted = {g_bytes + 370, 7}}},
-    {{.refcount = &grpc_static_metadata_refcounts[10],
-      .data.refcounted = {g_bytes + 90, 20}},
-     {.refcount = &grpc_static_metadata_refcounts[94],
-      .data.refcounted = {g_bytes + 969, 16}}},
+     {.refcount = &grpc_static_metadata_refcounts[28],
+      .data.refcounted = {g_bytes + 347, 8}}},
     {{.refcount = &grpc_static_metadata_refcounts[10],
       .data.refcounted = {g_bytes + 90, 20}},
      {.refcount = &grpc_static_metadata_refcounts[30],
-      .data.refcounted = {g_bytes + 366, 4}}},
+      .data.refcounted = {g_bytes + 359, 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[10],
+      .data.refcounted = {g_bytes + 90, 20}},
+     {.refcount = &grpc_static_metadata_refcounts[29],
+      .data.refcounted = {g_bytes + 355, 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[10],
       .data.refcounted = {g_bytes + 90, 20}},
      {.refcount = &grpc_static_metadata_refcounts[95],
-      .data.refcounted = {g_bytes + 985, 13}}},
+      .data.refcounted = {g_bytes + 987, 12}}},
     {{.refcount = &grpc_static_metadata_refcounts[10],
       .data.refcounted = {g_bytes + 90, 20}},
      {.refcount = &grpc_static_metadata_refcounts[96],
-      .data.refcounted = {g_bytes + 998, 12}}},
-    {{.refcount = &grpc_static_metadata_refcounts[10],
-      .data.refcounted = {g_bytes + 90, 20}},
-     {.refcount = &grpc_static_metadata_refcounts[97],
-      .data.refcounted = {g_bytes + 1010, 21}}},
+      .data.refcounted = {g_bytes + 999, 21}}},
 };
-const uint8_t grpc_static_accept_encoding_metadata[8] = {0,  74, 75, 76,
-                                                         77, 78, 79, 80};
+const uint8_t grpc_static_accept_encoding_metadata[8] = {0,  73, 74, 75,
+                                                         76, 77, 78, 79};
diff --git a/src/core/lib/transport/static_metadata.h b/src/core/lib/transport/static_metadata.h
index 7649ccd..f9600ee 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 98
+#define GRPC_STATIC_MDSTR_COUNT 97
 extern const grpc_slice grpc_static_slice_table[GRPC_STATIC_MDSTR_COUNT];
 /* ":path" */
 #define GRPC_MDSTR_PATH (grpc_static_slice_table[0])
@@ -78,174 +78,172 @@
 #define GRPC_MDSTR_HOST (grpc_static_slice_table[14])
 /* "lb-token" */
 #define GRPC_MDSTR_LB_TOKEN (grpc_static_slice_table[15])
-/* "lb-cost-bin" */
-#define GRPC_MDSTR_LB_COST_BIN (grpc_static_slice_table[16])
 /* "grpc-timeout" */
-#define GRPC_MDSTR_GRPC_TIMEOUT (grpc_static_slice_table[17])
+#define GRPC_MDSTR_GRPC_TIMEOUT (grpc_static_slice_table[16])
 /* "grpc-tracing-bin" */
-#define GRPC_MDSTR_GRPC_TRACING_BIN (grpc_static_slice_table[18])
+#define GRPC_MDSTR_GRPC_TRACING_BIN (grpc_static_slice_table[17])
 /* "grpc-stats-bin" */
-#define GRPC_MDSTR_GRPC_STATS_BIN (grpc_static_slice_table[19])
+#define GRPC_MDSTR_GRPC_STATS_BIN (grpc_static_slice_table[18])
 /* "" */
-#define GRPC_MDSTR_EMPTY (grpc_static_slice_table[20])
+#define GRPC_MDSTR_EMPTY (grpc_static_slice_table[19])
 /* "grpc.wait_for_ready" */
-#define GRPC_MDSTR_GRPC_DOT_WAIT_FOR_READY (grpc_static_slice_table[21])
+#define GRPC_MDSTR_GRPC_DOT_WAIT_FOR_READY (grpc_static_slice_table[20])
 /* "grpc.timeout" */
-#define GRPC_MDSTR_GRPC_DOT_TIMEOUT (grpc_static_slice_table[22])
+#define GRPC_MDSTR_GRPC_DOT_TIMEOUT (grpc_static_slice_table[21])
 /* "grpc.max_request_message_bytes" */
 #define GRPC_MDSTR_GRPC_DOT_MAX_REQUEST_MESSAGE_BYTES \
-  (grpc_static_slice_table[23])
+  (grpc_static_slice_table[22])
 /* "grpc.max_response_message_bytes" */
 #define GRPC_MDSTR_GRPC_DOT_MAX_RESPONSE_MESSAGE_BYTES \
-  (grpc_static_slice_table[24])
+  (grpc_static_slice_table[23])
 /* "/grpc.lb.v1.LoadBalancer/BalanceLoad" */
 #define GRPC_MDSTR_SLASH_GRPC_DOT_LB_DOT_V1_DOT_LOADBALANCER_SLASH_BALANCELOAD \
-  (grpc_static_slice_table[25])
+  (grpc_static_slice_table[24])
 /* "0" */
-#define GRPC_MDSTR_0 (grpc_static_slice_table[26])
+#define GRPC_MDSTR_0 (grpc_static_slice_table[25])
 /* "1" */
-#define GRPC_MDSTR_1 (grpc_static_slice_table[27])
+#define GRPC_MDSTR_1 (grpc_static_slice_table[26])
 /* "2" */
-#define GRPC_MDSTR_2 (grpc_static_slice_table[28])
+#define GRPC_MDSTR_2 (grpc_static_slice_table[27])
 /* "identity" */
-#define GRPC_MDSTR_IDENTITY (grpc_static_slice_table[29])
+#define GRPC_MDSTR_IDENTITY (grpc_static_slice_table[28])
 /* "gzip" */
-#define GRPC_MDSTR_GZIP (grpc_static_slice_table[30])
+#define GRPC_MDSTR_GZIP (grpc_static_slice_table[29])
 /* "deflate" */
-#define GRPC_MDSTR_DEFLATE (grpc_static_slice_table[31])
+#define GRPC_MDSTR_DEFLATE (grpc_static_slice_table[30])
 /* "trailers" */
-#define GRPC_MDSTR_TRAILERS (grpc_static_slice_table[32])
+#define GRPC_MDSTR_TRAILERS (grpc_static_slice_table[31])
 /* "application/grpc" */
-#define GRPC_MDSTR_APPLICATION_SLASH_GRPC (grpc_static_slice_table[33])
+#define GRPC_MDSTR_APPLICATION_SLASH_GRPC (grpc_static_slice_table[32])
 /* "POST" */
-#define GRPC_MDSTR_POST (grpc_static_slice_table[34])
+#define GRPC_MDSTR_POST (grpc_static_slice_table[33])
 /* "200" */
-#define GRPC_MDSTR_200 (grpc_static_slice_table[35])
+#define GRPC_MDSTR_200 (grpc_static_slice_table[34])
 /* "404" */
-#define GRPC_MDSTR_404 (grpc_static_slice_table[36])
+#define GRPC_MDSTR_404 (grpc_static_slice_table[35])
 /* "http" */
-#define GRPC_MDSTR_HTTP (grpc_static_slice_table[37])
+#define GRPC_MDSTR_HTTP (grpc_static_slice_table[36])
 /* "https" */
-#define GRPC_MDSTR_HTTPS (grpc_static_slice_table[38])
+#define GRPC_MDSTR_HTTPS (grpc_static_slice_table[37])
 /* "grpc" */
-#define GRPC_MDSTR_GRPC (grpc_static_slice_table[39])
+#define GRPC_MDSTR_GRPC (grpc_static_slice_table[38])
 /* "GET" */
-#define GRPC_MDSTR_GET (grpc_static_slice_table[40])
+#define GRPC_MDSTR_GET (grpc_static_slice_table[39])
 /* "PUT" */
-#define GRPC_MDSTR_PUT (grpc_static_slice_table[41])
+#define GRPC_MDSTR_PUT (grpc_static_slice_table[40])
 /* "/" */
-#define GRPC_MDSTR_SLASH (grpc_static_slice_table[42])
+#define GRPC_MDSTR_SLASH (grpc_static_slice_table[41])
 /* "/index.html" */
-#define GRPC_MDSTR_SLASH_INDEX_DOT_HTML (grpc_static_slice_table[43])
+#define GRPC_MDSTR_SLASH_INDEX_DOT_HTML (grpc_static_slice_table[42])
 /* "204" */
-#define GRPC_MDSTR_204 (grpc_static_slice_table[44])
+#define GRPC_MDSTR_204 (grpc_static_slice_table[43])
 /* "206" */
-#define GRPC_MDSTR_206 (grpc_static_slice_table[45])
+#define GRPC_MDSTR_206 (grpc_static_slice_table[44])
 /* "304" */
-#define GRPC_MDSTR_304 (grpc_static_slice_table[46])
+#define GRPC_MDSTR_304 (grpc_static_slice_table[45])
 /* "400" */
-#define GRPC_MDSTR_400 (grpc_static_slice_table[47])
+#define GRPC_MDSTR_400 (grpc_static_slice_table[46])
 /* "500" */
-#define GRPC_MDSTR_500 (grpc_static_slice_table[48])
+#define GRPC_MDSTR_500 (grpc_static_slice_table[47])
 /* "accept-charset" */
-#define GRPC_MDSTR_ACCEPT_CHARSET (grpc_static_slice_table[49])
+#define GRPC_MDSTR_ACCEPT_CHARSET (grpc_static_slice_table[48])
 /* "accept-encoding" */
-#define GRPC_MDSTR_ACCEPT_ENCODING (grpc_static_slice_table[50])
+#define GRPC_MDSTR_ACCEPT_ENCODING (grpc_static_slice_table[49])
 /* "gzip, deflate" */
-#define GRPC_MDSTR_GZIP_COMMA_DEFLATE (grpc_static_slice_table[51])
+#define GRPC_MDSTR_GZIP_COMMA_DEFLATE (grpc_static_slice_table[50])
 /* "accept-language" */
-#define GRPC_MDSTR_ACCEPT_LANGUAGE (grpc_static_slice_table[52])
+#define GRPC_MDSTR_ACCEPT_LANGUAGE (grpc_static_slice_table[51])
 /* "accept-ranges" */
-#define GRPC_MDSTR_ACCEPT_RANGES (grpc_static_slice_table[53])
+#define GRPC_MDSTR_ACCEPT_RANGES (grpc_static_slice_table[52])
 /* "accept" */
-#define GRPC_MDSTR_ACCEPT (grpc_static_slice_table[54])
+#define GRPC_MDSTR_ACCEPT (grpc_static_slice_table[53])
 /* "access-control-allow-origin" */
-#define GRPC_MDSTR_ACCESS_CONTROL_ALLOW_ORIGIN (grpc_static_slice_table[55])
+#define GRPC_MDSTR_ACCESS_CONTROL_ALLOW_ORIGIN (grpc_static_slice_table[54])
 /* "age" */
-#define GRPC_MDSTR_AGE (grpc_static_slice_table[56])
+#define GRPC_MDSTR_AGE (grpc_static_slice_table[55])
 /* "allow" */
-#define GRPC_MDSTR_ALLOW (grpc_static_slice_table[57])
+#define GRPC_MDSTR_ALLOW (grpc_static_slice_table[56])
 /* "authorization" */
-#define GRPC_MDSTR_AUTHORIZATION (grpc_static_slice_table[58])
+#define GRPC_MDSTR_AUTHORIZATION (grpc_static_slice_table[57])
 /* "cache-control" */
-#define GRPC_MDSTR_CACHE_CONTROL (grpc_static_slice_table[59])
+#define GRPC_MDSTR_CACHE_CONTROL (grpc_static_slice_table[58])
 /* "content-disposition" */
-#define GRPC_MDSTR_CONTENT_DISPOSITION (grpc_static_slice_table[60])
+#define GRPC_MDSTR_CONTENT_DISPOSITION (grpc_static_slice_table[59])
 /* "content-encoding" */
-#define GRPC_MDSTR_CONTENT_ENCODING (grpc_static_slice_table[61])
+#define GRPC_MDSTR_CONTENT_ENCODING (grpc_static_slice_table[60])
 /* "content-language" */
-#define GRPC_MDSTR_CONTENT_LANGUAGE (grpc_static_slice_table[62])
+#define GRPC_MDSTR_CONTENT_LANGUAGE (grpc_static_slice_table[61])
 /* "content-length" */
-#define GRPC_MDSTR_CONTENT_LENGTH (grpc_static_slice_table[63])
+#define GRPC_MDSTR_CONTENT_LENGTH (grpc_static_slice_table[62])
 /* "content-location" */
-#define GRPC_MDSTR_CONTENT_LOCATION (grpc_static_slice_table[64])
+#define GRPC_MDSTR_CONTENT_LOCATION (grpc_static_slice_table[63])
 /* "content-range" */
-#define GRPC_MDSTR_CONTENT_RANGE (grpc_static_slice_table[65])
+#define GRPC_MDSTR_CONTENT_RANGE (grpc_static_slice_table[64])
 /* "cookie" */
-#define GRPC_MDSTR_COOKIE (grpc_static_slice_table[66])
+#define GRPC_MDSTR_COOKIE (grpc_static_slice_table[65])
 /* "date" */
-#define GRPC_MDSTR_DATE (grpc_static_slice_table[67])
+#define GRPC_MDSTR_DATE (grpc_static_slice_table[66])
 /* "etag" */
-#define GRPC_MDSTR_ETAG (grpc_static_slice_table[68])
+#define GRPC_MDSTR_ETAG (grpc_static_slice_table[67])
 /* "expect" */
-#define GRPC_MDSTR_EXPECT (grpc_static_slice_table[69])
+#define GRPC_MDSTR_EXPECT (grpc_static_slice_table[68])
 /* "expires" */
-#define GRPC_MDSTR_EXPIRES (grpc_static_slice_table[70])
+#define GRPC_MDSTR_EXPIRES (grpc_static_slice_table[69])
 /* "from" */
-#define GRPC_MDSTR_FROM (grpc_static_slice_table[71])
+#define GRPC_MDSTR_FROM (grpc_static_slice_table[70])
 /* "if-match" */
-#define GRPC_MDSTR_IF_MATCH (grpc_static_slice_table[72])
+#define GRPC_MDSTR_IF_MATCH (grpc_static_slice_table[71])
 /* "if-modified-since" */
-#define GRPC_MDSTR_IF_MODIFIED_SINCE (grpc_static_slice_table[73])
+#define GRPC_MDSTR_IF_MODIFIED_SINCE (grpc_static_slice_table[72])
 /* "if-none-match" */
-#define GRPC_MDSTR_IF_NONE_MATCH (grpc_static_slice_table[74])
+#define GRPC_MDSTR_IF_NONE_MATCH (grpc_static_slice_table[73])
 /* "if-range" */
-#define GRPC_MDSTR_IF_RANGE (grpc_static_slice_table[75])
+#define GRPC_MDSTR_IF_RANGE (grpc_static_slice_table[74])
 /* "if-unmodified-since" */
-#define GRPC_MDSTR_IF_UNMODIFIED_SINCE (grpc_static_slice_table[76])
+#define GRPC_MDSTR_IF_UNMODIFIED_SINCE (grpc_static_slice_table[75])
 /* "last-modified" */
-#define GRPC_MDSTR_LAST_MODIFIED (grpc_static_slice_table[77])
+#define GRPC_MDSTR_LAST_MODIFIED (grpc_static_slice_table[76])
 /* "link" */
-#define GRPC_MDSTR_LINK (grpc_static_slice_table[78])
+#define GRPC_MDSTR_LINK (grpc_static_slice_table[77])
 /* "location" */
-#define GRPC_MDSTR_LOCATION (grpc_static_slice_table[79])
+#define GRPC_MDSTR_LOCATION (grpc_static_slice_table[78])
 /* "max-forwards" */
-#define GRPC_MDSTR_MAX_FORWARDS (grpc_static_slice_table[80])
+#define GRPC_MDSTR_MAX_FORWARDS (grpc_static_slice_table[79])
 /* "proxy-authenticate" */
-#define GRPC_MDSTR_PROXY_AUTHENTICATE (grpc_static_slice_table[81])
+#define GRPC_MDSTR_PROXY_AUTHENTICATE (grpc_static_slice_table[80])
 /* "proxy-authorization" */
-#define GRPC_MDSTR_PROXY_AUTHORIZATION (grpc_static_slice_table[82])
+#define GRPC_MDSTR_PROXY_AUTHORIZATION (grpc_static_slice_table[81])
 /* "range" */
-#define GRPC_MDSTR_RANGE (grpc_static_slice_table[83])
+#define GRPC_MDSTR_RANGE (grpc_static_slice_table[82])
 /* "referer" */
-#define GRPC_MDSTR_REFERER (grpc_static_slice_table[84])
+#define GRPC_MDSTR_REFERER (grpc_static_slice_table[83])
 /* "refresh" */
-#define GRPC_MDSTR_REFRESH (grpc_static_slice_table[85])
+#define GRPC_MDSTR_REFRESH (grpc_static_slice_table[84])
 /* "retry-after" */
-#define GRPC_MDSTR_RETRY_AFTER (grpc_static_slice_table[86])
+#define GRPC_MDSTR_RETRY_AFTER (grpc_static_slice_table[85])
 /* "server" */
-#define GRPC_MDSTR_SERVER (grpc_static_slice_table[87])
+#define GRPC_MDSTR_SERVER (grpc_static_slice_table[86])
 /* "set-cookie" */
-#define GRPC_MDSTR_SET_COOKIE (grpc_static_slice_table[88])
+#define GRPC_MDSTR_SET_COOKIE (grpc_static_slice_table[87])
 /* "strict-transport-security" */
-#define GRPC_MDSTR_STRICT_TRANSPORT_SECURITY (grpc_static_slice_table[89])
+#define GRPC_MDSTR_STRICT_TRANSPORT_SECURITY (grpc_static_slice_table[88])
 /* "transfer-encoding" */
-#define GRPC_MDSTR_TRANSFER_ENCODING (grpc_static_slice_table[90])
+#define GRPC_MDSTR_TRANSFER_ENCODING (grpc_static_slice_table[89])
 /* "vary" */
-#define GRPC_MDSTR_VARY (grpc_static_slice_table[91])
+#define GRPC_MDSTR_VARY (grpc_static_slice_table[90])
 /* "via" */
-#define GRPC_MDSTR_VIA (grpc_static_slice_table[92])
+#define GRPC_MDSTR_VIA (grpc_static_slice_table[91])
 /* "www-authenticate" */
-#define GRPC_MDSTR_WWW_AUTHENTICATE (grpc_static_slice_table[93])
+#define GRPC_MDSTR_WWW_AUTHENTICATE (grpc_static_slice_table[92])
 /* "identity,deflate" */
-#define GRPC_MDSTR_IDENTITY_COMMA_DEFLATE (grpc_static_slice_table[94])
+#define GRPC_MDSTR_IDENTITY_COMMA_DEFLATE (grpc_static_slice_table[93])
 /* "identity,gzip" */
-#define GRPC_MDSTR_IDENTITY_COMMA_GZIP (grpc_static_slice_table[95])
+#define GRPC_MDSTR_IDENTITY_COMMA_GZIP (grpc_static_slice_table[94])
 /* "deflate,gzip" */
-#define GRPC_MDSTR_DEFLATE_COMMA_GZIP (grpc_static_slice_table[96])
+#define GRPC_MDSTR_DEFLATE_COMMA_GZIP (grpc_static_slice_table[95])
 /* "identity,deflate,gzip" */
 #define GRPC_MDSTR_IDENTITY_COMMA_DEFLATE_COMMA_GZIP \
-  (grpc_static_slice_table[97])
+  (grpc_static_slice_table[96])
 
 extern const grpc_slice_refcount_vtable grpc_static_metadata_vtable;
 extern grpc_slice_refcount
@@ -257,7 +255,7 @@
 #define GRPC_STATIC_METADATA_INDEX(static_slice) \
   ((int)((static_slice).refcount - grpc_static_metadata_refcounts))
 
-#define GRPC_STATIC_MDELEM_COUNT 81
+#define GRPC_STATIC_MDELEM_COUNT 80
 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" */
@@ -428,81 +426,78 @@
 /* "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[57], GRPC_MDELEM_STORAGE_STATIC))
+  (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[56], GRPC_MDELEM_STORAGE_STATIC))
 /* "location": "" */
 #define GRPC_MDELEM_LOCATION_EMPTY \
-  (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[58], GRPC_MDELEM_STORAGE_STATIC))
+  (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[57], GRPC_MDELEM_STORAGE_STATIC))
 /* "max-forwards": "" */
 #define GRPC_MDELEM_MAX_FORWARDS_EMPTY \
-  (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[59], GRPC_MDELEM_STORAGE_STATIC))
+  (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[58], GRPC_MDELEM_STORAGE_STATIC))
 /* "proxy-authenticate": "" */
 #define GRPC_MDELEM_PROXY_AUTHENTICATE_EMPTY \
-  (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[60], GRPC_MDELEM_STORAGE_STATIC))
+  (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[59], GRPC_MDELEM_STORAGE_STATIC))
 /* "proxy-authorization": "" */
 #define GRPC_MDELEM_PROXY_AUTHORIZATION_EMPTY \
-  (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[61], GRPC_MDELEM_STORAGE_STATIC))
+  (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[60], GRPC_MDELEM_STORAGE_STATIC))
 /* "range": "" */
 #define GRPC_MDELEM_RANGE_EMPTY \
-  (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[62], GRPC_MDELEM_STORAGE_STATIC))
+  (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[61], GRPC_MDELEM_STORAGE_STATIC))
 /* "referer": "" */
 #define GRPC_MDELEM_REFERER_EMPTY \
-  (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[63], GRPC_MDELEM_STORAGE_STATIC))
+  (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[62], GRPC_MDELEM_STORAGE_STATIC))
 /* "refresh": "" */
 #define GRPC_MDELEM_REFRESH_EMPTY \
-  (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[64], GRPC_MDELEM_STORAGE_STATIC))
+  (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[63], GRPC_MDELEM_STORAGE_STATIC))
 /* "retry-after": "" */
 #define GRPC_MDELEM_RETRY_AFTER_EMPTY \
-  (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[65], GRPC_MDELEM_STORAGE_STATIC))
+  (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[64], GRPC_MDELEM_STORAGE_STATIC))
 /* "server": "" */
 #define GRPC_MDELEM_SERVER_EMPTY \
-  (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[66], GRPC_MDELEM_STORAGE_STATIC))
+  (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[65], GRPC_MDELEM_STORAGE_STATIC))
 /* "set-cookie": "" */
 #define GRPC_MDELEM_SET_COOKIE_EMPTY \
-  (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[67], GRPC_MDELEM_STORAGE_STATIC))
+  (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[66], GRPC_MDELEM_STORAGE_STATIC))
 /* "strict-transport-security": "" */
 #define GRPC_MDELEM_STRICT_TRANSPORT_SECURITY_EMPTY \
-  (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[68], GRPC_MDELEM_STORAGE_STATIC))
+  (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[67], GRPC_MDELEM_STORAGE_STATIC))
 /* "transfer-encoding": "" */
 #define GRPC_MDELEM_TRANSFER_ENCODING_EMPTY \
-  (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[69], GRPC_MDELEM_STORAGE_STATIC))
+  (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[68], GRPC_MDELEM_STORAGE_STATIC))
 /* "user-agent": "" */
 #define GRPC_MDELEM_USER_AGENT_EMPTY \
-  (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[70], GRPC_MDELEM_STORAGE_STATIC))
+  (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[69], GRPC_MDELEM_STORAGE_STATIC))
 /* "vary": "" */
 #define GRPC_MDELEM_VARY_EMPTY \
-  (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[71], GRPC_MDELEM_STORAGE_STATIC))
+  (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[70], GRPC_MDELEM_STORAGE_STATIC))
 /* "via": "" */
 #define GRPC_MDELEM_VIA_EMPTY \
-  (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[72], GRPC_MDELEM_STORAGE_STATIC))
+  (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[71], GRPC_MDELEM_STORAGE_STATIC))
 /* "www-authenticate": "" */
 #define GRPC_MDELEM_WWW_AUTHENTICATE_EMPTY \
-  (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[73], GRPC_MDELEM_STORAGE_STATIC))
+  (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[72], GRPC_MDELEM_STORAGE_STATIC))
 /* "grpc-accept-encoding": "identity" */
 #define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_IDENTITY \
-  (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[74], GRPC_MDELEM_STORAGE_STATIC))
+  (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[73], GRPC_MDELEM_STORAGE_STATIC))
 /* "grpc-accept-encoding": "deflate" */
 #define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_DEFLATE \
-  (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[75], GRPC_MDELEM_STORAGE_STATIC))
+  (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[74], 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[76], GRPC_MDELEM_STORAGE_STATIC))
+  (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[75], GRPC_MDELEM_STORAGE_STATIC))
 /* "grpc-accept-encoding": "gzip" */
 #define GRPC_MDELEM_GRPC_ACCEPT_ENCODING_GZIP \
-  (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[77], GRPC_MDELEM_STORAGE_STATIC))
+  (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[76], 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[78], GRPC_MDELEM_STORAGE_STATIC))
+  (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[77], 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[79], GRPC_MDELEM_STORAGE_STATIC))
+  (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[78], 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[80], GRPC_MDELEM_STORAGE_STATIC))
+  (GRPC_MAKE_MDELEM(&grpc_static_mdelem_table[79], GRPC_MDELEM_STORAGE_STATIC))
 
 grpc_mdelem grpc_static_mdelem_for_static_strings(int a, int b);
 typedef enum {
@@ -522,7 +517,6 @@
   GRPC_BATCH_USER_AGENT,
   GRPC_BATCH_HOST,
   GRPC_BATCH_LB_TOKEN,
-  GRPC_BATCH_LB_COST_BIN,
   GRPC_BATCH_CALLOUTS_COUNT
 } grpc_metadata_batch_callouts_index;
 
@@ -545,7 +539,6 @@
     struct grpc_linked_mdelem *user_agent;
     struct grpc_linked_mdelem *host;
     struct grpc_linked_mdelem *lb_token;
-    struct grpc_linked_mdelem *lb_cost_bin;
   } named;
 } grpc_metadata_batch_callouts;
 
diff --git a/src/core/lib/transport/transport.h b/src/core/lib/transport/transport.h
index 9a0abe1..e56bf27 100644
--- a/src/core/lib/transport/transport.h
+++ b/src/core/lib/transport/transport.h
@@ -167,9 +167,9 @@
 
   /***************************************************************************
    * remaining fields are initialized and used at the discretion of the
-   * transport implementation */
+   * current handler of the op */
 
-  grpc_transport_private_op_data transport_private;
+  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 */
diff --git a/src/cpp/server/health/default_health_check_service.cc b/src/cpp/server/health/default_health_check_service.cc
new file mode 100644
index 0000000..46def70
--- /dev/null
+++ b/src/cpp/server/health/default_health_check_service.cc
@@ -0,0 +1,166 @@
+/*
+ *
+ * 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 <memory>
+#include <mutex>
+
+#include <grpc++/impl/codegen/method_handler_impl.h>
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+
+#include "src/cpp/server/health/default_health_check_service.h"
+#include "src/cpp/server/health/health.pb.h"
+#include "third_party/nanopb/pb_decode.h"
+#include "third_party/nanopb/pb_encode.h"
+
+namespace grpc {
+namespace {
+const char kHealthCheckMethodName[] = "/grpc.health.v1.Health/Check";
+}  // namespace
+
+DefaultHealthCheckService::HealthCheckServiceImpl::HealthCheckServiceImpl(
+    DefaultHealthCheckService* service)
+    : service_(service), method_(nullptr) {
+  MethodHandler* handler =
+      new RpcMethodHandler<HealthCheckServiceImpl, ByteBuffer, ByteBuffer>(
+          std::mem_fn(&HealthCheckServiceImpl::Check), this);
+  method_ = new RpcServiceMethod(kHealthCheckMethodName, RpcMethod::NORMAL_RPC,
+                                 handler);
+  AddMethod(method_);
+}
+
+Status DefaultHealthCheckService::HealthCheckServiceImpl::Check(
+    ServerContext* context, const ByteBuffer* request, ByteBuffer* response) {
+  // Decode request.
+  std::vector<Slice> slices;
+  request->Dump(&slices);
+  uint8_t* request_bytes = nullptr;
+  bool request_bytes_owned = false;
+  size_t request_size = 0;
+  grpc_health_v1_HealthCheckRequest request_struct;
+  if (slices.empty()) {
+    request_struct.has_service = false;
+  } else if (slices.size() == 1) {
+    request_bytes = const_cast<uint8_t*>(slices[0].begin());
+    request_size = slices[0].size();
+  } else {
+    request_bytes_owned = true;
+    request_bytes = static_cast<uint8_t*>(gpr_malloc(request->Length()));
+    uint8_t* copy_to = request_bytes;
+    for (size_t i = 0; i < slices.size(); i++) {
+      memcpy(copy_to, slices[i].begin(), slices[i].size());
+      copy_to += slices[i].size();
+    }
+  }
+
+  if (request_bytes != nullptr) {
+    pb_istream_t istream = pb_istream_from_buffer(request_bytes, request_size);
+    bool decode_status = pb_decode(
+        &istream, grpc_health_v1_HealthCheckRequest_fields, &request_struct);
+    if (request_bytes_owned) {
+      gpr_free(request_bytes);
+    }
+    if (!decode_status) {
+      return Status(StatusCode::INVALID_ARGUMENT, "");
+    }
+  }
+
+  // Check status from the associated default health checking service.
+  DefaultHealthCheckService::ServingStatus serving_status =
+      service_->GetServingStatus(
+          request_struct.has_service ? request_struct.service : "");
+  if (serving_status == DefaultHealthCheckService::NOT_FOUND) {
+    return Status(StatusCode::NOT_FOUND, "");
+  }
+
+  // Encode response
+  grpc_health_v1_HealthCheckResponse response_struct;
+  response_struct.has_status = true;
+  response_struct.status =
+      serving_status == DefaultHealthCheckService::SERVING
+          ? grpc_health_v1_HealthCheckResponse_ServingStatus_SERVING
+          : grpc_health_v1_HealthCheckResponse_ServingStatus_NOT_SERVING;
+  pb_ostream_t ostream;
+  memset(&ostream, 0, sizeof(ostream));
+  pb_encode(&ostream, grpc_health_v1_HealthCheckResponse_fields,
+            &response_struct);
+  grpc_slice response_slice = grpc_slice_malloc(ostream.bytes_written);
+  ostream = pb_ostream_from_buffer(GRPC_SLICE_START_PTR(response_slice),
+                                   GRPC_SLICE_LENGTH(response_slice));
+  bool encode_status = pb_encode(
+      &ostream, grpc_health_v1_HealthCheckResponse_fields, &response_struct);
+  if (!encode_status) {
+    return Status(StatusCode::INTERNAL, "Failed to encode response.");
+  }
+  Slice encoded_response(response_slice, Slice::STEAL_REF);
+  ByteBuffer response_buffer(&encoded_response, 1);
+  response->Swap(&response_buffer);
+  return Status::OK;
+}
+
+DefaultHealthCheckService::DefaultHealthCheckService() {
+  services_map_.emplace("", true);
+}
+
+void DefaultHealthCheckService::SetServingStatus(
+    const grpc::string& service_name, bool serving) {
+  std::lock_guard<std::mutex> lock(mu_);
+  services_map_[service_name] = serving;
+}
+
+void DefaultHealthCheckService::SetServingStatus(bool serving) {
+  std::lock_guard<std::mutex> lock(mu_);
+  for (auto iter = services_map_.begin(); iter != services_map_.end(); ++iter) {
+    iter->second = serving;
+  }
+}
+
+DefaultHealthCheckService::ServingStatus
+DefaultHealthCheckService::GetServingStatus(
+    const grpc::string& service_name) const {
+  std::lock_guard<std::mutex> lock(mu_);
+  const auto& iter = services_map_.find(service_name);
+  if (iter == services_map_.end()) {
+    return NOT_FOUND;
+  }
+  return iter->second ? SERVING : NOT_SERVING;
+}
+
+DefaultHealthCheckService::HealthCheckServiceImpl*
+DefaultHealthCheckService::GetHealthCheckService() {
+  GPR_ASSERT(impl_ == nullptr);
+  impl_.reset(new HealthCheckServiceImpl(this));
+  return impl_.get();
+}
+
+}  // namespace grpc
diff --git a/src/cpp/server/health/default_health_check_service.h b/src/cpp/server/health/default_health_check_service.h
new file mode 100644
index 0000000..5c0e230
--- /dev/null
+++ b/src/cpp/server/health/default_health_check_service.h
@@ -0,0 +1,78 @@
+/*
+ *
+ * Copyright 2016, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef GRPC_INTERNAL_CPP_SERVER_DEFAULT_HEALTH_CHECK_SERVICE_H
+#define GRPC_INTERNAL_CPP_SERVER_DEFAULT_HEALTH_CHECK_SERVICE_H
+
+#include <mutex>
+
+#include <grpc++/health_check_service_interface.h>
+#include <grpc++/impl/codegen/service_type.h>
+#include <grpc++/support/byte_buffer.h>
+
+namespace grpc {
+
+// Default implementation of HealthCheckServiceInterface. Server will create and
+// own it.
+class DefaultHealthCheckService final : public HealthCheckServiceInterface {
+ public:
+  // The service impl to register with the server.
+  class HealthCheckServiceImpl : public Service {
+   public:
+    explicit HealthCheckServiceImpl(DefaultHealthCheckService* service);
+
+    Status Check(ServerContext* context, const ByteBuffer* request,
+                 ByteBuffer* response);
+
+   private:
+    const DefaultHealthCheckService* const service_;
+    RpcServiceMethod* method_;
+  };
+
+  DefaultHealthCheckService();
+  void SetServingStatus(const grpc::string& service_name,
+                        bool serving) override;
+  void SetServingStatus(bool serving) override;
+  enum ServingStatus { NOT_FOUND, SERVING, NOT_SERVING };
+  ServingStatus GetServingStatus(const grpc::string& service_name) const;
+  HealthCheckServiceImpl* GetHealthCheckService();
+
+ private:
+  mutable std::mutex mu_;
+  std::map<grpc::string, bool> services_map_;
+  std::unique_ptr<HealthCheckServiceImpl> impl_;
+};
+
+}  // namespace grpc
+
+#endif  // GRPC_INTERNAL_CPP_SERVER_DEFAULT_HEALTH_CHECK_SERVICE_H
diff --git a/src/cpp/server/health/health.pb.c b/src/cpp/server/health/health.pb.c
new file mode 100644
index 0000000..09bd98a
--- /dev/null
+++ b/src/cpp/server/health/health.pb.c
@@ -0,0 +1,24 @@
+/* Automatically generated nanopb constant definitions */
+/* Generated by nanopb-0.3.7-dev */
+
+#include "src/cpp/server/health/health.pb.h"
+
+/* @@protoc_insertion_point(includes) */
+#if PB_PROTO_HEADER_VERSION != 30
+#error Regenerate this file with the current version of nanopb generator.
+#endif
+
+
+
+const pb_field_t grpc_health_v1_HealthCheckRequest_fields[2] = {
+    PB_FIELD(  1, STRING  , OPTIONAL, STATIC  , FIRST, grpc_health_v1_HealthCheckRequest, service, service, 0),
+    PB_LAST_FIELD
+};
+
+const pb_field_t grpc_health_v1_HealthCheckResponse_fields[2] = {
+    PB_FIELD(  1, UENUM   , OPTIONAL, STATIC  , FIRST, grpc_health_v1_HealthCheckResponse, status, status, 0),
+    PB_LAST_FIELD
+};
+
+
+/* @@protoc_insertion_point(eof) */
diff --git a/src/cpp/server/health/health.pb.h b/src/cpp/server/health/health.pb.h
new file mode 100644
index 0000000..7051b32
--- /dev/null
+++ b/src/cpp/server/health/health.pb.h
@@ -0,0 +1,72 @@
+/* Automatically generated nanopb header */
+/* Generated by nanopb-0.3.7-dev */
+
+#ifndef PB_GRPC_HEALTH_V1_HEALTH_PB_H_INCLUDED
+#define PB_GRPC_HEALTH_V1_HEALTH_PB_H_INCLUDED
+#include "third_party/nanopb/pb.h"
+/* @@protoc_insertion_point(includes) */
+#if PB_PROTO_HEADER_VERSION != 30
+#error Regenerate this file with the current version of nanopb generator.
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Enum definitions */
+typedef enum _grpc_health_v1_HealthCheckResponse_ServingStatus {
+    grpc_health_v1_HealthCheckResponse_ServingStatus_UNKNOWN = 0,
+    grpc_health_v1_HealthCheckResponse_ServingStatus_SERVING = 1,
+    grpc_health_v1_HealthCheckResponse_ServingStatus_NOT_SERVING = 2
+} grpc_health_v1_HealthCheckResponse_ServingStatus;
+#define _grpc_health_v1_HealthCheckResponse_ServingStatus_MIN grpc_health_v1_HealthCheckResponse_ServingStatus_UNKNOWN
+#define _grpc_health_v1_HealthCheckResponse_ServingStatus_MAX grpc_health_v1_HealthCheckResponse_ServingStatus_NOT_SERVING
+#define _grpc_health_v1_HealthCheckResponse_ServingStatus_ARRAYSIZE ((grpc_health_v1_HealthCheckResponse_ServingStatus)(grpc_health_v1_HealthCheckResponse_ServingStatus_NOT_SERVING+1))
+
+/* Struct definitions */
+typedef struct _grpc_health_v1_HealthCheckRequest {
+    bool has_service;
+    char service[200];
+/* @@protoc_insertion_point(struct:grpc_health_v1_HealthCheckRequest) */
+} grpc_health_v1_HealthCheckRequest;
+
+typedef struct _grpc_health_v1_HealthCheckResponse {
+    bool has_status;
+    grpc_health_v1_HealthCheckResponse_ServingStatus status;
+/* @@protoc_insertion_point(struct:grpc_health_v1_HealthCheckResponse) */
+} grpc_health_v1_HealthCheckResponse;
+
+/* Default values for struct fields */
+
+/* Initializer values for message structs */
+#define grpc_health_v1_HealthCheckRequest_init_default {false, ""}
+#define grpc_health_v1_HealthCheckResponse_init_default {false, (grpc_health_v1_HealthCheckResponse_ServingStatus)0}
+#define grpc_health_v1_HealthCheckRequest_init_zero {false, ""}
+#define grpc_health_v1_HealthCheckResponse_init_zero {false, (grpc_health_v1_HealthCheckResponse_ServingStatus)0}
+
+/* Field tags (for use in manual encoding/decoding) */
+#define grpc_health_v1_HealthCheckRequest_service_tag 1
+#define grpc_health_v1_HealthCheckResponse_status_tag 1
+
+/* Struct field encoding specification for nanopb */
+extern const pb_field_t grpc_health_v1_HealthCheckRequest_fields[2];
+extern const pb_field_t grpc_health_v1_HealthCheckResponse_fields[2];
+
+/* Maximum encoded size of messages (where known) */
+#define grpc_health_v1_HealthCheckRequest_size   203
+#define grpc_health_v1_HealthCheckResponse_size  2
+
+/* Message IDs (where set with "msgid" option) */
+#ifdef PB_MSGID
+
+#define HEALTH_MESSAGES \
+
+
+#endif
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+/* @@protoc_insertion_point(eof) */
+
+#endif
diff --git a/src/cpp/test/server_context_test_spouse.cc b/src/cpp/server/health/health_check_service.cc
similarity index 69%
copy from src/cpp/test/server_context_test_spouse.cc
copy to src/cpp/server/health/health_check_service.cc
index b812d16..cca68c5 100644
--- a/src/cpp/test/server_context_test_spouse.cc
+++ b/src/cpp/server/health/health_check_service.cc
@@ -31,23 +31,19 @@
  *
  */
 
-#include <grpc++/test/server_context_test_spouse.h>
+#include <grpc++/health_check_service_interface.h>
 
 namespace grpc {
-namespace testing {
+namespace {
+bool g_grpc_default_health_check_service_enabled = false;
+}  // namesapce
 
-void ServerContextTestSpouse::AddClientMetadata(const grpc::string& key,
-                                                const grpc::string& value) {
-  client_metadata_storage_.insert(
-      std::pair<grpc::string, grpc::string>(key, value));
-  ctx_->client_metadata_.map()->clear();
-  for (auto iter = client_metadata_storage_.begin();
-       iter != client_metadata_storage_.end(); ++iter) {
-    ctx_->client_metadata_.map()->insert(
-        std::pair<grpc::string_ref, grpc::string_ref>(iter->first.c_str(),
-                                                      iter->second.c_str()));
-  }
+bool DefaultHealthCheckServiceEnabled() {
+  return g_grpc_default_health_check_service_enabled;
 }
 
-}  // namespace testing
+void EnableDefaultHealthCheckService(bool enable) {
+  g_grpc_default_health_check_service_enabled = enable;
+}
+
 }  // namespace grpc
diff --git a/src/cpp/test/server_context_test_spouse.cc b/src/cpp/server/health/health_check_service_server_builder_option.cc
similarity index 69%
rename from src/cpp/test/server_context_test_spouse.cc
rename to src/cpp/server/health/health_check_service_server_builder_option.cc
index b812d16..2426420 100644
--- a/src/cpp/test/server_context_test_spouse.cc
+++ b/src/cpp/server/health/health_check_service_server_builder_option.cc
@@ -31,23 +31,20 @@
  *
  */
 
-#include <grpc++/test/server_context_test_spouse.h>
+#include <grpc++/ext/health_check_service_server_builder_option.h>
 
 namespace grpc {
-namespace testing {
 
-void ServerContextTestSpouse::AddClientMetadata(const grpc::string& key,
-                                                const grpc::string& value) {
-  client_metadata_storage_.insert(
-      std::pair<grpc::string, grpc::string>(key, value));
-  ctx_->client_metadata_.map()->clear();
-  for (auto iter = client_metadata_storage_.begin();
-       iter != client_metadata_storage_.end(); ++iter) {
-    ctx_->client_metadata_.map()->insert(
-        std::pair<grpc::string_ref, grpc::string_ref>(iter->first.c_str(),
-                                                      iter->second.c_str()));
-  }
+HealthCheckServiceServerBuilderOption::HealthCheckServiceServerBuilderOption(
+    std::unique_ptr<HealthCheckServiceInterface> hc)
+    : hc_(std::move(hc)) {}
+// Hand over hc_ to the server.
+void HealthCheckServiceServerBuilderOption::UpdateArguments(
+    ChannelArguments* args) {
+  args->SetPointer(kHealthCheckServiceInterfaceArg, hc_.release());
 }
 
-}  // namespace testing
+void HealthCheckServiceServerBuilderOption::UpdatePlugins(
+    std::vector<std::unique_ptr<ServerBuilderPlugin>>* plugins) {}
+
 }  // namespace grpc
diff --git a/src/cpp/server/server_cc.cc b/src/cpp/server/server_cc.cc
index 29898a4..150c5a5 100644
--- a/src/cpp/server/server_cc.cc
+++ b/src/cpp/server/server_cc.cc
@@ -37,6 +37,7 @@
 
 #include <grpc++/completion_queue.h>
 #include <grpc++/generic/async_generic_service.h>
+#include <grpc++/impl/codegen/async_unary_call.h>
 #include <grpc++/impl/codegen/completion_queue_tag.h>
 #include <grpc++/impl/grpc_library.h>
 #include <grpc++/impl/method_handler_impl.h>
@@ -51,6 +52,7 @@
 #include <grpc/support/log.h>
 
 #include "src/core/lib/profiling/timers.h"
+#include "src/cpp/server/health/default_health_check_service.h"
 #include "src/cpp/thread_manager/thread_manager.h"
 
 namespace grpc {
@@ -186,7 +188,7 @@
    public:
     explicit CallData(Server* server, SyncRequest* mrd)
         : cq_(mrd->cq_),
-          call_(mrd->call_, server, &cq_),
+          call_(mrd->call_, server, &cq_, server->max_receive_message_size()),
           ctx_(mrd->deadline_, mrd->request_metadata_.metadata,
                mrd->request_metadata_.count),
           has_request_payload_(mrd->has_request_payload_),
@@ -342,6 +344,7 @@
   int cq_timeout_msec_;
   std::vector<std::unique_ptr<SyncRequest>> sync_requests_;
   std::unique_ptr<RpcServiceMethod> unknown_method_;
+  std::unique_ptr<RpcServiceMethod> health_check_;
   std::shared_ptr<Server::GlobalCallbacks> global_callbacks_;
 };
 
@@ -358,7 +361,8 @@
       shutdown_notified_(false),
       has_generic_service_(false),
       server_(nullptr),
-      server_initializer_(new ServerInitializer(this)) {
+      server_initializer_(new ServerInitializer(this)),
+      health_check_service_disabled_(false) {
   g_gli_initializer.summon();
   gpr_once_init(&g_once_init_callbacks, InitGlobalCallbacks);
   global_callbacks_ = g_callbacks;
@@ -374,6 +378,19 @@
   grpc_channel_args channel_args;
   args->SetChannelArgs(&channel_args);
 
+  for (size_t i = 0; i < channel_args.num_args; i++) {
+    if (0 ==
+        strcmp(channel_args.args[i].key, kHealthCheckServiceInterfaceArg)) {
+      if (channel_args.args[i].value.pointer.p == nullptr) {
+        health_check_service_disabled_ = true;
+      } else {
+        health_check_service_.reset(static_cast<HealthCheckServiceInterface*>(
+            channel_args.args[i].value.pointer.p));
+      }
+      break;
+    }
+  }
+
   server_ = grpc_server_create(&channel_args, nullptr);
 }
 
@@ -480,6 +497,21 @@
   GPR_ASSERT(!started_);
   global_callbacks_->PreServerStart(this);
   started_ = true;
+
+  // Only create default health check service when user did not provide an
+  // explicit one.
+  if (health_check_service_ == nullptr && !health_check_service_disabled_ &&
+      DefaultHealthCheckServiceEnabled()) {
+    if (sync_server_cqs_->empty()) {
+      gpr_log(GPR_ERROR,
+              "Default health check service disabled at async-only server.");
+    } else {
+      auto* default_hc_service = new DefaultHealthCheckService;
+      health_check_service_.reset(default_hc_service);
+      RegisterService(nullptr, default_hc_service->GetHealthCheckService());
+    }
+  }
+
   grpc_server_start(server_);
 
   if (!has_generic_service_) {
@@ -590,7 +622,7 @@
   }
   context_->set_call(call_);
   context_->cq_ = call_cq_;
-  Call call(call_, server_, call_cq_);
+  Call call(call_, server_, call_cq_, server_->max_receive_message_size());
   if (*status && call_) {
     context_->BeginCompletionOp(&call);
   }
diff --git a/src/cpp/server/server_context.cc b/src/cpp/server/server_context.cc
index a7aaa25..6edbc90 100644
--- a/src/cpp/server/server_context.cc
+++ b/src/cpp/server/server_context.cc
@@ -224,4 +224,20 @@
   return grpc_census_call_get_context(call_);
 }
 
+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());
+  }
+  grpc_call_set_load_reporting_cost_context(call_, cost_ctx);
+}
+
 }  // namespace grpc
diff --git a/src/csharp/Grpc.IntegrationTesting/InteropClient.cs b/src/csharp/Grpc.IntegrationTesting/InteropClient.cs
index 5ba83b1..68a8f48 100644
--- a/src/csharp/Grpc.IntegrationTesting/InteropClient.cs
+++ b/src/csharp/Grpc.IntegrationTesting/InteropClient.cs
@@ -56,7 +56,7 @@
     {
         private class ClientOptions
         {
-            [Option("server_host", Default = "127.0.0.1")]
+            [Option("server_host", Default = "localhost")]
             public string ServerHost { get; set; }
 
             [Option("server_host_override", Default = TestCredentials.DefaultHostOverride)]
diff --git a/src/php/ext/grpc/call.c b/src/php/ext/grpc/call.c
index be07190..48a374f 100644
--- a/src/php/ext/grpc/call.c
+++ b/src/php/ext/grpc/call.c
@@ -104,7 +104,8 @@
     str_key = ecalloc(key_len + 1, sizeof(char));
     memcpy(str_key, GRPC_SLICE_START_PTR(elem->key), key_len);
     str_val = ecalloc(GRPC_SLICE_LENGTH(elem->value) + 1, sizeof(char));
-    memcpy(str_val, GRPC_SLICE_START_PTR(elem->value), GRPC_SLICE_LENGTH(elem->value));
+    memcpy(str_val, GRPC_SLICE_START_PTR(elem->value),
+           GRPC_SLICE_LENGTH(elem->value));
     if (php_grpc_zend_hash_find(array_hash, str_key, key_len, (void **)&data)
         == SUCCESS) {
       if (Z_TYPE_P(data) != IS_ARRAY) {
@@ -115,7 +116,8 @@
         efree(str_val);
         return NULL;
       }
-      php_grpc_add_next_index_stringl(data, str_val, GRPC_SLICE_LENGTH(elem->value),
+      php_grpc_add_next_index_stringl(data, str_val,
+                                      GRPC_SLICE_LENGTH(elem->value),
                                       false);
     } else {
       PHP_GRPC_MAKE_STD_ZVAL(inner_array);
@@ -172,8 +174,10 @@
       if (Z_TYPE_P(value) != IS_STRING) {
         return false;
       }
-      metadata->metadata[metadata->count].key = grpc_slice_from_copied_string(key1);
-      metadata->metadata[metadata->count].value = grpc_slice_from_copied_buffer(Z_STRVAL_P(value), Z_STRLEN_P(value));
+      metadata->metadata[metadata->count].key =
+        grpc_slice_from_copied_string(key1);
+      metadata->metadata[metadata->count].value =
+        grpc_slice_from_copied_buffer(Z_STRVAL_P(value), Z_STRLEN_P(value));
       metadata->count += 1;
     PHP_GRPC_HASH_FOREACH_END()
   PHP_GRPC_HASH_FOREACH_END()
@@ -233,7 +237,8 @@
       grpc_slice_from_copied_string(host_override) : grpc_empty_slice();
   call->wrapped =
     grpc_channel_create_call(channel->wrapped, NULL, GRPC_PROPAGATE_DEFAULTS,
-                             completion_queue, method_slice, host_override != NULL ? &host_slice : NULL,
+                             completion_queue, method_slice,
+                             host_override != NULL ? &host_slice : NULL,
                              deadline->wrapped, NULL);
   grpc_slice_unref(method_slice);
   grpc_slice_unref(host_slice);
@@ -384,8 +389,10 @@
                                1 TSRMLS_CC);
           goto cleanup;
         }
-        send_status_details = grpc_slice_from_copied_string(Z_STRVAL_P(inner_value));
-        ops[op_num].data.send_status_from_server.status_details = &send_status_details;
+        send_status_details = grpc_slice_from_copied_string(
+          Z_STRVAL_P(inner_value));
+        ops[op_num].data.send_status_from_server.status_details =
+          &send_status_details;
       } else {
         zend_throw_exception(spl_ce_InvalidArgumentException,
                              "String status details is required",
@@ -557,12 +564,33 @@
   RETURN_LONG(error);
 }
 
+ZEND_BEGIN_ARG_INFO_EX(arginfo_construct, 0, 0, 3)
+  ZEND_ARG_INFO(0, channel)
+  ZEND_ARG_INFO(0, method)
+  ZEND_ARG_INFO(0, deadline)
+  ZEND_ARG_INFO(0, host_override)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_startBatch, 0, 0, 1)
+  ZEND_ARG_INFO(0, ops)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_getPeer, 0, 0, 0)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_cancel, 0, 0, 0)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_setCredentials, 0, 0, 1)
+  ZEND_ARG_INFO(0, credentials)
+ZEND_END_ARG_INFO()
+
 static zend_function_entry call_methods[] = {
-  PHP_ME(Call, __construct, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR)
-  PHP_ME(Call, startBatch, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(Call, getPeer, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(Call, cancel, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(Call, setCredentials, NULL, ZEND_ACC_PUBLIC)
+  PHP_ME(Call, __construct, arginfo_construct, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR)
+  PHP_ME(Call, startBatch, arginfo_startBatch, ZEND_ACC_PUBLIC)
+  PHP_ME(Call, getPeer, arginfo_getPeer, ZEND_ACC_PUBLIC)
+  PHP_ME(Call, cancel, arginfo_cancel, ZEND_ACC_PUBLIC)
+  PHP_ME(Call, setCredentials, arginfo_setCredentials, ZEND_ACC_PUBLIC)
   PHP_FE_END
 };
 
diff --git a/src/php/ext/grpc/call_credentials.c b/src/php/ext/grpc/call_credentials.c
index 043817f..625c0c6 100644
--- a/src/php/ext/grpc/call_credentials.c
+++ b/src/php/ext/grpc/call_credentials.c
@@ -212,10 +212,19 @@
   efree(state);
 }
 
+ZEND_BEGIN_ARG_INFO_EX(arginfo_createComposite, 0, 0, 2)
+  ZEND_ARG_INFO(0, creds1)
+  ZEND_ARG_INFO(0, creds2)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_createFromPlugin, 0, 0, 1)
+  ZEND_ARG_INFO(0, callback)
+ZEND_END_ARG_INFO()
+
 static zend_function_entry call_credentials_methods[] = {
-  PHP_ME(CallCredentials, createComposite, NULL,
+  PHP_ME(CallCredentials, createComposite, arginfo_createComposite,
          ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
-  PHP_ME(CallCredentials, createFromPlugin, NULL,
+  PHP_ME(CallCredentials, createFromPlugin, arginfo_createFromPlugin,
          ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
   PHP_FE_END
 };
diff --git a/src/php/ext/grpc/channel.c b/src/php/ext/grpc/channel.c
index 4ce4f30..c26fe4a 100644
--- a/src/php/ext/grpc/channel.c
+++ b/src/php/ext/grpc/channel.c
@@ -243,12 +243,37 @@
   }
 }
 
+ZEND_BEGIN_ARG_INFO_EX(arginfo_construct, 0, 0, 2)
+  ZEND_ARG_INFO(0, target)
+  ZEND_ARG_INFO(0, args)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_getTarget, 0, 0, 0)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_getConnectivityState, 0, 0, 0)
+  ZEND_ARG_INFO(0, try_to_connect)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_watchConnectivityState, 0, 0, 2)
+  ZEND_ARG_INFO(0, last_state)
+  ZEND_ARG_INFO(0, deadline)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_close, 0, 0, 0)
+ZEND_END_ARG_INFO()
+
 static zend_function_entry channel_methods[] = {
-  PHP_ME(Channel, __construct, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR)
-  PHP_ME(Channel, getTarget, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(Channel, getConnectivityState, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(Channel, watchConnectivityState, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(Channel, close, NULL, ZEND_ACC_PUBLIC)
+  PHP_ME(Channel, __construct, arginfo_construct,
+         ZEND_ACC_PUBLIC | ZEND_ACC_CTOR)
+  PHP_ME(Channel, getTarget, arginfo_getTarget,
+         ZEND_ACC_PUBLIC)
+  PHP_ME(Channel, getConnectivityState, arginfo_getConnectivityState,
+         ZEND_ACC_PUBLIC)
+  PHP_ME(Channel, watchConnectivityState, arginfo_watchConnectivityState,
+         ZEND_ACC_PUBLIC)
+  PHP_ME(Channel, close, arginfo_close,
+         ZEND_ACC_PUBLIC)
   PHP_FE_END
 };
 
diff --git a/src/php/ext/grpc/channel_credentials.c b/src/php/ext/grpc/channel_credentials.c
index 36a8223..2160a54 100644
--- a/src/php/ext/grpc/channel_credentials.c
+++ b/src/php/ext/grpc/channel_credentials.c
@@ -199,16 +199,37 @@
   RETURN_NULL();
 }
 
+ZEND_BEGIN_ARG_INFO_EX(arginfo_setDefaultRootsPem, 0, 0, 1)
+  ZEND_ARG_INFO(0, pem_roots)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_createDefault, 0, 0, 0)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_createSsl, 0, 0, 0)
+  ZEND_ARG_INFO(0, pem_root_certs)
+  ZEND_ARG_INFO(0, pem_private_key)
+  ZEND_ARG_INFO(0, pem_cert_chain)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_createComposite, 0, 0, 2)
+  ZEND_ARG_INFO(0, channel_creds)
+  ZEND_ARG_INFO(0, call_creds)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_createInsecure, 0, 0, 0)
+ZEND_END_ARG_INFO()
+
 static zend_function_entry channel_credentials_methods[] = {
-  PHP_ME(ChannelCredentials, setDefaultRootsPem, NULL,
+  PHP_ME(ChannelCredentials, setDefaultRootsPem, arginfo_setDefaultRootsPem,
          ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
-  PHP_ME(ChannelCredentials, createDefault, NULL,
+  PHP_ME(ChannelCredentials, createDefault, arginfo_createDefault,
          ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
-  PHP_ME(ChannelCredentials, createSsl, NULL,
+  PHP_ME(ChannelCredentials, createSsl, arginfo_createSsl,
          ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
-  PHP_ME(ChannelCredentials, createComposite, NULL,
+  PHP_ME(ChannelCredentials, createComposite, arginfo_createComposite,
          ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
-  PHP_ME(ChannelCredentials, createInsecure, NULL,
+  PHP_ME(ChannelCredentials, createInsecure, arginfo_createInsecure,
          ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
   PHP_FE_END
 };
diff --git a/src/php/ext/grpc/server.c b/src/php/ext/grpc/server.c
index 9ac5d2a..87780e9 100644
--- a/src/php/ext/grpc/server.c
+++ b/src/php/ext/grpc/server.c
@@ -116,8 +116,6 @@
 
 /**
  * Request a call on a server. Creates a single GRPC_SERVER_RPC_NEW event.
- * @param long $tag_new The tag to associate with the new request
- * @param long $tag_cancel The tag to use if the call is cancelled
  * @return void
  */
 PHP_METHOD(Server, requestCall) {
@@ -239,12 +237,36 @@
   grpc_server_start(server->wrapped);
 }
 
+ZEND_BEGIN_ARG_INFO_EX(arginfo_construct, 0, 0, 0)
+  ZEND_ARG_INFO(0, args)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_requestCall, 0, 0, 0)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_addHttp2Port, 0, 0, 1)
+  ZEND_ARG_INFO(0, addr)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_addSecureHttp2Port, 0, 0, 2)
+  ZEND_ARG_INFO(0, addr)
+  ZEND_ARG_INFO(0, server_creds)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_start, 0, 0, 0)
+ZEND_END_ARG_INFO()
+
 static zend_function_entry server_methods[] = {
-  PHP_ME(Server, __construct, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR)
-  PHP_ME(Server, requestCall, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(Server, addHttp2Port, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(Server, addSecureHttp2Port, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(Server, start, NULL, ZEND_ACC_PUBLIC)
+  PHP_ME(Server, __construct, arginfo_construct,
+         ZEND_ACC_PUBLIC | ZEND_ACC_CTOR)
+  PHP_ME(Server, requestCall, arginfo_requestCall,
+         ZEND_ACC_PUBLIC)
+  PHP_ME(Server, addHttp2Port, arginfo_addHttp2Port,
+         ZEND_ACC_PUBLIC)
+  PHP_ME(Server, addSecureHttp2Port, arginfo_addSecureHttp2Port,
+         ZEND_ACC_PUBLIC)
+  PHP_ME(Server, start, arginfo_start,
+         ZEND_ACC_PUBLIC)
   PHP_FE_END
 };
 
diff --git a/src/php/ext/grpc/server_credentials.c b/src/php/ext/grpc/server_credentials.c
index 3e39fee..ec29dfd 100644
--- a/src/php/ext/grpc/server_credentials.c
+++ b/src/php/ext/grpc/server_credentials.c
@@ -117,8 +117,14 @@
   RETURN_DESTROY_ZVAL(creds_object);
 }
 
+ZEND_BEGIN_ARG_INFO_EX(arginfo_createSsl, 0, 0, 3)
+  ZEND_ARG_INFO(0, pem_root_certs)
+  ZEND_ARG_INFO(0, pem_private_key)
+  ZEND_ARG_INFO(0, pem_cert_chain)
+ZEND_END_ARG_INFO()
+
 static zend_function_entry server_credentials_methods[] = {
-  PHP_ME(ServerCredentials, createSsl, NULL,
+  PHP_ME(ServerCredentials, createSsl, arginfo_createSsl,
          ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
   PHP_FE_END
  };
diff --git a/src/php/ext/grpc/timeval.c b/src/php/ext/grpc/timeval.c
index 7ada915..78c29e3 100644
--- a/src/php/ext/grpc/timeval.c
+++ b/src/php/ext/grpc/timeval.c
@@ -245,17 +245,65 @@
   gpr_sleep_until(this->wrapped);
 }
 
+ZEND_BEGIN_ARG_INFO_EX(arginfo_construct, 0, 0, 1)
+  ZEND_ARG_INFO(0, microseconds)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_add, 0, 0, 1)
+  ZEND_ARG_INFO(0, timeval)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_compare, 0, 0, 2)
+  ZEND_ARG_INFO(0, a_timeval)
+  ZEND_ARG_INFO(0, b_timeval)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_infFuture, 0, 0, 0)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_infPast, 0, 0, 0)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_now, 0, 0, 0)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_similar, 0, 0, 3)
+  ZEND_ARG_INFO(0, a_timeval)
+  ZEND_ARG_INFO(0, b_timeval)
+  ZEND_ARG_INFO(0, threshold_timeval)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_sleepUntil, 0, 0, 0)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_subtract, 0, 0, 1)
+  ZEND_ARG_INFO(0, timeval)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO_EX(arginfo_zero, 0, 0, 0)
+ZEND_END_ARG_INFO()
+
 static zend_function_entry timeval_methods[] = {
-  PHP_ME(Timeval, __construct, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_CTOR)
-  PHP_ME(Timeval, add, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(Timeval, compare, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
-  PHP_ME(Timeval, infFuture, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
-  PHP_ME(Timeval, infPast, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
-  PHP_ME(Timeval, now, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
-  PHP_ME(Timeval, similar, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
-  PHP_ME(Timeval, sleepUntil, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(Timeval, subtract, NULL, ZEND_ACC_PUBLIC)
-  PHP_ME(Timeval, zero, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
+  PHP_ME(Timeval, __construct, arginfo_construct,
+         ZEND_ACC_PUBLIC | ZEND_ACC_CTOR)
+  PHP_ME(Timeval, add, arginfo_add,
+         ZEND_ACC_PUBLIC)
+  PHP_ME(Timeval, compare, arginfo_compare,
+         ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
+  PHP_ME(Timeval, infFuture, arginfo_infFuture,
+         ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
+  PHP_ME(Timeval, infPast, arginfo_infPast,
+         ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
+  PHP_ME(Timeval, now, arginfo_now,
+         ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
+  PHP_ME(Timeval, similar, arginfo_similar,
+         ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
+  PHP_ME(Timeval, sleepUntil, arginfo_sleepUntil,
+         ZEND_ACC_PUBLIC)
+  PHP_ME(Timeval, subtract, arginfo_subtract,
+         ZEND_ACC_PUBLIC)
+  PHP_ME(Timeval, zero, arginfo_zero,
+         ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
   PHP_FE_END
 };
 
diff --git a/src/proto/grpc/health/v1/health.options b/src/proto/grpc/health/v1/health.options
new file mode 100644
index 0000000..240b498
--- /dev/null
+++ b/src/proto/grpc/health/v1/health.options
@@ -0,0 +1 @@
+grpc.health.v1.HealthCheckRequest.service max_size:200
diff --git a/src/python/grpcio_tests/tests/interop/client.py b/src/python/grpcio_tests/tests/interop/client.py
index 833818e..97f6843 100644
--- a/src/python/grpcio_tests/tests/interop/client.py
+++ b/src/python/grpcio_tests/tests/interop/client.py
@@ -45,7 +45,7 @@
         '--server_host',
         help='the host to which to connect',
         type=str,
-        default="127.0.0.1")
+        default="localhost")
     parser.add_argument(
         '--server_port', help='the port to which to connect', type=int)
     parser.add_argument(
diff --git a/src/ruby/ext/grpc/rb_grpc_imports.generated.c b/src/ruby/ext/grpc/rb_grpc_imports.generated.c
index d8d76cc..b8af800 100644
--- a/src/ruby/ext/grpc/rb_grpc_imports.generated.c
+++ b/src/ruby/ext/grpc/rb_grpc_imports.generated.c
@@ -107,6 +107,7 @@
 grpc_channel_create_registered_call_type grpc_channel_create_registered_call_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;
@@ -398,6 +399,7 @@
   grpc_channel_create_registered_call_import = (grpc_channel_create_registered_call_type) GetProcAddress(library, "grpc_channel_create_registered_call");
   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");
diff --git a/src/ruby/ext/grpc/rb_grpc_imports.generated.h b/src/ruby/ext/grpc/rb_grpc_imports.generated.h
index 4eab963..3229e2a 100644
--- a/src/ruby/ext/grpc/rb_grpc_imports.generated.h
+++ b/src/ruby/ext/grpc/rb_grpc_imports.generated.h
@@ -272,6 +272,9 @@
 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
diff --git a/src/ruby/lib/grpc/generic/client_stub.rb b/src/ruby/lib/grpc/generic/client_stub.rb
index 6934257..d8de0be 100644
--- a/src/ruby/lib/grpc/generic/client_stub.rb
+++ b/src/ruby/lib/grpc/generic/client_stub.rb
@@ -84,7 +84,7 @@
     # channel:
     #
     # - :channel_override
-    # when present, this must be a pre-created GRPC::Channel.  If it's
+    # when present, this must be a pre-created GRPC::Core::Channel.  If it's
     # present the host and arbitrary keyword arg areignored, and the RPC
     # connection uses this channel.
     #
diff --git a/test/core/client_channel/BUILD b/test/core/client_channel/BUILD
new file mode 100644
index 0000000..a29e9ac
--- /dev/null
+++ b/test/core/client_channel/BUILD
@@ -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.
+
+licenses(["notice"])  # 3-clause BSD
+
+load("//test/core/util:grpc_fuzzer.bzl", "grpc_fuzzer")
+
+grpc_fuzzer(
+  name = "uri_fuzzer_test",
+  srcs = ["uri_fuzzer_test.c"],
+  deps = ["//:gpr", "//:grpc", "//test/core/util:grpc_test_util"],
+  corpus = "uri_corpus",
+  copts = ["-std=c99"],
+)
+
+cc_test(
+    name = "lb_policies_test",
+    srcs = ["lb_policies_test.c"],
+    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/resolvers/BUILD b/test/core/client_channel/resolvers/BUILD
new file mode 100644
index 0000000..af37072
--- /dev/null
+++ b/test/core/client_channel/resolvers/BUILD
@@ -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.
+
+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']
+)
+
+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']
+)
+
+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']
+)
diff --git a/test/core/end2end/bad_server_response_test.c b/test/core/end2end/bad_server_response_test.c
index 42d960c..39a98e8 100644
--- a/test/core/end2end/bad_server_response_test.c
+++ b/test/core/end2end/bad_server_response_test.c
@@ -82,7 +82,9 @@
 #define HTTP1_DETAIL_MSG "Trying to connect an http1.x server"
 
 /* TODO(zyc) Check the content of incomming data instead of using this length */
-#define EXPECTED_INCOMING_DATA_LENGTH (size_t)310
+/* The 'bad' server will start sending responses after reading this amount of
+ * data from the client. */
+#define SERVER_INCOMING_DATA_LENGTH_LOWER_THRESHOLD (size_t)200
 
 struct rpc_state {
   char *target;
@@ -134,8 +136,10 @@
   }
 
   gpr_log(GPR_DEBUG, "got %" PRIuPTR " bytes, expected %" PRIuPTR " bytes",
-          state.incoming_data_length, EXPECTED_INCOMING_DATA_LENGTH);
-  if (state.incoming_data_length >= EXPECTED_INCOMING_DATA_LENGTH) {
+          state.incoming_data_length,
+          SERVER_INCOMING_DATA_LENGTH_LOWER_THRESHOLD);
+  if (state.incoming_data_length >=
+      SERVER_INCOMING_DATA_LENGTH_LOWER_THRESHOLD) {
     handle_write(exec_ctx);
   } else {
     grpc_endpoint_read(exec_ctx, state.tcp, &state.temp_incoming_buffer,
diff --git a/test/core/end2end/fixtures/http_proxy.c b/test/core/end2end/fixtures/http_proxy.c
index 6fdc86f..2682ea0 100644
--- a/test/core/end2end/fixtures/http_proxy.c
+++ b/test/core/end2end/fixtures/http_proxy.c
@@ -110,7 +110,7 @@
     grpc_endpoint_destroy(exec_ctx, conn->client_endpoint);
     if (conn->server_endpoint != NULL)
       grpc_endpoint_destroy(exec_ctx, conn->server_endpoint);
-    grpc_pollset_set_destroy(conn->pollset_set);
+    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,
                                        &conn->client_deferred_write_buffer);
diff --git a/test/core/end2end/fuzzers/hpack.dictionary b/test/core/end2end/fuzzers/hpack.dictionary
index 81a2419..6b96785 100644
--- a/test/core/end2end/fuzzers/hpack.dictionary
+++ b/test/core/end2end/fuzzers/hpack.dictionary
@@ -15,7 +15,6 @@
 "\x0Auser-agent"
 "\x04host"
 "\x08lb-token"
-"\x0Blb-cost-bin"
 "\x0Cgrpc-timeout"
 "\x10grpc-tracing-bin"
 "\x0Egrpc-stats-bin"
@@ -153,7 +152,6 @@
 "\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/tests/load_reporting_hook.c b/test/core/end2end/tests/load_reporting_hook.c
index 085a563..d1ee26f 100644
--- a/test/core/end2end/tests/load_reporting_hook.c
+++ b/test/core/end2end/tests/load_reporting_hook.c
@@ -31,23 +31,24 @@
  *
  */
 
-#include "test/core/end2end/end2end_tests.h"
-
 #include <string.h>
 
 #include <grpc/byte_buffer.h>
+#include <grpc/load_reporting.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 "test/core/end2end/cq_verifier.h"
 
 #include "src/core/ext/load_reporting/load_reporting.h"
 #include "src/core/ext/load_reporting/load_reporting_filter.h"
 #include "src/core/lib/channel/channel_args.h"
 #include "src/core/lib/transport/static_metadata.h"
 
+#include "test/core/end2end/cq_verifier.h"
+#include "test/core/end2end/end2end_tests.h"
+
 enum { TIMEOUT = 200000 };
 
 static void *tag(intptr_t t) { return (void *)t; }
@@ -124,7 +125,8 @@
 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_metadata *trailing_lr_metadata) {
+    grpc_metadata *initial_lr_metadata,
+    grpc_load_reporting_cost_context *cost_ctx) {
   grpc_slice request_payload_slice = grpc_slice_from_static_string(request_msg);
   grpc_slice response_payload_slice =
       grpc_slice_from_static_string(response_msg);
@@ -237,9 +239,8 @@
   op->reserved = NULL;
   op++;
   op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
-  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;
+  GPR_ASSERT(cost_ctx != NULL);
+  grpc_call_set_load_reporting_cost_context(s, cost_ctx);
   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;
@@ -293,21 +294,21 @@
   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));
 
-  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));
+  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");
 
   request_response_with_payload(config, f, method_name, request_msg,
-                                response_msg, &initial_lr_metadata,
-                                &trailing_lr_metadata);
+                                response_msg, &initial_lr_metadata, cost_ctx);
   end_test(&f);
   {
     grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
diff --git a/test/core/end2end/tests/network_status_change.c b/test/core/end2end/tests/network_status_change.c
index 9cef02b..7540ce9 100644
--- a/test/core/end2end/tests/network_status_change.c
+++ b/test/core/end2end/tests/network_status_change.c
@@ -212,8 +212,11 @@
   CQ_EXPECT_COMPLETION(cqv, tag(1), 1);
   cq_verify(cqv);
 
+  // TODO(makdharma) Update this when the shutdown_all_endpoints is implemented.
   // Expected behavior of a RPC when network is lost.
-  GPR_ASSERT(status == GRPC_STATUS_UNAVAILABLE);
+  // GPR_ASSERT(status == GRPC_STATUS_UNAVAILABLE);
+  GPR_ASSERT(status == GRPC_STATUS_OK);
+
   GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo"));
   validate_host_override_string("foo.test.google.fr:1234", call_details.host,
                                 config);
diff --git a/test/core/fling/BUILD b/test/core/fling/BUILD
new file mode 100644
index 0000000..0b0ebcb
--- /dev/null
+++ b/test/core/fling/BUILD
@@ -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.
+
+licenses(["notice"])  # 3-clause BSD
+
+load("//test/core/util:grpc_fuzzer.bzl", "grpc_fuzzer")
+
+cc_binary(
+    name = "client",
+    srcs = ["client.c"],
+    deps = ["//:grpc", "//test/core/util:grpc_test_util", "//:gpr", "//test/core/util:gpr_test_util", "//test/core/end2end:ssl_test_data"],
+    testonly = 1,
+    copts = ['-std=c99']
+)
+
+cc_binary(
+    name = "server",
+    srcs = ["server.c"],
+    deps = ["//:grpc", "//test/core/util:grpc_test_util", "//:gpr", "//test/core/util:gpr_test_util", "//test/core/end2end:ssl_test_data"],
+    testonly = 1,
+    copts = ['-std=c99']
+)
+
+cc_test(
+    name = "fling",
+    srcs = ["fling_test.c"],
+    deps = ["//:grpc", "//test/core/util:grpc_test_util", "//:gpr", "//test/core/util:gpr_test_util", "//test/core/end2end:ssl_test_data"],
+    data = [":client", ":server"]
+)
+
+cc_test(
+    name = "fling_stream",
+    srcs = ["fling_stream_test.c"],
+    deps = ["//:grpc", "//test/core/util:grpc_test_util", "//:gpr", "//test/core/util:gpr_test_util", "//test/core/end2end:ssl_test_data"],
+    data = [":client", ":server"]
+)
diff --git a/test/core/http/BUILD b/test/core/http/BUILD
index 037ede3..abfa759 100644
--- a/test/core/http/BUILD
+++ b/test/core/http/BUILD
@@ -47,3 +47,58 @@
   copts = ["-std=c99"],
 )
 
+# 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
+
+load("//test/core/util:grpc_fuzzer.bzl", "grpc_fuzzer")
+
+cc_test(
+    name = "httpcli_test",
+    srcs = ["httpcli_test.c"],
+    deps = ["//:grpc", "//test/core/util:grpc_test_util", "//:gpr", "//test/core/util:gpr_test_util", "//test/core/end2end:ssl_test_data"],
+    copts = ['-std=c99'],
+    data = ['test_server.py']
+)
+
+cc_test(
+    name = "httpscli_test",
+    srcs = ["httpscli_test.c"],
+    deps = ["//:grpc", "//test/core/util:grpc_test_util", "//:gpr", "//test/core/util:gpr_test_util", "//test/core/end2end:ssl_test_data"],
+    copts = ['-std=c99'],
+    data = ['test_server.py']
+)
+
+cc_test(
+    name = "parser_test",
+    srcs = ["parser_test.c"],
+    deps = ["//:grpc", "//test/core/util:grpc_test_util", "//:gpr", "//test/core/util:gpr_test_util", "//test/core/end2end:ssl_test_data"],
+    copts = ['-std=c99']
+)
diff --git a/test/core/http/httpcli_test.c b/test/core/http/httpcli_test.c
index 6cc00f8..be8301c 100644
--- a/test/core/http/httpcli_test.c
+++ b/test/core/http/httpcli_test.c
@@ -209,7 +209,7 @@
   test_get(port);
   test_post(port);
 
-  grpc_httpcli_context_destroy(&g_context);
+  grpc_httpcli_context_destroy(&exec_ctx, &g_context);
   grpc_closure_init(&destroyed, destroy_pops, &g_pops,
                     grpc_schedule_on_exec_ctx);
   grpc_pollset_shutdown(&exec_ctx, grpc_polling_entity_pollset(&g_pops),
diff --git a/test/core/http/httpscli_test.c b/test/core/http/httpscli_test.c
index e1a26d9..5a6f07b 100644
--- a/test/core/http/httpscli_test.c
+++ b/test/core/http/httpscli_test.c
@@ -212,7 +212,7 @@
   test_get(port);
   test_post(port);
 
-  grpc_httpcli_context_destroy(&g_context);
+  grpc_httpcli_context_destroy(&exec_ctx, &g_context);
   grpc_closure_init(&destroyed, destroy_pops, &g_pops,
                     grpc_schedule_on_exec_ctx);
   grpc_pollset_shutdown(&exec_ctx, grpc_polling_entity_pollset(&g_pops),
diff --git a/test/core/iomgr/BUILD b/test/core/iomgr/BUILD
new file mode 100644
index 0000000..0cf93e7
--- /dev/null
+++ b/test/core/iomgr/BUILD
@@ -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.
+
+licenses(["notice"])  # 3-clause BSD
+
+load("//test/core/util:grpc_fuzzer.bzl", "grpc_fuzzer")
+
+cc_library(
+    name = "endpoint_tests",
+    srcs = ["endpoint_tests.c"],
+    hdrs = ["endpoint_tests.h"],
+    deps = ["//:grpc", "//test/core/util:grpc_test_util", "//:gpr", "//test/core/util:gpr_test_util"],
+    visibility = ["//test:__subpackages__"],
+    copts = ['-std=c99']
+)
+
+cc_test(
+    name = "combiner_test",
+    srcs = ["combiner_test.c"],
+    deps = ["//:grpc", "//test/core/util:grpc_test_util", "//:gpr", "//test/core/util:gpr_test_util"],
+    copts = ['-std=c99']
+)
+
+cc_test(
+    name = "endpoint_pair_test",
+    srcs = ["endpoint_pair_test.c"],
+    deps = ["//:grpc", "//test/core/util:grpc_test_util", "//:gpr", "//test/core/util:gpr_test_util", ":endpoint_tests"],
+    copts = ['-std=c99']
+)
+
+cc_test(
+    name = "ev_epoll_linux_test",
+    srcs = ["ev_epoll_linux_test.c"],
+    deps = ["//:grpc", "//test/core/util:grpc_test_util", "//:gpr", "//test/core/util:gpr_test_util"],
+    copts = ['-std=c99']
+)
+
+cc_test(
+    name = "fd_conservation_posix_test",
+    srcs = ["fd_conservation_posix_test.c"],
+    deps = ["//:grpc", "//test/core/util:grpc_test_util", "//:gpr", "//test/core/util:gpr_test_util"],
+    copts = ['-std=c99']
+)
+
+cc_test(
+    name = "fd_posix_test",
+    srcs = ["fd_posix_test.c"],
+    deps = ["//:grpc", "//test/core/util:grpc_test_util", "//:gpr", "//test/core/util:gpr_test_util"],
+    copts = ['-std=c99']
+)
+
+cc_test(
+    name = "load_file_test",
+    srcs = ["load_file_test.c"],
+    deps = ["//:grpc", "//test/core/util:grpc_test_util", "//:gpr", "//test/core/util:gpr_test_util"],
+    copts = ['-std=c99']
+)
+
+cc_test(
+    name = "pollset_set_test",
+    srcs = ["pollset_set_test.c"],
+    deps = ["//:grpc", "//test/core/util:grpc_test_util", "//:gpr", "//test/core/util:gpr_test_util"],
+    copts = ['-std=c99']
+)
+
+cc_test(
+    name = "resolve_address_posix_test",
+    srcs = ["resolve_address_posix_test.c"],
+    deps = ["//:grpc", "//test/core/util:grpc_test_util", "//:gpr", "//test/core/util:gpr_test_util"],
+    copts = ['-std=c99']
+)
+
+cc_test(
+    name = "resolve_address_test",
+    srcs = ["resolve_address_test.c"],
+    deps = ["//:grpc", "//test/core/util:grpc_test_util", "//:gpr", "//test/core/util:gpr_test_util"],
+    copts = ['-std=c99']
+)
+
+cc_test(
+    name = "resource_quota_test",
+    srcs = ["resource_quota_test.c"],
+    deps = ["//:grpc", "//test/core/util:grpc_test_util", "//:gpr", "//test/core/util:gpr_test_util"],
+    copts = ['-std=c99']
+)
+
+cc_test(
+    name = "sockaddr_utils_test",
+    srcs = ["sockaddr_utils_test.c"],
+    deps = ["//:grpc", "//test/core/util:grpc_test_util", "//:gpr", "//test/core/util:gpr_test_util"],
+    copts = ['-std=c99']
+)
+
+cc_test(
+    name = "socket_utils_test",
+    srcs = ["socket_utils_test.c"],
+    deps = ["//:grpc", "//test/core/util:grpc_test_util", "//:gpr", "//test/core/util:gpr_test_util"],
+    copts = ['-std=c99']
+)
+
+cc_test(
+    name = "tcp_client_posix_test",
+    srcs = ["tcp_client_posix_test.c"],
+    deps = ["//:grpc", "//test/core/util:grpc_test_util", "//:gpr", "//test/core/util:gpr_test_util"],
+    copts = ['-std=c99']
+)
+
+cc_test(
+    name = "tcp_posix_test",
+    srcs = ["tcp_posix_test.c"],
+    deps = ["//:grpc", "//test/core/util:grpc_test_util", "//:gpr", "//test/core/util:gpr_test_util", ":endpoint_tests"],
+    copts = ['-std=c99']
+)
+
+cc_test(
+    name = "tcp_server_posix_test",
+    srcs = ["tcp_server_posix_test.c"],
+    deps = ["//:grpc", "//test/core/util:grpc_test_util", "//:gpr", "//test/core/util:gpr_test_util"],
+    copts = ['-std=c99']
+)
+
+cc_test(
+    name = "time_averaged_stats_test",
+    srcs = ["time_averaged_stats_test.c"],
+    deps = ["//:grpc", "//test/core/util:grpc_test_util", "//:gpr", "//test/core/util:gpr_test_util"],
+    copts = ['-std=c99']
+)
+
+cc_test(
+    name = "timer_heap_test",
+    srcs = ["timer_heap_test.c"],
+    deps = ["//:grpc", "//test/core/util:grpc_test_util", "//:gpr", "//test/core/util:gpr_test_util"],
+    copts = ['-std=c99']
+)
+
+cc_test(
+    name = "timer_list_test",
+    srcs = ["timer_list_test.c"],
+    deps = ["//:grpc", "//test/core/util:grpc_test_util", "//:gpr", "//test/core/util:gpr_test_util"],
+    copts = ['-std=c99']
+)
+
+cc_test(
+    name = "udp_server_test",
+    srcs = ["udp_server_test.c"],
+    deps = ["//:grpc", "//test/core/util:grpc_test_util", "//:gpr", "//test/core/util:gpr_test_util"],
+    copts = ['-std=c99']
+)
+
+cc_test(
+    name = "wakeup_fd_cv_test",
+    srcs = ["wakeup_fd_cv_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/iomgr/pollset_set_test.c b/test/core/iomgr/pollset_set_test.c
index 40fa858..e7777ac 100644
--- a/test/core/iomgr/pollset_set_test.c
+++ b/test/core/iomgr/pollset_set_test.c
@@ -59,10 +59,11 @@
   }
 }
 
-void cleanup_test_pollset_sets(test_pollset_set *pollset_sets,
+void cleanup_test_pollset_sets(grpc_exec_ctx *exec_ctx,
+                               test_pollset_set *pollset_sets,
                                const int num_pss) {
   for (int i = 0; i < num_pss; i++) {
-    grpc_pollset_set_destroy(pollset_sets[i].pss);
+    grpc_pollset_set_destroy(exec_ctx, pollset_sets[i].pss);
     pollset_sets[i].pss = NULL;
   }
 }
@@ -297,7 +298,7 @@
 
   cleanup_test_fds(&exec_ctx, tfds, num_fds);
   cleanup_test_pollsets(&exec_ctx, pollsets, num_ps);
-  cleanup_test_pollset_sets(pollset_sets, num_pss);
+  cleanup_test_pollset_sets(&exec_ctx, pollset_sets, num_pss);
   grpc_exec_ctx_finish(&exec_ctx);
 }
 
@@ -372,7 +373,7 @@
 
   cleanup_test_fds(&exec_ctx, tfds, num_fds);
   cleanup_test_pollsets(&exec_ctx, &pollset, num_ps);
-  cleanup_test_pollset_sets(pollset_sets, num_pss);
+  cleanup_test_pollset_sets(&exec_ctx, pollset_sets, num_pss);
   grpc_exec_ctx_finish(&exec_ctx);
 }
 
@@ -437,7 +438,7 @@
 
   cleanup_test_fds(&exec_ctx, tfds, num_fds);
   cleanup_test_pollsets(&exec_ctx, pollsets, num_ps);
-  cleanup_test_pollset_sets(&pollset_set, num_pss);
+  cleanup_test_pollset_sets(&exec_ctx, &pollset_set, num_pss);
   grpc_exec_ctx_finish(&exec_ctx);
 }
 
diff --git a/test/core/iomgr/resolve_address_posix_test.c b/test/core/iomgr/resolve_address_posix_test.c
index a4feff8..ef4cfdf 100644
--- a/test/core/iomgr/resolve_address_posix_test.c
+++ b/test/core/iomgr/resolve_address_posix_test.c
@@ -74,7 +74,7 @@
   GPR_ASSERT(gpr_event_wait(&args->ev, test_deadline()));
   grpc_resolved_addresses_destroy(args->addrs);
   grpc_pollset_set_del_pollset(exec_ctx, args->pollset_set, args->pollset);
-  grpc_pollset_set_destroy(args->pollset_set);
+  grpc_pollset_set_destroy(exec_ctx, args->pollset_set);
   grpc_closure do_nothing_cb;
   grpc_closure_init(&do_nothing_cb, do_nothing, NULL,
                     grpc_schedule_on_exec_ctx);
diff --git a/test/core/iomgr/resolve_address_test.c b/test/core/iomgr/resolve_address_test.c
index 54de9a2..6a9bb5a 100644
--- a/test/core/iomgr/resolve_address_test.c
+++ b/test/core/iomgr/resolve_address_test.c
@@ -69,7 +69,7 @@
   GPR_ASSERT(gpr_event_wait(&args->ev, test_deadline()));
   grpc_resolved_addresses_destroy(args->addrs);
   grpc_pollset_set_del_pollset(exec_ctx, args->pollset_set, args->pollset);
-  grpc_pollset_set_destroy(args->pollset_set);
+  grpc_pollset_set_destroy(exec_ctx, args->pollset_set);
   grpc_closure do_nothing_cb;
   grpc_closure_init(&do_nothing_cb, do_nothing, NULL,
                     grpc_schedule_on_exec_ctx);
diff --git a/test/core/iomgr/tcp_client_posix_test.c b/test/core/iomgr/tcp_client_posix_test.c
index dcdff8e..c9b514a 100644
--- a/test/core/iomgr/tcp_client_posix_test.c
+++ b/test/core/iomgr/tcp_client_posix_test.c
@@ -207,7 +207,7 @@
   test_succeeds();
   gpr_log(GPR_ERROR, "End of first test");
   test_fails();
-  grpc_pollset_set_destroy(g_pollset_set);
+  grpc_pollset_set_destroy(&exec_ctx, g_pollset_set);
   grpc_closure_init(&destroyed, destroy_pollset, g_pollset,
                     grpc_schedule_on_exec_ctx);
   grpc_pollset_shutdown(&exec_ctx, g_pollset, &destroyed);
diff --git a/test/core/json/BUILD b/test/core/json/BUILD
index 05d4c6e..f5a877e 100644
--- a/test/core/json/BUILD
+++ b/test/core/json/BUILD
@@ -1,4 +1,4 @@
-# Copyright 2016, Google Inc.
+# Copyright 2017, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
@@ -39,3 +39,32 @@
   copts = ["-std=c99"],
 )
 
+cc_binary(
+    name = "json_rewrite",
+    srcs = ["json_rewrite.c"],
+    deps = ["//:grpc", "//test/core/util:grpc_test_util", "//:gpr", "//test/core/util:gpr_test_util"],
+    testonly = 1,
+    copts = ['-std=c99']
+)
+
+cc_test(
+    name = "json_rewrite_test",
+    srcs = ["json_rewrite_test.c"],
+    deps = ["//:grpc", "//test/core/util:grpc_test_util", "//:gpr", "//test/core/util:gpr_test_util"],
+    copts = ['-std=c99'],
+    data = ["rewrite_test_input.json", "rewrite_test_output_condensed.json", "rewrite_test_output_indented.json", ":json_stream_error_test"]
+)
+
+cc_test(
+    name = "json_stream_error_test",
+    srcs = ["json_stream_error_test.c"],
+    deps = ["//:grpc", "//test/core/util:grpc_test_util", "//:gpr", "//test/core/util:gpr_test_util"],
+    copts = ['-std=c99']
+)
+
+cc_test(
+    name = "json_test",
+    srcs = ["json_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/network_benchmarks/BUILD b/test/core/network_benchmarks/BUILD
new file mode 100644
index 0000000..a5209de
--- /dev/null
+++ b/test/core/network_benchmarks/BUILD
@@ -0,0 +1,37 @@
+# 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.
+
+licenses(["notice"])  # 3-clause BSD
+
+cc_binary(
+    name = "low_level_ping_pong",
+    srcs = ["low_level_ping_pong.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/BUILD b/test/core/security/BUILD
new file mode 100644
index 0000000..e750c39
--- /dev/null
+++ b/test/core/security/BUILD
@@ -0,0 +1,104 @@
+# 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
+
+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"],
+  corpus = "corpus",
+  copts = ["-std=c99"],
+)
+
+cc_library(
+    name = "oauth2_utils",
+    srcs = ["oauth2_utils.c"],
+    hdrs = ["oauth2_utils.h"],
+    deps = ["//:grpc"],
+    copts = ['-std=c99']
+)
+
+cc_test(
+    name = "auth_context_test",
+    srcs = ["auth_context_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']
+)
+
+cc_test(
+    name = "credentials_test",
+    srcs = ["credentials_test.c"],
+    deps = ["//:grpc", "//test/core/util:grpc_test_util", "//:gpr", "//test/core/util:gpr_test_util"],
+    copts = ['-std=c99']
+)
+
+cc_test(
+    name = "secure_endpoint_test",
+    srcs = ["secure_endpoint_test.c"],
+    deps = ["//:grpc", "//test/core/util:grpc_test_util", "//:gpr", "//test/core/util:gpr_test_util", "//test/core/iomgr:endpoint_tests"],
+    copts = ['-std=c99']
+)
+
+cc_test(
+    name = "security_connector_test",
+    srcs = ["security_connector_test.c"],
+    deps = ["//:grpc", "//test/core/util:grpc_test_util", "//:gpr", "//test/core/util:gpr_test_util"],
+    copts = ['-std=c99']
+)
+
+cc_binary(
+    name = "create_jwt",
+    srcs = ["create_jwt.c"],
+    deps = ["//:grpc", "//:gpr"],
+    copts = ['-std=c99']
+)
+
+cc_binary(
+    name = "fetch_oauth2",
+    srcs = ["fetch_oauth2.c"],
+    deps = ["//:grpc", "//:gpr", ":oauth2_utils"],
+    copts = ['-std=c99']
+)
+
+cc_binary(
+    name = "verify_jwt",
+    srcs = ["verify_jwt.c"],
+    deps = ["//:grpc", "//:gpr"],
+    copts = ['-std=c99']
+)
diff --git a/test/core/security/jwt_verifier_test.c b/test/core/security/jwt_verifier_test.c
index a9bd976..0a73f67 100644
--- a/test/core/security/jwt_verifier_test.c
+++ b/test/core/security/jwt_verifier_test.c
@@ -386,9 +386,9 @@
   GPR_ASSERT(jwt != NULL);
   grpc_jwt_verifier_verify(&exec_ctx, verifier, NULL, jwt, expected_audience,
                            on_verification_success, (void *)expected_user_data);
+  grpc_jwt_verifier_destroy(&exec_ctx, verifier);
   grpc_exec_ctx_finish(&exec_ctx);
   gpr_free(jwt);
-  grpc_jwt_verifier_destroy(verifier);
   grpc_httpcli_set_override(NULL, NULL);
 }
 
@@ -420,9 +420,9 @@
   GPR_ASSERT(jwt != NULL);
   grpc_jwt_verifier_verify(&exec_ctx, verifier, NULL, jwt, expected_audience,
                            on_verification_success, (void *)expected_user_data);
+  grpc_jwt_verifier_destroy(&exec_ctx, verifier);
   grpc_exec_ctx_finish(&exec_ctx);
   gpr_free(jwt);
-  grpc_jwt_verifier_destroy(verifier);
   grpc_httpcli_set_override(NULL, NULL);
 }
 
@@ -469,9 +469,9 @@
   GPR_ASSERT(jwt != NULL);
   grpc_jwt_verifier_verify(&exec_ctx, verifier, NULL, jwt, expected_audience,
                            on_verification_success, (void *)expected_user_data);
+  grpc_jwt_verifier_destroy(&exec_ctx, verifier);
   grpc_exec_ctx_finish(&exec_ctx);
   gpr_free(jwt);
-  grpc_jwt_verifier_destroy(verifier);
   grpc_httpcli_set_override(NULL, NULL);
 }
 
@@ -511,9 +511,9 @@
   grpc_jwt_verifier_verify(&exec_ctx, verifier, NULL, jwt, expected_audience,
                            on_verification_key_retrieval_error,
                            (void *)expected_user_data);
+  grpc_jwt_verifier_destroy(&exec_ctx, verifier);
   grpc_exec_ctx_finish(&exec_ctx);
   gpr_free(jwt);
-  grpc_jwt_verifier_destroy(verifier);
   grpc_httpcli_set_override(NULL, NULL);
 }
 
@@ -534,9 +534,9 @@
   grpc_jwt_verifier_verify(&exec_ctx, verifier, NULL, jwt, expected_audience,
                            on_verification_key_retrieval_error,
                            (void *)expected_user_data);
+  grpc_jwt_verifier_destroy(&exec_ctx, verifier);
   grpc_exec_ctx_finish(&exec_ctx);
   gpr_free(jwt);
-  grpc_jwt_verifier_destroy(verifier);
   grpc_httpcli_set_override(NULL, NULL);
 }
 
@@ -588,9 +588,9 @@
   grpc_jwt_verifier_verify(&exec_ctx, verifier, NULL, jwt, expected_audience,
                            on_verification_bad_signature,
                            (void *)expected_user_data);
-  grpc_exec_ctx_finish(&exec_ctx);
   gpr_free(jwt);
-  grpc_jwt_verifier_destroy(verifier);
+  grpc_jwt_verifier_destroy(&exec_ctx, verifier);
+  grpc_exec_ctx_finish(&exec_ctx);
   grpc_httpcli_set_override(NULL, NULL);
 }
 
@@ -619,8 +619,8 @@
   grpc_jwt_verifier_verify(&exec_ctx, verifier, NULL, "bad jwt",
                            expected_audience, on_verification_bad_format,
                            (void *)expected_user_data);
+  grpc_jwt_verifier_destroy(&exec_ctx, verifier);
   grpc_exec_ctx_finish(&exec_ctx);
-  grpc_jwt_verifier_destroy(verifier);
   grpc_httpcli_set_override(NULL, NULL);
 }
 
diff --git a/test/core/security/verify_jwt.c b/test/core/security/verify_jwt.c
index bbd4a67..aaf0e7f 100644
--- a/test/core/security/verify_jwt.c
+++ b/test/core/security/verify_jwt.c
@@ -123,14 +123,15 @@
                               gpr_inf_future(GPR_CLOCK_MONOTONIC))))
       sync.is_done = true;
     gpr_mu_unlock(sync.mu);
-    grpc_exec_ctx_finish(&exec_ctx);
+    grpc_exec_ctx_flush(&exec_ctx);
     gpr_mu_lock(sync.mu);
   }
   gpr_mu_unlock(sync.mu);
 
   gpr_free(sync.pollset);
 
-  grpc_jwt_verifier_destroy(verifier);
+  grpc_jwt_verifier_destroy(&exec_ctx, verifier);
+  grpc_exec_ctx_finish(&exec_ctx);
   gpr_cmdline_destroy(cl);
   grpc_shutdown();
   return !sync.success;
diff --git a/test/core/slice/BUILD b/test/core/slice/BUILD
new file mode 100644
index 0000000..67a4706
--- /dev/null
+++ b/test/core/slice/BUILD
@@ -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.
+
+licenses(["notice"])  # 3-clause BSD
+
+load("//test/core/util:grpc_fuzzer.bzl", "grpc_fuzzer")
+
+grpc_fuzzer(
+  name = "percent_decode_fuzzer",
+  srcs = ["percent_decode_fuzzer.c"],
+  deps = ["//:gpr", "//:grpc", "//test/core/util:grpc_test_util"],
+  corpus = "response_corpus",
+  copts = ["-std=c99"],
+)
+
+cc_test(
+    name = "percent_encoding_test",
+    srcs = ["percent_encoding_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_string_helpers_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/surface/public_headers_must_be_c89.c b/test/core/surface/public_headers_must_be_c89.c
index e0a2c94..330da46 100644
--- a/test/core/surface/public_headers_must_be_c89.c
+++ b/test/core/surface/public_headers_must_be_c89.c
@@ -52,6 +52,7 @@
 #include <grpc/impl/codegen/status.h>
 #include <grpc/impl/codegen/sync.h>
 #include <grpc/impl/codegen/sync_generic.h>
+#include <grpc/load_reporting.h>
 #include <grpc/slice.h>
 #include <grpc/slice_buffer.h>
 #include <grpc/status.h>
diff --git a/test/core/transport/BUILD b/test/core/transport/BUILD
new file mode 100644
index 0000000..865b0c2
--- /dev/null
+++ b/test/core/transport/BUILD
@@ -0,0 +1,72 @@
+# 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 = "bdp_estimator_test",
+    srcs = ["bdp_estimator_test.c"],
+    deps = ["//:grpc", "//test/core/util:grpc_test_util", "//:gpr", "//test/core/util:gpr_test_util"],
+    copts = ['-std=c99']
+)
+
+cc_test(
+    name = "connectivity_state_test",
+    srcs = ["connectivity_state_test.c"],
+    deps = ["//:grpc", "//test/core/util:grpc_test_util", "//:gpr", "//test/core/util:gpr_test_util"],
+    copts = ['-std=c99']
+)
+
+cc_test(
+    name = "metadata_test",
+    srcs = ["metadata_test.c"],
+    deps = ["//:grpc", "//test/core/util:grpc_test_util", "//:gpr", "//test/core/util:gpr_test_util"],
+    copts = ['-std=c99']
+)
+
+cc_test(
+    name = "pid_controller_test",
+    srcs = ["pid_controller_test.c"],
+    deps = ["//:grpc", "//test/core/util:grpc_test_util", "//:gpr", "//test/core/util:gpr_test_util"],
+    copts = ['-std=c99']
+)
+
+cc_test(
+    name = "status_conversion_test",
+    srcs = ["status_conversion_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"],
+    deps = ["//:grpc", "//test/core/util:grpc_test_util", "//:gpr", "//test/core/util:gpr_test_util"],
+    copts = ['-std=c99']
+)
diff --git a/test/core/transport/chttp2/BUILD b/test/core/transport/chttp2/BUILD
index 94b4830..b507e27 100644
--- a/test/core/transport/chttp2/BUILD
+++ b/test/core/transport/chttp2/BUILD
@@ -38,3 +38,58 @@
   corpus = "hpack_parser_corpus"
 )
 
+cc_test(
+    name = "alpn_test",
+    srcs = ["alpn_test.c"],
+    deps = ["//:grpc", "//test/core/util:grpc_test_util", "//:gpr", "//test/core/util:gpr_test_util"],
+    copts = ['-std=c99']
+)
+
+cc_test(
+    name = "bin_decoder_test",
+    srcs = ["bin_decoder_test.c"],
+    deps = ["//:grpc", "//test/core/util:grpc_test_util", "//:gpr", "//test/core/util:gpr_test_util"],
+    copts = ['-std=c99']
+)
+
+cc_test(
+    name = "bin_encoder_test",
+    srcs = ["bin_encoder_test.c"],
+    deps = ["//:grpc", "//test/core/util:grpc_test_util", "//:gpr", "//test/core/util:gpr_test_util"],
+    copts = ['-std=c99']
+)
+
+cc_test(
+    name = "hpack_encoder_test",
+    srcs = ["hpack_encoder_test.c"],
+    deps = ["//:grpc", "//test/core/util:grpc_test_util", "//:gpr", "//test/core/util:gpr_test_util"],
+    copts = ['-std=c99']
+)
+
+cc_test(
+    name = "hpack_parser_test",
+    srcs = ["hpack_parser_test.c"],
+    deps = ["//:grpc", "//test/core/util:grpc_test_util", "//:gpr", "//test/core/util:gpr_test_util"],
+    copts = ['-std=c99']
+)
+
+cc_test(
+    name = "hpack_table_test",
+    srcs = ["hpack_table_test.c"],
+    deps = ["//:grpc", "//test/core/util:grpc_test_util", "//:gpr", "//test/core/util:gpr_test_util"],
+    copts = ['-std=c99']
+)
+
+cc_test(
+    name = "stream_map_test",
+    srcs = ["stream_map_test.c"],
+    deps = ["//:grpc", "//test/core/util:grpc_test_util", "//:gpr", "//test/core/util:gpr_test_util"],
+    copts = ['-std=c99']
+)
+
+cc_test(
+    name = "varint_test",
+    srcs = ["varint_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/transport/connectivity_state_test.c b/test/core/transport/connectivity_state_test.c
index 3520ef0..8314a5f 100644
--- a/test/core/transport/connectivity_state_test.c
+++ b/test/core/transport/connectivity_state_test.c
@@ -77,8 +77,9 @@
   grpc_error *error;
   gpr_log(GPR_DEBUG, "test_check");
   grpc_connectivity_state_init(&tracker, GRPC_CHANNEL_IDLE, "xxx");
-  GPR_ASSERT(grpc_connectivity_state_check(&tracker, &error) ==
+  GPR_ASSERT(grpc_connectivity_state_get(&tracker, &error) ==
              GRPC_CHANNEL_IDLE);
+  GPR_ASSERT(grpc_connectivity_state_check(&tracker) == GRPC_CHANNEL_IDLE);
   GPR_ASSERT(error == GRPC_ERROR_NONE);
   grpc_connectivity_state_destroy(&exec_ctx, &tracker);
   grpc_exec_ctx_finish(&exec_ctx);
diff --git a/test/core/tsi/BUILD b/test/core/tsi/BUILD
new file mode 100644
index 0000000..e6cba34
--- /dev/null
+++ b/test/core/tsi/BUILD
@@ -0,0 +1,37 @@
+# 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 = "transport_security_test",
+    srcs = ["transport_security_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/util/port_server_client.c b/test/core/util/port_server_client.c
index 6d722ff..7b733ab9c 100644
--- a/test/core/util/port_server_client.c
+++ b/test/core/util/port_server_client.c
@@ -121,7 +121,7 @@
   }
   gpr_mu_unlock(pr.mu);
 
-  grpc_httpcli_context_destroy(&context);
+  grpc_httpcli_context_destroy(&exec_ctx, &context);
   grpc_exec_ctx_finish(&exec_ctx);
   grpc_pollset_shutdown(&exec_ctx, grpc_polling_entity_pollset(&pr.pops),
                         shutdown_closure);
@@ -245,7 +245,7 @@
   gpr_mu_unlock(pr.mu);
 
   grpc_http_response_destroy(&pr.response);
-  grpc_httpcli_context_destroy(&context);
+  grpc_httpcli_context_destroy(&exec_ctx, &context);
   grpc_pollset_shutdown(&exec_ctx, grpc_polling_entity_pollset(&pr.pops),
                         shutdown_closure);
   grpc_exec_ctx_finish(&exec_ctx);
diff --git a/test/cpp/common/BUILD b/test/cpp/common/BUILD
new file mode 100644
index 0000000..0e2db00
--- /dev/null
+++ b/test/cpp/common/BUILD
@@ -0,0 +1,36 @@
+# 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 = "alarm_cpp_test",
+    srcs = ["alarm_cpp_test.cc"],
+    deps = ["//:grpc++", "//external:gtest", "//test/core/util:gpr_test_util"],
+)
diff --git a/test/cpp/end2end/health_service_end2end_test.cc b/test/cpp/end2end/health_service_end2end_test.cc
new file mode 100644
index 0000000..3d51007
--- /dev/null
+++ b/test/cpp/end2end/health_service_end2end_test.cc
@@ -0,0 +1,323 @@
+/*
+ *
+ * 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 <memory>
+#include <mutex>
+#include <thread>
+#include <vector>
+
+#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++/health_check_service_interface.h>
+#include <grpc++/server.h>
+#include <grpc++/server_builder.h>
+#include <grpc++/server_context.h>
+#include <grpc/grpc.h>
+#include <grpc/support/log.h>
+#include <gtest/gtest.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"
+#include "test/core/util/test_config.h"
+#include "test/cpp/end2end/test_service_impl.h"
+
+using grpc::health::v1::Health;
+using grpc::health::v1::HealthCheckRequest;
+using grpc::health::v1::HealthCheckResponse;
+
+namespace grpc {
+namespace testing {
+namespace {
+
+// A sample sync implementation of the health checking service. This does the
+// same thing as the default one.
+class HealthCheckServiceImpl : public ::grpc::health::v1::Health::Service {
+ public:
+  Status Check(ServerContext* context, const HealthCheckRequest* request,
+               HealthCheckResponse* response) override {
+    std::lock_guard<std::mutex> lock(mu_);
+    auto iter = status_map_.find(request->service());
+    if (iter == status_map_.end()) {
+      return Status(StatusCode::NOT_FOUND, "");
+    }
+    response->set_status(iter->second);
+    return Status::OK;
+  }
+
+  void SetStatus(const grpc::string& service_name,
+                 HealthCheckResponse::ServingStatus status) {
+    std::lock_guard<std::mutex> lock(mu_);
+    status_map_[service_name] = status;
+  }
+
+  void SetAll(HealthCheckResponse::ServingStatus status) {
+    std::lock_guard<std::mutex> lock(mu_);
+    for (auto iter = status_map_.begin(); iter != status_map_.end(); ++iter) {
+      iter->second = status;
+    }
+  }
+
+ private:
+  std::mutex mu_;
+  std::map<const grpc::string, HealthCheckResponse::ServingStatus> status_map_;
+};
+
+// A custom implementation of the health checking service interface. This is
+// used to test that it prevents the server from creating a default service and
+// also serves as an example of how to override the default service.
+class CustomHealthCheckService : public HealthCheckServiceInterface {
+ public:
+  explicit CustomHealthCheckService(HealthCheckServiceImpl* impl)
+      : impl_(impl) {
+    impl_->SetStatus("", HealthCheckResponse::SERVING);
+  }
+  void SetServingStatus(const grpc::string& service_name,
+                        bool serving) override {
+    impl_->SetStatus(service_name, serving ? HealthCheckResponse::SERVING
+                                           : HealthCheckResponse::NOT_SERVING);
+  }
+
+  void SetServingStatus(bool serving) override {
+    impl_->SetAll(serving ? HealthCheckResponse::SERVING
+                          : HealthCheckResponse::NOT_SERVING);
+  }
+
+ private:
+  HealthCheckServiceImpl* impl_;  // not owned
+};
+
+void LoopCompletionQueue(ServerCompletionQueue* cq) {
+  void* tag;
+  bool ok;
+  while (cq->Next(&tag, &ok)) {
+    abort();  // Nothing should come out of the cq.
+  }
+}
+
+class HealthServiceEnd2endTest : public ::testing::Test {
+ protected:
+  HealthServiceEnd2endTest() {}
+
+  void SetUpServer(bool register_sync_test_service, bool add_async_cq,
+                   bool explicit_health_service,
+                   std::unique_ptr<HealthCheckServiceInterface> service) {
+    int port = grpc_pick_unused_port_or_die();
+    server_address_ << "localhost:" << port;
+
+    bool register_sync_health_service_impl =
+        explicit_health_service && service != nullptr;
+
+    // Setup server
+    ServerBuilder builder;
+    if (explicit_health_service) {
+      std::unique_ptr<ServerBuilderOption> option(
+          new HealthCheckServiceServerBuilderOption(std::move(service)));
+      builder.SetOption(std::move(option));
+    }
+    builder.AddListeningPort(server_address_.str(),
+                             grpc::InsecureServerCredentials());
+    if (register_sync_test_service) {
+      // Register a sync service.
+      builder.RegisterService(&echo_test_service_);
+    }
+    if (register_sync_health_service_impl) {
+      builder.RegisterService(&health_check_service_impl_);
+    }
+    if (add_async_cq) {
+      cq_ = builder.AddCompletionQueue();
+    }
+    server_ = builder.BuildAndStart();
+  }
+
+  void TearDown() override {
+    if (server_) {
+      server_->Shutdown();
+      if (cq_ != nullptr) {
+        cq_->Shutdown();
+      }
+      if (cq_thread_.joinable()) {
+        cq_thread_.join();
+      }
+    }
+  }
+
+  void ResetStubs() {
+    std::shared_ptr<Channel> channel =
+        CreateChannel(server_address_.str(), InsecureChannelCredentials());
+    hc_stub_ = grpc::health::v1::Health::NewStub(channel);
+  }
+
+  // When the expected_status is NOT OK, we do not care about the response.
+  void SendHealthCheckRpc(const grpc::string& service_name,
+                          const Status& expected_status) {
+    EXPECT_FALSE(expected_status.ok());
+    SendHealthCheckRpc(service_name, expected_status,
+                       HealthCheckResponse::UNKNOWN);
+  }
+
+  void SendHealthCheckRpc(
+      const grpc::string& service_name, const Status& expected_status,
+      HealthCheckResponse::ServingStatus expected_serving_status) {
+    HealthCheckRequest request;
+    request.set_service(service_name);
+    HealthCheckResponse response;
+    ClientContext context;
+    Status s = hc_stub_->Check(&context, request, &response);
+    EXPECT_EQ(expected_status.error_code(), s.error_code());
+    if (s.ok()) {
+      EXPECT_EQ(expected_serving_status, response.status());
+    }
+  }
+
+  void VerifyHealthCheckService() {
+    HealthCheckServiceInterface* service = server_->GetHealthCheckService();
+    EXPECT_TRUE(service != nullptr);
+    const grpc::string kHealthyService("healthy_service");
+    const grpc::string kUnhealthyService("unhealthy_service");
+    const grpc::string kNotRegisteredService("not_registered");
+    service->SetServingStatus(kHealthyService, true);
+    service->SetServingStatus(kUnhealthyService, false);
+
+    ResetStubs();
+
+    SendHealthCheckRpc("", Status::OK, HealthCheckResponse::SERVING);
+    SendHealthCheckRpc(kHealthyService, Status::OK,
+                       HealthCheckResponse::SERVING);
+    SendHealthCheckRpc(kUnhealthyService, Status::OK,
+                       HealthCheckResponse::NOT_SERVING);
+    SendHealthCheckRpc(kNotRegisteredService,
+                       Status(StatusCode::NOT_FOUND, ""));
+
+    service->SetServingStatus(false);
+    SendHealthCheckRpc("", Status::OK, HealthCheckResponse::NOT_SERVING);
+    SendHealthCheckRpc(kHealthyService, Status::OK,
+                       HealthCheckResponse::NOT_SERVING);
+    SendHealthCheckRpc(kUnhealthyService, Status::OK,
+                       HealthCheckResponse::NOT_SERVING);
+    SendHealthCheckRpc(kNotRegisteredService,
+                       Status(StatusCode::NOT_FOUND, ""));
+  }
+
+  TestServiceImpl echo_test_service_;
+  HealthCheckServiceImpl health_check_service_impl_;
+  std::unique_ptr<Health::Stub> hc_stub_;
+  std::unique_ptr<ServerCompletionQueue> cq_;
+  std::unique_ptr<Server> server_;
+  std::ostringstream server_address_;
+  std::thread cq_thread_;
+};
+
+TEST_F(HealthServiceEnd2endTest, DefaultHealthServiceDisabled) {
+  EnableDefaultHealthCheckService(false);
+  EXPECT_FALSE(DefaultHealthCheckServiceEnabled());
+  SetUpServer(true, false, false, nullptr);
+  HealthCheckServiceInterface* default_service =
+      server_->GetHealthCheckService();
+  EXPECT_TRUE(default_service == nullptr);
+
+  ResetStubs();
+
+  SendHealthCheckRpc("", Status(StatusCode::UNIMPLEMENTED, ""));
+}
+
+TEST_F(HealthServiceEnd2endTest, DefaultHealthService) {
+  EnableDefaultHealthCheckService(true);
+  EXPECT_TRUE(DefaultHealthCheckServiceEnabled());
+  SetUpServer(true, false, false, nullptr);
+  VerifyHealthCheckService();
+
+  // The default service has a size limit of the service name.
+  const grpc::string kTooLongServiceName(201, 'x');
+  SendHealthCheckRpc(kTooLongServiceName,
+                     Status(StatusCode::INVALID_ARGUMENT, ""));
+}
+
+// The server has no sync service.
+TEST_F(HealthServiceEnd2endTest, DefaultHealthServiceAsyncOnly) {
+  EnableDefaultHealthCheckService(true);
+  EXPECT_TRUE(DefaultHealthCheckServiceEnabled());
+  SetUpServer(false, true, false, nullptr);
+  cq_thread_ = std::thread(LoopCompletionQueue, cq_.get());
+
+  HealthCheckServiceInterface* default_service =
+      server_->GetHealthCheckService();
+  EXPECT_TRUE(default_service == nullptr);
+
+  ResetStubs();
+
+  SendHealthCheckRpc("", Status(StatusCode::UNIMPLEMENTED, ""));
+}
+
+// Provide an empty service to disable the default service.
+TEST_F(HealthServiceEnd2endTest, ExplicitlyDisableViaOverride) {
+  EnableDefaultHealthCheckService(true);
+  EXPECT_TRUE(DefaultHealthCheckServiceEnabled());
+  std::unique_ptr<HealthCheckServiceInterface> empty_service;
+  SetUpServer(true, false, true, std::move(empty_service));
+  HealthCheckServiceInterface* service = server_->GetHealthCheckService();
+  EXPECT_TRUE(service == nullptr);
+
+  ResetStubs();
+
+  SendHealthCheckRpc("", Status(StatusCode::UNIMPLEMENTED, ""));
+}
+
+// Provide an explicit override of health checking service interface.
+TEST_F(HealthServiceEnd2endTest, ExplicitlyOverride) {
+  EnableDefaultHealthCheckService(true);
+  EXPECT_TRUE(DefaultHealthCheckServiceEnabled());
+  std::unique_ptr<HealthCheckServiceInterface> override_service(
+      new CustomHealthCheckService(&health_check_service_impl_));
+  HealthCheckServiceInterface* underlying_service = override_service.get();
+  SetUpServer(false, false, true, std::move(override_service));
+  HealthCheckServiceInterface* service = server_->GetHealthCheckService();
+  EXPECT_TRUE(service == underlying_service);
+
+  ResetStubs();
+
+  VerifyHealthCheckService();
+}
+
+}  // namespace
+}  // namespace testing
+}  // namespace grpc
+
+int main(int argc, char** argv) {
+  grpc_test_init(argc, argv);
+  ::testing::InitGoogleTest(&argc, argv);
+  return RUN_ALL_TESTS();
+}
diff --git a/test/cpp/interop/client.cc b/test/cpp/interop/client.cc
index 8a00b61..5688ab7 100644
--- a/test/cpp/interop/client.cc
+++ b/test/cpp/interop/client.cc
@@ -51,7 +51,7 @@
 DEFINE_string(custom_credentials_type, "", "User provided credentials type.");
 DEFINE_bool(use_test_ca, false, "False to use SSL roots for google");
 DEFINE_int32(server_port, 0, "Server port.");
-DEFINE_string(server_host, "127.0.0.1", "Server host to connect to");
+DEFINE_string(server_host, "localhost", "Server host to connect to");
 DEFINE_string(server_host_override, "foo.test.google.fr",
               "Override the server host which is sent in HTTP header");
 DEFINE_string(
diff --git a/test/cpp/interop/http2_client.cc b/test/cpp/interop/http2_client.cc
index 38aee43..b96e9fa 100644
--- a/test/cpp/interop/http2_client.cc
+++ b/test/cpp/interop/http2_client.cc
@@ -223,7 +223,7 @@
 }  // namespace grpc
 
 DEFINE_int32(server_port, 0, "Server port.");
-DEFINE_string(server_host, "127.0.0.1", "Server host to connect to");
+DEFINE_string(server_host, "localhost", "Server host to connect to");
 DEFINE_string(test_case, "rst_after_header",
               "Configure different test cases. Valid options are:\n\n"
               "goaway\n"
diff --git a/test/cpp/interop/reconnect_interop_client.cc b/test/cpp/interop/reconnect_interop_client.cc
index 797e52c..1c2f606 100644
--- a/test/cpp/interop/reconnect_interop_client.cc
+++ b/test/cpp/interop/reconnect_interop_client.cc
@@ -48,7 +48,7 @@
 
 DEFINE_int32(server_control_port, 0, "Server port for control rpcs.");
 DEFINE_int32(server_retry_port, 0, "Server port for testing reconnection.");
-DEFINE_string(server_host, "127.0.0.1", "Server host to connect to");
+DEFINE_string(server_host, "localhost", "Server host to connect to");
 DEFINE_int32(max_reconnect_backoff_ms, 0,
              "Maximum backoff time, or 0 for default.");
 
diff --git a/test/cpp/qps/qps_test_with_poll.cc b/test/cpp/qps/qps_test_with_poll.cc
deleted file mode 100644
index c64e6c9..0000000
--- a/test/cpp/qps/qps_test_with_poll.cc
+++ /dev/null
@@ -1,85 +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.
- *
- */
-
-#include <set>
-
-#include <grpc/support/log.h>
-
-#include "test/cpp/qps/driver.h"
-#include "test/cpp/qps/report.h"
-#include "test/cpp/util/benchmark_config.h"
-
-extern "C" {
-#include "src/core/lib/iomgr/pollset_posix.h"
-}
-
-namespace grpc {
-namespace testing {
-
-static const int WARMUP = 5;
-static const int BENCHMARK = 5;
-
-static void RunQPS() {
-  gpr_log(GPR_INFO, "Running QPS test");
-
-  ClientConfig client_config;
-  client_config.set_client_type(ASYNC_CLIENT);
-  client_config.set_outstanding_rpcs_per_channel(1000);
-  client_config.set_client_channels(8);
-  client_config.set_async_client_threads(8);
-  client_config.set_rpc_type(UNARY);
-  client_config.mutable_load_params()->mutable_closed_loop();
-
-  ServerConfig server_config;
-  server_config.set_server_type(ASYNC_SERVER);
-  server_config.set_async_server_threads(4);
-
-  const auto result =
-      RunScenario(client_config, 1, server_config, 1, WARMUP, BENCHMARK, -2);
-
-  GetReporter()->ReportQPSPerCore(*result);
-  GetReporter()->ReportLatency(*result);
-}
-
-}  // namespace testing
-}  // namespace grpc
-
-int main(int argc, char** argv) {
-  grpc::testing::InitBenchmark(&argc, &argv, true);
-
-  grpc_platform_become_multipoller = grpc_poll_become_multipoller;
-
-  grpc::testing::RunQPS();
-
-  return 0;
-}
diff --git a/test/cpp/util/BUILD b/test/cpp/util/BUILD
new file mode 100644
index 0000000..78eca8c
--- /dev/null
+++ b/test/cpp/util/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
+
+cc_library(
+    name = "test_config",
+    srcs = [
+        "test_config_cc.cc",
+    ],
+    hdrs = [
+        "test_config.h",
+    ],
+    deps = ["//:gpr"],
+    visibility = ["//test:__subpackages__"],
+)
+
+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",
+        "subprocess.cc",
+        "test_credentials_provider.cc",
+    ],
+    hdrs = [
+        "byte_buffer_proto_helper.h",
+        "create_test_channel.h",
+        "string_ref_helper.h",
+        "subprocess.h",
+        "test_credentials_provider.h",
+    ],
+    deps = ["//test/core/util:gpr_test_util", "//:grpc++", "//test/core/end2end:ssl_test_data"],
+    visibility = ["//test:__subpackages__"],
+)
diff --git a/third_party/gtest.BUILD b/third_party/gtest.BUILD
new file mode 100644
index 0000000..bf98075
--- /dev/null
+++ b/third_party/gtest.BUILD
@@ -0,0 +1,14 @@
+cc_library(
+    name = "gtest",
+    srcs = [
+        "src/gtest-all.cc",
+    ],
+    hdrs = glob(["include/**/*.h", "src/*.cc", "src/*.h"]),
+    includes = [
+        "include", "."
+    ],
+    linkstatic = 1,
+    visibility = [
+        "//visibility:public",
+    ],
+)
diff --git a/third_party/nanopb/BUILD b/third_party/nanopb/BUILD
index 5709884..f9fc57f 100644
--- a/third_party/nanopb/BUILD
+++ b/third_party/nanopb/BUILD
@@ -1,4 +1,7 @@
 licenses(["notice"])
+
+exports_files(["LICENSE.txt"])
+
 package(default_visibility = ["//visibility:public"])
 
 cc_library(
diff --git a/tools/codegen/core/gen_static_metadata.py b/tools/codegen/core/gen_static_metadata.py
index 4703708..109701f 100755
--- a/tools/codegen/core/gen_static_metadata.py
+++ b/tools/codegen/core/gen_static_metadata.py
@@ -123,7 +123,6 @@
     ('if-unmodified-since', ''),
     ('last-modified', ''),
     ('lb-token', ''),
-    ('lb-cost-bin', ''),
     ('link', ''),
     ('location', ''),
     ('max-forwards', ''),
@@ -160,7 +159,6 @@
     'user-agent',
     'host',
     'lb-token',
-    'lb-cost-bin',
 ]
 
 COMPRESSION_ALGORITHMS = [
diff --git a/tools/distrib/check_copyright.py b/tools/distrib/check_copyright.py
index c993407..611a9f4 100755
--- a/tools/distrib/check_copyright.py
+++ b/tools/distrib/check_copyright.py
@@ -106,6 +106,8 @@
 
   '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/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',
diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++
index 0706cdc..551ba46 100644
--- a/tools/doxygen/Doxyfile.c++
+++ b/tools/doxygen/Doxyfile.c++
@@ -795,9 +795,11 @@
 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/async_stream.h \
diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal
index cb0a3e5..0d7ddfc 100644
--- a/tools/doxygen/Doxyfile.c++.internal
+++ b/tools/doxygen/Doxyfile.c++.internal
@@ -795,9 +795,11 @@
 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/async_stream.h \
@@ -913,6 +915,12 @@
 src/cpp/server/create_default_thread_pool.cc \
 src/cpp/server/dynamic_thread_pool.cc \
 src/cpp/server/dynamic_thread_pool.h \
+src/cpp/server/health/default_health_check_service.cc \
+src/cpp/server/health/default_health_check_service.h \
+src/cpp/server/health/health.pb.c \
+src/cpp/server/health/health.pb.h \
+src/cpp/server/health/health_check_service.cc \
+src/cpp/server/health/health_check_service_server_builder_option.cc \
 src/cpp/server/insecure_server_credentials.cc \
 src/cpp/server/secure_server_credentials.cc \
 src/cpp/server/secure_server_credentials.h \
diff --git a/tools/doxygen/Doxyfile.core b/tools/doxygen/Doxyfile.core
index 060e098..896ee02 100644
--- a/tools/doxygen/Doxyfile.core
+++ b/tools/doxygen/Doxyfile.core
@@ -827,6 +827,7 @@
 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 \
diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal
index ce7e103..1080125 100644
--- a/tools/doxygen/Doxyfile.core.internal
+++ b/tools/doxygen/Doxyfile.core.internal
@@ -827,6 +827,7 @@
 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 \
diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json
index 704f22d..98b85cf 100644
--- a/tools/run_tests/generated/sources_and_headers.json
+++ b/tools/run_tests/generated/sources_and_headers.json
@@ -2894,6 +2894,25 @@
   }, 
   {
     "deps": [
+      "gpr", 
+      "gpr_test_util", 
+      "grpc", 
+      "grpc++", 
+      "grpc++_test_util", 
+      "grpc_test_util"
+    ], 
+    "headers": [], 
+    "is_filegroup": false, 
+    "language": "c++", 
+    "name": "health_service_end2end_test", 
+    "src": [
+      "test/cpp/end2end/health_service_end2end_test.cc"
+    ], 
+    "third_party": false, 
+    "type": "target"
+  }, 
+  {
+    "deps": [
       "grpc", 
       "grpc++", 
       "grpc++_test_config", 
@@ -5492,23 +5511,6 @@
     "type": "lib"
   }, 
   {
-    "deps": [
-      "grpc++"
-    ], 
-    "headers": [
-      "include/grpc++/test/server_context_test_spouse.h"
-    ], 
-    "is_filegroup": false, 
-    "language": "c++", 
-    "name": "grpc++_test", 
-    "src": [
-      "include/grpc++/test/server_context_test_spouse.h", 
-      "src/cpp/test/server_context_test_spouse.cc"
-    ], 
-    "third_party": false, 
-    "type": "lib"
-  }, 
-  {
     "deps": [], 
     "headers": [
       "test/cpp/util/test_config.h"
@@ -5534,6 +5536,8 @@
       "thrift_util"
     ], 
     "headers": [
+      "src/proto/grpc/health/v1/health.grpc.pb.h", 
+      "src/proto/grpc/health/v1/health.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/echo.grpc.pb.h", 
@@ -7100,6 +7104,7 @@
       "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", 
@@ -7220,6 +7225,7 @@
       "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", 
@@ -8121,9 +8127,11 @@
       "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", 
@@ -8160,6 +8168,8 @@
       "src/cpp/client/create_channel_internal.h", 
       "src/cpp/common/channel_filter.h", 
       "src/cpp/server/dynamic_thread_pool.h", 
+      "src/cpp/server/health/default_health_check_service.h", 
+      "src/cpp/server/health/health.pb.h", 
       "src/cpp/server/thread_pool_interface.h", 
       "src/cpp/thread_manager/thread_manager.h"
     ], 
@@ -8173,9 +8183,11 @@
       "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", 
@@ -8229,6 +8241,12 @@
       "src/cpp/server/create_default_thread_pool.cc", 
       "src/cpp/server/dynamic_thread_pool.cc", 
       "src/cpp/server/dynamic_thread_pool.h", 
+      "src/cpp/server/health/default_health_check_service.cc", 
+      "src/cpp/server/health/default_health_check_service.h", 
+      "src/cpp/server/health/health.pb.c", 
+      "src/cpp/server/health/health.pb.h", 
+      "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", 
@@ -8380,6 +8398,22 @@
   }, 
   {
     "deps": [
+      "grpc++"
+    ], 
+    "headers": [
+      "include/grpc++/test/server_context_test_spouse.h"
+    ], 
+    "is_filegroup": true, 
+    "language": "c++", 
+    "name": "grpc++_test", 
+    "src": [
+      "include/grpc++/test/server_context_test_spouse.h"
+    ], 
+    "third_party": false, 
+    "type": "filegroup"
+  }, 
+  {
+    "deps": [
       "grpc++_codegen_base"
     ], 
     "headers": [
diff --git a/tools/run_tests/generated/tests.json b/tools/run_tests/generated/tests.json
index a161e8a..0cfdab4 100644
--- a/tools/run_tests/generated/tests.json
+++ b/tools/run_tests/generated/tests.json
@@ -1529,28 +1529,6 @@
       "posix", 
       "windows"
     ], 
-    "cpu_cost": 0.1, 
-    "exclude_configs": [], 
-    "exclude_iomgrs": [], 
-    "flaky": true, 
-    "gtest": false, 
-    "language": "c", 
-    "name": "lb_policies_test", 
-    "platforms": [
-      "linux", 
-      "mac", 
-      "posix", 
-      "windows"
-    ]
-  }, 
-  {
-    "args": [], 
-    "ci_platforms": [
-      "linux", 
-      "mac", 
-      "posix", 
-      "windows"
-    ], 
     "cpu_cost": 1.0, 
     "exclude_configs": [], 
     "exclude_iomgrs": [], 
@@ -2918,6 +2896,28 @@
     "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++", 
diff --git a/tools/run_tests/run_microbenchmark.py b/tools/run_tests/run_microbenchmark.py
index 262c05b..d709cfc 100755
--- a/tools/run_tests/run_microbenchmark.py
+++ b/tools/run_tests/run_microbenchmark.py
@@ -93,7 +93,9 @@
                                        '--benchmark_list_tests']).splitlines():
     link(line, '%s.txt' % fnize(line))
     benchmarks.append(
-        jobset.JobSpec(['bins/basicprof/%s' % bm_name, '--benchmark_filter=^%s$' % line],
+        jobset.JobSpec(['bins/basicprof/%s' % bm_name,
+                        '--benchmark_filter=^%s$' % line,
+                        '--benchmark_min_time=0.05'],
                        environ={'LATENCY_TRACE': '%s.trace' % fnize(line)}))
     profile_analysis.append(
         jobset.JobSpec([sys.executable,
@@ -105,7 +107,7 @@
     # consume upwards of five gigabytes of ram in some cases, and so analysing
     # hundreds of them at once is impractical -- but we want at least some
     # concurrency or the work takes too long
-    if len(benchmarks) >= min(4, multiprocessing.cpu_count()):
+    if len(benchmarks) >= min(16, multiprocessing.cpu_count()):
       # run up to half the cpu count: each benchmark can use up to two cores
       # (one for the microbenchmark, one for the data flush)
       jobset.run(benchmarks, maxjobs=max(1, multiprocessing.cpu_count()/2),
diff --git a/tools/run_tests/run_tests.py b/tools/run_tests/run_tests.py
index 3d9b538..cfc2b04 100755
--- a/tools/run_tests/run_tests.py
+++ b/tools/run_tests/run_tests.py
@@ -1099,6 +1099,18 @@
         raise argparse.ArgumentTypeError(msg)
 
 
+def percent_type(arg_str):
+  pct = float(arg_str)
+  if pct > 100 or pct < 0:
+    raise argparse.ArgumentTypeError(
+        "'%f' is not a valid percentage in the [0, 100] range" % pct)
+  return pct
+
+# This is math.isclose in python >= 3.5
+def isclose(a, b, rel_tol=1e-09, abs_tol=0.0):
+      return abs(a-b) <= max(rel_tol * max(abs(a), abs(b)), abs_tol)
+
+
 # parse command line
 argp = argparse.ArgumentParser(description='Run grpc tests.')
 argp.add_argument('-c', '--config',
@@ -1111,6 +1123,8 @@
 argp.add_argument('--regex_exclude', default='', type=str)
 argp.add_argument('-j', '--jobs', default=multiprocessing.cpu_count(), type=int)
 argp.add_argument('-s', '--slowdown', default=1.0, type=float)
+argp.add_argument('-p', '--sample_percent', default=100.0, type=percent_type,
+                  help='Run a random sample with that percentage of tests')
 argp.add_argument('-f', '--forever',
                   default=False,
                   action='store_const',
@@ -1443,8 +1457,18 @@
     else:
       # whereas otherwise, we want to shuffle things up to give all tests a
       # chance to run.
-      massaged_one_run = list(one_run)  # random.shuffle needs an indexable seq.
-      random.shuffle(massaged_one_run)  # which it modifies in-place.
+      massaged_one_run = list(one_run)  # random.sample needs an indexable seq.
+      num_jobs = len(massaged_one_run)
+      # for a random sample, get as many as indicated by the 'sample_percent'
+      # argument. By default this arg is 100, resulting in a shuffle of all
+      # jobs.
+      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):
+        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
@@ -1455,7 +1479,7 @@
       jobset.message('START', 'Running tests quietly, only failing tests will be reported', do_newline=True)
     num_test_failures, resultset = jobset.run(
         all_runs, check_cancelled, newline_on_success=newline_on_success,
-        travis=args.travis, infinite_runs=infinite_runs, maxjobs=args.jobs,
+        travis=args.travis, maxjobs=args.jobs,
         stop_on_failure=args.stop_on_failure,
         add_env={'GRPC_TEST_PORT_SERVER': 'localhost:%d' % port_server_port},
         quiet_success=args.quiet_success)
diff --git a/vsprojects/vcxproj/grpc++/grpc++.vcxproj b/vsprojects/vcxproj/grpc++/grpc++.vcxproj
index 5859774..45f3037 100644
--- a/vsprojects/vcxproj/grpc++/grpc++.vcxproj
+++ b/vsprojects/vcxproj/grpc++/grpc++.vcxproj
@@ -264,9 +264,11 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\completion_queue.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\create_channel.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\create_channel_posix.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\ext\health_check_service_server_builder_option.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\generic\async_generic_service.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\generic\generic_stub.h" />
     <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\client_unary_call.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\core_codegen.h" />
@@ -360,6 +362,8 @@
     <ClInclude Include="$(SolutionDir)\..\src\cpp\client\create_channel_internal.h" />
     <ClInclude Include="$(SolutionDir)\..\src\cpp\common\channel_filter.h" />
     <ClInclude Include="$(SolutionDir)\..\src\cpp\server\dynamic_thread_pool.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\cpp\server\health\default_health_check_service.h" />
+    <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" />
   </ItemGroup>
@@ -414,6 +418,14 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\server\dynamic_thread_pool.cc">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\cpp\server\health\default_health_check_service.cc">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\cpp\server\health\health.pb.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\cpp\server\health\health_check_service.cc">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\cpp\server\health\health_check_service_server_builder_option.cc">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\server\server_builder.cc">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\server\server_cc.cc">
diff --git a/vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters b/vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters
index 4b501a1..95cdb74 100644
--- a/vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters
@@ -76,6 +76,18 @@
     <ClCompile Include="$(SolutionDir)\..\src\cpp\server\dynamic_thread_pool.cc">
       <Filter>src\cpp\server</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\cpp\server\health\default_health_check_service.cc">
+      <Filter>src\cpp\server\health</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\cpp\server\health\health.pb.c">
+      <Filter>src\cpp\server\health</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\cpp\server\health\health_check_service.cc">
+      <Filter>src\cpp\server\health</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\cpp\server\health\health_check_service_server_builder_option.cc">
+      <Filter>src\cpp\server\health</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\server\server_builder.cc">
       <Filter>src\cpp\server</Filter>
     </ClCompile>
@@ -132,6 +144,9 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\create_channel_posix.h">
       <Filter>include\grpc++</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\ext\health_check_service_server_builder_option.h">
+      <Filter>include\grpc++\ext</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\generic\async_generic_service.h">
       <Filter>include\grpc++\generic</Filter>
     </ClInclude>
@@ -141,6 +156,9 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\grpc++.h">
       <Filter>include\grpc++</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\health_check_service_interface.h">
+      <Filter>include\grpc++</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\call.h">
       <Filter>include\grpc++\impl</Filter>
     </ClInclude>
@@ -416,6 +434,12 @@
     <ClInclude Include="$(SolutionDir)\..\src\cpp\server\dynamic_thread_pool.h">
       <Filter>src\cpp\server</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\cpp\server\health\default_health_check_service.h">
+      <Filter>src\cpp\server\health</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\cpp\server\health\health.pb.h">
+      <Filter>src\cpp\server\health</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\cpp\server\thread_pool_interface.h">
       <Filter>src\cpp\server</Filter>
     </ClInclude>
@@ -434,6 +458,9 @@
     <Filter Include="include\grpc++">
       <UniqueIdentifier>{784a0281-f547-aeb0-9f55-b26b7de9c769}</UniqueIdentifier>
     </Filter>
+    <Filter Include="include\grpc++\ext">
+      <UniqueIdentifier>{25501d8e-5fae-2fe4-14a6-d69a07acefdd}</UniqueIdentifier>
+    </Filter>
     <Filter Include="include\grpc++\generic">
       <UniqueIdentifier>{51dae921-3aa2-1976-2ee4-c5615de1af54}</UniqueIdentifier>
     </Filter>
@@ -476,6 +503,9 @@
     <Filter Include="src\cpp\server">
       <UniqueIdentifier>{321b0980-74ad-e8ca-f23b-deffa5d6bb8f}</UniqueIdentifier>
     </Filter>
+    <Filter Include="src\cpp\server\health">
+      <UniqueIdentifier>{5bc9ef4e-78c1-159e-4e4e-30ddfce3e140}</UniqueIdentifier>
+    </Filter>
     <Filter Include="src\cpp\thread_manager">
       <UniqueIdentifier>{23f9df56-8604-52a0-e6a2-f01b8e68d0e7}</UniqueIdentifier>
     </Filter>
diff --git a/vsprojects/vcxproj/grpc++_test/grpc++_test.vcxproj b/vsprojects/vcxproj/grpc++_test/grpc++_test.vcxproj
deleted file mode 100644
index cd3e406..0000000
--- a/vsprojects/vcxproj/grpc++_test/grpc++_test.vcxproj
+++ /dev/null
@@ -1,170 +0,0 @@
-<?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>{3D3EAEA9-76C4-0CFE-4718-5A1F6B7F72C8}</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++_test</TargetName>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)'=='Release'">
-    <TargetName>grpc++_test</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++\test\server_context_test_spouse.h" />
-  </ItemGroup>
-  <ItemGroup>
-    <ClCompile Include="$(SolutionDir)\..\src\cpp\test\server_context_test_spouse.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++_test/grpc++_test.vcxproj.filters b/vsprojects/vcxproj/grpc++_test/grpc++_test.vcxproj.filters
deleted file mode 100644
index e1d8fe1..0000000
--- a/vsprojects/vcxproj/grpc++_test/grpc++_test.vcxproj.filters
+++ /dev/null
@@ -1,35 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <ItemGroup>
-    <ClCompile Include="$(SolutionDir)\..\src\cpp\test\server_context_test_spouse.cc">
-      <Filter>src\cpp\test</Filter>
-    </ClCompile>
-  </ItemGroup>
-  <ItemGroup>
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\test\server_context_test_spouse.h">
-      <Filter>include\grpc++\test</Filter>
-    </ClInclude>
-  </ItemGroup>
-
-  <ItemGroup>
-    <Filter Include="include">
-      <UniqueIdentifier>{418e2be9-9a04-af8a-8878-956543c507a1}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="include\grpc++">
-      <UniqueIdentifier>{bcaf3a2d-e884-bfbd-477b-09634054bcc5}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="include\grpc++\test">
-      <UniqueIdentifier>{3a14b66f-1d31-2d06-e9a1-c6d1199ab04d}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="src">
-      <UniqueIdentifier>{bc08c75b-ee7e-85a0-fb0f-7586bbd33c6f}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="src\cpp">
-      <UniqueIdentifier>{9797a57d-93ac-ff9c-5ac6-fd335777d782}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="src\cpp\test">
-      <UniqueIdentifier>{58d4b4e0-5617-abf4-48a6-f1264d127b27}</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 ba12f0b..13d80ec 100644
--- a/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj
+++ b/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj
@@ -210,6 +210,14 @@
     <ClInclude Include="$(SolutionDir)\..\test\cpp\util\test_credentials_provider.h" />
   </ItemGroup>
   <ItemGroup>
+    <ClCompile Include="$(SolutionDir)\..\src\proto\grpc\health\v1\health.pb.cc">
+    </ClCompile>
+    <ClInclude Include="$(SolutionDir)\..\src\proto\grpc\health\v1\health.pb.h">
+    </ClInclude>
+    <ClCompile Include="$(SolutionDir)\..\src\proto\grpc\health\v1\health.grpc.pb.cc">
+    </ClCompile>
+    <ClInclude Include="$(SolutionDir)\..\src\proto\grpc\health\v1\health.grpc.pb.h">
+    </ClInclude>
     <ClCompile Include="$(SolutionDir)\..\src\proto\grpc\testing\echo_messages.pb.cc">
     </ClCompile>
     <ClInclude Include="$(SolutionDir)\..\src\proto\grpc\testing\echo_messages.pb.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 116a639..7981feb 100644
--- a/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj.filters
@@ -1,6 +1,9 @@
 <?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\health\v1\health.proto">
+      <Filter>src\proto\grpc\health\v1</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\proto\grpc\testing\echo_messages.proto">
       <Filter>src\proto\grpc\testing</Filter>
     </ClCompile>
@@ -254,6 +257,12 @@
     <Filter Include="src\proto\grpc">
       <UniqueIdentifier>{f3daac52-2bfd-362e-9a76-04cd7a90aa34}</UniqueIdentifier>
     </Filter>
+    <Filter Include="src\proto\grpc\health">
+      <UniqueIdentifier>{d2393dd7-6f95-0e70-c36d-cd8ef8e2f17e}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\proto\grpc\health\v1">
+      <UniqueIdentifier>{f2f10901-f74f-a55a-abea-082923feb664}</UniqueIdentifier>
+    </Filter>
     <Filter Include="src\proto\grpc\testing">
       <UniqueIdentifier>{3df5f11f-e018-1126-8c22-291540035aa8}</UniqueIdentifier>
     </Filter>
diff --git a/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj b/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj
index f073ea5..22ea361 100644
--- a/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj
+++ b/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj
@@ -264,9 +264,11 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\completion_queue.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\create_channel.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\create_channel_posix.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\ext\health_check_service_server_builder_option.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\generic\async_generic_service.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\generic\generic_stub.h" />
     <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\client_unary_call.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\core_codegen.h" />
@@ -354,6 +356,8 @@
     <ClInclude Include="$(SolutionDir)\..\src\cpp\client\create_channel_internal.h" />
     <ClInclude Include="$(SolutionDir)\..\src\cpp\common\channel_filter.h" />
     <ClInclude Include="$(SolutionDir)\..\src\cpp\server\dynamic_thread_pool.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\cpp\server\health\default_health_check_service.h" />
+    <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" />
   </ItemGroup>
@@ -398,6 +402,14 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\server\dynamic_thread_pool.cc">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\cpp\server\health\default_health_check_service.cc">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\cpp\server\health\health.pb.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\cpp\server\health\health_check_service.cc">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\cpp\server\health\health_check_service_server_builder_option.cc">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\server\server_builder.cc">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\server\server_cc.cc">
diff --git a/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters b/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters
index a2515e2..c3cef2d 100644
--- a/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters
@@ -61,6 +61,18 @@
     <ClCompile Include="$(SolutionDir)\..\src\cpp\server\dynamic_thread_pool.cc">
       <Filter>src\cpp\server</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\cpp\server\health\default_health_check_service.cc">
+      <Filter>src\cpp\server\health</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\cpp\server\health\health.pb.c">
+      <Filter>src\cpp\server\health</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\cpp\server\health\health_check_service.cc">
+      <Filter>src\cpp\server\health</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\cpp\server\health\health_check_service_server_builder_option.cc">
+      <Filter>src\cpp\server\health</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\server\server_builder.cc">
       <Filter>src\cpp\server</Filter>
     </ClCompile>
@@ -117,6 +129,9 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\create_channel_posix.h">
       <Filter>include\grpc++</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\ext\health_check_service_server_builder_option.h">
+      <Filter>include\grpc++\ext</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\generic\async_generic_service.h">
       <Filter>include\grpc++\generic</Filter>
     </ClInclude>
@@ -126,6 +141,9 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\grpc++.h">
       <Filter>include\grpc++</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\health_check_service_interface.h">
+      <Filter>include\grpc++</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\call.h">
       <Filter>include\grpc++\impl</Filter>
     </ClInclude>
@@ -383,6 +401,12 @@
     <ClInclude Include="$(SolutionDir)\..\src\cpp\server\dynamic_thread_pool.h">
       <Filter>src\cpp\server</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\cpp\server\health\default_health_check_service.h">
+      <Filter>src\cpp\server\health</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\cpp\server\health\health.pb.h">
+      <Filter>src\cpp\server\health</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\cpp\server\thread_pool_interface.h">
       <Filter>src\cpp\server</Filter>
     </ClInclude>
@@ -401,6 +425,9 @@
     <Filter Include="include\grpc++">
       <UniqueIdentifier>{eceb50c0-bb49-3812-b6bd-b0af6df81da7}</UniqueIdentifier>
     </Filter>
+    <Filter Include="include\grpc++\ext">
+      <UniqueIdentifier>{e6643be2-2b2f-953d-ab14-27d89c835c8a}</UniqueIdentifier>
+    </Filter>
     <Filter Include="include\grpc++\generic">
       <UniqueIdentifier>{83717d3c-57d9-2bfa-ed9c-2b08f86da12b}</UniqueIdentifier>
     </Filter>
@@ -443,6 +470,9 @@
     <Filter Include="src\cpp\server">
       <UniqueIdentifier>{8a54a279-d14b-4237-0df3-1ffe1ef5a7af}</UniqueIdentifier>
     </Filter>
+    <Filter Include="src\cpp\server\health">
+      <UniqueIdentifier>{a003cb5c-7249-106c-8ee5-de5e11a6692c}</UniqueIdentifier>
+    </Filter>
     <Filter Include="src\cpp\thread_manager">
       <UniqueIdentifier>{e5b55f25-d99f-b8e5-9981-7da7fa7ba628}</UniqueIdentifier>
     </Filter>
diff --git a/vsprojects/vcxproj/grpc/grpc.vcxproj b/vsprojects/vcxproj/grpc/grpc.vcxproj
index 73d511e..fde60be 100644
--- a/vsprojects/vcxproj/grpc/grpc.vcxproj
+++ b/vsprojects/vcxproj/grpc/grpc.vcxproj
@@ -273,6 +273,7 @@
     <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" />
diff --git a/vsprojects/vcxproj/grpc/grpc.vcxproj.filters b/vsprojects/vcxproj/grpc/grpc.vcxproj.filters
index dae5504..8edbbc2 100644
--- a/vsprojects/vcxproj/grpc/grpc.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc/grpc.vcxproj.filters
@@ -696,6 +696,9 @@
     <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>
diff --git a/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj b/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj
index 504a3fc..6d4b4f7 100644
--- a/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj
+++ b/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj
@@ -153,6 +153,7 @@
     <ClInclude Include="$(SolutionDir)\..\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" />
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 8e51a64..5444f6f 100644
--- a/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj.filters
@@ -441,6 +441,9 @@
     <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>
diff --git a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj
index 5bdbff9..22f4740 100644
--- a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj
+++ b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj
@@ -264,6 +264,7 @@
     <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" />
diff --git a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters
index b2b46b0..5021cb4 100644
--- a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters
@@ -609,6 +609,9 @@
     <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>
diff --git a/vsprojects/vcxproj/test/health_service_end2end_test/health_service_end2end_test.vcxproj b/vsprojects/vcxproj/test/health_service_end2end_test/health_service_end2end_test.vcxproj
new file mode 100644
index 0000000..28530d0
--- /dev/null
+++ b/vsprojects/vcxproj/test/health_service_end2end_test/health_service_end2end_test.vcxproj
@@ -0,0 +1,207 @@
+<?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>{3EB2B3E9-8BC3-8DF7-82CB-38462FFE5919}</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>health_service_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>health_service_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)\..\test\cpp\end2end\health_service_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/health_service_end2end_test/health_service_end2end_test.vcxproj.filters b/vsprojects/vcxproj/test/health_service_end2end_test/health_service_end2end_test.vcxproj.filters
new file mode 100644
index 0000000..cccf968
--- /dev/null
+++ b/vsprojects/vcxproj/test/health_service_end2end_test/health_service_end2end_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\cpp\end2end\health_service_end2end_test.cc">
+      <Filter>test\cpp\end2end</Filter>
+    </ClCompile>
+  </ItemGroup>
+
+  <ItemGroup>
+    <Filter Include="test">
+      <UniqueIdentifier>{00d750b2-db02-2106-d9b7-1d3b2ca58604}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="test\cpp">
+      <UniqueIdentifier>{02e29b2f-d68a-4474-8483-621ecfd7fa9d}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="test\cpp\end2end">
+      <UniqueIdentifier>{b0de697a-d73a-23e1-c9af-fa0edf011d4d}</UniqueIdentifier>
+    </Filter>
+  </ItemGroup>
+</Project>
+
diff --git a/vsprojects/vcxproj/test/server_context_test_spouse_test/server_context_test_spouse_test.vcxproj b/vsprojects/vcxproj/test/server_context_test_spouse_test/server_context_test_spouse_test.vcxproj
index 9e586c6..fe2b1ab 100644
--- a/vsprojects/vcxproj/test/server_context_test_spouse_test/server_context_test_spouse_test.vcxproj
+++ b/vsprojects/vcxproj/test/server_context_test_spouse_test/server_context_test_spouse_test.vcxproj
@@ -167,9 +167,6 @@
     <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++_test\grpc++_test.vcxproj">
-      <Project>{3D3EAEA9-76C4-0CFE-4718-5A1F6B7F72C8}</Project>
-    </ProjectReference>
     <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc++\grpc++.vcxproj">
       <Project>{C187A093-A0FE-489D-A40A-6E33DE0F9FEB}</Project>
     </ProjectReference>