Merge github.com:grpc/grpc into configurable-lookahead
diff --git a/Makefile b/Makefile
index 53d0696..419715c 100644
--- a/Makefile
+++ b/Makefile
@@ -312,7 +312,7 @@
 Q = @
 endif
 
-VERSION = 0.11.0.0
+VERSION = 0.12.0.0
 
 CPPFLAGS_NO_ARCH += $(addprefix -I, $(INCLUDES)) $(addprefix -D, $(DEFINES))
 CPPFLAGS += $(CPPFLAGS_NO_ARCH) $(ARCH_FLAGS)
@@ -879,6 +879,7 @@
 interop_client: $(BINDIR)/$(CONFIG)/interop_client
 interop_server: $(BINDIR)/$(CONFIG)/interop_server
 interop_test: $(BINDIR)/$(CONFIG)/interop_test
+metrics_client: $(BINDIR)/$(CONFIG)/metrics_client
 mock_test: $(BINDIR)/$(CONFIG)/mock_test
 qps_driver: $(BINDIR)/$(CONFIG)/qps_driver
 qps_interarrival_test: $(BINDIR)/$(CONFIG)/qps_interarrival_test
@@ -916,6 +917,7 @@
 h2_compress_empty_batch_test: $(BINDIR)/$(CONFIG)/h2_compress_empty_batch_test
 h2_compress_graceful_server_shutdown_test: $(BINDIR)/$(CONFIG)/h2_compress_graceful_server_shutdown_test
 h2_compress_high_initial_seqno_test: $(BINDIR)/$(CONFIG)/h2_compress_high_initial_seqno_test
+h2_compress_hpack_size_test: $(BINDIR)/$(CONFIG)/h2_compress_hpack_size_test
 h2_compress_invoke_large_request_test: $(BINDIR)/$(CONFIG)/h2_compress_invoke_large_request_test
 h2_compress_large_metadata_test: $(BINDIR)/$(CONFIG)/h2_compress_large_metadata_test
 h2_compress_max_concurrent_streams_test: $(BINDIR)/$(CONFIG)/h2_compress_max_concurrent_streams_test
@@ -951,6 +953,7 @@
 h2_fakesec_empty_batch_test: $(BINDIR)/$(CONFIG)/h2_fakesec_empty_batch_test
 h2_fakesec_graceful_server_shutdown_test: $(BINDIR)/$(CONFIG)/h2_fakesec_graceful_server_shutdown_test
 h2_fakesec_high_initial_seqno_test: $(BINDIR)/$(CONFIG)/h2_fakesec_high_initial_seqno_test
+h2_fakesec_hpack_size_test: $(BINDIR)/$(CONFIG)/h2_fakesec_hpack_size_test
 h2_fakesec_invoke_large_request_test: $(BINDIR)/$(CONFIG)/h2_fakesec_invoke_large_request_test
 h2_fakesec_large_metadata_test: $(BINDIR)/$(CONFIG)/h2_fakesec_large_metadata_test
 h2_fakesec_max_concurrent_streams_test: $(BINDIR)/$(CONFIG)/h2_fakesec_max_concurrent_streams_test
@@ -986,6 +989,7 @@
 h2_full_empty_batch_test: $(BINDIR)/$(CONFIG)/h2_full_empty_batch_test
 h2_full_graceful_server_shutdown_test: $(BINDIR)/$(CONFIG)/h2_full_graceful_server_shutdown_test
 h2_full_high_initial_seqno_test: $(BINDIR)/$(CONFIG)/h2_full_high_initial_seqno_test
+h2_full_hpack_size_test: $(BINDIR)/$(CONFIG)/h2_full_hpack_size_test
 h2_full_invoke_large_request_test: $(BINDIR)/$(CONFIG)/h2_full_invoke_large_request_test
 h2_full_large_metadata_test: $(BINDIR)/$(CONFIG)/h2_full_large_metadata_test
 h2_full_max_concurrent_streams_test: $(BINDIR)/$(CONFIG)/h2_full_max_concurrent_streams_test
@@ -1021,6 +1025,7 @@
 h2_full+poll_empty_batch_test: $(BINDIR)/$(CONFIG)/h2_full+poll_empty_batch_test
 h2_full+poll_graceful_server_shutdown_test: $(BINDIR)/$(CONFIG)/h2_full+poll_graceful_server_shutdown_test
 h2_full+poll_high_initial_seqno_test: $(BINDIR)/$(CONFIG)/h2_full+poll_high_initial_seqno_test
+h2_full+poll_hpack_size_test: $(BINDIR)/$(CONFIG)/h2_full+poll_hpack_size_test
 h2_full+poll_invoke_large_request_test: $(BINDIR)/$(CONFIG)/h2_full+poll_invoke_large_request_test
 h2_full+poll_large_metadata_test: $(BINDIR)/$(CONFIG)/h2_full+poll_large_metadata_test
 h2_full+poll_max_concurrent_streams_test: $(BINDIR)/$(CONFIG)/h2_full+poll_max_concurrent_streams_test
@@ -1056,6 +1061,7 @@
 h2_oauth2_empty_batch_test: $(BINDIR)/$(CONFIG)/h2_oauth2_empty_batch_test
 h2_oauth2_graceful_server_shutdown_test: $(BINDIR)/$(CONFIG)/h2_oauth2_graceful_server_shutdown_test
 h2_oauth2_high_initial_seqno_test: $(BINDIR)/$(CONFIG)/h2_oauth2_high_initial_seqno_test
+h2_oauth2_hpack_size_test: $(BINDIR)/$(CONFIG)/h2_oauth2_hpack_size_test
 h2_oauth2_invoke_large_request_test: $(BINDIR)/$(CONFIG)/h2_oauth2_invoke_large_request_test
 h2_oauth2_large_metadata_test: $(BINDIR)/$(CONFIG)/h2_oauth2_large_metadata_test
 h2_oauth2_max_concurrent_streams_test: $(BINDIR)/$(CONFIG)/h2_oauth2_max_concurrent_streams_test
@@ -1119,6 +1125,7 @@
 h2_sockpair_empty_batch_test: $(BINDIR)/$(CONFIG)/h2_sockpair_empty_batch_test
 h2_sockpair_graceful_server_shutdown_test: $(BINDIR)/$(CONFIG)/h2_sockpair_graceful_server_shutdown_test
 h2_sockpair_high_initial_seqno_test: $(BINDIR)/$(CONFIG)/h2_sockpair_high_initial_seqno_test
+h2_sockpair_hpack_size_test: $(BINDIR)/$(CONFIG)/h2_sockpair_hpack_size_test
 h2_sockpair_invoke_large_request_test: $(BINDIR)/$(CONFIG)/h2_sockpair_invoke_large_request_test
 h2_sockpair_large_metadata_test: $(BINDIR)/$(CONFIG)/h2_sockpair_large_metadata_test
 h2_sockpair_max_concurrent_streams_test: $(BINDIR)/$(CONFIG)/h2_sockpair_max_concurrent_streams_test
@@ -1181,6 +1188,7 @@
 h2_sockpair_1byte_empty_batch_test: $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_empty_batch_test
 h2_sockpair_1byte_graceful_server_shutdown_test: $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_graceful_server_shutdown_test
 h2_sockpair_1byte_high_initial_seqno_test: $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_high_initial_seqno_test
+h2_sockpair_1byte_hpack_size_test: $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_hpack_size_test
 h2_sockpair_1byte_invoke_large_request_test: $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_invoke_large_request_test
 h2_sockpair_1byte_large_metadata_test: $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_large_metadata_test
 h2_sockpair_1byte_max_concurrent_streams_test: $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_max_concurrent_streams_test
@@ -1215,6 +1223,7 @@
 h2_ssl_empty_batch_test: $(BINDIR)/$(CONFIG)/h2_ssl_empty_batch_test
 h2_ssl_graceful_server_shutdown_test: $(BINDIR)/$(CONFIG)/h2_ssl_graceful_server_shutdown_test
 h2_ssl_high_initial_seqno_test: $(BINDIR)/$(CONFIG)/h2_ssl_high_initial_seqno_test
+h2_ssl_hpack_size_test: $(BINDIR)/$(CONFIG)/h2_ssl_hpack_size_test
 h2_ssl_invoke_large_request_test: $(BINDIR)/$(CONFIG)/h2_ssl_invoke_large_request_test
 h2_ssl_large_metadata_test: $(BINDIR)/$(CONFIG)/h2_ssl_large_metadata_test
 h2_ssl_max_concurrent_streams_test: $(BINDIR)/$(CONFIG)/h2_ssl_max_concurrent_streams_test
@@ -1250,6 +1259,7 @@
 h2_ssl+poll_empty_batch_test: $(BINDIR)/$(CONFIG)/h2_ssl+poll_empty_batch_test
 h2_ssl+poll_graceful_server_shutdown_test: $(BINDIR)/$(CONFIG)/h2_ssl+poll_graceful_server_shutdown_test
 h2_ssl+poll_high_initial_seqno_test: $(BINDIR)/$(CONFIG)/h2_ssl+poll_high_initial_seqno_test
+h2_ssl+poll_hpack_size_test: $(BINDIR)/$(CONFIG)/h2_ssl+poll_hpack_size_test
 h2_ssl+poll_invoke_large_request_test: $(BINDIR)/$(CONFIG)/h2_ssl+poll_invoke_large_request_test
 h2_ssl+poll_large_metadata_test: $(BINDIR)/$(CONFIG)/h2_ssl+poll_large_metadata_test
 h2_ssl+poll_max_concurrent_streams_test: $(BINDIR)/$(CONFIG)/h2_ssl+poll_max_concurrent_streams_test
@@ -1316,6 +1326,7 @@
 h2_uchannel_empty_batch_test: $(BINDIR)/$(CONFIG)/h2_uchannel_empty_batch_test
 h2_uchannel_graceful_server_shutdown_test: $(BINDIR)/$(CONFIG)/h2_uchannel_graceful_server_shutdown_test
 h2_uchannel_high_initial_seqno_test: $(BINDIR)/$(CONFIG)/h2_uchannel_high_initial_seqno_test
+h2_uchannel_hpack_size_test: $(BINDIR)/$(CONFIG)/h2_uchannel_hpack_size_test
 h2_uchannel_invoke_large_request_test: $(BINDIR)/$(CONFIG)/h2_uchannel_invoke_large_request_test
 h2_uchannel_large_metadata_test: $(BINDIR)/$(CONFIG)/h2_uchannel_large_metadata_test
 h2_uchannel_max_concurrent_streams_test: $(BINDIR)/$(CONFIG)/h2_uchannel_max_concurrent_streams_test
@@ -1350,6 +1361,7 @@
 h2_uds_empty_batch_test: $(BINDIR)/$(CONFIG)/h2_uds_empty_batch_test
 h2_uds_graceful_server_shutdown_test: $(BINDIR)/$(CONFIG)/h2_uds_graceful_server_shutdown_test
 h2_uds_high_initial_seqno_test: $(BINDIR)/$(CONFIG)/h2_uds_high_initial_seqno_test
+h2_uds_hpack_size_test: $(BINDIR)/$(CONFIG)/h2_uds_hpack_size_test
 h2_uds_invoke_large_request_test: $(BINDIR)/$(CONFIG)/h2_uds_invoke_large_request_test
 h2_uds_large_metadata_test: $(BINDIR)/$(CONFIG)/h2_uds_large_metadata_test
 h2_uds_max_concurrent_streams_test: $(BINDIR)/$(CONFIG)/h2_uds_max_concurrent_streams_test
@@ -1384,6 +1396,7 @@
 h2_uds+poll_empty_batch_test: $(BINDIR)/$(CONFIG)/h2_uds+poll_empty_batch_test
 h2_uds+poll_graceful_server_shutdown_test: $(BINDIR)/$(CONFIG)/h2_uds+poll_graceful_server_shutdown_test
 h2_uds+poll_high_initial_seqno_test: $(BINDIR)/$(CONFIG)/h2_uds+poll_high_initial_seqno_test
+h2_uds+poll_hpack_size_test: $(BINDIR)/$(CONFIG)/h2_uds+poll_hpack_size_test
 h2_uds+poll_invoke_large_request_test: $(BINDIR)/$(CONFIG)/h2_uds+poll_invoke_large_request_test
 h2_uds+poll_large_metadata_test: $(BINDIR)/$(CONFIG)/h2_uds+poll_large_metadata_test
 h2_uds+poll_max_concurrent_streams_test: $(BINDIR)/$(CONFIG)/h2_uds+poll_max_concurrent_streams_test
@@ -1418,6 +1431,7 @@
 h2_compress_empty_batch_nosec_test: $(BINDIR)/$(CONFIG)/h2_compress_empty_batch_nosec_test
 h2_compress_graceful_server_shutdown_nosec_test: $(BINDIR)/$(CONFIG)/h2_compress_graceful_server_shutdown_nosec_test
 h2_compress_high_initial_seqno_nosec_test: $(BINDIR)/$(CONFIG)/h2_compress_high_initial_seqno_nosec_test
+h2_compress_hpack_size_nosec_test: $(BINDIR)/$(CONFIG)/h2_compress_hpack_size_nosec_test
 h2_compress_invoke_large_request_nosec_test: $(BINDIR)/$(CONFIG)/h2_compress_invoke_large_request_nosec_test
 h2_compress_large_metadata_nosec_test: $(BINDIR)/$(CONFIG)/h2_compress_large_metadata_nosec_test
 h2_compress_max_concurrent_streams_nosec_test: $(BINDIR)/$(CONFIG)/h2_compress_max_concurrent_streams_nosec_test
@@ -1452,6 +1466,7 @@
 h2_full_empty_batch_nosec_test: $(BINDIR)/$(CONFIG)/h2_full_empty_batch_nosec_test
 h2_full_graceful_server_shutdown_nosec_test: $(BINDIR)/$(CONFIG)/h2_full_graceful_server_shutdown_nosec_test
 h2_full_high_initial_seqno_nosec_test: $(BINDIR)/$(CONFIG)/h2_full_high_initial_seqno_nosec_test
+h2_full_hpack_size_nosec_test: $(BINDIR)/$(CONFIG)/h2_full_hpack_size_nosec_test
 h2_full_invoke_large_request_nosec_test: $(BINDIR)/$(CONFIG)/h2_full_invoke_large_request_nosec_test
 h2_full_large_metadata_nosec_test: $(BINDIR)/$(CONFIG)/h2_full_large_metadata_nosec_test
 h2_full_max_concurrent_streams_nosec_test: $(BINDIR)/$(CONFIG)/h2_full_max_concurrent_streams_nosec_test
@@ -1486,6 +1501,7 @@
 h2_full+poll_empty_batch_nosec_test: $(BINDIR)/$(CONFIG)/h2_full+poll_empty_batch_nosec_test
 h2_full+poll_graceful_server_shutdown_nosec_test: $(BINDIR)/$(CONFIG)/h2_full+poll_graceful_server_shutdown_nosec_test
 h2_full+poll_high_initial_seqno_nosec_test: $(BINDIR)/$(CONFIG)/h2_full+poll_high_initial_seqno_nosec_test
+h2_full+poll_hpack_size_nosec_test: $(BINDIR)/$(CONFIG)/h2_full+poll_hpack_size_nosec_test
 h2_full+poll_invoke_large_request_nosec_test: $(BINDIR)/$(CONFIG)/h2_full+poll_invoke_large_request_nosec_test
 h2_full+poll_large_metadata_nosec_test: $(BINDIR)/$(CONFIG)/h2_full+poll_large_metadata_nosec_test
 h2_full+poll_max_concurrent_streams_nosec_test: $(BINDIR)/$(CONFIG)/h2_full+poll_max_concurrent_streams_nosec_test
@@ -1547,6 +1563,7 @@
 h2_sockpair_empty_batch_nosec_test: $(BINDIR)/$(CONFIG)/h2_sockpair_empty_batch_nosec_test
 h2_sockpair_graceful_server_shutdown_nosec_test: $(BINDIR)/$(CONFIG)/h2_sockpair_graceful_server_shutdown_nosec_test
 h2_sockpair_high_initial_seqno_nosec_test: $(BINDIR)/$(CONFIG)/h2_sockpair_high_initial_seqno_nosec_test
+h2_sockpair_hpack_size_nosec_test: $(BINDIR)/$(CONFIG)/h2_sockpair_hpack_size_nosec_test
 h2_sockpair_invoke_large_request_nosec_test: $(BINDIR)/$(CONFIG)/h2_sockpair_invoke_large_request_nosec_test
 h2_sockpair_large_metadata_nosec_test: $(BINDIR)/$(CONFIG)/h2_sockpair_large_metadata_nosec_test
 h2_sockpair_max_concurrent_streams_nosec_test: $(BINDIR)/$(CONFIG)/h2_sockpair_max_concurrent_streams_nosec_test
@@ -1607,6 +1624,7 @@
 h2_sockpair_1byte_empty_batch_nosec_test: $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_empty_batch_nosec_test
 h2_sockpair_1byte_graceful_server_shutdown_nosec_test: $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_graceful_server_shutdown_nosec_test
 h2_sockpair_1byte_high_initial_seqno_nosec_test: $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_high_initial_seqno_nosec_test
+h2_sockpair_1byte_hpack_size_nosec_test: $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_hpack_size_nosec_test
 h2_sockpair_1byte_invoke_large_request_nosec_test: $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_invoke_large_request_nosec_test
 h2_sockpair_1byte_large_metadata_nosec_test: $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_large_metadata_nosec_test
 h2_sockpair_1byte_max_concurrent_streams_nosec_test: $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_max_concurrent_streams_nosec_test
@@ -1640,6 +1658,7 @@
 h2_uchannel_empty_batch_nosec_test: $(BINDIR)/$(CONFIG)/h2_uchannel_empty_batch_nosec_test
 h2_uchannel_graceful_server_shutdown_nosec_test: $(BINDIR)/$(CONFIG)/h2_uchannel_graceful_server_shutdown_nosec_test
 h2_uchannel_high_initial_seqno_nosec_test: $(BINDIR)/$(CONFIG)/h2_uchannel_high_initial_seqno_nosec_test
+h2_uchannel_hpack_size_nosec_test: $(BINDIR)/$(CONFIG)/h2_uchannel_hpack_size_nosec_test
 h2_uchannel_invoke_large_request_nosec_test: $(BINDIR)/$(CONFIG)/h2_uchannel_invoke_large_request_nosec_test
 h2_uchannel_large_metadata_nosec_test: $(BINDIR)/$(CONFIG)/h2_uchannel_large_metadata_nosec_test
 h2_uchannel_max_concurrent_streams_nosec_test: $(BINDIR)/$(CONFIG)/h2_uchannel_max_concurrent_streams_nosec_test
@@ -1673,6 +1692,7 @@
 h2_uds_empty_batch_nosec_test: $(BINDIR)/$(CONFIG)/h2_uds_empty_batch_nosec_test
 h2_uds_graceful_server_shutdown_nosec_test: $(BINDIR)/$(CONFIG)/h2_uds_graceful_server_shutdown_nosec_test
 h2_uds_high_initial_seqno_nosec_test: $(BINDIR)/$(CONFIG)/h2_uds_high_initial_seqno_nosec_test
+h2_uds_hpack_size_nosec_test: $(BINDIR)/$(CONFIG)/h2_uds_hpack_size_nosec_test
 h2_uds_invoke_large_request_nosec_test: $(BINDIR)/$(CONFIG)/h2_uds_invoke_large_request_nosec_test
 h2_uds_large_metadata_nosec_test: $(BINDIR)/$(CONFIG)/h2_uds_large_metadata_nosec_test
 h2_uds_max_concurrent_streams_nosec_test: $(BINDIR)/$(CONFIG)/h2_uds_max_concurrent_streams_nosec_test
@@ -1706,6 +1726,7 @@
 h2_uds+poll_empty_batch_nosec_test: $(BINDIR)/$(CONFIG)/h2_uds+poll_empty_batch_nosec_test
 h2_uds+poll_graceful_server_shutdown_nosec_test: $(BINDIR)/$(CONFIG)/h2_uds+poll_graceful_server_shutdown_nosec_test
 h2_uds+poll_high_initial_seqno_nosec_test: $(BINDIR)/$(CONFIG)/h2_uds+poll_high_initial_seqno_nosec_test
+h2_uds+poll_hpack_size_nosec_test: $(BINDIR)/$(CONFIG)/h2_uds+poll_hpack_size_nosec_test
 h2_uds+poll_invoke_large_request_nosec_test: $(BINDIR)/$(CONFIG)/h2_uds+poll_invoke_large_request_nosec_test
 h2_uds+poll_large_metadata_nosec_test: $(BINDIR)/$(CONFIG)/h2_uds+poll_large_metadata_nosec_test
 h2_uds+poll_max_concurrent_streams_nosec_test: $(BINDIR)/$(CONFIG)/h2_uds+poll_max_concurrent_streams_nosec_test
@@ -1822,7 +1843,7 @@
 
 privatelibs: privatelibs_c privatelibs_cxx
 
-privatelibs_c:  $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libreconnect_server.a $(LIBDIR)/$(CONFIG)/libend2end_fixture_h2_compress.a $(LIBDIR)/$(CONFIG)/libend2end_fixture_h2_fakesec.a $(LIBDIR)/$(CONFIG)/libend2end_fixture_h2_full.a $(LIBDIR)/$(CONFIG)/libend2end_fixture_h2_full+poll.a $(LIBDIR)/$(CONFIG)/libend2end_fixture_h2_oauth2.a $(LIBDIR)/$(CONFIG)/libend2end_fixture_h2_proxy.a $(LIBDIR)/$(CONFIG)/libend2end_fixture_h2_sockpair.a $(LIBDIR)/$(CONFIG)/libend2end_fixture_h2_sockpair+trace.a $(LIBDIR)/$(CONFIG)/libend2end_fixture_h2_sockpair_1byte.a $(LIBDIR)/$(CONFIG)/libend2end_fixture_h2_ssl.a $(LIBDIR)/$(CONFIG)/libend2end_fixture_h2_ssl+poll.a $(LIBDIR)/$(CONFIG)/libend2end_fixture_h2_ssl_proxy.a $(LIBDIR)/$(CONFIG)/libend2end_fixture_h2_uchannel.a $(LIBDIR)/$(CONFIG)/libend2end_fixture_h2_uds.a $(LIBDIR)/$(CONFIG)/libend2end_fixture_h2_uds+poll.a $(LIBDIR)/$(CONFIG)/libend2end_test_bad_hostname.a $(LIBDIR)/$(CONFIG)/libend2end_test_binary_metadata.a $(LIBDIR)/$(CONFIG)/libend2end_test_call_creds.a $(LIBDIR)/$(CONFIG)/libend2end_test_cancel_after_accept.a $(LIBDIR)/$(CONFIG)/libend2end_test_cancel_after_client_done.a $(LIBDIR)/$(CONFIG)/libend2end_test_cancel_after_invoke.a $(LIBDIR)/$(CONFIG)/libend2end_test_cancel_before_invoke.a $(LIBDIR)/$(CONFIG)/libend2end_test_cancel_in_a_vacuum.a $(LIBDIR)/$(CONFIG)/libend2end_test_cancel_with_status.a $(LIBDIR)/$(CONFIG)/libend2end_test_census_simple_request.a $(LIBDIR)/$(CONFIG)/libend2end_test_channel_connectivity.a $(LIBDIR)/$(CONFIG)/libend2end_test_compressed_payload.a $(LIBDIR)/$(CONFIG)/libend2end_test_default_host.a $(LIBDIR)/$(CONFIG)/libend2end_test_disappearing_server.a $(LIBDIR)/$(CONFIG)/libend2end_test_empty_batch.a $(LIBDIR)/$(CONFIG)/libend2end_test_graceful_server_shutdown.a $(LIBDIR)/$(CONFIG)/libend2end_test_high_initial_seqno.a $(LIBDIR)/$(CONFIG)/libend2end_test_invoke_large_request.a $(LIBDIR)/$(CONFIG)/libend2end_test_large_metadata.a $(LIBDIR)/$(CONFIG)/libend2end_test_max_concurrent_streams.a $(LIBDIR)/$(CONFIG)/libend2end_test_max_message_length.a $(LIBDIR)/$(CONFIG)/libend2end_test_metadata.a $(LIBDIR)/$(CONFIG)/libend2end_test_negative_deadline.a $(LIBDIR)/$(CONFIG)/libend2end_test_no_op.a $(LIBDIR)/$(CONFIG)/libend2end_test_payload.a $(LIBDIR)/$(CONFIG)/libend2end_test_ping_pong_streaming.a $(LIBDIR)/$(CONFIG)/libend2end_test_registered_call.a $(LIBDIR)/$(CONFIG)/libend2end_test_request_with_flags.a $(LIBDIR)/$(CONFIG)/libend2end_test_request_with_payload.a $(LIBDIR)/$(CONFIG)/libend2end_test_server_finishes_request.a $(LIBDIR)/$(CONFIG)/libend2end_test_shutdown_finishes_calls.a $(LIBDIR)/$(CONFIG)/libend2end_test_shutdown_finishes_tags.a $(LIBDIR)/$(CONFIG)/libend2end_test_simple_delayed_request.a $(LIBDIR)/$(CONFIG)/libend2end_test_simple_request.a $(LIBDIR)/$(CONFIG)/libend2end_test_trailing_metadata.a $(LIBDIR)/$(CONFIG)/libend2end_certs.a $(LIBDIR)/$(CONFIG)/libbad_client_test.a
+privatelibs_c:  $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libreconnect_server.a $(LIBDIR)/$(CONFIG)/libend2end_fixture_h2_compress.a $(LIBDIR)/$(CONFIG)/libend2end_fixture_h2_fakesec.a $(LIBDIR)/$(CONFIG)/libend2end_fixture_h2_full.a $(LIBDIR)/$(CONFIG)/libend2end_fixture_h2_full+poll.a $(LIBDIR)/$(CONFIG)/libend2end_fixture_h2_oauth2.a $(LIBDIR)/$(CONFIG)/libend2end_fixture_h2_proxy.a $(LIBDIR)/$(CONFIG)/libend2end_fixture_h2_sockpair.a $(LIBDIR)/$(CONFIG)/libend2end_fixture_h2_sockpair+trace.a $(LIBDIR)/$(CONFIG)/libend2end_fixture_h2_sockpair_1byte.a $(LIBDIR)/$(CONFIG)/libend2end_fixture_h2_ssl.a $(LIBDIR)/$(CONFIG)/libend2end_fixture_h2_ssl+poll.a $(LIBDIR)/$(CONFIG)/libend2end_fixture_h2_ssl_proxy.a $(LIBDIR)/$(CONFIG)/libend2end_fixture_h2_uchannel.a $(LIBDIR)/$(CONFIG)/libend2end_fixture_h2_uds.a $(LIBDIR)/$(CONFIG)/libend2end_fixture_h2_uds+poll.a $(LIBDIR)/$(CONFIG)/libend2end_test_bad_hostname.a $(LIBDIR)/$(CONFIG)/libend2end_test_binary_metadata.a $(LIBDIR)/$(CONFIG)/libend2end_test_call_creds.a $(LIBDIR)/$(CONFIG)/libend2end_test_cancel_after_accept.a $(LIBDIR)/$(CONFIG)/libend2end_test_cancel_after_client_done.a $(LIBDIR)/$(CONFIG)/libend2end_test_cancel_after_invoke.a $(LIBDIR)/$(CONFIG)/libend2end_test_cancel_before_invoke.a $(LIBDIR)/$(CONFIG)/libend2end_test_cancel_in_a_vacuum.a $(LIBDIR)/$(CONFIG)/libend2end_test_cancel_with_status.a $(LIBDIR)/$(CONFIG)/libend2end_test_census_simple_request.a $(LIBDIR)/$(CONFIG)/libend2end_test_channel_connectivity.a $(LIBDIR)/$(CONFIG)/libend2end_test_compressed_payload.a $(LIBDIR)/$(CONFIG)/libend2end_test_default_host.a $(LIBDIR)/$(CONFIG)/libend2end_test_disappearing_server.a $(LIBDIR)/$(CONFIG)/libend2end_test_empty_batch.a $(LIBDIR)/$(CONFIG)/libend2end_test_graceful_server_shutdown.a $(LIBDIR)/$(CONFIG)/libend2end_test_high_initial_seqno.a $(LIBDIR)/$(CONFIG)/libend2end_test_hpack_size.a $(LIBDIR)/$(CONFIG)/libend2end_test_invoke_large_request.a $(LIBDIR)/$(CONFIG)/libend2end_test_large_metadata.a $(LIBDIR)/$(CONFIG)/libend2end_test_max_concurrent_streams.a $(LIBDIR)/$(CONFIG)/libend2end_test_max_message_length.a $(LIBDIR)/$(CONFIG)/libend2end_test_metadata.a $(LIBDIR)/$(CONFIG)/libend2end_test_negative_deadline.a $(LIBDIR)/$(CONFIG)/libend2end_test_no_op.a $(LIBDIR)/$(CONFIG)/libend2end_test_payload.a $(LIBDIR)/$(CONFIG)/libend2end_test_ping_pong_streaming.a $(LIBDIR)/$(CONFIG)/libend2end_test_registered_call.a $(LIBDIR)/$(CONFIG)/libend2end_test_request_with_flags.a $(LIBDIR)/$(CONFIG)/libend2end_test_request_with_payload.a $(LIBDIR)/$(CONFIG)/libend2end_test_server_finishes_request.a $(LIBDIR)/$(CONFIG)/libend2end_test_shutdown_finishes_calls.a $(LIBDIR)/$(CONFIG)/libend2end_test_shutdown_finishes_tags.a $(LIBDIR)/$(CONFIG)/libend2end_test_simple_delayed_request.a $(LIBDIR)/$(CONFIG)/libend2end_test_simple_request.a $(LIBDIR)/$(CONFIG)/libend2end_test_trailing_metadata.a $(LIBDIR)/$(CONFIG)/libend2end_certs.a $(LIBDIR)/$(CONFIG)/libbad_client_test.a
 pc_gpr: $(LIBDIR)/$(CONFIG)/pkgconfig/gpr.pc
 
 pc_c: $(LIBDIR)/$(CONFIG)/pkgconfig/grpc.pc
@@ -1850,9 +1871,9 @@
 
 buildtests: buildtests_c buildtests_cxx buildtests_zookeeper
 
-buildtests_c: privatelibs_c $(BINDIR)/$(CONFIG)/alpn_test $(BINDIR)/$(CONFIG)/bin_encoder_test $(BINDIR)/$(CONFIG)/chttp2_hpack_encoder_test $(BINDIR)/$(CONFIG)/chttp2_status_conversion_test $(BINDIR)/$(CONFIG)/chttp2_stream_map_test $(BINDIR)/$(CONFIG)/compression_test $(BINDIR)/$(CONFIG)/dualstack_socket_test $(BINDIR)/$(CONFIG)/endpoint_pair_test $(BINDIR)/$(CONFIG)/fd_conservation_posix_test $(BINDIR)/$(CONFIG)/fd_posix_test $(BINDIR)/$(CONFIG)/fling_client $(BINDIR)/$(CONFIG)/fling_server $(BINDIR)/$(CONFIG)/fling_stream_test $(BINDIR)/$(CONFIG)/fling_test $(BINDIR)/$(CONFIG)/gpr_cmdline_test $(BINDIR)/$(CONFIG)/gpr_cpu_test $(BINDIR)/$(CONFIG)/gpr_env_test $(BINDIR)/$(CONFIG)/gpr_file_test $(BINDIR)/$(CONFIG)/gpr_histogram_test $(BINDIR)/$(CONFIG)/gpr_host_port_test $(BINDIR)/$(CONFIG)/gpr_log_test $(BINDIR)/$(CONFIG)/gpr_slice_buffer_test $(BINDIR)/$(CONFIG)/gpr_slice_test $(BINDIR)/$(CONFIG)/gpr_stack_lockfree_test $(BINDIR)/$(CONFIG)/gpr_string_test $(BINDIR)/$(CONFIG)/gpr_sync_test $(BINDIR)/$(CONFIG)/gpr_thd_test $(BINDIR)/$(CONFIG)/gpr_time_test $(BINDIR)/$(CONFIG)/gpr_tls_test $(BINDIR)/$(CONFIG)/gpr_useful_test $(BINDIR)/$(CONFIG)/grpc_auth_context_test $(BINDIR)/$(CONFIG)/grpc_base64_test $(BINDIR)/$(CONFIG)/grpc_byte_buffer_reader_test $(BINDIR)/$(CONFIG)/grpc_channel_args_test $(BINDIR)/$(CONFIG)/grpc_channel_stack_test $(BINDIR)/$(CONFIG)/grpc_completion_queue_test $(BINDIR)/$(CONFIG)/grpc_credentials_test $(BINDIR)/$(CONFIG)/grpc_json_token_test $(BINDIR)/$(CONFIG)/grpc_jwt_verifier_test $(BINDIR)/$(CONFIG)/grpc_security_connector_test $(BINDIR)/$(CONFIG)/hpack_parser_test $(BINDIR)/$(CONFIG)/hpack_table_test $(BINDIR)/$(CONFIG)/httpcli_format_request_test $(BINDIR)/$(CONFIG)/httpcli_parser_test $(BINDIR)/$(CONFIG)/httpcli_test $(BINDIR)/$(CONFIG)/json_rewrite $(BINDIR)/$(CONFIG)/json_rewrite_test $(BINDIR)/$(CONFIG)/json_test $(BINDIR)/$(CONFIG)/lame_client_test $(BINDIR)/$(CONFIG)/lb_policies_test $(BINDIR)/$(CONFIG)/message_compress_test $(BINDIR)/$(CONFIG)/multi_init_test $(BINDIR)/$(CONFIG)/multiple_server_queues_test $(BINDIR)/$(CONFIG)/murmur_hash_test $(BINDIR)/$(CONFIG)/no_server_test $(BINDIR)/$(CONFIG)/resolve_address_test $(BINDIR)/$(CONFIG)/secure_endpoint_test $(BINDIR)/$(CONFIG)/sockaddr_utils_test $(BINDIR)/$(CONFIG)/tcp_client_posix_test $(BINDIR)/$(CONFIG)/tcp_posix_test $(BINDIR)/$(CONFIG)/tcp_server_posix_test $(BINDIR)/$(CONFIG)/time_averaged_stats_test $(BINDIR)/$(CONFIG)/timeout_encoding_test $(BINDIR)/$(CONFIG)/timer_heap_test $(BINDIR)/$(CONFIG)/timer_list_test $(BINDIR)/$(CONFIG)/timers_test $(BINDIR)/$(CONFIG)/transport_metadata_test $(BINDIR)/$(CONFIG)/transport_security_test $(BINDIR)/$(CONFIG)/udp_server_test $(BINDIR)/$(CONFIG)/uri_parser_test $(BINDIR)/$(CONFIG)/workqueue_test $(BINDIR)/$(CONFIG)/h2_compress_bad_hostname_test $(BINDIR)/$(CONFIG)/h2_compress_binary_metadata_test $(BINDIR)/$(CONFIG)/h2_compress_call_creds_test $(BINDIR)/$(CONFIG)/h2_compress_cancel_after_accept_test $(BINDIR)/$(CONFIG)/h2_compress_cancel_after_client_done_test $(BINDIR)/$(CONFIG)/h2_compress_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/h2_compress_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/h2_compress_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/h2_compress_cancel_with_status_test $(BINDIR)/$(CONFIG)/h2_compress_census_simple_request_test $(BINDIR)/$(CONFIG)/h2_compress_channel_connectivity_test $(BINDIR)/$(CONFIG)/h2_compress_compressed_payload_test $(BINDIR)/$(CONFIG)/h2_compress_default_host_test $(BINDIR)/$(CONFIG)/h2_compress_disappearing_server_test $(BINDIR)/$(CONFIG)/h2_compress_empty_batch_test $(BINDIR)/$(CONFIG)/h2_compress_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/h2_compress_high_initial_seqno_test $(BINDIR)/$(CONFIG)/h2_compress_invoke_large_request_test $(BINDIR)/$(CONFIG)/h2_compress_large_metadata_test $(BINDIR)/$(CONFIG)/h2_compress_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/h2_compress_max_message_length_test $(BINDIR)/$(CONFIG)/h2_compress_metadata_test $(BINDIR)/$(CONFIG)/h2_compress_negative_deadline_test $(BINDIR)/$(CONFIG)/h2_compress_no_op_test $(BINDIR)/$(CONFIG)/h2_compress_payload_test $(BINDIR)/$(CONFIG)/h2_compress_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/h2_compress_registered_call_test $(BINDIR)/$(CONFIG)/h2_compress_request_with_flags_test $(BINDIR)/$(CONFIG)/h2_compress_request_with_payload_test $(BINDIR)/$(CONFIG)/h2_compress_server_finishes_request_test $(BINDIR)/$(CONFIG)/h2_compress_shutdown_finishes_calls_test $(BINDIR)/$(CONFIG)/h2_compress_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/h2_compress_simple_delayed_request_test $(BINDIR)/$(CONFIG)/h2_compress_simple_request_test $(BINDIR)/$(CONFIG)/h2_compress_trailing_metadata_test $(BINDIR)/$(CONFIG)/h2_fakesec_bad_hostname_test $(BINDIR)/$(CONFIG)/h2_fakesec_binary_metadata_test $(BINDIR)/$(CONFIG)/h2_fakesec_call_creds_test $(BINDIR)/$(CONFIG)/h2_fakesec_cancel_after_accept_test $(BINDIR)/$(CONFIG)/h2_fakesec_cancel_after_client_done_test $(BINDIR)/$(CONFIG)/h2_fakesec_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/h2_fakesec_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/h2_fakesec_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/h2_fakesec_cancel_with_status_test $(BINDIR)/$(CONFIG)/h2_fakesec_census_simple_request_test $(BINDIR)/$(CONFIG)/h2_fakesec_channel_connectivity_test $(BINDIR)/$(CONFIG)/h2_fakesec_compressed_payload_test $(BINDIR)/$(CONFIG)/h2_fakesec_default_host_test $(BINDIR)/$(CONFIG)/h2_fakesec_disappearing_server_test $(BINDIR)/$(CONFIG)/h2_fakesec_empty_batch_test $(BINDIR)/$(CONFIG)/h2_fakesec_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/h2_fakesec_high_initial_seqno_test $(BINDIR)/$(CONFIG)/h2_fakesec_invoke_large_request_test $(BINDIR)/$(CONFIG)/h2_fakesec_large_metadata_test $(BINDIR)/$(CONFIG)/h2_fakesec_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/h2_fakesec_max_message_length_test $(BINDIR)/$(CONFIG)/h2_fakesec_metadata_test $(BINDIR)/$(CONFIG)/h2_fakesec_negative_deadline_test $(BINDIR)/$(CONFIG)/h2_fakesec_no_op_test $(BINDIR)/$(CONFIG)/h2_fakesec_payload_test $(BINDIR)/$(CONFIG)/h2_fakesec_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/h2_fakesec_registered_call_test $(BINDIR)/$(CONFIG)/h2_fakesec_request_with_flags_test $(BINDIR)/$(CONFIG)/h2_fakesec_request_with_payload_test $(BINDIR)/$(CONFIG)/h2_fakesec_server_finishes_request_test $(BINDIR)/$(CONFIG)/h2_fakesec_shutdown_finishes_calls_test $(BINDIR)/$(CONFIG)/h2_fakesec_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/h2_fakesec_simple_delayed_request_test $(BINDIR)/$(CONFIG)/h2_fakesec_simple_request_test $(BINDIR)/$(CONFIG)/h2_fakesec_trailing_metadata_test $(BINDIR)/$(CONFIG)/h2_full_bad_hostname_test $(BINDIR)/$(CONFIG)/h2_full_binary_metadata_test $(BINDIR)/$(CONFIG)/h2_full_call_creds_test $(BINDIR)/$(CONFIG)/h2_full_cancel_after_accept_test $(BINDIR)/$(CONFIG)/h2_full_cancel_after_client_done_test $(BINDIR)/$(CONFIG)/h2_full_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/h2_full_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/h2_full_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/h2_full_cancel_with_status_test $(BINDIR)/$(CONFIG)/h2_full_census_simple_request_test $(BINDIR)/$(CONFIG)/h2_full_channel_connectivity_test $(BINDIR)/$(CONFIG)/h2_full_compressed_payload_test $(BINDIR)/$(CONFIG)/h2_full_default_host_test $(BINDIR)/$(CONFIG)/h2_full_disappearing_server_test $(BINDIR)/$(CONFIG)/h2_full_empty_batch_test $(BINDIR)/$(CONFIG)/h2_full_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/h2_full_high_initial_seqno_test $(BINDIR)/$(CONFIG)/h2_full_invoke_large_request_test $(BINDIR)/$(CONFIG)/h2_full_large_metadata_test $(BINDIR)/$(CONFIG)/h2_full_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/h2_full_max_message_length_test $(BINDIR)/$(CONFIG)/h2_full_metadata_test $(BINDIR)/$(CONFIG)/h2_full_negative_deadline_test $(BINDIR)/$(CONFIG)/h2_full_no_op_test $(BINDIR)/$(CONFIG)/h2_full_payload_test $(BINDIR)/$(CONFIG)/h2_full_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/h2_full_registered_call_test $(BINDIR)/$(CONFIG)/h2_full_request_with_flags_test $(BINDIR)/$(CONFIG)/h2_full_request_with_payload_test $(BINDIR)/$(CONFIG)/h2_full_server_finishes_request_test $(BINDIR)/$(CONFIG)/h2_full_shutdown_finishes_calls_test $(BINDIR)/$(CONFIG)/h2_full_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/h2_full_simple_delayed_request_test $(BINDIR)/$(CONFIG)/h2_full_simple_request_test $(BINDIR)/$(CONFIG)/h2_full_trailing_metadata_test $(BINDIR)/$(CONFIG)/h2_full+poll_bad_hostname_test $(BINDIR)/$(CONFIG)/h2_full+poll_binary_metadata_test $(BINDIR)/$(CONFIG)/h2_full+poll_call_creds_test $(BINDIR)/$(CONFIG)/h2_full+poll_cancel_after_accept_test $(BINDIR)/$(CONFIG)/h2_full+poll_cancel_after_client_done_test $(BINDIR)/$(CONFIG)/h2_full+poll_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/h2_full+poll_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/h2_full+poll_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/h2_full+poll_cancel_with_status_test $(BINDIR)/$(CONFIG)/h2_full+poll_census_simple_request_test $(BINDIR)/$(CONFIG)/h2_full+poll_channel_connectivity_test $(BINDIR)/$(CONFIG)/h2_full+poll_compressed_payload_test $(BINDIR)/$(CONFIG)/h2_full+poll_default_host_test $(BINDIR)/$(CONFIG)/h2_full+poll_disappearing_server_test $(BINDIR)/$(CONFIG)/h2_full+poll_empty_batch_test $(BINDIR)/$(CONFIG)/h2_full+poll_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/h2_full+poll_high_initial_seqno_test $(BINDIR)/$(CONFIG)/h2_full+poll_invoke_large_request_test $(BINDIR)/$(CONFIG)/h2_full+poll_large_metadata_test $(BINDIR)/$(CONFIG)/h2_full+poll_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/h2_full+poll_max_message_length_test $(BINDIR)/$(CONFIG)/h2_full+poll_metadata_test $(BINDIR)/$(CONFIG)/h2_full+poll_negative_deadline_test $(BINDIR)/$(CONFIG)/h2_full+poll_no_op_test $(BINDIR)/$(CONFIG)/h2_full+poll_payload_test $(BINDIR)/$(CONFIG)/h2_full+poll_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/h2_full+poll_registered_call_test $(BINDIR)/$(CONFIG)/h2_full+poll_request_with_flags_test $(BINDIR)/$(CONFIG)/h2_full+poll_request_with_payload_test $(BINDIR)/$(CONFIG)/h2_full+poll_server_finishes_request_test $(BINDIR)/$(CONFIG)/h2_full+poll_shutdown_finishes_calls_test $(BINDIR)/$(CONFIG)/h2_full+poll_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/h2_full+poll_simple_delayed_request_test $(BINDIR)/$(CONFIG)/h2_full+poll_simple_request_test $(BINDIR)/$(CONFIG)/h2_full+poll_trailing_metadata_test $(BINDIR)/$(CONFIG)/h2_oauth2_bad_hostname_test $(BINDIR)/$(CONFIG)/h2_oauth2_binary_metadata_test $(BINDIR)/$(CONFIG)/h2_oauth2_call_creds_test $(BINDIR)/$(CONFIG)/h2_oauth2_cancel_after_accept_test $(BINDIR)/$(CONFIG)/h2_oauth2_cancel_after_client_done_test $(BINDIR)/$(CONFIG)/h2_oauth2_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/h2_oauth2_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/h2_oauth2_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/h2_oauth2_cancel_with_status_test $(BINDIR)/$(CONFIG)/h2_oauth2_census_simple_request_test $(BINDIR)/$(CONFIG)/h2_oauth2_channel_connectivity_test $(BINDIR)/$(CONFIG)/h2_oauth2_compressed_payload_test $(BINDIR)/$(CONFIG)/h2_oauth2_default_host_test $(BINDIR)/$(CONFIG)/h2_oauth2_disappearing_server_test $(BINDIR)/$(CONFIG)/h2_oauth2_empty_batch_test $(BINDIR)/$(CONFIG)/h2_oauth2_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/h2_oauth2_high_initial_seqno_test $(BINDIR)/$(CONFIG)/h2_oauth2_invoke_large_request_test $(BINDIR)/$(CONFIG)/h2_oauth2_large_metadata_test $(BINDIR)/$(CONFIG)/h2_oauth2_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/h2_oauth2_max_message_length_test $(BINDIR)/$(CONFIG)/h2_oauth2_metadata_test $(BINDIR)/$(CONFIG)/h2_oauth2_negative_deadline_test $(BINDIR)/$(CONFIG)/h2_oauth2_no_op_test $(BINDIR)/$(CONFIG)/h2_oauth2_payload_test $(BINDIR)/$(CONFIG)/h2_oauth2_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/h2_oauth2_registered_call_test $(BINDIR)/$(CONFIG)/h2_oauth2_request_with_flags_test $(BINDIR)/$(CONFIG)/h2_oauth2_request_with_payload_test $(BINDIR)/$(CONFIG)/h2_oauth2_server_finishes_request_test $(BINDIR)/$(CONFIG)/h2_oauth2_shutdown_finishes_calls_test $(BINDIR)/$(CONFIG)/h2_oauth2_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/h2_oauth2_simple_delayed_request_test $(BINDIR)/$(CONFIG)/h2_oauth2_simple_request_test $(BINDIR)/$(CONFIG)/h2_oauth2_trailing_metadata_test $(BINDIR)/$(CONFIG)/h2_proxy_bad_hostname_test $(BINDIR)/$(CONFIG)/h2_proxy_binary_metadata_test $(BINDIR)/$(CONFIG)/h2_proxy_call_creds_test $(BINDIR)/$(CONFIG)/h2_proxy_cancel_after_accept_test $(BINDIR)/$(CONFIG)/h2_proxy_cancel_after_client_done_test $(BINDIR)/$(CONFIG)/h2_proxy_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/h2_proxy_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/h2_proxy_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/h2_proxy_cancel_with_status_test $(BINDIR)/$(CONFIG)/h2_proxy_census_simple_request_test $(BINDIR)/$(CONFIG)/h2_proxy_default_host_test $(BINDIR)/$(CONFIG)/h2_proxy_disappearing_server_test $(BINDIR)/$(CONFIG)/h2_proxy_empty_batch_test $(BINDIR)/$(CONFIG)/h2_proxy_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/h2_proxy_high_initial_seqno_test $(BINDIR)/$(CONFIG)/h2_proxy_invoke_large_request_test $(BINDIR)/$(CONFIG)/h2_proxy_large_metadata_test $(BINDIR)/$(CONFIG)/h2_proxy_max_message_length_test $(BINDIR)/$(CONFIG)/h2_proxy_metadata_test $(BINDIR)/$(CONFIG)/h2_proxy_negative_deadline_test $(BINDIR)/$(CONFIG)/h2_proxy_no_op_test $(BINDIR)/$(CONFIG)/h2_proxy_payload_test $(BINDIR)/$(CONFIG)/h2_proxy_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/h2_proxy_registered_call_test $(BINDIR)/$(CONFIG)/h2_proxy_request_with_payload_test $(BINDIR)/$(CONFIG)/h2_proxy_server_finishes_request_test $(BINDIR)/$(CONFIG)/h2_proxy_shutdown_finishes_calls_test $(BINDIR)/$(CONFIG)/h2_proxy_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/h2_proxy_simple_delayed_request_test $(BINDIR)/$(CONFIG)/h2_proxy_simple_request_test $(BINDIR)/$(CONFIG)/h2_proxy_trailing_metadata_test $(BINDIR)/$(CONFIG)/h2_sockpair_bad_hostname_test $(BINDIR)/$(CONFIG)/h2_sockpair_binary_metadata_test $(BINDIR)/$(CONFIG)/h2_sockpair_call_creds_test $(BINDIR)/$(CONFIG)/h2_sockpair_cancel_after_accept_test $(BINDIR)/$(CONFIG)/h2_sockpair_cancel_after_client_done_test $(BINDIR)/$(CONFIG)/h2_sockpair_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/h2_sockpair_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/h2_sockpair_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/h2_sockpair_cancel_with_status_test $(BINDIR)/$(CONFIG)/h2_sockpair_census_simple_request_test $(BINDIR)/$(CONFIG)/h2_sockpair_compressed_payload_test $(BINDIR)/$(CONFIG)/h2_sockpair_empty_batch_test $(BINDIR)/$(CONFIG)/h2_sockpair_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/h2_sockpair_high_initial_seqno_test $(BINDIR)/$(CONFIG)/h2_sockpair_invoke_large_request_test $(BINDIR)/$(CONFIG)/h2_sockpair_large_metadata_test $(BINDIR)/$(CONFIG)/h2_sockpair_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/h2_sockpair_max_message_length_test $(BINDIR)/$(CONFIG)/h2_sockpair_metadata_test $(BINDIR)/$(CONFIG)/h2_sockpair_negative_deadline_test $(BINDIR)/$(CONFIG)/h2_sockpair_no_op_test $(BINDIR)/$(CONFIG)/h2_sockpair_payload_test $(BINDIR)/$(CONFIG)/h2_sockpair_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/h2_sockpair_registered_call_test $(BINDIR)/$(CONFIG)/h2_sockpair_request_with_flags_test $(BINDIR)/$(CONFIG)/h2_sockpair_request_with_payload_test $(BINDIR)/$(CONFIG)/h2_sockpair_server_finishes_request_test $(BINDIR)/$(CONFIG)/h2_sockpair_shutdown_finishes_calls_test $(BINDIR)/$(CONFIG)/h2_sockpair_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/h2_sockpair_simple_request_test $(BINDIR)/$(CONFIG)/h2_sockpair_trailing_metadata_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_bad_hostname_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_binary_metadata_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_call_creds_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_cancel_after_accept_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_cancel_after_client_done_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_cancel_with_status_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_census_simple_request_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_compressed_payload_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_empty_batch_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_high_initial_seqno_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_invoke_large_request_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_large_metadata_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_max_message_length_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_metadata_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_negative_deadline_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_no_op_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_payload_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_registered_call_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_request_with_flags_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_request_with_payload_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_server_finishes_request_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_shutdown_finishes_calls_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_simple_request_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_trailing_metadata_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_bad_hostname_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_binary_metadata_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_call_creds_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_cancel_after_accept_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_cancel_after_client_done_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_cancel_with_status_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_census_simple_request_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_compressed_payload_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_empty_batch_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_high_initial_seqno_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_invoke_large_request_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_large_metadata_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_max_message_length_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_metadata_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_negative_deadline_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_no_op_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_payload_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_registered_call_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_request_with_flags_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_request_with_payload_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_server_finishes_request_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_shutdown_finishes_calls_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_simple_request_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_trailing_metadata_test $(BINDIR)/$(CONFIG)/h2_ssl_bad_hostname_test $(BINDIR)/$(CONFIG)/h2_ssl_binary_metadata_test $(BINDIR)/$(CONFIG)/h2_ssl_call_creds_test $(BINDIR)/$(CONFIG)/h2_ssl_cancel_after_accept_test $(BINDIR)/$(CONFIG)/h2_ssl_cancel_after_client_done_test $(BINDIR)/$(CONFIG)/h2_ssl_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/h2_ssl_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/h2_ssl_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/h2_ssl_cancel_with_status_test $(BINDIR)/$(CONFIG)/h2_ssl_census_simple_request_test $(BINDIR)/$(CONFIG)/h2_ssl_channel_connectivity_test $(BINDIR)/$(CONFIG)/h2_ssl_compressed_payload_test $(BINDIR)/$(CONFIG)/h2_ssl_default_host_test $(BINDIR)/$(CONFIG)/h2_ssl_disappearing_server_test $(BINDIR)/$(CONFIG)/h2_ssl_empty_batch_test $(BINDIR)/$(CONFIG)/h2_ssl_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/h2_ssl_high_initial_seqno_test $(BINDIR)/$(CONFIG)/h2_ssl_invoke_large_request_test $(BINDIR)/$(CONFIG)/h2_ssl_large_metadata_test $(BINDIR)/$(CONFIG)/h2_ssl_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/h2_ssl_max_message_length_test $(BINDIR)/$(CONFIG)/h2_ssl_metadata_test $(BINDIR)/$(CONFIG)/h2_ssl_negative_deadline_test $(BINDIR)/$(CONFIG)/h2_ssl_no_op_test $(BINDIR)/$(CONFIG)/h2_ssl_payload_test $(BINDIR)/$(CONFIG)/h2_ssl_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/h2_ssl_registered_call_test $(BINDIR)/$(CONFIG)/h2_ssl_request_with_flags_test $(BINDIR)/$(CONFIG)/h2_ssl_request_with_payload_test $(BINDIR)/$(CONFIG)/h2_ssl_server_finishes_request_test $(BINDIR)/$(CONFIG)/h2_ssl_shutdown_finishes_calls_test $(BINDIR)/$(CONFIG)/h2_ssl_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/h2_ssl_simple_delayed_request_test $(BINDIR)/$(CONFIG)/h2_ssl_simple_request_test $(BINDIR)/$(CONFIG)/h2_ssl_trailing_metadata_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_bad_hostname_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_binary_metadata_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_call_creds_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_cancel_after_accept_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_cancel_after_client_done_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_cancel_with_status_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_census_simple_request_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_channel_connectivity_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_compressed_payload_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_default_host_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_disappearing_server_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_empty_batch_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_high_initial_seqno_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_invoke_large_request_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_large_metadata_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_max_message_length_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_metadata_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_negative_deadline_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_no_op_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_payload_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_registered_call_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_request_with_flags_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_request_with_payload_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_server_finishes_request_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_shutdown_finishes_calls_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_simple_delayed_request_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_simple_request_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_trailing_metadata_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_bad_hostname_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_binary_metadata_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_call_creds_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_cancel_after_accept_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_cancel_after_client_done_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_cancel_with_status_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_census_simple_request_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_default_host_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_disappearing_server_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_empty_batch_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_high_initial_seqno_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_invoke_large_request_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_large_metadata_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_max_message_length_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_metadata_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_negative_deadline_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_no_op_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_payload_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_registered_call_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_request_with_payload_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_server_finishes_request_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_shutdown_finishes_calls_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_simple_delayed_request_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_simple_request_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_trailing_metadata_test $(BINDIR)/$(CONFIG)/h2_uchannel_bad_hostname_test $(BINDIR)/$(CONFIG)/h2_uchannel_binary_metadata_test $(BINDIR)/$(CONFIG)/h2_uchannel_call_creds_test $(BINDIR)/$(CONFIG)/h2_uchannel_cancel_after_accept_test $(BINDIR)/$(CONFIG)/h2_uchannel_cancel_after_client_done_test $(BINDIR)/$(CONFIG)/h2_uchannel_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/h2_uchannel_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/h2_uchannel_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/h2_uchannel_cancel_with_status_test $(BINDIR)/$(CONFIG)/h2_uchannel_census_simple_request_test $(BINDIR)/$(CONFIG)/h2_uchannel_channel_connectivity_test $(BINDIR)/$(CONFIG)/h2_uchannel_compressed_payload_test $(BINDIR)/$(CONFIG)/h2_uchannel_default_host_test $(BINDIR)/$(CONFIG)/h2_uchannel_disappearing_server_test $(BINDIR)/$(CONFIG)/h2_uchannel_empty_batch_test $(BINDIR)/$(CONFIG)/h2_uchannel_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/h2_uchannel_high_initial_seqno_test $(BINDIR)/$(CONFIG)/h2_uchannel_invoke_large_request_test $(BINDIR)/$(CONFIG)/h2_uchannel_large_metadata_test $(BINDIR)/$(CONFIG)/h2_uchannel_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/h2_uchannel_max_message_length_test $(BINDIR)/$(CONFIG)/h2_uchannel_metadata_test $(BINDIR)/$(CONFIG)/h2_uchannel_negative_deadline_test $(BINDIR)/$(CONFIG)/h2_uchannel_no_op_test $(BINDIR)/$(CONFIG)/h2_uchannel_payload_test $(BINDIR)/$(CONFIG)/h2_uchannel_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/h2_uchannel_registered_call_test $(BINDIR)/$(CONFIG)/h2_uchannel_request_with_flags_test $(BINDIR)/$(CONFIG)/h2_uchannel_request_with_payload_test $(BINDIR)/$(CONFIG)/h2_uchannel_server_finishes_request_test $(BINDIR)/$(CONFIG)/h2_uchannel_shutdown_finishes_calls_test $(BINDIR)/$(CONFIG)/h2_uchannel_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/h2_uchannel_simple_delayed_request_test $(BINDIR)/$(CONFIG)/h2_uchannel_simple_request_test $(BINDIR)/$(CONFIG)/h2_uchannel_trailing_metadata_test $(BINDIR)/$(CONFIG)/h2_uds_bad_hostname_test $(BINDIR)/$(CONFIG)/h2_uds_binary_metadata_test $(BINDIR)/$(CONFIG)/h2_uds_call_creds_test $(BINDIR)/$(CONFIG)/h2_uds_cancel_after_accept_test $(BINDIR)/$(CONFIG)/h2_uds_cancel_after_client_done_test $(BINDIR)/$(CONFIG)/h2_uds_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/h2_uds_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/h2_uds_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/h2_uds_cancel_with_status_test $(BINDIR)/$(CONFIG)/h2_uds_census_simple_request_test $(BINDIR)/$(CONFIG)/h2_uds_channel_connectivity_test $(BINDIR)/$(CONFIG)/h2_uds_compressed_payload_test $(BINDIR)/$(CONFIG)/h2_uds_disappearing_server_test $(BINDIR)/$(CONFIG)/h2_uds_empty_batch_test $(BINDIR)/$(CONFIG)/h2_uds_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/h2_uds_high_initial_seqno_test $(BINDIR)/$(CONFIG)/h2_uds_invoke_large_request_test $(BINDIR)/$(CONFIG)/h2_uds_large_metadata_test $(BINDIR)/$(CONFIG)/h2_uds_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/h2_uds_max_message_length_test $(BINDIR)/$(CONFIG)/h2_uds_metadata_test $(BINDIR)/$(CONFIG)/h2_uds_negative_deadline_test $(BINDIR)/$(CONFIG)/h2_uds_no_op_test $(BINDIR)/$(CONFIG)/h2_uds_payload_test $(BINDIR)/$(CONFIG)/h2_uds_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/h2_uds_registered_call_test $(BINDIR)/$(CONFIG)/h2_uds_request_with_flags_test $(BINDIR)/$(CONFIG)/h2_uds_request_with_payload_test $(BINDIR)/$(CONFIG)/h2_uds_server_finishes_request_test $(BINDIR)/$(CONFIG)/h2_uds_shutdown_finishes_calls_test $(BINDIR)/$(CONFIG)/h2_uds_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/h2_uds_simple_delayed_request_test $(BINDIR)/$(CONFIG)/h2_uds_simple_request_test $(BINDIR)/$(CONFIG)/h2_uds_trailing_metadata_test $(BINDIR)/$(CONFIG)/h2_uds+poll_bad_hostname_test $(BINDIR)/$(CONFIG)/h2_uds+poll_binary_metadata_test $(BINDIR)/$(CONFIG)/h2_uds+poll_call_creds_test $(BINDIR)/$(CONFIG)/h2_uds+poll_cancel_after_accept_test $(BINDIR)/$(CONFIG)/h2_uds+poll_cancel_after_client_done_test $(BINDIR)/$(CONFIG)/h2_uds+poll_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/h2_uds+poll_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/h2_uds+poll_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/h2_uds+poll_cancel_with_status_test $(BINDIR)/$(CONFIG)/h2_uds+poll_census_simple_request_test $(BINDIR)/$(CONFIG)/h2_uds+poll_channel_connectivity_test $(BINDIR)/$(CONFIG)/h2_uds+poll_compressed_payload_test $(BINDIR)/$(CONFIG)/h2_uds+poll_disappearing_server_test $(BINDIR)/$(CONFIG)/h2_uds+poll_empty_batch_test $(BINDIR)/$(CONFIG)/h2_uds+poll_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/h2_uds+poll_high_initial_seqno_test $(BINDIR)/$(CONFIG)/h2_uds+poll_invoke_large_request_test $(BINDIR)/$(CONFIG)/h2_uds+poll_large_metadata_test $(BINDIR)/$(CONFIG)/h2_uds+poll_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/h2_uds+poll_max_message_length_test $(BINDIR)/$(CONFIG)/h2_uds+poll_metadata_test $(BINDIR)/$(CONFIG)/h2_uds+poll_negative_deadline_test $(BINDIR)/$(CONFIG)/h2_uds+poll_no_op_test $(BINDIR)/$(CONFIG)/h2_uds+poll_payload_test $(BINDIR)/$(CONFIG)/h2_uds+poll_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/h2_uds+poll_registered_call_test $(BINDIR)/$(CONFIG)/h2_uds+poll_request_with_flags_test $(BINDIR)/$(CONFIG)/h2_uds+poll_request_with_payload_test $(BINDIR)/$(CONFIG)/h2_uds+poll_server_finishes_request_test $(BINDIR)/$(CONFIG)/h2_uds+poll_shutdown_finishes_calls_test $(BINDIR)/$(CONFIG)/h2_uds+poll_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/h2_uds+poll_simple_delayed_request_test $(BINDIR)/$(CONFIG)/h2_uds+poll_simple_request_test $(BINDIR)/$(CONFIG)/h2_uds+poll_trailing_metadata_test $(BINDIR)/$(CONFIG)/h2_compress_bad_hostname_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_binary_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_cancel_after_accept_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_cancel_after_client_done_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_cancel_after_invoke_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_cancel_before_invoke_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_cancel_in_a_vacuum_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_cancel_with_status_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_census_simple_request_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_channel_connectivity_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_compressed_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_default_host_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_disappearing_server_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_empty_batch_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_graceful_server_shutdown_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_high_initial_seqno_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_invoke_large_request_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_large_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_max_concurrent_streams_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_max_message_length_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_negative_deadline_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_no_op_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_ping_pong_streaming_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_registered_call_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_request_with_flags_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_request_with_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_server_finishes_request_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_shutdown_finishes_calls_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_shutdown_finishes_tags_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_simple_delayed_request_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_simple_request_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_trailing_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_full_bad_hostname_nosec_test $(BINDIR)/$(CONFIG)/h2_full_binary_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_full_cancel_after_accept_nosec_test $(BINDIR)/$(CONFIG)/h2_full_cancel_after_client_done_nosec_test $(BINDIR)/$(CONFIG)/h2_full_cancel_after_invoke_nosec_test $(BINDIR)/$(CONFIG)/h2_full_cancel_before_invoke_nosec_test $(BINDIR)/$(CONFIG)/h2_full_cancel_in_a_vacuum_nosec_test $(BINDIR)/$(CONFIG)/h2_full_cancel_with_status_nosec_test $(BINDIR)/$(CONFIG)/h2_full_census_simple_request_nosec_test $(BINDIR)/$(CONFIG)/h2_full_channel_connectivity_nosec_test $(BINDIR)/$(CONFIG)/h2_full_compressed_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_full_default_host_nosec_test $(BINDIR)/$(CONFIG)/h2_full_disappearing_server_nosec_test $(BINDIR)/$(CONFIG)/h2_full_empty_batch_nosec_test $(BINDIR)/$(CONFIG)/h2_full_graceful_server_shutdown_nosec_test $(BINDIR)/$(CONFIG)/h2_full_high_initial_seqno_nosec_test $(BINDIR)/$(CONFIG)/h2_full_invoke_large_request_nosec_test $(BINDIR)/$(CONFIG)/h2_full_large_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_full_max_concurrent_streams_nosec_test $(BINDIR)/$(CONFIG)/h2_full_max_message_length_nosec_test $(BINDIR)/$(CONFIG)/h2_full_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_full_negative_deadline_nosec_test $(BINDIR)/$(CONFIG)/h2_full_no_op_nosec_test $(BINDIR)/$(CONFIG)/h2_full_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_full_ping_pong_streaming_nosec_test $(BINDIR)/$(CONFIG)/h2_full_registered_call_nosec_test $(BINDIR)/$(CONFIG)/h2_full_request_with_flags_nosec_test $(BINDIR)/$(CONFIG)/h2_full_request_with_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_full_server_finishes_request_nosec_test $(BINDIR)/$(CONFIG)/h2_full_shutdown_finishes_calls_nosec_test $(BINDIR)/$(CONFIG)/h2_full_shutdown_finishes_tags_nosec_test $(BINDIR)/$(CONFIG)/h2_full_simple_delayed_request_nosec_test $(BINDIR)/$(CONFIG)/h2_full_simple_request_nosec_test $(BINDIR)/$(CONFIG)/h2_full_trailing_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_bad_hostname_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_binary_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_cancel_after_accept_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_cancel_after_client_done_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_cancel_after_invoke_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_cancel_before_invoke_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_cancel_in_a_vacuum_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_cancel_with_status_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_census_simple_request_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_channel_connectivity_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_compressed_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_default_host_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_disappearing_server_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_empty_batch_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_graceful_server_shutdown_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_high_initial_seqno_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_invoke_large_request_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_large_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_max_concurrent_streams_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_max_message_length_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_negative_deadline_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_no_op_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_ping_pong_streaming_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_registered_call_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_request_with_flags_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_request_with_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_server_finishes_request_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_shutdown_finishes_calls_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_shutdown_finishes_tags_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_simple_delayed_request_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_simple_request_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_trailing_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_bad_hostname_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_binary_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_cancel_after_accept_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_cancel_after_client_done_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_cancel_after_invoke_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_cancel_before_invoke_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_cancel_in_a_vacuum_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_cancel_with_status_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_census_simple_request_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_default_host_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_disappearing_server_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_empty_batch_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_graceful_server_shutdown_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_high_initial_seqno_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_invoke_large_request_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_large_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_max_message_length_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_negative_deadline_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_no_op_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_ping_pong_streaming_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_registered_call_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_request_with_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_server_finishes_request_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_shutdown_finishes_calls_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_shutdown_finishes_tags_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_simple_delayed_request_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_simple_request_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_trailing_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_bad_hostname_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_binary_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_cancel_after_accept_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_cancel_after_client_done_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_cancel_after_invoke_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_cancel_before_invoke_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_cancel_in_a_vacuum_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_cancel_with_status_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_census_simple_request_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_compressed_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_empty_batch_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_graceful_server_shutdown_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_high_initial_seqno_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_invoke_large_request_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_large_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_max_concurrent_streams_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_max_message_length_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_negative_deadline_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_no_op_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_ping_pong_streaming_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_registered_call_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_request_with_flags_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_request_with_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_server_finishes_request_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_shutdown_finishes_calls_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_shutdown_finishes_tags_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_simple_request_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_trailing_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_bad_hostname_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_binary_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_cancel_after_accept_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_cancel_after_client_done_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_cancel_after_invoke_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_cancel_before_invoke_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_cancel_in_a_vacuum_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_cancel_with_status_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_census_simple_request_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_compressed_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_empty_batch_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_graceful_server_shutdown_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_high_initial_seqno_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_invoke_large_request_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_large_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_max_concurrent_streams_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_max_message_length_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_negative_deadline_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_no_op_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_ping_pong_streaming_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_registered_call_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_request_with_flags_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_request_with_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_server_finishes_request_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_shutdown_finishes_calls_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_shutdown_finishes_tags_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_simple_request_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_trailing_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_bad_hostname_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_binary_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_cancel_after_accept_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_cancel_after_client_done_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_cancel_after_invoke_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_cancel_before_invoke_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_cancel_in_a_vacuum_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_cancel_with_status_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_census_simple_request_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_compressed_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_empty_batch_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_graceful_server_shutdown_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_high_initial_seqno_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_invoke_large_request_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_large_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_max_concurrent_streams_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_max_message_length_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_negative_deadline_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_no_op_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_ping_pong_streaming_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_registered_call_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_request_with_flags_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_request_with_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_server_finishes_request_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_shutdown_finishes_calls_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_shutdown_finishes_tags_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_simple_request_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_trailing_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_bad_hostname_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_binary_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_cancel_after_accept_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_cancel_after_client_done_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_cancel_after_invoke_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_cancel_before_invoke_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_cancel_in_a_vacuum_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_cancel_with_status_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_census_simple_request_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_channel_connectivity_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_compressed_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_default_host_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_disappearing_server_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_empty_batch_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_graceful_server_shutdown_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_high_initial_seqno_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_invoke_large_request_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_large_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_max_concurrent_streams_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_max_message_length_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_negative_deadline_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_no_op_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_ping_pong_streaming_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_registered_call_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_request_with_flags_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_request_with_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_server_finishes_request_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_shutdown_finishes_calls_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_shutdown_finishes_tags_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_simple_delayed_request_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_simple_request_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_trailing_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_bad_hostname_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_binary_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_cancel_after_accept_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_cancel_after_client_done_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_cancel_after_invoke_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_cancel_before_invoke_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_cancel_in_a_vacuum_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_cancel_with_status_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_census_simple_request_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_channel_connectivity_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_compressed_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_disappearing_server_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_empty_batch_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_graceful_server_shutdown_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_high_initial_seqno_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_invoke_large_request_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_large_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_max_concurrent_streams_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_max_message_length_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_negative_deadline_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_no_op_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_ping_pong_streaming_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_registered_call_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_request_with_flags_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_request_with_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_server_finishes_request_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_shutdown_finishes_calls_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_shutdown_finishes_tags_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_simple_delayed_request_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_simple_request_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_trailing_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_bad_hostname_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_binary_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_cancel_after_accept_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_cancel_after_client_done_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_cancel_after_invoke_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_cancel_before_invoke_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_cancel_in_a_vacuum_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_cancel_with_status_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_census_simple_request_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_channel_connectivity_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_compressed_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_disappearing_server_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_empty_batch_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_graceful_server_shutdown_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_high_initial_seqno_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_invoke_large_request_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_large_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_max_concurrent_streams_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_max_message_length_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_negative_deadline_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_no_op_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_ping_pong_streaming_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_registered_call_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_request_with_flags_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_request_with_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_server_finishes_request_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_shutdown_finishes_calls_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_shutdown_finishes_tags_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_simple_delayed_request_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_simple_request_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_trailing_metadata_nosec_test $(BINDIR)/$(CONFIG)/connection_prefix_bad_client_test $(BINDIR)/$(CONFIG)/initial_settings_frame_bad_client_test
+buildtests_c: privatelibs_c $(BINDIR)/$(CONFIG)/alpn_test $(BINDIR)/$(CONFIG)/bin_encoder_test $(BINDIR)/$(CONFIG)/chttp2_hpack_encoder_test $(BINDIR)/$(CONFIG)/chttp2_status_conversion_test $(BINDIR)/$(CONFIG)/chttp2_stream_map_test $(BINDIR)/$(CONFIG)/compression_test $(BINDIR)/$(CONFIG)/dualstack_socket_test $(BINDIR)/$(CONFIG)/endpoint_pair_test $(BINDIR)/$(CONFIG)/fd_conservation_posix_test $(BINDIR)/$(CONFIG)/fd_posix_test $(BINDIR)/$(CONFIG)/fling_client $(BINDIR)/$(CONFIG)/fling_server $(BINDIR)/$(CONFIG)/fling_stream_test $(BINDIR)/$(CONFIG)/fling_test $(BINDIR)/$(CONFIG)/gpr_cmdline_test $(BINDIR)/$(CONFIG)/gpr_cpu_test $(BINDIR)/$(CONFIG)/gpr_env_test $(BINDIR)/$(CONFIG)/gpr_file_test $(BINDIR)/$(CONFIG)/gpr_histogram_test $(BINDIR)/$(CONFIG)/gpr_host_port_test $(BINDIR)/$(CONFIG)/gpr_log_test $(BINDIR)/$(CONFIG)/gpr_slice_buffer_test $(BINDIR)/$(CONFIG)/gpr_slice_test $(BINDIR)/$(CONFIG)/gpr_stack_lockfree_test $(BINDIR)/$(CONFIG)/gpr_string_test $(BINDIR)/$(CONFIG)/gpr_sync_test $(BINDIR)/$(CONFIG)/gpr_thd_test $(BINDIR)/$(CONFIG)/gpr_time_test $(BINDIR)/$(CONFIG)/gpr_tls_test $(BINDIR)/$(CONFIG)/gpr_useful_test $(BINDIR)/$(CONFIG)/grpc_auth_context_test $(BINDIR)/$(CONFIG)/grpc_base64_test $(BINDIR)/$(CONFIG)/grpc_byte_buffer_reader_test $(BINDIR)/$(CONFIG)/grpc_channel_args_test $(BINDIR)/$(CONFIG)/grpc_channel_stack_test $(BINDIR)/$(CONFIG)/grpc_completion_queue_test $(BINDIR)/$(CONFIG)/grpc_credentials_test $(BINDIR)/$(CONFIG)/grpc_json_token_test $(BINDIR)/$(CONFIG)/grpc_jwt_verifier_test $(BINDIR)/$(CONFIG)/grpc_security_connector_test $(BINDIR)/$(CONFIG)/hpack_parser_test $(BINDIR)/$(CONFIG)/hpack_table_test $(BINDIR)/$(CONFIG)/httpcli_format_request_test $(BINDIR)/$(CONFIG)/httpcli_parser_test $(BINDIR)/$(CONFIG)/httpcli_test $(BINDIR)/$(CONFIG)/json_rewrite $(BINDIR)/$(CONFIG)/json_rewrite_test $(BINDIR)/$(CONFIG)/json_test $(BINDIR)/$(CONFIG)/lame_client_test $(BINDIR)/$(CONFIG)/lb_policies_test $(BINDIR)/$(CONFIG)/message_compress_test $(BINDIR)/$(CONFIG)/multi_init_test $(BINDIR)/$(CONFIG)/multiple_server_queues_test $(BINDIR)/$(CONFIG)/murmur_hash_test $(BINDIR)/$(CONFIG)/no_server_test $(BINDIR)/$(CONFIG)/resolve_address_test $(BINDIR)/$(CONFIG)/secure_endpoint_test $(BINDIR)/$(CONFIG)/sockaddr_utils_test $(BINDIR)/$(CONFIG)/tcp_client_posix_test $(BINDIR)/$(CONFIG)/tcp_posix_test $(BINDIR)/$(CONFIG)/tcp_server_posix_test $(BINDIR)/$(CONFIG)/time_averaged_stats_test $(BINDIR)/$(CONFIG)/timeout_encoding_test $(BINDIR)/$(CONFIG)/timer_heap_test $(BINDIR)/$(CONFIG)/timer_list_test $(BINDIR)/$(CONFIG)/timers_test $(BINDIR)/$(CONFIG)/transport_metadata_test $(BINDIR)/$(CONFIG)/transport_security_test $(BINDIR)/$(CONFIG)/udp_server_test $(BINDIR)/$(CONFIG)/uri_parser_test $(BINDIR)/$(CONFIG)/workqueue_test $(BINDIR)/$(CONFIG)/h2_compress_bad_hostname_test $(BINDIR)/$(CONFIG)/h2_compress_binary_metadata_test $(BINDIR)/$(CONFIG)/h2_compress_call_creds_test $(BINDIR)/$(CONFIG)/h2_compress_cancel_after_accept_test $(BINDIR)/$(CONFIG)/h2_compress_cancel_after_client_done_test $(BINDIR)/$(CONFIG)/h2_compress_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/h2_compress_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/h2_compress_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/h2_compress_cancel_with_status_test $(BINDIR)/$(CONFIG)/h2_compress_census_simple_request_test $(BINDIR)/$(CONFIG)/h2_compress_channel_connectivity_test $(BINDIR)/$(CONFIG)/h2_compress_compressed_payload_test $(BINDIR)/$(CONFIG)/h2_compress_default_host_test $(BINDIR)/$(CONFIG)/h2_compress_disappearing_server_test $(BINDIR)/$(CONFIG)/h2_compress_empty_batch_test $(BINDIR)/$(CONFIG)/h2_compress_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/h2_compress_high_initial_seqno_test $(BINDIR)/$(CONFIG)/h2_compress_hpack_size_test $(BINDIR)/$(CONFIG)/h2_compress_invoke_large_request_test $(BINDIR)/$(CONFIG)/h2_compress_large_metadata_test $(BINDIR)/$(CONFIG)/h2_compress_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/h2_compress_max_message_length_test $(BINDIR)/$(CONFIG)/h2_compress_metadata_test $(BINDIR)/$(CONFIG)/h2_compress_negative_deadline_test $(BINDIR)/$(CONFIG)/h2_compress_no_op_test $(BINDIR)/$(CONFIG)/h2_compress_payload_test $(BINDIR)/$(CONFIG)/h2_compress_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/h2_compress_registered_call_test $(BINDIR)/$(CONFIG)/h2_compress_request_with_flags_test $(BINDIR)/$(CONFIG)/h2_compress_request_with_payload_test $(BINDIR)/$(CONFIG)/h2_compress_server_finishes_request_test $(BINDIR)/$(CONFIG)/h2_compress_shutdown_finishes_calls_test $(BINDIR)/$(CONFIG)/h2_compress_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/h2_compress_simple_delayed_request_test $(BINDIR)/$(CONFIG)/h2_compress_simple_request_test $(BINDIR)/$(CONFIG)/h2_compress_trailing_metadata_test $(BINDIR)/$(CONFIG)/h2_fakesec_bad_hostname_test $(BINDIR)/$(CONFIG)/h2_fakesec_binary_metadata_test $(BINDIR)/$(CONFIG)/h2_fakesec_call_creds_test $(BINDIR)/$(CONFIG)/h2_fakesec_cancel_after_accept_test $(BINDIR)/$(CONFIG)/h2_fakesec_cancel_after_client_done_test $(BINDIR)/$(CONFIG)/h2_fakesec_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/h2_fakesec_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/h2_fakesec_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/h2_fakesec_cancel_with_status_test $(BINDIR)/$(CONFIG)/h2_fakesec_census_simple_request_test $(BINDIR)/$(CONFIG)/h2_fakesec_channel_connectivity_test $(BINDIR)/$(CONFIG)/h2_fakesec_compressed_payload_test $(BINDIR)/$(CONFIG)/h2_fakesec_default_host_test $(BINDIR)/$(CONFIG)/h2_fakesec_disappearing_server_test $(BINDIR)/$(CONFIG)/h2_fakesec_empty_batch_test $(BINDIR)/$(CONFIG)/h2_fakesec_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/h2_fakesec_high_initial_seqno_test $(BINDIR)/$(CONFIG)/h2_fakesec_hpack_size_test $(BINDIR)/$(CONFIG)/h2_fakesec_invoke_large_request_test $(BINDIR)/$(CONFIG)/h2_fakesec_large_metadata_test $(BINDIR)/$(CONFIG)/h2_fakesec_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/h2_fakesec_max_message_length_test $(BINDIR)/$(CONFIG)/h2_fakesec_metadata_test $(BINDIR)/$(CONFIG)/h2_fakesec_negative_deadline_test $(BINDIR)/$(CONFIG)/h2_fakesec_no_op_test $(BINDIR)/$(CONFIG)/h2_fakesec_payload_test $(BINDIR)/$(CONFIG)/h2_fakesec_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/h2_fakesec_registered_call_test $(BINDIR)/$(CONFIG)/h2_fakesec_request_with_flags_test $(BINDIR)/$(CONFIG)/h2_fakesec_request_with_payload_test $(BINDIR)/$(CONFIG)/h2_fakesec_server_finishes_request_test $(BINDIR)/$(CONFIG)/h2_fakesec_shutdown_finishes_calls_test $(BINDIR)/$(CONFIG)/h2_fakesec_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/h2_fakesec_simple_delayed_request_test $(BINDIR)/$(CONFIG)/h2_fakesec_simple_request_test $(BINDIR)/$(CONFIG)/h2_fakesec_trailing_metadata_test $(BINDIR)/$(CONFIG)/h2_full_bad_hostname_test $(BINDIR)/$(CONFIG)/h2_full_binary_metadata_test $(BINDIR)/$(CONFIG)/h2_full_call_creds_test $(BINDIR)/$(CONFIG)/h2_full_cancel_after_accept_test $(BINDIR)/$(CONFIG)/h2_full_cancel_after_client_done_test $(BINDIR)/$(CONFIG)/h2_full_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/h2_full_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/h2_full_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/h2_full_cancel_with_status_test $(BINDIR)/$(CONFIG)/h2_full_census_simple_request_test $(BINDIR)/$(CONFIG)/h2_full_channel_connectivity_test $(BINDIR)/$(CONFIG)/h2_full_compressed_payload_test $(BINDIR)/$(CONFIG)/h2_full_default_host_test $(BINDIR)/$(CONFIG)/h2_full_disappearing_server_test $(BINDIR)/$(CONFIG)/h2_full_empty_batch_test $(BINDIR)/$(CONFIG)/h2_full_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/h2_full_high_initial_seqno_test $(BINDIR)/$(CONFIG)/h2_full_hpack_size_test $(BINDIR)/$(CONFIG)/h2_full_invoke_large_request_test $(BINDIR)/$(CONFIG)/h2_full_large_metadata_test $(BINDIR)/$(CONFIG)/h2_full_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/h2_full_max_message_length_test $(BINDIR)/$(CONFIG)/h2_full_metadata_test $(BINDIR)/$(CONFIG)/h2_full_negative_deadline_test $(BINDIR)/$(CONFIG)/h2_full_no_op_test $(BINDIR)/$(CONFIG)/h2_full_payload_test $(BINDIR)/$(CONFIG)/h2_full_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/h2_full_registered_call_test $(BINDIR)/$(CONFIG)/h2_full_request_with_flags_test $(BINDIR)/$(CONFIG)/h2_full_request_with_payload_test $(BINDIR)/$(CONFIG)/h2_full_server_finishes_request_test $(BINDIR)/$(CONFIG)/h2_full_shutdown_finishes_calls_test $(BINDIR)/$(CONFIG)/h2_full_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/h2_full_simple_delayed_request_test $(BINDIR)/$(CONFIG)/h2_full_simple_request_test $(BINDIR)/$(CONFIG)/h2_full_trailing_metadata_test $(BINDIR)/$(CONFIG)/h2_full+poll_bad_hostname_test $(BINDIR)/$(CONFIG)/h2_full+poll_binary_metadata_test $(BINDIR)/$(CONFIG)/h2_full+poll_call_creds_test $(BINDIR)/$(CONFIG)/h2_full+poll_cancel_after_accept_test $(BINDIR)/$(CONFIG)/h2_full+poll_cancel_after_client_done_test $(BINDIR)/$(CONFIG)/h2_full+poll_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/h2_full+poll_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/h2_full+poll_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/h2_full+poll_cancel_with_status_test $(BINDIR)/$(CONFIG)/h2_full+poll_census_simple_request_test $(BINDIR)/$(CONFIG)/h2_full+poll_channel_connectivity_test $(BINDIR)/$(CONFIG)/h2_full+poll_compressed_payload_test $(BINDIR)/$(CONFIG)/h2_full+poll_default_host_test $(BINDIR)/$(CONFIG)/h2_full+poll_disappearing_server_test $(BINDIR)/$(CONFIG)/h2_full+poll_empty_batch_test $(BINDIR)/$(CONFIG)/h2_full+poll_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/h2_full+poll_high_initial_seqno_test $(BINDIR)/$(CONFIG)/h2_full+poll_hpack_size_test $(BINDIR)/$(CONFIG)/h2_full+poll_invoke_large_request_test $(BINDIR)/$(CONFIG)/h2_full+poll_large_metadata_test $(BINDIR)/$(CONFIG)/h2_full+poll_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/h2_full+poll_max_message_length_test $(BINDIR)/$(CONFIG)/h2_full+poll_metadata_test $(BINDIR)/$(CONFIG)/h2_full+poll_negative_deadline_test $(BINDIR)/$(CONFIG)/h2_full+poll_no_op_test $(BINDIR)/$(CONFIG)/h2_full+poll_payload_test $(BINDIR)/$(CONFIG)/h2_full+poll_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/h2_full+poll_registered_call_test $(BINDIR)/$(CONFIG)/h2_full+poll_request_with_flags_test $(BINDIR)/$(CONFIG)/h2_full+poll_request_with_payload_test $(BINDIR)/$(CONFIG)/h2_full+poll_server_finishes_request_test $(BINDIR)/$(CONFIG)/h2_full+poll_shutdown_finishes_calls_test $(BINDIR)/$(CONFIG)/h2_full+poll_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/h2_full+poll_simple_delayed_request_test $(BINDIR)/$(CONFIG)/h2_full+poll_simple_request_test $(BINDIR)/$(CONFIG)/h2_full+poll_trailing_metadata_test $(BINDIR)/$(CONFIG)/h2_oauth2_bad_hostname_test $(BINDIR)/$(CONFIG)/h2_oauth2_binary_metadata_test $(BINDIR)/$(CONFIG)/h2_oauth2_call_creds_test $(BINDIR)/$(CONFIG)/h2_oauth2_cancel_after_accept_test $(BINDIR)/$(CONFIG)/h2_oauth2_cancel_after_client_done_test $(BINDIR)/$(CONFIG)/h2_oauth2_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/h2_oauth2_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/h2_oauth2_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/h2_oauth2_cancel_with_status_test $(BINDIR)/$(CONFIG)/h2_oauth2_census_simple_request_test $(BINDIR)/$(CONFIG)/h2_oauth2_channel_connectivity_test $(BINDIR)/$(CONFIG)/h2_oauth2_compressed_payload_test $(BINDIR)/$(CONFIG)/h2_oauth2_default_host_test $(BINDIR)/$(CONFIG)/h2_oauth2_disappearing_server_test $(BINDIR)/$(CONFIG)/h2_oauth2_empty_batch_test $(BINDIR)/$(CONFIG)/h2_oauth2_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/h2_oauth2_high_initial_seqno_test $(BINDIR)/$(CONFIG)/h2_oauth2_hpack_size_test $(BINDIR)/$(CONFIG)/h2_oauth2_invoke_large_request_test $(BINDIR)/$(CONFIG)/h2_oauth2_large_metadata_test $(BINDIR)/$(CONFIG)/h2_oauth2_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/h2_oauth2_max_message_length_test $(BINDIR)/$(CONFIG)/h2_oauth2_metadata_test $(BINDIR)/$(CONFIG)/h2_oauth2_negative_deadline_test $(BINDIR)/$(CONFIG)/h2_oauth2_no_op_test $(BINDIR)/$(CONFIG)/h2_oauth2_payload_test $(BINDIR)/$(CONFIG)/h2_oauth2_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/h2_oauth2_registered_call_test $(BINDIR)/$(CONFIG)/h2_oauth2_request_with_flags_test $(BINDIR)/$(CONFIG)/h2_oauth2_request_with_payload_test $(BINDIR)/$(CONFIG)/h2_oauth2_server_finishes_request_test $(BINDIR)/$(CONFIG)/h2_oauth2_shutdown_finishes_calls_test $(BINDIR)/$(CONFIG)/h2_oauth2_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/h2_oauth2_simple_delayed_request_test $(BINDIR)/$(CONFIG)/h2_oauth2_simple_request_test $(BINDIR)/$(CONFIG)/h2_oauth2_trailing_metadata_test $(BINDIR)/$(CONFIG)/h2_proxy_bad_hostname_test $(BINDIR)/$(CONFIG)/h2_proxy_binary_metadata_test $(BINDIR)/$(CONFIG)/h2_proxy_call_creds_test $(BINDIR)/$(CONFIG)/h2_proxy_cancel_after_accept_test $(BINDIR)/$(CONFIG)/h2_proxy_cancel_after_client_done_test $(BINDIR)/$(CONFIG)/h2_proxy_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/h2_proxy_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/h2_proxy_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/h2_proxy_cancel_with_status_test $(BINDIR)/$(CONFIG)/h2_proxy_census_simple_request_test $(BINDIR)/$(CONFIG)/h2_proxy_default_host_test $(BINDIR)/$(CONFIG)/h2_proxy_disappearing_server_test $(BINDIR)/$(CONFIG)/h2_proxy_empty_batch_test $(BINDIR)/$(CONFIG)/h2_proxy_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/h2_proxy_high_initial_seqno_test $(BINDIR)/$(CONFIG)/h2_proxy_invoke_large_request_test $(BINDIR)/$(CONFIG)/h2_proxy_large_metadata_test $(BINDIR)/$(CONFIG)/h2_proxy_max_message_length_test $(BINDIR)/$(CONFIG)/h2_proxy_metadata_test $(BINDIR)/$(CONFIG)/h2_proxy_negative_deadline_test $(BINDIR)/$(CONFIG)/h2_proxy_no_op_test $(BINDIR)/$(CONFIG)/h2_proxy_payload_test $(BINDIR)/$(CONFIG)/h2_proxy_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/h2_proxy_registered_call_test $(BINDIR)/$(CONFIG)/h2_proxy_request_with_payload_test $(BINDIR)/$(CONFIG)/h2_proxy_server_finishes_request_test $(BINDIR)/$(CONFIG)/h2_proxy_shutdown_finishes_calls_test $(BINDIR)/$(CONFIG)/h2_proxy_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/h2_proxy_simple_delayed_request_test $(BINDIR)/$(CONFIG)/h2_proxy_simple_request_test $(BINDIR)/$(CONFIG)/h2_proxy_trailing_metadata_test $(BINDIR)/$(CONFIG)/h2_sockpair_bad_hostname_test $(BINDIR)/$(CONFIG)/h2_sockpair_binary_metadata_test $(BINDIR)/$(CONFIG)/h2_sockpair_call_creds_test $(BINDIR)/$(CONFIG)/h2_sockpair_cancel_after_accept_test $(BINDIR)/$(CONFIG)/h2_sockpair_cancel_after_client_done_test $(BINDIR)/$(CONFIG)/h2_sockpair_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/h2_sockpair_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/h2_sockpair_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/h2_sockpair_cancel_with_status_test $(BINDIR)/$(CONFIG)/h2_sockpair_census_simple_request_test $(BINDIR)/$(CONFIG)/h2_sockpair_compressed_payload_test $(BINDIR)/$(CONFIG)/h2_sockpair_empty_batch_test $(BINDIR)/$(CONFIG)/h2_sockpair_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/h2_sockpair_high_initial_seqno_test $(BINDIR)/$(CONFIG)/h2_sockpair_hpack_size_test $(BINDIR)/$(CONFIG)/h2_sockpair_invoke_large_request_test $(BINDIR)/$(CONFIG)/h2_sockpair_large_metadata_test $(BINDIR)/$(CONFIG)/h2_sockpair_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/h2_sockpair_max_message_length_test $(BINDIR)/$(CONFIG)/h2_sockpair_metadata_test $(BINDIR)/$(CONFIG)/h2_sockpair_negative_deadline_test $(BINDIR)/$(CONFIG)/h2_sockpair_no_op_test $(BINDIR)/$(CONFIG)/h2_sockpair_payload_test $(BINDIR)/$(CONFIG)/h2_sockpair_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/h2_sockpair_registered_call_test $(BINDIR)/$(CONFIG)/h2_sockpair_request_with_flags_test $(BINDIR)/$(CONFIG)/h2_sockpair_request_with_payload_test $(BINDIR)/$(CONFIG)/h2_sockpair_server_finishes_request_test $(BINDIR)/$(CONFIG)/h2_sockpair_shutdown_finishes_calls_test $(BINDIR)/$(CONFIG)/h2_sockpair_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/h2_sockpair_simple_request_test $(BINDIR)/$(CONFIG)/h2_sockpair_trailing_metadata_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_bad_hostname_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_binary_metadata_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_call_creds_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_cancel_after_accept_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_cancel_after_client_done_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_cancel_with_status_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_census_simple_request_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_compressed_payload_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_empty_batch_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_high_initial_seqno_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_invoke_large_request_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_large_metadata_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_max_message_length_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_metadata_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_negative_deadline_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_no_op_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_payload_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_registered_call_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_request_with_flags_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_request_with_payload_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_server_finishes_request_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_shutdown_finishes_calls_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_simple_request_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_trailing_metadata_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_bad_hostname_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_binary_metadata_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_call_creds_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_cancel_after_accept_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_cancel_after_client_done_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_cancel_with_status_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_census_simple_request_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_compressed_payload_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_empty_batch_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_high_initial_seqno_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_hpack_size_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_invoke_large_request_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_large_metadata_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_max_message_length_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_metadata_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_negative_deadline_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_no_op_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_payload_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_registered_call_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_request_with_flags_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_request_with_payload_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_server_finishes_request_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_shutdown_finishes_calls_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_simple_request_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_trailing_metadata_test $(BINDIR)/$(CONFIG)/h2_ssl_bad_hostname_test $(BINDIR)/$(CONFIG)/h2_ssl_binary_metadata_test $(BINDIR)/$(CONFIG)/h2_ssl_call_creds_test $(BINDIR)/$(CONFIG)/h2_ssl_cancel_after_accept_test $(BINDIR)/$(CONFIG)/h2_ssl_cancel_after_client_done_test $(BINDIR)/$(CONFIG)/h2_ssl_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/h2_ssl_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/h2_ssl_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/h2_ssl_cancel_with_status_test $(BINDIR)/$(CONFIG)/h2_ssl_census_simple_request_test $(BINDIR)/$(CONFIG)/h2_ssl_channel_connectivity_test $(BINDIR)/$(CONFIG)/h2_ssl_compressed_payload_test $(BINDIR)/$(CONFIG)/h2_ssl_default_host_test $(BINDIR)/$(CONFIG)/h2_ssl_disappearing_server_test $(BINDIR)/$(CONFIG)/h2_ssl_empty_batch_test $(BINDIR)/$(CONFIG)/h2_ssl_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/h2_ssl_high_initial_seqno_test $(BINDIR)/$(CONFIG)/h2_ssl_hpack_size_test $(BINDIR)/$(CONFIG)/h2_ssl_invoke_large_request_test $(BINDIR)/$(CONFIG)/h2_ssl_large_metadata_test $(BINDIR)/$(CONFIG)/h2_ssl_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/h2_ssl_max_message_length_test $(BINDIR)/$(CONFIG)/h2_ssl_metadata_test $(BINDIR)/$(CONFIG)/h2_ssl_negative_deadline_test $(BINDIR)/$(CONFIG)/h2_ssl_no_op_test $(BINDIR)/$(CONFIG)/h2_ssl_payload_test $(BINDIR)/$(CONFIG)/h2_ssl_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/h2_ssl_registered_call_test $(BINDIR)/$(CONFIG)/h2_ssl_request_with_flags_test $(BINDIR)/$(CONFIG)/h2_ssl_request_with_payload_test $(BINDIR)/$(CONFIG)/h2_ssl_server_finishes_request_test $(BINDIR)/$(CONFIG)/h2_ssl_shutdown_finishes_calls_test $(BINDIR)/$(CONFIG)/h2_ssl_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/h2_ssl_simple_delayed_request_test $(BINDIR)/$(CONFIG)/h2_ssl_simple_request_test $(BINDIR)/$(CONFIG)/h2_ssl_trailing_metadata_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_bad_hostname_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_binary_metadata_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_call_creds_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_cancel_after_accept_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_cancel_after_client_done_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_cancel_with_status_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_census_simple_request_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_channel_connectivity_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_compressed_payload_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_default_host_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_disappearing_server_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_empty_batch_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_high_initial_seqno_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_hpack_size_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_invoke_large_request_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_large_metadata_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_max_message_length_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_metadata_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_negative_deadline_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_no_op_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_payload_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_registered_call_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_request_with_flags_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_request_with_payload_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_server_finishes_request_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_shutdown_finishes_calls_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_simple_delayed_request_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_simple_request_test $(BINDIR)/$(CONFIG)/h2_ssl+poll_trailing_metadata_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_bad_hostname_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_binary_metadata_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_call_creds_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_cancel_after_accept_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_cancel_after_client_done_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_cancel_with_status_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_census_simple_request_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_default_host_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_disappearing_server_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_empty_batch_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_high_initial_seqno_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_invoke_large_request_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_large_metadata_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_max_message_length_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_metadata_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_negative_deadline_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_no_op_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_payload_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_registered_call_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_request_with_payload_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_server_finishes_request_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_shutdown_finishes_calls_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_simple_delayed_request_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_simple_request_test $(BINDIR)/$(CONFIG)/h2_ssl_proxy_trailing_metadata_test $(BINDIR)/$(CONFIG)/h2_uchannel_bad_hostname_test $(BINDIR)/$(CONFIG)/h2_uchannel_binary_metadata_test $(BINDIR)/$(CONFIG)/h2_uchannel_call_creds_test $(BINDIR)/$(CONFIG)/h2_uchannel_cancel_after_accept_test $(BINDIR)/$(CONFIG)/h2_uchannel_cancel_after_client_done_test $(BINDIR)/$(CONFIG)/h2_uchannel_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/h2_uchannel_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/h2_uchannel_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/h2_uchannel_cancel_with_status_test $(BINDIR)/$(CONFIG)/h2_uchannel_census_simple_request_test $(BINDIR)/$(CONFIG)/h2_uchannel_channel_connectivity_test $(BINDIR)/$(CONFIG)/h2_uchannel_compressed_payload_test $(BINDIR)/$(CONFIG)/h2_uchannel_default_host_test $(BINDIR)/$(CONFIG)/h2_uchannel_disappearing_server_test $(BINDIR)/$(CONFIG)/h2_uchannel_empty_batch_test $(BINDIR)/$(CONFIG)/h2_uchannel_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/h2_uchannel_high_initial_seqno_test $(BINDIR)/$(CONFIG)/h2_uchannel_hpack_size_test $(BINDIR)/$(CONFIG)/h2_uchannel_invoke_large_request_test $(BINDIR)/$(CONFIG)/h2_uchannel_large_metadata_test $(BINDIR)/$(CONFIG)/h2_uchannel_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/h2_uchannel_max_message_length_test $(BINDIR)/$(CONFIG)/h2_uchannel_metadata_test $(BINDIR)/$(CONFIG)/h2_uchannel_negative_deadline_test $(BINDIR)/$(CONFIG)/h2_uchannel_no_op_test $(BINDIR)/$(CONFIG)/h2_uchannel_payload_test $(BINDIR)/$(CONFIG)/h2_uchannel_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/h2_uchannel_registered_call_test $(BINDIR)/$(CONFIG)/h2_uchannel_request_with_flags_test $(BINDIR)/$(CONFIG)/h2_uchannel_request_with_payload_test $(BINDIR)/$(CONFIG)/h2_uchannel_server_finishes_request_test $(BINDIR)/$(CONFIG)/h2_uchannel_shutdown_finishes_calls_test $(BINDIR)/$(CONFIG)/h2_uchannel_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/h2_uchannel_simple_delayed_request_test $(BINDIR)/$(CONFIG)/h2_uchannel_simple_request_test $(BINDIR)/$(CONFIG)/h2_uchannel_trailing_metadata_test $(BINDIR)/$(CONFIG)/h2_uds_bad_hostname_test $(BINDIR)/$(CONFIG)/h2_uds_binary_metadata_test $(BINDIR)/$(CONFIG)/h2_uds_call_creds_test $(BINDIR)/$(CONFIG)/h2_uds_cancel_after_accept_test $(BINDIR)/$(CONFIG)/h2_uds_cancel_after_client_done_test $(BINDIR)/$(CONFIG)/h2_uds_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/h2_uds_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/h2_uds_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/h2_uds_cancel_with_status_test $(BINDIR)/$(CONFIG)/h2_uds_census_simple_request_test $(BINDIR)/$(CONFIG)/h2_uds_channel_connectivity_test $(BINDIR)/$(CONFIG)/h2_uds_compressed_payload_test $(BINDIR)/$(CONFIG)/h2_uds_disappearing_server_test $(BINDIR)/$(CONFIG)/h2_uds_empty_batch_test $(BINDIR)/$(CONFIG)/h2_uds_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/h2_uds_high_initial_seqno_test $(BINDIR)/$(CONFIG)/h2_uds_hpack_size_test $(BINDIR)/$(CONFIG)/h2_uds_invoke_large_request_test $(BINDIR)/$(CONFIG)/h2_uds_large_metadata_test $(BINDIR)/$(CONFIG)/h2_uds_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/h2_uds_max_message_length_test $(BINDIR)/$(CONFIG)/h2_uds_metadata_test $(BINDIR)/$(CONFIG)/h2_uds_negative_deadline_test $(BINDIR)/$(CONFIG)/h2_uds_no_op_test $(BINDIR)/$(CONFIG)/h2_uds_payload_test $(BINDIR)/$(CONFIG)/h2_uds_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/h2_uds_registered_call_test $(BINDIR)/$(CONFIG)/h2_uds_request_with_flags_test $(BINDIR)/$(CONFIG)/h2_uds_request_with_payload_test $(BINDIR)/$(CONFIG)/h2_uds_server_finishes_request_test $(BINDIR)/$(CONFIG)/h2_uds_shutdown_finishes_calls_test $(BINDIR)/$(CONFIG)/h2_uds_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/h2_uds_simple_delayed_request_test $(BINDIR)/$(CONFIG)/h2_uds_simple_request_test $(BINDIR)/$(CONFIG)/h2_uds_trailing_metadata_test $(BINDIR)/$(CONFIG)/h2_uds+poll_bad_hostname_test $(BINDIR)/$(CONFIG)/h2_uds+poll_binary_metadata_test $(BINDIR)/$(CONFIG)/h2_uds+poll_call_creds_test $(BINDIR)/$(CONFIG)/h2_uds+poll_cancel_after_accept_test $(BINDIR)/$(CONFIG)/h2_uds+poll_cancel_after_client_done_test $(BINDIR)/$(CONFIG)/h2_uds+poll_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/h2_uds+poll_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/h2_uds+poll_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/h2_uds+poll_cancel_with_status_test $(BINDIR)/$(CONFIG)/h2_uds+poll_census_simple_request_test $(BINDIR)/$(CONFIG)/h2_uds+poll_channel_connectivity_test $(BINDIR)/$(CONFIG)/h2_uds+poll_compressed_payload_test $(BINDIR)/$(CONFIG)/h2_uds+poll_disappearing_server_test $(BINDIR)/$(CONFIG)/h2_uds+poll_empty_batch_test $(BINDIR)/$(CONFIG)/h2_uds+poll_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/h2_uds+poll_high_initial_seqno_test $(BINDIR)/$(CONFIG)/h2_uds+poll_hpack_size_test $(BINDIR)/$(CONFIG)/h2_uds+poll_invoke_large_request_test $(BINDIR)/$(CONFIG)/h2_uds+poll_large_metadata_test $(BINDIR)/$(CONFIG)/h2_uds+poll_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/h2_uds+poll_max_message_length_test $(BINDIR)/$(CONFIG)/h2_uds+poll_metadata_test $(BINDIR)/$(CONFIG)/h2_uds+poll_negative_deadline_test $(BINDIR)/$(CONFIG)/h2_uds+poll_no_op_test $(BINDIR)/$(CONFIG)/h2_uds+poll_payload_test $(BINDIR)/$(CONFIG)/h2_uds+poll_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/h2_uds+poll_registered_call_test $(BINDIR)/$(CONFIG)/h2_uds+poll_request_with_flags_test $(BINDIR)/$(CONFIG)/h2_uds+poll_request_with_payload_test $(BINDIR)/$(CONFIG)/h2_uds+poll_server_finishes_request_test $(BINDIR)/$(CONFIG)/h2_uds+poll_shutdown_finishes_calls_test $(BINDIR)/$(CONFIG)/h2_uds+poll_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/h2_uds+poll_simple_delayed_request_test $(BINDIR)/$(CONFIG)/h2_uds+poll_simple_request_test $(BINDIR)/$(CONFIG)/h2_uds+poll_trailing_metadata_test $(BINDIR)/$(CONFIG)/h2_compress_bad_hostname_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_binary_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_cancel_after_accept_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_cancel_after_client_done_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_cancel_after_invoke_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_cancel_before_invoke_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_cancel_in_a_vacuum_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_cancel_with_status_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_census_simple_request_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_channel_connectivity_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_compressed_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_default_host_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_disappearing_server_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_empty_batch_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_graceful_server_shutdown_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_high_initial_seqno_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_hpack_size_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_invoke_large_request_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_large_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_max_concurrent_streams_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_max_message_length_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_negative_deadline_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_no_op_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_ping_pong_streaming_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_registered_call_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_request_with_flags_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_request_with_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_server_finishes_request_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_shutdown_finishes_calls_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_shutdown_finishes_tags_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_simple_delayed_request_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_simple_request_nosec_test $(BINDIR)/$(CONFIG)/h2_compress_trailing_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_full_bad_hostname_nosec_test $(BINDIR)/$(CONFIG)/h2_full_binary_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_full_cancel_after_accept_nosec_test $(BINDIR)/$(CONFIG)/h2_full_cancel_after_client_done_nosec_test $(BINDIR)/$(CONFIG)/h2_full_cancel_after_invoke_nosec_test $(BINDIR)/$(CONFIG)/h2_full_cancel_before_invoke_nosec_test $(BINDIR)/$(CONFIG)/h2_full_cancel_in_a_vacuum_nosec_test $(BINDIR)/$(CONFIG)/h2_full_cancel_with_status_nosec_test $(BINDIR)/$(CONFIG)/h2_full_census_simple_request_nosec_test $(BINDIR)/$(CONFIG)/h2_full_channel_connectivity_nosec_test $(BINDIR)/$(CONFIG)/h2_full_compressed_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_full_default_host_nosec_test $(BINDIR)/$(CONFIG)/h2_full_disappearing_server_nosec_test $(BINDIR)/$(CONFIG)/h2_full_empty_batch_nosec_test $(BINDIR)/$(CONFIG)/h2_full_graceful_server_shutdown_nosec_test $(BINDIR)/$(CONFIG)/h2_full_high_initial_seqno_nosec_test $(BINDIR)/$(CONFIG)/h2_full_hpack_size_nosec_test $(BINDIR)/$(CONFIG)/h2_full_invoke_large_request_nosec_test $(BINDIR)/$(CONFIG)/h2_full_large_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_full_max_concurrent_streams_nosec_test $(BINDIR)/$(CONFIG)/h2_full_max_message_length_nosec_test $(BINDIR)/$(CONFIG)/h2_full_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_full_negative_deadline_nosec_test $(BINDIR)/$(CONFIG)/h2_full_no_op_nosec_test $(BINDIR)/$(CONFIG)/h2_full_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_full_ping_pong_streaming_nosec_test $(BINDIR)/$(CONFIG)/h2_full_registered_call_nosec_test $(BINDIR)/$(CONFIG)/h2_full_request_with_flags_nosec_test $(BINDIR)/$(CONFIG)/h2_full_request_with_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_full_server_finishes_request_nosec_test $(BINDIR)/$(CONFIG)/h2_full_shutdown_finishes_calls_nosec_test $(BINDIR)/$(CONFIG)/h2_full_shutdown_finishes_tags_nosec_test $(BINDIR)/$(CONFIG)/h2_full_simple_delayed_request_nosec_test $(BINDIR)/$(CONFIG)/h2_full_simple_request_nosec_test $(BINDIR)/$(CONFIG)/h2_full_trailing_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_bad_hostname_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_binary_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_cancel_after_accept_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_cancel_after_client_done_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_cancel_after_invoke_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_cancel_before_invoke_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_cancel_in_a_vacuum_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_cancel_with_status_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_census_simple_request_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_channel_connectivity_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_compressed_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_default_host_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_disappearing_server_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_empty_batch_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_graceful_server_shutdown_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_high_initial_seqno_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_hpack_size_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_invoke_large_request_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_large_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_max_concurrent_streams_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_max_message_length_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_negative_deadline_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_no_op_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_ping_pong_streaming_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_registered_call_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_request_with_flags_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_request_with_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_server_finishes_request_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_shutdown_finishes_calls_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_shutdown_finishes_tags_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_simple_delayed_request_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_simple_request_nosec_test $(BINDIR)/$(CONFIG)/h2_full+poll_trailing_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_bad_hostname_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_binary_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_cancel_after_accept_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_cancel_after_client_done_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_cancel_after_invoke_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_cancel_before_invoke_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_cancel_in_a_vacuum_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_cancel_with_status_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_census_simple_request_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_default_host_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_disappearing_server_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_empty_batch_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_graceful_server_shutdown_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_high_initial_seqno_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_invoke_large_request_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_large_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_max_message_length_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_negative_deadline_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_no_op_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_ping_pong_streaming_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_registered_call_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_request_with_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_server_finishes_request_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_shutdown_finishes_calls_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_shutdown_finishes_tags_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_simple_delayed_request_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_simple_request_nosec_test $(BINDIR)/$(CONFIG)/h2_proxy_trailing_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_bad_hostname_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_binary_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_cancel_after_accept_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_cancel_after_client_done_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_cancel_after_invoke_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_cancel_before_invoke_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_cancel_in_a_vacuum_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_cancel_with_status_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_census_simple_request_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_compressed_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_empty_batch_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_graceful_server_shutdown_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_high_initial_seqno_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_hpack_size_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_invoke_large_request_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_large_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_max_concurrent_streams_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_max_message_length_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_negative_deadline_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_no_op_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_ping_pong_streaming_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_registered_call_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_request_with_flags_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_request_with_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_server_finishes_request_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_shutdown_finishes_calls_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_shutdown_finishes_tags_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_simple_request_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_trailing_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_bad_hostname_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_binary_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_cancel_after_accept_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_cancel_after_client_done_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_cancel_after_invoke_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_cancel_before_invoke_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_cancel_in_a_vacuum_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_cancel_with_status_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_census_simple_request_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_compressed_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_empty_batch_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_graceful_server_shutdown_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_high_initial_seqno_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_invoke_large_request_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_large_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_max_concurrent_streams_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_max_message_length_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_negative_deadline_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_no_op_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_ping_pong_streaming_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_registered_call_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_request_with_flags_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_request_with_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_server_finishes_request_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_shutdown_finishes_calls_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_shutdown_finishes_tags_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_simple_request_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair+trace_trailing_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_bad_hostname_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_binary_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_cancel_after_accept_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_cancel_after_client_done_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_cancel_after_invoke_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_cancel_before_invoke_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_cancel_in_a_vacuum_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_cancel_with_status_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_census_simple_request_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_compressed_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_empty_batch_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_graceful_server_shutdown_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_high_initial_seqno_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_hpack_size_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_invoke_large_request_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_large_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_max_concurrent_streams_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_max_message_length_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_negative_deadline_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_no_op_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_ping_pong_streaming_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_registered_call_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_request_with_flags_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_request_with_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_server_finishes_request_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_shutdown_finishes_calls_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_shutdown_finishes_tags_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_simple_request_nosec_test $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_trailing_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_bad_hostname_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_binary_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_cancel_after_accept_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_cancel_after_client_done_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_cancel_after_invoke_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_cancel_before_invoke_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_cancel_in_a_vacuum_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_cancel_with_status_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_census_simple_request_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_channel_connectivity_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_compressed_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_default_host_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_disappearing_server_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_empty_batch_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_graceful_server_shutdown_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_high_initial_seqno_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_hpack_size_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_invoke_large_request_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_large_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_max_concurrent_streams_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_max_message_length_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_negative_deadline_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_no_op_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_ping_pong_streaming_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_registered_call_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_request_with_flags_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_request_with_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_server_finishes_request_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_shutdown_finishes_calls_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_shutdown_finishes_tags_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_simple_delayed_request_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_simple_request_nosec_test $(BINDIR)/$(CONFIG)/h2_uchannel_trailing_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_bad_hostname_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_binary_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_cancel_after_accept_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_cancel_after_client_done_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_cancel_after_invoke_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_cancel_before_invoke_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_cancel_in_a_vacuum_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_cancel_with_status_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_census_simple_request_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_channel_connectivity_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_compressed_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_disappearing_server_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_empty_batch_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_graceful_server_shutdown_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_high_initial_seqno_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_hpack_size_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_invoke_large_request_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_large_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_max_concurrent_streams_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_max_message_length_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_negative_deadline_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_no_op_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_ping_pong_streaming_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_registered_call_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_request_with_flags_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_request_with_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_server_finishes_request_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_shutdown_finishes_calls_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_shutdown_finishes_tags_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_simple_delayed_request_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_simple_request_nosec_test $(BINDIR)/$(CONFIG)/h2_uds_trailing_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_bad_hostname_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_binary_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_cancel_after_accept_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_cancel_after_client_done_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_cancel_after_invoke_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_cancel_before_invoke_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_cancel_in_a_vacuum_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_cancel_with_status_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_census_simple_request_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_channel_connectivity_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_compressed_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_disappearing_server_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_empty_batch_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_graceful_server_shutdown_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_high_initial_seqno_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_hpack_size_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_invoke_large_request_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_large_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_max_concurrent_streams_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_max_message_length_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_metadata_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_negative_deadline_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_no_op_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_ping_pong_streaming_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_registered_call_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_request_with_flags_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_request_with_payload_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_server_finishes_request_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_shutdown_finishes_calls_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_shutdown_finishes_tags_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_simple_delayed_request_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_simple_request_nosec_test $(BINDIR)/$(CONFIG)/h2_uds+poll_trailing_metadata_nosec_test $(BINDIR)/$(CONFIG)/connection_prefix_bad_client_test $(BINDIR)/$(CONFIG)/initial_settings_frame_bad_client_test
 
-buildtests_cxx: buildtests_zookeeper privatelibs_cxx $(BINDIR)/$(CONFIG)/async_end2end_test $(BINDIR)/$(CONFIG)/async_streaming_ping_pong_test $(BINDIR)/$(CONFIG)/async_unary_ping_pong_test $(BINDIR)/$(CONFIG)/auth_property_iterator_test $(BINDIR)/$(CONFIG)/channel_arguments_test $(BINDIR)/$(CONFIG)/cli_call_test $(BINDIR)/$(CONFIG)/client_crash_test $(BINDIR)/$(CONFIG)/client_crash_test_server $(BINDIR)/$(CONFIG)/credentials_test $(BINDIR)/$(CONFIG)/cxx_byte_buffer_test $(BINDIR)/$(CONFIG)/cxx_slice_test $(BINDIR)/$(CONFIG)/cxx_string_ref_test $(BINDIR)/$(CONFIG)/cxx_time_test $(BINDIR)/$(CONFIG)/end2end_test $(BINDIR)/$(CONFIG)/generic_end2end_test $(BINDIR)/$(CONFIG)/grpc_cli $(BINDIR)/$(CONFIG)/interop_client $(BINDIR)/$(CONFIG)/interop_server $(BINDIR)/$(CONFIG)/interop_test $(BINDIR)/$(CONFIG)/mock_test $(BINDIR)/$(CONFIG)/qps_interarrival_test $(BINDIR)/$(CONFIG)/qps_openloop_test $(BINDIR)/$(CONFIG)/qps_test $(BINDIR)/$(CONFIG)/reconnect_interop_client $(BINDIR)/$(CONFIG)/reconnect_interop_server $(BINDIR)/$(CONFIG)/secure_auth_context_test $(BINDIR)/$(CONFIG)/secure_sync_unary_ping_pong_test $(BINDIR)/$(CONFIG)/server_crash_test $(BINDIR)/$(CONFIG)/server_crash_test_client $(BINDIR)/$(CONFIG)/shutdown_test $(BINDIR)/$(CONFIG)/status_test $(BINDIR)/$(CONFIG)/streaming_throughput_test $(BINDIR)/$(CONFIG)/stress_test $(BINDIR)/$(CONFIG)/sync_streaming_ping_pong_test $(BINDIR)/$(CONFIG)/sync_unary_ping_pong_test $(BINDIR)/$(CONFIG)/thread_stress_test
+buildtests_cxx: buildtests_zookeeper privatelibs_cxx $(BINDIR)/$(CONFIG)/async_end2end_test $(BINDIR)/$(CONFIG)/async_streaming_ping_pong_test $(BINDIR)/$(CONFIG)/async_unary_ping_pong_test $(BINDIR)/$(CONFIG)/auth_property_iterator_test $(BINDIR)/$(CONFIG)/channel_arguments_test $(BINDIR)/$(CONFIG)/cli_call_test $(BINDIR)/$(CONFIG)/client_crash_test $(BINDIR)/$(CONFIG)/client_crash_test_server $(BINDIR)/$(CONFIG)/credentials_test $(BINDIR)/$(CONFIG)/cxx_byte_buffer_test $(BINDIR)/$(CONFIG)/cxx_slice_test $(BINDIR)/$(CONFIG)/cxx_string_ref_test $(BINDIR)/$(CONFIG)/cxx_time_test $(BINDIR)/$(CONFIG)/end2end_test $(BINDIR)/$(CONFIG)/generic_end2end_test $(BINDIR)/$(CONFIG)/grpc_cli $(BINDIR)/$(CONFIG)/interop_client $(BINDIR)/$(CONFIG)/interop_server $(BINDIR)/$(CONFIG)/interop_test $(BINDIR)/$(CONFIG)/metrics_client $(BINDIR)/$(CONFIG)/mock_test $(BINDIR)/$(CONFIG)/qps_interarrival_test $(BINDIR)/$(CONFIG)/qps_openloop_test $(BINDIR)/$(CONFIG)/qps_test $(BINDIR)/$(CONFIG)/reconnect_interop_client $(BINDIR)/$(CONFIG)/reconnect_interop_server $(BINDIR)/$(CONFIG)/secure_auth_context_test $(BINDIR)/$(CONFIG)/secure_sync_unary_ping_pong_test $(BINDIR)/$(CONFIG)/server_crash_test $(BINDIR)/$(CONFIG)/server_crash_test_client $(BINDIR)/$(CONFIG)/shutdown_test $(BINDIR)/$(CONFIG)/status_test $(BINDIR)/$(CONFIG)/streaming_throughput_test $(BINDIR)/$(CONFIG)/stress_test $(BINDIR)/$(CONFIG)/sync_streaming_ping_pong_test $(BINDIR)/$(CONFIG)/sync_unary_ping_pong_test $(BINDIR)/$(CONFIG)/thread_stress_test
 
 ifeq ($(HAS_ZOOKEEPER),true)
 buildtests_zookeeper: privatelibs_zookeeper $(BINDIR)/$(CONFIG)/zookeeper_test
@@ -2036,6 +2057,8 @@
 	$(Q) $(BINDIR)/$(CONFIG)/h2_compress_graceful_server_shutdown_test || ( echo test h2_compress_graceful_server_shutdown_test failed ; exit 1 )
 	$(E) "[RUN]     Testing h2_compress_high_initial_seqno_test"
 	$(Q) $(BINDIR)/$(CONFIG)/h2_compress_high_initial_seqno_test || ( echo test h2_compress_high_initial_seqno_test failed ; exit 1 )
+	$(E) "[RUN]     Testing h2_compress_hpack_size_test"
+	$(Q) $(BINDIR)/$(CONFIG)/h2_compress_hpack_size_test || ( echo test h2_compress_hpack_size_test failed ; exit 1 )
 	$(E) "[RUN]     Testing h2_compress_invoke_large_request_test"
 	$(Q) $(BINDIR)/$(CONFIG)/h2_compress_invoke_large_request_test || ( echo test h2_compress_invoke_large_request_test failed ; exit 1 )
 	$(E) "[RUN]     Testing h2_compress_large_metadata_test"
@@ -2106,6 +2129,8 @@
 	$(Q) $(BINDIR)/$(CONFIG)/h2_fakesec_graceful_server_shutdown_test || ( echo test h2_fakesec_graceful_server_shutdown_test failed ; exit 1 )
 	$(E) "[RUN]     Testing h2_fakesec_high_initial_seqno_test"
 	$(Q) $(BINDIR)/$(CONFIG)/h2_fakesec_high_initial_seqno_test || ( echo test h2_fakesec_high_initial_seqno_test failed ; exit 1 )
+	$(E) "[RUN]     Testing h2_fakesec_hpack_size_test"
+	$(Q) $(BINDIR)/$(CONFIG)/h2_fakesec_hpack_size_test || ( echo test h2_fakesec_hpack_size_test failed ; exit 1 )
 	$(E) "[RUN]     Testing h2_fakesec_invoke_large_request_test"
 	$(Q) $(BINDIR)/$(CONFIG)/h2_fakesec_invoke_large_request_test || ( echo test h2_fakesec_invoke_large_request_test failed ; exit 1 )
 	$(E) "[RUN]     Testing h2_fakesec_large_metadata_test"
@@ -2176,6 +2201,8 @@
 	$(Q) $(BINDIR)/$(CONFIG)/h2_full_graceful_server_shutdown_test || ( echo test h2_full_graceful_server_shutdown_test failed ; exit 1 )
 	$(E) "[RUN]     Testing h2_full_high_initial_seqno_test"
 	$(Q) $(BINDIR)/$(CONFIG)/h2_full_high_initial_seqno_test || ( echo test h2_full_high_initial_seqno_test failed ; exit 1 )
+	$(E) "[RUN]     Testing h2_full_hpack_size_test"
+	$(Q) $(BINDIR)/$(CONFIG)/h2_full_hpack_size_test || ( echo test h2_full_hpack_size_test failed ; exit 1 )
 	$(E) "[RUN]     Testing h2_full_invoke_large_request_test"
 	$(Q) $(BINDIR)/$(CONFIG)/h2_full_invoke_large_request_test || ( echo test h2_full_invoke_large_request_test failed ; exit 1 )
 	$(E) "[RUN]     Testing h2_full_large_metadata_test"
@@ -2246,6 +2273,8 @@
 	$(Q) $(BINDIR)/$(CONFIG)/h2_full+poll_graceful_server_shutdown_test || ( echo test h2_full+poll_graceful_server_shutdown_test failed ; exit 1 )
 	$(E) "[RUN]     Testing h2_full+poll_high_initial_seqno_test"
 	$(Q) $(BINDIR)/$(CONFIG)/h2_full+poll_high_initial_seqno_test || ( echo test h2_full+poll_high_initial_seqno_test failed ; exit 1 )
+	$(E) "[RUN]     Testing h2_full+poll_hpack_size_test"
+	$(Q) $(BINDIR)/$(CONFIG)/h2_full+poll_hpack_size_test || ( echo test h2_full+poll_hpack_size_test failed ; exit 1 )
 	$(E) "[RUN]     Testing h2_full+poll_invoke_large_request_test"
 	$(Q) $(BINDIR)/$(CONFIG)/h2_full+poll_invoke_large_request_test || ( echo test h2_full+poll_invoke_large_request_test failed ; exit 1 )
 	$(E) "[RUN]     Testing h2_full+poll_large_metadata_test"
@@ -2316,6 +2345,8 @@
 	$(Q) $(BINDIR)/$(CONFIG)/h2_oauth2_graceful_server_shutdown_test || ( echo test h2_oauth2_graceful_server_shutdown_test failed ; exit 1 )
 	$(E) "[RUN]     Testing h2_oauth2_high_initial_seqno_test"
 	$(Q) $(BINDIR)/$(CONFIG)/h2_oauth2_high_initial_seqno_test || ( echo test h2_oauth2_high_initial_seqno_test failed ; exit 1 )
+	$(E) "[RUN]     Testing h2_oauth2_hpack_size_test"
+	$(Q) $(BINDIR)/$(CONFIG)/h2_oauth2_hpack_size_test || ( echo test h2_oauth2_hpack_size_test failed ; exit 1 )
 	$(E) "[RUN]     Testing h2_oauth2_invoke_large_request_test"
 	$(Q) $(BINDIR)/$(CONFIG)/h2_oauth2_invoke_large_request_test || ( echo test h2_oauth2_invoke_large_request_test failed ; exit 1 )
 	$(E) "[RUN]     Testing h2_oauth2_large_metadata_test"
@@ -2442,6 +2473,8 @@
 	$(Q) $(BINDIR)/$(CONFIG)/h2_sockpair_graceful_server_shutdown_test || ( echo test h2_sockpair_graceful_server_shutdown_test failed ; exit 1 )
 	$(E) "[RUN]     Testing h2_sockpair_high_initial_seqno_test"
 	$(Q) $(BINDIR)/$(CONFIG)/h2_sockpair_high_initial_seqno_test || ( echo test h2_sockpair_high_initial_seqno_test failed ; exit 1 )
+	$(E) "[RUN]     Testing h2_sockpair_hpack_size_test"
+	$(Q) $(BINDIR)/$(CONFIG)/h2_sockpair_hpack_size_test || ( echo test h2_sockpair_hpack_size_test failed ; exit 1 )
 	$(E) "[RUN]     Testing h2_sockpair_invoke_large_request_test"
 	$(Q) $(BINDIR)/$(CONFIG)/h2_sockpair_invoke_large_request_test || ( echo test h2_sockpair_invoke_large_request_test failed ; exit 1 )
 	$(E) "[RUN]     Testing h2_sockpair_large_metadata_test"
@@ -2566,6 +2599,8 @@
 	$(Q) $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_graceful_server_shutdown_test || ( echo test h2_sockpair_1byte_graceful_server_shutdown_test failed ; exit 1 )
 	$(E) "[RUN]     Testing h2_sockpair_1byte_high_initial_seqno_test"
 	$(Q) $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_high_initial_seqno_test || ( echo test h2_sockpair_1byte_high_initial_seqno_test failed ; exit 1 )
+	$(E) "[RUN]     Testing h2_sockpair_1byte_hpack_size_test"
+	$(Q) $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_hpack_size_test || ( echo test h2_sockpair_1byte_hpack_size_test failed ; exit 1 )
 	$(E) "[RUN]     Testing h2_sockpair_1byte_invoke_large_request_test"
 	$(Q) $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_invoke_large_request_test || ( echo test h2_sockpair_1byte_invoke_large_request_test failed ; exit 1 )
 	$(E) "[RUN]     Testing h2_sockpair_1byte_large_metadata_test"
@@ -2634,6 +2669,8 @@
 	$(Q) $(BINDIR)/$(CONFIG)/h2_ssl_graceful_server_shutdown_test || ( echo test h2_ssl_graceful_server_shutdown_test failed ; exit 1 )
 	$(E) "[RUN]     Testing h2_ssl_high_initial_seqno_test"
 	$(Q) $(BINDIR)/$(CONFIG)/h2_ssl_high_initial_seqno_test || ( echo test h2_ssl_high_initial_seqno_test failed ; exit 1 )
+	$(E) "[RUN]     Testing h2_ssl_hpack_size_test"
+	$(Q) $(BINDIR)/$(CONFIG)/h2_ssl_hpack_size_test || ( echo test h2_ssl_hpack_size_test failed ; exit 1 )
 	$(E) "[RUN]     Testing h2_ssl_invoke_large_request_test"
 	$(Q) $(BINDIR)/$(CONFIG)/h2_ssl_invoke_large_request_test || ( echo test h2_ssl_invoke_large_request_test failed ; exit 1 )
 	$(E) "[RUN]     Testing h2_ssl_large_metadata_test"
@@ -2704,6 +2741,8 @@
 	$(Q) $(BINDIR)/$(CONFIG)/h2_ssl+poll_graceful_server_shutdown_test || ( echo test h2_ssl+poll_graceful_server_shutdown_test failed ; exit 1 )
 	$(E) "[RUN]     Testing h2_ssl+poll_high_initial_seqno_test"
 	$(Q) $(BINDIR)/$(CONFIG)/h2_ssl+poll_high_initial_seqno_test || ( echo test h2_ssl+poll_high_initial_seqno_test failed ; exit 1 )
+	$(E) "[RUN]     Testing h2_ssl+poll_hpack_size_test"
+	$(Q) $(BINDIR)/$(CONFIG)/h2_ssl+poll_hpack_size_test || ( echo test h2_ssl+poll_hpack_size_test failed ; exit 1 )
 	$(E) "[RUN]     Testing h2_ssl+poll_invoke_large_request_test"
 	$(Q) $(BINDIR)/$(CONFIG)/h2_ssl+poll_invoke_large_request_test || ( echo test h2_ssl+poll_invoke_large_request_test failed ; exit 1 )
 	$(E) "[RUN]     Testing h2_ssl+poll_large_metadata_test"
@@ -2836,6 +2875,8 @@
 	$(Q) $(BINDIR)/$(CONFIG)/h2_uchannel_graceful_server_shutdown_test || ( echo test h2_uchannel_graceful_server_shutdown_test failed ; exit 1 )
 	$(E) "[RUN]     Testing h2_uchannel_high_initial_seqno_test"
 	$(Q) $(BINDIR)/$(CONFIG)/h2_uchannel_high_initial_seqno_test || ( echo test h2_uchannel_high_initial_seqno_test failed ; exit 1 )
+	$(E) "[RUN]     Testing h2_uchannel_hpack_size_test"
+	$(Q) $(BINDIR)/$(CONFIG)/h2_uchannel_hpack_size_test || ( echo test h2_uchannel_hpack_size_test failed ; exit 1 )
 	$(E) "[RUN]     Testing h2_uchannel_invoke_large_request_test"
 	$(Q) $(BINDIR)/$(CONFIG)/h2_uchannel_invoke_large_request_test || ( echo test h2_uchannel_invoke_large_request_test failed ; exit 1 )
 	$(E) "[RUN]     Testing h2_uchannel_large_metadata_test"
@@ -2904,6 +2945,8 @@
 	$(Q) $(BINDIR)/$(CONFIG)/h2_uds_graceful_server_shutdown_test || ( echo test h2_uds_graceful_server_shutdown_test failed ; exit 1 )
 	$(E) "[RUN]     Testing h2_uds_high_initial_seqno_test"
 	$(Q) $(BINDIR)/$(CONFIG)/h2_uds_high_initial_seqno_test || ( echo test h2_uds_high_initial_seqno_test failed ; exit 1 )
+	$(E) "[RUN]     Testing h2_uds_hpack_size_test"
+	$(Q) $(BINDIR)/$(CONFIG)/h2_uds_hpack_size_test || ( echo test h2_uds_hpack_size_test failed ; exit 1 )
 	$(E) "[RUN]     Testing h2_uds_invoke_large_request_test"
 	$(Q) $(BINDIR)/$(CONFIG)/h2_uds_invoke_large_request_test || ( echo test h2_uds_invoke_large_request_test failed ; exit 1 )
 	$(E) "[RUN]     Testing h2_uds_large_metadata_test"
@@ -2972,6 +3015,8 @@
 	$(Q) $(BINDIR)/$(CONFIG)/h2_uds+poll_graceful_server_shutdown_test || ( echo test h2_uds+poll_graceful_server_shutdown_test failed ; exit 1 )
 	$(E) "[RUN]     Testing h2_uds+poll_high_initial_seqno_test"
 	$(Q) $(BINDIR)/$(CONFIG)/h2_uds+poll_high_initial_seqno_test || ( echo test h2_uds+poll_high_initial_seqno_test failed ; exit 1 )
+	$(E) "[RUN]     Testing h2_uds+poll_hpack_size_test"
+	$(Q) $(BINDIR)/$(CONFIG)/h2_uds+poll_hpack_size_test || ( echo test h2_uds+poll_hpack_size_test failed ; exit 1 )
 	$(E) "[RUN]     Testing h2_uds+poll_invoke_large_request_test"
 	$(Q) $(BINDIR)/$(CONFIG)/h2_uds+poll_invoke_large_request_test || ( echo test h2_uds+poll_invoke_large_request_test failed ; exit 1 )
 	$(E) "[RUN]     Testing h2_uds+poll_large_metadata_test"
@@ -3040,6 +3085,8 @@
 	$(Q) $(BINDIR)/$(CONFIG)/h2_compress_graceful_server_shutdown_nosec_test || ( echo test h2_compress_graceful_server_shutdown_nosec_test failed ; exit 1 )
 	$(E) "[RUN]     Testing h2_compress_high_initial_seqno_nosec_test"
 	$(Q) $(BINDIR)/$(CONFIG)/h2_compress_high_initial_seqno_nosec_test || ( echo test h2_compress_high_initial_seqno_nosec_test failed ; exit 1 )
+	$(E) "[RUN]     Testing h2_compress_hpack_size_nosec_test"
+	$(Q) $(BINDIR)/$(CONFIG)/h2_compress_hpack_size_nosec_test || ( echo test h2_compress_hpack_size_nosec_test failed ; exit 1 )
 	$(E) "[RUN]     Testing h2_compress_invoke_large_request_nosec_test"
 	$(Q) $(BINDIR)/$(CONFIG)/h2_compress_invoke_large_request_nosec_test || ( echo test h2_compress_invoke_large_request_nosec_test failed ; exit 1 )
 	$(E) "[RUN]     Testing h2_compress_large_metadata_nosec_test"
@@ -3108,6 +3155,8 @@
 	$(Q) $(BINDIR)/$(CONFIG)/h2_full_graceful_server_shutdown_nosec_test || ( echo test h2_full_graceful_server_shutdown_nosec_test failed ; exit 1 )
 	$(E) "[RUN]     Testing h2_full_high_initial_seqno_nosec_test"
 	$(Q) $(BINDIR)/$(CONFIG)/h2_full_high_initial_seqno_nosec_test || ( echo test h2_full_high_initial_seqno_nosec_test failed ; exit 1 )
+	$(E) "[RUN]     Testing h2_full_hpack_size_nosec_test"
+	$(Q) $(BINDIR)/$(CONFIG)/h2_full_hpack_size_nosec_test || ( echo test h2_full_hpack_size_nosec_test failed ; exit 1 )
 	$(E) "[RUN]     Testing h2_full_invoke_large_request_nosec_test"
 	$(Q) $(BINDIR)/$(CONFIG)/h2_full_invoke_large_request_nosec_test || ( echo test h2_full_invoke_large_request_nosec_test failed ; exit 1 )
 	$(E) "[RUN]     Testing h2_full_large_metadata_nosec_test"
@@ -3176,6 +3225,8 @@
 	$(Q) $(BINDIR)/$(CONFIG)/h2_full+poll_graceful_server_shutdown_nosec_test || ( echo test h2_full+poll_graceful_server_shutdown_nosec_test failed ; exit 1 )
 	$(E) "[RUN]     Testing h2_full+poll_high_initial_seqno_nosec_test"
 	$(Q) $(BINDIR)/$(CONFIG)/h2_full+poll_high_initial_seqno_nosec_test || ( echo test h2_full+poll_high_initial_seqno_nosec_test failed ; exit 1 )
+	$(E) "[RUN]     Testing h2_full+poll_hpack_size_nosec_test"
+	$(Q) $(BINDIR)/$(CONFIG)/h2_full+poll_hpack_size_nosec_test || ( echo test h2_full+poll_hpack_size_nosec_test failed ; exit 1 )
 	$(E) "[RUN]     Testing h2_full+poll_invoke_large_request_nosec_test"
 	$(Q) $(BINDIR)/$(CONFIG)/h2_full+poll_invoke_large_request_nosec_test || ( echo test h2_full+poll_invoke_large_request_nosec_test failed ; exit 1 )
 	$(E) "[RUN]     Testing h2_full+poll_large_metadata_nosec_test"
@@ -3298,6 +3349,8 @@
 	$(Q) $(BINDIR)/$(CONFIG)/h2_sockpair_graceful_server_shutdown_nosec_test || ( echo test h2_sockpair_graceful_server_shutdown_nosec_test failed ; exit 1 )
 	$(E) "[RUN]     Testing h2_sockpair_high_initial_seqno_nosec_test"
 	$(Q) $(BINDIR)/$(CONFIG)/h2_sockpair_high_initial_seqno_nosec_test || ( echo test h2_sockpair_high_initial_seqno_nosec_test failed ; exit 1 )
+	$(E) "[RUN]     Testing h2_sockpair_hpack_size_nosec_test"
+	$(Q) $(BINDIR)/$(CONFIG)/h2_sockpair_hpack_size_nosec_test || ( echo test h2_sockpair_hpack_size_nosec_test failed ; exit 1 )
 	$(E) "[RUN]     Testing h2_sockpair_invoke_large_request_nosec_test"
 	$(Q) $(BINDIR)/$(CONFIG)/h2_sockpair_invoke_large_request_nosec_test || ( echo test h2_sockpair_invoke_large_request_nosec_test failed ; exit 1 )
 	$(E) "[RUN]     Testing h2_sockpair_large_metadata_nosec_test"
@@ -3418,6 +3471,8 @@
 	$(Q) $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_graceful_server_shutdown_nosec_test || ( echo test h2_sockpair_1byte_graceful_server_shutdown_nosec_test failed ; exit 1 )
 	$(E) "[RUN]     Testing h2_sockpair_1byte_high_initial_seqno_nosec_test"
 	$(Q) $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_high_initial_seqno_nosec_test || ( echo test h2_sockpair_1byte_high_initial_seqno_nosec_test failed ; exit 1 )
+	$(E) "[RUN]     Testing h2_sockpair_1byte_hpack_size_nosec_test"
+	$(Q) $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_hpack_size_nosec_test || ( echo test h2_sockpair_1byte_hpack_size_nosec_test failed ; exit 1 )
 	$(E) "[RUN]     Testing h2_sockpair_1byte_invoke_large_request_nosec_test"
 	$(Q) $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_invoke_large_request_nosec_test || ( echo test h2_sockpair_1byte_invoke_large_request_nosec_test failed ; exit 1 )
 	$(E) "[RUN]     Testing h2_sockpair_1byte_large_metadata_nosec_test"
@@ -3484,6 +3539,8 @@
 	$(Q) $(BINDIR)/$(CONFIG)/h2_uchannel_graceful_server_shutdown_nosec_test || ( echo test h2_uchannel_graceful_server_shutdown_nosec_test failed ; exit 1 )
 	$(E) "[RUN]     Testing h2_uchannel_high_initial_seqno_nosec_test"
 	$(Q) $(BINDIR)/$(CONFIG)/h2_uchannel_high_initial_seqno_nosec_test || ( echo test h2_uchannel_high_initial_seqno_nosec_test failed ; exit 1 )
+	$(E) "[RUN]     Testing h2_uchannel_hpack_size_nosec_test"
+	$(Q) $(BINDIR)/$(CONFIG)/h2_uchannel_hpack_size_nosec_test || ( echo test h2_uchannel_hpack_size_nosec_test failed ; exit 1 )
 	$(E) "[RUN]     Testing h2_uchannel_invoke_large_request_nosec_test"
 	$(Q) $(BINDIR)/$(CONFIG)/h2_uchannel_invoke_large_request_nosec_test || ( echo test h2_uchannel_invoke_large_request_nosec_test failed ; exit 1 )
 	$(E) "[RUN]     Testing h2_uchannel_large_metadata_nosec_test"
@@ -3550,6 +3607,8 @@
 	$(Q) $(BINDIR)/$(CONFIG)/h2_uds_graceful_server_shutdown_nosec_test || ( echo test h2_uds_graceful_server_shutdown_nosec_test failed ; exit 1 )
 	$(E) "[RUN]     Testing h2_uds_high_initial_seqno_nosec_test"
 	$(Q) $(BINDIR)/$(CONFIG)/h2_uds_high_initial_seqno_nosec_test || ( echo test h2_uds_high_initial_seqno_nosec_test failed ; exit 1 )
+	$(E) "[RUN]     Testing h2_uds_hpack_size_nosec_test"
+	$(Q) $(BINDIR)/$(CONFIG)/h2_uds_hpack_size_nosec_test || ( echo test h2_uds_hpack_size_nosec_test failed ; exit 1 )
 	$(E) "[RUN]     Testing h2_uds_invoke_large_request_nosec_test"
 	$(Q) $(BINDIR)/$(CONFIG)/h2_uds_invoke_large_request_nosec_test || ( echo test h2_uds_invoke_large_request_nosec_test failed ; exit 1 )
 	$(E) "[RUN]     Testing h2_uds_large_metadata_nosec_test"
@@ -3616,6 +3675,8 @@
 	$(Q) $(BINDIR)/$(CONFIG)/h2_uds+poll_graceful_server_shutdown_nosec_test || ( echo test h2_uds+poll_graceful_server_shutdown_nosec_test failed ; exit 1 )
 	$(E) "[RUN]     Testing h2_uds+poll_high_initial_seqno_nosec_test"
 	$(Q) $(BINDIR)/$(CONFIG)/h2_uds+poll_high_initial_seqno_nosec_test || ( echo test h2_uds+poll_high_initial_seqno_nosec_test failed ; exit 1 )
+	$(E) "[RUN]     Testing h2_uds+poll_hpack_size_nosec_test"
+	$(Q) $(BINDIR)/$(CONFIG)/h2_uds+poll_hpack_size_nosec_test || ( echo test h2_uds+poll_hpack_size_nosec_test failed ; exit 1 )
 	$(E) "[RUN]     Testing h2_uds+poll_invoke_large_request_nosec_test"
 	$(Q) $(BINDIR)/$(CONFIG)/h2_uds+poll_invoke_large_request_nosec_test || ( echo test h2_uds+poll_invoke_large_request_nosec_test failed ; exit 1 )
 	$(E) "[RUN]     Testing h2_uds+poll_large_metadata_nosec_test"
@@ -3993,6 +4054,21 @@
 endif
 
 ifeq ($(NO_PROTOC),true)
+$(GENDIR)/test/proto/metrics.pb.cc: protoc_dep_error
+$(GENDIR)/test/proto/metrics.grpc.pb.cc: protoc_dep_error
+else
+$(GENDIR)/test/proto/metrics.pb.cc: test/proto/metrics.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS)
+	$(E) "[PROTOC]  Generating protobuf CC file from $<"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(PROTOC) --cpp_out=$(GENDIR) $<
+
+$(GENDIR)/test/proto/metrics.grpc.pb.cc: test/proto/metrics.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS)
+	$(E) "[GRPC]    Generating gRPC's protobuf service CC file from $<"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(PROTOC) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $<
+endif
+
+ifeq ($(NO_PROTOC),true)
 $(GENDIR)/test/proto/test.pb.cc: protoc_dep_error
 $(GENDIR)/test/proto/test.grpc.pb.cc: protoc_dep_error
 else
@@ -6535,6 +6611,29 @@
 endif
 
 
+LIBEND2END_TEST_HPACK_SIZE_SRC = \
+    test/core/end2end/tests/hpack_size.c \
+
+
+LIBEND2END_TEST_HPACK_SIZE_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBEND2END_TEST_HPACK_SIZE_SRC))))
+
+$(LIBDIR)/$(CONFIG)/libend2end_test_hpack_size.a: $(ZLIB_DEP) $(LIBEND2END_TEST_HPACK_SIZE_OBJS)
+	$(E) "[AR]      Creating $@"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libend2end_test_hpack_size.a
+	$(Q) $(AR) rcs $(LIBDIR)/$(CONFIG)/libend2end_test_hpack_size.a $(LIBEND2END_TEST_HPACK_SIZE_OBJS)
+ifeq ($(SYSTEM),Darwin)
+	$(Q) ranlib $(LIBDIR)/$(CONFIG)/libend2end_test_hpack_size.a
+endif
+
+
+
+
+ifneq ($(NO_DEPS),true)
+-include $(LIBEND2END_TEST_HPACK_SIZE_OBJS:.o=.dep)
+endif
+
+
 LIBEND2END_TEST_INVOKE_LARGE_REQUEST_SRC = \
     test/core/end2end/tests/invoke_large_request.c \
 
@@ -10169,6 +10268,49 @@
 endif
 
 
+METRICS_CLIENT_SRC = \
+    $(GENDIR)/test/proto/metrics.pb.cc $(GENDIR)/test/proto/metrics.grpc.pb.cc \
+    test/cpp/interop/metrics_client.cc \
+
+METRICS_CLIENT_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(METRICS_CLIENT_SRC))))
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure targets if you don't have OpenSSL.
+
+$(BINDIR)/$(CONFIG)/metrics_client: 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)/metrics_client: protobuf_dep_error
+
+else
+
+$(BINDIR)/$(CONFIG)/metrics_client: $(PROTOBUF_DEP) $(METRICS_CLIENT_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a
+	$(E) "[LD]      Linking $@"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(LDXX) $(LDFLAGS) $(METRICS_CLIENT_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/metrics_client
+
+endif
+
+endif
+
+$(OBJDIR)/$(CONFIG)/test/proto/metrics.o:  $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a
+$(OBJDIR)/$(CONFIG)/test/cpp/interop/metrics_client.o:  $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a
+deps_metrics_client: $(METRICS_CLIENT_OBJS:.o=.dep)
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(METRICS_CLIENT_OBJS:.o=.dep)
+endif
+endif
+$(OBJDIR)/$(CONFIG)/test/cpp/interop/metrics_client.o: $(GENDIR)/test/proto/metrics.pb.cc $(GENDIR)/test/proto/metrics.grpc.pb.cc
+
+
 MOCK_TEST_SRC = \
     test/cpp/end2end/mock_test.cc \
 
@@ -10786,10 +10928,12 @@
 STRESS_TEST_SRC = \
     $(GENDIR)/test/proto/empty.pb.cc $(GENDIR)/test/proto/empty.grpc.pb.cc \
     $(GENDIR)/test/proto/messages.pb.cc $(GENDIR)/test/proto/messages.grpc.pb.cc \
+    $(GENDIR)/test/proto/metrics.pb.cc $(GENDIR)/test/proto/metrics.grpc.pb.cc \
     $(GENDIR)/test/proto/test.pb.cc $(GENDIR)/test/proto/test.grpc.pb.cc \
     test/cpp/interop/interop_client.cc \
     test/cpp/interop/stress_interop_client.cc \
     test/cpp/interop/stress_test.cc \
+    test/cpp/util/metrics_server.cc \
 
 STRESS_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(STRESS_TEST_SRC))))
 ifeq ($(NO_SECURE),true)
@@ -10820,10 +10964,12 @@
 
 $(OBJDIR)/$(CONFIG)/test/proto/empty.o:  $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a
 $(OBJDIR)/$(CONFIG)/test/proto/messages.o:  $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a
+$(OBJDIR)/$(CONFIG)/test/proto/metrics.o:  $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a
 $(OBJDIR)/$(CONFIG)/test/proto/test.o:  $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a
 $(OBJDIR)/$(CONFIG)/test/cpp/interop/interop_client.o:  $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a
 $(OBJDIR)/$(CONFIG)/test/cpp/interop/stress_interop_client.o:  $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a
 $(OBJDIR)/$(CONFIG)/test/cpp/interop/stress_test.o:  $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a
+$(OBJDIR)/$(CONFIG)/test/cpp/util/metrics_server.o:  $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a
 deps_stress_test: $(STRESS_TEST_OBJS:.o=.dep)
 
 ifneq ($(NO_SECURE),true)
@@ -10831,9 +10977,10 @@
 -include $(STRESS_TEST_OBJS:.o=.dep)
 endif
 endif
-$(OBJDIR)/$(CONFIG)/test/cpp/interop/interop_client.o: $(GENDIR)/test/proto/empty.pb.cc $(GENDIR)/test/proto/empty.grpc.pb.cc $(GENDIR)/test/proto/messages.pb.cc $(GENDIR)/test/proto/messages.grpc.pb.cc $(GENDIR)/test/proto/test.pb.cc $(GENDIR)/test/proto/test.grpc.pb.cc
-$(OBJDIR)/$(CONFIG)/test/cpp/interop/stress_interop_client.o: $(GENDIR)/test/proto/empty.pb.cc $(GENDIR)/test/proto/empty.grpc.pb.cc $(GENDIR)/test/proto/messages.pb.cc $(GENDIR)/test/proto/messages.grpc.pb.cc $(GENDIR)/test/proto/test.pb.cc $(GENDIR)/test/proto/test.grpc.pb.cc
-$(OBJDIR)/$(CONFIG)/test/cpp/interop/stress_test.o: $(GENDIR)/test/proto/empty.pb.cc $(GENDIR)/test/proto/empty.grpc.pb.cc $(GENDIR)/test/proto/messages.pb.cc $(GENDIR)/test/proto/messages.grpc.pb.cc $(GENDIR)/test/proto/test.pb.cc $(GENDIR)/test/proto/test.grpc.pb.cc
+$(OBJDIR)/$(CONFIG)/test/cpp/interop/interop_client.o: $(GENDIR)/test/proto/empty.pb.cc $(GENDIR)/test/proto/empty.grpc.pb.cc $(GENDIR)/test/proto/messages.pb.cc $(GENDIR)/test/proto/messages.grpc.pb.cc $(GENDIR)/test/proto/metrics.pb.cc $(GENDIR)/test/proto/metrics.grpc.pb.cc $(GENDIR)/test/proto/test.pb.cc $(GENDIR)/test/proto/test.grpc.pb.cc
+$(OBJDIR)/$(CONFIG)/test/cpp/interop/stress_interop_client.o: $(GENDIR)/test/proto/empty.pb.cc $(GENDIR)/test/proto/empty.grpc.pb.cc $(GENDIR)/test/proto/messages.pb.cc $(GENDIR)/test/proto/messages.grpc.pb.cc $(GENDIR)/test/proto/metrics.pb.cc $(GENDIR)/test/proto/metrics.grpc.pb.cc $(GENDIR)/test/proto/test.pb.cc $(GENDIR)/test/proto/test.grpc.pb.cc
+$(OBJDIR)/$(CONFIG)/test/cpp/interop/stress_test.o: $(GENDIR)/test/proto/empty.pb.cc $(GENDIR)/test/proto/empty.grpc.pb.cc $(GENDIR)/test/proto/messages.pb.cc $(GENDIR)/test/proto/messages.grpc.pb.cc $(GENDIR)/test/proto/metrics.pb.cc $(GENDIR)/test/proto/metrics.grpc.pb.cc $(GENDIR)/test/proto/test.pb.cc $(GENDIR)/test/proto/test.grpc.pb.cc
+$(OBJDIR)/$(CONFIG)/test/cpp/util/metrics_server.o: $(GENDIR)/test/proto/empty.pb.cc $(GENDIR)/test/proto/empty.grpc.pb.cc $(GENDIR)/test/proto/messages.pb.cc $(GENDIR)/test/proto/messages.grpc.pb.cc $(GENDIR)/test/proto/metrics.pb.cc $(GENDIR)/test/proto/metrics.grpc.pb.cc $(GENDIR)/test/proto/test.pb.cc $(GENDIR)/test/proto/test.grpc.pb.cc
 
 
 SYNC_STREAMING_PING_PONG_TEST_SRC = \
@@ -11306,6 +11453,24 @@
 
 # You can't build secure targets if you don't have OpenSSL.
 
+$(BINDIR)/$(CONFIG)/h2_compress_hpack_size_test: openssl_dep_error
+
+else
+
+$(BINDIR)/$(CONFIG)/h2_compress_hpack_size_test:  $(LIBDIR)/$(CONFIG)/libend2end_fixture_h2_compress.a $(LIBDIR)/$(CONFIG)/libend2end_test_hpack_size.a $(LIBDIR)/$(CONFIG)/libend2end_certs.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+	$(E) "[LD]      Linking $@"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(LD) $(LDFLAGS)  $(LIBDIR)/$(CONFIG)/libend2end_fixture_h2_compress.a $(LIBDIR)/$(CONFIG)/libend2end_test_hpack_size.a $(LIBDIR)/$(CONFIG)/libend2end_certs.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_compress_hpack_size_test
+
+endif
+
+
+
+
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure targets if you don't have OpenSSL.
+
 $(BINDIR)/$(CONFIG)/h2_compress_invoke_large_request_test: openssl_dep_error
 
 else
@@ -11936,6 +12101,24 @@
 
 # You can't build secure targets if you don't have OpenSSL.
 
+$(BINDIR)/$(CONFIG)/h2_fakesec_hpack_size_test: openssl_dep_error
+
+else
+
+$(BINDIR)/$(CONFIG)/h2_fakesec_hpack_size_test:  $(LIBDIR)/$(CONFIG)/libend2end_fixture_h2_fakesec.a $(LIBDIR)/$(CONFIG)/libend2end_test_hpack_size.a $(LIBDIR)/$(CONFIG)/libend2end_certs.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+	$(E) "[LD]      Linking $@"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(LD) $(LDFLAGS)  $(LIBDIR)/$(CONFIG)/libend2end_fixture_h2_fakesec.a $(LIBDIR)/$(CONFIG)/libend2end_test_hpack_size.a $(LIBDIR)/$(CONFIG)/libend2end_certs.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_fakesec_hpack_size_test
+
+endif
+
+
+
+
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure targets if you don't have OpenSSL.
+
 $(BINDIR)/$(CONFIG)/h2_fakesec_invoke_large_request_test: openssl_dep_error
 
 else
@@ -12566,6 +12749,24 @@
 
 # You can't build secure targets if you don't have OpenSSL.
 
+$(BINDIR)/$(CONFIG)/h2_full_hpack_size_test: openssl_dep_error
+
+else
+
+$(BINDIR)/$(CONFIG)/h2_full_hpack_size_test:  $(LIBDIR)/$(CONFIG)/libend2end_fixture_h2_full.a $(LIBDIR)/$(CONFIG)/libend2end_test_hpack_size.a $(LIBDIR)/$(CONFIG)/libend2end_certs.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+	$(E) "[LD]      Linking $@"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(LD) $(LDFLAGS)  $(LIBDIR)/$(CONFIG)/libend2end_fixture_h2_full.a $(LIBDIR)/$(CONFIG)/libend2end_test_hpack_size.a $(LIBDIR)/$(CONFIG)/libend2end_certs.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_full_hpack_size_test
+
+endif
+
+
+
+
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure targets if you don't have OpenSSL.
+
 $(BINDIR)/$(CONFIG)/h2_full_invoke_large_request_test: openssl_dep_error
 
 else
@@ -13196,6 +13397,24 @@
 
 # You can't build secure targets if you don't have OpenSSL.
 
+$(BINDIR)/$(CONFIG)/h2_full+poll_hpack_size_test: openssl_dep_error
+
+else
+
+$(BINDIR)/$(CONFIG)/h2_full+poll_hpack_size_test:  $(LIBDIR)/$(CONFIG)/libend2end_fixture_h2_full+poll.a $(LIBDIR)/$(CONFIG)/libend2end_test_hpack_size.a $(LIBDIR)/$(CONFIG)/libend2end_certs.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+	$(E) "[LD]      Linking $@"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(LD) $(LDFLAGS)  $(LIBDIR)/$(CONFIG)/libend2end_fixture_h2_full+poll.a $(LIBDIR)/$(CONFIG)/libend2end_test_hpack_size.a $(LIBDIR)/$(CONFIG)/libend2end_certs.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_full+poll_hpack_size_test
+
+endif
+
+
+
+
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure targets if you don't have OpenSSL.
+
 $(BINDIR)/$(CONFIG)/h2_full+poll_invoke_large_request_test: openssl_dep_error
 
 else
@@ -13826,6 +14045,24 @@
 
 # You can't build secure targets if you don't have OpenSSL.
 
+$(BINDIR)/$(CONFIG)/h2_oauth2_hpack_size_test: openssl_dep_error
+
+else
+
+$(BINDIR)/$(CONFIG)/h2_oauth2_hpack_size_test:  $(LIBDIR)/$(CONFIG)/libend2end_fixture_h2_oauth2.a $(LIBDIR)/$(CONFIG)/libend2end_test_hpack_size.a $(LIBDIR)/$(CONFIG)/libend2end_certs.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+	$(E) "[LD]      Linking $@"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(LD) $(LDFLAGS)  $(LIBDIR)/$(CONFIG)/libend2end_fixture_h2_oauth2.a $(LIBDIR)/$(CONFIG)/libend2end_test_hpack_size.a $(LIBDIR)/$(CONFIG)/libend2end_certs.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_oauth2_hpack_size_test
+
+endif
+
+
+
+
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure targets if you don't have OpenSSL.
+
 $(BINDIR)/$(CONFIG)/h2_oauth2_invoke_large_request_test: openssl_dep_error
 
 else
@@ -14960,6 +15197,24 @@
 
 # You can't build secure targets if you don't have OpenSSL.
 
+$(BINDIR)/$(CONFIG)/h2_sockpair_hpack_size_test: openssl_dep_error
+
+else
+
+$(BINDIR)/$(CONFIG)/h2_sockpair_hpack_size_test:  $(LIBDIR)/$(CONFIG)/libend2end_fixture_h2_sockpair.a $(LIBDIR)/$(CONFIG)/libend2end_test_hpack_size.a $(LIBDIR)/$(CONFIG)/libend2end_certs.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+	$(E) "[LD]      Linking $@"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(LD) $(LDFLAGS)  $(LIBDIR)/$(CONFIG)/libend2end_fixture_h2_sockpair.a $(LIBDIR)/$(CONFIG)/libend2end_test_hpack_size.a $(LIBDIR)/$(CONFIG)/libend2end_certs.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_sockpair_hpack_size_test
+
+endif
+
+
+
+
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure targets if you don't have OpenSSL.
+
 $(BINDIR)/$(CONFIG)/h2_sockpair_invoke_large_request_test: openssl_dep_error
 
 else
@@ -16076,6 +16331,24 @@
 
 # You can't build secure targets if you don't have OpenSSL.
 
+$(BINDIR)/$(CONFIG)/h2_sockpair_1byte_hpack_size_test: openssl_dep_error
+
+else
+
+$(BINDIR)/$(CONFIG)/h2_sockpair_1byte_hpack_size_test:  $(LIBDIR)/$(CONFIG)/libend2end_fixture_h2_sockpair_1byte.a $(LIBDIR)/$(CONFIG)/libend2end_test_hpack_size.a $(LIBDIR)/$(CONFIG)/libend2end_certs.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+	$(E) "[LD]      Linking $@"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(LD) $(LDFLAGS)  $(LIBDIR)/$(CONFIG)/libend2end_fixture_h2_sockpair_1byte.a $(LIBDIR)/$(CONFIG)/libend2end_test_hpack_size.a $(LIBDIR)/$(CONFIG)/libend2end_certs.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_hpack_size_test
+
+endif
+
+
+
+
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure targets if you don't have OpenSSL.
+
 $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_invoke_large_request_test: openssl_dep_error
 
 else
@@ -16688,6 +16961,24 @@
 
 # You can't build secure targets if you don't have OpenSSL.
 
+$(BINDIR)/$(CONFIG)/h2_ssl_hpack_size_test: openssl_dep_error
+
+else
+
+$(BINDIR)/$(CONFIG)/h2_ssl_hpack_size_test:  $(LIBDIR)/$(CONFIG)/libend2end_fixture_h2_ssl.a $(LIBDIR)/$(CONFIG)/libend2end_test_hpack_size.a $(LIBDIR)/$(CONFIG)/libend2end_certs.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+	$(E) "[LD]      Linking $@"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(LD) $(LDFLAGS)  $(LIBDIR)/$(CONFIG)/libend2end_fixture_h2_ssl.a $(LIBDIR)/$(CONFIG)/libend2end_test_hpack_size.a $(LIBDIR)/$(CONFIG)/libend2end_certs.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_ssl_hpack_size_test
+
+endif
+
+
+
+
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure targets if you don't have OpenSSL.
+
 $(BINDIR)/$(CONFIG)/h2_ssl_invoke_large_request_test: openssl_dep_error
 
 else
@@ -17318,6 +17609,24 @@
 
 # You can't build secure targets if you don't have OpenSSL.
 
+$(BINDIR)/$(CONFIG)/h2_ssl+poll_hpack_size_test: openssl_dep_error
+
+else
+
+$(BINDIR)/$(CONFIG)/h2_ssl+poll_hpack_size_test:  $(LIBDIR)/$(CONFIG)/libend2end_fixture_h2_ssl+poll.a $(LIBDIR)/$(CONFIG)/libend2end_test_hpack_size.a $(LIBDIR)/$(CONFIG)/libend2end_certs.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+	$(E) "[LD]      Linking $@"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(LD) $(LDFLAGS)  $(LIBDIR)/$(CONFIG)/libend2end_fixture_h2_ssl+poll.a $(LIBDIR)/$(CONFIG)/libend2end_test_hpack_size.a $(LIBDIR)/$(CONFIG)/libend2end_certs.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_ssl+poll_hpack_size_test
+
+endif
+
+
+
+
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure targets if you don't have OpenSSL.
+
 $(BINDIR)/$(CONFIG)/h2_ssl+poll_invoke_large_request_test: openssl_dep_error
 
 else
@@ -18506,6 +18815,24 @@
 
 # You can't build secure targets if you don't have OpenSSL.
 
+$(BINDIR)/$(CONFIG)/h2_uchannel_hpack_size_test: openssl_dep_error
+
+else
+
+$(BINDIR)/$(CONFIG)/h2_uchannel_hpack_size_test:  $(LIBDIR)/$(CONFIG)/libend2end_fixture_h2_uchannel.a $(LIBDIR)/$(CONFIG)/libend2end_test_hpack_size.a $(LIBDIR)/$(CONFIG)/libend2end_certs.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+	$(E) "[LD]      Linking $@"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(LD) $(LDFLAGS)  $(LIBDIR)/$(CONFIG)/libend2end_fixture_h2_uchannel.a $(LIBDIR)/$(CONFIG)/libend2end_test_hpack_size.a $(LIBDIR)/$(CONFIG)/libend2end_certs.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_uchannel_hpack_size_test
+
+endif
+
+
+
+
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure targets if you don't have OpenSSL.
+
 $(BINDIR)/$(CONFIG)/h2_uchannel_invoke_large_request_test: openssl_dep_error
 
 else
@@ -19118,6 +19445,24 @@
 
 # You can't build secure targets if you don't have OpenSSL.
 
+$(BINDIR)/$(CONFIG)/h2_uds_hpack_size_test: openssl_dep_error
+
+else
+
+$(BINDIR)/$(CONFIG)/h2_uds_hpack_size_test:  $(LIBDIR)/$(CONFIG)/libend2end_fixture_h2_uds.a $(LIBDIR)/$(CONFIG)/libend2end_test_hpack_size.a $(LIBDIR)/$(CONFIG)/libend2end_certs.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+	$(E) "[LD]      Linking $@"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(LD) $(LDFLAGS)  $(LIBDIR)/$(CONFIG)/libend2end_fixture_h2_uds.a $(LIBDIR)/$(CONFIG)/libend2end_test_hpack_size.a $(LIBDIR)/$(CONFIG)/libend2end_certs.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_uds_hpack_size_test
+
+endif
+
+
+
+
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure targets if you don't have OpenSSL.
+
 $(BINDIR)/$(CONFIG)/h2_uds_invoke_large_request_test: openssl_dep_error
 
 else
@@ -19730,6 +20075,24 @@
 
 # You can't build secure targets if you don't have OpenSSL.
 
+$(BINDIR)/$(CONFIG)/h2_uds+poll_hpack_size_test: openssl_dep_error
+
+else
+
+$(BINDIR)/$(CONFIG)/h2_uds+poll_hpack_size_test:  $(LIBDIR)/$(CONFIG)/libend2end_fixture_h2_uds+poll.a $(LIBDIR)/$(CONFIG)/libend2end_test_hpack_size.a $(LIBDIR)/$(CONFIG)/libend2end_certs.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+	$(E) "[LD]      Linking $@"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(LD) $(LDFLAGS)  $(LIBDIR)/$(CONFIG)/libend2end_fixture_h2_uds+poll.a $(LIBDIR)/$(CONFIG)/libend2end_test_hpack_size.a $(LIBDIR)/$(CONFIG)/libend2end_certs.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_uds+poll_hpack_size_test
+
+endif
+
+
+
+
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure targets if you don't have OpenSSL.
+
 $(BINDIR)/$(CONFIG)/h2_uds+poll_invoke_large_request_test: openssl_dep_error
 
 else
@@ -20178,6 +20541,14 @@
 
 
 
+$(BINDIR)/$(CONFIG)/h2_compress_hpack_size_nosec_test:  $(LIBDIR)/$(CONFIG)/libend2end_fixture_h2_compress.a $(LIBDIR)/$(CONFIG)/libend2end_test_hpack_size.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+	$(E) "[LD]      Linking $@"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(LD) $(LDFLAGS)  $(LIBDIR)/$(CONFIG)/libend2end_fixture_h2_compress.a $(LIBDIR)/$(CONFIG)/libend2end_test_hpack_size.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/h2_compress_hpack_size_nosec_test
+
+
+
+
 $(BINDIR)/$(CONFIG)/h2_compress_invoke_large_request_nosec_test:  $(LIBDIR)/$(CONFIG)/libend2end_fixture_h2_compress.a $(LIBDIR)/$(CONFIG)/libend2end_test_invoke_large_request.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
@@ -20450,6 +20821,14 @@
 
 
 
+$(BINDIR)/$(CONFIG)/h2_full_hpack_size_nosec_test:  $(LIBDIR)/$(CONFIG)/libend2end_fixture_h2_full.a $(LIBDIR)/$(CONFIG)/libend2end_test_hpack_size.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+	$(E) "[LD]      Linking $@"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(LD) $(LDFLAGS)  $(LIBDIR)/$(CONFIG)/libend2end_fixture_h2_full.a $(LIBDIR)/$(CONFIG)/libend2end_test_hpack_size.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/h2_full_hpack_size_nosec_test
+
+
+
+
 $(BINDIR)/$(CONFIG)/h2_full_invoke_large_request_nosec_test:  $(LIBDIR)/$(CONFIG)/libend2end_fixture_h2_full.a $(LIBDIR)/$(CONFIG)/libend2end_test_invoke_large_request.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
@@ -20722,6 +21101,14 @@
 
 
 
+$(BINDIR)/$(CONFIG)/h2_full+poll_hpack_size_nosec_test:  $(LIBDIR)/$(CONFIG)/libend2end_fixture_h2_full+poll.a $(LIBDIR)/$(CONFIG)/libend2end_test_hpack_size.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+	$(E) "[LD]      Linking $@"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(LD) $(LDFLAGS)  $(LIBDIR)/$(CONFIG)/libend2end_fixture_h2_full+poll.a $(LIBDIR)/$(CONFIG)/libend2end_test_hpack_size.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/h2_full+poll_hpack_size_nosec_test
+
+
+
+
 $(BINDIR)/$(CONFIG)/h2_full+poll_invoke_large_request_nosec_test:  $(LIBDIR)/$(CONFIG)/libend2end_fixture_h2_full+poll.a $(LIBDIR)/$(CONFIG)/libend2end_test_invoke_large_request.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
@@ -21210,6 +21597,14 @@
 
 
 
+$(BINDIR)/$(CONFIG)/h2_sockpair_hpack_size_nosec_test:  $(LIBDIR)/$(CONFIG)/libend2end_fixture_h2_sockpair.a $(LIBDIR)/$(CONFIG)/libend2end_test_hpack_size.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+	$(E) "[LD]      Linking $@"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(LD) $(LDFLAGS)  $(LIBDIR)/$(CONFIG)/libend2end_fixture_h2_sockpair.a $(LIBDIR)/$(CONFIG)/libend2end_test_hpack_size.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/h2_sockpair_hpack_size_nosec_test
+
+
+
+
 $(BINDIR)/$(CONFIG)/h2_sockpair_invoke_large_request_nosec_test:  $(LIBDIR)/$(CONFIG)/libend2end_fixture_h2_sockpair.a $(LIBDIR)/$(CONFIG)/libend2end_test_invoke_large_request.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
@@ -21690,6 +22085,14 @@
 
 
 
+$(BINDIR)/$(CONFIG)/h2_sockpair_1byte_hpack_size_nosec_test:  $(LIBDIR)/$(CONFIG)/libend2end_fixture_h2_sockpair_1byte.a $(LIBDIR)/$(CONFIG)/libend2end_test_hpack_size.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+	$(E) "[LD]      Linking $@"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(LD) $(LDFLAGS)  $(LIBDIR)/$(CONFIG)/libend2end_fixture_h2_sockpair_1byte.a $(LIBDIR)/$(CONFIG)/libend2end_test_hpack_size.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_hpack_size_nosec_test
+
+
+
+
 $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_invoke_large_request_nosec_test:  $(LIBDIR)/$(CONFIG)/libend2end_fixture_h2_sockpair_1byte.a $(LIBDIR)/$(CONFIG)/libend2end_test_invoke_large_request.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
@@ -21954,6 +22357,14 @@
 
 
 
+$(BINDIR)/$(CONFIG)/h2_uchannel_hpack_size_nosec_test:  $(LIBDIR)/$(CONFIG)/libend2end_fixture_h2_uchannel.a $(LIBDIR)/$(CONFIG)/libend2end_test_hpack_size.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+	$(E) "[LD]      Linking $@"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(LD) $(LDFLAGS)  $(LIBDIR)/$(CONFIG)/libend2end_fixture_h2_uchannel.a $(LIBDIR)/$(CONFIG)/libend2end_test_hpack_size.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/h2_uchannel_hpack_size_nosec_test
+
+
+
+
 $(BINDIR)/$(CONFIG)/h2_uchannel_invoke_large_request_nosec_test:  $(LIBDIR)/$(CONFIG)/libend2end_fixture_h2_uchannel.a $(LIBDIR)/$(CONFIG)/libend2end_test_invoke_large_request.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
@@ -22218,6 +22629,14 @@
 
 
 
+$(BINDIR)/$(CONFIG)/h2_uds_hpack_size_nosec_test:  $(LIBDIR)/$(CONFIG)/libend2end_fixture_h2_uds.a $(LIBDIR)/$(CONFIG)/libend2end_test_hpack_size.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+	$(E) "[LD]      Linking $@"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(LD) $(LDFLAGS)  $(LIBDIR)/$(CONFIG)/libend2end_fixture_h2_uds.a $(LIBDIR)/$(CONFIG)/libend2end_test_hpack_size.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/h2_uds_hpack_size_nosec_test
+
+
+
+
 $(BINDIR)/$(CONFIG)/h2_uds_invoke_large_request_nosec_test:  $(LIBDIR)/$(CONFIG)/libend2end_fixture_h2_uds.a $(LIBDIR)/$(CONFIG)/libend2end_test_invoke_large_request.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
@@ -22482,6 +22901,14 @@
 
 
 
+$(BINDIR)/$(CONFIG)/h2_uds+poll_hpack_size_nosec_test:  $(LIBDIR)/$(CONFIG)/libend2end_fixture_h2_uds+poll.a $(LIBDIR)/$(CONFIG)/libend2end_test_hpack_size.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+	$(E) "[LD]      Linking $@"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(LD) $(LDFLAGS)  $(LIBDIR)/$(CONFIG)/libend2end_fixture_h2_uds+poll.a $(LIBDIR)/$(CONFIG)/libend2end_test_hpack_size.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/h2_uds+poll_hpack_size_nosec_test
+
+
+
+
 $(BINDIR)/$(CONFIG)/h2_uds+poll_invoke_large_request_nosec_test:  $(LIBDIR)/$(CONFIG)/libend2end_fixture_h2_uds+poll.a $(LIBDIR)/$(CONFIG)/libend2end_test_invoke_large_request.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
diff --git a/binding.gyp b/binding.gyp
index 502b9d7..1883f73 100644
--- a/binding.gyp
+++ b/binding.gyp
@@ -347,11 +347,12 @@
         "src/node/ext/node_grpc.cc",
         "src/node/ext/server.cc",
         "src/node/ext/server_credentials.cc",
-        "src/node/ext/timeval.cc"
+        "src/node/ext/timeval.cc",
       ],
       "dependencies": [
-        "grpc"
+        "grpc",
+        "gpr",
       ]
-    }
+    },
   ]
 }
diff --git a/build.yaml b/build.yaml
index bd93a16..2af2c1e 100644
--- a/build.yaml
+++ b/build.yaml
@@ -5,7 +5,7 @@
   '#': The public version number of the library.
   version:
     major: 0
-    minor: 11
+    minor: 12
     micro: 0
     build: 0
 filegroups:
@@ -1887,6 +1887,20 @@
   - mac
   - linux
   - posix
+- name: metrics_client
+  build: test
+  run: false
+  language: c++
+  headers:
+  - test/cpp/util/metrics_server.h
+  src:
+  - test/proto/metrics.proto
+  - test/cpp/interop/metrics_client.cc
+  deps:
+  - grpc++
+  - grpc
+  - gpr
+  - grpc++_test_config
 - name: mock_test
   build: test
   language: c++
@@ -2127,13 +2141,16 @@
   - test/cpp/interop/client_helper.h
   - test/cpp/interop/interop_client.h
   - test/cpp/interop/stress_interop_client.h
+  - test/cpp/util/metrics_server.h
   src:
   - test/proto/empty.proto
   - test/proto/messages.proto
+  - test/proto/metrics.proto
   - test/proto/test.proto
   - test/cpp/interop/interop_client.cc
   - test/cpp/interop/stress_interop_client.cc
   - test/cpp/interop/stress_test.cc
+  - test/cpp/util/metrics_server.cc
   deps:
   - grpc++_test_util
   - grpc_test_util
@@ -2224,3 +2241,36 @@
   props: false
   redist: false
   version: 1.7.0.1
+node_modules:
+- deps:
+  - grpc
+  - gpr
+  headers:
+  - src/node/ext/byte_buffer.h
+  - src/node/ext/call.h
+  - src/node/ext/call_credentials.h
+  - src/node/ext/channel.h
+  - src/node/ext/channel_credentials.h
+  - src/node/ext/completion_queue_async_worker.h
+  - src/node/ext/server.h
+  - src/node/ext/server_credentials.h
+  - src/node/ext/timeval.h
+  js:
+  - src/node/index.js
+  - src/node/src/client.js
+  - src/node/src/common.js
+  - src/node/src/credentials.js
+  - src/node/src/metadata.js
+  - src/node/src/server.js
+  name: grpc_node
+  src:
+  - src/node/ext/byte_buffer.cc
+  - src/node/ext/call.cc
+  - src/node/ext/call_credentials.cc
+  - src/node/ext/channel.cc
+  - src/node/ext/channel_credentials.cc
+  - src/node/ext/completion_queue_async_worker.cc
+  - src/node/ext/node_grpc.cc
+  - src/node/ext/server.cc
+  - src/node/ext/server_credentials.cc
+  - src/node/ext/timeval.cc
diff --git a/doc/grpc-auth-support.md b/doc/grpc-auth-support.md
index 800fbed..b210ff1 100644
--- a/doc/grpc-auth-support.md
+++ b/doc/grpc-auth-support.md
@@ -36,9 +36,9 @@
 ```cpp
 SslCredentialsOptions ssl_opts;  // Options to override SSL params, empty by default
 // Create the credentials object by providing service account key in constructor
-std::unique_ptr<Credentials> creds = CredentialsFactory::SslCredentials(ssl_opts);
+std::shared_ptr<ChannelCredentials> creds = SslCredentials(ssl_opts);
 // Create a channel using the credentials created in the previous step
-std::shared_ptr<ChannelInterface> channel = CreateChannel(server_name, creds, channel_args);
+std::shared_ptr<Channel> channel = CreateChannel(server_name, creds);
 // Create a stub on the channel
 std::unique_ptr<Greeter::Stub> stub(Greeter::NewStub(channel));
 // Make actual RPC calls on the stub.
@@ -55,9 +55,9 @@
 gRPC applications can use a simple API to create a credential that works in various deployment scenarios.
 
 ```cpp
-std::unique_ptr<Credentials> creds = CredentialsFactory::GoogleDefaultCredentials();
+std::shared_ptr<ChannelCredentials> creds = GoogleDefaultCredentials();
 // Create a channel, stub and make RPC calls (same as in the previous example)
-std::shared_ptr<ChannelInterface> channel = CreateChannel(server_name, creds, channel_args);
+std::shared_ptr<Channel> channel = CreateChannel(server_name, creds);
 std::unique_ptr<Greeter::Stub> stub(Greeter::NewStub(channel));
 grpc::Status s = stub->sayHello(&context, *request, response);
 ```
diff --git a/doc/interop-test-descriptions.md b/doc/interop-test-descriptions.md
index 8649213..53cc47b 100644
--- a/doc/interop-test-descriptions.md
+++ b/doc/interop-test-descriptions.md
@@ -4,7 +4,7 @@
 Client and server use
 [test.proto](https://github.com/grpc/grpc/blob/master/test/proto/test.proto)
 and the [gRPC over HTTP/2 v2
-protocol](doc/PROTOCOL-HTTP2.md).
+protocol](https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md).
 
 Client
 ------
diff --git a/examples/cpp/cpptutorial.md b/examples/cpp/cpptutorial.md
index 78de014..cd1cddb 100644
--- a/examples/cpp/cpptutorial.md
+++ b/examples/cpp/cpptutorial.md
@@ -245,7 +245,7 @@
 First we need to create a gRPC *channel* for our stub, specifying the server address and port we want to connect to without SSL:
 
 ```cpp
-grpc::CreateChannel("localhost:50051", grpc::InsecureCredentials());
+grpc::CreateChannel("localhost:50051", grpc::InsecureChannelCredentials());
 ```
 
 Now we can use the channel to create our stub using the `NewStub` method provided in the `RouteGuide` class we generated from our .proto.
diff --git a/examples/cpp/helloworld/README.md b/examples/cpp/helloworld/README.md
index b16c084..7a7194d 100644
--- a/examples/cpp/helloworld/README.md
+++ b/examples/cpp/helloworld/README.md
@@ -94,7 +94,7 @@
   arguments as follows
 
     ```
-    auto channel = CreateChannel("localhost:50051", InsecureCredentials());
+    auto channel = CreateChannel("localhost:50051", InsecureChannelCredentials());
     ```
 
 - Create a stub. A stub implements the rpc methods of a service and in the
diff --git a/examples/cpp/helloworld/greeter_async_client.cc b/examples/cpp/helloworld/greeter_async_client.cc
index 923c8ff..3501426 100644
--- a/examples/cpp/helloworld/greeter_async_client.cc
+++ b/examples/cpp/helloworld/greeter_async_client.cc
@@ -114,9 +114,9 @@
   // Instantiate the client. It requires a channel, out of which the actual RPCs
   // are created. This channel models a connection to an endpoint (in this case,
   // localhost at port 50051). We indicate that the channel isn't authenticated
-  // (use of InsecureCredentials()).
-  GreeterClient greeter(
-      grpc::CreateChannel("localhost:50051", grpc::InsecureCredentials()));
+  // (use of InsecureChannelCredentials()).
+  GreeterClient greeter(grpc::CreateChannel(
+      "localhost:50051", grpc::InsecureChannelCredentials()));
   std::string user("world");
   std::string reply = greeter.SayHello(user);  // The actual RPC call!
   std::cout << "Greeter received: " << reply << std::endl;
diff --git a/examples/cpp/helloworld/greeter_client.cc b/examples/cpp/helloworld/greeter_client.cc
index 6cd8353..bf3b63c 100644
--- a/examples/cpp/helloworld/greeter_client.cc
+++ b/examples/cpp/helloworld/greeter_client.cc
@@ -84,9 +84,9 @@
   // Instantiate the client. It requires a channel, out of which the actual RPCs
   // are created. This channel models a connection to an endpoint (in this case,
   // localhost at port 50051). We indicate that the channel isn't authenticated
-  // (use of InsecureCredentials()).
-  GreeterClient greeter(
-      grpc::CreateChannel("localhost:50051", grpc::InsecureCredentials()));
+  // (use of InsecureChannelCredentials()).
+  GreeterClient greeter(grpc::CreateChannel(
+      "localhost:50051", grpc::InsecureChannelCredentials()));
   std::string user("world");
   std::string reply = greeter.SayHello(user);
   std::cout << "Greeter received: " << reply << std::endl;
diff --git a/examples/cpp/route_guide/route_guide_client.cc b/examples/cpp/route_guide/route_guide_client.cc
index 85173a3..b9abe72 100644
--- a/examples/cpp/route_guide/route_guide_client.cc
+++ b/examples/cpp/route_guide/route_guide_client.cc
@@ -234,7 +234,8 @@
   // Expect only arg: --db_path=path/to/route_guide_db.json.
   std::string db = routeguide::GetDbFileContent(argc, argv);
   RouteGuideClient guide(
-      grpc::CreateChannel("localhost:50051", grpc::InsecureCredentials()),
+      grpc::CreateChannel("localhost:50051",
+                          grpc::InsecureChannelCredentials()),
       db);
 
   std::cout << "-------------- GetFeature --------------" << std::endl;
diff --git a/examples/python/helloworld/greeter_server.py b/examples/python/helloworld/greeter_server.py
index 1514d8f..2cde5ad 100644
--- a/examples/python/helloworld/greeter_server.py
+++ b/examples/python/helloworld/greeter_server.py
@@ -50,7 +50,7 @@
     while True:
       time.sleep(_ONE_DAY_IN_SECONDS)
   except KeyboardInterrupt:
-    server.stop()
+    server.stop(0)
 
 if __name__ == '__main__':
   serve()
diff --git a/include/grpc++/channel.h b/include/grpc++/channel.h
index 60c816d..d6d72a9 100644
--- a/include/grpc++/channel.h
+++ b/include/grpc++/channel.h
@@ -47,8 +47,8 @@
 class CallOpSetInterface;
 class ChannelArguments;
 class CompletionQueue;
-class Credentials;
-class SecureCredentials;
+class ChannelCredentials;
+class SecureChannelCredentials;
 
 template <class R>
 class ClientReader;
diff --git a/include/grpc++/client_context.h b/include/grpc++/client_context.h
index 7046f93..5c6f432 100644
--- a/include/grpc++/client_context.h
+++ b/include/grpc++/client_context.h
@@ -53,15 +53,16 @@
 #include <memory>
 #include <string>
 
-#include <grpc/compression.h>
-#include <grpc/grpc.h>
-#include <grpc/support/log.h>
-#include <grpc/support/time.h>
+#include <grpc++/impl/sync.h>
 #include <grpc++/security/auth_context.h>
 #include <grpc++/support/config.h>
 #include <grpc++/support/status.h>
 #include <grpc++/support/string_ref.h>
 #include <grpc++/support/time.h>
+#include <grpc/compression.h>
+#include <grpc/grpc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/time.h>
 
 struct census_context;
 
@@ -69,7 +70,7 @@
 
 class Channel;
 class CompletionQueue;
-class Credentials;
+class CallCredentials;
 class RpcMethod;
 template <class R>
 class ClientReader;
@@ -244,7 +245,7 @@
   /// call.
   ///
   /// \see  https://github.com/grpc/grpc/blob/master/doc/grpc-auth-support.md
-  void set_credentials(const std::shared_ptr<Credentials>& creds) {
+  void set_credentials(const std::shared_ptr<CallCredentials>& creds) {
     creds_ = creds;
   }
 
@@ -315,10 +316,12 @@
 
   bool initial_metadata_received_;
   std::shared_ptr<Channel> channel_;
+  grpc::mutex mu_;
   grpc_call* call_;
+  bool call_canceled_;
   gpr_timespec deadline_;
   grpc::string authority_;
-  std::shared_ptr<Credentials> creds_;
+  std::shared_ptr<CallCredentials> creds_;
   mutable std::shared_ptr<const AuthContext> auth_context_;
   struct census_context* census_context_;
   std::multimap<grpc::string, grpc::string> send_initial_metadata_;
diff --git a/include/grpc++/create_channel.h b/include/grpc++/create_channel.h
index 196d292..aff9c29 100644
--- a/include/grpc++/create_channel.h
+++ b/include/grpc++/create_channel.h
@@ -49,7 +49,8 @@
 /// an object or is invalid, a lame channel is returned.
 /// \param args Options for channel creation.
 std::shared_ptr<Channel> CreateChannel(
-    const grpc::string& target, const std::shared_ptr<Credentials>& creds);
+    const grpc::string& target,
+    const std::shared_ptr<ChannelCredentials>& creds);
 
 /// Create a new \em custom \a Channel pointing to \a target
 ///
@@ -61,7 +62,8 @@
 /// an object or is invalid, a lame channel is returned.
 /// \param args Options for channel creation.
 std::shared_ptr<Channel> CreateCustomChannel(
-    const grpc::string& target, const std::shared_ptr<Credentials>& creds,
+    const grpc::string& target,
+    const std::shared_ptr<ChannelCredentials>& creds,
     const ChannelArguments& args);
 
 }  // namespace grpc
diff --git a/include/grpc++/impl/thd_no_cxx11.h b/include/grpc++/impl/thd_no_cxx11.h
index 84d03ce..3f981d3 100644
--- a/include/grpc++/impl/thd_no_cxx11.h
+++ b/include/grpc++/impl/thd_no_cxx11.h
@@ -46,10 +46,21 @@
     joined_ = false;
     start();
   }
+  template <class T, class U>
+  thread(void (T::*fptr)(U arg), T *obj, U arg) {
+    func_ = new thread_function_arg<T, U>(fptr, obj, arg);
+    joined_ = false;
+    start();
+  }
   ~thread() {
     if (!joined_) std::terminate();
     delete func_;
   }
+  thread(thread &&other)
+      : func_(other.func_), thd_(other.thd_), joined_(other.joined_) {
+    other.joined_ = true;
+    other.func_ = NULL;
+  }
   void join() {
     gpr_thd_join(thd_);
     joined_ = true;
@@ -80,6 +91,18 @@
     void (T::*fptr_)();
     T *obj_;
   };
+  template <class T, class U>
+  class thread_function_arg : public thread_function_base {
+   public:
+    thread_function_arg(void (T::*fptr)(U arg), T *obj, U arg)
+        : fptr_(fptr), obj_(obj), arg_(arg) {}
+    virtual void call() { (obj_->*fptr_)(arg_); }
+
+   private:
+    void (T::*fptr_)(U arg);
+    T *obj_;
+    U arg_;
+  };
   thread_function_base *func_;
   gpr_thd_id thd_;
   bool joined_;
diff --git a/include/grpc++/security/credentials.h b/include/grpc++/security/credentials.h
index ff41bc5..cc827f0 100644
--- a/include/grpc++/security/credentials.h
+++ b/include/grpc++/security/credentials.h
@@ -45,35 +45,58 @@
 namespace grpc {
 class ChannelArguments;
 class Channel;
-class SecureCredentials;
+class SecureChannelCredentials;
+class CallCredentials;
+class SecureCallCredentials;
 
-/// A credentials object encapsulates all the state needed by a client to
-/// authenticate with a server and make various assertions, e.g., about the
-/// client’s identity, role, or whether it is authorized to make a particular
-/// call.
+/// A channel credentials object encapsulates all the state needed by a client
+/// to authenticate with a server for a given channel.
+/// It can make various assertions, e.g., about the client’s identity, role
+/// for all the calls on that channel.
 ///
 /// \see https://github.com/grpc/grpc/blob/master/doc/grpc-auth-support.md
-class Credentials : public GrpcLibrary {
+class ChannelCredentials : public GrpcLibrary {
  public:
-  ~Credentials() GRPC_OVERRIDE;
+  ~ChannelCredentials() GRPC_OVERRIDE;
+
+ protected:
+  friend std::shared_ptr<ChannelCredentials> CompositeChannelCredentials(
+      const std::shared_ptr<ChannelCredentials>& channel_creds,
+      const std::shared_ptr<CallCredentials>& call_creds);
+
+  virtual SecureChannelCredentials* AsSecureCredentials() = 0;
+
+ private:
+  friend std::shared_ptr<Channel> CreateCustomChannel(
+      const grpc::string& target,
+      const std::shared_ptr<ChannelCredentials>& creds,
+      const ChannelArguments& args);
+
+  virtual std::shared_ptr<Channel> CreateChannel(
+      const grpc::string& target, const ChannelArguments& args) = 0;
+};
+
+/// A call credentials object encapsulates the state needed by a client to
+/// authenticate with a server for a given call on a channel.
+///
+/// \see https://github.com/grpc/grpc/blob/master/doc/grpc-auth-support.md
+class CallCredentials : public GrpcLibrary {
+ public:
+  ~CallCredentials() GRPC_OVERRIDE;
 
   /// Apply this instance's credentials to \a call.
   virtual bool ApplyToCall(grpc_call* call) = 0;
 
  protected:
-  friend std::shared_ptr<Credentials> CompositeCredentials(
-      const std::shared_ptr<Credentials>& creds1,
-      const std::shared_ptr<Credentials>& creds2);
+  friend std::shared_ptr<ChannelCredentials> CompositeChannelCredentials(
+      const std::shared_ptr<ChannelCredentials>& channel_creds,
+      const std::shared_ptr<CallCredentials>& call_creds);
 
-  virtual SecureCredentials* AsSecureCredentials() = 0;
+  friend std::shared_ptr<CallCredentials> CompositeCallCredentials(
+      const std::shared_ptr<CallCredentials>& creds1,
+      const std::shared_ptr<CallCredentials>& creds2);
 
- private:
-  friend std::shared_ptr<Channel> CreateCustomChannel(
-      const grpc::string& target, const std::shared_ptr<Credentials>& creds,
-      const ChannelArguments& args);
-
-  virtual std::shared_ptr<Channel> CreateChannel(
-      const grpc::string& target, const ChannelArguments& args) = 0;
+  virtual SecureCallCredentials* AsSecureCredentials() = 0;
 };
 
 /// Options used to build SslCredentials.
@@ -106,10 +129,10 @@
 /// Using these credentials to connect to any other service may result in this
 /// service being able to impersonate your client for requests to Google
 /// services.
-std::shared_ptr<Credentials> GoogleDefaultCredentials();
+std::shared_ptr<ChannelCredentials> GoogleDefaultCredentials();
 
 /// Builds SSL Credentials given SSL specific options
-std::shared_ptr<Credentials> SslCredentials(
+std::shared_ptr<ChannelCredentials> SslCredentials(
     const SslCredentialsOptions& options);
 
 /// Builds credentials for use when running in GCE
@@ -118,14 +141,14 @@
 /// Using these credentials to connect to any other service may result in this
 /// service being able to impersonate your client for requests to Google
 /// services.
-std::shared_ptr<Credentials> GoogleComputeEngineCredentials();
+std::shared_ptr<CallCredentials> GoogleComputeEngineCredentials();
 
 /// Builds Service Account JWT Access credentials.
 /// json_key is the JSON key string containing the client's private key.
 /// token_lifetime_seconds is the lifetime in seconds of each Json Web Token
 /// (JWT) created with this credentials. It should not exceed
 /// grpc_max_auth_token_lifetime or will be cropped to this value.
-std::shared_ptr<Credentials> ServiceAccountJWTAccessCredentials(
+std::shared_ptr<CallCredentials> ServiceAccountJWTAccessCredentials(
     const grpc::string& json_key, long token_lifetime_seconds);
 
 /// Builds refresh token credentials.
@@ -136,7 +159,7 @@
 /// Using these credentials to connect to any other service may result in this
 /// service being able to impersonate your client for requests to Google
 /// services.
-std::shared_ptr<Credentials> GoogleRefreshTokenCredentials(
+std::shared_ptr<CallCredentials> GoogleRefreshTokenCredentials(
     const grpc::string& json_refresh_token);
 
 /// Builds access token credentials.
@@ -147,7 +170,7 @@
 /// Using these credentials to connect to any other service may result in this
 /// service being able to impersonate your client for requests to Google
 /// services.
-std::shared_ptr<Credentials> AccessTokenCredentials(
+std::shared_ptr<CallCredentials> AccessTokenCredentials(
     const grpc::string& access_token);
 
 /// Builds IAM credentials.
@@ -156,17 +179,23 @@
 /// Using these credentials to connect to any other service may result in this
 /// service being able to impersonate your client for requests to Google
 /// services.
-std::shared_ptr<Credentials> GoogleIAMCredentials(
+std::shared_ptr<CallCredentials> GoogleIAMCredentials(
     const grpc::string& authorization_token,
     const grpc::string& authority_selector);
 
-/// Combines two credentials objects into a composite credentials
-std::shared_ptr<Credentials> CompositeCredentials(
-    const std::shared_ptr<Credentials>& creds1,
-    const std::shared_ptr<Credentials>& creds2);
+/// Combines a channel credentials and a call credentials into a composite
+/// channel credentials.
+std::shared_ptr<ChannelCredentials> CompositeChannelCredentials(
+    const std::shared_ptr<ChannelCredentials>& channel_creds,
+    const std::shared_ptr<CallCredentials>& call_creds);
+
+/// Combines two call credentials objects into a composite call credentials.
+std::shared_ptr<CallCredentials> CompositeCallCredentials(
+    const std::shared_ptr<CallCredentials>& creds1,
+    const std::shared_ptr<CallCredentials>& creds2);
 
 /// Credentials for an unencrypted, unauthenticated channel
-std::shared_ptr<Credentials> InsecureCredentials();
+std::shared_ptr<ChannelCredentials> InsecureChannelCredentials();
 
 // User defined metadata credentials.
 class MetadataCredentialsPlugin {
@@ -183,7 +212,7 @@
       std::multimap<grpc::string, grpc::string>* metadata) = 0;
 };
 
-std::shared_ptr<Credentials> MetadataCredentialsFromPlugin(
+std::shared_ptr<CallCredentials> MetadataCredentialsFromPlugin(
     std::unique_ptr<MetadataCredentialsPlugin> plugin);
 
 }  // namespace grpc
diff --git a/include/grpc++/support/channel_arguments.h b/include/grpc++/support/channel_arguments.h
index 4da76a8..cf8eab3 100644
--- a/include/grpc++/support/channel_arguments.h
+++ b/include/grpc++/support/channel_arguments.h
@@ -84,7 +84,7 @@
   void SetString(const grpc::string& key, const grpc::string& value);
 
  private:
-  friend class SecureCredentials;
+  friend class SecureChannelCredentials;
   friend class testing::ChannelArgumentsTest;
 
   // Returns empty string when it is not set.
diff --git a/include/grpc++/support/time.h b/include/grpc++/support/time.h
index 2d4196b..e00e0d8 100644
--- a/include/grpc++/support/time.h
+++ b/include/grpc++/support/time.h
@@ -35,6 +35,7 @@
 #define GRPCXX_SUPPORT_TIME_H
 
 #include <grpc++/support/config.h>
+#include <grpc/support/time.h>
 
 namespace grpc {
 
diff --git a/include/grpc/grpc.h b/include/grpc/grpc.h
index 05c1b4c..cedcee7 100644
--- a/include/grpc/grpc.h
+++ b/include/grpc/grpc.h
@@ -132,6 +132,12 @@
     NOTE: at some point we'd like to auto-tune this, and this parameter
     will become a no-op. */
 #define GRPC_ARG_HTTP2_STREAM_LOOKAHEAD_BYTES "grpc.http2.lookahead_bytes"
+/** How much memory to use for hpack decoding */
+#define GRPC_ARG_HTTP2_HPACK_TABLE_SIZE_DECODER \
+  "grpc.http2.hpack_table_size.decoder"
+/** How much memory to use for hpack encoding */
+#define GRPC_ARG_HTTP2_HPACK_TABLE_SIZE_ENCODER \
+  "grpc.http2.hpack_table_size.encoder"
 /** Default authority to pass if none specified on call construction */
 #define GRPC_ARG_DEFAULT_AUTHORITY "grpc.default_authority"
 /** Primary user agent: goes at the start of the user-agent metadata
diff --git a/include/grpc/grpc_security.h b/include/grpc/grpc_security.h
index 7a442e2..c8da593 100644
--- a/include/grpc/grpc_security.h
+++ b/include/grpc/grpc_security.h
@@ -41,15 +41,16 @@
 extern "C" {
 #endif
 
-/* --- grpc_credentials object. ---
+/* --- grpc_channel_credentials object. ---
 
-   A credentials object represents a way to authenticate a client.  */
+   A channel credentials object represents a way to authenticate a client on a
+   channel.  */
 
-typedef struct grpc_credentials grpc_credentials;
+typedef struct grpc_channel_credentials grpc_channel_credentials;
 
-/* Releases a credentials object.
+/* Releases a channel credentials object.
    The creator of the credentials object is responsible for its release. */
-void grpc_credentials_release(grpc_credentials *creds);
+void grpc_channel_credentials_release(grpc_channel_credentials *creds);
 
 /* Environment variable that points to the google default application
    credentials json key or refresh token. Used in the
@@ -59,7 +60,7 @@
 /* Creates default credentials to connect to a google gRPC service.
    WARNING: Do NOT use this credentials to connect to a non-google service as
    this could result in an oauth2 token leak. */
-grpc_credentials *grpc_google_default_credentials_create(void);
+grpc_channel_credentials *grpc_google_default_credentials_create(void);
 
 /* Environment variable that points to the default SSL roots file. This file
    must be a PEM encoded file with all the roots such as the one that can be
@@ -88,19 +89,37 @@
    - pem_key_cert_pair is a pointer on the object containing client's private
      key and certificate chain. This parameter can be NULL if the client does
      not have such a key/cert pair. */
-grpc_credentials *grpc_ssl_credentials_create(
+grpc_channel_credentials *grpc_ssl_credentials_create(
     const char *pem_root_certs, grpc_ssl_pem_key_cert_pair *pem_key_cert_pair,
     void *reserved);
 
-/* Creates a composite credentials object. */
-grpc_credentials *grpc_composite_credentials_create(grpc_credentials *creds1,
-                                                    grpc_credentials *creds2,
-                                                    void *reserved);
+/* --- grpc_call_credentials object.
+
+   A call credentials object represents a way to authenticate on a particular
+   call. These credentials can be composed with a channel credentials object
+   so that they are sent with every call on this channel.  */
+
+typedef struct grpc_call_credentials grpc_call_credentials;
+
+/* Releases a call credentials object.
+   The creator of the credentials object is responsible for its release. */
+void grpc_call_credentials_release(grpc_call_credentials *creds);
+
+/* Creates a composite channel credentials object. */
+grpc_channel_credentials *grpc_composite_channel_credentials_create(
+    grpc_channel_credentials *channel_creds, grpc_call_credentials *call_creds,
+    void *reserved);
+
+/* Creates a composite call credentials object. */
+grpc_call_credentials *grpc_composite_call_credentials_create(
+    grpc_call_credentials *creds1, grpc_call_credentials *creds2,
+    void *reserved);
 
 /* Creates a compute engine credentials object for connecting to Google.
    WARNING: Do NOT use this credentials to connect to a non-google service as
    this could result in an oauth2 token leak. */
-grpc_credentials *grpc_google_compute_engine_credentials_create(void *reserved);
+grpc_call_credentials *grpc_google_compute_engine_credentials_create(
+    void *reserved);
 
 extern const gpr_timespec grpc_max_auth_token_lifetime;
 
@@ -109,7 +128,7 @@
    - token_lifetime is the lifetime of each Json Web Token (JWT) created with
      this credentials.  It should not exceed grpc_max_auth_token_lifetime or
      will be cropped to this value.  */
-grpc_credentials *grpc_service_account_jwt_access_credentials_create(
+grpc_call_credentials *grpc_service_account_jwt_access_credentials_create(
     const char *json_key, gpr_timespec token_lifetime, void *reserved);
 
 /* Creates an Oauth2 Refresh Token credentials object for connecting to Google.
@@ -118,16 +137,16 @@
    this could result in an oauth2 token leak.
    - json_refresh_token is the JSON string containing the refresh token itself
      along with a client_id and client_secret. */
-grpc_credentials *grpc_google_refresh_token_credentials_create(
+grpc_call_credentials *grpc_google_refresh_token_credentials_create(
     const char *json_refresh_token, void *reserved);
 
 /* Creates an Oauth2 Access Token credentials with an access token that was
    aquired by an out of band mechanism. */
-grpc_credentials *grpc_access_token_credentials_create(const char *access_token,
-                                                       void *reserved);
+grpc_call_credentials *grpc_access_token_credentials_create(
+    const char *access_token, void *reserved);
 
 /* Creates an IAM credentials object for connecting to Google. */
-grpc_credentials *grpc_google_iam_credentials_create(
+grpc_call_credentials *grpc_google_iam_credentials_create(
     const char *authorization_token, const char *authority_selector,
     void *reserved);
 
@@ -168,13 +187,13 @@
 } grpc_metadata_credentials_plugin;
 
 /* Creates a credentials object from a plugin. */
-grpc_credentials *grpc_metadata_credentials_create_from_plugin(
+grpc_call_credentials *grpc_metadata_credentials_create_from_plugin(
     grpc_metadata_credentials_plugin plugin, void *reserved);
 
 /* --- Secure channel creation. --- */
 
 /* Creates a secure channel using the passed-in credentials. */
-grpc_channel *grpc_secure_channel_create(grpc_credentials *creds,
+grpc_channel *grpc_secure_channel_create(grpc_channel_credentials *creds,
                                          const char *target,
                                          const grpc_channel_args *args,
                                          void *reserved);
@@ -218,7 +237,7 @@
 /* Sets a credentials to a call. Can only be called on the client side before
    grpc_call_start_batch. */
 grpc_call_error grpc_call_set_credentials(grpc_call *call,
-                                          grpc_credentials *creds);
+                                          grpc_call_credentials *creds);
 
 /* --- Authentication Context. --- */
 
diff --git a/reports/interop_html_report.template b/reports/interop_html_report.template
new file mode 100644
index 0000000..1ba2e6c
--- /dev/null
+++ b/reports/interop_html_report.template
@@ -0,0 +1,141 @@
+<!DOCTYPE html>
+<html lang="en">
+<head><title>Interop Test Result</title></head>
+<body>
+
+<%def name="fill_one_test_result(shortname, resultset)">
+  % if shortname in resultset:
+    ## Because interop tests does not have runs_per_test flag, each test is 
+    ## run once. So there should only be one element for each result.
+    <% result = resultset[shortname][0] %>
+    % if result.state == 'PASSED':      
+        <td bgcolor="green">PASS</td>
+    % else:
+      <% 
+        tooltip = ''
+        if result.returncode > 0 or result.message:
+          if result.returncode > 0:
+            tooltip = 'returncode: %d ' % result.returncode
+          if result.message:
+            tooltip = '%smessage: %s' % (tooltip, result.message)  
+      %>     
+      % if result.state == 'FAILED':
+        <td bgcolor="red">
+        % if tooltip:  
+          <a href="#" data-toggle="tooltip" data-placement="auto" title="${tooltip | h}">FAIL</a></td>
+        % else:
+          FAIL</td>
+        % endif
+      % elif result.state == 'TIMEOUT':
+        <td bgcolor="yellow">
+        % if tooltip:
+          <a href="#" data-toggle="tooltip" data-placement="auto" title="${tooltip | h}">TIMEOUT</a></td> 
+        % else:
+          TIMEOUT</td>
+        % endif
+      % endif
+    % endif
+  % else:
+     <td bgcolor="magenta">Not implemented</td>
+  % endif
+</%def>
+
+% if num_failures > 1:
+  <p><h2><font color="red">${num_failures} tests failed!</font></h2></p>
+% elif num_failures:
+  <p><h2><font color="red">${num_failures} test failed!</font></h2></p>
+% else:
+  <p><h2><font color="green">All tests passed!</font></h2></p>
+% endif
+
+% if cloud_to_prod:
+  ## Each column header is the client language.
+  <h2>Cloud to Prod</h2>
+  <table style="width:100%" border="1">
+  <tr bgcolor="#00BFFF">
+  <th>Client languages &#9658;<br/>Test Cases &#9660;</th>
+  % for client_lang in client_langs:
+    <th>${client_lang}</th>
+  % endfor
+  </tr>
+  % for test_case in test_cases + auth_test_cases:
+    <tr><td><b>${test_case}</b></td>
+    % for client_lang in client_langs:
+      <% 
+        if test_case in auth_test_cases:
+          shortname = 'cloud_to_prod_auth:%s:%s' % (client_lang, test_case)
+        else:
+          shortname = 'cloud_to_prod:%s:%s' % (client_lang, test_case)
+      %>
+      ${fill_one_test_result(shortname, resultset)}
+    % endfor
+    </tr> 
+  % endfor
+  </table>
+% endif
+
+% if http2_interop:
+  ## Each column header is the server language.
+  <h2>HTTP/2 Interop</h2> 
+  <table style="width:100%" border="1">
+  <tr bgcolor="#00BFFF">
+  <th>Servers &#9658;<br/>Test Cases &#9660;</th>
+  % for server_lang in server_langs:
+    <th>${server_lang}</th>
+  % endfor
+  % if cloud_to_prod:
+    <th>prod</th>
+  % endif
+  </tr>
+  % for test_case in http2_cases:
+    <tr><td><b>${test_case}</b></td>
+    ## Fill up the cells with test result.
+    % for server_lang in server_langs:
+      <% 
+        shortname = 'cloud_to_cloud:http2:%s_server:%s' % (
+            server_lang, test_case)
+      %>
+      ${fill_one_test_result(shortname, resultset)}
+    % endfor
+    % if cloud_to_prod:
+      <% shortname = 'cloud_to_prod:http2:%s' % test_case %>
+      ${fill_one_test_result(shortname, resultset)}
+    % endif
+    </tr>
+  % endfor
+  </table>
+% endif
+
+% if server_langs:
+  % for test_case in test_cases:
+    ## Each column header is the client language.
+    <h2>${test_case}</h2> 
+    <table style="width:100%" border="1">
+    <tr bgcolor="#00BFFF">
+    <th>Client languages &#9658;<br/>Server languages &#9660;</th>
+    % for client_lang in client_langs:
+      <th>${client_lang}</th>
+    % endfor
+    </tr>
+    ## Each row head is the server language.
+    % for server_lang in server_langs:
+      <tr>
+      <td><b>${server_lang}</b></td>
+      % for client_lang in client_langs:
+        <% 
+          shortname = 'cloud_to_cloud:%s:%s_server:%s' % (
+              client_lang, server_lang, test_case)
+        %>
+        ${fill_one_test_result(shortname, resultset)}
+      % endfor
+      </tr>
+    % endfor
+    </table>
+  % endfor
+% endif
+
+<script>
+  $(document).ready(function(){$('[data-toggle="tooltip"]').tooltip();});
+</script>
+</body>
+</html>
diff --git a/src/core/client_config/subchannel.c b/src/core/client_config/subchannel.c
index 49c2cf9..b15a903 100644
--- a/src/core/client_config/subchannel.c
+++ b/src/core/client_config/subchannel.c
@@ -697,10 +697,25 @@
 
 /* Update backoff_delta and next_attempt in subchannel */
 static void update_reconnect_parameters(grpc_subchannel *c) {
+  size_t i;
   gpr_int32 backoff_delta_millis, jitter;
   gpr_int32 max_backoff_millis =
       GRPC_SUBCHANNEL_RECONNECT_MAX_BACKOFF_SECONDS * 1000;
   double jitter_range;
+
+  if (c->args) {
+    for (i = 0; i < c->args->num_args; i++) {
+      if (0 == strcmp(c->args->args[i].key,
+                      "grpc.testing.fixed_reconnect_backoff")) {
+        GPR_ASSERT(c->args->args[i].type == GRPC_ARG_INTEGER);
+        c->next_attempt = gpr_time_add(
+            gpr_now(GPR_CLOCK_MONOTONIC),
+            gpr_time_from_millis(c->args->args[i].value.integer, GPR_TIMESPAN));
+        return;
+      }
+    }
+  }
+
   backoff_delta_millis =
       (gpr_int32)(gpr_time_to_millis(c->backoff_delta) *
                   GRPC_SUBCHANNEL_RECONNECT_BACKOFF_MULTIPLIER);
diff --git a/src/core/client_config/subchannel.h b/src/core/client_config/subchannel.h
index 1fefa18..381b768 100644
--- a/src/core/client_config/subchannel.h
+++ b/src/core/client_config/subchannel.h
@@ -77,10 +77,10 @@
 
 /** construct a subchannel call (possibly asynchronously).
  *
- * If the returned status is 1, the call will return immediately and \a target 
- * will point to a connected \a subchannel_call instance. Note that \a notify 
+ * If the returned status is 1, the call will return immediately and \a target
+ * will point to a connected \a subchannel_call instance. Note that \a notify
  * will \em not be invoked in this case.
- * Otherwise, if the returned status is 0, the subchannel call will be created 
+ * Otherwise, if the returned status is 0, the subchannel call will be created
  * asynchronously, invoking the \a notify callback upon completion. */
 int grpc_subchannel_create_call(grpc_exec_ctx *exec_ctx,
                                 grpc_subchannel *subchannel,
diff --git a/src/core/iomgr/pollset_windows.c b/src/core/iomgr/pollset_windows.c
index c3f310e..deb6615 100644
--- a/src/core/iomgr/pollset_windows.c
+++ b/src/core/iomgr/pollset_windows.c
@@ -126,7 +126,8 @@
 
 void grpc_pollset_reset(grpc_pollset *pollset) {
   GPR_ASSERT(pollset->shutting_down);
-  GPR_ASSERT(!has_workers(&pollset->root_worker, GRPC_POLLSET_WORKER_LINK_POLLSET));
+  GPR_ASSERT(
+      !has_workers(&pollset->root_worker, GRPC_POLLSET_WORKER_LINK_POLLSET));
   pollset->shutting_down = 0;
   pollset->is_iocp_worker = 0;
   pollset->kicked_without_pollers = 0;
diff --git a/src/core/iomgr/tcp_server.h b/src/core/iomgr/tcp_server.h
index 882635f..3df3617 100644
--- a/src/core/iomgr/tcp_server.h
+++ b/src/core/iomgr/tcp_server.h
@@ -39,6 +39,9 @@
 /* Forward decl of grpc_tcp_server */
 typedef struct grpc_tcp_server grpc_tcp_server;
 
+/* Forward decl of grpc_tcp_listener */
+typedef struct grpc_tcp_listener grpc_tcp_listener;
+
 /* Called for newly connected TCP connections. */
 typedef void (*grpc_tcp_server_cb)(grpc_exec_ctx *exec_ctx, void *arg,
                                    grpc_endpoint *ep);
@@ -51,19 +54,18 @@
                            grpc_pollset **pollsets, size_t pollset_count,
                            grpc_tcp_server_cb on_accept_cb, void *cb_arg);
 
-/* Add a port to the server, returning port number on success, or negative
-   on failure.
+/* Add a port to the server, returning the newly created listener on success,
+   or a null pointer on failure.
 
    The :: and 0.0.0.0 wildcard addresses are treated identically, accepting
    both IPv4 and IPv6 connections, but :: is the preferred style.  This usually
    creates one socket, but possibly two on systems which support IPv6,
-   but not dualstack sockets.
-
-   For raw access to the underlying sockets, see grpc_tcp_server_get_fd(). */
+   but not dualstack sockets. */
 /* TODO(ctiller): deprecate this, and make grpc_tcp_server_add_ports to handle
                   all of the multiple socket port matching logic in one place */
-int grpc_tcp_server_add_port(grpc_tcp_server *s, const void *addr,
-                             size_t addr_len);
+grpc_tcp_listener *grpc_tcp_server_add_port(grpc_tcp_server *s,
+                                            const void *addr,
+                                            size_t addr_len);
 
 /* Returns the file descriptor of the Nth listening socket on this server,
    or -1 if the index is out of bounds.
@@ -75,4 +77,8 @@
 void grpc_tcp_server_destroy(grpc_exec_ctx *exec_ctx, grpc_tcp_server *server,
                              grpc_closure *closure);
 
+int grpc_tcp_listener_get_port(grpc_tcp_listener *listener);
+void grpc_tcp_listener_ref(grpc_tcp_listener *listener);
+void grpc_tcp_listener_unref(grpc_tcp_listener *listener);
+
 #endif /* GRPC_INTERNAL_CORE_IOMGR_TCP_SERVER_H */
diff --git a/src/core/iomgr/tcp_server_posix.c b/src/core/iomgr/tcp_server_posix.c
index 99c76dc..1439dfc 100644
--- a/src/core/iomgr/tcp_server_posix.c
+++ b/src/core/iomgr/tcp_server_posix.c
@@ -67,14 +67,13 @@
 #include <grpc/support/sync.h>
 #include <grpc/support/time.h>
 
-#define INIT_PORT_CAP 2
 #define MIN_SAFE_ACCEPT_QUEUE_SIZE 100
 
 static gpr_once s_init_max_accept_queue_size;
 static int s_max_accept_queue_size;
 
 /* one listening port */
-typedef struct {
+struct grpc_tcp_listener {
   int fd;
   grpc_fd *emfd;
   grpc_tcp_server *server;
@@ -84,9 +83,18 @@
     struct sockaddr_un un;
   } addr;
   size_t addr_len;
+  int port;
   grpc_closure read_closure;
   grpc_closure destroyed_closure;
-} server_port;
+  gpr_refcount refs;
+  struct grpc_tcp_listener *next;
+  /* When we add a listener, more than one can be created, mainly because of
+     IPv6. A sibling will still be in the normal list, but will be flagged
+     as such. Any action, such as ref or unref, will affect all of the
+     siblings in the list. */
+  struct grpc_tcp_listener *sibling;
+  int is_sibling;
+};
 
 static void unlink_if_unix_domain_socket(const struct sockaddr_un *un) {
   struct stat st;
@@ -112,10 +120,9 @@
   /* is this server shutting down? (boolean) */
   int shutdown;
 
-  /* all listening ports */
-  server_port *ports;
-  size_t nports;
-  size_t port_capacity;
+  /* linked list of server ports */
+  grpc_tcp_listener *head;
+  unsigned nports;
 
   /* shutdown callback */
   grpc_closure *shutdown_complete;
@@ -134,9 +141,8 @@
   s->shutdown = 0;
   s->on_accept_cb = NULL;
   s->on_accept_cb_arg = NULL;
-  s->ports = gpr_malloc(sizeof(server_port) * INIT_PORT_CAP);
+  s->head = NULL;
   s->nports = 0;
-  s->port_capacity = INIT_PORT_CAP;
   return s;
 }
 
@@ -145,7 +151,12 @@
 
   gpr_mu_destroy(&s->mu);
 
-  gpr_free(s->ports);
+  while (s->head) {
+    grpc_tcp_listener *sp = s->head;
+    s->head = sp->next;
+    grpc_tcp_listener_unref(sp);
+  }
+
   gpr_free(s);
 }
 
@@ -166,8 +177,6 @@
    events will be received on them - at this point it's safe to destroy
    things */
 static void deactivated_all_ports(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s) {
-  size_t i;
-
   /* delete ALL the things */
   gpr_mu_lock(&s->mu);
 
@@ -176,9 +185,9 @@
     return;
   }
 
-  if (s->nports) {
-    for (i = 0; i < s->nports; i++) {
-      server_port *sp = &s->ports[i];
+  if (s->head) {
+    grpc_tcp_listener *sp;
+    for (sp = s->head; sp; sp = sp->next) {
       if (sp->addr.sockaddr.sa_family == AF_UNIX) {
         unlink_if_unix_domain_socket(&sp->addr.un);
       }
@@ -196,7 +205,6 @@
 
 void grpc_tcp_server_destroy(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s,
                              grpc_closure *closure) {
-  size_t i;
   gpr_mu_lock(&s->mu);
 
   GPR_ASSERT(!s->shutdown);
@@ -206,8 +214,9 @@
 
   /* shutdown all fd's */
   if (s->active_ports) {
-    for (i = 0; i < s->nports; i++) {
-      grpc_fd_shutdown(exec_ctx, s->ports[i].emfd);
+    grpc_tcp_listener *sp;
+    for (sp = s->head; sp; sp = sp->next) {
+      grpc_fd_shutdown(exec_ctx, sp->emfd);
     }
     gpr_mu_unlock(&s->mu);
   } else {
@@ -298,7 +307,7 @@
 
 /* event manager callback when reads are ready */
 static void on_read(grpc_exec_ctx *exec_ctx, void *arg, int success) {
-  server_port *sp = arg;
+  grpc_tcp_listener *sp = arg;
   grpc_fd *fdobj;
   size_t i;
 
@@ -364,9 +373,10 @@
   }
 }
 
-static int add_socket_to_server(grpc_tcp_server *s, int fd,
-                                const struct sockaddr *addr, size_t addr_len) {
-  server_port *sp;
+static grpc_tcp_listener *add_socket_to_server(grpc_tcp_server *s, int fd,
+                                         const struct sockaddr *addr,
+                                         size_t addr_len) {
+  grpc_tcp_listener *sp = NULL;
   int port;
   char *addr_str;
   char *name;
@@ -376,32 +386,35 @@
     grpc_sockaddr_to_string(&addr_str, (struct sockaddr *)&addr, 1);
     gpr_asprintf(&name, "tcp-server-listener:%s", addr_str);
     gpr_mu_lock(&s->mu);
+    s->nports++;
     GPR_ASSERT(!s->on_accept_cb && "must add ports before starting server");
-    /* append it to the list under a lock */
-    if (s->nports == s->port_capacity) {
-      s->port_capacity *= 2;
-      s->ports = gpr_realloc(s->ports, sizeof(server_port) * s->port_capacity);
-    }
-    sp = &s->ports[s->nports++];
+    sp = gpr_malloc(sizeof(grpc_tcp_listener));
+    sp->next = s->head;
+    s->head = sp;
     sp->server = s;
     sp->fd = fd;
     sp->emfd = grpc_fd_create(fd, name);
     memcpy(sp->addr.untyped, addr, addr_len);
     sp->addr_len = addr_len;
+    sp->port = port;
+    sp->is_sibling = 0;
+    sp->sibling = NULL;
+    gpr_ref_init(&sp->refs, 1);
     GPR_ASSERT(sp->emfd);
     gpr_mu_unlock(&s->mu);
     gpr_free(addr_str);
     gpr_free(name);
   }
 
-  return port;
+  return sp;
 }
 
-int grpc_tcp_server_add_port(grpc_tcp_server *s, const void *addr,
-                             size_t addr_len) {
-  int allocated_port1 = -1;
-  int allocated_port2 = -1;
-  unsigned i;
+grpc_tcp_listener *grpc_tcp_server_add_port(grpc_tcp_server *s,
+                                            const void *addr,
+                                            size_t addr_len) {
+  int allocated_port = -1;
+  grpc_tcp_listener *sp;
+  grpc_tcp_listener *sp2 = NULL;
   int fd;
   grpc_dualstack_mode dsmode;
   struct sockaddr_in6 addr6_v4mapped;
@@ -420,9 +433,9 @@
   /* Check if this is a wildcard port, and if so, try to keep the port the same
      as some previously created listener. */
   if (grpc_sockaddr_get_port(addr) == 0) {
-    for (i = 0; i < s->nports; i++) {
+    for (sp = s->head; sp; sp = sp->next) {
       sockname_len = sizeof(sockname_temp);
-      if (0 == getsockname(s->ports[i].fd, (struct sockaddr *)&sockname_temp,
+      if (0 == getsockname(sp->fd, (struct sockaddr *)&sockname_temp,
                            &sockname_len)) {
         port = grpc_sockaddr_get_port((struct sockaddr *)&sockname_temp);
         if (port > 0) {
@@ -436,6 +449,8 @@
     }
   }
 
+  sp = NULL;
+
   if (grpc_sockaddr_to_v4mapped(addr, &addr6_v4mapped)) {
     addr = (const struct sockaddr *)&addr6_v4mapped;
     addr_len = sizeof(addr6_v4mapped);
@@ -449,14 +464,16 @@
     addr = (struct sockaddr *)&wild6;
     addr_len = sizeof(wild6);
     fd = grpc_create_dualstack_socket(addr, SOCK_STREAM, 0, &dsmode);
-    allocated_port1 = add_socket_to_server(s, fd, addr, addr_len);
+    sp = add_socket_to_server(s, fd, addr, addr_len);
+    allocated_port = sp->port;
     if (fd >= 0 && dsmode == GRPC_DSMODE_DUALSTACK) {
       goto done;
     }
 
     /* If we didn't get a dualstack socket, also listen on 0.0.0.0. */
-    if (port == 0 && allocated_port1 > 0) {
-      grpc_sockaddr_set_port((struct sockaddr *)&wild4, allocated_port1);
+    if (port == 0 && allocated_port > 0) {
+      grpc_sockaddr_set_port((struct sockaddr *)&wild4, allocated_port);
+      sp2 = sp;
     }
     addr = (struct sockaddr *)&wild4;
     addr_len = sizeof(wild4);
@@ -471,22 +488,31 @@
     addr = (struct sockaddr *)&addr4_copy;
     addr_len = sizeof(addr4_copy);
   }
-  allocated_port2 = add_socket_to_server(s, fd, addr, addr_len);
+  sp = add_socket_to_server(s, fd, addr, addr_len);
+  sp->sibling = sp2;
+  if (sp2) sp2->is_sibling = 1;
 
 done:
   gpr_free(allocated_addr);
-  return allocated_port1 >= 0 ? allocated_port1 : allocated_port2;
+  return sp;
 }
 
 int grpc_tcp_server_get_fd(grpc_tcp_server *s, unsigned port_index) {
-  return (port_index < s->nports) ? s->ports[port_index].fd : -1;
+  grpc_tcp_listener *sp;
+  for (sp = s->head; sp && port_index != 0; sp = sp->next, port_index--);
+  if (port_index == 0 && sp) {
+    return sp->fd;
+  } else {
+    return -1;
+  }
 }
 
 void grpc_tcp_server_start(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s,
                            grpc_pollset **pollsets, size_t pollset_count,
                            grpc_tcp_server_cb on_accept_cb,
                            void *on_accept_cb_arg) {
-  size_t i, j;
+  size_t i;
+  grpc_tcp_listener *sp;
   GPR_ASSERT(on_accept_cb);
   gpr_mu_lock(&s->mu);
   GPR_ASSERT(!s->on_accept_cb);
@@ -495,17 +521,41 @@
   s->on_accept_cb_arg = on_accept_cb_arg;
   s->pollsets = pollsets;
   s->pollset_count = pollset_count;
-  for (i = 0; i < s->nports; i++) {
-    for (j = 0; j < pollset_count; j++) {
-      grpc_pollset_add_fd(exec_ctx, pollsets[j], s->ports[i].emfd);
+  for (sp = s->head; sp; sp = sp->next) {
+    for (i = 0; i < pollset_count; i++) {
+      grpc_pollset_add_fd(exec_ctx, pollsets[i], sp->emfd);
     }
-    s->ports[i].read_closure.cb = on_read;
-    s->ports[i].read_closure.cb_arg = &s->ports[i];
-    grpc_fd_notify_on_read(exec_ctx, s->ports[i].emfd,
-                           &s->ports[i].read_closure);
+    sp->read_closure.cb = on_read;
+    sp->read_closure.cb_arg = sp;
+    grpc_fd_notify_on_read(exec_ctx, sp->emfd,
+                           &sp->read_closure);
     s->active_ports++;
   }
   gpr_mu_unlock(&s->mu);
 }
 
+int grpc_tcp_listener_get_port(grpc_tcp_listener *listener) {
+  grpc_tcp_listener *sp = listener;
+  return sp->port;
+}
+
+void grpc_tcp_listener_ref(grpc_tcp_listener *listener) {
+  grpc_tcp_listener *sp = listener;
+  gpr_ref(&sp->refs);
+}
+
+void grpc_tcp_listener_unref(grpc_tcp_listener *listener) {
+  grpc_tcp_listener *sp = listener;
+  if (sp->is_sibling) return;
+  if (gpr_unref(&sp->refs)) {
+    grpc_tcp_listener *sibling = sp->sibling;
+    while (sibling) {
+      sp = sibling;
+      sibling = sp->sibling;
+      gpr_free(sp);
+    }
+    gpr_free(listener);
+  }
+}
+
 #endif
diff --git a/src/core/iomgr/tcp_server_windows.c b/src/core/iomgr/tcp_server_windows.c
index 3fea8b5..e4a1d7f 100644
--- a/src/core/iomgr/tcp_server_windows.c
+++ b/src/core/iomgr/tcp_server_windows.c
@@ -35,7 +35,8 @@
 
 #ifdef GPR_WINSOCK_SOCKET
 
-#define _GNU_SOURCE
+#include <io.h>
+
 #include "src/core/iomgr/sockaddr_utils.h"
 
 #include <grpc/support/alloc.h>
@@ -51,25 +52,29 @@
 #include "src/core/iomgr/tcp_server.h"
 #include "src/core/iomgr/tcp_windows.h"
 
-#define INIT_PORT_CAP 2
 #define MIN_SAFE_ACCEPT_QUEUE_SIZE 100
 
 /* one listening port */
-typedef struct server_port {
+struct grpc_tcp_listener {
   /* This seemingly magic number comes from AcceptEx's documentation. each
      address buffer needs to have at least 16 more bytes at their end. */
   gpr_uint8 addresses[(sizeof(struct sockaddr_in6) + 16) * 2];
   /* This will hold the socket for the next accept. */
   SOCKET new_socket;
-  /* The listener winsocked. */
+  /* The listener winsocket. */
   grpc_winsocket *socket;
+  /* The actual TCP port number. */
+  int port;
   grpc_tcp_server *server;
   /* The cached AcceptEx for that port. */
   LPFN_ACCEPTEX AcceptEx;
   int shutting_down;
   /* closure for socket notification of accept being ready */
   grpc_closure on_accept;
-} server_port;
+  gpr_refcount refs;
+  /* linked list */
+  struct grpc_tcp_listener *next;
+};
 
 /* the overall server */
 struct grpc_tcp_server {
@@ -82,10 +87,8 @@
   /* active port count: how many ports are actually still listening */
   int active_ports;
 
-  /* all listening ports */
-  server_port *ports;
-  size_t nports;
-  size_t port_capacity;
+  /* linked list of server ports */
+  grpc_tcp_listener *head;
 
   /* shutdown callback */
   grpc_closure *shutdown_complete;
@@ -99,9 +102,7 @@
   s->active_ports = 0;
   s->on_accept_cb = NULL;
   s->on_accept_cb_arg = NULL;
-  s->ports = gpr_malloc(sizeof(server_port) * INIT_PORT_CAP);
-  s->nports = 0;
-  s->port_capacity = INIT_PORT_CAP;
+  s->head = NULL;
   s->shutdown_complete = NULL;
   return s;
 }
@@ -109,26 +110,26 @@
 static void dont_care_about_shutdown_completion(void *arg) {}
 
 static void finish_shutdown(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s) {
-  size_t i;
-
   grpc_exec_ctx_enqueue(exec_ctx, s->shutdown_complete, 1);
 
   /* Now that the accepts have been aborted, we can destroy the sockets.
      The IOCP won't get notified on these, so we can flag them as already
      closed by the system. */
-  for (i = 0; i < s->nports; i++) {
-    server_port *sp = &s->ports[i];
+  while (s->head) {
+    grpc_tcp_listener *sp = s->head;
+    s->head = sp->next;
+    sp->next = NULL;
     grpc_winsocket_destroy(sp->socket);
+    grpc_tcp_listener_unref(sp);
   }
-  gpr_free(s->ports);
   gpr_free(s);
 }
 
 /* Public function. Stops and destroys a grpc_tcp_server. */
 void grpc_tcp_server_destroy(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s,
                              grpc_closure *shutdown_complete) {
-  size_t i;
   int immediately_done = 0;
+  grpc_tcp_listener *sp;
   gpr_mu_lock(&s->mu);
 
   s->shutdown_complete = shutdown_complete;
@@ -138,8 +139,7 @@
   if (s->active_ports == 0) {
     immediately_done = 1;
   }
-  for (i = 0; i < s->nports; i++) {
-    server_port *sp = &s->ports[i];
+  for (sp = s->head; sp; sp = sp->next) {
     sp->shutting_down = 1;
     grpc_winsocket_shutdown(sp->socket);
   }
@@ -199,7 +199,7 @@
 }
 
 static void decrement_active_ports_and_notify(grpc_exec_ctx *exec_ctx,
-                                              server_port *sp) {
+                                              grpc_tcp_listener *sp) {
   int notify = 0;
   sp->shutting_down = 0;
   gpr_mu_lock(&sp->server->mu);
@@ -216,7 +216,7 @@
 
 /* In order to do an async accept, we need to create a socket first which
    will be the one assigned to the new incoming connection. */
-static void start_accept(grpc_exec_ctx *exec_ctx, server_port *port) {
+static void start_accept(grpc_exec_ctx *exec_ctx, grpc_tcp_listener *port) {
   SOCKET sock = INVALID_SOCKET;
   char *message;
   char *utf8_message;
@@ -276,7 +276,7 @@
 
 /* Event manager callback when reads are ready. */
 static void on_accept(grpc_exec_ctx *exec_ctx, void *arg, int from_iocp) {
-  server_port *sp = arg;
+  grpc_tcp_listener *sp = arg;
   SOCKET sock = sp->new_socket;
   grpc_winsocket_callback_info *info = &sp->socket->read_info;
   grpc_endpoint *ep = NULL;
@@ -351,16 +351,17 @@
   start_accept(exec_ctx, sp);
 }
 
-static int add_socket_to_server(grpc_tcp_server *s, SOCKET sock,
-                                const struct sockaddr *addr, size_t addr_len) {
-  server_port *sp;
+static grpc_tcp_listener *add_socket_to_server(grpc_tcp_server *s, SOCKET sock,
+                                         const struct sockaddr *addr,
+                                         size_t addr_len) {
+  grpc_tcp_listener *sp = NULL;
   int port;
   int status;
   GUID guid = WSAID_ACCEPTEX;
   DWORD ioctl_num_bytes;
   LPFN_ACCEPTEX AcceptEx;
 
-  if (sock == INVALID_SOCKET) return -1;
+  if (sock == INVALID_SOCKET) return NULL;
 
   /* We need to grab the AcceptEx pointer for that port, as it may be
      interface-dependent. We'll cache it to avoid doing that again. */
@@ -373,37 +374,35 @@
     gpr_log(GPR_ERROR, "on_connect error: %s", utf8_message);
     gpr_free(utf8_message);
     closesocket(sock);
-    return -1;
+    return NULL;
   }
 
   port = prepare_socket(sock, addr, addr_len);
   if (port >= 0) {
     gpr_mu_lock(&s->mu);
     GPR_ASSERT(!s->on_accept_cb && "must add ports before starting server");
-    /* append it to the list under a lock */
-    if (s->nports == s->port_capacity) {
-      /* too many ports, and we need to store their address in a closure */
-      /* TODO(ctiller): make server_port a linked list */
-      abort();
-    }
-    sp = &s->ports[s->nports++];
+    sp = gpr_malloc(sizeof(grpc_tcp_listener));
+    sp->next = s->head;
+    s->head = sp;
     sp->server = s;
     sp->socket = grpc_winsocket_create(sock, "listener");
     sp->shutting_down = 0;
     sp->AcceptEx = AcceptEx;
     sp->new_socket = INVALID_SOCKET;
+    sp->port = port;
+    gpr_ref_init(&sp->refs, 1);
     grpc_closure_init(&sp->on_accept, on_accept, sp);
     GPR_ASSERT(sp->socket);
     gpr_mu_unlock(&s->mu);
   }
 
-  return port;
+  return sp;
 }
 
-int grpc_tcp_server_add_port(grpc_tcp_server *s, const void *addr,
-                             size_t addr_len) {
-  int allocated_port = -1;
-  unsigned i;
+grpc_tcp_listener *grpc_tcp_server_add_port(grpc_tcp_server *s,
+                                            const void *addr,
+                                            size_t addr_len) {
+  grpc_tcp_listener *sp;
   SOCKET sock;
   struct sockaddr_in6 addr6_v4mapped;
   struct sockaddr_in6 wildcard;
@@ -415,9 +414,9 @@
   /* Check if this is a wildcard port, and if so, try to keep the port the same
      as some previously created listener. */
   if (grpc_sockaddr_get_port(addr) == 0) {
-    for (i = 0; i < s->nports; i++) {
+    for (sp = s->head; sp; sp = sp->next) {
       sockname_len = sizeof(sockname_temp);
-      if (0 == getsockname(s->ports[i].socket->socket,
+      if (0 == getsockname(sp->socket->socket,
                            (struct sockaddr *)&sockname_temp, &sockname_len)) {
         port = grpc_sockaddr_get_port((struct sockaddr *)&sockname_temp);
         if (port > 0) {
@@ -452,33 +451,55 @@
     gpr_free(utf8_message);
   }
 
-  allocated_port = add_socket_to_server(s, sock, addr, addr_len);
+  sp = add_socket_to_server(s, sock, addr, addr_len);
   gpr_free(allocated_addr);
 
-  return allocated_port;
+  return sp;
 }
 
-SOCKET
-grpc_tcp_server_get_socket(grpc_tcp_server *s, unsigned index) {
-  return (index < s->nports) ? s->ports[index].socket->socket : INVALID_SOCKET;
+int grpc_tcp_server_get_fd(grpc_tcp_server *s, unsigned port_index) {
+  grpc_tcp_listener *sp;
+  for (sp = s->head; sp && port_index != 0; sp = sp->next, port_index--);
+  if (port_index == 0 && sp) {
+    return _open_osfhandle(sp->socket->socket, 0);
+  } else {
+    return -1;
+  }
 }
 
 void grpc_tcp_server_start(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s,
                            grpc_pollset **pollset, size_t pollset_count,
                            grpc_tcp_server_cb on_accept_cb,
                            void *on_accept_cb_arg) {
-  size_t i;
+  grpc_tcp_listener *sp;
   GPR_ASSERT(on_accept_cb);
   gpr_mu_lock(&s->mu);
   GPR_ASSERT(!s->on_accept_cb);
   GPR_ASSERT(s->active_ports == 0);
   s->on_accept_cb = on_accept_cb;
   s->on_accept_cb_arg = on_accept_cb_arg;
-  for (i = 0; i < s->nports; i++) {
-    start_accept(exec_ctx, s->ports + i);
+  for (sp = s->head; sp; sp = sp->next) {
+    start_accept(exec_ctx, sp);
     s->active_ports++;
   }
   gpr_mu_unlock(&s->mu);
 }
 
+int grpc_tcp_listener_get_port(grpc_tcp_listener *listener) {
+  grpc_tcp_listener *sp = listener;
+  return sp->port;
+}
+
+void grpc_tcp_listener_ref(grpc_tcp_listener *listener) {
+  grpc_tcp_listener *sp = listener;
+  gpr_ref(&sp->refs);
+}
+
+void grpc_tcp_listener_unref(grpc_tcp_listener *listener) {
+  grpc_tcp_listener *sp = listener;
+  if (gpr_unref(&sp->refs)) {
+    gpr_free(listener);
+  }
+}
+
 #endif /* GPR_WINSOCK_SOCKET */
diff --git a/src/core/security/client_auth_filter.c b/src/core/security/client_auth_filter.c
index c780b65..be2522a 100644
--- a/src/core/security/client_auth_filter.c
+++ b/src/core/security/client_auth_filter.c
@@ -50,7 +50,7 @@
 
 /* We can have a per-call credentials. */
 typedef struct {
-  grpc_credentials *creds;
+  grpc_call_credentials *creds;
   grpc_mdstr *host;
   grpc_mdstr *method;
   /* pollset bound to this call; if we need to make external
@@ -143,39 +143,35 @@
   channel_data *chand = elem->channel_data;
   grpc_client_security_context *ctx =
       (grpc_client_security_context *)op->context[GRPC_CONTEXT_SECURITY].value;
-  grpc_credentials *channel_creds =
+  grpc_call_credentials *channel_call_creds =
       chand->security_connector->request_metadata_creds;
-  int channel_creds_has_md =
-      (channel_creds != NULL) &&
-      grpc_credentials_has_request_metadata(channel_creds);
-  int call_creds_has_md = (ctx != NULL) && (ctx->creds != NULL) &&
-                          grpc_credentials_has_request_metadata(ctx->creds);
+  int call_creds_has_md = (ctx != NULL) && (ctx->creds != NULL);
 
-  if (!channel_creds_has_md && !call_creds_has_md) {
+  if (channel_call_creds == NULL && !call_creds_has_md) {
     /* Skip sending metadata altogether. */
     grpc_call_next_op(exec_ctx, elem, op);
     return;
   }
 
-  if (channel_creds_has_md && call_creds_has_md) {
-    calld->creds =
-        grpc_composite_credentials_create(channel_creds, ctx->creds, NULL);
+  if (channel_call_creds != NULL && call_creds_has_md) {
+    calld->creds = grpc_composite_call_credentials_create(channel_call_creds,
+                                                          ctx->creds, NULL);
     if (calld->creds == NULL) {
       bubble_up_error(exec_ctx, elem, GRPC_STATUS_INVALID_ARGUMENT,
                       "Incompatible credentials set on channel and call.");
       return;
     }
   } else {
-    calld->creds =
-        grpc_credentials_ref(call_creds_has_md ? ctx->creds : channel_creds);
+    calld->creds = grpc_call_credentials_ref(
+        call_creds_has_md ? ctx->creds : channel_call_creds);
   }
 
   build_service_url(chand->security_connector->base.url_scheme, calld);
   calld->op = *op; /* Copy op (originates from the caller's stack). */
   GPR_ASSERT(calld->pollset);
-  grpc_credentials_get_request_metadata(exec_ctx, calld->creds, calld->pollset,
-                                        calld->service_url,
-                                        on_credentials_metadata, elem);
+  grpc_call_credentials_get_request_metadata(exec_ctx, calld->creds,
+                                             calld->pollset, calld->service_url,
+                                             on_credentials_metadata, elem);
 }
 
 static void on_host_checked(grpc_exec_ctx *exec_ctx, void *user_data,
@@ -282,7 +278,7 @@
 static void destroy_call_elem(grpc_exec_ctx *exec_ctx,
                               grpc_call_element *elem) {
   call_data *calld = elem->call_data;
-  grpc_credentials_unref(calld->creds);
+  grpc_call_credentials_unref(calld->creds);
   if (calld->host != NULL) {
     GRPC_MDSTR_UNREF(calld->host);
   }
diff --git a/src/core/security/credentials.c b/src/core/security/credentials.c
index 2a8ffae..f7a2e73 100644
--- a/src/core/security/credentials.c
+++ b/src/core/security/credentials.c
@@ -54,18 +54,18 @@
 /* -- Common. -- */
 
 struct grpc_credentials_metadata_request {
-  grpc_credentials *creds;
+  grpc_call_credentials *creds;
   grpc_credentials_metadata_cb cb;
   void *user_data;
 };
 
 static grpc_credentials_metadata_request *
-grpc_credentials_metadata_request_create(grpc_credentials *creds,
+grpc_credentials_metadata_request_create(grpc_call_credentials *creds,
                                          grpc_credentials_metadata_cb cb,
                                          void *user_data) {
   grpc_credentials_metadata_request *r =
       gpr_malloc(sizeof(grpc_credentials_metadata_request));
-  r->creds = grpc_credentials_ref(creds);
+  r->creds = grpc_call_credentials_ref(creds);
   r->cb = cb;
   r->user_data = user_data;
   return r;
@@ -73,44 +73,56 @@
 
 static void grpc_credentials_metadata_request_destroy(
     grpc_credentials_metadata_request *r) {
-  grpc_credentials_unref(r->creds);
+  grpc_call_credentials_unref(r->creds);
   gpr_free(r);
 }
 
-grpc_credentials *grpc_credentials_ref(grpc_credentials *creds) {
+grpc_channel_credentials *grpc_channel_credentials_ref(
+    grpc_channel_credentials *creds) {
   if (creds == NULL) return NULL;
   gpr_ref(&creds->refcount);
   return creds;
 }
 
-void grpc_credentials_unref(grpc_credentials *creds) {
+void grpc_channel_credentials_unref(grpc_channel_credentials *creds) {
   if (creds == NULL) return;
   if (gpr_unref(&creds->refcount)) {
-    creds->vtable->destruct(creds);
+    if (creds->vtable->destruct != NULL) creds->vtable->destruct(creds);
     gpr_free(creds);
   }
 }
 
-void grpc_credentials_release(grpc_credentials *creds) {
-  GRPC_API_TRACE("grpc_credentials_release(creds=%p)", 1, (creds));
-  grpc_credentials_unref(creds);
+void grpc_channel_credentials_release(grpc_channel_credentials *creds) {
+  GRPC_API_TRACE("grpc_channel_credentials_release(creds=%p)", 1, (creds));
+  grpc_channel_credentials_unref(creds);
 }
 
-int grpc_credentials_has_request_metadata(grpc_credentials *creds) {
-  if (creds == NULL) return 0;
-  return creds->vtable->has_request_metadata(creds);
+grpc_call_credentials *grpc_call_credentials_ref(grpc_call_credentials *creds) {
+  if (creds == NULL) return NULL;
+  gpr_ref(&creds->refcount);
+  return creds;
 }
 
-int grpc_credentials_has_request_metadata_only(grpc_credentials *creds) {
-  if (creds == NULL) return 0;
-  return creds->vtable->has_request_metadata_only(creds);
+void grpc_call_credentials_unref(grpc_call_credentials *creds) {
+  if (creds == NULL) return;
+  if (gpr_unref(&creds->refcount)) {
+    if (creds->vtable->destruct != NULL) creds->vtable->destruct(creds);
+    gpr_free(creds);
+  }
 }
 
-void grpc_credentials_get_request_metadata(
-    grpc_exec_ctx *exec_ctx, grpc_credentials *creds, grpc_pollset *pollset,
-    const char *service_url, grpc_credentials_metadata_cb cb, void *user_data) {
-  if (creds == NULL || !grpc_credentials_has_request_metadata(creds) ||
-      creds->vtable->get_request_metadata == NULL) {
+void grpc_call_credentials_release(grpc_call_credentials *creds) {
+  GRPC_API_TRACE("grpc_call_credentials_release(creds=%p)", 1, (creds));
+  grpc_call_credentials_unref(creds);
+}
+
+void grpc_call_credentials_get_request_metadata(grpc_exec_ctx *exec_ctx,
+                                                grpc_call_credentials *creds,
+                                                grpc_pollset *pollset,
+                                                const char *service_url,
+                                                grpc_credentials_metadata_cb cb,
+                                                void *user_data) {
+  if (creds == NULL || creds->vtable->get_request_metadata == NULL) {
     if (cb != NULL) {
       cb(exec_ctx, user_data, NULL, 0, GRPC_CREDENTIALS_OK);
     }
@@ -120,19 +132,17 @@
                                       user_data);
 }
 
-grpc_security_status grpc_credentials_create_security_connector(
-    grpc_credentials *creds, const char *target, const grpc_channel_args *args,
-    grpc_credentials *request_metadata_creds,
-    grpc_channel_security_connector **sc, grpc_channel_args **new_args) {
+grpc_security_status grpc_channel_credentials_create_security_connector(
+    grpc_channel_credentials *channel_creds, const char *target,
+    const grpc_channel_args *args, grpc_channel_security_connector **sc,
+    grpc_channel_args **new_args) {
   *new_args = NULL;
-  if (creds == NULL || creds->vtable->create_security_connector == NULL ||
-      grpc_credentials_has_request_metadata_only(creds)) {
-    gpr_log(GPR_ERROR,
-            "Invalid credentials for creating a security connector.");
+  if (channel_creds == NULL) {
     return GRPC_SECURITY_ERROR;
   }
-  return creds->vtable->create_security_connector(
-      creds, target, args, request_metadata_creds, sc, new_args);
+  GPR_ASSERT(channel_creds->vtable->create_security_connector != NULL);
+  return channel_creds->vtable->create_security_connector(
+      channel_creds, NULL, target, args, sc, new_args);
 }
 
 grpc_server_credentials *grpc_server_credentials_ref(
@@ -145,7 +155,7 @@
 void grpc_server_credentials_unref(grpc_server_credentials *creds) {
   if (creds == NULL) return;
   if (gpr_unref(&creds->refcount)) {
-    creds->vtable->destruct(creds);
+    if (creds->vtable->destruct != NULL) creds->vtable->destruct(creds);
     if (creds->processor.destroy != NULL && creds->processor.state != NULL) {
       creds->processor.destroy(creds->processor.state);
     }
@@ -224,7 +234,7 @@
 
 /* -- Ssl credentials. -- */
 
-static void ssl_destruct(grpc_credentials *creds) {
+static void ssl_destruct(grpc_channel_credentials *creds) {
   grpc_ssl_credentials *c = (grpc_ssl_credentials *)creds;
   if (c->config.pem_root_certs != NULL) gpr_free(c->config.pem_root_certs);
   if (c->config.pem_private_key != NULL) gpr_free(c->config.pem_private_key);
@@ -253,15 +263,9 @@
   if (c->config.pem_root_certs != NULL) gpr_free(c->config.pem_root_certs);
 }
 
-static int ssl_has_request_metadata(const grpc_credentials *creds) { return 0; }
-
-static int ssl_has_request_metadata_only(const grpc_credentials *creds) {
-  return 0;
-}
-
 static grpc_security_status ssl_create_security_connector(
-    grpc_credentials *creds, const char *target, const grpc_channel_args *args,
-    grpc_credentials *request_metadata_creds,
+    grpc_channel_credentials *creds, grpc_call_credentials *call_creds,
+    const char *target, const grpc_channel_args *args,
     grpc_channel_security_connector **sc, grpc_channel_args **new_args) {
   grpc_ssl_credentials *c = (grpc_ssl_credentials *)creds;
   grpc_security_status status = GRPC_SECURITY_OK;
@@ -278,7 +282,7 @@
     }
   }
   status = grpc_ssl_channel_security_connector_create(
-      request_metadata_creds, &c->config, target, overridden_target_name, sc);
+      call_creds, &c->config, target, overridden_target_name, sc);
   if (status != GRPC_SECURITY_OK) {
     return status;
   }
@@ -295,9 +299,8 @@
   return grpc_ssl_server_security_connector_create(&c->config, sc);
 }
 
-static grpc_credentials_vtable ssl_vtable = {
-    ssl_destruct, ssl_has_request_metadata, ssl_has_request_metadata_only, NULL,
-    ssl_create_security_connector};
+static grpc_channel_credentials_vtable ssl_vtable = {
+    ssl_destruct, ssl_create_security_connector};
 
 static grpc_server_credentials_vtable ssl_server_vtable = {
     ssl_server_destruct, ssl_server_create_security_connector};
@@ -362,7 +365,7 @@
   }
 }
 
-grpc_credentials *grpc_ssl_credentials_create(
+grpc_channel_credentials *grpc_ssl_credentials_create(
     const char *pem_root_certs, grpc_ssl_pem_key_cert_pair *pem_key_cert_pair,
     void *reserved) {
   grpc_ssl_credentials *c = gpr_malloc(sizeof(grpc_ssl_credentials));
@@ -373,7 +376,7 @@
       3, (pem_root_certs, pem_key_cert_pair, reserved));
   GPR_ASSERT(reserved == NULL);
   memset(c, 0, sizeof(grpc_ssl_credentials));
-  c->base.type = GRPC_CREDENTIALS_TYPE_SSL;
+  c->base.type = GRPC_CHANNEL_CREDENTIALS_TYPE_SSL;
   c->base.vtable = &ssl_vtable;
   gpr_ref_init(&c->base.refcount, 1);
   ssl_build_config(pem_root_certs, pem_key_cert_pair, &c->config);
@@ -393,7 +396,7 @@
           force_client_auth, reserved));
   GPR_ASSERT(reserved == NULL);
   memset(c, 0, sizeof(grpc_ssl_server_credentials));
-  c->base.type = GRPC_CREDENTIALS_TYPE_SSL;
+  c->base.type = GRPC_CHANNEL_CREDENTIALS_TYPE_SSL;
   gpr_ref_init(&c->base.refcount, 1);
   c->base.vtable = &ssl_server_vtable;
   ssl_build_server_config(pem_root_certs, pem_key_cert_pairs,
@@ -415,7 +418,7 @@
   c->cached.jwt_expiration = gpr_inf_past(GPR_CLOCK_REALTIME);
 }
 
-static void jwt_destruct(grpc_credentials *creds) {
+static void jwt_destruct(grpc_call_credentials *creds) {
   grpc_service_account_jwt_access_credentials *c =
       (grpc_service_account_jwt_access_credentials *)creds;
   grpc_auth_json_key_destruct(&c->key);
@@ -423,15 +426,12 @@
   gpr_mu_destroy(&c->cache_mu);
 }
 
-static int jwt_has_request_metadata(const grpc_credentials *creds) { return 1; }
-
-static int jwt_has_request_metadata_only(const grpc_credentials *creds) {
-  return 1;
-}
-
-static void jwt_get_request_metadata(
-    grpc_exec_ctx *exec_ctx, grpc_credentials *creds, grpc_pollset *pollset,
-    const char *service_url, grpc_credentials_metadata_cb cb, void *user_data) {
+static void jwt_get_request_metadata(grpc_exec_ctx *exec_ctx,
+                                     grpc_call_credentials *creds,
+                                     grpc_pollset *pollset,
+                                     const char *service_url,
+                                     grpc_credentials_metadata_cb cb,
+                                     void *user_data) {
   grpc_service_account_jwt_access_credentials *c =
       (grpc_service_account_jwt_access_credentials *)creds;
   gpr_timespec refresh_threshold = gpr_time_from_seconds(
@@ -483,11 +483,10 @@
   }
 }
 
-static grpc_credentials_vtable jwt_vtable = {
-    jwt_destruct, jwt_has_request_metadata, jwt_has_request_metadata_only,
-    jwt_get_request_metadata, NULL};
+static grpc_call_credentials_vtable jwt_vtable = {jwt_destruct,
+                                                  jwt_get_request_metadata};
 
-grpc_credentials *
+grpc_call_credentials *
 grpc_service_account_jwt_access_credentials_create_from_auth_json_key(
     grpc_auth_json_key key, gpr_timespec token_lifetime) {
   grpc_service_account_jwt_access_credentials *c;
@@ -497,7 +496,7 @@
   }
   c = gpr_malloc(sizeof(grpc_service_account_jwt_access_credentials));
   memset(c, 0, sizeof(grpc_service_account_jwt_access_credentials));
-  c->base.type = GRPC_CREDENTIALS_TYPE_JWT;
+  c->base.type = GRPC_CALL_CREDENTIALS_TYPE_JWT;
   gpr_ref_init(&c->base.refcount, 1);
   c->base.vtable = &jwt_vtable;
   c->key = key;
@@ -507,7 +506,7 @@
   return &c->base;
 }
 
-grpc_credentials *grpc_service_account_jwt_access_credentials_create(
+grpc_call_credentials *grpc_service_account_jwt_access_credentials_create(
     const char *json_key, gpr_timespec token_lifetime, void *reserved) {
   GRPC_API_TRACE(
       "grpc_service_account_jwt_access_credentials_create("
@@ -524,7 +523,7 @@
 
 /* -- Oauth2TokenFetcher credentials -- */
 
-static void oauth2_token_fetcher_destruct(grpc_credentials *creds) {
+static void oauth2_token_fetcher_destruct(grpc_call_credentials *creds) {
   grpc_oauth2_token_fetcher_credentials *c =
       (grpc_oauth2_token_fetcher_credentials *)creds;
   grpc_credentials_md_store_unref(c->access_token_md);
@@ -532,16 +531,6 @@
   grpc_httpcli_context_destroy(&c->httpcli_context);
 }
 
-static int oauth2_token_fetcher_has_request_metadata(
-    const grpc_credentials *creds) {
-  return 1;
-}
-
-static int oauth2_token_fetcher_has_request_metadata_only(
-    const grpc_credentials *creds) {
-  return 1;
-}
-
 grpc_credentials_status
 grpc_oauth2_token_fetcher_credentials_parse_server_response(
     const grpc_httpcli_response *response, grpc_credentials_md_store **token_md,
@@ -659,8 +648,9 @@
 }
 
 static void oauth2_token_fetcher_get_request_metadata(
-    grpc_exec_ctx *exec_ctx, grpc_credentials *creds, grpc_pollset *pollset,
-    const char *service_url, grpc_credentials_metadata_cb cb, void *user_data) {
+    grpc_exec_ctx *exec_ctx, grpc_call_credentials *creds,
+    grpc_pollset *pollset, const char *service_url,
+    grpc_credentials_metadata_cb cb, void *user_data) {
   grpc_oauth2_token_fetcher_credentials *c =
       (grpc_oauth2_token_fetcher_credentials *)creds;
   gpr_timespec refresh_threshold = gpr_time_from_seconds(
@@ -693,7 +683,7 @@
 static void init_oauth2_token_fetcher(grpc_oauth2_token_fetcher_credentials *c,
                                       grpc_fetch_oauth2_func fetch_func) {
   memset(c, 0, sizeof(grpc_oauth2_token_fetcher_credentials));
-  c->base.type = GRPC_CREDENTIALS_TYPE_OAUTH2;
+  c->base.type = GRPC_CALL_CREDENTIALS_TYPE_OAUTH2;
   gpr_ref_init(&c->base.refcount, 1);
   gpr_mu_init(&c->mu);
   c->token_expiration = gpr_inf_past(GPR_CLOCK_REALTIME);
@@ -703,10 +693,8 @@
 
 /* -- GoogleComputeEngine credentials. -- */
 
-static grpc_credentials_vtable compute_engine_vtable = {
-    oauth2_token_fetcher_destruct, oauth2_token_fetcher_has_request_metadata,
-    oauth2_token_fetcher_has_request_metadata_only,
-    oauth2_token_fetcher_get_request_metadata, NULL};
+static grpc_call_credentials_vtable compute_engine_vtable = {
+    oauth2_token_fetcher_destruct, oauth2_token_fetcher_get_request_metadata};
 
 static void compute_engine_fetch_oauth2(
     grpc_exec_ctx *exec_ctx, grpc_credentials_metadata_request *metadata_req,
@@ -723,7 +711,7 @@
                    response_cb, metadata_req);
 }
 
-grpc_credentials *grpc_google_compute_engine_credentials_create(
+grpc_call_credentials *grpc_google_compute_engine_credentials_create(
     void *reserved) {
   grpc_oauth2_token_fetcher_credentials *c =
       gpr_malloc(sizeof(grpc_oauth2_token_fetcher_credentials));
@@ -737,17 +725,15 @@
 
 /* -- GoogleRefreshToken credentials. -- */
 
-static void refresh_token_destruct(grpc_credentials *creds) {
+static void refresh_token_destruct(grpc_call_credentials *creds) {
   grpc_google_refresh_token_credentials *c =
       (grpc_google_refresh_token_credentials *)creds;
   grpc_auth_refresh_token_destruct(&c->refresh_token);
   oauth2_token_fetcher_destruct(&c->base.base);
 }
 
-static grpc_credentials_vtable refresh_token_vtable = {
-    refresh_token_destruct, oauth2_token_fetcher_has_request_metadata,
-    oauth2_token_fetcher_has_request_metadata_only,
-    oauth2_token_fetcher_get_request_metadata, NULL};
+static grpc_call_credentials_vtable refresh_token_vtable = {
+    refresh_token_destruct, oauth2_token_fetcher_get_request_metadata};
 
 static void refresh_token_fetch_oauth2(
     grpc_exec_ctx *exec_ctx, grpc_credentials_metadata_request *metadata_req,
@@ -773,7 +759,8 @@
   gpr_free(body);
 }
 
-grpc_credentials *grpc_refresh_token_credentials_create_from_auth_refresh_token(
+grpc_call_credentials *
+grpc_refresh_token_credentials_create_from_auth_refresh_token(
     grpc_auth_refresh_token refresh_token) {
   grpc_google_refresh_token_credentials *c;
   if (!grpc_auth_refresh_token_is_valid(&refresh_token)) {
@@ -788,7 +775,7 @@
   return &c->base.base;
 }
 
-grpc_credentials *grpc_google_refresh_token_credentials_create(
+grpc_call_credentials *grpc_google_refresh_token_credentials_create(
     const char *json_refresh_token, void *reserved) {
   GRPC_API_TRACE(
       "grpc_refresh_token_credentials_create(json_refresh_token=%s, "
@@ -801,20 +788,11 @@
 
 /* -- Metadata-only credentials. -- */
 
-static void md_only_test_destruct(grpc_credentials *creds) {
+static void md_only_test_destruct(grpc_call_credentials *creds) {
   grpc_md_only_test_credentials *c = (grpc_md_only_test_credentials *)creds;
   grpc_credentials_md_store_unref(c->md_store);
 }
 
-static int md_only_test_has_request_metadata(const grpc_credentials *creds) {
-  return 1;
-}
-
-static int md_only_test_has_request_metadata_only(
-    const grpc_credentials *creds) {
-  return 1;
-}
-
 static void on_simulated_token_fetch_done(void *user_data) {
   grpc_credentials_metadata_request *r =
       (grpc_credentials_metadata_request *)user_data;
@@ -826,9 +804,12 @@
   grpc_exec_ctx_finish(&exec_ctx);
 }
 
-static void md_only_test_get_request_metadata(
-    grpc_exec_ctx *exec_ctx, grpc_credentials *creds, grpc_pollset *pollset,
-    const char *service_url, grpc_credentials_metadata_cb cb, void *user_data) {
+static void md_only_test_get_request_metadata(grpc_exec_ctx *exec_ctx,
+                                              grpc_call_credentials *creds,
+                                              grpc_pollset *pollset,
+                                              const char *service_url,
+                                              grpc_credentials_metadata_cb cb,
+                                              void *user_data) {
   grpc_md_only_test_credentials *c = (grpc_md_only_test_credentials *)creds;
 
   if (c->is_async) {
@@ -841,18 +822,15 @@
   }
 }
 
-static grpc_credentials_vtable md_only_test_vtable = {
-    md_only_test_destruct, md_only_test_has_request_metadata,
-    md_only_test_has_request_metadata_only, md_only_test_get_request_metadata,
-    NULL};
+static grpc_call_credentials_vtable md_only_test_vtable = {
+    md_only_test_destruct, md_only_test_get_request_metadata};
 
-grpc_credentials *grpc_md_only_test_credentials_create(const char *md_key,
-                                                       const char *md_value,
-                                                       int is_async) {
+grpc_call_credentials *grpc_md_only_test_credentials_create(
+    const char *md_key, const char *md_value, int is_async) {
   grpc_md_only_test_credentials *c =
       gpr_malloc(sizeof(grpc_md_only_test_credentials));
   memset(c, 0, sizeof(grpc_md_only_test_credentials));
-  c->base.type = GRPC_CREDENTIALS_TYPE_OAUTH2;
+  c->base.type = GRPC_CALL_CREDENTIALS_TYPE_OAUTH2;
   c->base.vtable = &md_only_test_vtable;
   gpr_ref_init(&c->base.refcount, 1);
   c->md_store = grpc_credentials_md_store_create(1);
@@ -863,34 +841,26 @@
 
 /* -- Oauth2 Access Token credentials. -- */
 
-static void access_token_destruct(grpc_credentials *creds) {
+static void access_token_destruct(grpc_call_credentials *creds) {
   grpc_access_token_credentials *c = (grpc_access_token_credentials *)creds;
   grpc_credentials_md_store_unref(c->access_token_md);
 }
 
-static int access_token_has_request_metadata(const grpc_credentials *creds) {
-  return 1;
-}
-
-static int access_token_has_request_metadata_only(
-    const grpc_credentials *creds) {
-  return 1;
-}
-
-static void access_token_get_request_metadata(
-    grpc_exec_ctx *exec_ctx, grpc_credentials *creds, grpc_pollset *pollset,
-    const char *service_url, grpc_credentials_metadata_cb cb, void *user_data) {
+static void access_token_get_request_metadata(grpc_exec_ctx *exec_ctx,
+                                              grpc_call_credentials *creds,
+                                              grpc_pollset *pollset,
+                                              const char *service_url,
+                                              grpc_credentials_metadata_cb cb,
+                                              void *user_data) {
   grpc_access_token_credentials *c = (grpc_access_token_credentials *)creds;
   cb(exec_ctx, user_data, c->access_token_md->entries, 1, GRPC_CREDENTIALS_OK);
 }
 
-static grpc_credentials_vtable access_token_vtable = {
-    access_token_destruct, access_token_has_request_metadata,
-    access_token_has_request_metadata_only, access_token_get_request_metadata,
-    NULL};
+static grpc_call_credentials_vtable access_token_vtable = {
+    access_token_destruct, access_token_get_request_metadata};
 
-grpc_credentials *grpc_access_token_credentials_create(const char *access_token,
-                                                       void *reserved) {
+grpc_call_credentials *grpc_access_token_credentials_create(
+    const char *access_token, void *reserved) {
   grpc_access_token_credentials *c =
       gpr_malloc(sizeof(grpc_access_token_credentials));
   char *token_md_value;
@@ -900,7 +870,7 @@
       2, (access_token, reserved));
   GPR_ASSERT(reserved == NULL);
   memset(c, 0, sizeof(grpc_access_token_credentials));
-  c->base.type = GRPC_CREDENTIALS_TYPE_OAUTH2;
+  c->base.type = GRPC_CALL_CREDENTIALS_TYPE_OAUTH2;
   c->base.vtable = &access_token_vtable;
   gpr_ref_init(&c->base.refcount, 1);
   c->access_token_md = grpc_credentials_md_store_create(1);
@@ -913,31 +883,11 @@
 
 /* -- Fake transport security credentials. -- */
 
-static void fake_transport_security_credentials_destruct(
-    grpc_credentials *creds) {
-  /* Nothing to do here. */
-}
-
-static void fake_transport_security_server_credentials_destruct(
-    grpc_server_credentials *creds) {
-  /* Nothing to do here. */
-}
-
-static int fake_transport_security_has_request_metadata(
-    const grpc_credentials *creds) {
-  return 0;
-}
-
-static int fake_transport_security_has_request_metadata_only(
-    const grpc_credentials *creds) {
-  return 0;
-}
-
 static grpc_security_status fake_transport_security_create_security_connector(
-    grpc_credentials *c, const char *target, const grpc_channel_args *args,
-    grpc_credentials *request_metadata_creds,
+    grpc_channel_credentials *c, grpc_call_credentials *call_creds,
+    const char *target, const grpc_channel_args *args,
     grpc_channel_security_connector **sc, grpc_channel_args **new_args) {
-  *sc = grpc_fake_channel_security_connector_create(request_metadata_creds, 1);
+  *sc = grpc_fake_channel_security_connector_create(call_creds, 1);
   return GRPC_SECURITY_OK;
 }
 
@@ -948,21 +898,19 @@
   return GRPC_SECURITY_OK;
 }
 
-static grpc_credentials_vtable fake_transport_security_credentials_vtable = {
-    fake_transport_security_credentials_destruct,
-    fake_transport_security_has_request_metadata,
-    fake_transport_security_has_request_metadata_only, NULL,
-    fake_transport_security_create_security_connector};
+static grpc_channel_credentials_vtable
+    fake_transport_security_credentials_vtable = {
+        NULL, fake_transport_security_create_security_connector};
 
 static grpc_server_credentials_vtable
     fake_transport_security_server_credentials_vtable = {
-        fake_transport_security_server_credentials_destruct,
-        fake_transport_security_server_create_security_connector};
+        NULL, fake_transport_security_server_create_security_connector};
 
-grpc_credentials *grpc_fake_transport_security_credentials_create(void) {
-  grpc_credentials *c = gpr_malloc(sizeof(grpc_credentials));
-  memset(c, 0, sizeof(grpc_credentials));
-  c->type = GRPC_CREDENTIALS_TYPE_FAKE_TRANSPORT_SECURITY;
+grpc_channel_credentials *grpc_fake_transport_security_credentials_create(
+    void) {
+  grpc_channel_credentials *c = gpr_malloc(sizeof(grpc_channel_credentials));
+  memset(c, 0, sizeof(grpc_channel_credentials));
+  c->type = GRPC_CHANNEL_CREDENTIALS_TYPE_FAKE_TRANSPORT_SECURITY;
   c->vtable = &fake_transport_security_credentials_vtable;
   gpr_ref_init(&c->refcount, 1);
   return c;
@@ -972,69 +920,46 @@
     void) {
   grpc_server_credentials *c = gpr_malloc(sizeof(grpc_server_credentials));
   memset(c, 0, sizeof(grpc_server_credentials));
-  c->type = GRPC_CREDENTIALS_TYPE_FAKE_TRANSPORT_SECURITY;
+  c->type = GRPC_CHANNEL_CREDENTIALS_TYPE_FAKE_TRANSPORT_SECURITY;
   gpr_ref_init(&c->refcount, 1);
   c->vtable = &fake_transport_security_server_credentials_vtable;
   return c;
 }
 
-/* -- Composite credentials. -- */
+/* -- Composite call credentials. -- */
 
 typedef struct {
-  grpc_composite_credentials *composite_creds;
+  grpc_composite_call_credentials *composite_creds;
   size_t creds_index;
   grpc_credentials_md_store *md_elems;
   char *service_url;
   void *user_data;
   grpc_pollset *pollset;
   grpc_credentials_metadata_cb cb;
-} grpc_composite_credentials_metadata_context;
+} grpc_composite_call_credentials_metadata_context;
 
-static void composite_destruct(grpc_credentials *creds) {
-  grpc_composite_credentials *c = (grpc_composite_credentials *)creds;
+static void composite_call_destruct(grpc_call_credentials *creds) {
+  grpc_composite_call_credentials *c = (grpc_composite_call_credentials *)creds;
   size_t i;
   for (i = 0; i < c->inner.num_creds; i++) {
-    grpc_credentials_unref(c->inner.creds_array[i]);
+    grpc_call_credentials_unref(c->inner.creds_array[i]);
   }
   gpr_free(c->inner.creds_array);
 }
 
-static int composite_has_request_metadata(const grpc_credentials *creds) {
-  const grpc_composite_credentials *c =
-      (const grpc_composite_credentials *)creds;
-  size_t i;
-  for (i = 0; i < c->inner.num_creds; i++) {
-    if (grpc_credentials_has_request_metadata(c->inner.creds_array[i])) {
-      return 1;
-    }
-  }
-  return 0;
-}
-
-static int composite_has_request_metadata_only(const grpc_credentials *creds) {
-  const grpc_composite_credentials *c =
-      (const grpc_composite_credentials *)creds;
-  size_t i;
-  for (i = 0; i < c->inner.num_creds; i++) {
-    if (!grpc_credentials_has_request_metadata_only(c->inner.creds_array[i])) {
-      return 0;
-    }
-  }
-  return 1;
-}
-
-static void composite_md_context_destroy(
-    grpc_composite_credentials_metadata_context *ctx) {
+static void composite_call_md_context_destroy(
+    grpc_composite_call_credentials_metadata_context *ctx) {
   grpc_credentials_md_store_unref(ctx->md_elems);
   if (ctx->service_url != NULL) gpr_free(ctx->service_url);
   gpr_free(ctx);
 }
 
-static void composite_metadata_cb(grpc_exec_ctx *exec_ctx, void *user_data,
-                                  grpc_credentials_md *md_elems, size_t num_md,
-                                  grpc_credentials_status status) {
-  grpc_composite_credentials_metadata_context *ctx =
-      (grpc_composite_credentials_metadata_context *)user_data;
+static void composite_call_metadata_cb(grpc_exec_ctx *exec_ctx, void *user_data,
+                                       grpc_credentials_md *md_elems,
+                                       size_t num_md,
+                                       grpc_credentials_status status) {
+  grpc_composite_call_credentials_metadata_context *ctx =
+      (grpc_composite_call_credentials_metadata_context *)user_data;
   if (status != GRPC_CREDENTIALS_OK) {
     ctx->cb(exec_ctx, ctx->user_data, NULL, 0, status);
     return;
@@ -1050,158 +975,114 @@
   }
 
   /* See if we need to get some more metadata. */
-  while (ctx->creds_index < ctx->composite_creds->inner.num_creds) {
-    grpc_credentials *inner_creds =
+  if (ctx->creds_index < ctx->composite_creds->inner.num_creds) {
+    grpc_call_credentials *inner_creds =
         ctx->composite_creds->inner.creds_array[ctx->creds_index++];
-    if (grpc_credentials_has_request_metadata(inner_creds)) {
-      grpc_credentials_get_request_metadata(exec_ctx, inner_creds, ctx->pollset,
-                                            ctx->service_url,
-                                            composite_metadata_cb, ctx);
-      return;
-    }
+    grpc_call_credentials_get_request_metadata(exec_ctx, inner_creds,
+                                               ctx->pollset, ctx->service_url,
+                                               composite_call_metadata_cb, ctx);
+    return;
   }
 
   /* We're done!. */
   ctx->cb(exec_ctx, ctx->user_data, ctx->md_elems->entries,
           ctx->md_elems->num_entries, GRPC_CREDENTIALS_OK);
-  composite_md_context_destroy(ctx);
+  composite_call_md_context_destroy(ctx);
 }
 
-static void composite_get_request_metadata(
-    grpc_exec_ctx *exec_ctx, grpc_credentials *creds, grpc_pollset *pollset,
-    const char *service_url, grpc_credentials_metadata_cb cb, void *user_data) {
-  grpc_composite_credentials *c = (grpc_composite_credentials *)creds;
-  grpc_composite_credentials_metadata_context *ctx;
-  if (!grpc_credentials_has_request_metadata(creds)) {
-    cb(exec_ctx, user_data, NULL, 0, GRPC_CREDENTIALS_OK);
-    return;
-  }
-  ctx = gpr_malloc(sizeof(grpc_composite_credentials_metadata_context));
-  memset(ctx, 0, sizeof(grpc_composite_credentials_metadata_context));
+static void composite_call_get_request_metadata(grpc_exec_ctx *exec_ctx,
+                                                grpc_call_credentials *creds,
+                                                grpc_pollset *pollset,
+                                                const char *service_url,
+                                                grpc_credentials_metadata_cb cb,
+                                                void *user_data) {
+  grpc_composite_call_credentials *c = (grpc_composite_call_credentials *)creds;
+  grpc_composite_call_credentials_metadata_context *ctx;
+
+  ctx = gpr_malloc(sizeof(grpc_composite_call_credentials_metadata_context));
+  memset(ctx, 0, sizeof(grpc_composite_call_credentials_metadata_context));
   ctx->service_url = gpr_strdup(service_url);
   ctx->user_data = user_data;
   ctx->cb = cb;
   ctx->composite_creds = c;
   ctx->pollset = pollset;
   ctx->md_elems = grpc_credentials_md_store_create(c->inner.num_creds);
-  while (ctx->creds_index < c->inner.num_creds) {
-    grpc_credentials *inner_creds = c->inner.creds_array[ctx->creds_index++];
-    if (grpc_credentials_has_request_metadata(inner_creds)) {
-      grpc_credentials_get_request_metadata(exec_ctx, inner_creds, pollset,
-                                            service_url, composite_metadata_cb,
-                                            ctx);
-      return;
-    }
-  }
-  GPR_ASSERT(0); /* Should have exited before. */
+  grpc_call_credentials_get_request_metadata(
+      exec_ctx, c->inner.creds_array[ctx->creds_index++], pollset, service_url,
+      composite_call_metadata_cb, ctx);
 }
 
-static grpc_security_status composite_create_security_connector(
-    grpc_credentials *creds, const char *target, const grpc_channel_args *args,
-    grpc_credentials *request_metadata_creds,
-    grpc_channel_security_connector **sc, grpc_channel_args **new_args) {
-  grpc_composite_credentials *c = (grpc_composite_credentials *)creds;
-  if (c->connector_creds == NULL) {
-    gpr_log(GPR_ERROR,
-            "Cannot create security connector, missing connector credentials.");
-    return GRPC_SECURITY_ERROR;
-  }
-  return grpc_credentials_create_security_connector(c->connector_creds, target,
-                                                    args, creds, sc, new_args);
-}
+static grpc_call_credentials_vtable composite_call_credentials_vtable = {
+    composite_call_destruct, composite_call_get_request_metadata};
 
-static grpc_credentials_vtable composite_credentials_vtable = {
-    composite_destruct, composite_has_request_metadata,
-    composite_has_request_metadata_only, composite_get_request_metadata,
-    composite_create_security_connector};
-
-static grpc_credentials_array get_creds_array(grpc_credentials **creds_addr) {
-  grpc_credentials_array result;
-  grpc_credentials *creds = *creds_addr;
+static grpc_call_credentials_array get_creds_array(
+    grpc_call_credentials **creds_addr) {
+  grpc_call_credentials_array result;
+  grpc_call_credentials *creds = *creds_addr;
   result.creds_array = creds_addr;
   result.num_creds = 1;
-  if (strcmp(creds->type, GRPC_CREDENTIALS_TYPE_COMPOSITE) == 0) {
-    result = *grpc_composite_credentials_get_credentials(creds);
+  if (strcmp(creds->type, GRPC_CALL_CREDENTIALS_TYPE_COMPOSITE) == 0) {
+    result = *grpc_composite_call_credentials_get_credentials(creds);
   }
   return result;
 }
 
-grpc_credentials *grpc_composite_credentials_create(grpc_credentials *creds1,
-                                                    grpc_credentials *creds2,
-                                                    void *reserved) {
+grpc_call_credentials *grpc_composite_call_credentials_create(
+    grpc_call_credentials *creds1, grpc_call_credentials *creds2,
+    void *reserved) {
   size_t i;
   size_t creds_array_byte_size;
-  grpc_credentials_array creds1_array;
-  grpc_credentials_array creds2_array;
-  grpc_composite_credentials *c;
+  grpc_call_credentials_array creds1_array;
+  grpc_call_credentials_array creds2_array;
+  grpc_composite_call_credentials *c;
   GRPC_API_TRACE(
-      "grpc_composite_credentials_create(creds1=%p, creds2=%p, "
+      "grpc_composite_call_credentials_create(creds1=%p, creds2=%p, "
       "reserved=%p)",
       3, (creds1, creds2, reserved));
   GPR_ASSERT(reserved == NULL);
   GPR_ASSERT(creds1 != NULL);
   GPR_ASSERT(creds2 != NULL);
-  c = gpr_malloc(sizeof(grpc_composite_credentials));
-  memset(c, 0, sizeof(grpc_composite_credentials));
-  c->base.type = GRPC_CREDENTIALS_TYPE_COMPOSITE;
-  c->base.vtable = &composite_credentials_vtable;
+  c = gpr_malloc(sizeof(grpc_composite_call_credentials));
+  memset(c, 0, sizeof(grpc_composite_call_credentials));
+  c->base.type = GRPC_CALL_CREDENTIALS_TYPE_COMPOSITE;
+  c->base.vtable = &composite_call_credentials_vtable;
   gpr_ref_init(&c->base.refcount, 1);
   creds1_array = get_creds_array(&creds1);
   creds2_array = get_creds_array(&creds2);
   c->inner.num_creds = creds1_array.num_creds + creds2_array.num_creds;
-  creds_array_byte_size = c->inner.num_creds * sizeof(grpc_credentials *);
+  creds_array_byte_size = c->inner.num_creds * sizeof(grpc_call_credentials *);
   c->inner.creds_array = gpr_malloc(creds_array_byte_size);
   memset(c->inner.creds_array, 0, creds_array_byte_size);
   for (i = 0; i < creds1_array.num_creds; i++) {
-    grpc_credentials *cur_creds = creds1_array.creds_array[i];
-    if (!grpc_credentials_has_request_metadata_only(cur_creds)) {
-      if (c->connector_creds == NULL) {
-        c->connector_creds = cur_creds;
-      } else {
-        gpr_log(GPR_ERROR, "Cannot compose multiple connector credentials.");
-        goto fail;
-      }
-    }
-    c->inner.creds_array[i] = grpc_credentials_ref(cur_creds);
+    grpc_call_credentials *cur_creds = creds1_array.creds_array[i];
+    c->inner.creds_array[i] = grpc_call_credentials_ref(cur_creds);
   }
   for (i = 0; i < creds2_array.num_creds; i++) {
-    grpc_credentials *cur_creds = creds2_array.creds_array[i];
-    if (!grpc_credentials_has_request_metadata_only(cur_creds)) {
-      if (c->connector_creds == NULL) {
-        c->connector_creds = cur_creds;
-      } else {
-        gpr_log(GPR_ERROR, "Cannot compose multiple connector credentials.");
-        goto fail;
-      }
-    }
+    grpc_call_credentials *cur_creds = creds2_array.creds_array[i];
     c->inner.creds_array[i + creds1_array.num_creds] =
-        grpc_credentials_ref(cur_creds);
+        grpc_call_credentials_ref(cur_creds);
   }
   return &c->base;
-
-fail:
-  grpc_credentials_unref(&c->base);
-  return NULL;
 }
 
-const grpc_credentials_array *grpc_composite_credentials_get_credentials(
-    grpc_credentials *creds) {
-  const grpc_composite_credentials *c =
-      (const grpc_composite_credentials *)creds;
-  GPR_ASSERT(strcmp(creds->type, GRPC_CREDENTIALS_TYPE_COMPOSITE) == 0);
+const grpc_call_credentials_array *
+grpc_composite_call_credentials_get_credentials(grpc_call_credentials *creds) {
+  const grpc_composite_call_credentials *c =
+      (const grpc_composite_call_credentials *)creds;
+  GPR_ASSERT(strcmp(creds->type, GRPC_CALL_CREDENTIALS_TYPE_COMPOSITE) == 0);
   return &c->inner;
 }
 
-grpc_credentials *grpc_credentials_contains_type(
-    grpc_credentials *creds, const char *type,
-    grpc_credentials **composite_creds) {
+grpc_call_credentials *grpc_credentials_contains_type(
+    grpc_call_credentials *creds, const char *type,
+    grpc_call_credentials **composite_creds) {
   size_t i;
   if (strcmp(creds->type, type) == 0) {
     if (composite_creds != NULL) *composite_creds = NULL;
     return creds;
-  } else if (strcmp(creds->type, GRPC_CREDENTIALS_TYPE_COMPOSITE) == 0) {
-    const grpc_credentials_array *inner_creds_array =
-        grpc_composite_credentials_get_credentials(creds);
+  } else if (strcmp(creds->type, GRPC_CALL_CREDENTIALS_TYPE_COMPOSITE) == 0) {
+    const grpc_call_credentials_array *inner_creds_array =
+        grpc_composite_call_credentials_get_credentials(creds);
     for (i = 0; i < inner_creds_array->num_creds; i++) {
       if (strcmp(type, inner_creds_array->creds_array[i]->type) == 0) {
         if (composite_creds != NULL) *composite_creds = creds;
@@ -1214,30 +1095,26 @@
 
 /* -- IAM credentials. -- */
 
-static void iam_destruct(grpc_credentials *creds) {
+static void iam_destruct(grpc_call_credentials *creds) {
   grpc_google_iam_credentials *c = (grpc_google_iam_credentials *)creds;
   grpc_credentials_md_store_unref(c->iam_md);
 }
 
-static int iam_has_request_metadata(const grpc_credentials *creds) { return 1; }
-
-static int iam_has_request_metadata_only(const grpc_credentials *creds) {
-  return 1;
-}
-
-static void iam_get_request_metadata(
-    grpc_exec_ctx *exec_ctx, grpc_credentials *creds, grpc_pollset *pollset,
-    const char *service_url, grpc_credentials_metadata_cb cb, void *user_data) {
+static void iam_get_request_metadata(grpc_exec_ctx *exec_ctx,
+                                     grpc_call_credentials *creds,
+                                     grpc_pollset *pollset,
+                                     const char *service_url,
+                                     grpc_credentials_metadata_cb cb,
+                                     void *user_data) {
   grpc_google_iam_credentials *c = (grpc_google_iam_credentials *)creds;
   cb(exec_ctx, user_data, c->iam_md->entries, c->iam_md->num_entries,
      GRPC_CREDENTIALS_OK);
 }
 
-static grpc_credentials_vtable iam_vtable = {
-    iam_destruct, iam_has_request_metadata, iam_has_request_metadata_only,
-    iam_get_request_metadata, NULL};
+static grpc_call_credentials_vtable iam_vtable = {iam_destruct,
+                                                  iam_get_request_metadata};
 
-grpc_credentials *grpc_google_iam_credentials_create(
+grpc_call_credentials *grpc_google_iam_credentials_create(
     const char *token, const char *authority_selector, void *reserved) {
   grpc_google_iam_credentials *c;
   GRPC_API_TRACE(
@@ -1249,7 +1126,7 @@
   GPR_ASSERT(authority_selector != NULL);
   c = gpr_malloc(sizeof(grpc_google_iam_credentials));
   memset(c, 0, sizeof(grpc_google_iam_credentials));
-  c->base.type = GRPC_CREDENTIALS_TYPE_IAM;
+  c->base.type = GRPC_CALL_CREDENTIALS_TYPE_IAM;
   c->base.vtable = &iam_vtable;
   gpr_ref_init(&c->base.refcount, 1);
   c->iam_md = grpc_credentials_md_store_create(2);
@@ -1267,21 +1144,13 @@
   grpc_credentials_metadata_cb cb;
 } grpc_metadata_plugin_request;
 
-static void plugin_destruct(grpc_credentials *creds) {
+static void plugin_destruct(grpc_call_credentials *creds) {
   grpc_plugin_credentials *c = (grpc_plugin_credentials *)creds;
   if (c->plugin.state != NULL && c->plugin.destroy != NULL) {
     c->plugin.destroy(c->plugin.state);
   }
 }
 
-static int plugin_has_request_metadata(const grpc_credentials *creds) {
-  return 1;
-}
-
-static int plugin_has_request_metadata_only(const grpc_credentials *creds) {
-  return 1;
-}
-
 static void plugin_md_request_metadata_ready(void *request,
                                              const grpc_metadata *md,
                                              size_t num_md,
@@ -1320,9 +1189,12 @@
   grpc_exec_ctx_finish(&exec_ctx);
 }
 
-static void plugin_get_request_metadata(
-    grpc_exec_ctx *exec_ctx, grpc_credentials *creds, grpc_pollset *pollset,
-    const char *service_url, grpc_credentials_metadata_cb cb, void *user_data) {
+static void plugin_get_request_metadata(grpc_exec_ctx *exec_ctx,
+                                        grpc_call_credentials *creds,
+                                        grpc_pollset *pollset,
+                                        const char *service_url,
+                                        grpc_credentials_metadata_cb cb,
+                                        void *user_data) {
   grpc_plugin_credentials *c = (grpc_plugin_credentials *)creds;
   if (c->plugin.get_metadata != NULL) {
     grpc_metadata_plugin_request *request = gpr_malloc(sizeof(*request));
@@ -1336,18 +1208,75 @@
   }
 }
 
-static grpc_credentials_vtable plugin_vtable = {
-    plugin_destruct, plugin_has_request_metadata,
-    plugin_has_request_metadata_only, plugin_get_request_metadata, NULL};
+static grpc_call_credentials_vtable plugin_vtable = {
+    plugin_destruct, plugin_get_request_metadata};
 
-grpc_credentials *grpc_metadata_credentials_create_from_plugin(
+grpc_call_credentials *grpc_metadata_credentials_create_from_plugin(
     grpc_metadata_credentials_plugin plugin, void *reserved) {
   grpc_plugin_credentials *c = gpr_malloc(sizeof(*c));
+  GRPC_API_TRACE("grpc_metadata_credentials_create_from_plugin(reserved=%p)", 1,
+                 (reserved));
   GPR_ASSERT(reserved == NULL);
   memset(c, 0, sizeof(*c));
-  c->base.type = GRPC_CREDENTIALS_TYPE_METADATA_PLUGIN;
+  c->base.type = GRPC_CALL_CREDENTIALS_TYPE_METADATA_PLUGIN;
   c->base.vtable = &plugin_vtable;
   gpr_ref_init(&c->base.refcount, 1);
   c->plugin = plugin;
   return &c->base;
 }
+
+/* -- Composite channel credentials. -- */
+
+static void composite_channel_destruct(grpc_channel_credentials *creds) {
+  grpc_composite_channel_credentials *c =
+      (grpc_composite_channel_credentials *)creds;
+  grpc_channel_credentials_unref(c->inner_creds);
+  grpc_call_credentials_unref(c->call_creds);
+}
+
+static grpc_security_status composite_channel_create_security_connector(
+    grpc_channel_credentials *creds, grpc_call_credentials *call_creds,
+    const char *target, const grpc_channel_args *args,
+    grpc_channel_security_connector **sc, grpc_channel_args **new_args) {
+  grpc_composite_channel_credentials *c =
+      (grpc_composite_channel_credentials *)creds;
+  grpc_security_status status = GRPC_SECURITY_ERROR;
+
+  GPR_ASSERT(c->inner_creds != NULL && c->call_creds != NULL &&
+             c->inner_creds->vtable != NULL &&
+             c->inner_creds->vtable->create_security_connector != NULL);
+  /* If we are passed a call_creds, create a call composite to pass it
+     downstream. */
+  if (call_creds != NULL) {
+    grpc_call_credentials *composite_call_creds =
+        grpc_composite_call_credentials_create(c->call_creds, call_creds, NULL);
+    status = c->inner_creds->vtable->create_security_connector(
+        c->inner_creds, composite_call_creds, target, args, sc, new_args);
+    grpc_call_credentials_unref(composite_call_creds);
+  } else {
+    status = c->inner_creds->vtable->create_security_connector(
+        c->inner_creds, c->call_creds, target, args, sc, new_args);
+  }
+  return status;
+}
+
+static grpc_channel_credentials_vtable composite_channel_credentials_vtable = {
+    composite_channel_destruct, composite_channel_create_security_connector};
+
+grpc_channel_credentials *grpc_composite_channel_credentials_create(
+    grpc_channel_credentials *channel_creds, grpc_call_credentials *call_creds,
+    void *reserved) {
+  grpc_composite_channel_credentials *c = gpr_malloc(sizeof(*c));
+  memset(c, 0, sizeof(*c));
+  GPR_ASSERT(channel_creds != NULL && call_creds != NULL && reserved == NULL);
+  GRPC_API_TRACE(
+      "grpc_composite_channel_credentials_create(channel_creds=%p, "
+      "call_creds=%p, reserved=%p)",
+      3, (channel_creds, call_creds, reserved));
+  c->base.type = channel_creds->type;
+  c->base.vtable = &composite_channel_credentials_vtable;
+  gpr_ref_init(&c->base.refcount, 1);
+  c->inner_creds = grpc_channel_credentials_ref(channel_creds);
+  c->call_creds = grpc_call_credentials_ref(call_creds);
+  return &c->base;
+}
diff --git a/src/core/security/credentials.h b/src/core/security/credentials.h
index c74beef..1320609 100644
--- a/src/core/security/credentials.h
+++ b/src/core/security/credentials.h
@@ -54,15 +54,17 @@
 
 #define GRPC_FAKE_TRANSPORT_SECURITY_TYPE "fake"
 
-#define GRPC_CREDENTIALS_TYPE_SSL "Ssl"
-#define GRPC_CREDENTIALS_TYPE_OAUTH2 "Oauth2"
-#define GRPC_CREDENTIALS_TYPE_METADATA_PLUGIN "Plugin"
-#define GRPC_CREDENTIALS_TYPE_JWT "Jwt"
-#define GRPC_CREDENTIALS_TYPE_IAM "Iam"
-#define GRPC_CREDENTIALS_TYPE_COMPOSITE "Composite"
-#define GRPC_CREDENTIALS_TYPE_FAKE_TRANSPORT_SECURITY "FakeTransportSecurity"
+#define GRPC_CHANNEL_CREDENTIALS_TYPE_SSL "Ssl"
+#define GRPC_CHANNEL_CREDENTIALS_TYPE_FAKE_TRANSPORT_SECURITY \
+  "FakeTransportSecurity"
 
-#define GRPC_AUTHORIZATION_METADATA_KEY "Authorization"
+#define GRPC_CALL_CREDENTIALS_TYPE_OAUTH2 "Oauth2"
+#define GRPC_CALL_CREDENTIALS_TYPE_METADATA_PLUGIN "Plugin"
+#define GRPC_CALL_CREDENTIALS_TYPE_JWT "Jwt"
+#define GRPC_CALL_CREDENTIALS_TYPE_IAM "Iam"
+#define GRPC_CALL_CREDENTIALS_TYPE_COMPOSITE "Composite"
+
+#define GRPC_AUTHORIZATION_METADATA_KEY "authorization"
 #define GRPC_IAM_AUTHORIZATION_TOKEN_METADATA_KEY \
   "x-goog-iam-authorization-token"
 #define GRPC_IAM_AUTHORITY_SELECTOR_METADATA_KEY "x-goog-iam-authority-selector"
@@ -87,6 +89,41 @@
 #define GRPC_REFRESH_TOKEN_POST_BODY_FORMAT_STRING \
   "client_id=%s&client_secret=%s&refresh_token=%s&grant_type=refresh_token"
 
+/* --- Google utils --- */
+
+/* It is the caller's responsibility to gpr_free the result if not NULL. */
+char *grpc_get_well_known_google_credentials_file_path(void);
+
+/* --- grpc_channel_credentials. --- */
+
+typedef struct {
+  void (*destruct)(grpc_channel_credentials *c);
+
+  grpc_security_status (*create_security_connector)(
+      grpc_channel_credentials *c, grpc_call_credentials *call_creds,
+      const char *target, const grpc_channel_args *args,
+      grpc_channel_security_connector **sc, grpc_channel_args **new_args);
+} grpc_channel_credentials_vtable;
+
+struct grpc_channel_credentials {
+  const grpc_channel_credentials_vtable *vtable;
+  const char *type;
+  gpr_refcount refcount;
+};
+
+grpc_channel_credentials *grpc_channel_credentials_ref(
+    grpc_channel_credentials *creds);
+void grpc_channel_credentials_unref(grpc_channel_credentials *creds);
+
+/* Creates a security connector for the channel. May also create new channel
+   args for the channel to be used in place of the passed in const args if
+   returned non NULL. In that case the caller is responsible for destroying
+   new_args after channel creation. */
+grpc_security_status grpc_channel_credentials_create_security_connector(
+    grpc_channel_credentials *creds, const char *target,
+    const grpc_channel_args *args, grpc_channel_security_connector **sc,
+    grpc_channel_args **new_args);
+
 /* --- grpc_credentials_md. --- */
 
 typedef struct {
@@ -113,16 +150,7 @@
     grpc_credentials_md_store *store);
 void grpc_credentials_md_store_unref(grpc_credentials_md_store *store);
 
-/* --- grpc_credentials. --- */
-
-/* Creates a fake transport security credentials object for testing. */
-grpc_credentials *grpc_fake_transport_security_credentials_create(void);
-/* Creates a fake server transport security credentials object for testing. */
-grpc_server_credentials *grpc_fake_transport_security_server_credentials_create(
-    void);
-
-/* It is the caller's responsibility to gpr_free the result if not NULL. */
-char *grpc_get_well_known_google_credentials_file_path(void);
+/* --- grpc_call_credentials. --- */
 
 typedef void (*grpc_credentials_metadata_cb)(grpc_exec_ctx *exec_ctx,
                                              void *user_data,
@@ -131,57 +159,45 @@
                                              grpc_credentials_status status);
 
 typedef struct {
-  void (*destruct)(grpc_credentials *c);
-  int (*has_request_metadata)(const grpc_credentials *c);
-  int (*has_request_metadata_only)(const grpc_credentials *c);
-  void (*get_request_metadata)(grpc_exec_ctx *exec_ctx, grpc_credentials *c,
-                               grpc_pollset *pollset, const char *service_url,
+  void (*destruct)(grpc_call_credentials *c);
+  void (*get_request_metadata)(grpc_exec_ctx *exec_ctx,
+                               grpc_call_credentials *c, grpc_pollset *pollset,
+                               const char *service_url,
                                grpc_credentials_metadata_cb cb,
                                void *user_data);
-  grpc_security_status (*create_security_connector)(
-      grpc_credentials *c, const char *target, const grpc_channel_args *args,
-      grpc_credentials *request_metadata_creds,
-      grpc_channel_security_connector **sc, grpc_channel_args **new_args);
-} grpc_credentials_vtable;
+} grpc_call_credentials_vtable;
 
-struct grpc_credentials {
-  const grpc_credentials_vtable *vtable;
+struct grpc_call_credentials {
+  const grpc_call_credentials_vtable *vtable;
   const char *type;
   gpr_refcount refcount;
 };
 
-grpc_credentials *grpc_credentials_ref(grpc_credentials *creds);
-void grpc_credentials_unref(grpc_credentials *creds);
-int grpc_credentials_has_request_metadata(grpc_credentials *creds);
-int grpc_credentials_has_request_metadata_only(grpc_credentials *creds);
-void grpc_credentials_get_request_metadata(
-    grpc_exec_ctx *exec_ctx, grpc_credentials *creds, grpc_pollset *pollset,
-    const char *service_url, grpc_credentials_metadata_cb cb, void *user_data);
-
-/* Creates a security connector for the channel. May also create new channel
-   args for the channel to be used in place of the passed in const args if
-   returned non NULL. In that case the caller is responsible for destroying
-   new_args after channel creation. */
-grpc_security_status grpc_credentials_create_security_connector(
-    grpc_credentials *creds, const char *target, const grpc_channel_args *args,
-    grpc_credentials *request_metadata_creds,
-    grpc_channel_security_connector **sc, grpc_channel_args **new_args);
+grpc_call_credentials *grpc_call_credentials_ref(grpc_call_credentials *creds);
+void grpc_call_credentials_unref(grpc_call_credentials *creds);
+void grpc_call_credentials_get_request_metadata(grpc_exec_ctx *exec_ctx,
+                                                grpc_call_credentials *creds,
+                                                grpc_pollset *pollset,
+                                                const char *service_url,
+                                                grpc_credentials_metadata_cb cb,
+                                                void *user_data);
 
 typedef struct {
-  grpc_credentials **creds_array;
+  grpc_call_credentials **creds_array;
   size_t num_creds;
-} grpc_credentials_array;
+} grpc_call_credentials_array;
 
-const grpc_credentials_array *grpc_composite_credentials_get_credentials(
-    grpc_credentials *composite_creds);
+const grpc_call_credentials_array *
+grpc_composite_call_credentials_get_credentials(
+    grpc_call_credentials *composite_creds);
 
 /* Returns creds if creds is of the specified type or the inner creds of the
    specified type (if found), if the creds is of type COMPOSITE.
    If composite_creds is not NULL, *composite_creds will point to creds if of
    type COMPOSITE in case of success. */
-grpc_credentials *grpc_credentials_contains_type(
-    grpc_credentials *creds, const char *type,
-    grpc_credentials **composite_creds);
+grpc_call_credentials *grpc_credentials_contains_type(
+    grpc_call_credentials *creds, const char *type,
+    grpc_call_credentials **composite_creds);
 
 /* Exposed for testing only. */
 grpc_credentials_status
@@ -192,19 +208,19 @@
 
 /* Metadata-only credentials with the specified key and value where
    asynchronicity can be simulated for testing. */
-grpc_credentials *grpc_md_only_test_credentials_create(const char *md_key,
-                                                       const char *md_value,
-                                                       int is_async);
+grpc_call_credentials *grpc_md_only_test_credentials_create(
+    const char *md_key, const char *md_value, int is_async);
 
 /* Private constructor for jwt credentials from an already parsed json key.
    Takes ownership of the key. */
-grpc_credentials *
+grpc_call_credentials *
 grpc_service_account_jwt_access_credentials_create_from_auth_json_key(
     grpc_auth_json_key key, gpr_timespec token_lifetime);
 
 /* Private constructor for refresh token credentials from an already parsed
    refresh token. Takes ownership of the refresh token. */
-grpc_credentials *grpc_refresh_token_credentials_create_from_auth_refresh_token(
+grpc_call_credentials *
+grpc_refresh_token_credentials_create_from_auth_refresh_token(
     grpc_auth_refresh_token token);
 
 /* --- grpc_server_credentials. --- */
@@ -237,10 +253,18 @@
 grpc_server_credentials *grpc_find_server_credentials_in_args(
     const grpc_channel_args *args);
 
+/* -- Fake transport security credentials. -- */
+
+/* Creates a fake transport security credentials object for testing. */
+grpc_channel_credentials *grpc_fake_transport_security_credentials_create(void);
+/* Creates a fake server transport security credentials object for testing. */
+grpc_server_credentials *grpc_fake_transport_security_server_credentials_create(
+    void);
+
 /* -- Ssl credentials. -- */
 
 typedef struct {
-  grpc_credentials base;
+  grpc_channel_credentials base;
   grpc_ssl_config config;
 } grpc_ssl_credentials;
 
@@ -249,10 +273,18 @@
   grpc_ssl_server_config config;
 } grpc_ssl_server_credentials;
 
+/* -- Channel composite credentials. -- */
+
+typedef struct {
+  grpc_channel_credentials base;
+  grpc_channel_credentials *inner_creds;
+  grpc_call_credentials *call_creds;
+} grpc_composite_channel_credentials;
+
 /* -- Jwt credentials -- */
 
 typedef struct {
-  grpc_credentials base;
+  grpc_call_credentials base;
 
   /* Have a simple cache for now with just 1 entry. We could have a map based on
      the service_url for a more sophisticated one. */
@@ -283,7 +315,7 @@
                                        gpr_timespec deadline);
 
 typedef struct {
-  grpc_credentials base;
+  grpc_call_credentials base;
   gpr_mu mu;
   grpc_credentials_md_store *access_token_md;
   gpr_timespec token_expiration;
@@ -301,14 +333,14 @@
 /* -- Oauth2 Access Token credentials. -- */
 
 typedef struct {
-  grpc_credentials base;
+  grpc_call_credentials base;
   grpc_credentials_md_store *access_token_md;
 } grpc_access_token_credentials;
 
 /* --  Metadata-only Test credentials. -- */
 
 typedef struct {
-  grpc_credentials base;
+  grpc_call_credentials base;
   grpc_credentials_md_store *md_store;
   int is_async;
 } grpc_md_only_test_credentials;
@@ -316,22 +348,21 @@
 /* -- GoogleIAM credentials. -- */
 
 typedef struct {
-  grpc_credentials base;
+  grpc_call_credentials base;
   grpc_credentials_md_store *iam_md;
 } grpc_google_iam_credentials;
 
 /* -- Composite credentials. -- */
 
 typedef struct {
-  grpc_credentials base;
-  grpc_credentials_array inner;
-  grpc_credentials *connector_creds;
-} grpc_composite_credentials;
+  grpc_call_credentials base;
+  grpc_call_credentials_array inner;
+} grpc_composite_call_credentials;
 
 /* -- Plugin credentials. -- */
 
 typedef struct {
-  grpc_credentials base;
+  grpc_call_credentials base;
   grpc_metadata_credentials_plugin plugin;
   grpc_credentials_md_store *plugin_md;
 } grpc_plugin_credentials;
diff --git a/src/core/security/google_default_credentials.c b/src/core/security/google_default_credentials.c
index 4513530..6a54fe4 100644
--- a/src/core/security/google_default_credentials.c
+++ b/src/core/security/google_default_credentials.c
@@ -50,7 +50,7 @@
 
 /* -- Default credentials. -- */
 
-static grpc_credentials *default_credentials = NULL;
+static grpc_channel_credentials *default_credentials = NULL;
 static int compute_engine_detection_done = 0;
 static gpr_mu g_mu;
 static gpr_once g_once = GPR_ONCE_INIT;
@@ -138,11 +138,11 @@
 }
 
 /* Takes ownership of creds_path if not NULL. */
-static grpc_credentials *create_default_creds_from_path(char *creds_path) {
+static grpc_call_credentials *create_default_creds_from_path(char *creds_path) {
   grpc_json *json = NULL;
   grpc_auth_json_key key;
   grpc_auth_refresh_token token;
-  grpc_credentials *result = NULL;
+  grpc_call_credentials *result = NULL;
   gpr_slice creds_data = gpr_empty_slice();
   int file_ok = 0;
   if (creds_path == NULL) goto end;
@@ -176,9 +176,9 @@
   return result;
 }
 
-grpc_credentials *grpc_google_default_credentials_create(void) {
-  grpc_credentials *result = NULL;
-  int serving_cached_credentials = 0;
+grpc_channel_credentials *grpc_google_default_credentials_create(void) {
+  grpc_channel_credentials *result = NULL;
+  grpc_call_credentials *call_creds = NULL;
 
   GRPC_API_TRACE("grpc_google_default_credentials_create(void)", 0, ());
 
@@ -187,20 +187,19 @@
   gpr_mu_lock(&g_mu);
 
   if (default_credentials != NULL) {
-    result = grpc_credentials_ref(default_credentials);
-    serving_cached_credentials = 1;
+    result = grpc_channel_credentials_ref(default_credentials);
     goto end;
   }
 
   /* First, try the environment variable. */
-  result = create_default_creds_from_path(
+  call_creds = create_default_creds_from_path(
       gpr_getenv(GRPC_GOOGLE_CREDENTIALS_ENV_VAR));
-  if (result != NULL) goto end;
+  if (call_creds != NULL) goto end;
 
   /* Then the well-known file. */
-  result = create_default_creds_from_path(
+  call_creds = create_default_creds_from_path(
       grpc_get_well_known_google_credentials_file_path());
-  if (result != NULL) goto end;
+  if (call_creds != NULL) goto end;
 
   /* At last try to see if we're on compute engine (do the detection only once
      since it requires a network test). */
@@ -208,21 +207,28 @@
     int need_compute_engine_creds = is_stack_running_on_compute_engine();
     compute_engine_detection_done = 1;
     if (need_compute_engine_creds) {
-      result = grpc_google_compute_engine_credentials_create(NULL);
+      call_creds = grpc_google_compute_engine_credentials_create(NULL);
     }
   }
 
 end:
-  if (!serving_cached_credentials && result != NULL) {
-    /* Blend with default ssl credentials and add a global reference so that it
-       can be cached and re-served. */
-    grpc_credentials *ssl_creds = grpc_ssl_credentials_create(NULL, NULL, NULL);
-    default_credentials = grpc_credentials_ref(
-        grpc_composite_credentials_create(ssl_creds, result, NULL));
-    GPR_ASSERT(default_credentials != NULL);
-    grpc_credentials_unref(ssl_creds);
-    grpc_credentials_unref(result);
-    result = default_credentials;
+  if (result == NULL) {
+    if (call_creds != NULL) {
+      /* Blend with default ssl credentials and add a global reference so that
+         it
+         can be cached and re-served. */
+      grpc_channel_credentials *ssl_creds =
+          grpc_ssl_credentials_create(NULL, NULL, NULL);
+      default_credentials = grpc_channel_credentials_ref(
+          grpc_composite_channel_credentials_create(ssl_creds, call_creds,
+                                                    NULL));
+      GPR_ASSERT(default_credentials != NULL);
+      grpc_channel_credentials_unref(ssl_creds);
+      grpc_call_credentials_unref(call_creds);
+      result = default_credentials;
+    } else {
+      gpr_log(GPR_ERROR, "Could not create google default credentials.");
+    }
   }
   gpr_mu_unlock(&g_mu);
   return result;
@@ -232,7 +238,7 @@
   gpr_once_init(&g_once, init_default_credentials);
   gpr_mu_lock(&g_mu);
   if (default_credentials != NULL) {
-    grpc_credentials_unref(default_credentials);
+    grpc_channel_credentials_unref(default_credentials);
     default_credentials = NULL;
   }
   gpr_mu_unlock(&g_mu);
diff --git a/src/core/security/security_connector.c b/src/core/security/security_connector.c
index 7c4cf6f..3c54a4d 100644
--- a/src/core/security/security_connector.c
+++ b/src/core/security/security_connector.c
@@ -203,16 +203,6 @@
   return NULL;
 }
 
-static int check_request_metadata_creds(grpc_credentials *creds) {
-  if (creds != NULL && !grpc_credentials_has_request_metadata(creds)) {
-    gpr_log(GPR_ERROR,
-            "Incompatible credentials for channel security connector: needs to "
-            "set request metadata.");
-    return 0;
-  }
-  return 1;
-}
-
 /* -- Fake implementation. -- */
 
 typedef struct {
@@ -222,7 +212,7 @@
 
 static void fake_channel_destroy(grpc_security_connector *sc) {
   grpc_channel_security_connector *c = (grpc_channel_security_connector *)sc;
-  grpc_credentials_unref(c->request_metadata_creds);
+  grpc_call_credentials_unref(c->request_metadata_creds);
   GRPC_AUTH_CONTEXT_UNREF(sc->auth_context, "connector");
   gpr_free(sc);
 }
@@ -306,7 +296,8 @@
     fake_server_destroy, fake_server_do_handshake, fake_check_peer};
 
 grpc_channel_security_connector *grpc_fake_channel_security_connector_create(
-    grpc_credentials *request_metadata_creds, int call_host_check_is_async) {
+    grpc_call_credentials *request_metadata_creds,
+    int call_host_check_is_async) {
   grpc_fake_channel_security_connector *c =
       gpr_malloc(sizeof(grpc_fake_channel_security_connector));
   memset(c, 0, sizeof(grpc_fake_channel_security_connector));
@@ -314,8 +305,8 @@
   c->base.base.is_client_side = 1;
   c->base.base.url_scheme = GRPC_FAKE_SECURITY_URL_SCHEME;
   c->base.base.vtable = &fake_channel_vtable;
-  GPR_ASSERT(check_request_metadata_creds(request_metadata_creds));
-  c->base.request_metadata_creds = grpc_credentials_ref(request_metadata_creds);
+  c->base.request_metadata_creds =
+      grpc_call_credentials_ref(request_metadata_creds);
   c->base.check_call_host = fake_channel_check_call_host;
   c->call_host_check_is_async = call_host_check_is_async;
   return &c->base;
@@ -349,7 +340,7 @@
 static void ssl_channel_destroy(grpc_security_connector *sc) {
   grpc_ssl_channel_security_connector *c =
       (grpc_ssl_channel_security_connector *)sc;
-  grpc_credentials_unref(c->base.request_metadata_creds);
+  grpc_call_credentials_unref(c->base.request_metadata_creds);
   if (c->handshaker_factory != NULL) {
     tsi_ssl_handshaker_factory_destroy(c->handshaker_factory);
   }
@@ -580,9 +571,9 @@
 }
 
 grpc_security_status grpc_ssl_channel_security_connector_create(
-    grpc_credentials *request_metadata_creds, const grpc_ssl_config *config,
-    const char *target_name, const char *overridden_target_name,
-    grpc_channel_security_connector **sc) {
+    grpc_call_credentials *request_metadata_creds,
+    const grpc_ssl_config *config, const char *target_name,
+    const char *overridden_target_name, grpc_channel_security_connector **sc) {
   size_t num_alpn_protocols = grpc_chttp2_num_alpn_versions();
   const unsigned char **alpn_protocol_strings =
       gpr_malloc(sizeof(const char *) * num_alpn_protocols);
@@ -606,9 +597,6 @@
     gpr_log(GPR_ERROR, "An ssl channel needs a config and a target name.");
     goto error;
   }
-  if (!check_request_metadata_creds(request_metadata_creds)) {
-    goto error;
-  }
   if (config->pem_root_certs == NULL) {
     pem_root_certs_size = grpc_get_default_ssl_roots(&pem_root_certs);
     if (pem_root_certs == NULL || pem_root_certs_size == 0) {
@@ -627,7 +615,8 @@
   c->base.base.vtable = &ssl_channel_vtable;
   c->base.base.is_client_side = 1;
   c->base.base.url_scheme = GRPC_SSL_URL_SCHEME;
-  c->base.request_metadata_creds = grpc_credentials_ref(request_metadata_creds);
+  c->base.request_metadata_creds =
+      grpc_call_credentials_ref(request_metadata_creds);
   c->base.check_call_host = ssl_channel_check_call_host;
   gpr_split_host_port(target_name, &c->target_name, &port);
   gpr_free(port);
diff --git a/src/core/security/security_connector.h b/src/core/security/security_connector.h
index 9218a3c..c5f00c5 100644
--- a/src/core/security/security_connector.h
+++ b/src/core/security/security_connector.h
@@ -145,7 +145,7 @@
 
 struct grpc_channel_security_connector {
   grpc_security_connector base; /* requires is_client_side to be non 0. */
-  grpc_credentials *request_metadata_creds;
+  grpc_call_credentials *request_metadata_creds;
   grpc_security_status (*check_call_host)(grpc_exec_ctx *exec_ctx,
                                           grpc_channel_security_connector *sc,
                                           const char *host,
@@ -167,7 +167,8 @@
 /* For TESTING ONLY!
    Creates a fake connector that emulates real channel security.  */
 grpc_channel_security_connector *grpc_fake_channel_security_connector_create(
-    grpc_credentials *request_metadata_creds, int call_host_check_is_async);
+    grpc_call_credentials *request_metadata_creds,
+    int call_host_check_is_async);
 
 /* For TESTING ONLY!
    Creates a fake connector that emulates real server security.  */
@@ -197,9 +198,9 @@
   specific error code otherwise.
 */
 grpc_security_status grpc_ssl_channel_security_connector_create(
-    grpc_credentials *request_metadata_creds, const grpc_ssl_config *config,
-    const char *target_name, const char *overridden_target_name,
-    grpc_channel_security_connector **sc);
+    grpc_call_credentials *request_metadata_creds,
+    const grpc_ssl_config *config, const char *target_name,
+    const char *overridden_target_name, grpc_channel_security_connector **sc);
 
 /* Gets the default ssl roots. */
 size_t grpc_get_default_ssl_roots(const unsigned char **pem_root_certs);
diff --git a/src/core/security/security_context.c b/src/core/security/security_context.c
index ff3ad64..2068c97 100644
--- a/src/core/security/security_context.c
+++ b/src/core/security/security_context.c
@@ -46,7 +46,7 @@
 /* --- grpc_call --- */
 
 grpc_call_error grpc_call_set_credentials(grpc_call *call,
-                                          grpc_credentials *creds) {
+                                          grpc_call_credentials *creds) {
   grpc_client_security_context *ctx = NULL;
   GRPC_API_TRACE("grpc_call_set_credentials(call=%p, creds=%p)", 2,
                  (call, creds));
@@ -54,20 +54,16 @@
     gpr_log(GPR_ERROR, "Method is client-side only.");
     return GRPC_CALL_ERROR_NOT_ON_SERVER;
   }
-  if (creds != NULL && !grpc_credentials_has_request_metadata_only(creds)) {
-    gpr_log(GPR_ERROR, "Incompatible credentials to set on a call.");
-    return GRPC_CALL_ERROR;
-  }
   ctx = (grpc_client_security_context *)grpc_call_context_get(
       call, GRPC_CONTEXT_SECURITY);
   if (ctx == NULL) {
     ctx = grpc_client_security_context_create();
-    ctx->creds = grpc_credentials_ref(creds);
+    ctx->creds = grpc_call_credentials_ref(creds);
     grpc_call_context_set(call, GRPC_CONTEXT_SECURITY, ctx,
                           grpc_client_security_context_destroy);
   } else {
-    grpc_credentials_unref(ctx->creds);
-    ctx->creds = grpc_credentials_ref(creds);
+    grpc_call_credentials_unref(ctx->creds);
+    ctx->creds = grpc_call_credentials_ref(creds);
   }
   return GRPC_CALL_OK;
 }
@@ -101,7 +97,7 @@
 
 void grpc_client_security_context_destroy(void *ctx) {
   grpc_client_security_context *c = (grpc_client_security_context *)ctx;
-  grpc_credentials_unref(c->creds);
+  grpc_call_credentials_unref(c->creds);
   GRPC_AUTH_CONTEXT_UNREF(c->auth_context, "client_security_context");
   gpr_free(ctx);
 }
diff --git a/src/core/security/security_context.h b/src/core/security/security_context.h
index 2bbdc4b..794258e 100644
--- a/src/core/security/security_context.h
+++ b/src/core/security/security_context.h
@@ -85,7 +85,7 @@
    Internal client-side security context. */
 
 typedef struct {
-  grpc_credentials *creds;
+  grpc_call_credentials *creds;
   grpc_auth_context *auth_context;
 } grpc_client_security_context;
 
diff --git a/src/core/security/server_secure_chttp2.c b/src/core/security/server_secure_chttp2.c
index 851e0cf..1ea269b 100644
--- a/src/core/security/server_secure_chttp2.c
+++ b/src/core/security/server_secure_chttp2.c
@@ -249,9 +249,11 @@
   }
 
   for (i = 0; i < resolved->naddrs; i++) {
-    port_temp = grpc_tcp_server_add_port(
+    grpc_tcp_listener *listener;
+    listener = grpc_tcp_server_add_port(
         tcp, (struct sockaddr *)&resolved->addrs[i].addr,
         resolved->addrs[i].len);
+    port_temp = grpc_tcp_listener_get_port(listener);
     if (port_temp >= 0) {
       if (port_num == -1) {
         port_num = port_temp;
diff --git a/src/core/support/slice_buffer.c b/src/core/support/slice_buffer.c
index 17c0b6c..856d3a2 100644
--- a/src/core/support/slice_buffer.c
+++ b/src/core/support/slice_buffer.c
@@ -220,7 +220,7 @@
     return;
   }
   src_idx = 0;
-  for (;;) {
+  while (src_idx < src->capacity) {
     gpr_slice slice = src->slices[src_idx];
     size_t slice_len = GPR_SLICE_LENGTH(slice);
     if (n > slice_len) {
diff --git a/src/core/surface/byte_buffer_reader.c b/src/core/surface/byte_buffer_reader.c
index 9f830df..57417f4 100644
--- a/src/core/surface/byte_buffer_reader.c
+++ b/src/core/surface/byte_buffer_reader.c
@@ -121,4 +121,3 @@
   }
   return out_slice;
 }
-
diff --git a/src/core/surface/call.c b/src/core/surface/call.c
index aa435d4..86d5fca 100644
--- a/src/core/surface/call.c
+++ b/src/core/surface/call.c
@@ -922,7 +922,8 @@
   size_t i;
   for (i = 0; i < MAX_CONCURRENT_BATCHES; i++) {
     if ((call->used_batches & (1 << i)) == 0) {
-      call->used_batches |= (gpr_uint8)(1 << i);
+      call->used_batches =
+          (gpr_uint8)(call->used_batches | (gpr_uint8)(1 << i));
       return &call->active_batches[i];
     }
   }
diff --git a/src/core/surface/secure_channel_create.c b/src/core/surface/secure_channel_create.c
index 1282ee9..0dd0a31 100644
--- a/src/core/surface/secure_channel_create.c
+++ b/src/core/surface/secure_channel_create.c
@@ -230,7 +230,7 @@
    Asynchronously: - resolve target
                    - connect to it (trying alternatives as presented)
                    - perform handshakes */
-grpc_channel *grpc_secure_channel_create(grpc_credentials *creds,
+grpc_channel *grpc_secure_channel_create(grpc_channel_credentials *creds,
                                          const char *target,
                                          const grpc_channel_args *args,
                                          void *reserved) {
@@ -261,9 +261,9 @@
         "Security connector exists in channel args.");
   }
 
-  if (grpc_credentials_create_security_connector(
-          creds, target, args, NULL, &security_connector,
-          &new_args_from_connector) != GRPC_SECURITY_OK) {
+  if (grpc_channel_credentials_create_security_connector(
+          creds, target, args, &security_connector, &new_args_from_connector) !=
+      GRPC_SECURITY_OK) {
     grpc_exec_ctx_finish(&exec_ctx);
     return grpc_lame_client_channel_create(
         target, GRPC_STATUS_INVALID_ARGUMENT,
diff --git a/src/core/surface/server_chttp2.c b/src/core/surface/server_chttp2.c
index 580b915..1408f9c 100644
--- a/src/core/surface/server_chttp2.c
+++ b/src/core/surface/server_chttp2.c
@@ -107,9 +107,11 @@
   }
 
   for (i = 0; i < resolved->naddrs; i++) {
-    port_temp = grpc_tcp_server_add_port(
+    grpc_tcp_listener *listener;
+    listener = grpc_tcp_server_add_port(
         tcp, (struct sockaddr *)&resolved->addrs[i].addr,
         resolved->addrs[i].len);
+    port_temp = grpc_tcp_listener_get_port(listener);
     if (port_temp >= 0) {
       if (port_num == -1) {
         port_num = port_temp;
diff --git a/src/core/surface/version.c b/src/core/surface/version.c
index e559d51..962a721 100644
--- a/src/core/surface/version.c
+++ b/src/core/surface/version.c
@@ -36,4 +36,4 @@
 
 #include <grpc/grpc.h>
 
-const char *grpc_version_string(void) { return "0.11.0.0"; }
+const char *grpc_version_string(void) { return "0.12.0.0"; }
diff --git a/src/core/transport/chttp2/hpack_encoder.c b/src/core/transport/chttp2/hpack_encoder.c
index 6c7c00b..758babc 100644
--- a/src/core/transport/chttp2/hpack_encoder.c
+++ b/src/core/transport/chttp2/hpack_encoder.c
@@ -36,8 +36,10 @@
 #include <assert.h>
 #include <string.h>
 
+#include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
 #include <grpc/support/useful.h>
+
 #include "src/core/transport/chttp2/bin_encoder.h"
 #include "src/core/transport/chttp2/hpack_table.h"
 #include "src/core/transport/chttp2/timeout_encoding.h"
@@ -154,6 +156,18 @@
   return gpr_slice_buffer_tiny_add(st->output, len);
 }
 
+static void evict_entry(grpc_chttp2_hpack_compressor *c) {
+  c->tail_remote_index++;
+  GPR_ASSERT(c->tail_remote_index > 0);
+  GPR_ASSERT(c->table_size >=
+             c->table_elem_size[c->tail_remote_index % c->cap_table_elems]);
+  GPR_ASSERT(c->table_elems > 0);
+  c->table_size = (gpr_uint16)(
+      c->table_size -
+      c->table_elem_size[c->tail_remote_index % c->cap_table_elems]);
+  c->table_elems--;
+}
+
 /* add an element to the decoder table */
 static void add_elem(grpc_chttp2_hpack_compressor *c, grpc_mdelem *elem) {
   gpr_uint32 key_hash = elem->key->hash;
@@ -164,26 +178,21 @@
 
   GPR_ASSERT(elem_size < 65536);
 
+  if (elem_size > c->max_table_size) {
+    while (c->table_size > 0) {
+      evict_entry(c);
+    }
+    return;
+  }
+
   /* Reserve space for this element in the remote table: if this overflows
      the current table, drop elements until it fits, matching the decompressor
      algorithm */
-  /* TODO(ctiller): constant */
-  while (c->table_size + elem_size > 4096) {
-    c->tail_remote_index++;
-    GPR_ASSERT(c->tail_remote_index > 0);
-    GPR_ASSERT(c->table_size >=
-               c->table_elem_size[c->tail_remote_index %
-                                  GRPC_CHTTP2_HPACKC_MAX_TABLE_ELEMS]);
-    GPR_ASSERT(c->table_elems > 0);
-    c->table_size =
-        (gpr_uint16)(c->table_size -
-                     c->table_elem_size[c->tail_remote_index %
-                                        GRPC_CHTTP2_HPACKC_MAX_TABLE_ELEMS]);
-    c->table_elems--;
+  while (c->table_size + elem_size > c->max_table_size) {
+    evict_entry(c);
   }
-  GPR_ASSERT(c->table_elems < GRPC_CHTTP2_HPACKC_MAX_TABLE_ELEMS);
-  c->table_elem_size[new_index % GRPC_CHTTP2_HPACKC_MAX_TABLE_ELEMS] =
-      (gpr_uint16)elem_size;
+  GPR_ASSERT(c->table_elems < c->max_table_size);
+  c->table_elem_size[new_index % c->cap_table_elems] = (gpr_uint16)elem_size;
   c->table_size = (gpr_uint16)(c->table_size + elem_size);
   c->table_elems++;
 
@@ -329,6 +338,14 @@
   add_header_data(st, gpr_slice_ref(value_slice));
 }
 
+static void emit_advertise_table_size_change(grpc_chttp2_hpack_compressor *c,
+                                             framer_state *st) {
+  gpr_uint32 len = GRPC_CHTTP2_VARINT_LENGTH(c->max_table_size, 3);
+  GRPC_CHTTP2_WRITE_VARINT(c->max_table_size, 3, 0x20,
+                           add_tiny_header_data(st, len), len);
+  c->advertise_table_size_change = 0;
+}
+
 static gpr_uint32 dynidx(grpc_chttp2_hpack_compressor *c,
                          gpr_uint32 elem_index) {
   return 1 + GRPC_CHTTP2_LAST_STATIC_ENTRY + c->tail_remote_index +
@@ -447,11 +464,23 @@
   return slice;
 }
 
+static gpr_uint32 elems_for_bytes(gpr_uint32 bytes) {
+  return (bytes + 31) / 32;
+}
+
 void grpc_chttp2_hpack_compressor_init(grpc_chttp2_hpack_compressor *c,
                                        grpc_mdctx *ctx) {
   memset(c, 0, sizeof(*c));
   c->mdctx = ctx;
   c->timeout_key_str = grpc_mdstr_from_string(ctx, "grpc-timeout");
+  c->max_table_size = GRPC_CHTTP2_HPACKC_INITIAL_TABLE_SIZE;
+  c->cap_table_elems = elems_for_bytes(c->max_table_size);
+  c->max_table_elems = c->cap_table_elems;
+  c->max_usable_size = GRPC_CHTTP2_HPACKC_INITIAL_TABLE_SIZE;
+  c->table_elem_size =
+      gpr_malloc(sizeof(*c->table_elem_size) * c->cap_table_elems);
+  memset(c->table_elem_size, 0,
+         sizeof(*c->table_elem_size) * c->cap_table_elems);
 }
 
 void grpc_chttp2_hpack_compressor_destroy(grpc_chttp2_hpack_compressor *c) {
@@ -461,6 +490,54 @@
     if (c->entries_elems[i]) GRPC_MDELEM_UNREF(c->entries_elems[i]);
   }
   GRPC_MDSTR_UNREF(c->timeout_key_str);
+  gpr_free(c->table_elem_size);
+}
+
+void grpc_chttp2_hpack_compressor_set_max_usable_size(
+    grpc_chttp2_hpack_compressor *c, gpr_uint32 max_table_size) {
+  c->max_usable_size = max_table_size;
+  grpc_chttp2_hpack_compressor_set_max_table_size(
+      c, GPR_MIN(c->max_table_size, max_table_size));
+}
+
+static void rebuild_elems(grpc_chttp2_hpack_compressor *c, gpr_uint32 new_cap) {
+  gpr_uint16 *table_elem_size = gpr_malloc(sizeof(*table_elem_size) * new_cap);
+  gpr_uint32 i;
+
+  memset(table_elem_size, 0, sizeof(*table_elem_size) * new_cap);
+  GPR_ASSERT(c->table_elems <= new_cap);
+
+  for (i = 0; i < c->table_elems; i++) {
+    gpr_uint32 ofs = c->tail_remote_index + i + 1;
+    table_elem_size[ofs % new_cap] = c->table_elem_size[ofs % c->cap_table_elems];
+  }
+
+  c->cap_table_elems = new_cap;
+  gpr_free(c->table_elem_size);
+  c->table_elem_size = table_elem_size;
+}
+
+void grpc_chttp2_hpack_compressor_set_max_table_size(
+    grpc_chttp2_hpack_compressor *c, gpr_uint32 max_table_size) {
+  max_table_size = GPR_MIN(max_table_size, c->max_usable_size);
+  if (max_table_size == c->max_table_size) {
+    return;
+  }
+  while (c->table_size > 0 && c->table_size > max_table_size) {
+    evict_entry(c);
+  }
+  c->max_table_size = max_table_size;
+  c->max_table_elems = elems_for_bytes(max_table_size);
+  if (c->max_table_elems > c->cap_table_elems) {
+    rebuild_elems(c, GPR_MAX(c->max_table_elems, 2 * c->cap_table_elems));
+  } else if (c->max_table_elems < c->cap_table_elems / 3) {
+    gpr_uint32 new_cap = GPR_MAX(c->max_table_elems, 16);
+    if (new_cap != c->cap_table_elems) {
+      rebuild_elems(c, new_cap);
+    }
+  }
+  c->advertise_table_size_change = 1;
+  gpr_log(GPR_DEBUG, "set max table size from encoder to %d", max_table_size);
 }
 
 void grpc_chttp2_encode_header(grpc_chttp2_hpack_compressor *c,
@@ -483,6 +560,9 @@
      slot. THIS MAY NOT BE THE SAME ELEMENT (if a decoder table slot got
      updated). After this loop, we'll do a batch unref of elements. */
   begin_frame(&st);
+  if (c->advertise_table_size_change != 0) {
+    emit_advertise_table_size_change(c, &st);
+  }
   grpc_metadata_batch_assert_ok(metadata);
   for (l = metadata->list.head; l; l = l->next) {
     hpack_enc(c, l->md, &st);
diff --git a/src/core/transport/chttp2/hpack_encoder.h b/src/core/transport/chttp2/hpack_encoder.h
index 59b122d..ce83d10 100644
--- a/src/core/transport/chttp2/hpack_encoder.h
+++ b/src/core/transport/chttp2/hpack_encoder.h
@@ -43,14 +43,26 @@
 
 #define GRPC_CHTTP2_HPACKC_NUM_FILTERS 256
 #define GRPC_CHTTP2_HPACKC_NUM_VALUES 256
-#define GRPC_CHTTP2_HPACKC_MAX_TABLE_ELEMS (4096 / 32)
+/* initial table size, per spec */
+#define GRPC_CHTTP2_HPACKC_INITIAL_TABLE_SIZE 4096
+/* maximum table size we'll actually use */
+#define GRPC_CHTTP2_HPACKC_MAX_TABLE_SIZE (1024 * 1024)
 
 typedef struct {
   gpr_uint32 filter_elems_sum;
+  gpr_uint32 max_table_size;
+  gpr_uint32 max_table_elems;
+  gpr_uint32 cap_table_elems;
+  /** if non-zero, advertise to the decoder that we'll start using a table
+      of this size */
+  gpr_uint8 advertise_table_size_change;
+  /** maximum number of bytes we'll use for the decode table (to guard against
+      peers ooming us by setting decode table size high) */
+  gpr_uint32 max_usable_size;
   /* one before the lowest usable table index */
   gpr_uint32 tail_remote_index;
-  gpr_uint16 table_size;
-  gpr_uint16 table_elems;
+  gpr_uint32 table_size;
+  gpr_uint32 table_elems;
 
   /* filter tables for elems: this tables provides an approximate
      popularity count for particular hashes, and are used to determine whether
@@ -71,12 +83,16 @@
   gpr_uint32 indices_keys[GRPC_CHTTP2_HPACKC_NUM_VALUES];
   gpr_uint32 indices_elems[GRPC_CHTTP2_HPACKC_NUM_VALUES];
 
-  gpr_uint16 table_elem_size[GRPC_CHTTP2_HPACKC_MAX_TABLE_ELEMS];
+  gpr_uint16 *table_elem_size;
 } grpc_chttp2_hpack_compressor;
 
 void grpc_chttp2_hpack_compressor_init(grpc_chttp2_hpack_compressor *c,
                                        grpc_mdctx *mdctx);
 void grpc_chttp2_hpack_compressor_destroy(grpc_chttp2_hpack_compressor *c);
+void grpc_chttp2_hpack_compressor_set_max_table_size(
+    grpc_chttp2_hpack_compressor *c, gpr_uint32 max_table_size);
+void grpc_chttp2_hpack_compressor_set_max_usable_size(
+    grpc_chttp2_hpack_compressor *c, gpr_uint32 max_table_size);
 
 void grpc_chttp2_encode_header(grpc_chttp2_hpack_compressor *c, gpr_uint32 id,
                                grpc_metadata_batch *metadata, int is_eof,
diff --git a/src/core/transport/chttp2/hpack_parser.c b/src/core/transport/chttp2/hpack_parser.c
index 6eebfc3..57a3a20 100644
--- a/src/core/transport/chttp2/hpack_parser.c
+++ b/src/core/transport/chttp2/hpack_parser.c
@@ -74,6 +74,8 @@
                        const gpr_uint8 *end);
 static int parse_error(grpc_chttp2_hpack_parser *p, const gpr_uint8 *cur,
                        const gpr_uint8 *end);
+static int parse_illegal_op(grpc_chttp2_hpack_parser *p, const gpr_uint8 *cur,
+                            const gpr_uint8 *end);
 
 static int parse_string_prefix(grpc_chttp2_hpack_parser *p,
                                const gpr_uint8 *cur, const gpr_uint8 *end);
@@ -156,7 +158,7 @@
     parse_lithdr_incidx_x, parse_lithdr_incidx_v, parse_lithdr_notidx,
     parse_lithdr_notidx_x, parse_lithdr_notidx_v, parse_lithdr_nvridx,
     parse_lithdr_nvridx_x, parse_lithdr_nvridx_v, parse_max_tbl_size,
-    parse_max_tbl_size_x,  parse_error};
+    parse_max_tbl_size_x,  parse_illegal_op};
 
 /* indexes the first byte to a parse state function - generated by
    gen_hpack_tables.c */
@@ -169,7 +171,7 @@
     LITHDR_NVRIDX,   LITHDR_NVRIDX, LITHDR_NVRIDX, LITHDR_NVRIDX,
     LITHDR_NVRIDX,   LITHDR_NVRIDX, LITHDR_NVRIDX, LITHDR_NVRIDX,
     LITHDR_NVRIDX,   LITHDR_NVRIDX, LITHDR_NVRIDX, LITHDR_NVRIDX_X,
-    ILLEGAL,         MAX_TBL_SIZE,  MAX_TBL_SIZE,  MAX_TBL_SIZE,
+    MAX_TBL_SIZE,    MAX_TBL_SIZE,  MAX_TBL_SIZE,  MAX_TBL_SIZE,
     MAX_TBL_SIZE,    MAX_TBL_SIZE,  MAX_TBL_SIZE,  MAX_TBL_SIZE,
     MAX_TBL_SIZE,    MAX_TBL_SIZE,  MAX_TBL_SIZE,  MAX_TBL_SIZE,
     MAX_TBL_SIZE,    MAX_TBL_SIZE,  MAX_TBL_SIZE,  MAX_TBL_SIZE,
@@ -622,13 +624,15 @@
 };
 
 /* emission helpers */
-static void on_hdr(grpc_chttp2_hpack_parser *p, grpc_mdelem *md,
-                   int add_to_table) {
+static int on_hdr(grpc_chttp2_hpack_parser *p, grpc_mdelem *md,
+                  int add_to_table) {
   if (add_to_table) {
-    GRPC_MDELEM_REF(md);
-    grpc_chttp2_hptbl_add(&p->table, md);
+    if (!grpc_chttp2_hptbl_add(&p->table, md)) {
+      return 0;
+    }
   }
   p->on_header(p->on_header_user_data, md);
+  return 1;
 }
 
 static grpc_mdstr *take_string(grpc_chttp2_hpack_parser *p,
@@ -714,9 +718,12 @@
 static int finish_indexed_field(grpc_chttp2_hpack_parser *p,
                                 const gpr_uint8 *cur, const gpr_uint8 *end) {
   grpc_mdelem *md = grpc_chttp2_hptbl_lookup(&p->table, p->index);
+  if (md == NULL) {
+    gpr_log(GPR_ERROR, "Invalid HPACK index received: %d", p->index);
+    return 0;
+  }
   GRPC_MDELEM_REF(md);
-  on_hdr(p, md, 0);
-  return parse_begin(p, cur, end);
+  return on_hdr(p, md, 0) && parse_begin(p, cur, end);
 }
 
 /* parse an indexed field with index < 127 */
@@ -742,21 +749,21 @@
 static int finish_lithdr_incidx(grpc_chttp2_hpack_parser *p,
                                 const gpr_uint8 *cur, const gpr_uint8 *end) {
   grpc_mdelem *md = grpc_chttp2_hptbl_lookup(&p->table, p->index);
-  on_hdr(p, grpc_mdelem_from_metadata_strings(p->table.mdctx,
-                                              GRPC_MDSTR_REF(md->key),
-                                              take_string(p, &p->value)),
-         1);
-  return parse_begin(p, cur, end);
+  return on_hdr(p, grpc_mdelem_from_metadata_strings(p->table.mdctx,
+                                                     GRPC_MDSTR_REF(md->key),
+                                                     take_string(p, &p->value)),
+                1) &&
+         parse_begin(p, cur, end);
 }
 
 /* finish a literal header with incremental indexing with no index */
 static int finish_lithdr_incidx_v(grpc_chttp2_hpack_parser *p,
                                   const gpr_uint8 *cur, const gpr_uint8 *end) {
-  on_hdr(p, grpc_mdelem_from_metadata_strings(p->table.mdctx,
-                                              take_string(p, &p->key),
-                                              take_string(p, &p->value)),
-         1);
-  return parse_begin(p, cur, end);
+  return on_hdr(p, grpc_mdelem_from_metadata_strings(p->table.mdctx,
+                                                     take_string(p, &p->key),
+                                                     take_string(p, &p->value)),
+                1) &&
+         parse_begin(p, cur, end);
 }
 
 /* parse a literal header with incremental indexing; index < 63 */
@@ -795,21 +802,21 @@
 static int finish_lithdr_notidx(grpc_chttp2_hpack_parser *p,
                                 const gpr_uint8 *cur, const gpr_uint8 *end) {
   grpc_mdelem *md = grpc_chttp2_hptbl_lookup(&p->table, p->index);
-  on_hdr(p, grpc_mdelem_from_metadata_strings(p->table.mdctx,
-                                              GRPC_MDSTR_REF(md->key),
-                                              take_string(p, &p->value)),
-         0);
-  return parse_begin(p, cur, end);
+  return on_hdr(p, grpc_mdelem_from_metadata_strings(p->table.mdctx,
+                                                     GRPC_MDSTR_REF(md->key),
+                                                     take_string(p, &p->value)),
+                0) &&
+         parse_begin(p, cur, end);
 }
 
 /* finish a literal header without incremental indexing with index = 0 */
 static int finish_lithdr_notidx_v(grpc_chttp2_hpack_parser *p,
                                   const gpr_uint8 *cur, const gpr_uint8 *end) {
-  on_hdr(p, grpc_mdelem_from_metadata_strings(p->table.mdctx,
-                                              take_string(p, &p->key),
-                                              take_string(p, &p->value)),
-         0);
-  return parse_begin(p, cur, end);
+  return on_hdr(p, grpc_mdelem_from_metadata_strings(p->table.mdctx,
+                                                     take_string(p, &p->key),
+                                                     take_string(p, &p->value)),
+                0) &&
+         parse_begin(p, cur, end);
 }
 
 /* parse a literal header without incremental indexing; index < 15 */
@@ -848,21 +855,21 @@
 static int finish_lithdr_nvridx(grpc_chttp2_hpack_parser *p,
                                 const gpr_uint8 *cur, const gpr_uint8 *end) {
   grpc_mdelem *md = grpc_chttp2_hptbl_lookup(&p->table, p->index);
-  on_hdr(p, grpc_mdelem_from_metadata_strings(p->table.mdctx,
-                                              GRPC_MDSTR_REF(md->key),
-                                              take_string(p, &p->value)),
-         0);
-  return parse_begin(p, cur, end);
+  return on_hdr(p, grpc_mdelem_from_metadata_strings(p->table.mdctx,
+                                                     GRPC_MDSTR_REF(md->key),
+                                                     take_string(p, &p->value)),
+                0) &&
+         parse_begin(p, cur, end);
 }
 
 /* finish a literal header that is never indexed with an extra value */
 static int finish_lithdr_nvridx_v(grpc_chttp2_hpack_parser *p,
                                   const gpr_uint8 *cur, const gpr_uint8 *end) {
-  on_hdr(p, grpc_mdelem_from_metadata_strings(p->table.mdctx,
-                                              take_string(p, &p->key),
-                                              take_string(p, &p->value)),
-         0);
-  return parse_begin(p, cur, end);
+  return on_hdr(p, grpc_mdelem_from_metadata_strings(p->table.mdctx,
+                                                     take_string(p, &p->key),
+                                                     take_string(p, &p->value)),
+                0) &&
+         parse_begin(p, cur, end);
 }
 
 /* parse a literal header that is never indexed; index < 15 */
@@ -901,14 +908,14 @@
 static int finish_max_tbl_size(grpc_chttp2_hpack_parser *p,
                                const gpr_uint8 *cur, const gpr_uint8 *end) {
   gpr_log(GPR_INFO, "MAX TABLE SIZE: %d", p->index);
-  abort(); /* not implemented */
-  return parse_begin(p, cur, end);
+  return grpc_chttp2_hptbl_set_current_table_size(&p->table, p->index) &&
+         parse_begin(p, cur, end);
 }
 
 /* parse a max table size change, max size < 15 */
 static int parse_max_tbl_size(grpc_chttp2_hpack_parser *p, const gpr_uint8 *cur,
                               const gpr_uint8 *end) {
-  p->index = (*cur) & 0xf;
+  p->index = (*cur) & 0x1f;
   return finish_max_tbl_size(p, cur + 1, end);
 }
 
@@ -918,7 +925,7 @@
   static const grpc_chttp2_hpack_parser_state and_then[] = {
       finish_max_tbl_size};
   p->next_state = and_then;
-  p->index = 0xf;
+  p->index = 0x1f;
   p->parsing.value = &p->index;
   return parse_value0(p, cur + 1, end);
 }
@@ -930,6 +937,13 @@
   return 0;
 }
 
+static int parse_illegal_op(grpc_chttp2_hpack_parser *p, const gpr_uint8 *cur,
+                            const gpr_uint8 *end) {
+  GPR_ASSERT(cur != end);
+  gpr_log(GPR_DEBUG, "Illegal hpack op code %d", *cur);
+  return parse_error(p, cur, end);
+}
+
 /* parse the 1st byte of a varint into p->parsing.value
    no overflow is possible */
 static int parse_value0(grpc_chttp2_hpack_parser *p, const gpr_uint8 *cur,
diff --git a/src/core/transport/chttp2/hpack_table.c b/src/core/transport/chttp2/hpack_table.c
index c442c2c..f2362b0 100644
--- a/src/core/transport/chttp2/hpack_table.c
+++ b/src/core/transport/chttp2/hpack_table.c
@@ -36,7 +36,9 @@
 #include <assert.h>
 #include <string.h>
 
+#include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
+
 #include "src/core/support/murmur_hash.h"
 
 static struct {
@@ -169,12 +171,22 @@
     {"www-authenticate", ""},
 };
 
+static gpr_uint32 entries_for_bytes(gpr_uint32 bytes) {
+  return (bytes + GRPC_CHTTP2_HPACK_ENTRY_OVERHEAD - 1) /
+         GRPC_CHTTP2_HPACK_ENTRY_OVERHEAD;
+}
+
 void grpc_chttp2_hptbl_init(grpc_chttp2_hptbl *tbl, grpc_mdctx *mdctx) {
   size_t i;
 
   memset(tbl, 0, sizeof(*tbl));
   tbl->mdctx = mdctx;
-  tbl->max_bytes = GRPC_CHTTP2_INITIAL_HPACK_TABLE_SIZE;
+  tbl->current_table_bytes = tbl->max_bytes =
+      GRPC_CHTTP2_INITIAL_HPACK_TABLE_SIZE;
+  tbl->max_entries = tbl->cap_entries =
+      entries_for_bytes(tbl->current_table_bytes);
+  tbl->ents = gpr_malloc(sizeof(*tbl->ents) * tbl->cap_entries);
+  memset(tbl->ents, 0, sizeof(*tbl->ents) * tbl->cap_entries);
   for (i = 1; i <= GRPC_CHTTP2_LAST_STATIC_ENTRY; i++) {
     tbl->static_ents[i - 1] = grpc_mdelem_from_strings(
         mdctx, static_table[i].key, static_table[i].value);
@@ -187,9 +199,9 @@
     GRPC_MDELEM_UNREF(tbl->static_ents[i]);
   }
   for (i = 0; i < tbl->num_ents; i++) {
-    GRPC_MDELEM_UNREF(
-        tbl->ents[(tbl->first_ent + i) % GRPC_CHTTP2_MAX_TABLE_COUNT]);
+    GRPC_MDELEM_UNREF(tbl->ents[(tbl->first_ent + i) % tbl->cap_entries]);
   }
+  gpr_free(tbl->ents);
 }
 
 grpc_mdelem *grpc_chttp2_hptbl_lookup(const grpc_chttp2_hptbl *tbl,
@@ -201,8 +213,8 @@
   /* Otherwise, find the value in the list of valid entries */
   tbl_index -= (GRPC_CHTTP2_LAST_STATIC_ENTRY + 1);
   if (tbl_index < tbl->num_ents) {
-    gpr_uint32 offset = (tbl->num_ents - 1u - tbl_index + tbl->first_ent) %
-                        GRPC_CHTTP2_MAX_TABLE_COUNT;
+    gpr_uint32 offset =
+        (tbl->num_ents - 1u - tbl_index + tbl->first_ent) % tbl->cap_entries;
     return tbl->ents[offset];
   }
   /* Invalid entry: return error */
@@ -216,21 +228,81 @@
                       GPR_SLICE_LENGTH(first_ent->value->slice) +
                       GRPC_CHTTP2_HPACK_ENTRY_OVERHEAD;
   GPR_ASSERT(elem_bytes <= tbl->mem_used);
-  tbl->mem_used = (gpr_uint16)(tbl->mem_used - elem_bytes);
-  tbl->first_ent =
-      (gpr_uint16)((tbl->first_ent + 1) % GRPC_CHTTP2_MAX_TABLE_COUNT);
+  tbl->mem_used -= (gpr_uint32)elem_bytes;
+  tbl->first_ent = ((tbl->first_ent + 1) % tbl->cap_entries);
   tbl->num_ents--;
   GRPC_MDELEM_UNREF(first_ent);
 }
 
-void grpc_chttp2_hptbl_add(grpc_chttp2_hptbl *tbl, grpc_mdelem *md) {
+static void rebuild_ents(grpc_chttp2_hptbl *tbl, gpr_uint32 new_cap) {
+  grpc_mdelem **ents = gpr_malloc(sizeof(*ents) * new_cap);
+  gpr_uint32 i;
+
+  for (i = 0; i < tbl->num_ents; i++) {
+    ents[i] = tbl->ents[(tbl->first_ent + i) % tbl->cap_entries];
+  }
+  gpr_free(tbl->ents);
+  tbl->ents = ents;
+  tbl->cap_entries = new_cap;
+  tbl->first_ent = 0;
+}
+
+void grpc_chttp2_hptbl_set_max_bytes(grpc_chttp2_hptbl *tbl,
+                                     gpr_uint32 max_bytes) {
+  if (tbl->max_bytes == max_bytes) {
+    return;
+  }
+  gpr_log(GPR_DEBUG, "Update hpack parser max size to %d", max_bytes);
+  while (tbl->mem_used > max_bytes) {
+    evict1(tbl);
+  }
+  tbl->max_bytes = max_bytes;
+}
+
+int grpc_chttp2_hptbl_set_current_table_size(grpc_chttp2_hptbl *tbl,
+                                             gpr_uint32 bytes) {
+  if (tbl->current_table_bytes == bytes) {
+    return 1;
+  }
+  if (bytes > tbl->max_bytes) {
+    gpr_log(GPR_ERROR,
+            "Attempt to make hpack table %d bytes when max is %d bytes", bytes,
+            tbl->max_bytes);
+    return 0;
+  }
+  gpr_log(GPR_DEBUG, "Update hpack parser table size to %d", bytes);
+  while (tbl->mem_used > bytes) {
+    evict1(tbl);
+  }
+  tbl->current_table_bytes = bytes;
+  tbl->max_entries = entries_for_bytes(bytes);
+  if (tbl->max_entries > tbl->cap_entries) {
+    rebuild_ents(tbl, GPR_MAX(tbl->max_entries, 2 * tbl->cap_entries));
+  } else if (tbl->max_entries < tbl->cap_entries / 3) {
+    gpr_uint32 new_cap = GPR_MAX(tbl->max_entries, 16u);
+    if (new_cap != tbl->cap_entries) {
+      rebuild_ents(tbl, new_cap);
+    }
+  }
+  return 1;
+}
+
+int grpc_chttp2_hptbl_add(grpc_chttp2_hptbl *tbl, grpc_mdelem *md) {
   /* determine how many bytes of buffer this entry represents */
   size_t elem_bytes = GPR_SLICE_LENGTH(md->key->slice) +
                       GPR_SLICE_LENGTH(md->value->slice) +
                       GRPC_CHTTP2_HPACK_ENTRY_OVERHEAD;
 
+  if (tbl->current_table_bytes > tbl->max_bytes) {
+    gpr_log(GPR_ERROR,
+            "HPACK max table size reduced to %d but not reflected by hpack "
+            "stream (still at %d)",
+            tbl->max_bytes, tbl->current_table_bytes);
+    return 0;
+  }
+
   /* we can't add elements bigger than the max table size */
-  if (elem_bytes > tbl->max_bytes) {
+  if (elem_bytes > tbl->current_table_bytes) {
     /* HPACK draft 10 section 4.4 states:
      * If the size of the new entry is less than or equal to the maximum
      * size, that entry is added to the table.  It is not an error to
@@ -243,44 +315,43 @@
     while (tbl->num_ents) {
       evict1(tbl);
     }
-    return;
+    return 1;
   }
 
   /* evict entries to ensure no overflow */
-  while (elem_bytes > (size_t)tbl->max_bytes - tbl->mem_used) {
+  while (elem_bytes > (size_t)tbl->current_table_bytes - tbl->mem_used) {
     evict1(tbl);
   }
 
   /* copy the finalized entry in */
-  tbl->ents[tbl->last_ent] = md;
+  tbl->ents[(tbl->first_ent + tbl->num_ents) % tbl->cap_entries] =
+      GRPC_MDELEM_REF(md);
 
   /* update accounting values */
-  tbl->last_ent =
-      (gpr_uint16)((tbl->last_ent + 1) % GRPC_CHTTP2_MAX_TABLE_COUNT);
   tbl->num_ents++;
-  tbl->mem_used = (gpr_uint16)(tbl->mem_used + elem_bytes);
+  tbl->mem_used += (gpr_uint32)elem_bytes;
+  return 1;
 }
 
 grpc_chttp2_hptbl_find_result grpc_chttp2_hptbl_find(
     const grpc_chttp2_hptbl *tbl, grpc_mdelem *md) {
   grpc_chttp2_hptbl_find_result r = {0, 0};
-  gpr_uint16 i;
+  gpr_uint32 i;
 
   /* See if the string is in the static table */
   for (i = 0; i < GRPC_CHTTP2_LAST_STATIC_ENTRY; i++) {
     grpc_mdelem *ent = tbl->static_ents[i];
     if (md->key != ent->key) continue;
-    r.index = (gpr_uint16)(i + 1);
+    r.index = i + 1u;
     r.has_value = md->value == ent->value;
     if (r.has_value) return r;
   }
 
   /* Scan the dynamic table */
   for (i = 0; i < tbl->num_ents; i++) {
-    gpr_uint16 idx =
-        (gpr_uint16)(tbl->num_ents - i + GRPC_CHTTP2_LAST_STATIC_ENTRY);
-    grpc_mdelem *ent =
-        tbl->ents[(tbl->first_ent + i) % GRPC_CHTTP2_MAX_TABLE_COUNT];
+    gpr_uint32 idx =
+        (gpr_uint32)(tbl->num_ents - i + GRPC_CHTTP2_LAST_STATIC_ENTRY);
+    grpc_mdelem *ent = tbl->ents[(tbl->first_ent + i) % tbl->cap_entries];
     if (md->key != ent->key) continue;
     r.index = idx;
     r.has_value = md->value == ent->value;
diff --git a/src/core/transport/chttp2/hpack_table.h b/src/core/transport/chttp2/hpack_table.h
index 4f882e2..e03b8c1 100644
--- a/src/core/transport/chttp2/hpack_table.h
+++ b/src/core/transport/chttp2/hpack_table.h
@@ -49,47 +49,59 @@
 #define GRPC_CHTTP2_MAX_HPACK_TABLE_SIZE GRPC_CHTTP2_INITIAL_HPACK_TABLE_SIZE
 /* Per entry overhead bytes as per the spec */
 #define GRPC_CHTTP2_HPACK_ENTRY_OVERHEAD 32
+#if 0
 /* Maximum number of entries we could possibly fit in the table, given defined
    overheads */
 #define GRPC_CHTTP2_MAX_TABLE_COUNT                                            \
   ((GRPC_CHTTP2_MAX_HPACK_TABLE_SIZE + GRPC_CHTTP2_HPACK_ENTRY_OVERHEAD - 1) / \
    GRPC_CHTTP2_HPACK_ENTRY_OVERHEAD)
+#endif
 
 /* hpack decoder table */
 typedef struct {
   grpc_mdctx *mdctx;
   /* the first used entry in ents */
-  gpr_uint16 first_ent;
-  /* the last used entry in ents */
-  gpr_uint16 last_ent;
+  gpr_uint32 first_ent;
   /* how many entries are in the table */
-  gpr_uint16 num_ents;
+  gpr_uint32 num_ents;
   /* the amount of memory used by the table, according to the hpack algorithm */
-  gpr_uint16 mem_used;
+  gpr_uint32 mem_used;
   /* the max memory allowed to be used by the table, according to the hpack
      algorithm */
-  gpr_uint16 max_bytes;
+  gpr_uint32 max_bytes;
+  /* the currently agreed size of the table, according to the hpack algorithm */
+  gpr_uint32 current_table_bytes;
+  /* Maximum number of entries we could possibly fit in the table, given defined
+     overheads */
+  gpr_uint32 max_entries;
+  /* Number of entries allocated in ents */
+  gpr_uint32 cap_entries;
   /* a circular buffer of headers - this is stored in the opposite order to
      what hpack specifies, in order to simplify table management a little...
      meaning lookups need to SUBTRACT from the end position */
-  grpc_mdelem *ents[GRPC_CHTTP2_MAX_TABLE_COUNT];
+  grpc_mdelem **ents;
   grpc_mdelem *static_ents[GRPC_CHTTP2_LAST_STATIC_ENTRY];
 } grpc_chttp2_hptbl;
 
 /* initialize a hpack table */
 void grpc_chttp2_hptbl_init(grpc_chttp2_hptbl *tbl, grpc_mdctx *mdctx);
 void grpc_chttp2_hptbl_destroy(grpc_chttp2_hptbl *tbl);
+void grpc_chttp2_hptbl_set_max_bytes(grpc_chttp2_hptbl *tbl,
+                                     gpr_uint32 max_bytes);
+int grpc_chttp2_hptbl_set_current_table_size(grpc_chttp2_hptbl *tbl,
+                                             gpr_uint32 bytes);
 
 /* lookup a table entry based on its hpack index */
 grpc_mdelem *grpc_chttp2_hptbl_lookup(const grpc_chttp2_hptbl *tbl,
                                       gpr_uint32 index);
 /* add a table entry to the index */
-void grpc_chttp2_hptbl_add(grpc_chttp2_hptbl *tbl, grpc_mdelem *md);
+int grpc_chttp2_hptbl_add(grpc_chttp2_hptbl *tbl,
+                          grpc_mdelem *md) GRPC_MUST_USE_RESULT;
 /* Find a key/value pair in the table... returns the index in the table of the
    most similar entry, or 0 if the value was not found */
 typedef struct {
-  gpr_uint16 index;
-  gpr_uint8 has_value;
+  gpr_uint32 index;
+  int has_value;
 } grpc_chttp2_hptbl_find_result;
 grpc_chttp2_hptbl_find_result grpc_chttp2_hptbl_find(
     const grpc_chttp2_hptbl *tbl, grpc_mdelem *md);
diff --git a/src/core/transport/chttp2/internal.h b/src/core/transport/chttp2/internal.h
index 9723479..b2ac8ee 100644
--- a/src/core/transport/chttp2/internal.h
+++ b/src/core/transport/chttp2/internal.h
@@ -230,6 +230,9 @@
   /** was a goaway frame received? */
   gpr_uint8 goaway_received;
 
+  /** the last sent max_table_size setting */
+  gpr_uint32 last_sent_max_table_size;
+
   /** initial window change */
   gpr_int64 initial_window_update;
 
@@ -486,7 +489,8 @@
 /** Someone is unlocking the transport mutex: check to see if writes
     are required, and schedule them if so */
 int grpc_chttp2_unlocking_check_writes(grpc_chttp2_transport_global *global,
-                                       grpc_chttp2_transport_writing *writing);
+                                       grpc_chttp2_transport_writing *writing,
+                                       int is_parsing);
 void grpc_chttp2_perform_writes(
     grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_writing *transport_writing,
     grpc_endpoint *endpoint);
diff --git a/src/core/transport/chttp2/parsing.c b/src/core/transport/chttp2/parsing.c
index 8cef8fb..1e06532 100644
--- a/src/core/transport/chttp2/parsing.c
+++ b/src/core/transport/chttp2/parsing.c
@@ -78,6 +78,9 @@
   GPR_TIMER_BEGIN("grpc_chttp2_prepare_to_read", 0);
 
   transport_parsing->next_stream_id = transport_global->next_stream_id;
+  transport_parsing->last_sent_max_table_size =
+      transport_global->settings[GRPC_SENT_SETTINGS]
+                                [GRPC_CHTTP2_SETTINGS_HEADER_TABLE_SIZE];
 
   /* update the parsing view of incoming window */
   while (grpc_chttp2_list_pop_unannounced_incoming_window_available(
@@ -127,6 +130,7 @@
            transport_global->settings[GRPC_SENT_SETTINGS],
            GRPC_CHTTP2_NUM_SETTINGS * sizeof(gpr_uint32));
     transport_parsing->settings_ack_received = 0;
+    transport_global->sent_local_settings = 0;
   }
 
   /* move goaway to the global state if we received one (it will be
@@ -819,6 +823,9 @@
   }
   if (transport_parsing->incoming_frame_flags & GRPC_CHTTP2_FLAG_ACK) {
     transport_parsing->settings_ack_received = 1;
+    grpc_chttp2_hptbl_set_max_bytes(
+        &transport_parsing->hpack_parser.table,
+        transport_parsing->last_sent_max_table_size);
   }
   transport_parsing->parser = grpc_chttp2_settings_parser_parse;
   transport_parsing->parser_data = &transport_parsing->simple.settings;
diff --git a/src/core/transport/chttp2/writing.c b/src/core/transport/chttp2/writing.c
index 353e476..3cb28f8 100644
--- a/src/core/transport/chttp2/writing.c
+++ b/src/core/transport/chttp2/writing.c
@@ -45,7 +45,7 @@
 
 int grpc_chttp2_unlocking_check_writes(
     grpc_chttp2_transport_global *transport_global,
-    grpc_chttp2_transport_writing *transport_writing) {
+    grpc_chttp2_transport_writing *transport_writing, int is_parsing) {
   grpc_chttp2_stream_global *stream_global;
   grpc_chttp2_stream_writing *stream_writing;
 
@@ -55,8 +55,13 @@
   gpr_slice_buffer_swap(&transport_global->qbuf, &transport_writing->outbuf);
   GPR_ASSERT(transport_global->qbuf.count == 0);
 
+  grpc_chttp2_hpack_compressor_set_max_table_size(
+      &transport_writing->hpack_compressor,
+      transport_global->settings[GRPC_PEER_SETTINGS]
+                                [GRPC_CHTTP2_SETTINGS_HEADER_TABLE_SIZE]);
+
   if (transport_global->dirtied_local_settings &&
-      !transport_global->sent_local_settings) {
+      !transport_global->sent_local_settings && !is_parsing) {
     gpr_slice_buffer_add(
         &transport_writing->outbuf,
         grpc_chttp2_settings_create(
diff --git a/src/core/transport/chttp2_transport.c b/src/core/transport/chttp2_transport.c
index 98a0186..77c68c9 100644
--- a/src/core/transport/chttp2_transport.c
+++ b/src/core/transport/chttp2_transport.c
@@ -350,6 +350,31 @@
           t->global.stream_lookahead =
               (gpr_uint32)channel_args->args[i].value.integer;
         }
+      } else if (0 == strcmp(channel_args->args[i].key,
+                             GRPC_ARG_HTTP2_HPACK_TABLE_SIZE_DECODER)) {
+        if (channel_args->args[i].type != GRPC_ARG_INTEGER) {
+          gpr_log(GPR_ERROR, "%s: must be an integer",
+                  GRPC_ARG_HTTP2_HPACK_TABLE_SIZE_DECODER);
+        } else if (channel_args->args[i].value.integer < 0) {
+          gpr_log(GPR_DEBUG, "%s: must be non-negative",
+                  GRPC_ARG_HTTP2_HPACK_TABLE_SIZE_DECODER);
+        } else {
+          push_setting(t, GRPC_CHTTP2_SETTINGS_HEADER_TABLE_SIZE,
+                       (gpr_uint32)channel_args->args[i].value.integer);
+        }
+      } else if (0 == strcmp(channel_args->args[i].key,
+                             GRPC_ARG_HTTP2_HPACK_TABLE_SIZE_ENCODER)) {
+        if (channel_args->args[i].type != GRPC_ARG_INTEGER) {
+          gpr_log(GPR_ERROR, "%s: must be an integer",
+                  GRPC_ARG_HTTP2_HPACK_TABLE_SIZE_ENCODER);
+        } else if (channel_args->args[i].value.integer < 0) {
+          gpr_log(GPR_DEBUG, "%s: must be non-negative",
+                  GRPC_ARG_HTTP2_HPACK_TABLE_SIZE_ENCODER);
+        } else {
+          grpc_chttp2_hpack_compressor_set_max_usable_size(
+              &t->writing.hpack_compressor,
+              (gpr_uint32)channel_args->args[i].value.integer);
+        }
       }
     }
   }
@@ -575,7 +600,8 @@
 static void unlock(grpc_exec_ctx *exec_ctx, grpc_chttp2_transport *t) {
   GPR_TIMER_BEGIN("unlock", 0);
   if (!t->writing_active && !t->closed &&
-      grpc_chttp2_unlocking_check_writes(&t->global, &t->writing)) {
+      grpc_chttp2_unlocking_check_writes(&t->global, &t->writing,
+                                         t->parsing_active)) {
     t->writing_active = 1;
     REF_TRANSPORT(t, "writing");
     grpc_exec_ctx_enqueue(exec_ctx, &t->writing_action, 1);
@@ -747,6 +773,8 @@
   return 0;
 }
 
+static void do_nothing(grpc_exec_ctx *exec_ctx, void *arg, int success) {}
+
 static void perform_stream_op_locked(
     grpc_exec_ctx *exec_ctx, grpc_chttp2_transport_global *transport_global,
     grpc_chttp2_stream_global *stream_global, grpc_transport_stream_op *op) {
@@ -755,6 +783,9 @@
   GPR_TIMER_BEGIN("perform_stream_op_locked", 0);
 
   on_complete = op->on_complete;
+  if (on_complete == NULL) {
+    on_complete = grpc_closure_create(do_nothing, NULL);
+  }
   /* use final_data as a barrier until enqueue time; the inital counter is
      dropped at the end of this function */
   on_complete->final_data = 2;
@@ -818,7 +849,7 @@
     }
     if (stream_global->write_closed) {
       grpc_chttp2_complete_closure_step(
-          exec_ctx, &stream_global->send_trailing_metadata_finished, 
+          exec_ctx, &stream_global->send_trailing_metadata_finished,
           grpc_metadata_batch_is_empty(op->send_trailing_metadata));
     } else if (stream_global->id != 0) {
       /* TODO(ctiller): check if there's flow control for any outstanding
@@ -1045,7 +1076,8 @@
      to the upper layers - drop what we've got, and then publish
      what we want - which is safe because we haven't told anyone
      about the metadata yet */
-  if (!stream_global->published_trailing_metadata || stream_global->recv_trailing_metadata_finished != NULL) {
+  if (!stream_global->published_trailing_metadata ||
+      stream_global->recv_trailing_metadata_finished != NULL) {
     grpc_mdctx *mdctx =
         TRANSPORT_FROM_GLOBAL(transport_global)->metadata_context;
     char status_string[GPR_LTOA_MIN_BUFSIZE];
diff --git a/src/core/tsi/test_creds/server1.pem b/src/core/tsi/test_creds/server1.pem
index 8e582e5..f3d43fc 100644
--- a/src/core/tsi/test_creds/server1.pem
+++ b/src/core/tsi/test_creds/server1.pem
@@ -1,16 +1,16 @@
 -----BEGIN CERTIFICATE-----
-MIICmzCCAgSgAwIBAgIBAzANBgkqhkiG9w0BAQUFADBWMQswCQYDVQQGEwJBVTET
-MBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQ
-dHkgTHRkMQ8wDQYDVQQDDAZ0ZXN0Y2EwHhcNMTQwNzIyMDYwMDU3WhcNMjQwNzE5
-MDYwMDU3WjBkMQswCQYDVQQGEwJVUzERMA8GA1UECBMISWxsaW5vaXMxEDAOBgNV
-BAcTB0NoaWNhZ28xFDASBgNVBAoTC0dvb2dsZSBJbmMuMRowGAYDVQQDFBEqLnRl
-c3QuZ29vZ2xlLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA4cMVJygs
-JUmlgMMzgdi0h1XoCR7+ww1pop04OMMyy7H/i0PJ2W6Y35+b4CM8QrkYeEafUGDO
-RYX6yV/cHGGsD/x02ye6ey1UDtkGAD/mpDEx8YCrjAc1Vfvt8Fk6Cn1WVIxV/J30
-3xjBsFgByQ55RBp1OLZfVLo6AleBDSbcxaECAwEAAaNrMGkwCQYDVR0TBAIwADAL
-BgNVHQ8EBAMCBeAwTwYDVR0RBEgwRoIQKi50ZXN0Lmdvb2dsZS5mcoIYd2F0ZXJ6
-b29pLnRlc3QuZ29vZ2xlLmJlghIqLnRlc3QueW91dHViZS5jb22HBMCoAQMwDQYJ
-KoZIhvcNAQEFBQADgYEAM2Ii0LgTGbJ1j4oqX9bxVcxm+/R5Yf8oi0aZqTJlnLYS
-wXcBykxTx181s7WyfJ49WwrYXo78zTDAnf1ma0fPq3e4mpspvyndLh1a+OarHa1e
-aT0DIIYk7qeEa1YcVljx2KyLd0r1BBAfrwyGaEPVeJQVYWaOJRU2we/KD4ojf9s=
+MIICnDCCAgWgAwIBAgIBBzANBgkqhkiG9w0BAQsFADBWMQswCQYDVQQGEwJBVTET
+MBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQ
+dHkgTHRkMQ8wDQYDVQQDEwZ0ZXN0Y2EwHhcNMTUxMTA0MDIyMDI0WhcNMjUxMTAx
+MDIyMDI0WjBlMQswCQYDVQQGEwJVUzERMA8GA1UECBMISWxsaW5vaXMxEDAOBgNV
+BAcTB0NoaWNhZ28xFTATBgNVBAoTDEV4YW1wbGUsIENvLjEaMBgGA1UEAxQRKi50
+ZXN0Lmdvb2dsZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAOHDFSco
+LCVJpYDDM4HYtIdV6Ake/sMNaaKdODjDMsux/4tDydlumN+fm+AjPEK5GHhGn1Bg
+zkWF+slf3BxhrA/8dNsnunstVA7ZBgA/5qQxMfGAq4wHNVX77fBZOgp9VlSMVfyd
+9N8YwbBYAckOeUQadTi2X1S6OgJXgQ0m3MWhAgMBAAGjazBpMAkGA1UdEwQCMAAw
+CwYDVR0PBAQDAgXgME8GA1UdEQRIMEaCECoudGVzdC5nb29nbGUuZnKCGHdhdGVy
+em9vaS50ZXN0Lmdvb2dsZS5iZYISKi50ZXN0LnlvdXR1YmUuY29thwTAqAEDMA0G
+CSqGSIb3DQEBCwUAA4GBAJFXVifQNub1LUP4JlnX5lXNlo8FxZ2a12AFQs+bzoJ6
+hM044EDjqyxUqSbVePK0ni3w1fHQB5rY9yYC5f8G7aqqTY1QOhoUk8ZTSTRpnkTh
+y4jjdvTZeLDVBlueZUTDRmy2feY5aZIU18vFDK08dTG0A87pppuv1LNIR3loveU8
 -----END CERTIFICATE-----
diff --git a/src/cpp/client/client_context.cc b/src/cpp/client/client_context.cc
index 574656a..9bb358b 100644
--- a/src/cpp/client/client_context.cc
+++ b/src/cpp/client/client_context.cc
@@ -48,6 +48,7 @@
 ClientContext::ClientContext()
     : initial_metadata_received_(false),
       call_(nullptr),
+      call_canceled_(false),
       deadline_(gpr_inf_future(GPR_CLOCK_REALTIME)),
       propagate_from_call_(nullptr) {}
 
@@ -72,6 +73,7 @@
 
 void ClientContext::set_call(grpc_call* call,
                              const std::shared_ptr<Channel>& channel) {
+  grpc::unique_lock<grpc::mutex> lock(mu_);
   GPR_ASSERT(call_ == nullptr);
   call_ = call;
   channel_ = channel;
@@ -79,6 +81,9 @@
     grpc_call_cancel_with_status(call, GRPC_STATUS_CANCELLED,
                                  "Failed to set credentials to rpc.", nullptr);
   }
+  if (call_canceled_) {
+    grpc_call_cancel(call_, nullptr);
+  }
 }
 
 void ClientContext::set_compression_algorithm(
@@ -101,8 +106,11 @@
 }
 
 void ClientContext::TryCancel() {
+  grpc::unique_lock<grpc::mutex> lock(mu_);
   if (call_) {
     grpc_call_cancel(call_, nullptr);
+  } else {
+    call_canceled_ = true;
   }
 }
 
diff --git a/src/cpp/client/create_channel.cc b/src/cpp/client/create_channel.cc
index d2b2d30..3bbca80 100644
--- a/src/cpp/client/create_channel.cc
+++ b/src/cpp/client/create_channel.cc
@@ -44,12 +44,14 @@
 class ChannelArguments;
 
 std::shared_ptr<Channel> CreateChannel(
-    const grpc::string& target, const std::shared_ptr<Credentials>& creds) {
+    const grpc::string& target,
+    const std::shared_ptr<ChannelCredentials>& creds) {
   return CreateCustomChannel(target, creds, ChannelArguments());
 }
 
 std::shared_ptr<Channel> CreateCustomChannel(
-    const grpc::string& target, const std::shared_ptr<Credentials>& creds,
+    const grpc::string& target,
+    const std::shared_ptr<ChannelCredentials>& creds,
     const ChannelArguments& args) {
   GrpcLibrary init_lib;  // We need to call init in case of a bad creds.
   ChannelArguments cp_args = args;
diff --git a/src/cpp/client/credentials.cc b/src/cpp/client/credentials.cc
index 7a8149e..0c08db1 100644
--- a/src/cpp/client/credentials.cc
+++ b/src/cpp/client/credentials.cc
@@ -35,6 +35,8 @@
 
 namespace grpc {
 
-Credentials::~Credentials() {}
+ChannelCredentials::~ChannelCredentials() {}
+
+CallCredentials::~CallCredentials() {}
 
 }  // namespace grpc
diff --git a/src/cpp/client/insecure_credentials.cc b/src/cpp/client/insecure_credentials.cc
index c476f3c..1293203 100644
--- a/src/cpp/client/insecure_credentials.cc
+++ b/src/cpp/client/insecure_credentials.cc
@@ -43,7 +43,7 @@
 namespace grpc {
 
 namespace {
-class InsecureCredentialsImpl GRPC_FINAL : public Credentials {
+class InsecureChannelCredentialsImpl GRPC_FINAL : public ChannelCredentials {
  public:
   std::shared_ptr<grpc::Channel> CreateChannel(
       const string& target, const grpc::ChannelArguments& args) GRPC_OVERRIDE {
@@ -54,15 +54,15 @@
         grpc_insecure_channel_create(target.c_str(), &channel_args, nullptr));
   }
 
-  // InsecureCredentials should not be applied to a call.
-  bool ApplyToCall(grpc_call* call) GRPC_OVERRIDE { return false; }
-
-  SecureCredentials* AsSecureCredentials() GRPC_OVERRIDE { return nullptr; }
+  SecureChannelCredentials* AsSecureCredentials() GRPC_OVERRIDE {
+    return nullptr;
+  }
 };
 }  // namespace
 
-std::shared_ptr<Credentials> InsecureCredentials() {
-  return std::shared_ptr<Credentials>(new InsecureCredentialsImpl());
+std::shared_ptr<ChannelCredentials> InsecureChannelCredentials() {
+  return std::shared_ptr<ChannelCredentials>(
+      new InsecureChannelCredentialsImpl());
 }
 
 }  // namespace grpc
diff --git a/src/cpp/client/secure_credentials.cc b/src/cpp/client/secure_credentials.cc
index 8299ebe..a1b9a30 100644
--- a/src/cpp/client/secure_credentials.cc
+++ b/src/cpp/client/secure_credentials.cc
@@ -40,7 +40,7 @@
 
 namespace grpc {
 
-std::shared_ptr<grpc::Channel> SecureCredentials::CreateChannel(
+std::shared_ptr<grpc::Channel> SecureChannelCredentials::CreateChannel(
     const string& target, const grpc::ChannelArguments& args) {
   grpc_channel_args channel_args;
   args.SetChannelArgs(&channel_args);
@@ -50,96 +50,104 @@
                                  nullptr));
 }
 
-bool SecureCredentials::ApplyToCall(grpc_call* call) {
+bool SecureCallCredentials::ApplyToCall(grpc_call* call) {
   return grpc_call_set_credentials(call, c_creds_) == GRPC_CALL_OK;
 }
 
 namespace {
-std::shared_ptr<Credentials> WrapCredentials(grpc_credentials* creds) {
-  return creds == nullptr
-             ? nullptr
-             : std::shared_ptr<Credentials>(new SecureCredentials(creds));
+std::shared_ptr<ChannelCredentials> WrapChannelCredentials(
+    grpc_channel_credentials* creds) {
+  return creds == nullptr ? nullptr : std::shared_ptr<ChannelCredentials>(
+                                          new SecureChannelCredentials(creds));
+}
+
+std::shared_ptr<CallCredentials> WrapCallCredentials(
+    grpc_call_credentials* creds) {
+  return creds == nullptr ? nullptr : std::shared_ptr<CallCredentials>(
+                                          new SecureCallCredentials(creds));
 }
 }  // namespace
 
-std::shared_ptr<Credentials> GoogleDefaultCredentials() {
+std::shared_ptr<ChannelCredentials> GoogleDefaultCredentials() {
   GrpcLibrary init;  // To call grpc_init().
-  return WrapCredentials(grpc_google_default_credentials_create());
+  return WrapChannelCredentials(grpc_google_default_credentials_create());
 }
 
 // Builds SSL Credentials given SSL specific options
-std::shared_ptr<Credentials> SslCredentials(
+std::shared_ptr<ChannelCredentials> SslCredentials(
     const SslCredentialsOptions& options) {
   GrpcLibrary init;  // To call grpc_init().
   grpc_ssl_pem_key_cert_pair pem_key_cert_pair = {
       options.pem_private_key.c_str(), options.pem_cert_chain.c_str()};
 
-  grpc_credentials* c_creds = grpc_ssl_credentials_create(
+  grpc_channel_credentials* c_creds = grpc_ssl_credentials_create(
       options.pem_root_certs.empty() ? nullptr : options.pem_root_certs.c_str(),
       options.pem_private_key.empty() ? nullptr : &pem_key_cert_pair, nullptr);
-  return WrapCredentials(c_creds);
+  return WrapChannelCredentials(c_creds);
 }
 
 // Builds credentials for use when running in GCE
-std::shared_ptr<Credentials> GoogleComputeEngineCredentials() {
+std::shared_ptr<CallCredentials> GoogleComputeEngineCredentials() {
   GrpcLibrary init;  // To call grpc_init().
-  return WrapCredentials(
+  return WrapCallCredentials(
       grpc_google_compute_engine_credentials_create(nullptr));
 }
 
 // Builds JWT credentials.
-std::shared_ptr<Credentials> ServiceAccountJWTAccessCredentials(
+std::shared_ptr<CallCredentials> ServiceAccountJWTAccessCredentials(
     const grpc::string& json_key, long token_lifetime_seconds) {
   GrpcLibrary init;  // To call grpc_init().
   if (token_lifetime_seconds <= 0) {
     gpr_log(GPR_ERROR,
             "Trying to create JWTCredentials with non-positive lifetime");
-    return WrapCredentials(nullptr);
+    return WrapCallCredentials(nullptr);
   }
   gpr_timespec lifetime =
       gpr_time_from_seconds(token_lifetime_seconds, GPR_TIMESPAN);
-  return WrapCredentials(grpc_service_account_jwt_access_credentials_create(
+  return WrapCallCredentials(grpc_service_account_jwt_access_credentials_create(
       json_key.c_str(), lifetime, nullptr));
 }
 
 // Builds refresh token credentials.
-std::shared_ptr<Credentials> GoogleRefreshTokenCredentials(
+std::shared_ptr<CallCredentials> GoogleRefreshTokenCredentials(
     const grpc::string& json_refresh_token) {
   GrpcLibrary init;  // To call grpc_init().
-  return WrapCredentials(grpc_google_refresh_token_credentials_create(
+  return WrapCallCredentials(grpc_google_refresh_token_credentials_create(
       json_refresh_token.c_str(), nullptr));
 }
 
 // Builds access token credentials.
-std::shared_ptr<Credentials> AccessTokenCredentials(
+std::shared_ptr<CallCredentials> AccessTokenCredentials(
     const grpc::string& access_token) {
   GrpcLibrary init;  // To call grpc_init().
-  return WrapCredentials(
+  return WrapCallCredentials(
       grpc_access_token_credentials_create(access_token.c_str(), nullptr));
 }
 
 // Builds IAM credentials.
-std::shared_ptr<Credentials> GoogleIAMCredentials(
+std::shared_ptr<CallCredentials> GoogleIAMCredentials(
     const grpc::string& authorization_token,
     const grpc::string& authority_selector) {
   GrpcLibrary init;  // To call grpc_init().
-  return WrapCredentials(grpc_google_iam_credentials_create(
+  return WrapCallCredentials(grpc_google_iam_credentials_create(
       authorization_token.c_str(), authority_selector.c_str(), nullptr));
 }
 
-// Combines two credentials objects into a composite credentials.
-std::shared_ptr<Credentials> CompositeCredentials(
-    const std::shared_ptr<Credentials>& creds1,
-    const std::shared_ptr<Credentials>& creds2) {
-  // Note that we are not saving shared_ptrs to the two credentials
-  // passed in here. This is OK because the underlying C objects (i.e.,
-  // creds1 and creds2) into grpc_composite_credentials_create will see their
-  // refcounts incremented.
-  SecureCredentials* s1 = creds1->AsSecureCredentials();
-  SecureCredentials* s2 = creds2->AsSecureCredentials();
-  if (s1 && s2) {
-    return WrapCredentials(grpc_composite_credentials_create(
-        s1->GetRawCreds(), s2->GetRawCreds(), nullptr));
+// Combines one channel credentials and one call credentials into a channel
+// composite credentials.
+std::shared_ptr<ChannelCredentials> CompositeChannelCredentials(
+    const std::shared_ptr<ChannelCredentials>& channel_creds,
+    const std::shared_ptr<CallCredentials>& call_creds) {
+  // Note that we are not saving shared_ptrs to the two credentials passed in
+  // here. This is OK because the underlying C objects (i.e., channel_creds and
+  // call_creds) into grpc_composite_credentials_create will see their refcounts
+  // incremented.
+  SecureChannelCredentials* s_channel_creds =
+      channel_creds->AsSecureCredentials();
+  SecureCallCredentials* s_call_creds = call_creds->AsSecureCredentials();
+  if (s_channel_creds && s_call_creds) {
+    return WrapChannelCredentials(grpc_composite_channel_credentials_create(
+        s_channel_creds->GetRawCreds(), s_call_creds->GetRawCreds(), nullptr));
   }
   return nullptr;
 }
@@ -193,7 +201,7 @@
     std::unique_ptr<MetadataCredentialsPlugin> plugin)
     : thread_pool_(CreateDefaultThreadPool()), plugin_(std::move(plugin)) {}
 
-std::shared_ptr<Credentials> MetadataCredentialsFromPlugin(
+std::shared_ptr<CallCredentials> MetadataCredentialsFromPlugin(
     std::unique_ptr<MetadataCredentialsPlugin> plugin) {
   GrpcLibrary init;  // To call grpc_init().
   MetadataCredentialsPluginWrapper* wrapper =
@@ -201,7 +209,7 @@
   grpc_metadata_credentials_plugin c_plugin = {
       MetadataCredentialsPluginWrapper::GetMetadata,
       MetadataCredentialsPluginWrapper::Destroy, wrapper};
-  return WrapCredentials(
+  return WrapCallCredentials(
       grpc_metadata_credentials_create_from_plugin(c_plugin, nullptr));
 }
 
diff --git a/src/cpp/client/secure_credentials.h b/src/cpp/client/secure_credentials.h
index d354827..e9afa9e 100644
--- a/src/cpp/client/secure_credentials.h
+++ b/src/cpp/client/secure_credentials.h
@@ -43,19 +43,37 @@
 
 namespace grpc {
 
-class SecureCredentials GRPC_FINAL : public Credentials {
+class SecureChannelCredentials GRPC_FINAL : public ChannelCredentials {
  public:
-  explicit SecureCredentials(grpc_credentials* c_creds) : c_creds_(c_creds) {}
-  ~SecureCredentials() GRPC_OVERRIDE { grpc_credentials_release(c_creds_); }
-  grpc_credentials* GetRawCreds() { return c_creds_; }
-  bool ApplyToCall(grpc_call* call) GRPC_OVERRIDE;
+  explicit SecureChannelCredentials(grpc_channel_credentials* c_creds)
+      : c_creds_(c_creds) {}
+  ~SecureChannelCredentials() GRPC_OVERRIDE {
+    grpc_channel_credentials_release(c_creds_);
+  }
+  grpc_channel_credentials* GetRawCreds() { return c_creds_; }
 
   std::shared_ptr<grpc::Channel> CreateChannel(
       const string& target, const grpc::ChannelArguments& args) GRPC_OVERRIDE;
-  SecureCredentials* AsSecureCredentials() GRPC_OVERRIDE { return this; }
+  SecureChannelCredentials* AsSecureCredentials() GRPC_OVERRIDE { return this; }
 
  private:
-  grpc_credentials* const c_creds_;
+  grpc_channel_credentials* const c_creds_;
+};
+
+class SecureCallCredentials GRPC_FINAL : public CallCredentials {
+ public:
+  explicit SecureCallCredentials(grpc_call_credentials* c_creds)
+      : c_creds_(c_creds) {}
+  ~SecureCallCredentials() GRPC_OVERRIDE {
+    grpc_call_credentials_release(c_creds_);
+  }
+  grpc_call_credentials* GetRawCreds() { return c_creds_; }
+
+  bool ApplyToCall(grpc_call* call) GRPC_OVERRIDE;
+  SecureCallCredentials* AsSecureCredentials() GRPC_OVERRIDE { return this; }
+
+ private:
+  grpc_call_credentials* const c_creds_;
 };
 
 class MetadataCredentialsPluginWrapper GRPC_FINAL {
diff --git a/src/csharp/Grpc.Core.Tests/FakeCredentials.cs b/src/csharp/Grpc.Core.Tests/FakeCredentials.cs
index 87d55cd..144b832 100644
--- a/src/csharp/Grpc.Core.Tests/FakeCredentials.cs
+++ b/src/csharp/Grpc.Core.Tests/FakeCredentials.cs
@@ -57,7 +57,7 @@
             get { return composable; }
         }
 
-        internal override CredentialsSafeHandle ToNativeCredentials()
+        internal override ChannelCredentialsSafeHandle ToNativeCredentials()
         {
             return null;
         }
@@ -65,7 +65,7 @@
 
     internal class FakeCallCredentials : CallCredentials
     {
-        internal override CredentialsSafeHandle ToNativeCredentials()
+        internal override CallCredentialsSafeHandle ToNativeCredentials()
         {
             return null;
         }
diff --git a/src/csharp/Grpc.Core/CallCredentials.cs b/src/csharp/Grpc.Core/CallCredentials.cs
index 400a982..5ea179d 100644
--- a/src/csharp/Grpc.Core/CallCredentials.cs
+++ b/src/csharp/Grpc.Core/CallCredentials.cs
@@ -78,7 +78,7 @@
         /// Creates native object for the credentials.
         /// </summary>
         /// <returns>The native credentials.</returns>
-        internal abstract CredentialsSafeHandle ToNativeCredentials();
+        internal abstract CallCredentialsSafeHandle ToNativeCredentials();
     }
 
     /// <summary>
@@ -98,7 +98,7 @@
             this.interceptor = Preconditions.CheckNotNull(interceptor);
         }
 
-        internal override CredentialsSafeHandle ToNativeCredentials()
+        internal override CallCredentialsSafeHandle ToNativeCredentials()
         {
             NativeMetadataCredentialsPlugin plugin = new NativeMetadataCredentialsPlugin(interceptor);
             return plugin.Credentials;
@@ -123,14 +123,14 @@
             this.credentials = new List<CallCredentials>(credentials);
         }
 
-        internal override CredentialsSafeHandle ToNativeCredentials()
+        internal override CallCredentialsSafeHandle ToNativeCredentials()
         {
             return ToNativeRecursive(0);
         }
 
         // Recursive descent makes managing lifetime of intermediate CredentialSafeHandle instances easier.
         // In practice, we won't usually see composites from more than two credentials anyway.
-        private CredentialsSafeHandle ToNativeRecursive(int startIndex)
+        private CallCredentialsSafeHandle ToNativeRecursive(int startIndex)
         {
             if (startIndex == credentials.Count - 1)
             {
@@ -140,7 +140,7 @@
             using (var cred1 = credentials[startIndex].ToNativeCredentials())
             using (var cred2 = ToNativeRecursive(startIndex + 1))
             {
-                var nativeComposite = CredentialsSafeHandle.CreateComposite(cred1, cred2);
+                var nativeComposite = CallCredentialsSafeHandle.CreateComposite(cred1, cred2);
                 if (nativeComposite.IsInvalid)
                 {
                     throw new ArgumentException("Error creating native composite credentials. Likely, this is because you are trying to compose incompatible credentials.");
diff --git a/src/csharp/Grpc.Core/Channel.cs b/src/csharp/Grpc.Core/Channel.cs
index 6b99055..f5eec96 100644
--- a/src/csharp/Grpc.Core/Channel.cs
+++ b/src/csharp/Grpc.Core/Channel.cs
@@ -75,8 +75,8 @@
             this.options = options != null ? new List<ChannelOption>(options) : new List<ChannelOption>();
 
             EnsureUserAgentChannelOption(this.options);
-            using (CredentialsSafeHandle nativeCredentials = credentials.ToNativeCredentials())
-            using (ChannelArgsSafeHandle nativeChannelArgs = ChannelOptions.CreateChannelArgs(this.options))
+            using (var nativeCredentials = credentials.ToNativeCredentials())
+            using (var nativeChannelArgs = ChannelOptions.CreateChannelArgs(this.options))
             {
                 if (nativeCredentials != null)
                 {
diff --git a/src/csharp/Grpc.Core/ChannelCredentials.cs b/src/csharp/Grpc.Core/ChannelCredentials.cs
index 9d2bcda..5d96958 100644
--- a/src/csharp/Grpc.Core/ChannelCredentials.cs
+++ b/src/csharp/Grpc.Core/ChannelCredentials.cs
@@ -76,7 +76,7 @@
         /// should be created.
         /// </summary>
         /// <returns>The native credentials.</returns>
-        internal abstract CredentialsSafeHandle ToNativeCredentials();
+        internal abstract ChannelCredentialsSafeHandle ToNativeCredentials();
 
         /// <summary>
         /// Returns <c>true</c> if this credential type allows being composed by <c>CompositeCredentials</c>.
@@ -88,7 +88,7 @@
 
         private sealed class InsecureCredentialsImpl : ChannelCredentials
         {
-            internal override CredentialsSafeHandle ToNativeCredentials()
+            internal override ChannelCredentialsSafeHandle ToNativeCredentials()
             {
                 return null;
             }
@@ -160,9 +160,9 @@
             get { return true; }
         }
 
-        internal override CredentialsSafeHandle ToNativeCredentials()
+        internal override ChannelCredentialsSafeHandle ToNativeCredentials()
         {
-            return CredentialsSafeHandle.CreateSslCredentials(rootCertificates, keyCertificatePair);
+            return ChannelCredentialsSafeHandle.CreateSslCredentials(rootCertificates, keyCertificatePair);
         }
     }
 
@@ -188,12 +188,12 @@
             Preconditions.CheckArgument(channelCredentials.IsComposable, "Supplied channel credentials do not allow composition.");
         }
 
-        internal override CredentialsSafeHandle ToNativeCredentials()
+        internal override ChannelCredentialsSafeHandle ToNativeCredentials()
         {
-            using (var cred1 = channelCredentials.ToNativeCredentials())
-            using (var cred2 = callCredentials.ToNativeCredentials())
+            using (var channelCreds = channelCredentials.ToNativeCredentials())
+            using (var callCreds = callCredentials.ToNativeCredentials())
             {
-                var nativeComposite = CredentialsSafeHandle.CreateComposite(cred1, cred2);
+                var nativeComposite = ChannelCredentialsSafeHandle.CreateComposite(channelCreds, callCreds);
                 if (nativeComposite.IsInvalid)
                 {
                     throw new ArgumentException("Error creating native composite credentials. Likely, this is because you are trying to compose incompatible credentials.");
diff --git a/src/csharp/Grpc.Core/Grpc.Core.csproj b/src/csharp/Grpc.Core/Grpc.Core.csproj
index 0aab7bd..c4f7992 100644
--- a/src/csharp/Grpc.Core/Grpc.Core.csproj
+++ b/src/csharp/Grpc.Core/Grpc.Core.csproj
@@ -80,7 +80,6 @@
     <Compile Include="ServerServiceDefinition.cs" />
     <Compile Include="Utils\AsyncStreamExtensions.cs" />
     <Compile Include="Utils\BenchmarkUtil.cs" />
-    <Compile Include="Internal\CredentialsSafeHandle.cs" />
     <Compile Include="ChannelCredentials.cs" />
     <Compile Include="Internal\ChannelArgsSafeHandle.cs" />
     <Compile Include="Internal\AsyncCompletion.cs" />
@@ -119,6 +118,8 @@
     <Compile Include="CompressionLevel.cs" />
     <Compile Include="WriteOptions.cs" />
     <Compile Include="ContextPropagationToken.cs" />
+    <Compile Include="Internal\CallCredentialsSafeHandle.cs" />
+    <Compile Include="Internal\ChannelCredentialsSafeHandle.cs" />
     <Compile Include="Profiling\ProfilerEntry.cs" />
     <Compile Include="Profiling\ProfilerScope.cs" />
     <Compile Include="Profiling\IProfiler.cs" />
@@ -157,4 +158,4 @@
   <ItemGroup>
     <Folder Include="Profiling\" />
   </ItemGroup>
-</Project>
\ No newline at end of file
+</Project>
diff --git a/src/csharp/Grpc.Core/Internal/CallCredentialsSafeHandle.cs b/src/csharp/Grpc.Core/Internal/CallCredentialsSafeHandle.cs
new file mode 100644
index 0000000..3678c7d
--- /dev/null
+++ b/src/csharp/Grpc.Core/Internal/CallCredentialsSafeHandle.cs
@@ -0,0 +1,64 @@
+#region Copyright notice and license
+// Copyright 2015, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#endregion
+using System;
+using System.Runtime.InteropServices;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace Grpc.Core.Internal
+{
+    /// <summary>
+    /// grpc_call_credentials from <c>grpc/grpc_security.h</c>
+    /// </summary>
+    internal class CallCredentialsSafeHandle : SafeHandleZeroIsInvalid
+    {
+        [DllImport("grpc_csharp_ext.dll")]
+        static extern CallCredentialsSafeHandle grpcsharp_composite_call_credentials_create(CallCredentialsSafeHandle creds1, CallCredentialsSafeHandle creds2);
+
+        [DllImport("grpc_csharp_ext.dll")]
+        static extern void grpcsharp_call_credentials_release(IntPtr credentials);
+
+        private CallCredentialsSafeHandle()
+        {
+        }
+
+        public static CallCredentialsSafeHandle CreateComposite(CallCredentialsSafeHandle creds1, CallCredentialsSafeHandle creds2)
+        {
+            return grpcsharp_composite_call_credentials_create(creds1, creds2);
+        }
+
+        protected override bool ReleaseHandle()
+        {
+            grpcsharp_call_credentials_release(handle);
+            return true;
+        }
+    }
+}
diff --git a/src/csharp/Grpc.Core/Internal/CallSafeHandle.cs b/src/csharp/Grpc.Core/Internal/CallSafeHandle.cs
index ddeedeb..ad2e291 100644
--- a/src/csharp/Grpc.Core/Internal/CallSafeHandle.cs
+++ b/src/csharp/Grpc.Core/Internal/CallSafeHandle.cs
@@ -100,7 +100,7 @@
             BatchContextSafeHandle ctx, MetadataArraySafeHandle metadataArray);
 
         [DllImport("grpc_csharp_ext.dll")]
-        static extern GRPCCallError grpcsharp_call_set_credentials(CallSafeHandle call, CredentialsSafeHandle credentials);
+        static extern GRPCCallError grpcsharp_call_set_credentials(CallSafeHandle call, CallCredentialsSafeHandle credentials);
 
         [DllImport("grpc_csharp_ext.dll")]
         static extern CStringSafeHandle grpcsharp_call_get_peer(CallSafeHandle call);
@@ -117,7 +117,7 @@
             this.completionRegistry = completionRegistry;
         }
 
-        public void SetCredentials(CredentialsSafeHandle credentials)
+        public void SetCredentials(CallCredentialsSafeHandle credentials)
         {
             grpcsharp_call_set_credentials(this, credentials).CheckOk();
         }
diff --git a/src/csharp/Grpc.Core/Internal/CredentialsSafeHandle.cs b/src/csharp/Grpc.Core/Internal/ChannelCredentialsSafeHandle.cs
similarity index 68%
rename from src/csharp/Grpc.Core/Internal/CredentialsSafeHandle.cs
rename to src/csharp/Grpc.Core/Internal/ChannelCredentialsSafeHandle.cs
index bab4510..8a58c64 100644
--- a/src/csharp/Grpc.Core/Internal/CredentialsSafeHandle.cs
+++ b/src/csharp/Grpc.Core/Internal/ChannelCredentialsSafeHandle.cs
@@ -36,31 +36,31 @@
 namespace Grpc.Core.Internal
 {
     /// <summary>
-    /// grpc_credentials from <c>grpc/grpc_security.h</c>
+    /// grpc_channel_credentials from <c>grpc/grpc_security.h</c>
     /// </summary>
-    internal class CredentialsSafeHandle : SafeHandleZeroIsInvalid
+    internal class ChannelCredentialsSafeHandle : SafeHandleZeroIsInvalid
     {
         [DllImport("grpc_csharp_ext.dll", CharSet = CharSet.Ansi)]
-        static extern CredentialsSafeHandle grpcsharp_ssl_credentials_create(string pemRootCerts, string keyCertPairCertChain, string keyCertPairPrivateKey);
+        static extern ChannelCredentialsSafeHandle grpcsharp_ssl_credentials_create(string pemRootCerts, string keyCertPairCertChain, string keyCertPairPrivateKey);
 
         [DllImport("grpc_csharp_ext.dll")]
-        static extern CredentialsSafeHandle grpcsharp_composite_credentials_create(CredentialsSafeHandle creds1, CredentialsSafeHandle creds2);
+        static extern ChannelCredentialsSafeHandle grpcsharp_composite_channel_credentials_create(ChannelCredentialsSafeHandle channelCreds, CallCredentialsSafeHandle callCreds);
 
         [DllImport("grpc_csharp_ext.dll")]
-        static extern void grpcsharp_credentials_release(IntPtr credentials);
+        static extern void grpcsharp_channel_credentials_release(IntPtr credentials);
 
-        private CredentialsSafeHandle()
+        private ChannelCredentialsSafeHandle()
         {
         }
 
-        public static CredentialsSafeHandle CreateNullCredentials()
+        public static ChannelCredentialsSafeHandle CreateNullCredentials()
         {
-            var creds = new CredentialsSafeHandle();
+            var creds = new ChannelCredentialsSafeHandle();
             creds.SetHandle(IntPtr.Zero);
             return creds;
         }
 
-        public static CredentialsSafeHandle CreateSslCredentials(string pemRootCerts, KeyCertificatePair keyCertPair)
+        public static ChannelCredentialsSafeHandle CreateSslCredentials(string pemRootCerts, KeyCertificatePair keyCertPair)
         {
             if (keyCertPair != null)
             {
@@ -72,14 +72,14 @@
             }
         }
 
-        public static CredentialsSafeHandle CreateComposite(CredentialsSafeHandle creds1, CredentialsSafeHandle creds2)
+        public static ChannelCredentialsSafeHandle CreateComposite(ChannelCredentialsSafeHandle channelCreds, CallCredentialsSafeHandle callCreds)
         {
-            return grpcsharp_composite_credentials_create(creds1, creds2);
+            return grpcsharp_composite_channel_credentials_create(channelCreds, callCreds);
         }
 
         protected override bool ReleaseHandle()
         {
-            grpcsharp_credentials_release(handle);
+            grpcsharp_channel_credentials_release(handle);
             return true;
         }
     }
diff --git a/src/csharp/Grpc.Core/Internal/ChannelSafeHandle.cs b/src/csharp/Grpc.Core/Internal/ChannelSafeHandle.cs
index 5f9169b..b3aa27c 100644
--- a/src/csharp/Grpc.Core/Internal/ChannelSafeHandle.cs
+++ b/src/csharp/Grpc.Core/Internal/ChannelSafeHandle.cs
@@ -45,7 +45,7 @@
         static extern ChannelSafeHandle grpcsharp_insecure_channel_create(string target, ChannelArgsSafeHandle channelArgs);
 
         [DllImport("grpc_csharp_ext.dll")]
-        static extern ChannelSafeHandle grpcsharp_secure_channel_create(CredentialsSafeHandle credentials, string target, ChannelArgsSafeHandle channelArgs);
+        static extern ChannelSafeHandle grpcsharp_secure_channel_create(ChannelCredentialsSafeHandle credentials, string target, ChannelArgsSafeHandle channelArgs);
 
         [DllImport("grpc_csharp_ext.dll")]
         static extern CallSafeHandle grpcsharp_channel_create_call(ChannelSafeHandle channel, CallSafeHandle parentCall, ContextPropagationFlags propagationMask, CompletionQueueSafeHandle cq, string method, string host, Timespec deadline);
@@ -75,7 +75,7 @@
             return grpcsharp_insecure_channel_create(target, channelArgs);
         }
 
-        public static ChannelSafeHandle CreateSecure(CredentialsSafeHandle credentials, string target, ChannelArgsSafeHandle channelArgs)
+        public static ChannelSafeHandle CreateSecure(ChannelCredentialsSafeHandle credentials, string target, ChannelArgsSafeHandle channelArgs)
         {
             // Increment reference count for the native gRPC environment to make sure we don't do grpc_shutdown() before destroying the server handle.
             // Doing so would make object finalizer crash if we end up abandoning the handle.
@@ -83,7 +83,7 @@
             return grpcsharp_secure_channel_create(credentials, target, channelArgs);
         }
 
-        public CallSafeHandle CreateCall(CompletionRegistry registry, CallSafeHandle parentCall, ContextPropagationFlags propagationMask, CompletionQueueSafeHandle cq, string method, string host, Timespec deadline, CredentialsSafeHandle credentials)
+        public CallSafeHandle CreateCall(CompletionRegistry registry, CallSafeHandle parentCall, ContextPropagationFlags propagationMask, CompletionQueueSafeHandle cq, string method, string host, Timespec deadline, CallCredentialsSafeHandle credentials)
         {
             using (Profilers.ForCurrentThread().NewScope("ChannelSafeHandle.CreateCall"))
             {
diff --git a/src/csharp/Grpc.Core/Internal/NativeMetadataCredentialsPlugin.cs b/src/csharp/Grpc.Core/Internal/NativeMetadataCredentialsPlugin.cs
index f76492c..2a571cd 100644
--- a/src/csharp/Grpc.Core/Internal/NativeMetadataCredentialsPlugin.cs
+++ b/src/csharp/Grpc.Core/Internal/NativeMetadataCredentialsPlugin.cs
@@ -46,7 +46,7 @@
         static readonly ILogger Logger = GrpcEnvironment.Logger.ForType<NativeMetadataCredentialsPlugin>();
 
         [DllImport("grpc_csharp_ext.dll")]
-        static extern CredentialsSafeHandle grpcsharp_metadata_credentials_create_from_plugin(NativeMetadataInterceptor interceptor);
+        static extern CallCredentialsSafeHandle grpcsharp_metadata_credentials_create_from_plugin(NativeMetadataInterceptor interceptor);
         
         [DllImport("grpc_csharp_ext.dll", CharSet = CharSet.Ansi)]
         static extern void grpcsharp_metadata_credentials_notify_from_plugin(IntPtr callbackPtr, IntPtr userData, MetadataArraySafeHandle metadataArray, StatusCode statusCode, string errorDetails);
@@ -54,7 +54,7 @@
         AsyncAuthInterceptor interceptor;
         GCHandle gcHandle;
         NativeMetadataInterceptor nativeInterceptor;
-        CredentialsSafeHandle credentials;
+        CallCredentialsSafeHandle credentials;
 
         public NativeMetadataCredentialsPlugin(AsyncAuthInterceptor interceptor)
         {
@@ -66,7 +66,7 @@
             this.credentials = grpcsharp_metadata_credentials_create_from_plugin(nativeInterceptor);
         }
 
-        public CredentialsSafeHandle Credentials
+        public CallCredentialsSafeHandle Credentials
         {
             get { return credentials; }
         }
diff --git a/src/csharp/Grpc.Core/Profiling/IProfiler.cs b/src/csharp/Grpc.Core/Profiling/IProfiler.cs
index c426c36..e850375 100644
--- a/src/csharp/Grpc.Core/Profiling/IProfiler.cs
+++ b/src/csharp/Grpc.Core/Profiling/IProfiler.cs
@@ -41,7 +41,9 @@
     internal interface IProfiler 
     {
         void Begin(string tag);
+
         void End(string tag);
+
         void Mark(string tag);
     }
 }
diff --git a/src/csharp/Grpc.Core/Profiling/ProfilerEntry.cs b/src/csharp/Grpc.Core/Profiling/ProfilerEntry.cs
index 5cc4c3c..792e3c3 100644
--- a/src/csharp/Grpc.Core/Profiling/ProfilerEntry.cs
+++ b/src/csharp/Grpc.Core/Profiling/ProfilerEntry.cs
@@ -40,7 +40,8 @@
 {
     internal struct ProfilerEntry
     {
-        public enum Type {
+        public enum Type
+        {
             BEGIN,
             END,
             MARK
diff --git a/src/csharp/Grpc.Core/Profiling/Profilers.cs b/src/csharp/Grpc.Core/Profiling/Profilers.cs
index c812334..471ee20 100644
--- a/src/csharp/Grpc.Core/Profiling/Profilers.cs
+++ b/src/csharp/Grpc.Core/Profiling/Profilers.cs
@@ -40,12 +40,12 @@
 {
     internal static class Profilers
     {
-        static readonly NopProfiler defaultProfiler = new NopProfiler();
+        static readonly NopProfiler DefaultProfiler = new NopProfiler();
         static readonly ThreadLocal<IProfiler> profilers = new ThreadLocal<IProfiler>();
 
         public static IProfiler ForCurrentThread()
         {
-            return profilers.Value ?? defaultProfiler;
+            return profilers.Value ?? DefaultProfiler;
         }
 
         public static void SetForCurrentThread(IProfiler profiler)
@@ -89,15 +89,18 @@
             this.entries = new ProfilerEntry[capacity];
         }
 
-        public void Begin(string tag) {
+        public void Begin(string tag)
+        {
             AddEntry(new ProfilerEntry(Timespec.PreciseNow, ProfilerEntry.Type.BEGIN, tag));
         }
 
-        public void End(string tag) {
+        public void End(string tag)
+        {
             AddEntry(new ProfilerEntry(Timespec.PreciseNow, ProfilerEntry.Type.END, tag));
         }
 
-        public void Mark(string tag) {
+        public void Mark(string tag)
+        {
             AddEntry(new ProfilerEntry(Timespec.PreciseNow, ProfilerEntry.Type.MARK, tag));
         }
 
diff --git a/src/csharp/Grpc.IntegrationTesting.QpsWorker/.gitignore b/src/csharp/Grpc.IntegrationTesting.QpsWorker/.gitignore
new file mode 100644
index 0000000..a382af2
--- /dev/null
+++ b/src/csharp/Grpc.IntegrationTesting.QpsWorker/.gitignore
@@ -0,0 +1,3 @@
+bin
+obj
+
diff --git a/src/csharp/Grpc.IntegrationTesting.QpsWorker/Grpc.IntegrationTesting.QpsWorker.csproj b/src/csharp/Grpc.IntegrationTesting.QpsWorker/Grpc.IntegrationTesting.QpsWorker.csproj
new file mode 100644
index 0000000..8b245ad
--- /dev/null
+++ b/src/csharp/Grpc.IntegrationTesting.QpsWorker/Grpc.IntegrationTesting.QpsWorker.csproj
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProjectGuid>{B82B7DFE-7F7B-40EF-B3D6-064FF2B01294}</ProjectGuid>
+    <OutputType>Exe</OutputType>
+    <RootNamespace>Grpc.IntegrationTesting.QpsWorker</RootNamespace>
+    <AssemblyName>Grpc.IntegrationTesting.QpsWorker</AssemblyName>
+    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug</OutputPath>
+    <DefineConstants>DEBUG;</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <PlatformTarget>AnyCPU</PlatformTarget>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release</OutputPath>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <PlatformTarget>AnyCPU</PlatformTarget>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'ReleaseSigned|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\ReleaseSigned</OutputPath>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <SignAssembly>True</SignAssembly>
+    <AssemblyOriginatorKeyFile>C:\keys\Grpc.snk</AssemblyOriginatorKeyFile>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="..\Grpc.Core\Version.cs">
+      <Link>Version.cs</Link>
+    </Compile>
+    <Compile Include="Program.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+  </ItemGroup>
+  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+  <ItemGroup>
+    <ProjectReference Include="..\Grpc.Core\Grpc.Core.csproj">
+      <Project>{CCC4440E-49F7-4790-B0AF-FEABB0837AE7}</Project>
+      <Name>Grpc.Core</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\Grpc.IntegrationTesting\Grpc.IntegrationTesting.csproj">
+      <Project>{C61154BA-DD4A-4838-8420-0162A28925E0}</Project>
+      <Name>Grpc.IntegrationTesting</Name>
+    </ProjectReference>
+  </ItemGroup>
+</Project>
\ No newline at end of file
diff --git a/src/csharp/Grpc.IntegrationTesting.QpsWorker/Program.cs b/src/csharp/Grpc.IntegrationTesting.QpsWorker/Program.cs
new file mode 100644
index 0000000..3084633
--- /dev/null
+++ b/src/csharp/Grpc.IntegrationTesting.QpsWorker/Program.cs
@@ -0,0 +1,46 @@
+#region Copyright notice and license
+
+// Copyright 2015, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#endregion
+
+using System;
+using Grpc.IntegrationTesting;
+
+namespace Grpc.IntegrationTesting
+{
+    class Program
+    {
+        public static void Main(string[] args)
+        {
+            QpsWorker.Run(args);
+        }
+    }
+}
diff --git a/src/csharp/Grpc.IntegrationTesting.QpsWorker/Properties/AssemblyInfo.cs b/src/csharp/Grpc.IntegrationTesting.QpsWorker/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..aacfc16
--- /dev/null
+++ b/src/csharp/Grpc.IntegrationTesting.QpsWorker/Properties/AssemblyInfo.cs
@@ -0,0 +1,11 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+
+[assembly: AssemblyTitle("Grpc.IntegrationTesting.QpsWorker")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("")]
+[assembly: AssemblyCopyright("Google Inc.  All rights reserved.")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
diff --git a/src/csharp/Grpc.IntegrationTesting/BenchmarkServiceImpl.cs b/src/csharp/Grpc.IntegrationTesting/BenchmarkServiceImpl.cs
new file mode 100644
index 0000000..47a1522
--- /dev/null
+++ b/src/csharp/Grpc.IntegrationTesting/BenchmarkServiceImpl.cs
@@ -0,0 +1,76 @@
+#region Copyright notice and license
+
+// Copyright 2015, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Threading;
+using System.Threading.Tasks;
+using Google.Protobuf;
+using Grpc.Core;
+using Grpc.Core.Utils;
+
+namespace Grpc.Testing
+{
+    /// <summary>
+    /// Implementation of BenchmarkService server
+    /// </summary>
+    public class BenchmarkServiceImpl : BenchmarkService.IBenchmarkService
+    {
+        private readonly int responseSize;
+
+        public BenchmarkServiceImpl(int responseSize)
+        {
+            this.responseSize = responseSize;
+        }
+
+        public Task<SimpleResponse> UnaryCall(SimpleRequest request, ServerCallContext context)
+        {
+            var response = new SimpleResponse { Payload = CreateZerosPayload(responseSize) };
+            return Task.FromResult(response);
+        }
+
+        public async Task StreamingCall(IAsyncStreamReader<SimpleRequest> requestStream, IServerStreamWriter<SimpleResponse> responseStream, ServerCallContext context)
+        {
+            await requestStream.ForEachAsync(async request =>
+            {
+                var response = new SimpleResponse { Payload = CreateZerosPayload(responseSize) };
+                await responseStream.WriteAsync(response);
+            });
+        }
+
+        private static Payload CreateZerosPayload(int size)
+        {
+            return new Payload { Body = ByteString.CopyFrom(new byte[size]) };
+        }
+    }
+}
diff --git a/src/csharp/Grpc.IntegrationTesting/ClientRunners.cs b/src/csharp/Grpc.IntegrationTesting/ClientRunners.cs
new file mode 100644
index 0000000..e9e659c
--- /dev/null
+++ b/src/csharp/Grpc.IntegrationTesting/ClientRunners.cs
@@ -0,0 +1,153 @@
+#region Copyright notice and license
+
+// Copyright 2015, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.Linq;
+using System.Text.RegularExpressions;
+using System.Threading;
+using System.Threading.Tasks;
+using Google.Protobuf;
+using Grpc.Core;
+using Grpc.Core.Utils;
+using NUnit.Framework;
+using Grpc.Testing;
+
+namespace Grpc.IntegrationTesting
+{
+    /// <summary>
+    /// Helper methods to start client runners for performance testing.
+    /// </summary>
+    public static class ClientRunners
+    {
+        /// <summary>
+        /// Creates a started client runner.
+        /// </summary>
+        public static IClientRunner CreateStarted(ClientConfig config)
+        {
+            string target = config.ServerTargets.Single();
+            Grpc.Core.Utils.Preconditions.CheckArgument(config.LoadParams.LoadCase == LoadParams.LoadOneofCase.ClosedLoop);
+
+            var credentials = config.SecurityParams != null ? TestCredentials.CreateSslCredentials() : ChannelCredentials.Insecure;
+            var channel = new Channel(target, credentials);
+
+            switch (config.RpcType)
+            {
+                case RpcType.UNARY:
+                    return new SyncUnaryClientRunner(channel,
+                        config.PayloadConfig.SimpleParams.ReqSize,
+                        config.HistogramParams);
+
+                case RpcType.STREAMING:
+                default:
+                    throw new ArgumentException("Unsupported RpcType.");
+            }
+        }
+    }
+
+    /// <summary>
+    /// Client that starts synchronous unary calls in a closed loop.
+    /// </summary>
+    public class SyncUnaryClientRunner : IClientRunner
+    {
+        const double SecondsToNanos = 1e9;
+
+        readonly Channel channel;
+        readonly int payloadSize;
+        readonly Histogram histogram;
+
+        readonly BenchmarkService.IBenchmarkServiceClient client;
+        readonly Task runnerTask;
+        readonly CancellationTokenSource stoppedCts;
+        readonly WallClockStopwatch wallClockStopwatch = new WallClockStopwatch();
+        
+        public SyncUnaryClientRunner(Channel channel, int payloadSize, HistogramParams histogramParams)
+        {
+            this.channel = Grpc.Core.Utils.Preconditions.CheckNotNull(channel);
+            this.payloadSize = payloadSize;
+            this.histogram = new Histogram(histogramParams.Resolution, histogramParams.MaxPossible);
+
+            this.stoppedCts = new CancellationTokenSource();
+            this.client = BenchmarkService.NewClient(channel);
+            this.runnerTask = Task.Factory.StartNew(Run, TaskCreationOptions.LongRunning);
+        }
+
+        public ClientStats GetStats(bool reset)
+        {
+            var histogramData = histogram.GetSnapshot(reset);
+            var secondsElapsed = wallClockStopwatch.GetElapsedSnapshot(reset).TotalSeconds;
+
+            // TODO: populate user time and system time
+            return new ClientStats
+            {
+                Latencies = histogramData,
+                TimeElapsed = secondsElapsed,
+                TimeUser = 0,
+                TimeSystem = 0
+            };
+        }
+
+        public async Task StopAsync()
+        {
+            stoppedCts.Cancel();
+            await runnerTask;
+            await channel.ShutdownAsync();
+        }
+
+        private void Run()
+        {
+            var request = new SimpleRequest
+            {
+                Payload = CreateZerosPayload(payloadSize)
+            };
+            var stopwatch = new Stopwatch();
+
+            while (!stoppedCts.Token.IsCancellationRequested)
+            {
+                stopwatch.Restart();
+                client.UnaryCall(request);
+                stopwatch.Stop();
+
+                // spec requires data point in nanoseconds.
+                histogram.AddObservation(stopwatch.Elapsed.TotalSeconds * SecondsToNanos);
+            }
+        }
+
+        private static Payload CreateZerosPayload(int size)
+        {
+            return new Payload { Body = ByteString.CopyFrom(new byte[size]) };
+        }
+    }
+}
diff --git a/src/csharp/Grpc.IntegrationTesting/Control.cs b/src/csharp/Grpc.IntegrationTesting/Control.cs
new file mode 100644
index 0000000..4764e10
--- /dev/null
+++ b/src/csharp/Grpc.IntegrationTesting/Control.cs
@@ -0,0 +1,2362 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: test/proto/benchmarks/control.proto
+#pragma warning disable 1591, 0612, 3021
+#region Designer generated code
+
+using pb = global::Google.Protobuf;
+using pbc = global::Google.Protobuf.Collections;
+using pbr = global::Google.Protobuf.Reflection;
+using scg = global::System.Collections.Generic;
+namespace Grpc.Testing {
+
+  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+  public static partial class Control {
+
+    #region Descriptor
+    public static pbr::FileDescriptor Descriptor {
+      get { return descriptor; }
+    }
+    private static pbr::FileDescriptor descriptor;
+
+    static Control() {
+      byte[] descriptorData = global::System.Convert.FromBase64String(
+          string.Concat(
+            "CiN0ZXN0L3Byb3RvL2JlbmNobWFya3MvY29udHJvbC5wcm90bxIMZ3JwYy50", 
+            "ZXN0aW5nGiR0ZXN0L3Byb3RvL2JlbmNobWFya3MvcGF5bG9hZHMucHJvdG8a", 
+            "IXRlc3QvcHJvdG8vYmVuY2htYXJrcy9zdGF0cy5wcm90byIlCg1Qb2lzc29u", 
+            "UGFyYW1zEhQKDG9mZmVyZWRfbG9hZBgBIAEoASJBCg1Vbmlmb3JtUGFyYW1z", 
+            "EhcKD2ludGVyYXJyaXZhbF9sbxgBIAEoARIXCg9pbnRlcmFycml2YWxfaGkY", 
+            "AiABKAEiKwoTRGV0ZXJtaW5pc3RpY1BhcmFtcxIUCgxvZmZlcmVkX2xvYWQY", 
+            "ASABKAEiOAoMUGFyZXRvUGFyYW1zEhkKEWludGVyYXJyaXZhbF9iYXNlGAEg", 
+            "ASgBEg0KBWFscGhhGAIgASgBIhIKEENsb3NlZExvb3BQYXJhbXMijgIKCkxv", 
+            "YWRQYXJhbXMSNQoLY2xvc2VkX2xvb3AYASABKAsyHi5ncnBjLnRlc3Rpbmcu", 
+            "Q2xvc2VkTG9vcFBhcmFtc0gAEi4KB3BvaXNzb24YAiABKAsyGy5ncnBjLnRl", 
+            "c3RpbmcuUG9pc3NvblBhcmFtc0gAEi4KB3VuaWZvcm0YAyABKAsyGy5ncnBj", 
+            "LnRlc3RpbmcuVW5pZm9ybVBhcmFtc0gAEjMKBmRldGVybRgEIAEoCzIhLmdy", 
+            "cGMudGVzdGluZy5EZXRlcm1pbmlzdGljUGFyYW1zSAASLAoGcGFyZXRvGAUg", 
+            "ASgLMhouZ3JwYy50ZXN0aW5nLlBhcmV0b1BhcmFtc0gAQgYKBGxvYWQiQwoO", 
+            "U2VjdXJpdHlQYXJhbXMSEwoLdXNlX3Rlc3RfY2EYASABKAgSHAoUc2VydmVy", 
+            "X2hvc3Rfb3ZlcnJpZGUYAiABKAkirwMKDENsaWVudENvbmZpZxIWCg5zZXJ2", 
+            "ZXJfdGFyZ2V0cxgBIAMoCRItCgtjbGllbnRfdHlwZRgCIAEoDjIYLmdycGMu", 
+            "dGVzdGluZy5DbGllbnRUeXBlEjUKD3NlY3VyaXR5X3BhcmFtcxgDIAEoCzIc", 
+            "LmdycGMudGVzdGluZy5TZWN1cml0eVBhcmFtcxIkChxvdXRzdGFuZGluZ19y", 
+            "cGNzX3Blcl9jaGFubmVsGAQgASgFEhcKD2NsaWVudF9jaGFubmVscxgFIAEo", 
+            "BRIcChRhc3luY19jbGllbnRfdGhyZWFkcxgHIAEoBRInCghycGNfdHlwZRgI", 
+            "IAEoDjIVLmdycGMudGVzdGluZy5ScGNUeXBlEi0KC2xvYWRfcGFyYW1zGAog", 
+            "ASgLMhguZ3JwYy50ZXN0aW5nLkxvYWRQYXJhbXMSMwoOcGF5bG9hZF9jb25m", 
+            "aWcYCyABKAsyGy5ncnBjLnRlc3RpbmcuUGF5bG9hZENvbmZpZxI3ChBoaXN0", 
+            "b2dyYW1fcGFyYW1zGAwgASgLMh0uZ3JwYy50ZXN0aW5nLkhpc3RvZ3JhbVBh", 
+            "cmFtcyI4CgxDbGllbnRTdGF0dXMSKAoFc3RhdHMYASABKAsyGS5ncnBjLnRl", 
+            "c3RpbmcuQ2xpZW50U3RhdHMiFQoETWFyaxINCgVyZXNldBgBIAEoCCJoCgpD", 
+            "bGllbnRBcmdzEisKBXNldHVwGAEgASgLMhouZ3JwYy50ZXN0aW5nLkNsaWVu", 
+            "dENvbmZpZ0gAEiIKBG1hcmsYAiABKAsyEi5ncnBjLnRlc3RpbmcuTWFya0gA", 
+            "QgkKB2FyZ3R5cGUi9wEKDFNlcnZlckNvbmZpZxItCgtzZXJ2ZXJfdHlwZRgB", 
+            "IAEoDjIYLmdycGMudGVzdGluZy5TZXJ2ZXJUeXBlEjUKD3NlY3VyaXR5X3Bh", 
+            "cmFtcxgCIAEoCzIcLmdycGMudGVzdGluZy5TZWN1cml0eVBhcmFtcxIMCgRo", 
+            "b3N0GAMgASgJEgwKBHBvcnQYBCABKAUSHAoUYXN5bmNfc2VydmVyX3RocmVh", 
+            "ZHMYByABKAUSEgoKY29yZV9saW1pdBgIIAEoBRIzCg5wYXlsb2FkX2NvbmZp", 
+            "ZxgJIAEoCzIbLmdycGMudGVzdGluZy5QYXlsb2FkQ29uZmlnImgKClNlcnZl", 
+            "ckFyZ3MSKwoFc2V0dXAYASABKAsyGi5ncnBjLnRlc3RpbmcuU2VydmVyQ29u", 
+            "ZmlnSAASIgoEbWFyaxgCIAEoCzISLmdycGMudGVzdGluZy5NYXJrSABCCQoH", 
+            "YXJndHlwZSJVCgxTZXJ2ZXJTdGF0dXMSKAoFc3RhdHMYASABKAsyGS5ncnBj", 
+            "LnRlc3RpbmcuU2VydmVyU3RhdHMSDAoEcG9ydBgCIAEoBRINCgVjb3JlcxgD", 
+            "IAEoBSovCgpDbGllbnRUeXBlEg8KC1NZTkNfQ0xJRU5UEAASEAoMQVNZTkNf", 
+            "Q0xJRU5UEAEqLwoKU2VydmVyVHlwZRIPCgtTWU5DX1NFUlZFUhAAEhAKDEFT", 
+            "WU5DX1NFUlZFUhABKiMKB1JwY1R5cGUSCQoFVU5BUlkQABINCglTVFJFQU1J", 
+            "TkcQAWIGcHJvdG8z"));
+      descriptor = pbr::FileDescriptor.InternalBuildGeneratedFileFrom(descriptorData,
+          new pbr::FileDescriptor[] { global::Grpc.Testing.Payloads.Descriptor, global::Grpc.Testing.Stats.Descriptor, },
+          new pbr::GeneratedCodeInfo(new[] {typeof(global::Grpc.Testing.ClientType), typeof(global::Grpc.Testing.ServerType), typeof(global::Grpc.Testing.RpcType), }, new pbr::GeneratedCodeInfo[] {
+            new pbr::GeneratedCodeInfo(typeof(global::Grpc.Testing.PoissonParams), new[]{ "OfferedLoad" }, null, null, null),
+            new pbr::GeneratedCodeInfo(typeof(global::Grpc.Testing.UniformParams), new[]{ "InterarrivalLo", "InterarrivalHi" }, null, null, null),
+            new pbr::GeneratedCodeInfo(typeof(global::Grpc.Testing.DeterministicParams), new[]{ "OfferedLoad" }, null, null, null),
+            new pbr::GeneratedCodeInfo(typeof(global::Grpc.Testing.ParetoParams), new[]{ "InterarrivalBase", "Alpha" }, null, null, null),
+            new pbr::GeneratedCodeInfo(typeof(global::Grpc.Testing.ClosedLoopParams), null, null, null, null),
+            new pbr::GeneratedCodeInfo(typeof(global::Grpc.Testing.LoadParams), new[]{ "ClosedLoop", "Poisson", "Uniform", "Determ", "Pareto" }, new[]{ "Load" }, null, null),
+            new pbr::GeneratedCodeInfo(typeof(global::Grpc.Testing.SecurityParams), new[]{ "UseTestCa", "ServerHostOverride" }, null, null, null),
+            new pbr::GeneratedCodeInfo(typeof(global::Grpc.Testing.ClientConfig), new[]{ "ServerTargets", "ClientType", "SecurityParams", "OutstandingRpcsPerChannel", "ClientChannels", "AsyncClientThreads", "RpcType", "LoadParams", "PayloadConfig", "HistogramParams" }, null, null, null),
+            new pbr::GeneratedCodeInfo(typeof(global::Grpc.Testing.ClientStatus), new[]{ "Stats" }, null, null, null),
+            new pbr::GeneratedCodeInfo(typeof(global::Grpc.Testing.Mark), new[]{ "Reset" }, null, null, null),
+            new pbr::GeneratedCodeInfo(typeof(global::Grpc.Testing.ClientArgs), new[]{ "Setup", "Mark" }, new[]{ "Argtype" }, null, null),
+            new pbr::GeneratedCodeInfo(typeof(global::Grpc.Testing.ServerConfig), new[]{ "ServerType", "SecurityParams", "Host", "Port", "AsyncServerThreads", "CoreLimit", "PayloadConfig" }, null, null, null),
+            new pbr::GeneratedCodeInfo(typeof(global::Grpc.Testing.ServerArgs), new[]{ "Setup", "Mark" }, new[]{ "Argtype" }, null, null),
+            new pbr::GeneratedCodeInfo(typeof(global::Grpc.Testing.ServerStatus), new[]{ "Stats", "Port", "Cores" }, null, null, null)
+          }));
+    }
+    #endregion
+
+  }
+  #region Enums
+  public enum ClientType {
+    SYNC_CLIENT = 0,
+    ASYNC_CLIENT = 1,
+  }
+
+  public enum ServerType {
+    SYNC_SERVER = 0,
+    ASYNC_SERVER = 1,
+  }
+
+  public enum RpcType {
+    UNARY = 0,
+    STREAMING = 1,
+  }
+
+  #endregion
+
+  #region Messages
+  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+  public sealed partial class PoissonParams : pb::IMessage<PoissonParams> {
+    private static readonly pb::MessageParser<PoissonParams> _parser = new pb::MessageParser<PoissonParams>(() => new PoissonParams());
+    public static pb::MessageParser<PoissonParams> Parser { get { return _parser; } }
+
+    public static pbr::MessageDescriptor Descriptor {
+      get { return global::Grpc.Testing.Control.Descriptor.MessageTypes[0]; }
+    }
+
+    pbr::MessageDescriptor pb::IMessage.Descriptor {
+      get { return Descriptor; }
+    }
+
+    public PoissonParams() {
+      OnConstruction();
+    }
+
+    partial void OnConstruction();
+
+    public PoissonParams(PoissonParams other) : this() {
+      offeredLoad_ = other.offeredLoad_;
+    }
+
+    public PoissonParams Clone() {
+      return new PoissonParams(this);
+    }
+
+    public const int OfferedLoadFieldNumber = 1;
+    private double offeredLoad_;
+    public double OfferedLoad {
+      get { return offeredLoad_; }
+      set {
+        offeredLoad_ = value;
+      }
+    }
+
+    public override bool Equals(object other) {
+      return Equals(other as PoissonParams);
+    }
+
+    public bool Equals(PoissonParams other) {
+      if (ReferenceEquals(other, null)) {
+        return false;
+      }
+      if (ReferenceEquals(other, this)) {
+        return true;
+      }
+      if (OfferedLoad != other.OfferedLoad) return false;
+      return true;
+    }
+
+    public override int GetHashCode() {
+      int hash = 1;
+      if (OfferedLoad != 0D) hash ^= OfferedLoad.GetHashCode();
+      return hash;
+    }
+
+    public override string ToString() {
+      return pb::JsonFormatter.Default.Format(this);
+    }
+
+    public void WriteTo(pb::CodedOutputStream output) {
+      if (OfferedLoad != 0D) {
+        output.WriteRawTag(9);
+        output.WriteDouble(OfferedLoad);
+      }
+    }
+
+    public int CalculateSize() {
+      int size = 0;
+      if (OfferedLoad != 0D) {
+        size += 1 + 8;
+      }
+      return size;
+    }
+
+    public void MergeFrom(PoissonParams other) {
+      if (other == null) {
+        return;
+      }
+      if (other.OfferedLoad != 0D) {
+        OfferedLoad = other.OfferedLoad;
+      }
+    }
+
+    public void MergeFrom(pb::CodedInputStream input) {
+      uint tag;
+      while ((tag = input.ReadTag()) != 0) {
+        switch(tag) {
+          default:
+            input.SkipLastField();
+            break;
+          case 9: {
+            OfferedLoad = input.ReadDouble();
+            break;
+          }
+        }
+      }
+    }
+
+  }
+
+  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+  public sealed partial class UniformParams : pb::IMessage<UniformParams> {
+    private static readonly pb::MessageParser<UniformParams> _parser = new pb::MessageParser<UniformParams>(() => new UniformParams());
+    public static pb::MessageParser<UniformParams> Parser { get { return _parser; } }
+
+    public static pbr::MessageDescriptor Descriptor {
+      get { return global::Grpc.Testing.Control.Descriptor.MessageTypes[1]; }
+    }
+
+    pbr::MessageDescriptor pb::IMessage.Descriptor {
+      get { return Descriptor; }
+    }
+
+    public UniformParams() {
+      OnConstruction();
+    }
+
+    partial void OnConstruction();
+
+    public UniformParams(UniformParams other) : this() {
+      interarrivalLo_ = other.interarrivalLo_;
+      interarrivalHi_ = other.interarrivalHi_;
+    }
+
+    public UniformParams Clone() {
+      return new UniformParams(this);
+    }
+
+    public const int InterarrivalLoFieldNumber = 1;
+    private double interarrivalLo_;
+    public double InterarrivalLo {
+      get { return interarrivalLo_; }
+      set {
+        interarrivalLo_ = value;
+      }
+    }
+
+    public const int InterarrivalHiFieldNumber = 2;
+    private double interarrivalHi_;
+    public double InterarrivalHi {
+      get { return interarrivalHi_; }
+      set {
+        interarrivalHi_ = value;
+      }
+    }
+
+    public override bool Equals(object other) {
+      return Equals(other as UniformParams);
+    }
+
+    public bool Equals(UniformParams other) {
+      if (ReferenceEquals(other, null)) {
+        return false;
+      }
+      if (ReferenceEquals(other, this)) {
+        return true;
+      }
+      if (InterarrivalLo != other.InterarrivalLo) return false;
+      if (InterarrivalHi != other.InterarrivalHi) return false;
+      return true;
+    }
+
+    public override int GetHashCode() {
+      int hash = 1;
+      if (InterarrivalLo != 0D) hash ^= InterarrivalLo.GetHashCode();
+      if (InterarrivalHi != 0D) hash ^= InterarrivalHi.GetHashCode();
+      return hash;
+    }
+
+    public override string ToString() {
+      return pb::JsonFormatter.Default.Format(this);
+    }
+
+    public void WriteTo(pb::CodedOutputStream output) {
+      if (InterarrivalLo != 0D) {
+        output.WriteRawTag(9);
+        output.WriteDouble(InterarrivalLo);
+      }
+      if (InterarrivalHi != 0D) {
+        output.WriteRawTag(17);
+        output.WriteDouble(InterarrivalHi);
+      }
+    }
+
+    public int CalculateSize() {
+      int size = 0;
+      if (InterarrivalLo != 0D) {
+        size += 1 + 8;
+      }
+      if (InterarrivalHi != 0D) {
+        size += 1 + 8;
+      }
+      return size;
+    }
+
+    public void MergeFrom(UniformParams other) {
+      if (other == null) {
+        return;
+      }
+      if (other.InterarrivalLo != 0D) {
+        InterarrivalLo = other.InterarrivalLo;
+      }
+      if (other.InterarrivalHi != 0D) {
+        InterarrivalHi = other.InterarrivalHi;
+      }
+    }
+
+    public void MergeFrom(pb::CodedInputStream input) {
+      uint tag;
+      while ((tag = input.ReadTag()) != 0) {
+        switch(tag) {
+          default:
+            input.SkipLastField();
+            break;
+          case 9: {
+            InterarrivalLo = input.ReadDouble();
+            break;
+          }
+          case 17: {
+            InterarrivalHi = input.ReadDouble();
+            break;
+          }
+        }
+      }
+    }
+
+  }
+
+  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+  public sealed partial class DeterministicParams : pb::IMessage<DeterministicParams> {
+    private static readonly pb::MessageParser<DeterministicParams> _parser = new pb::MessageParser<DeterministicParams>(() => new DeterministicParams());
+    public static pb::MessageParser<DeterministicParams> Parser { get { return _parser; } }
+
+    public static pbr::MessageDescriptor Descriptor {
+      get { return global::Grpc.Testing.Control.Descriptor.MessageTypes[2]; }
+    }
+
+    pbr::MessageDescriptor pb::IMessage.Descriptor {
+      get { return Descriptor; }
+    }
+
+    public DeterministicParams() {
+      OnConstruction();
+    }
+
+    partial void OnConstruction();
+
+    public DeterministicParams(DeterministicParams other) : this() {
+      offeredLoad_ = other.offeredLoad_;
+    }
+
+    public DeterministicParams Clone() {
+      return new DeterministicParams(this);
+    }
+
+    public const int OfferedLoadFieldNumber = 1;
+    private double offeredLoad_;
+    public double OfferedLoad {
+      get { return offeredLoad_; }
+      set {
+        offeredLoad_ = value;
+      }
+    }
+
+    public override bool Equals(object other) {
+      return Equals(other as DeterministicParams);
+    }
+
+    public bool Equals(DeterministicParams other) {
+      if (ReferenceEquals(other, null)) {
+        return false;
+      }
+      if (ReferenceEquals(other, this)) {
+        return true;
+      }
+      if (OfferedLoad != other.OfferedLoad) return false;
+      return true;
+    }
+
+    public override int GetHashCode() {
+      int hash = 1;
+      if (OfferedLoad != 0D) hash ^= OfferedLoad.GetHashCode();
+      return hash;
+    }
+
+    public override string ToString() {
+      return pb::JsonFormatter.Default.Format(this);
+    }
+
+    public void WriteTo(pb::CodedOutputStream output) {
+      if (OfferedLoad != 0D) {
+        output.WriteRawTag(9);
+        output.WriteDouble(OfferedLoad);
+      }
+    }
+
+    public int CalculateSize() {
+      int size = 0;
+      if (OfferedLoad != 0D) {
+        size += 1 + 8;
+      }
+      return size;
+    }
+
+    public void MergeFrom(DeterministicParams other) {
+      if (other == null) {
+        return;
+      }
+      if (other.OfferedLoad != 0D) {
+        OfferedLoad = other.OfferedLoad;
+      }
+    }
+
+    public void MergeFrom(pb::CodedInputStream input) {
+      uint tag;
+      while ((tag = input.ReadTag()) != 0) {
+        switch(tag) {
+          default:
+            input.SkipLastField();
+            break;
+          case 9: {
+            OfferedLoad = input.ReadDouble();
+            break;
+          }
+        }
+      }
+    }
+
+  }
+
+  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+  public sealed partial class ParetoParams : pb::IMessage<ParetoParams> {
+    private static readonly pb::MessageParser<ParetoParams> _parser = new pb::MessageParser<ParetoParams>(() => new ParetoParams());
+    public static pb::MessageParser<ParetoParams> Parser { get { return _parser; } }
+
+    public static pbr::MessageDescriptor Descriptor {
+      get { return global::Grpc.Testing.Control.Descriptor.MessageTypes[3]; }
+    }
+
+    pbr::MessageDescriptor pb::IMessage.Descriptor {
+      get { return Descriptor; }
+    }
+
+    public ParetoParams() {
+      OnConstruction();
+    }
+
+    partial void OnConstruction();
+
+    public ParetoParams(ParetoParams other) : this() {
+      interarrivalBase_ = other.interarrivalBase_;
+      alpha_ = other.alpha_;
+    }
+
+    public ParetoParams Clone() {
+      return new ParetoParams(this);
+    }
+
+    public const int InterarrivalBaseFieldNumber = 1;
+    private double interarrivalBase_;
+    public double InterarrivalBase {
+      get { return interarrivalBase_; }
+      set {
+        interarrivalBase_ = value;
+      }
+    }
+
+    public const int AlphaFieldNumber = 2;
+    private double alpha_;
+    public double Alpha {
+      get { return alpha_; }
+      set {
+        alpha_ = value;
+      }
+    }
+
+    public override bool Equals(object other) {
+      return Equals(other as ParetoParams);
+    }
+
+    public bool Equals(ParetoParams other) {
+      if (ReferenceEquals(other, null)) {
+        return false;
+      }
+      if (ReferenceEquals(other, this)) {
+        return true;
+      }
+      if (InterarrivalBase != other.InterarrivalBase) return false;
+      if (Alpha != other.Alpha) return false;
+      return true;
+    }
+
+    public override int GetHashCode() {
+      int hash = 1;
+      if (InterarrivalBase != 0D) hash ^= InterarrivalBase.GetHashCode();
+      if (Alpha != 0D) hash ^= Alpha.GetHashCode();
+      return hash;
+    }
+
+    public override string ToString() {
+      return pb::JsonFormatter.Default.Format(this);
+    }
+
+    public void WriteTo(pb::CodedOutputStream output) {
+      if (InterarrivalBase != 0D) {
+        output.WriteRawTag(9);
+        output.WriteDouble(InterarrivalBase);
+      }
+      if (Alpha != 0D) {
+        output.WriteRawTag(17);
+        output.WriteDouble(Alpha);
+      }
+    }
+
+    public int CalculateSize() {
+      int size = 0;
+      if (InterarrivalBase != 0D) {
+        size += 1 + 8;
+      }
+      if (Alpha != 0D) {
+        size += 1 + 8;
+      }
+      return size;
+    }
+
+    public void MergeFrom(ParetoParams other) {
+      if (other == null) {
+        return;
+      }
+      if (other.InterarrivalBase != 0D) {
+        InterarrivalBase = other.InterarrivalBase;
+      }
+      if (other.Alpha != 0D) {
+        Alpha = other.Alpha;
+      }
+    }
+
+    public void MergeFrom(pb::CodedInputStream input) {
+      uint tag;
+      while ((tag = input.ReadTag()) != 0) {
+        switch(tag) {
+          default:
+            input.SkipLastField();
+            break;
+          case 9: {
+            InterarrivalBase = input.ReadDouble();
+            break;
+          }
+          case 17: {
+            Alpha = input.ReadDouble();
+            break;
+          }
+        }
+      }
+    }
+
+  }
+
+  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+  public sealed partial class ClosedLoopParams : pb::IMessage<ClosedLoopParams> {
+    private static readonly pb::MessageParser<ClosedLoopParams> _parser = new pb::MessageParser<ClosedLoopParams>(() => new ClosedLoopParams());
+    public static pb::MessageParser<ClosedLoopParams> Parser { get { return _parser; } }
+
+    public static pbr::MessageDescriptor Descriptor {
+      get { return global::Grpc.Testing.Control.Descriptor.MessageTypes[4]; }
+    }
+
+    pbr::MessageDescriptor pb::IMessage.Descriptor {
+      get { return Descriptor; }
+    }
+
+    public ClosedLoopParams() {
+      OnConstruction();
+    }
+
+    partial void OnConstruction();
+
+    public ClosedLoopParams(ClosedLoopParams other) : this() {
+    }
+
+    public ClosedLoopParams Clone() {
+      return new ClosedLoopParams(this);
+    }
+
+    public override bool Equals(object other) {
+      return Equals(other as ClosedLoopParams);
+    }
+
+    public bool Equals(ClosedLoopParams other) {
+      if (ReferenceEquals(other, null)) {
+        return false;
+      }
+      if (ReferenceEquals(other, this)) {
+        return true;
+      }
+      return true;
+    }
+
+    public override int GetHashCode() {
+      int hash = 1;
+      return hash;
+    }
+
+    public override string ToString() {
+      return pb::JsonFormatter.Default.Format(this);
+    }
+
+    public void WriteTo(pb::CodedOutputStream output) {
+    }
+
+    public int CalculateSize() {
+      int size = 0;
+      return size;
+    }
+
+    public void MergeFrom(ClosedLoopParams other) {
+      if (other == null) {
+        return;
+      }
+    }
+
+    public void MergeFrom(pb::CodedInputStream input) {
+      uint tag;
+      while ((tag = input.ReadTag()) != 0) {
+        switch(tag) {
+          default:
+            input.SkipLastField();
+            break;
+        }
+      }
+    }
+
+  }
+
+  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+  public sealed partial class LoadParams : pb::IMessage<LoadParams> {
+    private static readonly pb::MessageParser<LoadParams> _parser = new pb::MessageParser<LoadParams>(() => new LoadParams());
+    public static pb::MessageParser<LoadParams> Parser { get { return _parser; } }
+
+    public static pbr::MessageDescriptor Descriptor {
+      get { return global::Grpc.Testing.Control.Descriptor.MessageTypes[5]; }
+    }
+
+    pbr::MessageDescriptor pb::IMessage.Descriptor {
+      get { return Descriptor; }
+    }
+
+    public LoadParams() {
+      OnConstruction();
+    }
+
+    partial void OnConstruction();
+
+    public LoadParams(LoadParams other) : this() {
+      switch (other.LoadCase) {
+        case LoadOneofCase.ClosedLoop:
+          ClosedLoop = other.ClosedLoop.Clone();
+          break;
+        case LoadOneofCase.Poisson:
+          Poisson = other.Poisson.Clone();
+          break;
+        case LoadOneofCase.Uniform:
+          Uniform = other.Uniform.Clone();
+          break;
+        case LoadOneofCase.Determ:
+          Determ = other.Determ.Clone();
+          break;
+        case LoadOneofCase.Pareto:
+          Pareto = other.Pareto.Clone();
+          break;
+      }
+
+    }
+
+    public LoadParams Clone() {
+      return new LoadParams(this);
+    }
+
+    public const int ClosedLoopFieldNumber = 1;
+    public global::Grpc.Testing.ClosedLoopParams ClosedLoop {
+      get { return loadCase_ == LoadOneofCase.ClosedLoop ? (global::Grpc.Testing.ClosedLoopParams) load_ : null; }
+      set {
+        load_ = value;
+        loadCase_ = value == null ? LoadOneofCase.None : LoadOneofCase.ClosedLoop;
+      }
+    }
+
+    public const int PoissonFieldNumber = 2;
+    public global::Grpc.Testing.PoissonParams Poisson {
+      get { return loadCase_ == LoadOneofCase.Poisson ? (global::Grpc.Testing.PoissonParams) load_ : null; }
+      set {
+        load_ = value;
+        loadCase_ = value == null ? LoadOneofCase.None : LoadOneofCase.Poisson;
+      }
+    }
+
+    public const int UniformFieldNumber = 3;
+    public global::Grpc.Testing.UniformParams Uniform {
+      get { return loadCase_ == LoadOneofCase.Uniform ? (global::Grpc.Testing.UniformParams) load_ : null; }
+      set {
+        load_ = value;
+        loadCase_ = value == null ? LoadOneofCase.None : LoadOneofCase.Uniform;
+      }
+    }
+
+    public const int DetermFieldNumber = 4;
+    public global::Grpc.Testing.DeterministicParams Determ {
+      get { return loadCase_ == LoadOneofCase.Determ ? (global::Grpc.Testing.DeterministicParams) load_ : null; }
+      set {
+        load_ = value;
+        loadCase_ = value == null ? LoadOneofCase.None : LoadOneofCase.Determ;
+      }
+    }
+
+    public const int ParetoFieldNumber = 5;
+    public global::Grpc.Testing.ParetoParams Pareto {
+      get { return loadCase_ == LoadOneofCase.Pareto ? (global::Grpc.Testing.ParetoParams) load_ : null; }
+      set {
+        load_ = value;
+        loadCase_ = value == null ? LoadOneofCase.None : LoadOneofCase.Pareto;
+      }
+    }
+
+    private object load_;
+    public enum LoadOneofCase {
+      None = 0,
+      ClosedLoop = 1,
+      Poisson = 2,
+      Uniform = 3,
+      Determ = 4,
+      Pareto = 5,
+    }
+    private LoadOneofCase loadCase_ = LoadOneofCase.None;
+    public LoadOneofCase LoadCase {
+      get { return loadCase_; }
+    }
+
+    public void ClearLoad() {
+      loadCase_ = LoadOneofCase.None;
+      load_ = null;
+    }
+
+    public override bool Equals(object other) {
+      return Equals(other as LoadParams);
+    }
+
+    public bool Equals(LoadParams other) {
+      if (ReferenceEquals(other, null)) {
+        return false;
+      }
+      if (ReferenceEquals(other, this)) {
+        return true;
+      }
+      if (!object.Equals(ClosedLoop, other.ClosedLoop)) return false;
+      if (!object.Equals(Poisson, other.Poisson)) return false;
+      if (!object.Equals(Uniform, other.Uniform)) return false;
+      if (!object.Equals(Determ, other.Determ)) return false;
+      if (!object.Equals(Pareto, other.Pareto)) return false;
+      return true;
+    }
+
+    public override int GetHashCode() {
+      int hash = 1;
+      if (loadCase_ == LoadOneofCase.ClosedLoop) hash ^= ClosedLoop.GetHashCode();
+      if (loadCase_ == LoadOneofCase.Poisson) hash ^= Poisson.GetHashCode();
+      if (loadCase_ == LoadOneofCase.Uniform) hash ^= Uniform.GetHashCode();
+      if (loadCase_ == LoadOneofCase.Determ) hash ^= Determ.GetHashCode();
+      if (loadCase_ == LoadOneofCase.Pareto) hash ^= Pareto.GetHashCode();
+      return hash;
+    }
+
+    public override string ToString() {
+      return pb::JsonFormatter.Default.Format(this);
+    }
+
+    public void WriteTo(pb::CodedOutputStream output) {
+      if (loadCase_ == LoadOneofCase.ClosedLoop) {
+        output.WriteRawTag(10);
+        output.WriteMessage(ClosedLoop);
+      }
+      if (loadCase_ == LoadOneofCase.Poisson) {
+        output.WriteRawTag(18);
+        output.WriteMessage(Poisson);
+      }
+      if (loadCase_ == LoadOneofCase.Uniform) {
+        output.WriteRawTag(26);
+        output.WriteMessage(Uniform);
+      }
+      if (loadCase_ == LoadOneofCase.Determ) {
+        output.WriteRawTag(34);
+        output.WriteMessage(Determ);
+      }
+      if (loadCase_ == LoadOneofCase.Pareto) {
+        output.WriteRawTag(42);
+        output.WriteMessage(Pareto);
+      }
+    }
+
+    public int CalculateSize() {
+      int size = 0;
+      if (loadCase_ == LoadOneofCase.ClosedLoop) {
+        size += 1 + pb::CodedOutputStream.ComputeMessageSize(ClosedLoop);
+      }
+      if (loadCase_ == LoadOneofCase.Poisson) {
+        size += 1 + pb::CodedOutputStream.ComputeMessageSize(Poisson);
+      }
+      if (loadCase_ == LoadOneofCase.Uniform) {
+        size += 1 + pb::CodedOutputStream.ComputeMessageSize(Uniform);
+      }
+      if (loadCase_ == LoadOneofCase.Determ) {
+        size += 1 + pb::CodedOutputStream.ComputeMessageSize(Determ);
+      }
+      if (loadCase_ == LoadOneofCase.Pareto) {
+        size += 1 + pb::CodedOutputStream.ComputeMessageSize(Pareto);
+      }
+      return size;
+    }
+
+    public void MergeFrom(LoadParams other) {
+      if (other == null) {
+        return;
+      }
+      switch (other.LoadCase) {
+        case LoadOneofCase.ClosedLoop:
+          ClosedLoop = other.ClosedLoop;
+          break;
+        case LoadOneofCase.Poisson:
+          Poisson = other.Poisson;
+          break;
+        case LoadOneofCase.Uniform:
+          Uniform = other.Uniform;
+          break;
+        case LoadOneofCase.Determ:
+          Determ = other.Determ;
+          break;
+        case LoadOneofCase.Pareto:
+          Pareto = other.Pareto;
+          break;
+      }
+
+    }
+
+    public void MergeFrom(pb::CodedInputStream input) {
+      uint tag;
+      while ((tag = input.ReadTag()) != 0) {
+        switch(tag) {
+          default:
+            input.SkipLastField();
+            break;
+          case 10: {
+            global::Grpc.Testing.ClosedLoopParams subBuilder = new global::Grpc.Testing.ClosedLoopParams();
+            if (loadCase_ == LoadOneofCase.ClosedLoop) {
+              subBuilder.MergeFrom(ClosedLoop);
+            }
+            input.ReadMessage(subBuilder);
+            ClosedLoop = subBuilder;
+            break;
+          }
+          case 18: {
+            global::Grpc.Testing.PoissonParams subBuilder = new global::Grpc.Testing.PoissonParams();
+            if (loadCase_ == LoadOneofCase.Poisson) {
+              subBuilder.MergeFrom(Poisson);
+            }
+            input.ReadMessage(subBuilder);
+            Poisson = subBuilder;
+            break;
+          }
+          case 26: {
+            global::Grpc.Testing.UniformParams subBuilder = new global::Grpc.Testing.UniformParams();
+            if (loadCase_ == LoadOneofCase.Uniform) {
+              subBuilder.MergeFrom(Uniform);
+            }
+            input.ReadMessage(subBuilder);
+            Uniform = subBuilder;
+            break;
+          }
+          case 34: {
+            global::Grpc.Testing.DeterministicParams subBuilder = new global::Grpc.Testing.DeterministicParams();
+            if (loadCase_ == LoadOneofCase.Determ) {
+              subBuilder.MergeFrom(Determ);
+            }
+            input.ReadMessage(subBuilder);
+            Determ = subBuilder;
+            break;
+          }
+          case 42: {
+            global::Grpc.Testing.ParetoParams subBuilder = new global::Grpc.Testing.ParetoParams();
+            if (loadCase_ == LoadOneofCase.Pareto) {
+              subBuilder.MergeFrom(Pareto);
+            }
+            input.ReadMessage(subBuilder);
+            Pareto = subBuilder;
+            break;
+          }
+        }
+      }
+    }
+
+  }
+
+  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+  public sealed partial class SecurityParams : pb::IMessage<SecurityParams> {
+    private static readonly pb::MessageParser<SecurityParams> _parser = new pb::MessageParser<SecurityParams>(() => new SecurityParams());
+    public static pb::MessageParser<SecurityParams> Parser { get { return _parser; } }
+
+    public static pbr::MessageDescriptor Descriptor {
+      get { return global::Grpc.Testing.Control.Descriptor.MessageTypes[6]; }
+    }
+
+    pbr::MessageDescriptor pb::IMessage.Descriptor {
+      get { return Descriptor; }
+    }
+
+    public SecurityParams() {
+      OnConstruction();
+    }
+
+    partial void OnConstruction();
+
+    public SecurityParams(SecurityParams other) : this() {
+      useTestCa_ = other.useTestCa_;
+      serverHostOverride_ = other.serverHostOverride_;
+    }
+
+    public SecurityParams Clone() {
+      return new SecurityParams(this);
+    }
+
+    public const int UseTestCaFieldNumber = 1;
+    private bool useTestCa_;
+    public bool UseTestCa {
+      get { return useTestCa_; }
+      set {
+        useTestCa_ = value;
+      }
+    }
+
+    public const int ServerHostOverrideFieldNumber = 2;
+    private string serverHostOverride_ = "";
+    public string ServerHostOverride {
+      get { return serverHostOverride_; }
+      set {
+        serverHostOverride_ = pb::Preconditions.CheckNotNull(value, "value");
+      }
+    }
+
+    public override bool Equals(object other) {
+      return Equals(other as SecurityParams);
+    }
+
+    public bool Equals(SecurityParams other) {
+      if (ReferenceEquals(other, null)) {
+        return false;
+      }
+      if (ReferenceEquals(other, this)) {
+        return true;
+      }
+      if (UseTestCa != other.UseTestCa) return false;
+      if (ServerHostOverride != other.ServerHostOverride) return false;
+      return true;
+    }
+
+    public override int GetHashCode() {
+      int hash = 1;
+      if (UseTestCa != false) hash ^= UseTestCa.GetHashCode();
+      if (ServerHostOverride.Length != 0) hash ^= ServerHostOverride.GetHashCode();
+      return hash;
+    }
+
+    public override string ToString() {
+      return pb::JsonFormatter.Default.Format(this);
+    }
+
+    public void WriteTo(pb::CodedOutputStream output) {
+      if (UseTestCa != false) {
+        output.WriteRawTag(8);
+        output.WriteBool(UseTestCa);
+      }
+      if (ServerHostOverride.Length != 0) {
+        output.WriteRawTag(18);
+        output.WriteString(ServerHostOverride);
+      }
+    }
+
+    public int CalculateSize() {
+      int size = 0;
+      if (UseTestCa != false) {
+        size += 1 + 1;
+      }
+      if (ServerHostOverride.Length != 0) {
+        size += 1 + pb::CodedOutputStream.ComputeStringSize(ServerHostOverride);
+      }
+      return size;
+    }
+
+    public void MergeFrom(SecurityParams other) {
+      if (other == null) {
+        return;
+      }
+      if (other.UseTestCa != false) {
+        UseTestCa = other.UseTestCa;
+      }
+      if (other.ServerHostOverride.Length != 0) {
+        ServerHostOverride = other.ServerHostOverride;
+      }
+    }
+
+    public void MergeFrom(pb::CodedInputStream input) {
+      uint tag;
+      while ((tag = input.ReadTag()) != 0) {
+        switch(tag) {
+          default:
+            input.SkipLastField();
+            break;
+          case 8: {
+            UseTestCa = input.ReadBool();
+            break;
+          }
+          case 18: {
+            ServerHostOverride = input.ReadString();
+            break;
+          }
+        }
+      }
+    }
+
+  }
+
+  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+  public sealed partial class ClientConfig : pb::IMessage<ClientConfig> {
+    private static readonly pb::MessageParser<ClientConfig> _parser = new pb::MessageParser<ClientConfig>(() => new ClientConfig());
+    public static pb::MessageParser<ClientConfig> Parser { get { return _parser; } }
+
+    public static pbr::MessageDescriptor Descriptor {
+      get { return global::Grpc.Testing.Control.Descriptor.MessageTypes[7]; }
+    }
+
+    pbr::MessageDescriptor pb::IMessage.Descriptor {
+      get { return Descriptor; }
+    }
+
+    public ClientConfig() {
+      OnConstruction();
+    }
+
+    partial void OnConstruction();
+
+    public ClientConfig(ClientConfig other) : this() {
+      serverTargets_ = other.serverTargets_.Clone();
+      clientType_ = other.clientType_;
+      SecurityParams = other.securityParams_ != null ? other.SecurityParams.Clone() : null;
+      outstandingRpcsPerChannel_ = other.outstandingRpcsPerChannel_;
+      clientChannels_ = other.clientChannels_;
+      asyncClientThreads_ = other.asyncClientThreads_;
+      rpcType_ = other.rpcType_;
+      LoadParams = other.loadParams_ != null ? other.LoadParams.Clone() : null;
+      PayloadConfig = other.payloadConfig_ != null ? other.PayloadConfig.Clone() : null;
+      HistogramParams = other.histogramParams_ != null ? other.HistogramParams.Clone() : null;
+    }
+
+    public ClientConfig Clone() {
+      return new ClientConfig(this);
+    }
+
+    public const int ServerTargetsFieldNumber = 1;
+    private static readonly pb::FieldCodec<string> _repeated_serverTargets_codec
+        = pb::FieldCodec.ForString(10);
+    private readonly pbc::RepeatedField<string> serverTargets_ = new pbc::RepeatedField<string>();
+    public pbc::RepeatedField<string> ServerTargets {
+      get { return serverTargets_; }
+    }
+
+    public const int ClientTypeFieldNumber = 2;
+    private global::Grpc.Testing.ClientType clientType_ = global::Grpc.Testing.ClientType.SYNC_CLIENT;
+    public global::Grpc.Testing.ClientType ClientType {
+      get { return clientType_; }
+      set {
+        clientType_ = value;
+      }
+    }
+
+    public const int SecurityParamsFieldNumber = 3;
+    private global::Grpc.Testing.SecurityParams securityParams_;
+    public global::Grpc.Testing.SecurityParams SecurityParams {
+      get { return securityParams_; }
+      set {
+        securityParams_ = value;
+      }
+    }
+
+    public const int OutstandingRpcsPerChannelFieldNumber = 4;
+    private int outstandingRpcsPerChannel_;
+    public int OutstandingRpcsPerChannel {
+      get { return outstandingRpcsPerChannel_; }
+      set {
+        outstandingRpcsPerChannel_ = value;
+      }
+    }
+
+    public const int ClientChannelsFieldNumber = 5;
+    private int clientChannels_;
+    public int ClientChannels {
+      get { return clientChannels_; }
+      set {
+        clientChannels_ = value;
+      }
+    }
+
+    public const int AsyncClientThreadsFieldNumber = 7;
+    private int asyncClientThreads_;
+    public int AsyncClientThreads {
+      get { return asyncClientThreads_; }
+      set {
+        asyncClientThreads_ = value;
+      }
+    }
+
+    public const int RpcTypeFieldNumber = 8;
+    private global::Grpc.Testing.RpcType rpcType_ = global::Grpc.Testing.RpcType.UNARY;
+    public global::Grpc.Testing.RpcType RpcType {
+      get { return rpcType_; }
+      set {
+        rpcType_ = value;
+      }
+    }
+
+    public const int LoadParamsFieldNumber = 10;
+    private global::Grpc.Testing.LoadParams loadParams_;
+    public global::Grpc.Testing.LoadParams LoadParams {
+      get { return loadParams_; }
+      set {
+        loadParams_ = value;
+      }
+    }
+
+    public const int PayloadConfigFieldNumber = 11;
+    private global::Grpc.Testing.PayloadConfig payloadConfig_;
+    public global::Grpc.Testing.PayloadConfig PayloadConfig {
+      get { return payloadConfig_; }
+      set {
+        payloadConfig_ = value;
+      }
+    }
+
+    public const int HistogramParamsFieldNumber = 12;
+    private global::Grpc.Testing.HistogramParams histogramParams_;
+    public global::Grpc.Testing.HistogramParams HistogramParams {
+      get { return histogramParams_; }
+      set {
+        histogramParams_ = value;
+      }
+    }
+
+    public override bool Equals(object other) {
+      return Equals(other as ClientConfig);
+    }
+
+    public bool Equals(ClientConfig other) {
+      if (ReferenceEquals(other, null)) {
+        return false;
+      }
+      if (ReferenceEquals(other, this)) {
+        return true;
+      }
+      if(!serverTargets_.Equals(other.serverTargets_)) return false;
+      if (ClientType != other.ClientType) return false;
+      if (!object.Equals(SecurityParams, other.SecurityParams)) return false;
+      if (OutstandingRpcsPerChannel != other.OutstandingRpcsPerChannel) return false;
+      if (ClientChannels != other.ClientChannels) return false;
+      if (AsyncClientThreads != other.AsyncClientThreads) return false;
+      if (RpcType != other.RpcType) return false;
+      if (!object.Equals(LoadParams, other.LoadParams)) return false;
+      if (!object.Equals(PayloadConfig, other.PayloadConfig)) return false;
+      if (!object.Equals(HistogramParams, other.HistogramParams)) return false;
+      return true;
+    }
+
+    public override int GetHashCode() {
+      int hash = 1;
+      hash ^= serverTargets_.GetHashCode();
+      if (ClientType != global::Grpc.Testing.ClientType.SYNC_CLIENT) hash ^= ClientType.GetHashCode();
+      if (securityParams_ != null) hash ^= SecurityParams.GetHashCode();
+      if (OutstandingRpcsPerChannel != 0) hash ^= OutstandingRpcsPerChannel.GetHashCode();
+      if (ClientChannels != 0) hash ^= ClientChannels.GetHashCode();
+      if (AsyncClientThreads != 0) hash ^= AsyncClientThreads.GetHashCode();
+      if (RpcType != global::Grpc.Testing.RpcType.UNARY) hash ^= RpcType.GetHashCode();
+      if (loadParams_ != null) hash ^= LoadParams.GetHashCode();
+      if (payloadConfig_ != null) hash ^= PayloadConfig.GetHashCode();
+      if (histogramParams_ != null) hash ^= HistogramParams.GetHashCode();
+      return hash;
+    }
+
+    public override string ToString() {
+      return pb::JsonFormatter.Default.Format(this);
+    }
+
+    public void WriteTo(pb::CodedOutputStream output) {
+      serverTargets_.WriteTo(output, _repeated_serverTargets_codec);
+      if (ClientType != global::Grpc.Testing.ClientType.SYNC_CLIENT) {
+        output.WriteRawTag(16);
+        output.WriteEnum((int) ClientType);
+      }
+      if (securityParams_ != null) {
+        output.WriteRawTag(26);
+        output.WriteMessage(SecurityParams);
+      }
+      if (OutstandingRpcsPerChannel != 0) {
+        output.WriteRawTag(32);
+        output.WriteInt32(OutstandingRpcsPerChannel);
+      }
+      if (ClientChannels != 0) {
+        output.WriteRawTag(40);
+        output.WriteInt32(ClientChannels);
+      }
+      if (AsyncClientThreads != 0) {
+        output.WriteRawTag(56);
+        output.WriteInt32(AsyncClientThreads);
+      }
+      if (RpcType != global::Grpc.Testing.RpcType.UNARY) {
+        output.WriteRawTag(64);
+        output.WriteEnum((int) RpcType);
+      }
+      if (loadParams_ != null) {
+        output.WriteRawTag(82);
+        output.WriteMessage(LoadParams);
+      }
+      if (payloadConfig_ != null) {
+        output.WriteRawTag(90);
+        output.WriteMessage(PayloadConfig);
+      }
+      if (histogramParams_ != null) {
+        output.WriteRawTag(98);
+        output.WriteMessage(HistogramParams);
+      }
+    }
+
+    public int CalculateSize() {
+      int size = 0;
+      size += serverTargets_.CalculateSize(_repeated_serverTargets_codec);
+      if (ClientType != global::Grpc.Testing.ClientType.SYNC_CLIENT) {
+        size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) ClientType);
+      }
+      if (securityParams_ != null) {
+        size += 1 + pb::CodedOutputStream.ComputeMessageSize(SecurityParams);
+      }
+      if (OutstandingRpcsPerChannel != 0) {
+        size += 1 + pb::CodedOutputStream.ComputeInt32Size(OutstandingRpcsPerChannel);
+      }
+      if (ClientChannels != 0) {
+        size += 1 + pb::CodedOutputStream.ComputeInt32Size(ClientChannels);
+      }
+      if (AsyncClientThreads != 0) {
+        size += 1 + pb::CodedOutputStream.ComputeInt32Size(AsyncClientThreads);
+      }
+      if (RpcType != global::Grpc.Testing.RpcType.UNARY) {
+        size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) RpcType);
+      }
+      if (loadParams_ != null) {
+        size += 1 + pb::CodedOutputStream.ComputeMessageSize(LoadParams);
+      }
+      if (payloadConfig_ != null) {
+        size += 1 + pb::CodedOutputStream.ComputeMessageSize(PayloadConfig);
+      }
+      if (histogramParams_ != null) {
+        size += 1 + pb::CodedOutputStream.ComputeMessageSize(HistogramParams);
+      }
+      return size;
+    }
+
+    public void MergeFrom(ClientConfig other) {
+      if (other == null) {
+        return;
+      }
+      serverTargets_.Add(other.serverTargets_);
+      if (other.ClientType != global::Grpc.Testing.ClientType.SYNC_CLIENT) {
+        ClientType = other.ClientType;
+      }
+      if (other.securityParams_ != null) {
+        if (securityParams_ == null) {
+          securityParams_ = new global::Grpc.Testing.SecurityParams();
+        }
+        SecurityParams.MergeFrom(other.SecurityParams);
+      }
+      if (other.OutstandingRpcsPerChannel != 0) {
+        OutstandingRpcsPerChannel = other.OutstandingRpcsPerChannel;
+      }
+      if (other.ClientChannels != 0) {
+        ClientChannels = other.ClientChannels;
+      }
+      if (other.AsyncClientThreads != 0) {
+        AsyncClientThreads = other.AsyncClientThreads;
+      }
+      if (other.RpcType != global::Grpc.Testing.RpcType.UNARY) {
+        RpcType = other.RpcType;
+      }
+      if (other.loadParams_ != null) {
+        if (loadParams_ == null) {
+          loadParams_ = new global::Grpc.Testing.LoadParams();
+        }
+        LoadParams.MergeFrom(other.LoadParams);
+      }
+      if (other.payloadConfig_ != null) {
+        if (payloadConfig_ == null) {
+          payloadConfig_ = new global::Grpc.Testing.PayloadConfig();
+        }
+        PayloadConfig.MergeFrom(other.PayloadConfig);
+      }
+      if (other.histogramParams_ != null) {
+        if (histogramParams_ == null) {
+          histogramParams_ = new global::Grpc.Testing.HistogramParams();
+        }
+        HistogramParams.MergeFrom(other.HistogramParams);
+      }
+    }
+
+    public void MergeFrom(pb::CodedInputStream input) {
+      uint tag;
+      while ((tag = input.ReadTag()) != 0) {
+        switch(tag) {
+          default:
+            input.SkipLastField();
+            break;
+          case 10: {
+            serverTargets_.AddEntriesFrom(input, _repeated_serverTargets_codec);
+            break;
+          }
+          case 16: {
+            clientType_ = (global::Grpc.Testing.ClientType) input.ReadEnum();
+            break;
+          }
+          case 26: {
+            if (securityParams_ == null) {
+              securityParams_ = new global::Grpc.Testing.SecurityParams();
+            }
+            input.ReadMessage(securityParams_);
+            break;
+          }
+          case 32: {
+            OutstandingRpcsPerChannel = input.ReadInt32();
+            break;
+          }
+          case 40: {
+            ClientChannels = input.ReadInt32();
+            break;
+          }
+          case 56: {
+            AsyncClientThreads = input.ReadInt32();
+            break;
+          }
+          case 64: {
+            rpcType_ = (global::Grpc.Testing.RpcType) input.ReadEnum();
+            break;
+          }
+          case 82: {
+            if (loadParams_ == null) {
+              loadParams_ = new global::Grpc.Testing.LoadParams();
+            }
+            input.ReadMessage(loadParams_);
+            break;
+          }
+          case 90: {
+            if (payloadConfig_ == null) {
+              payloadConfig_ = new global::Grpc.Testing.PayloadConfig();
+            }
+            input.ReadMessage(payloadConfig_);
+            break;
+          }
+          case 98: {
+            if (histogramParams_ == null) {
+              histogramParams_ = new global::Grpc.Testing.HistogramParams();
+            }
+            input.ReadMessage(histogramParams_);
+            break;
+          }
+        }
+      }
+    }
+
+  }
+
+  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+  public sealed partial class ClientStatus : pb::IMessage<ClientStatus> {
+    private static readonly pb::MessageParser<ClientStatus> _parser = new pb::MessageParser<ClientStatus>(() => new ClientStatus());
+    public static pb::MessageParser<ClientStatus> Parser { get { return _parser; } }
+
+    public static pbr::MessageDescriptor Descriptor {
+      get { return global::Grpc.Testing.Control.Descriptor.MessageTypes[8]; }
+    }
+
+    pbr::MessageDescriptor pb::IMessage.Descriptor {
+      get { return Descriptor; }
+    }
+
+    public ClientStatus() {
+      OnConstruction();
+    }
+
+    partial void OnConstruction();
+
+    public ClientStatus(ClientStatus other) : this() {
+      Stats = other.stats_ != null ? other.Stats.Clone() : null;
+    }
+
+    public ClientStatus Clone() {
+      return new ClientStatus(this);
+    }
+
+    public const int StatsFieldNumber = 1;
+    private global::Grpc.Testing.ClientStats stats_;
+    public global::Grpc.Testing.ClientStats Stats {
+      get { return stats_; }
+      set {
+        stats_ = value;
+      }
+    }
+
+    public override bool Equals(object other) {
+      return Equals(other as ClientStatus);
+    }
+
+    public bool Equals(ClientStatus other) {
+      if (ReferenceEquals(other, null)) {
+        return false;
+      }
+      if (ReferenceEquals(other, this)) {
+        return true;
+      }
+      if (!object.Equals(Stats, other.Stats)) return false;
+      return true;
+    }
+
+    public override int GetHashCode() {
+      int hash = 1;
+      if (stats_ != null) hash ^= Stats.GetHashCode();
+      return hash;
+    }
+
+    public override string ToString() {
+      return pb::JsonFormatter.Default.Format(this);
+    }
+
+    public void WriteTo(pb::CodedOutputStream output) {
+      if (stats_ != null) {
+        output.WriteRawTag(10);
+        output.WriteMessage(Stats);
+      }
+    }
+
+    public int CalculateSize() {
+      int size = 0;
+      if (stats_ != null) {
+        size += 1 + pb::CodedOutputStream.ComputeMessageSize(Stats);
+      }
+      return size;
+    }
+
+    public void MergeFrom(ClientStatus other) {
+      if (other == null) {
+        return;
+      }
+      if (other.stats_ != null) {
+        if (stats_ == null) {
+          stats_ = new global::Grpc.Testing.ClientStats();
+        }
+        Stats.MergeFrom(other.Stats);
+      }
+    }
+
+    public void MergeFrom(pb::CodedInputStream input) {
+      uint tag;
+      while ((tag = input.ReadTag()) != 0) {
+        switch(tag) {
+          default:
+            input.SkipLastField();
+            break;
+          case 10: {
+            if (stats_ == null) {
+              stats_ = new global::Grpc.Testing.ClientStats();
+            }
+            input.ReadMessage(stats_);
+            break;
+          }
+        }
+      }
+    }
+
+  }
+
+  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+  public sealed partial class Mark : pb::IMessage<Mark> {
+    private static readonly pb::MessageParser<Mark> _parser = new pb::MessageParser<Mark>(() => new Mark());
+    public static pb::MessageParser<Mark> Parser { get { return _parser; } }
+
+    public static pbr::MessageDescriptor Descriptor {
+      get { return global::Grpc.Testing.Control.Descriptor.MessageTypes[9]; }
+    }
+
+    pbr::MessageDescriptor pb::IMessage.Descriptor {
+      get { return Descriptor; }
+    }
+
+    public Mark() {
+      OnConstruction();
+    }
+
+    partial void OnConstruction();
+
+    public Mark(Mark other) : this() {
+      reset_ = other.reset_;
+    }
+
+    public Mark Clone() {
+      return new Mark(this);
+    }
+
+    public const int ResetFieldNumber = 1;
+    private bool reset_;
+    public bool Reset {
+      get { return reset_; }
+      set {
+        reset_ = value;
+      }
+    }
+
+    public override bool Equals(object other) {
+      return Equals(other as Mark);
+    }
+
+    public bool Equals(Mark other) {
+      if (ReferenceEquals(other, null)) {
+        return false;
+      }
+      if (ReferenceEquals(other, this)) {
+        return true;
+      }
+      if (Reset != other.Reset) return false;
+      return true;
+    }
+
+    public override int GetHashCode() {
+      int hash = 1;
+      if (Reset != false) hash ^= Reset.GetHashCode();
+      return hash;
+    }
+
+    public override string ToString() {
+      return pb::JsonFormatter.Default.Format(this);
+    }
+
+    public void WriteTo(pb::CodedOutputStream output) {
+      if (Reset != false) {
+        output.WriteRawTag(8);
+        output.WriteBool(Reset);
+      }
+    }
+
+    public int CalculateSize() {
+      int size = 0;
+      if (Reset != false) {
+        size += 1 + 1;
+      }
+      return size;
+    }
+
+    public void MergeFrom(Mark other) {
+      if (other == null) {
+        return;
+      }
+      if (other.Reset != false) {
+        Reset = other.Reset;
+      }
+    }
+
+    public void MergeFrom(pb::CodedInputStream input) {
+      uint tag;
+      while ((tag = input.ReadTag()) != 0) {
+        switch(tag) {
+          default:
+            input.SkipLastField();
+            break;
+          case 8: {
+            Reset = input.ReadBool();
+            break;
+          }
+        }
+      }
+    }
+
+  }
+
+  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+  public sealed partial class ClientArgs : pb::IMessage<ClientArgs> {
+    private static readonly pb::MessageParser<ClientArgs> _parser = new pb::MessageParser<ClientArgs>(() => new ClientArgs());
+    public static pb::MessageParser<ClientArgs> Parser { get { return _parser; } }
+
+    public static pbr::MessageDescriptor Descriptor {
+      get { return global::Grpc.Testing.Control.Descriptor.MessageTypes[10]; }
+    }
+
+    pbr::MessageDescriptor pb::IMessage.Descriptor {
+      get { return Descriptor; }
+    }
+
+    public ClientArgs() {
+      OnConstruction();
+    }
+
+    partial void OnConstruction();
+
+    public ClientArgs(ClientArgs other) : this() {
+      switch (other.ArgtypeCase) {
+        case ArgtypeOneofCase.Setup:
+          Setup = other.Setup.Clone();
+          break;
+        case ArgtypeOneofCase.Mark:
+          Mark = other.Mark.Clone();
+          break;
+      }
+
+    }
+
+    public ClientArgs Clone() {
+      return new ClientArgs(this);
+    }
+
+    public const int SetupFieldNumber = 1;
+    public global::Grpc.Testing.ClientConfig Setup {
+      get { return argtypeCase_ == ArgtypeOneofCase.Setup ? (global::Grpc.Testing.ClientConfig) argtype_ : null; }
+      set {
+        argtype_ = value;
+        argtypeCase_ = value == null ? ArgtypeOneofCase.None : ArgtypeOneofCase.Setup;
+      }
+    }
+
+    public const int MarkFieldNumber = 2;
+    public global::Grpc.Testing.Mark Mark {
+      get { return argtypeCase_ == ArgtypeOneofCase.Mark ? (global::Grpc.Testing.Mark) argtype_ : null; }
+      set {
+        argtype_ = value;
+        argtypeCase_ = value == null ? ArgtypeOneofCase.None : ArgtypeOneofCase.Mark;
+      }
+    }
+
+    private object argtype_;
+    public enum ArgtypeOneofCase {
+      None = 0,
+      Setup = 1,
+      Mark = 2,
+    }
+    private ArgtypeOneofCase argtypeCase_ = ArgtypeOneofCase.None;
+    public ArgtypeOneofCase ArgtypeCase {
+      get { return argtypeCase_; }
+    }
+
+    public void ClearArgtype() {
+      argtypeCase_ = ArgtypeOneofCase.None;
+      argtype_ = null;
+    }
+
+    public override bool Equals(object other) {
+      return Equals(other as ClientArgs);
+    }
+
+    public bool Equals(ClientArgs other) {
+      if (ReferenceEquals(other, null)) {
+        return false;
+      }
+      if (ReferenceEquals(other, this)) {
+        return true;
+      }
+      if (!object.Equals(Setup, other.Setup)) return false;
+      if (!object.Equals(Mark, other.Mark)) return false;
+      return true;
+    }
+
+    public override int GetHashCode() {
+      int hash = 1;
+      if (argtypeCase_ == ArgtypeOneofCase.Setup) hash ^= Setup.GetHashCode();
+      if (argtypeCase_ == ArgtypeOneofCase.Mark) hash ^= Mark.GetHashCode();
+      return hash;
+    }
+
+    public override string ToString() {
+      return pb::JsonFormatter.Default.Format(this);
+    }
+
+    public void WriteTo(pb::CodedOutputStream output) {
+      if (argtypeCase_ == ArgtypeOneofCase.Setup) {
+        output.WriteRawTag(10);
+        output.WriteMessage(Setup);
+      }
+      if (argtypeCase_ == ArgtypeOneofCase.Mark) {
+        output.WriteRawTag(18);
+        output.WriteMessage(Mark);
+      }
+    }
+
+    public int CalculateSize() {
+      int size = 0;
+      if (argtypeCase_ == ArgtypeOneofCase.Setup) {
+        size += 1 + pb::CodedOutputStream.ComputeMessageSize(Setup);
+      }
+      if (argtypeCase_ == ArgtypeOneofCase.Mark) {
+        size += 1 + pb::CodedOutputStream.ComputeMessageSize(Mark);
+      }
+      return size;
+    }
+
+    public void MergeFrom(ClientArgs other) {
+      if (other == null) {
+        return;
+      }
+      switch (other.ArgtypeCase) {
+        case ArgtypeOneofCase.Setup:
+          Setup = other.Setup;
+          break;
+        case ArgtypeOneofCase.Mark:
+          Mark = other.Mark;
+          break;
+      }
+
+    }
+
+    public void MergeFrom(pb::CodedInputStream input) {
+      uint tag;
+      while ((tag = input.ReadTag()) != 0) {
+        switch(tag) {
+          default:
+            input.SkipLastField();
+            break;
+          case 10: {
+            global::Grpc.Testing.ClientConfig subBuilder = new global::Grpc.Testing.ClientConfig();
+            if (argtypeCase_ == ArgtypeOneofCase.Setup) {
+              subBuilder.MergeFrom(Setup);
+            }
+            input.ReadMessage(subBuilder);
+            Setup = subBuilder;
+            break;
+          }
+          case 18: {
+            global::Grpc.Testing.Mark subBuilder = new global::Grpc.Testing.Mark();
+            if (argtypeCase_ == ArgtypeOneofCase.Mark) {
+              subBuilder.MergeFrom(Mark);
+            }
+            input.ReadMessage(subBuilder);
+            Mark = subBuilder;
+            break;
+          }
+        }
+      }
+    }
+
+  }
+
+  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+  public sealed partial class ServerConfig : pb::IMessage<ServerConfig> {
+    private static readonly pb::MessageParser<ServerConfig> _parser = new pb::MessageParser<ServerConfig>(() => new ServerConfig());
+    public static pb::MessageParser<ServerConfig> Parser { get { return _parser; } }
+
+    public static pbr::MessageDescriptor Descriptor {
+      get { return global::Grpc.Testing.Control.Descriptor.MessageTypes[11]; }
+    }
+
+    pbr::MessageDescriptor pb::IMessage.Descriptor {
+      get { return Descriptor; }
+    }
+
+    public ServerConfig() {
+      OnConstruction();
+    }
+
+    partial void OnConstruction();
+
+    public ServerConfig(ServerConfig other) : this() {
+      serverType_ = other.serverType_;
+      SecurityParams = other.securityParams_ != null ? other.SecurityParams.Clone() : null;
+      host_ = other.host_;
+      port_ = other.port_;
+      asyncServerThreads_ = other.asyncServerThreads_;
+      coreLimit_ = other.coreLimit_;
+      PayloadConfig = other.payloadConfig_ != null ? other.PayloadConfig.Clone() : null;
+    }
+
+    public ServerConfig Clone() {
+      return new ServerConfig(this);
+    }
+
+    public const int ServerTypeFieldNumber = 1;
+    private global::Grpc.Testing.ServerType serverType_ = global::Grpc.Testing.ServerType.SYNC_SERVER;
+    public global::Grpc.Testing.ServerType ServerType {
+      get { return serverType_; }
+      set {
+        serverType_ = value;
+      }
+    }
+
+    public const int SecurityParamsFieldNumber = 2;
+    private global::Grpc.Testing.SecurityParams securityParams_;
+    public global::Grpc.Testing.SecurityParams SecurityParams {
+      get { return securityParams_; }
+      set {
+        securityParams_ = value;
+      }
+    }
+
+    public const int HostFieldNumber = 3;
+    private string host_ = "";
+    public string Host {
+      get { return host_; }
+      set {
+        host_ = pb::Preconditions.CheckNotNull(value, "value");
+      }
+    }
+
+    public const int PortFieldNumber = 4;
+    private int port_;
+    public int Port {
+      get { return port_; }
+      set {
+        port_ = value;
+      }
+    }
+
+    public const int AsyncServerThreadsFieldNumber = 7;
+    private int asyncServerThreads_;
+    public int AsyncServerThreads {
+      get { return asyncServerThreads_; }
+      set {
+        asyncServerThreads_ = value;
+      }
+    }
+
+    public const int CoreLimitFieldNumber = 8;
+    private int coreLimit_;
+    public int CoreLimit {
+      get { return coreLimit_; }
+      set {
+        coreLimit_ = value;
+      }
+    }
+
+    public const int PayloadConfigFieldNumber = 9;
+    private global::Grpc.Testing.PayloadConfig payloadConfig_;
+    public global::Grpc.Testing.PayloadConfig PayloadConfig {
+      get { return payloadConfig_; }
+      set {
+        payloadConfig_ = value;
+      }
+    }
+
+    public override bool Equals(object other) {
+      return Equals(other as ServerConfig);
+    }
+
+    public bool Equals(ServerConfig other) {
+      if (ReferenceEquals(other, null)) {
+        return false;
+      }
+      if (ReferenceEquals(other, this)) {
+        return true;
+      }
+      if (ServerType != other.ServerType) return false;
+      if (!object.Equals(SecurityParams, other.SecurityParams)) return false;
+      if (Host != other.Host) return false;
+      if (Port != other.Port) return false;
+      if (AsyncServerThreads != other.AsyncServerThreads) return false;
+      if (CoreLimit != other.CoreLimit) return false;
+      if (!object.Equals(PayloadConfig, other.PayloadConfig)) return false;
+      return true;
+    }
+
+    public override int GetHashCode() {
+      int hash = 1;
+      if (ServerType != global::Grpc.Testing.ServerType.SYNC_SERVER) hash ^= ServerType.GetHashCode();
+      if (securityParams_ != null) hash ^= SecurityParams.GetHashCode();
+      if (Host.Length != 0) hash ^= Host.GetHashCode();
+      if (Port != 0) hash ^= Port.GetHashCode();
+      if (AsyncServerThreads != 0) hash ^= AsyncServerThreads.GetHashCode();
+      if (CoreLimit != 0) hash ^= CoreLimit.GetHashCode();
+      if (payloadConfig_ != null) hash ^= PayloadConfig.GetHashCode();
+      return hash;
+    }
+
+    public override string ToString() {
+      return pb::JsonFormatter.Default.Format(this);
+    }
+
+    public void WriteTo(pb::CodedOutputStream output) {
+      if (ServerType != global::Grpc.Testing.ServerType.SYNC_SERVER) {
+        output.WriteRawTag(8);
+        output.WriteEnum((int) ServerType);
+      }
+      if (securityParams_ != null) {
+        output.WriteRawTag(18);
+        output.WriteMessage(SecurityParams);
+      }
+      if (Host.Length != 0) {
+        output.WriteRawTag(26);
+        output.WriteString(Host);
+      }
+      if (Port != 0) {
+        output.WriteRawTag(32);
+        output.WriteInt32(Port);
+      }
+      if (AsyncServerThreads != 0) {
+        output.WriteRawTag(56);
+        output.WriteInt32(AsyncServerThreads);
+      }
+      if (CoreLimit != 0) {
+        output.WriteRawTag(64);
+        output.WriteInt32(CoreLimit);
+      }
+      if (payloadConfig_ != null) {
+        output.WriteRawTag(74);
+        output.WriteMessage(PayloadConfig);
+      }
+    }
+
+    public int CalculateSize() {
+      int size = 0;
+      if (ServerType != global::Grpc.Testing.ServerType.SYNC_SERVER) {
+        size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) ServerType);
+      }
+      if (securityParams_ != null) {
+        size += 1 + pb::CodedOutputStream.ComputeMessageSize(SecurityParams);
+      }
+      if (Host.Length != 0) {
+        size += 1 + pb::CodedOutputStream.ComputeStringSize(Host);
+      }
+      if (Port != 0) {
+        size += 1 + pb::CodedOutputStream.ComputeInt32Size(Port);
+      }
+      if (AsyncServerThreads != 0) {
+        size += 1 + pb::CodedOutputStream.ComputeInt32Size(AsyncServerThreads);
+      }
+      if (CoreLimit != 0) {
+        size += 1 + pb::CodedOutputStream.ComputeInt32Size(CoreLimit);
+      }
+      if (payloadConfig_ != null) {
+        size += 1 + pb::CodedOutputStream.ComputeMessageSize(PayloadConfig);
+      }
+      return size;
+    }
+
+    public void MergeFrom(ServerConfig other) {
+      if (other == null) {
+        return;
+      }
+      if (other.ServerType != global::Grpc.Testing.ServerType.SYNC_SERVER) {
+        ServerType = other.ServerType;
+      }
+      if (other.securityParams_ != null) {
+        if (securityParams_ == null) {
+          securityParams_ = new global::Grpc.Testing.SecurityParams();
+        }
+        SecurityParams.MergeFrom(other.SecurityParams);
+      }
+      if (other.Host.Length != 0) {
+        Host = other.Host;
+      }
+      if (other.Port != 0) {
+        Port = other.Port;
+      }
+      if (other.AsyncServerThreads != 0) {
+        AsyncServerThreads = other.AsyncServerThreads;
+      }
+      if (other.CoreLimit != 0) {
+        CoreLimit = other.CoreLimit;
+      }
+      if (other.payloadConfig_ != null) {
+        if (payloadConfig_ == null) {
+          payloadConfig_ = new global::Grpc.Testing.PayloadConfig();
+        }
+        PayloadConfig.MergeFrom(other.PayloadConfig);
+      }
+    }
+
+    public void MergeFrom(pb::CodedInputStream input) {
+      uint tag;
+      while ((tag = input.ReadTag()) != 0) {
+        switch(tag) {
+          default:
+            input.SkipLastField();
+            break;
+          case 8: {
+            serverType_ = (global::Grpc.Testing.ServerType) input.ReadEnum();
+            break;
+          }
+          case 18: {
+            if (securityParams_ == null) {
+              securityParams_ = new global::Grpc.Testing.SecurityParams();
+            }
+            input.ReadMessage(securityParams_);
+            break;
+          }
+          case 26: {
+            Host = input.ReadString();
+            break;
+          }
+          case 32: {
+            Port = input.ReadInt32();
+            break;
+          }
+          case 56: {
+            AsyncServerThreads = input.ReadInt32();
+            break;
+          }
+          case 64: {
+            CoreLimit = input.ReadInt32();
+            break;
+          }
+          case 74: {
+            if (payloadConfig_ == null) {
+              payloadConfig_ = new global::Grpc.Testing.PayloadConfig();
+            }
+            input.ReadMessage(payloadConfig_);
+            break;
+          }
+        }
+      }
+    }
+
+  }
+
+  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+  public sealed partial class ServerArgs : pb::IMessage<ServerArgs> {
+    private static readonly pb::MessageParser<ServerArgs> _parser = new pb::MessageParser<ServerArgs>(() => new ServerArgs());
+    public static pb::MessageParser<ServerArgs> Parser { get { return _parser; } }
+
+    public static pbr::MessageDescriptor Descriptor {
+      get { return global::Grpc.Testing.Control.Descriptor.MessageTypes[12]; }
+    }
+
+    pbr::MessageDescriptor pb::IMessage.Descriptor {
+      get { return Descriptor; }
+    }
+
+    public ServerArgs() {
+      OnConstruction();
+    }
+
+    partial void OnConstruction();
+
+    public ServerArgs(ServerArgs other) : this() {
+      switch (other.ArgtypeCase) {
+        case ArgtypeOneofCase.Setup:
+          Setup = other.Setup.Clone();
+          break;
+        case ArgtypeOneofCase.Mark:
+          Mark = other.Mark.Clone();
+          break;
+      }
+
+    }
+
+    public ServerArgs Clone() {
+      return new ServerArgs(this);
+    }
+
+    public const int SetupFieldNumber = 1;
+    public global::Grpc.Testing.ServerConfig Setup {
+      get { return argtypeCase_ == ArgtypeOneofCase.Setup ? (global::Grpc.Testing.ServerConfig) argtype_ : null; }
+      set {
+        argtype_ = value;
+        argtypeCase_ = value == null ? ArgtypeOneofCase.None : ArgtypeOneofCase.Setup;
+      }
+    }
+
+    public const int MarkFieldNumber = 2;
+    public global::Grpc.Testing.Mark Mark {
+      get { return argtypeCase_ == ArgtypeOneofCase.Mark ? (global::Grpc.Testing.Mark) argtype_ : null; }
+      set {
+        argtype_ = value;
+        argtypeCase_ = value == null ? ArgtypeOneofCase.None : ArgtypeOneofCase.Mark;
+      }
+    }
+
+    private object argtype_;
+    public enum ArgtypeOneofCase {
+      None = 0,
+      Setup = 1,
+      Mark = 2,
+    }
+    private ArgtypeOneofCase argtypeCase_ = ArgtypeOneofCase.None;
+    public ArgtypeOneofCase ArgtypeCase {
+      get { return argtypeCase_; }
+    }
+
+    public void ClearArgtype() {
+      argtypeCase_ = ArgtypeOneofCase.None;
+      argtype_ = null;
+    }
+
+    public override bool Equals(object other) {
+      return Equals(other as ServerArgs);
+    }
+
+    public bool Equals(ServerArgs other) {
+      if (ReferenceEquals(other, null)) {
+        return false;
+      }
+      if (ReferenceEquals(other, this)) {
+        return true;
+      }
+      if (!object.Equals(Setup, other.Setup)) return false;
+      if (!object.Equals(Mark, other.Mark)) return false;
+      return true;
+    }
+
+    public override int GetHashCode() {
+      int hash = 1;
+      if (argtypeCase_ == ArgtypeOneofCase.Setup) hash ^= Setup.GetHashCode();
+      if (argtypeCase_ == ArgtypeOneofCase.Mark) hash ^= Mark.GetHashCode();
+      return hash;
+    }
+
+    public override string ToString() {
+      return pb::JsonFormatter.Default.Format(this);
+    }
+
+    public void WriteTo(pb::CodedOutputStream output) {
+      if (argtypeCase_ == ArgtypeOneofCase.Setup) {
+        output.WriteRawTag(10);
+        output.WriteMessage(Setup);
+      }
+      if (argtypeCase_ == ArgtypeOneofCase.Mark) {
+        output.WriteRawTag(18);
+        output.WriteMessage(Mark);
+      }
+    }
+
+    public int CalculateSize() {
+      int size = 0;
+      if (argtypeCase_ == ArgtypeOneofCase.Setup) {
+        size += 1 + pb::CodedOutputStream.ComputeMessageSize(Setup);
+      }
+      if (argtypeCase_ == ArgtypeOneofCase.Mark) {
+        size += 1 + pb::CodedOutputStream.ComputeMessageSize(Mark);
+      }
+      return size;
+    }
+
+    public void MergeFrom(ServerArgs other) {
+      if (other == null) {
+        return;
+      }
+      switch (other.ArgtypeCase) {
+        case ArgtypeOneofCase.Setup:
+          Setup = other.Setup;
+          break;
+        case ArgtypeOneofCase.Mark:
+          Mark = other.Mark;
+          break;
+      }
+
+    }
+
+    public void MergeFrom(pb::CodedInputStream input) {
+      uint tag;
+      while ((tag = input.ReadTag()) != 0) {
+        switch(tag) {
+          default:
+            input.SkipLastField();
+            break;
+          case 10: {
+            global::Grpc.Testing.ServerConfig subBuilder = new global::Grpc.Testing.ServerConfig();
+            if (argtypeCase_ == ArgtypeOneofCase.Setup) {
+              subBuilder.MergeFrom(Setup);
+            }
+            input.ReadMessage(subBuilder);
+            Setup = subBuilder;
+            break;
+          }
+          case 18: {
+            global::Grpc.Testing.Mark subBuilder = new global::Grpc.Testing.Mark();
+            if (argtypeCase_ == ArgtypeOneofCase.Mark) {
+              subBuilder.MergeFrom(Mark);
+            }
+            input.ReadMessage(subBuilder);
+            Mark = subBuilder;
+            break;
+          }
+        }
+      }
+    }
+
+  }
+
+  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+  public sealed partial class ServerStatus : pb::IMessage<ServerStatus> {
+    private static readonly pb::MessageParser<ServerStatus> _parser = new pb::MessageParser<ServerStatus>(() => new ServerStatus());
+    public static pb::MessageParser<ServerStatus> Parser { get { return _parser; } }
+
+    public static pbr::MessageDescriptor Descriptor {
+      get { return global::Grpc.Testing.Control.Descriptor.MessageTypes[13]; }
+    }
+
+    pbr::MessageDescriptor pb::IMessage.Descriptor {
+      get { return Descriptor; }
+    }
+
+    public ServerStatus() {
+      OnConstruction();
+    }
+
+    partial void OnConstruction();
+
+    public ServerStatus(ServerStatus other) : this() {
+      Stats = other.stats_ != null ? other.Stats.Clone() : null;
+      port_ = other.port_;
+      cores_ = other.cores_;
+    }
+
+    public ServerStatus Clone() {
+      return new ServerStatus(this);
+    }
+
+    public const int StatsFieldNumber = 1;
+    private global::Grpc.Testing.ServerStats stats_;
+    public global::Grpc.Testing.ServerStats Stats {
+      get { return stats_; }
+      set {
+        stats_ = value;
+      }
+    }
+
+    public const int PortFieldNumber = 2;
+    private int port_;
+    public int Port {
+      get { return port_; }
+      set {
+        port_ = value;
+      }
+    }
+
+    public const int CoresFieldNumber = 3;
+    private int cores_;
+    public int Cores {
+      get { return cores_; }
+      set {
+        cores_ = value;
+      }
+    }
+
+    public override bool Equals(object other) {
+      return Equals(other as ServerStatus);
+    }
+
+    public bool Equals(ServerStatus other) {
+      if (ReferenceEquals(other, null)) {
+        return false;
+      }
+      if (ReferenceEquals(other, this)) {
+        return true;
+      }
+      if (!object.Equals(Stats, other.Stats)) return false;
+      if (Port != other.Port) return false;
+      if (Cores != other.Cores) return false;
+      return true;
+    }
+
+    public override int GetHashCode() {
+      int hash = 1;
+      if (stats_ != null) hash ^= Stats.GetHashCode();
+      if (Port != 0) hash ^= Port.GetHashCode();
+      if (Cores != 0) hash ^= Cores.GetHashCode();
+      return hash;
+    }
+
+    public override string ToString() {
+      return pb::JsonFormatter.Default.Format(this);
+    }
+
+    public void WriteTo(pb::CodedOutputStream output) {
+      if (stats_ != null) {
+        output.WriteRawTag(10);
+        output.WriteMessage(Stats);
+      }
+      if (Port != 0) {
+        output.WriteRawTag(16);
+        output.WriteInt32(Port);
+      }
+      if (Cores != 0) {
+        output.WriteRawTag(24);
+        output.WriteInt32(Cores);
+      }
+    }
+
+    public int CalculateSize() {
+      int size = 0;
+      if (stats_ != null) {
+        size += 1 + pb::CodedOutputStream.ComputeMessageSize(Stats);
+      }
+      if (Port != 0) {
+        size += 1 + pb::CodedOutputStream.ComputeInt32Size(Port);
+      }
+      if (Cores != 0) {
+        size += 1 + pb::CodedOutputStream.ComputeInt32Size(Cores);
+      }
+      return size;
+    }
+
+    public void MergeFrom(ServerStatus other) {
+      if (other == null) {
+        return;
+      }
+      if (other.stats_ != null) {
+        if (stats_ == null) {
+          stats_ = new global::Grpc.Testing.ServerStats();
+        }
+        Stats.MergeFrom(other.Stats);
+      }
+      if (other.Port != 0) {
+        Port = other.Port;
+      }
+      if (other.Cores != 0) {
+        Cores = other.Cores;
+      }
+    }
+
+    public void MergeFrom(pb::CodedInputStream input) {
+      uint tag;
+      while ((tag = input.ReadTag()) != 0) {
+        switch(tag) {
+          default:
+            input.SkipLastField();
+            break;
+          case 10: {
+            if (stats_ == null) {
+              stats_ = new global::Grpc.Testing.ServerStats();
+            }
+            input.ReadMessage(stats_);
+            break;
+          }
+          case 16: {
+            Port = input.ReadInt32();
+            break;
+          }
+          case 24: {
+            Cores = input.ReadInt32();
+            break;
+          }
+        }
+      }
+    }
+
+  }
+
+  #endregion
+
+}
+
+#endregion Designer generated code
diff --git a/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj b/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj
index 2b75305..012de45 100644
--- a/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj
+++ b/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj
@@ -38,45 +38,9 @@
     <AssemblyOriginatorKeyFile>C:\keys\Grpc.snk</AssemblyOriginatorKeyFile>
   </PropertyGroup>
   <ItemGroup>
-    <Reference Include="BouncyCastle.Crypto, Version=1.7.4137.9688, Culture=neutral, PublicKeyToken=a4292a325f69b123, processorArchitecture=MSIL">
-      <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\BouncyCastle.1.7.0\lib\Net40-Client\BouncyCastle.Crypto.dll</HintPath>
-    </Reference>
     <Reference Include="CommandLine">
       <HintPath>..\packages\CommandLineParser.1.9.71\lib\net45\CommandLine.dll</HintPath>
     </Reference>
-    <Reference Include="Google.Apis.Auth, Version=1.9.3.19379, Culture=neutral, PublicKeyToken=4b01fa6e34db77ab, processorArchitecture=MSIL">
-      <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\Google.Apis.Auth.1.9.3\lib\net40\Google.Apis.Auth.dll</HintPath>
-    </Reference>
-    <Reference Include="Google.Apis.Auth.PlatformServices, Version=1.9.3.19383, Culture=neutral, PublicKeyToken=4b01fa6e34db77ab, processorArchitecture=MSIL">
-      <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\Google.Apis.Auth.1.9.3\lib\net40\Google.Apis.Auth.PlatformServices.dll</HintPath>
-    </Reference>
-    <Reference Include="Google.Apis.Core, Version=1.9.3.19379, Culture=neutral, PublicKeyToken=4b01fa6e34db77ab, processorArchitecture=MSIL">
-      <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\Google.Apis.Core.1.9.3\lib\portable-net40+sl50+win+wpa81+wp80\Google.Apis.Core.dll</HintPath>
-    </Reference>
-    <Reference Include="Google.Protobuf, Version=3.0.0.0, Culture=neutral, PublicKeyToken=a7d26565bac4d604, processorArchitecture=MSIL">
-      <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\Google.Protobuf.3.0.0-alpha4\lib\portable-net45+netcore45+wpa81+wp8\Google.Protobuf.dll</HintPath>
-    </Reference>
-    <Reference Include="Microsoft.Threading.Tasks, Version=1.0.12.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
-      <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.dll</HintPath>
-    </Reference>
-    <Reference Include="Microsoft.Threading.Tasks.Extensions, Version=1.0.12.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
-      <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.dll</HintPath>
-    </Reference>
-    <Reference Include="Microsoft.Threading.Tasks.Extensions.Desktop, Version=1.0.168.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
-      <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.Desktop.dll</HintPath>
-    </Reference>
-    <Reference Include="Newtonsoft.Json, Version=7.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
-      <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
-    </Reference>
     <Reference Include="nunit.framework">
       <HintPath>..\packages\NUnit.2.6.4\lib\nunit.framework.dll</HintPath>
     </Reference>
@@ -87,6 +51,33 @@
     <Reference Include="System.Net" />
     <Reference Include="System.Net.Http" />
     <Reference Include="System.Net.Http.WebRequest" />
+    <Reference Include="BouncyCastle.Crypto">
+      <HintPath>..\packages\BouncyCastle.1.7.0\lib\Net40-Client\BouncyCastle.Crypto.dll</HintPath>
+    </Reference>
+    <Reference Include="Google.Apis.Auth">
+      <HintPath>..\packages\Google.Apis.Auth.1.9.3\lib\net40\Google.Apis.Auth.dll</HintPath>
+    </Reference>
+    <Reference Include="Google.Apis.Auth.PlatformServices">
+      <HintPath>..\packages\Google.Apis.Auth.1.9.3\lib\net40\Google.Apis.Auth.PlatformServices.dll</HintPath>
+    </Reference>
+    <Reference Include="Google.Apis.Core">
+      <HintPath>..\packages\Google.Apis.Core.1.9.3\lib\portable-net40+sl50+win+wpa81+wp80\Google.Apis.Core.dll</HintPath>
+    </Reference>
+    <Reference Include="Google.Protobuf">
+      <HintPath>..\packages\Google.Protobuf.3.0.0-alpha4\lib\portable-net45+netcore45+wpa81+wp8\Google.Protobuf.dll</HintPath>
+    </Reference>
+    <Reference Include="Microsoft.Threading.Tasks">
+      <HintPath>..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.dll</HintPath>
+    </Reference>
+    <Reference Include="Microsoft.Threading.Tasks.Extensions">
+      <HintPath>..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.dll</HintPath>
+    </Reference>
+    <Reference Include="Microsoft.Threading.Tasks.Extensions.Desktop">
+      <HintPath>..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.Desktop.dll</HintPath>
+    </Reference>
+    <Reference Include="Newtonsoft.Json">
+      <HintPath>..\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
+    </Reference>
   </ItemGroup>
   <ItemGroup>
     <Compile Include="..\Grpc.Core\Version.cs">
@@ -104,6 +95,22 @@
     <Compile Include="TestGrpc.cs" />
     <Compile Include="SslCredentialsTest.cs" />
     <Compile Include="Test.cs" />
+    <Compile Include="IClientRunner.cs" />
+    <Compile Include="ClientRunners.cs" />
+    <Compile Include="IServerRunner.cs" />
+    <Compile Include="ServerRunners.cs" />
+    <Compile Include="RunnerClientServerTest.cs" />
+    <Compile Include="Control.cs" />
+    <Compile Include="Payloads.cs" />
+    <Compile Include="Services.cs" />
+    <Compile Include="ServicesGrpc.cs" />
+    <Compile Include="Stats.cs" />
+    <Compile Include="BenchmarkServiceImpl.cs" />
+    <Compile Include="Histogram.cs" />
+    <Compile Include="HistogramTest.cs" />
+    <Compile Include="WorkerServiceImpl.cs" />
+    <Compile Include="QpsWorker.cs" />
+    <Compile Include="WallClockStopwatch.cs" />
   </ItemGroup>
   <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
   <ItemGroup>
diff --git a/src/csharp/Grpc.IntegrationTesting/Histogram.cs b/src/csharp/Grpc.IntegrationTesting/Histogram.cs
new file mode 100644
index 0000000..7e7cb2c
--- /dev/null
+++ b/src/csharp/Grpc.IntegrationTesting/Histogram.cs
@@ -0,0 +1,153 @@
+#region Copyright notice and license
+
+// Copyright 2015, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.Linq;
+using System.Text.RegularExpressions;
+using System.Threading;
+using System.Threading.Tasks;
+using Google.Protobuf;
+using Grpc.Core;
+using Grpc.Core.Utils;
+using NUnit.Framework;
+using Grpc.Testing;
+
+namespace Grpc.IntegrationTesting
+{
+    /// <summary>
+    /// Basic implementation of histogram based on grpc/support/histogram.h.
+    /// </summary>
+    public class Histogram
+    {
+        readonly object myLock = new object();
+        readonly double multiplier;
+        readonly double oneOnLogMultiplier;
+        readonly double maxPossible;
+        readonly uint[] buckets;
+
+        int count;
+        double sum;
+        double sumOfSquares;
+        double min;
+        double max;
+
+        public Histogram(double resolution, double maxPossible)
+        {
+            Grpc.Core.Utils.Preconditions.CheckArgument(resolution > 0);
+            Grpc.Core.Utils.Preconditions.CheckArgument(maxPossible > 0);
+            this.maxPossible = maxPossible;
+            this.multiplier = 1.0 + resolution;
+            this.oneOnLogMultiplier = 1.0 / Math.Log(1.0 + resolution);
+            this.buckets = new uint[FindBucket(maxPossible) + 1];
+
+            ResetUnsafe();
+        }
+
+        public void AddObservation(double value)
+        {
+            lock (myLock)
+            {
+                AddObservationUnsafe(value);    
+            }
+        }
+
+
+        /// <summary>
+        /// Gets snapshot of stats and reset 
+        /// </summary>
+        public HistogramData GetSnapshot(bool reset = false)
+        {
+            lock (myLock)
+            {
+                return GetSnapshotUnsafe(reset);    
+            }
+        }
+
+        /// <summary>
+        /// Finds bucket index to which given observation should go.
+        /// </summary>
+        private int FindBucket(double value)
+        {
+            value = Math.Max(value, 1.0);
+            value = Math.Min(value, this.maxPossible);
+            return (int)(Math.Log(value) * oneOnLogMultiplier);
+        }
+
+        private void AddObservationUnsafe(double value)
+        {
+            this.count++;
+            this.sum += value;
+            this.sumOfSquares += value * value;
+            this.min = Math.Min(this.min, value);
+            this.max = Math.Max(this.max, value);
+
+            this.buckets[FindBucket(value)]++;
+        }
+
+        private HistogramData GetSnapshotUnsafe(bool reset)
+        {
+            var data = new HistogramData
+            {
+                Count = count,
+                Sum = sum,
+                SumOfSquares = sumOfSquares,
+                MinSeen = min,
+                MaxSeen = max,
+                Bucket = { buckets }
+            };
+
+            if (reset)
+            {
+                ResetUnsafe();
+            }
+
+            return data;
+        }
+
+        private void ResetUnsafe()
+        {
+            this.count = 0;
+            this.sum = 0;
+            this.sumOfSquares = 0;
+            this.min = double.PositiveInfinity;
+            this.max = double.NegativeInfinity;
+            for (int i = 0; i < this.buckets.Length; i++)
+            {
+                this.buckets[i] = 0;
+            }
+        }
+    }
+}
diff --git a/src/csharp/Grpc.IntegrationTesting/HistogramTest.cs b/src/csharp/Grpc.IntegrationTesting/HistogramTest.cs
new file mode 100644
index 0000000..fa160cb
--- /dev/null
+++ b/src/csharp/Grpc.IntegrationTesting/HistogramTest.cs
@@ -0,0 +1,104 @@
+#region Copyright notice and license
+
+// Copyright 2015, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+using Grpc.Core;
+using Grpc.Core.Utils;
+using Grpc.Testing;
+using NUnit.Framework;
+
+namespace Grpc.IntegrationTesting
+{
+    public class HistogramTest
+    {
+        [Test]
+        public void Simple()
+        {
+            var hist = new Histogram(0.01, 60e9);
+            hist.AddObservation(10000);
+            hist.AddObservation(10000);
+            hist.AddObservation(11000);
+            hist.AddObservation(11000);
+
+            var data = hist.GetSnapshot();
+
+            Assert.AreEqual(4, data.Count);
+            Assert.AreEqual(42000.0, data.Sum, 1e-6);
+            Assert.AreEqual(10000, data.MinSeen);
+            Assert.AreEqual(11000, data.MaxSeen);
+            Assert.AreEqual(2.0*10000*10000 + 2.0*11000*11000, data.SumOfSquares, 1e-6);
+
+            // 1.01^925 < 10000 < 1.01^926
+            Assert.AreEqual(2, data.Bucket[925]);
+            Assert.AreEqual(2, data.Bucket[935]);
+        }
+
+        [Test]
+        public void ExtremeObservations()
+        {
+            var hist = new Histogram(0.01, 60e9);
+            hist.AddObservation(-0.5);  // should be in the first bucket
+            hist.AddObservation(1e12);  // should be in the last bucket 
+
+            var data = hist.GetSnapshot();
+            Assert.AreEqual(1, data.Bucket[0]);
+            Assert.AreEqual(1, data.Bucket[data.Bucket.Count - 1]);
+        }
+
+        [Test]
+        public void Reset()
+        {
+            var hist = new Histogram(0.01, 60e9);
+            hist.AddObservation(10000);
+            hist.AddObservation(11000);
+
+            var data = hist.GetSnapshot(true);  // snapshot contains data before reset
+            Assert.AreEqual(2, data.Count);
+            Assert.AreEqual(10000, data.MinSeen);
+            Assert.AreEqual(11000, data.MaxSeen);
+
+            data = hist.GetSnapshot();  // snapshot contains state after reset
+            Assert.AreEqual(0, data.Count);
+            Assert.AreEqual(double.PositiveInfinity, data.MinSeen);
+            Assert.AreEqual(double.NegativeInfinity, data.MaxSeen);
+            Assert.AreEqual(0, data.Sum);
+            Assert.AreEqual(0, data.SumOfSquares);
+            CollectionAssert.AreEqual(new uint[data.Bucket.Count], data.Bucket); 
+        }
+    }
+}
diff --git a/src/csharp/Grpc.IntegrationTesting/IClientRunner.cs b/src/csharp/Grpc.IntegrationTesting/IClientRunner.cs
new file mode 100644
index 0000000..39b94f1
--- /dev/null
+++ b/src/csharp/Grpc.IntegrationTesting/IClientRunner.cs
@@ -0,0 +1,67 @@
+#region Copyright notice and license
+
+// Copyright 2015, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.Linq;
+using System.Text.RegularExpressions;
+using System.Threading.Tasks;
+using Google.Protobuf;
+using Grpc.Core;
+using Grpc.Core.Utils;
+using NUnit.Framework;
+using Grpc.Testing;
+
+namespace Grpc.IntegrationTesting
+{
+    /// <summary>
+    /// Abstract client runner.
+    /// </summary>
+    public interface IClientRunner
+    {
+        /// <summary>
+        /// Gets stats snapshot.
+        /// </summary>
+        /// <returns>The stats.</returns>
+        ClientStats GetStats(bool reset);
+
+        /// <summary>
+        /// Asynchronously stops the client.
+        /// </summary>
+        /// <returns>Task that finishes when client has come to a full stop.</returns>
+        Task StopAsync();
+    }
+        
+}
diff --git a/src/csharp/Grpc.IntegrationTesting/IServerRunner.cs b/src/csharp/Grpc.IntegrationTesting/IServerRunner.cs
new file mode 100644
index 0000000..53a62fb
--- /dev/null
+++ b/src/csharp/Grpc.IntegrationTesting/IServerRunner.cs
@@ -0,0 +1,72 @@
+#region Copyright notice and license
+
+// Copyright 2015, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.Linq;
+using System.Text.RegularExpressions;
+using System.Threading.Tasks;
+using Google.Protobuf;
+using Grpc.Core;
+using Grpc.Core.Utils;
+using NUnit.Framework;
+using Grpc.Testing;
+
+namespace Grpc.IntegrationTesting
+{
+    /// <summary>
+    /// Abstract server runner.
+    /// </summary>
+    public interface IServerRunner
+    {
+        /// <summary>
+        /// Port on which the server is listening.
+        /// </summary>
+        int BoundPort { get; }
+        
+        /// <summary>
+        /// Gets server stats.
+        /// </summary>
+        /// <returns>The stats.</returns>
+        ServerStats GetStats(bool reset);
+
+        /// <summary>
+        /// Asynchronously stops the server.
+        /// </summary>
+        /// <returns>Task that finishes when server has shutdown.</returns>
+        Task StopAsync();
+    }
+        
+}
diff --git a/src/csharp/Grpc.IntegrationTesting/Payloads.cs b/src/csharp/Grpc.IntegrationTesting/Payloads.cs
new file mode 100644
index 0000000..a37dd9a
--- /dev/null
+++ b/src/csharp/Grpc.IntegrationTesting/Payloads.cs
@@ -0,0 +1,580 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: test/proto/benchmarks/payloads.proto
+#pragma warning disable 1591, 0612, 3021
+#region Designer generated code
+
+using pb = global::Google.Protobuf;
+using pbc = global::Google.Protobuf.Collections;
+using pbr = global::Google.Protobuf.Reflection;
+using scg = global::System.Collections.Generic;
+namespace Grpc.Testing {
+
+  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+  public static partial class Payloads {
+
+    #region Descriptor
+    public static pbr::FileDescriptor Descriptor {
+      get { return descriptor; }
+    }
+    private static pbr::FileDescriptor descriptor;
+
+    static Payloads() {
+      byte[] descriptorData = global::System.Convert.FromBase64String(
+          string.Concat(
+            "CiR0ZXN0L3Byb3RvL2JlbmNobWFya3MvcGF5bG9hZHMucHJvdG8SDGdycGMu", 
+            "dGVzdGluZyI3ChBCeXRlQnVmZmVyUGFyYW1zEhAKCHJlcV9zaXplGAEgASgF", 
+            "EhEKCXJlc3Bfc2l6ZRgCIAEoBSI4ChFTaW1wbGVQcm90b1BhcmFtcxIQCghy", 
+            "ZXFfc2l6ZRgBIAEoBRIRCglyZXNwX3NpemUYAiABKAUiFAoSQ29tcGxleFBy", 
+            "b3RvUGFyYW1zIsoBCg1QYXlsb2FkQ29uZmlnEjgKDmJ5dGVidWZfcGFyYW1z", 
+            "GAEgASgLMh4uZ3JwYy50ZXN0aW5nLkJ5dGVCdWZmZXJQYXJhbXNIABI4Cg1z", 
+            "aW1wbGVfcGFyYW1zGAIgASgLMh8uZ3JwYy50ZXN0aW5nLlNpbXBsZVByb3Rv", 
+            "UGFyYW1zSAASOgoOY29tcGxleF9wYXJhbXMYAyABKAsyIC5ncnBjLnRlc3Rp", 
+            "bmcuQ29tcGxleFByb3RvUGFyYW1zSABCCQoHcGF5bG9hZGIGcHJvdG8z"));
+      descriptor = pbr::FileDescriptor.InternalBuildGeneratedFileFrom(descriptorData,
+          new pbr::FileDescriptor[] { },
+          new pbr::GeneratedCodeInfo(null, new pbr::GeneratedCodeInfo[] {
+            new pbr::GeneratedCodeInfo(typeof(global::Grpc.Testing.ByteBufferParams), new[]{ "ReqSize", "RespSize" }, null, null, null),
+            new pbr::GeneratedCodeInfo(typeof(global::Grpc.Testing.SimpleProtoParams), new[]{ "ReqSize", "RespSize" }, null, null, null),
+            new pbr::GeneratedCodeInfo(typeof(global::Grpc.Testing.ComplexProtoParams), null, null, null, null),
+            new pbr::GeneratedCodeInfo(typeof(global::Grpc.Testing.PayloadConfig), new[]{ "BytebufParams", "SimpleParams", "ComplexParams" }, new[]{ "Payload" }, null, null)
+          }));
+    }
+    #endregion
+
+  }
+  #region Messages
+  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+  public sealed partial class ByteBufferParams : pb::IMessage<ByteBufferParams> {
+    private static readonly pb::MessageParser<ByteBufferParams> _parser = new pb::MessageParser<ByteBufferParams>(() => new ByteBufferParams());
+    public static pb::MessageParser<ByteBufferParams> Parser { get { return _parser; } }
+
+    public static pbr::MessageDescriptor Descriptor {
+      get { return global::Grpc.Testing.Payloads.Descriptor.MessageTypes[0]; }
+    }
+
+    pbr::MessageDescriptor pb::IMessage.Descriptor {
+      get { return Descriptor; }
+    }
+
+    public ByteBufferParams() {
+      OnConstruction();
+    }
+
+    partial void OnConstruction();
+
+    public ByteBufferParams(ByteBufferParams other) : this() {
+      reqSize_ = other.reqSize_;
+      respSize_ = other.respSize_;
+    }
+
+    public ByteBufferParams Clone() {
+      return new ByteBufferParams(this);
+    }
+
+    public const int ReqSizeFieldNumber = 1;
+    private int reqSize_;
+    public int ReqSize {
+      get { return reqSize_; }
+      set {
+        reqSize_ = value;
+      }
+    }
+
+    public const int RespSizeFieldNumber = 2;
+    private int respSize_;
+    public int RespSize {
+      get { return respSize_; }
+      set {
+        respSize_ = value;
+      }
+    }
+
+    public override bool Equals(object other) {
+      return Equals(other as ByteBufferParams);
+    }
+
+    public bool Equals(ByteBufferParams other) {
+      if (ReferenceEquals(other, null)) {
+        return false;
+      }
+      if (ReferenceEquals(other, this)) {
+        return true;
+      }
+      if (ReqSize != other.ReqSize) return false;
+      if (RespSize != other.RespSize) return false;
+      return true;
+    }
+
+    public override int GetHashCode() {
+      int hash = 1;
+      if (ReqSize != 0) hash ^= ReqSize.GetHashCode();
+      if (RespSize != 0) hash ^= RespSize.GetHashCode();
+      return hash;
+    }
+
+    public override string ToString() {
+      return pb::JsonFormatter.Default.Format(this);
+    }
+
+    public void WriteTo(pb::CodedOutputStream output) {
+      if (ReqSize != 0) {
+        output.WriteRawTag(8);
+        output.WriteInt32(ReqSize);
+      }
+      if (RespSize != 0) {
+        output.WriteRawTag(16);
+        output.WriteInt32(RespSize);
+      }
+    }
+
+    public int CalculateSize() {
+      int size = 0;
+      if (ReqSize != 0) {
+        size += 1 + pb::CodedOutputStream.ComputeInt32Size(ReqSize);
+      }
+      if (RespSize != 0) {
+        size += 1 + pb::CodedOutputStream.ComputeInt32Size(RespSize);
+      }
+      return size;
+    }
+
+    public void MergeFrom(ByteBufferParams other) {
+      if (other == null) {
+        return;
+      }
+      if (other.ReqSize != 0) {
+        ReqSize = other.ReqSize;
+      }
+      if (other.RespSize != 0) {
+        RespSize = other.RespSize;
+      }
+    }
+
+    public void MergeFrom(pb::CodedInputStream input) {
+      uint tag;
+      while ((tag = input.ReadTag()) != 0) {
+        switch(tag) {
+          default:
+            input.SkipLastField();
+            break;
+          case 8: {
+            ReqSize = input.ReadInt32();
+            break;
+          }
+          case 16: {
+            RespSize = input.ReadInt32();
+            break;
+          }
+        }
+      }
+    }
+
+  }
+
+  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+  public sealed partial class SimpleProtoParams : pb::IMessage<SimpleProtoParams> {
+    private static readonly pb::MessageParser<SimpleProtoParams> _parser = new pb::MessageParser<SimpleProtoParams>(() => new SimpleProtoParams());
+    public static pb::MessageParser<SimpleProtoParams> Parser { get { return _parser; } }
+
+    public static pbr::MessageDescriptor Descriptor {
+      get { return global::Grpc.Testing.Payloads.Descriptor.MessageTypes[1]; }
+    }
+
+    pbr::MessageDescriptor pb::IMessage.Descriptor {
+      get { return Descriptor; }
+    }
+
+    public SimpleProtoParams() {
+      OnConstruction();
+    }
+
+    partial void OnConstruction();
+
+    public SimpleProtoParams(SimpleProtoParams other) : this() {
+      reqSize_ = other.reqSize_;
+      respSize_ = other.respSize_;
+    }
+
+    public SimpleProtoParams Clone() {
+      return new SimpleProtoParams(this);
+    }
+
+    public const int ReqSizeFieldNumber = 1;
+    private int reqSize_;
+    public int ReqSize {
+      get { return reqSize_; }
+      set {
+        reqSize_ = value;
+      }
+    }
+
+    public const int RespSizeFieldNumber = 2;
+    private int respSize_;
+    public int RespSize {
+      get { return respSize_; }
+      set {
+        respSize_ = value;
+      }
+    }
+
+    public override bool Equals(object other) {
+      return Equals(other as SimpleProtoParams);
+    }
+
+    public bool Equals(SimpleProtoParams other) {
+      if (ReferenceEquals(other, null)) {
+        return false;
+      }
+      if (ReferenceEquals(other, this)) {
+        return true;
+      }
+      if (ReqSize != other.ReqSize) return false;
+      if (RespSize != other.RespSize) return false;
+      return true;
+    }
+
+    public override int GetHashCode() {
+      int hash = 1;
+      if (ReqSize != 0) hash ^= ReqSize.GetHashCode();
+      if (RespSize != 0) hash ^= RespSize.GetHashCode();
+      return hash;
+    }
+
+    public override string ToString() {
+      return pb::JsonFormatter.Default.Format(this);
+    }
+
+    public void WriteTo(pb::CodedOutputStream output) {
+      if (ReqSize != 0) {
+        output.WriteRawTag(8);
+        output.WriteInt32(ReqSize);
+      }
+      if (RespSize != 0) {
+        output.WriteRawTag(16);
+        output.WriteInt32(RespSize);
+      }
+    }
+
+    public int CalculateSize() {
+      int size = 0;
+      if (ReqSize != 0) {
+        size += 1 + pb::CodedOutputStream.ComputeInt32Size(ReqSize);
+      }
+      if (RespSize != 0) {
+        size += 1 + pb::CodedOutputStream.ComputeInt32Size(RespSize);
+      }
+      return size;
+    }
+
+    public void MergeFrom(SimpleProtoParams other) {
+      if (other == null) {
+        return;
+      }
+      if (other.ReqSize != 0) {
+        ReqSize = other.ReqSize;
+      }
+      if (other.RespSize != 0) {
+        RespSize = other.RespSize;
+      }
+    }
+
+    public void MergeFrom(pb::CodedInputStream input) {
+      uint tag;
+      while ((tag = input.ReadTag()) != 0) {
+        switch(tag) {
+          default:
+            input.SkipLastField();
+            break;
+          case 8: {
+            ReqSize = input.ReadInt32();
+            break;
+          }
+          case 16: {
+            RespSize = input.ReadInt32();
+            break;
+          }
+        }
+      }
+    }
+
+  }
+
+  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+  public sealed partial class ComplexProtoParams : pb::IMessage<ComplexProtoParams> {
+    private static readonly pb::MessageParser<ComplexProtoParams> _parser = new pb::MessageParser<ComplexProtoParams>(() => new ComplexProtoParams());
+    public static pb::MessageParser<ComplexProtoParams> Parser { get { return _parser; } }
+
+    public static pbr::MessageDescriptor Descriptor {
+      get { return global::Grpc.Testing.Payloads.Descriptor.MessageTypes[2]; }
+    }
+
+    pbr::MessageDescriptor pb::IMessage.Descriptor {
+      get { return Descriptor; }
+    }
+
+    public ComplexProtoParams() {
+      OnConstruction();
+    }
+
+    partial void OnConstruction();
+
+    public ComplexProtoParams(ComplexProtoParams other) : this() {
+    }
+
+    public ComplexProtoParams Clone() {
+      return new ComplexProtoParams(this);
+    }
+
+    public override bool Equals(object other) {
+      return Equals(other as ComplexProtoParams);
+    }
+
+    public bool Equals(ComplexProtoParams other) {
+      if (ReferenceEquals(other, null)) {
+        return false;
+      }
+      if (ReferenceEquals(other, this)) {
+        return true;
+      }
+      return true;
+    }
+
+    public override int GetHashCode() {
+      int hash = 1;
+      return hash;
+    }
+
+    public override string ToString() {
+      return pb::JsonFormatter.Default.Format(this);
+    }
+
+    public void WriteTo(pb::CodedOutputStream output) {
+    }
+
+    public int CalculateSize() {
+      int size = 0;
+      return size;
+    }
+
+    public void MergeFrom(ComplexProtoParams other) {
+      if (other == null) {
+        return;
+      }
+    }
+
+    public void MergeFrom(pb::CodedInputStream input) {
+      uint tag;
+      while ((tag = input.ReadTag()) != 0) {
+        switch(tag) {
+          default:
+            input.SkipLastField();
+            break;
+        }
+      }
+    }
+
+  }
+
+  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+  public sealed partial class PayloadConfig : pb::IMessage<PayloadConfig> {
+    private static readonly pb::MessageParser<PayloadConfig> _parser = new pb::MessageParser<PayloadConfig>(() => new PayloadConfig());
+    public static pb::MessageParser<PayloadConfig> Parser { get { return _parser; } }
+
+    public static pbr::MessageDescriptor Descriptor {
+      get { return global::Grpc.Testing.Payloads.Descriptor.MessageTypes[3]; }
+    }
+
+    pbr::MessageDescriptor pb::IMessage.Descriptor {
+      get { return Descriptor; }
+    }
+
+    public PayloadConfig() {
+      OnConstruction();
+    }
+
+    partial void OnConstruction();
+
+    public PayloadConfig(PayloadConfig other) : this() {
+      switch (other.PayloadCase) {
+        case PayloadOneofCase.BytebufParams:
+          BytebufParams = other.BytebufParams.Clone();
+          break;
+        case PayloadOneofCase.SimpleParams:
+          SimpleParams = other.SimpleParams.Clone();
+          break;
+        case PayloadOneofCase.ComplexParams:
+          ComplexParams = other.ComplexParams.Clone();
+          break;
+      }
+
+    }
+
+    public PayloadConfig Clone() {
+      return new PayloadConfig(this);
+    }
+
+    public const int BytebufParamsFieldNumber = 1;
+    public global::Grpc.Testing.ByteBufferParams BytebufParams {
+      get { return payloadCase_ == PayloadOneofCase.BytebufParams ? (global::Grpc.Testing.ByteBufferParams) payload_ : null; }
+      set {
+        payload_ = value;
+        payloadCase_ = value == null ? PayloadOneofCase.None : PayloadOneofCase.BytebufParams;
+      }
+    }
+
+    public const int SimpleParamsFieldNumber = 2;
+    public global::Grpc.Testing.SimpleProtoParams SimpleParams {
+      get { return payloadCase_ == PayloadOneofCase.SimpleParams ? (global::Grpc.Testing.SimpleProtoParams) payload_ : null; }
+      set {
+        payload_ = value;
+        payloadCase_ = value == null ? PayloadOneofCase.None : PayloadOneofCase.SimpleParams;
+      }
+    }
+
+    public const int ComplexParamsFieldNumber = 3;
+    public global::Grpc.Testing.ComplexProtoParams ComplexParams {
+      get { return payloadCase_ == PayloadOneofCase.ComplexParams ? (global::Grpc.Testing.ComplexProtoParams) payload_ : null; }
+      set {
+        payload_ = value;
+        payloadCase_ = value == null ? PayloadOneofCase.None : PayloadOneofCase.ComplexParams;
+      }
+    }
+
+    private object payload_;
+    public enum PayloadOneofCase {
+      None = 0,
+      BytebufParams = 1,
+      SimpleParams = 2,
+      ComplexParams = 3,
+    }
+    private PayloadOneofCase payloadCase_ = PayloadOneofCase.None;
+    public PayloadOneofCase PayloadCase {
+      get { return payloadCase_; }
+    }
+
+    public void ClearPayload() {
+      payloadCase_ = PayloadOneofCase.None;
+      payload_ = null;
+    }
+
+    public override bool Equals(object other) {
+      return Equals(other as PayloadConfig);
+    }
+
+    public bool Equals(PayloadConfig other) {
+      if (ReferenceEquals(other, null)) {
+        return false;
+      }
+      if (ReferenceEquals(other, this)) {
+        return true;
+      }
+      if (!object.Equals(BytebufParams, other.BytebufParams)) return false;
+      if (!object.Equals(SimpleParams, other.SimpleParams)) return false;
+      if (!object.Equals(ComplexParams, other.ComplexParams)) return false;
+      return true;
+    }
+
+    public override int GetHashCode() {
+      int hash = 1;
+      if (payloadCase_ == PayloadOneofCase.BytebufParams) hash ^= BytebufParams.GetHashCode();
+      if (payloadCase_ == PayloadOneofCase.SimpleParams) hash ^= SimpleParams.GetHashCode();
+      if (payloadCase_ == PayloadOneofCase.ComplexParams) hash ^= ComplexParams.GetHashCode();
+      return hash;
+    }
+
+    public override string ToString() {
+      return pb::JsonFormatter.Default.Format(this);
+    }
+
+    public void WriteTo(pb::CodedOutputStream output) {
+      if (payloadCase_ == PayloadOneofCase.BytebufParams) {
+        output.WriteRawTag(10);
+        output.WriteMessage(BytebufParams);
+      }
+      if (payloadCase_ == PayloadOneofCase.SimpleParams) {
+        output.WriteRawTag(18);
+        output.WriteMessage(SimpleParams);
+      }
+      if (payloadCase_ == PayloadOneofCase.ComplexParams) {
+        output.WriteRawTag(26);
+        output.WriteMessage(ComplexParams);
+      }
+    }
+
+    public int CalculateSize() {
+      int size = 0;
+      if (payloadCase_ == PayloadOneofCase.BytebufParams) {
+        size += 1 + pb::CodedOutputStream.ComputeMessageSize(BytebufParams);
+      }
+      if (payloadCase_ == PayloadOneofCase.SimpleParams) {
+        size += 1 + pb::CodedOutputStream.ComputeMessageSize(SimpleParams);
+      }
+      if (payloadCase_ == PayloadOneofCase.ComplexParams) {
+        size += 1 + pb::CodedOutputStream.ComputeMessageSize(ComplexParams);
+      }
+      return size;
+    }
+
+    public void MergeFrom(PayloadConfig other) {
+      if (other == null) {
+        return;
+      }
+      switch (other.PayloadCase) {
+        case PayloadOneofCase.BytebufParams:
+          BytebufParams = other.BytebufParams;
+          break;
+        case PayloadOneofCase.SimpleParams:
+          SimpleParams = other.SimpleParams;
+          break;
+        case PayloadOneofCase.ComplexParams:
+          ComplexParams = other.ComplexParams;
+          break;
+      }
+
+    }
+
+    public void MergeFrom(pb::CodedInputStream input) {
+      uint tag;
+      while ((tag = input.ReadTag()) != 0) {
+        switch(tag) {
+          default:
+            input.SkipLastField();
+            break;
+          case 10: {
+            global::Grpc.Testing.ByteBufferParams subBuilder = new global::Grpc.Testing.ByteBufferParams();
+            if (payloadCase_ == PayloadOneofCase.BytebufParams) {
+              subBuilder.MergeFrom(BytebufParams);
+            }
+            input.ReadMessage(subBuilder);
+            BytebufParams = subBuilder;
+            break;
+          }
+          case 18: {
+            global::Grpc.Testing.SimpleProtoParams subBuilder = new global::Grpc.Testing.SimpleProtoParams();
+            if (payloadCase_ == PayloadOneofCase.SimpleParams) {
+              subBuilder.MergeFrom(SimpleParams);
+            }
+            input.ReadMessage(subBuilder);
+            SimpleParams = subBuilder;
+            break;
+          }
+          case 26: {
+            global::Grpc.Testing.ComplexProtoParams subBuilder = new global::Grpc.Testing.ComplexProtoParams();
+            if (payloadCase_ == PayloadOneofCase.ComplexParams) {
+              subBuilder.MergeFrom(ComplexParams);
+            }
+            input.ReadMessage(subBuilder);
+            ComplexParams = subBuilder;
+            break;
+          }
+        }
+      }
+    }
+
+  }
+
+  #endregion
+
+}
+
+#endregion Designer generated code
diff --git a/src/csharp/Grpc.IntegrationTesting/QpsWorker.cs b/src/csharp/Grpc.IntegrationTesting/QpsWorker.cs
new file mode 100644
index 0000000..686b484
--- /dev/null
+++ b/src/csharp/Grpc.IntegrationTesting/QpsWorker.cs
@@ -0,0 +1,108 @@
+#region Copyright notice and license
+
+// Copyright 2015, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.Linq;
+using System.Text.RegularExpressions;
+using System.Threading.Tasks;
+
+using CommandLine;
+using CommandLine.Text;
+using Grpc.Core;
+using Grpc.Core.Utils;
+using Grpc.Testing;
+using NUnit.Framework;
+
+namespace Grpc.IntegrationTesting
+{
+    public class QpsWorker
+    {
+        private class ServerOptions
+        {
+            [Option("driver_port", DefaultValue = 0)]
+            public int DriverPort { get; set; }
+
+            [HelpOption]
+            public string GetUsage()
+            {
+                var help = new HelpText
+                {
+                    Heading = "gRPC C# performance testing worker",
+                    AddDashesToOption = true
+                };
+                help.AddPreOptionsLine("Usage:");
+                help.AddOptions(this);
+                return help;
+            }
+        }
+
+        ServerOptions options;
+
+        private QpsWorker(ServerOptions options)
+        {
+            this.options = options;
+        }
+
+        public static void Run(string[] args)
+        {
+            var options = new ServerOptions();
+            if (!Parser.Default.ParseArguments(args, options))
+            {
+                Environment.Exit(1);
+            }
+
+            var workerServer = new QpsWorker(options);
+            workerServer.Run();
+        }
+
+        private void Run()
+        {
+            string host = "0.0.0.0";
+            int port = options.DriverPort;
+
+            var server = new Server
+            {
+                Services = { WorkerService.BindService(new WorkerServiceImpl()) },
+                Ports = { new ServerPort(host, options.DriverPort, ServerCredentials.Insecure )}
+            };
+            int boundPort = server.Ports.Single().BoundPort;
+            Console.WriteLine("Running qps worker server on " + string.Format("{0}:{1}", host, boundPort));
+            server.Start();
+
+            server.ShutdownTask.Wait();
+        }
+    }
+}
diff --git a/src/csharp/Grpc.IntegrationTesting/RunnerClientServerTest.cs b/src/csharp/Grpc.IntegrationTesting/RunnerClientServerTest.cs
new file mode 100644
index 0000000..2b51526
--- /dev/null
+++ b/src/csharp/Grpc.IntegrationTesting/RunnerClientServerTest.cs
@@ -0,0 +1,117 @@
+#region Copyright notice and license
+
+// Copyright 2015, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+using Grpc.Core;
+using Grpc.Core.Utils;
+using Grpc.Testing;
+using NUnit.Framework;
+
+namespace Grpc.IntegrationTesting
+{
+    /// <summary>
+    /// Runs performance tests in-process.
+    /// </summary>
+    public class RunnerClientServerTest
+    {
+        const string Host = "localhost";
+        IServerRunner serverRunner;
+
+        [TestFixtureSetUp]
+        public void Init()
+        {
+            var serverConfig = new ServerConfig
+            {
+                ServerType = ServerType.ASYNC_SERVER,
+                Host = Host,
+                PayloadConfig = new PayloadConfig
+                {
+                    SimpleParams = new SimpleProtoParams
+                    {
+                        RespSize = 100
+                    }
+                }
+            };
+            serverRunner = ServerRunners.CreateStarted(serverConfig);
+        }
+
+        [TestFixtureTearDown]
+        public void Cleanup()
+        {
+            serverRunner.StopAsync().Wait();
+        }
+
+        // Test attribute commented out to prevent running as part of the default test suite.
+        //[Test]
+        //[Category("Performance")]
+        public async Task ClientServerRunner()
+        {
+            var config = new ClientConfig
+            {
+                ServerTargets = { string.Format("{0}:{1}", Host, serverRunner.BoundPort) },
+                RpcType = RpcType.UNARY,
+                LoadParams = new LoadParams { ClosedLoop = new ClosedLoopParams() },
+                PayloadConfig = new PayloadConfig
+                {
+                    SimpleParams = new SimpleProtoParams
+                    {
+                        ReqSize = 100
+                    }
+                },
+                HistogramParams = new HistogramParams
+                {
+                    Resolution = 0.01,
+                    MaxPossible = 60e9
+                }
+            };
+
+            var runner = ClientRunners.CreateStarted(config);
+
+            System.Console.WriteLine("Warming up");
+            await Task.Delay(3000);
+            runner.GetStats(true);  // throw away warm-up data
+
+            System.Console.WriteLine("Benchmarking");
+            await Task.Delay(3000);
+            var stats = runner.GetStats(true);
+            await runner.StopAsync();
+
+            System.Console.WriteLine(stats);
+            System.Console.WriteLine("avg micros/call " + (long) (stats.Latencies.Sum / stats.Latencies.Count / 1000.0));
+        }
+    }
+}
diff --git a/src/csharp/Grpc.IntegrationTesting/ServerRunners.cs b/src/csharp/Grpc.IntegrationTesting/ServerRunners.cs
new file mode 100644
index 0000000..e8be775
--- /dev/null
+++ b/src/csharp/Grpc.IntegrationTesting/ServerRunners.cs
@@ -0,0 +1,124 @@
+#region Copyright notice and license
+
+// Copyright 2015, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.Linq;
+using System.Text.RegularExpressions;
+using System.Threading;
+using System.Threading.Tasks;
+using Google.Protobuf;
+using Grpc.Core;
+using Grpc.Core.Utils;
+using NUnit.Framework;
+using Grpc.Testing;
+
+namespace Grpc.IntegrationTesting
+{
+    /// <summary>
+    /// Helper methods to start server runners for performance testing.
+    /// </summary>
+    public static class ServerRunners
+    {
+        /// <summary>
+        /// Creates a started server runner.
+        /// </summary>
+        public static IServerRunner CreateStarted(ServerConfig config)
+        {
+            Grpc.Core.Utils.Preconditions.CheckArgument(config.ServerType == ServerType.ASYNC_SERVER);
+            var credentials = config.SecurityParams != null ? TestCredentials.CreateSslServerCredentials() : ServerCredentials.Insecure;
+
+            // TODO: qps_driver needs to setup payload properly...
+            int responseSize = config.PayloadConfig != null ? config.PayloadConfig.SimpleParams.RespSize : 0;
+            var server = new Server
+            {
+                Services = { BenchmarkService.BindService(new BenchmarkServiceImpl(responseSize)) },
+                Ports = { new ServerPort(config.Host, config.Port, credentials) }
+            };
+
+            server.Start();
+            return new ServerRunnerImpl(server);
+        }
+    }
+
+    /// <summary>
+    /// Server runner.
+    /// </summary>
+    public class ServerRunnerImpl : IServerRunner
+    {
+        readonly Server server;
+        readonly WallClockStopwatch wallClockStopwatch = new WallClockStopwatch();
+
+        public ServerRunnerImpl(Server server)
+        {
+            this.server = Grpc.Core.Utils.Preconditions.CheckNotNull(server);
+        }
+
+        public int BoundPort
+        {
+            get
+            {
+                return server.Ports.Single().BoundPort;
+            }
+        }
+
+        /// <summary>
+        /// Gets server stats.
+        /// </summary>
+        /// <returns>The stats.</returns>
+        public ServerStats GetStats(bool reset)
+        {
+            var secondsElapsed = wallClockStopwatch.GetElapsedSnapshot(reset).TotalSeconds;
+
+            // TODO: populate user time and system time
+            return new ServerStats
+            {
+                TimeElapsed = secondsElapsed,
+                TimeUser = 0,
+                TimeSystem = 0
+            };
+        }
+
+        /// <summary>
+        /// Asynchronously stops the server.
+        /// </summary>
+        /// <returns>Task that finishes when server has shutdown.</returns>
+        public Task StopAsync()
+        {
+            return server.ShutdownAsync();
+        }
+    }
+        
+}
diff --git a/src/csharp/Grpc.IntegrationTesting/Services.cs b/src/csharp/Grpc.IntegrationTesting/Services.cs
new file mode 100644
index 0000000..b648da6
--- /dev/null
+++ b/src/csharp/Grpc.IntegrationTesting/Services.cs
@@ -0,0 +1,44 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: test/proto/benchmarks/services.proto
+#pragma warning disable 1591, 0612, 3021
+#region Designer generated code
+
+using pb = global::Google.Protobuf;
+using pbc = global::Google.Protobuf.Collections;
+using pbr = global::Google.Protobuf.Reflection;
+using scg = global::System.Collections.Generic;
+namespace Grpc.Testing {
+
+  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+  public static partial class Services {
+
+    #region Descriptor
+    public static pbr::FileDescriptor Descriptor {
+      get { return descriptor; }
+    }
+    private static pbr::FileDescriptor descriptor;
+
+    static Services() {
+      byte[] descriptorData = global::System.Convert.FromBase64String(
+          string.Concat(
+            "CiR0ZXN0L3Byb3RvL2JlbmNobWFya3Mvc2VydmljZXMucHJvdG8SDGdycGMu", 
+            "dGVzdGluZxoZdGVzdC9wcm90by9tZXNzYWdlcy5wcm90bxojdGVzdC9wcm90", 
+            "by9iZW5jaG1hcmtzL2NvbnRyb2wucHJvdG8yqgEKEEJlbmNobWFya1NlcnZp", 
+            "Y2USRgoJVW5hcnlDYWxsEhsuZ3JwYy50ZXN0aW5nLlNpbXBsZVJlcXVlc3Qa", 
+            "HC5ncnBjLnRlc3RpbmcuU2ltcGxlUmVzcG9uc2USTgoNU3RyZWFtaW5nQ2Fs", 
+            "bBIbLmdycGMudGVzdGluZy5TaW1wbGVSZXF1ZXN0GhwuZ3JwYy50ZXN0aW5n", 
+            "LlNpbXBsZVJlc3BvbnNlKAEwATKdAQoNV29ya2VyU2VydmljZRJFCglSdW5T", 
+            "ZXJ2ZXISGC5ncnBjLnRlc3RpbmcuU2VydmVyQXJncxoaLmdycGMudGVzdGlu", 
+            "Zy5TZXJ2ZXJTdGF0dXMoATABEkUKCVJ1bkNsaWVudBIYLmdycGMudGVzdGlu", 
+            "Zy5DbGllbnRBcmdzGhouZ3JwYy50ZXN0aW5nLkNsaWVudFN0YXR1cygBMAFi", 
+            "BnByb3RvMw=="));
+      descriptor = pbr::FileDescriptor.InternalBuildGeneratedFileFrom(descriptorData,
+          new pbr::FileDescriptor[] { global::Grpc.Testing.Messages.Descriptor, global::Grpc.Testing.Control.Descriptor, },
+          new pbr::GeneratedCodeInfo(null, null));
+    }
+    #endregion
+
+  }
+}
+
+#endregion Designer generated code
diff --git a/src/csharp/Grpc.IntegrationTesting/ServicesGrpc.cs b/src/csharp/Grpc.IntegrationTesting/ServicesGrpc.cs
new file mode 100644
index 0000000..ce388c6
--- /dev/null
+++ b/src/csharp/Grpc.IntegrationTesting/ServicesGrpc.cs
@@ -0,0 +1,198 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: test/proto/benchmarks/services.proto
+#region Designer generated code
+
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+using Grpc.Core;
+
+namespace Grpc.Testing {
+  public static class BenchmarkService
+  {
+    static readonly string __ServiceName = "grpc.testing.BenchmarkService";
+
+    static readonly Marshaller<global::Grpc.Testing.SimpleRequest> __Marshaller_SimpleRequest = Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.SimpleRequest.Parser.ParseFrom);
+    static readonly Marshaller<global::Grpc.Testing.SimpleResponse> __Marshaller_SimpleResponse = Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.SimpleResponse.Parser.ParseFrom);
+
+    static readonly Method<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse> __Method_UnaryCall = new Method<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse>(
+        MethodType.Unary,
+        __ServiceName,
+        "UnaryCall",
+        __Marshaller_SimpleRequest,
+        __Marshaller_SimpleResponse);
+
+    static readonly Method<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse> __Method_StreamingCall = new Method<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse>(
+        MethodType.DuplexStreaming,
+        __ServiceName,
+        "StreamingCall",
+        __Marshaller_SimpleRequest,
+        __Marshaller_SimpleResponse);
+
+    // service descriptor
+    public static global::Google.Protobuf.Reflection.ServiceDescriptor Descriptor
+    {
+      get { return global::Grpc.Testing.Services.Descriptor.Services[0]; }
+    }
+
+    // client interface
+    public interface IBenchmarkServiceClient
+    {
+      global::Grpc.Testing.SimpleResponse UnaryCall(global::Grpc.Testing.SimpleRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
+      global::Grpc.Testing.SimpleResponse UnaryCall(global::Grpc.Testing.SimpleRequest request, CallOptions options);
+      AsyncUnaryCall<global::Grpc.Testing.SimpleResponse> UnaryCallAsync(global::Grpc.Testing.SimpleRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
+      AsyncUnaryCall<global::Grpc.Testing.SimpleResponse> UnaryCallAsync(global::Grpc.Testing.SimpleRequest request, CallOptions options);
+      AsyncDuplexStreamingCall<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse> StreamingCall(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
+      AsyncDuplexStreamingCall<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse> StreamingCall(CallOptions options);
+    }
+
+    // server-side interface
+    public interface IBenchmarkService
+    {
+      Task<global::Grpc.Testing.SimpleResponse> UnaryCall(global::Grpc.Testing.SimpleRequest request, ServerCallContext context);
+      Task StreamingCall(IAsyncStreamReader<global::Grpc.Testing.SimpleRequest> requestStream, IServerStreamWriter<global::Grpc.Testing.SimpleResponse> responseStream, ServerCallContext context);
+    }
+
+    // client stub
+    public class BenchmarkServiceClient : ClientBase, IBenchmarkServiceClient
+    {
+      public BenchmarkServiceClient(Channel channel) : base(channel)
+      {
+      }
+      public global::Grpc.Testing.SimpleResponse UnaryCall(global::Grpc.Testing.SimpleRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      {
+        var call = CreateCall(__Method_UnaryCall, new CallOptions(headers, deadline, cancellationToken));
+        return Calls.BlockingUnaryCall(call, request);
+      }
+      public global::Grpc.Testing.SimpleResponse UnaryCall(global::Grpc.Testing.SimpleRequest request, CallOptions options)
+      {
+        var call = CreateCall(__Method_UnaryCall, options);
+        return Calls.BlockingUnaryCall(call, request);
+      }
+      public AsyncUnaryCall<global::Grpc.Testing.SimpleResponse> UnaryCallAsync(global::Grpc.Testing.SimpleRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      {
+        var call = CreateCall(__Method_UnaryCall, new CallOptions(headers, deadline, cancellationToken));
+        return Calls.AsyncUnaryCall(call, request);
+      }
+      public AsyncUnaryCall<global::Grpc.Testing.SimpleResponse> UnaryCallAsync(global::Grpc.Testing.SimpleRequest request, CallOptions options)
+      {
+        var call = CreateCall(__Method_UnaryCall, options);
+        return Calls.AsyncUnaryCall(call, request);
+      }
+      public AsyncDuplexStreamingCall<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse> StreamingCall(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      {
+        var call = CreateCall(__Method_StreamingCall, new CallOptions(headers, deadline, cancellationToken));
+        return Calls.AsyncDuplexStreamingCall(call);
+      }
+      public AsyncDuplexStreamingCall<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse> StreamingCall(CallOptions options)
+      {
+        var call = CreateCall(__Method_StreamingCall, options);
+        return Calls.AsyncDuplexStreamingCall(call);
+      }
+    }
+
+    // creates service definition that can be registered with a server
+    public static ServerServiceDefinition BindService(IBenchmarkService serviceImpl)
+    {
+      return ServerServiceDefinition.CreateBuilder(__ServiceName)
+          .AddMethod(__Method_UnaryCall, serviceImpl.UnaryCall)
+          .AddMethod(__Method_StreamingCall, serviceImpl.StreamingCall).Build();
+    }
+
+    // creates a new client
+    public static BenchmarkServiceClient NewClient(Channel channel)
+    {
+      return new BenchmarkServiceClient(channel);
+    }
+
+  }
+  public static class WorkerService
+  {
+    static readonly string __ServiceName = "grpc.testing.WorkerService";
+
+    static readonly Marshaller<global::Grpc.Testing.ServerArgs> __Marshaller_ServerArgs = Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.ServerArgs.Parser.ParseFrom);
+    static readonly Marshaller<global::Grpc.Testing.ServerStatus> __Marshaller_ServerStatus = Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.ServerStatus.Parser.ParseFrom);
+    static readonly Marshaller<global::Grpc.Testing.ClientArgs> __Marshaller_ClientArgs = Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.ClientArgs.Parser.ParseFrom);
+    static readonly Marshaller<global::Grpc.Testing.ClientStatus> __Marshaller_ClientStatus = Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Grpc.Testing.ClientStatus.Parser.ParseFrom);
+
+    static readonly Method<global::Grpc.Testing.ServerArgs, global::Grpc.Testing.ServerStatus> __Method_RunServer = new Method<global::Grpc.Testing.ServerArgs, global::Grpc.Testing.ServerStatus>(
+        MethodType.DuplexStreaming,
+        __ServiceName,
+        "RunServer",
+        __Marshaller_ServerArgs,
+        __Marshaller_ServerStatus);
+
+    static readonly Method<global::Grpc.Testing.ClientArgs, global::Grpc.Testing.ClientStatus> __Method_RunClient = new Method<global::Grpc.Testing.ClientArgs, global::Grpc.Testing.ClientStatus>(
+        MethodType.DuplexStreaming,
+        __ServiceName,
+        "RunClient",
+        __Marshaller_ClientArgs,
+        __Marshaller_ClientStatus);
+
+    // service descriptor
+    public static global::Google.Protobuf.Reflection.ServiceDescriptor Descriptor
+    {
+      get { return global::Grpc.Testing.Services.Descriptor.Services[1]; }
+    }
+
+    // client interface
+    public interface IWorkerServiceClient
+    {
+      AsyncDuplexStreamingCall<global::Grpc.Testing.ServerArgs, global::Grpc.Testing.ServerStatus> RunServer(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
+      AsyncDuplexStreamingCall<global::Grpc.Testing.ServerArgs, global::Grpc.Testing.ServerStatus> RunServer(CallOptions options);
+      AsyncDuplexStreamingCall<global::Grpc.Testing.ClientArgs, global::Grpc.Testing.ClientStatus> RunClient(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
+      AsyncDuplexStreamingCall<global::Grpc.Testing.ClientArgs, global::Grpc.Testing.ClientStatus> RunClient(CallOptions options);
+    }
+
+    // server-side interface
+    public interface IWorkerService
+    {
+      Task RunServer(IAsyncStreamReader<global::Grpc.Testing.ServerArgs> requestStream, IServerStreamWriter<global::Grpc.Testing.ServerStatus> responseStream, ServerCallContext context);
+      Task RunClient(IAsyncStreamReader<global::Grpc.Testing.ClientArgs> requestStream, IServerStreamWriter<global::Grpc.Testing.ClientStatus> responseStream, ServerCallContext context);
+    }
+
+    // client stub
+    public class WorkerServiceClient : ClientBase, IWorkerServiceClient
+    {
+      public WorkerServiceClient(Channel channel) : base(channel)
+      {
+      }
+      public AsyncDuplexStreamingCall<global::Grpc.Testing.ServerArgs, global::Grpc.Testing.ServerStatus> RunServer(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      {
+        var call = CreateCall(__Method_RunServer, new CallOptions(headers, deadline, cancellationToken));
+        return Calls.AsyncDuplexStreamingCall(call);
+      }
+      public AsyncDuplexStreamingCall<global::Grpc.Testing.ServerArgs, global::Grpc.Testing.ServerStatus> RunServer(CallOptions options)
+      {
+        var call = CreateCall(__Method_RunServer, options);
+        return Calls.AsyncDuplexStreamingCall(call);
+      }
+      public AsyncDuplexStreamingCall<global::Grpc.Testing.ClientArgs, global::Grpc.Testing.ClientStatus> RunClient(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      {
+        var call = CreateCall(__Method_RunClient, new CallOptions(headers, deadline, cancellationToken));
+        return Calls.AsyncDuplexStreamingCall(call);
+      }
+      public AsyncDuplexStreamingCall<global::Grpc.Testing.ClientArgs, global::Grpc.Testing.ClientStatus> RunClient(CallOptions options)
+      {
+        var call = CreateCall(__Method_RunClient, options);
+        return Calls.AsyncDuplexStreamingCall(call);
+      }
+    }
+
+    // creates service definition that can be registered with a server
+    public static ServerServiceDefinition BindService(IWorkerService serviceImpl)
+    {
+      return ServerServiceDefinition.CreateBuilder(__ServiceName)
+          .AddMethod(__Method_RunServer, serviceImpl.RunServer)
+          .AddMethod(__Method_RunClient, serviceImpl.RunClient).Build();
+    }
+
+    // creates a new client
+    public static WorkerServiceClient NewClient(Channel channel)
+    {
+      return new WorkerServiceClient(channel);
+    }
+
+  }
+}
+#endregion
diff --git a/src/csharp/Grpc.IntegrationTesting/Settings.StyleCop b/src/csharp/Grpc.IntegrationTesting/Settings.StyleCop
index fb99cd4..746f2ef 100644
--- a/src/csharp/Grpc.IntegrationTesting/Settings.StyleCop
+++ b/src/csharp/Grpc.IntegrationTesting/Settings.StyleCop
@@ -1,7 +1,10 @@
 <StyleCopSettings Version="105">
   <SourceFileList>
-    <SourceFile>Messages.cs</SourceFile>
     <SourceFile>Empty.cs</SourceFile>
+    <SourceFile>Control.cs</SourceFile>
+    <SourceFile>Messages.cs</SourceFile>
+    <SourceFile>Payloads.cs</SourceFile>
+    <SourceFile>Stats.cs</SourceFile>
     <Settings>
     <GlobalSettings>
       <BooleanProperty Name="RulesEnabledByDefault">False</BooleanProperty>
diff --git a/src/csharp/Grpc.IntegrationTesting/Stats.cs b/src/csharp/Grpc.IntegrationTesting/Stats.cs
new file mode 100644
index 0000000..4ae66ba
--- /dev/null
+++ b/src/csharp/Grpc.IntegrationTesting/Stats.cs
@@ -0,0 +1,744 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: test/proto/benchmarks/stats.proto
+#pragma warning disable 1591, 0612, 3021
+#region Designer generated code
+
+using pb = global::Google.Protobuf;
+using pbc = global::Google.Protobuf.Collections;
+using pbr = global::Google.Protobuf.Reflection;
+using scg = global::System.Collections.Generic;
+namespace Grpc.Testing {
+
+  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+  public static partial class Stats {
+
+    #region Descriptor
+    public static pbr::FileDescriptor Descriptor {
+      get { return descriptor; }
+    }
+    private static pbr::FileDescriptor descriptor;
+
+    static Stats() {
+      byte[] descriptorData = global::System.Convert.FromBase64String(
+          string.Concat(
+            "CiF0ZXN0L3Byb3RvL2JlbmNobWFya3Mvc3RhdHMucHJvdG8SDGdycGMudGVz", 
+            "dGluZyJLCgtTZXJ2ZXJTdGF0cxIUCgx0aW1lX2VsYXBzZWQYASABKAESEQoJ", 
+            "dGltZV91c2VyGAIgASgBEhMKC3RpbWVfc3lzdGVtGAMgASgBIjsKD0hpc3Rv", 
+            "Z3JhbVBhcmFtcxISCgpyZXNvbHV0aW9uGAEgASgBEhQKDG1heF9wb3NzaWJs", 
+            "ZRgCIAEoASJ3Cg1IaXN0b2dyYW1EYXRhEg4KBmJ1Y2tldBgBIAMoDRIQCght", 
+            "aW5fc2VlbhgCIAEoARIQCghtYXhfc2VlbhgDIAEoARILCgNzdW0YBCABKAES", 
+            "FgoOc3VtX29mX3NxdWFyZXMYBSABKAESDQoFY291bnQYBiABKAEiewoLQ2xp", 
+            "ZW50U3RhdHMSLgoJbGF0ZW5jaWVzGAEgASgLMhsuZ3JwYy50ZXN0aW5nLkhp", 
+            "c3RvZ3JhbURhdGESFAoMdGltZV9lbGFwc2VkGAIgASgBEhEKCXRpbWVfdXNl", 
+            "chgDIAEoARITCgt0aW1lX3N5c3RlbRgEIAEoAWIGcHJvdG8z"));
+      descriptor = pbr::FileDescriptor.InternalBuildGeneratedFileFrom(descriptorData,
+          new pbr::FileDescriptor[] { },
+          new pbr::GeneratedCodeInfo(null, new pbr::GeneratedCodeInfo[] {
+            new pbr::GeneratedCodeInfo(typeof(global::Grpc.Testing.ServerStats), new[]{ "TimeElapsed", "TimeUser", "TimeSystem" }, null, null, null),
+            new pbr::GeneratedCodeInfo(typeof(global::Grpc.Testing.HistogramParams), new[]{ "Resolution", "MaxPossible" }, null, null, null),
+            new pbr::GeneratedCodeInfo(typeof(global::Grpc.Testing.HistogramData), new[]{ "Bucket", "MinSeen", "MaxSeen", "Sum", "SumOfSquares", "Count" }, null, null, null),
+            new pbr::GeneratedCodeInfo(typeof(global::Grpc.Testing.ClientStats), new[]{ "Latencies", "TimeElapsed", "TimeUser", "TimeSystem" }, null, null, null)
+          }));
+    }
+    #endregion
+
+  }
+  #region Messages
+  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+  public sealed partial class ServerStats : pb::IMessage<ServerStats> {
+    private static readonly pb::MessageParser<ServerStats> _parser = new pb::MessageParser<ServerStats>(() => new ServerStats());
+    public static pb::MessageParser<ServerStats> Parser { get { return _parser; } }
+
+    public static pbr::MessageDescriptor Descriptor {
+      get { return global::Grpc.Testing.Stats.Descriptor.MessageTypes[0]; }
+    }
+
+    pbr::MessageDescriptor pb::IMessage.Descriptor {
+      get { return Descriptor; }
+    }
+
+    public ServerStats() {
+      OnConstruction();
+    }
+
+    partial void OnConstruction();
+
+    public ServerStats(ServerStats other) : this() {
+      timeElapsed_ = other.timeElapsed_;
+      timeUser_ = other.timeUser_;
+      timeSystem_ = other.timeSystem_;
+    }
+
+    public ServerStats Clone() {
+      return new ServerStats(this);
+    }
+
+    public const int TimeElapsedFieldNumber = 1;
+    private double timeElapsed_;
+    public double TimeElapsed {
+      get { return timeElapsed_; }
+      set {
+        timeElapsed_ = value;
+      }
+    }
+
+    public const int TimeUserFieldNumber = 2;
+    private double timeUser_;
+    public double TimeUser {
+      get { return timeUser_; }
+      set {
+        timeUser_ = value;
+      }
+    }
+
+    public const int TimeSystemFieldNumber = 3;
+    private double timeSystem_;
+    public double TimeSystem {
+      get { return timeSystem_; }
+      set {
+        timeSystem_ = value;
+      }
+    }
+
+    public override bool Equals(object other) {
+      return Equals(other as ServerStats);
+    }
+
+    public bool Equals(ServerStats other) {
+      if (ReferenceEquals(other, null)) {
+        return false;
+      }
+      if (ReferenceEquals(other, this)) {
+        return true;
+      }
+      if (TimeElapsed != other.TimeElapsed) return false;
+      if (TimeUser != other.TimeUser) return false;
+      if (TimeSystem != other.TimeSystem) return false;
+      return true;
+    }
+
+    public override int GetHashCode() {
+      int hash = 1;
+      if (TimeElapsed != 0D) hash ^= TimeElapsed.GetHashCode();
+      if (TimeUser != 0D) hash ^= TimeUser.GetHashCode();
+      if (TimeSystem != 0D) hash ^= TimeSystem.GetHashCode();
+      return hash;
+    }
+
+    public override string ToString() {
+      return pb::JsonFormatter.Default.Format(this);
+    }
+
+    public void WriteTo(pb::CodedOutputStream output) {
+      if (TimeElapsed != 0D) {
+        output.WriteRawTag(9);
+        output.WriteDouble(TimeElapsed);
+      }
+      if (TimeUser != 0D) {
+        output.WriteRawTag(17);
+        output.WriteDouble(TimeUser);
+      }
+      if (TimeSystem != 0D) {
+        output.WriteRawTag(25);
+        output.WriteDouble(TimeSystem);
+      }
+    }
+
+    public int CalculateSize() {
+      int size = 0;
+      if (TimeElapsed != 0D) {
+        size += 1 + 8;
+      }
+      if (TimeUser != 0D) {
+        size += 1 + 8;
+      }
+      if (TimeSystem != 0D) {
+        size += 1 + 8;
+      }
+      return size;
+    }
+
+    public void MergeFrom(ServerStats other) {
+      if (other == null) {
+        return;
+      }
+      if (other.TimeElapsed != 0D) {
+        TimeElapsed = other.TimeElapsed;
+      }
+      if (other.TimeUser != 0D) {
+        TimeUser = other.TimeUser;
+      }
+      if (other.TimeSystem != 0D) {
+        TimeSystem = other.TimeSystem;
+      }
+    }
+
+    public void MergeFrom(pb::CodedInputStream input) {
+      uint tag;
+      while ((tag = input.ReadTag()) != 0) {
+        switch(tag) {
+          default:
+            input.SkipLastField();
+            break;
+          case 9: {
+            TimeElapsed = input.ReadDouble();
+            break;
+          }
+          case 17: {
+            TimeUser = input.ReadDouble();
+            break;
+          }
+          case 25: {
+            TimeSystem = input.ReadDouble();
+            break;
+          }
+        }
+      }
+    }
+
+  }
+
+  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+  public sealed partial class HistogramParams : pb::IMessage<HistogramParams> {
+    private static readonly pb::MessageParser<HistogramParams> _parser = new pb::MessageParser<HistogramParams>(() => new HistogramParams());
+    public static pb::MessageParser<HistogramParams> Parser { get { return _parser; } }
+
+    public static pbr::MessageDescriptor Descriptor {
+      get { return global::Grpc.Testing.Stats.Descriptor.MessageTypes[1]; }
+    }
+
+    pbr::MessageDescriptor pb::IMessage.Descriptor {
+      get { return Descriptor; }
+    }
+
+    public HistogramParams() {
+      OnConstruction();
+    }
+
+    partial void OnConstruction();
+
+    public HistogramParams(HistogramParams other) : this() {
+      resolution_ = other.resolution_;
+      maxPossible_ = other.maxPossible_;
+    }
+
+    public HistogramParams Clone() {
+      return new HistogramParams(this);
+    }
+
+    public const int ResolutionFieldNumber = 1;
+    private double resolution_;
+    public double Resolution {
+      get { return resolution_; }
+      set {
+        resolution_ = value;
+      }
+    }
+
+    public const int MaxPossibleFieldNumber = 2;
+    private double maxPossible_;
+    public double MaxPossible {
+      get { return maxPossible_; }
+      set {
+        maxPossible_ = value;
+      }
+    }
+
+    public override bool Equals(object other) {
+      return Equals(other as HistogramParams);
+    }
+
+    public bool Equals(HistogramParams other) {
+      if (ReferenceEquals(other, null)) {
+        return false;
+      }
+      if (ReferenceEquals(other, this)) {
+        return true;
+      }
+      if (Resolution != other.Resolution) return false;
+      if (MaxPossible != other.MaxPossible) return false;
+      return true;
+    }
+
+    public override int GetHashCode() {
+      int hash = 1;
+      if (Resolution != 0D) hash ^= Resolution.GetHashCode();
+      if (MaxPossible != 0D) hash ^= MaxPossible.GetHashCode();
+      return hash;
+    }
+
+    public override string ToString() {
+      return pb::JsonFormatter.Default.Format(this);
+    }
+
+    public void WriteTo(pb::CodedOutputStream output) {
+      if (Resolution != 0D) {
+        output.WriteRawTag(9);
+        output.WriteDouble(Resolution);
+      }
+      if (MaxPossible != 0D) {
+        output.WriteRawTag(17);
+        output.WriteDouble(MaxPossible);
+      }
+    }
+
+    public int CalculateSize() {
+      int size = 0;
+      if (Resolution != 0D) {
+        size += 1 + 8;
+      }
+      if (MaxPossible != 0D) {
+        size += 1 + 8;
+      }
+      return size;
+    }
+
+    public void MergeFrom(HistogramParams other) {
+      if (other == null) {
+        return;
+      }
+      if (other.Resolution != 0D) {
+        Resolution = other.Resolution;
+      }
+      if (other.MaxPossible != 0D) {
+        MaxPossible = other.MaxPossible;
+      }
+    }
+
+    public void MergeFrom(pb::CodedInputStream input) {
+      uint tag;
+      while ((tag = input.ReadTag()) != 0) {
+        switch(tag) {
+          default:
+            input.SkipLastField();
+            break;
+          case 9: {
+            Resolution = input.ReadDouble();
+            break;
+          }
+          case 17: {
+            MaxPossible = input.ReadDouble();
+            break;
+          }
+        }
+      }
+    }
+
+  }
+
+  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+  public sealed partial class HistogramData : pb::IMessage<HistogramData> {
+    private static readonly pb::MessageParser<HistogramData> _parser = new pb::MessageParser<HistogramData>(() => new HistogramData());
+    public static pb::MessageParser<HistogramData> Parser { get { return _parser; } }
+
+    public static pbr::MessageDescriptor Descriptor {
+      get { return global::Grpc.Testing.Stats.Descriptor.MessageTypes[2]; }
+    }
+
+    pbr::MessageDescriptor pb::IMessage.Descriptor {
+      get { return Descriptor; }
+    }
+
+    public HistogramData() {
+      OnConstruction();
+    }
+
+    partial void OnConstruction();
+
+    public HistogramData(HistogramData other) : this() {
+      bucket_ = other.bucket_.Clone();
+      minSeen_ = other.minSeen_;
+      maxSeen_ = other.maxSeen_;
+      sum_ = other.sum_;
+      sumOfSquares_ = other.sumOfSquares_;
+      count_ = other.count_;
+    }
+
+    public HistogramData Clone() {
+      return new HistogramData(this);
+    }
+
+    public const int BucketFieldNumber = 1;
+    private static readonly pb::FieldCodec<uint> _repeated_bucket_codec
+        = pb::FieldCodec.ForUInt32(10);
+    private readonly pbc::RepeatedField<uint> bucket_ = new pbc::RepeatedField<uint>();
+    public pbc::RepeatedField<uint> Bucket {
+      get { return bucket_; }
+    }
+
+    public const int MinSeenFieldNumber = 2;
+    private double minSeen_;
+    public double MinSeen {
+      get { return minSeen_; }
+      set {
+        minSeen_ = value;
+      }
+    }
+
+    public const int MaxSeenFieldNumber = 3;
+    private double maxSeen_;
+    public double MaxSeen {
+      get { return maxSeen_; }
+      set {
+        maxSeen_ = value;
+      }
+    }
+
+    public const int SumFieldNumber = 4;
+    private double sum_;
+    public double Sum {
+      get { return sum_; }
+      set {
+        sum_ = value;
+      }
+    }
+
+    public const int SumOfSquaresFieldNumber = 5;
+    private double sumOfSquares_;
+    public double SumOfSquares {
+      get { return sumOfSquares_; }
+      set {
+        sumOfSquares_ = value;
+      }
+    }
+
+    public const int CountFieldNumber = 6;
+    private double count_;
+    public double Count {
+      get { return count_; }
+      set {
+        count_ = value;
+      }
+    }
+
+    public override bool Equals(object other) {
+      return Equals(other as HistogramData);
+    }
+
+    public bool Equals(HistogramData other) {
+      if (ReferenceEquals(other, null)) {
+        return false;
+      }
+      if (ReferenceEquals(other, this)) {
+        return true;
+      }
+      if(!bucket_.Equals(other.bucket_)) return false;
+      if (MinSeen != other.MinSeen) return false;
+      if (MaxSeen != other.MaxSeen) return false;
+      if (Sum != other.Sum) return false;
+      if (SumOfSquares != other.SumOfSquares) return false;
+      if (Count != other.Count) return false;
+      return true;
+    }
+
+    public override int GetHashCode() {
+      int hash = 1;
+      hash ^= bucket_.GetHashCode();
+      if (MinSeen != 0D) hash ^= MinSeen.GetHashCode();
+      if (MaxSeen != 0D) hash ^= MaxSeen.GetHashCode();
+      if (Sum != 0D) hash ^= Sum.GetHashCode();
+      if (SumOfSquares != 0D) hash ^= SumOfSquares.GetHashCode();
+      if (Count != 0D) hash ^= Count.GetHashCode();
+      return hash;
+    }
+
+    public override string ToString() {
+      return pb::JsonFormatter.Default.Format(this);
+    }
+
+    public void WriteTo(pb::CodedOutputStream output) {
+      bucket_.WriteTo(output, _repeated_bucket_codec);
+      if (MinSeen != 0D) {
+        output.WriteRawTag(17);
+        output.WriteDouble(MinSeen);
+      }
+      if (MaxSeen != 0D) {
+        output.WriteRawTag(25);
+        output.WriteDouble(MaxSeen);
+      }
+      if (Sum != 0D) {
+        output.WriteRawTag(33);
+        output.WriteDouble(Sum);
+      }
+      if (SumOfSquares != 0D) {
+        output.WriteRawTag(41);
+        output.WriteDouble(SumOfSquares);
+      }
+      if (Count != 0D) {
+        output.WriteRawTag(49);
+        output.WriteDouble(Count);
+      }
+    }
+
+    public int CalculateSize() {
+      int size = 0;
+      size += bucket_.CalculateSize(_repeated_bucket_codec);
+      if (MinSeen != 0D) {
+        size += 1 + 8;
+      }
+      if (MaxSeen != 0D) {
+        size += 1 + 8;
+      }
+      if (Sum != 0D) {
+        size += 1 + 8;
+      }
+      if (SumOfSquares != 0D) {
+        size += 1 + 8;
+      }
+      if (Count != 0D) {
+        size += 1 + 8;
+      }
+      return size;
+    }
+
+    public void MergeFrom(HistogramData other) {
+      if (other == null) {
+        return;
+      }
+      bucket_.Add(other.bucket_);
+      if (other.MinSeen != 0D) {
+        MinSeen = other.MinSeen;
+      }
+      if (other.MaxSeen != 0D) {
+        MaxSeen = other.MaxSeen;
+      }
+      if (other.Sum != 0D) {
+        Sum = other.Sum;
+      }
+      if (other.SumOfSquares != 0D) {
+        SumOfSquares = other.SumOfSquares;
+      }
+      if (other.Count != 0D) {
+        Count = other.Count;
+      }
+    }
+
+    public void MergeFrom(pb::CodedInputStream input) {
+      uint tag;
+      while ((tag = input.ReadTag()) != 0) {
+        switch(tag) {
+          default:
+            input.SkipLastField();
+            break;
+          case 10:
+          case 8: {
+            bucket_.AddEntriesFrom(input, _repeated_bucket_codec);
+            break;
+          }
+          case 17: {
+            MinSeen = input.ReadDouble();
+            break;
+          }
+          case 25: {
+            MaxSeen = input.ReadDouble();
+            break;
+          }
+          case 33: {
+            Sum = input.ReadDouble();
+            break;
+          }
+          case 41: {
+            SumOfSquares = input.ReadDouble();
+            break;
+          }
+          case 49: {
+            Count = input.ReadDouble();
+            break;
+          }
+        }
+      }
+    }
+
+  }
+
+  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+  public sealed partial class ClientStats : pb::IMessage<ClientStats> {
+    private static readonly pb::MessageParser<ClientStats> _parser = new pb::MessageParser<ClientStats>(() => new ClientStats());
+    public static pb::MessageParser<ClientStats> Parser { get { return _parser; } }
+
+    public static pbr::MessageDescriptor Descriptor {
+      get { return global::Grpc.Testing.Stats.Descriptor.MessageTypes[3]; }
+    }
+
+    pbr::MessageDescriptor pb::IMessage.Descriptor {
+      get { return Descriptor; }
+    }
+
+    public ClientStats() {
+      OnConstruction();
+    }
+
+    partial void OnConstruction();
+
+    public ClientStats(ClientStats other) : this() {
+      Latencies = other.latencies_ != null ? other.Latencies.Clone() : null;
+      timeElapsed_ = other.timeElapsed_;
+      timeUser_ = other.timeUser_;
+      timeSystem_ = other.timeSystem_;
+    }
+
+    public ClientStats Clone() {
+      return new ClientStats(this);
+    }
+
+    public const int LatenciesFieldNumber = 1;
+    private global::Grpc.Testing.HistogramData latencies_;
+    public global::Grpc.Testing.HistogramData Latencies {
+      get { return latencies_; }
+      set {
+        latencies_ = value;
+      }
+    }
+
+    public const int TimeElapsedFieldNumber = 2;
+    private double timeElapsed_;
+    public double TimeElapsed {
+      get { return timeElapsed_; }
+      set {
+        timeElapsed_ = value;
+      }
+    }
+
+    public const int TimeUserFieldNumber = 3;
+    private double timeUser_;
+    public double TimeUser {
+      get { return timeUser_; }
+      set {
+        timeUser_ = value;
+      }
+    }
+
+    public const int TimeSystemFieldNumber = 4;
+    private double timeSystem_;
+    public double TimeSystem {
+      get { return timeSystem_; }
+      set {
+        timeSystem_ = value;
+      }
+    }
+
+    public override bool Equals(object other) {
+      return Equals(other as ClientStats);
+    }
+
+    public bool Equals(ClientStats other) {
+      if (ReferenceEquals(other, null)) {
+        return false;
+      }
+      if (ReferenceEquals(other, this)) {
+        return true;
+      }
+      if (!object.Equals(Latencies, other.Latencies)) return false;
+      if (TimeElapsed != other.TimeElapsed) return false;
+      if (TimeUser != other.TimeUser) return false;
+      if (TimeSystem != other.TimeSystem) return false;
+      return true;
+    }
+
+    public override int GetHashCode() {
+      int hash = 1;
+      if (latencies_ != null) hash ^= Latencies.GetHashCode();
+      if (TimeElapsed != 0D) hash ^= TimeElapsed.GetHashCode();
+      if (TimeUser != 0D) hash ^= TimeUser.GetHashCode();
+      if (TimeSystem != 0D) hash ^= TimeSystem.GetHashCode();
+      return hash;
+    }
+
+    public override string ToString() {
+      return pb::JsonFormatter.Default.Format(this);
+    }
+
+    public void WriteTo(pb::CodedOutputStream output) {
+      if (latencies_ != null) {
+        output.WriteRawTag(10);
+        output.WriteMessage(Latencies);
+      }
+      if (TimeElapsed != 0D) {
+        output.WriteRawTag(17);
+        output.WriteDouble(TimeElapsed);
+      }
+      if (TimeUser != 0D) {
+        output.WriteRawTag(25);
+        output.WriteDouble(TimeUser);
+      }
+      if (TimeSystem != 0D) {
+        output.WriteRawTag(33);
+        output.WriteDouble(TimeSystem);
+      }
+    }
+
+    public int CalculateSize() {
+      int size = 0;
+      if (latencies_ != null) {
+        size += 1 + pb::CodedOutputStream.ComputeMessageSize(Latencies);
+      }
+      if (TimeElapsed != 0D) {
+        size += 1 + 8;
+      }
+      if (TimeUser != 0D) {
+        size += 1 + 8;
+      }
+      if (TimeSystem != 0D) {
+        size += 1 + 8;
+      }
+      return size;
+    }
+
+    public void MergeFrom(ClientStats other) {
+      if (other == null) {
+        return;
+      }
+      if (other.latencies_ != null) {
+        if (latencies_ == null) {
+          latencies_ = new global::Grpc.Testing.HistogramData();
+        }
+        Latencies.MergeFrom(other.Latencies);
+      }
+      if (other.TimeElapsed != 0D) {
+        TimeElapsed = other.TimeElapsed;
+      }
+      if (other.TimeUser != 0D) {
+        TimeUser = other.TimeUser;
+      }
+      if (other.TimeSystem != 0D) {
+        TimeSystem = other.TimeSystem;
+      }
+    }
+
+    public void MergeFrom(pb::CodedInputStream input) {
+      uint tag;
+      while ((tag = input.ReadTag()) != 0) {
+        switch(tag) {
+          default:
+            input.SkipLastField();
+            break;
+          case 10: {
+            if (latencies_ == null) {
+              latencies_ = new global::Grpc.Testing.HistogramData();
+            }
+            input.ReadMessage(latencies_);
+            break;
+          }
+          case 17: {
+            TimeElapsed = input.ReadDouble();
+            break;
+          }
+          case 25: {
+            TimeUser = input.ReadDouble();
+            break;
+          }
+          case 33: {
+            TimeSystem = input.ReadDouble();
+            break;
+          }
+        }
+      }
+    }
+
+  }
+
+  #endregion
+
+}
+
+#endregion Designer generated code
diff --git a/src/csharp/Grpc.IntegrationTesting/WallClockStopwatch.cs b/src/csharp/Grpc.IntegrationTesting/WallClockStopwatch.cs
new file mode 100644
index 0000000..e44ae2a
--- /dev/null
+++ b/src/csharp/Grpc.IntegrationTesting/WallClockStopwatch.cs
@@ -0,0 +1,78 @@
+#region Copyright notice and license
+
+// Copyright 2015, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.Linq;
+using System.Text.RegularExpressions;
+using System.Threading;
+using System.Threading.Tasks;
+using Google.Protobuf;
+using Grpc.Core;
+using Grpc.Core.Utils;
+using NUnit.Framework;
+using Grpc.Testing;
+
+namespace Grpc.IntegrationTesting
+{
+    /// <summary>
+    /// Snapshottable wall clock stopwatch.
+    /// </summary>
+    public class WallClockStopwatch
+    {
+        long startTicks;
+
+        public WallClockStopwatch()
+        {
+            this.startTicks = DateTime.UtcNow.Ticks;
+        }
+
+        public TimeSpan GetElapsedSnapshot(bool reset)
+        {
+            var utcNow = DateTime.UtcNow;
+
+            long oldStartTicks;
+            if (reset)
+            {
+                oldStartTicks = Interlocked.Exchange(ref this.startTicks, utcNow.Ticks);
+            }
+            else
+            {
+                oldStartTicks = this.startTicks;
+            }
+            return utcNow - new DateTime(oldStartTicks, DateTimeKind.Utc);
+        }
+    }
+}
diff --git a/src/csharp/Grpc.IntegrationTesting/WorkerServiceImpl.cs b/src/csharp/Grpc.IntegrationTesting/WorkerServiceImpl.cs
new file mode 100644
index 0000000..bb2918b
--- /dev/null
+++ b/src/csharp/Grpc.IntegrationTesting/WorkerServiceImpl.cs
@@ -0,0 +1,96 @@
+#region Copyright notice and license
+
+// Copyright 2015, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Threading;
+using System.Threading.Tasks;
+using Google.Protobuf;
+using Grpc.Core;
+using Grpc.Core.Utils;
+using Grpc.IntegrationTesting;
+
+namespace Grpc.Testing
+{
+    /// <summary>
+    /// Implementation of WorkerService server
+    /// </summary>
+    public class WorkerServiceImpl : WorkerService.IWorkerService
+    {
+        public async Task RunServer(IAsyncStreamReader<ServerArgs> requestStream, IServerStreamWriter<ServerStatus> responseStream, ServerCallContext context)
+        {
+            Grpc.Core.Utils.Preconditions.CheckState(await requestStream.MoveNext());
+            var serverConfig = requestStream.Current.Setup;
+            var runner = ServerRunners.CreateStarted(serverConfig);
+
+            await responseStream.WriteAsync(new ServerStatus
+            {
+                Stats = runner.GetStats(false),
+                Port = runner.BoundPort,
+                Cores = 0,  // TODO: set number of cores
+            });
+                
+            while (await requestStream.MoveNext())
+            {
+                var reset = requestStream.Current.Mark.Reset;
+                await responseStream.WriteAsync(new ServerStatus
+                {
+                    Stats = runner.GetStats(reset)
+                });
+            }
+            await runner.StopAsync();
+        }
+
+        public async Task RunClient(IAsyncStreamReader<ClientArgs> requestStream, IServerStreamWriter<ClientStatus> responseStream, ServerCallContext context)
+        {
+            Grpc.Core.Utils.Preconditions.CheckState(await requestStream.MoveNext());
+            var clientConfig = requestStream.Current.Setup;
+            var runner = ClientRunners.CreateStarted(clientConfig);
+
+            await responseStream.WriteAsync(new ClientStatus
+            {
+                Stats = runner.GetStats(false)
+            });
+
+            while (await requestStream.MoveNext())
+            {
+                var reset = requestStream.Current.Mark.Reset;
+                await responseStream.WriteAsync(new ClientStatus
+                {
+                    Stats = runner.GetStats(reset)
+                });
+            }
+            await runner.StopAsync();
+        }
+    }
+}
diff --git a/src/csharp/Grpc.IntegrationTesting/data/server1.pem b/src/csharp/Grpc.IntegrationTesting/data/server1.pem
index 8e582e5..f3d43fc 100644
--- a/src/csharp/Grpc.IntegrationTesting/data/server1.pem
+++ b/src/csharp/Grpc.IntegrationTesting/data/server1.pem
@@ -1,16 +1,16 @@
 -----BEGIN CERTIFICATE-----
-MIICmzCCAgSgAwIBAgIBAzANBgkqhkiG9w0BAQUFADBWMQswCQYDVQQGEwJBVTET
-MBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQ
-dHkgTHRkMQ8wDQYDVQQDDAZ0ZXN0Y2EwHhcNMTQwNzIyMDYwMDU3WhcNMjQwNzE5
-MDYwMDU3WjBkMQswCQYDVQQGEwJVUzERMA8GA1UECBMISWxsaW5vaXMxEDAOBgNV
-BAcTB0NoaWNhZ28xFDASBgNVBAoTC0dvb2dsZSBJbmMuMRowGAYDVQQDFBEqLnRl
-c3QuZ29vZ2xlLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA4cMVJygs
-JUmlgMMzgdi0h1XoCR7+ww1pop04OMMyy7H/i0PJ2W6Y35+b4CM8QrkYeEafUGDO
-RYX6yV/cHGGsD/x02ye6ey1UDtkGAD/mpDEx8YCrjAc1Vfvt8Fk6Cn1WVIxV/J30
-3xjBsFgByQ55RBp1OLZfVLo6AleBDSbcxaECAwEAAaNrMGkwCQYDVR0TBAIwADAL
-BgNVHQ8EBAMCBeAwTwYDVR0RBEgwRoIQKi50ZXN0Lmdvb2dsZS5mcoIYd2F0ZXJ6
-b29pLnRlc3QuZ29vZ2xlLmJlghIqLnRlc3QueW91dHViZS5jb22HBMCoAQMwDQYJ
-KoZIhvcNAQEFBQADgYEAM2Ii0LgTGbJ1j4oqX9bxVcxm+/R5Yf8oi0aZqTJlnLYS
-wXcBykxTx181s7WyfJ49WwrYXo78zTDAnf1ma0fPq3e4mpspvyndLh1a+OarHa1e
-aT0DIIYk7qeEa1YcVljx2KyLd0r1BBAfrwyGaEPVeJQVYWaOJRU2we/KD4ojf9s=
+MIICnDCCAgWgAwIBAgIBBzANBgkqhkiG9w0BAQsFADBWMQswCQYDVQQGEwJBVTET
+MBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQ
+dHkgTHRkMQ8wDQYDVQQDEwZ0ZXN0Y2EwHhcNMTUxMTA0MDIyMDI0WhcNMjUxMTAx
+MDIyMDI0WjBlMQswCQYDVQQGEwJVUzERMA8GA1UECBMISWxsaW5vaXMxEDAOBgNV
+BAcTB0NoaWNhZ28xFTATBgNVBAoTDEV4YW1wbGUsIENvLjEaMBgGA1UEAxQRKi50
+ZXN0Lmdvb2dsZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAOHDFSco
+LCVJpYDDM4HYtIdV6Ake/sMNaaKdODjDMsux/4tDydlumN+fm+AjPEK5GHhGn1Bg
+zkWF+slf3BxhrA/8dNsnunstVA7ZBgA/5qQxMfGAq4wHNVX77fBZOgp9VlSMVfyd
+9N8YwbBYAckOeUQadTi2X1S6OgJXgQ0m3MWhAgMBAAGjazBpMAkGA1UdEwQCMAAw
+CwYDVR0PBAQDAgXgME8GA1UdEQRIMEaCECoudGVzdC5nb29nbGUuZnKCGHdhdGVy
+em9vaS50ZXN0Lmdvb2dsZS5iZYISKi50ZXN0LnlvdXR1YmUuY29thwTAqAEDMA0G
+CSqGSIb3DQEBCwUAA4GBAJFXVifQNub1LUP4JlnX5lXNlo8FxZ2a12AFQs+bzoJ6
+hM044EDjqyxUqSbVePK0ni3w1fHQB5rY9yYC5f8G7aqqTY1QOhoUk8ZTSTRpnkTh
+y4jjdvTZeLDVBlueZUTDRmy2feY5aZIU18vFDK08dTG0A87pppuv1LNIR3loveU8
 -----END CERTIFICATE-----
diff --git a/src/csharp/Grpc.sln b/src/csharp/Grpc.sln
index f19f29c..8ff35e8 100644
--- a/src/csharp/Grpc.sln
+++ b/src/csharp/Grpc.sln
@@ -1,6 +1,6 @@
 

 Microsoft Visual Studio Solution File, Format Version 12.00

-# Visual Studio 2013

+# Visual Studio 2012

 VisualStudioVersion = 12.0.31101.0

 MinimumVisualStudioVersion = 10.0.40219.1

 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Grpc.Examples", "Grpc.Examples\Grpc.Examples.csproj", "{7DC1433E-3225-42C7-B7EA-546D56E27A4B}"

@@ -32,6 +32,8 @@
 EndProject

 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Grpc.HealthCheck.Tests", "Grpc.HealthCheck.Tests\Grpc.HealthCheck.Tests.csproj", "{F8C6D937-C44B-4EE3-A431-B0FBAEACE47D}"

 EndProject

+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Grpc.IntegrationTesting.QpsWorker", "Grpc.IntegrationTesting.QpsWorker\Grpc.IntegrationTesting.QpsWorker.csproj", "{B82B7DFE-7F7B-40EF-B3D6-064FF2B01294}"

+EndProject

 Global

 	GlobalSection(SolutionConfigurationPlatforms) = preSolution

 		Debug|Any CPU = Debug|Any CPU

@@ -39,72 +41,78 @@
 		ReleaseSigned|Any CPU = ReleaseSigned|Any CPU

 	EndGlobalSection

 	GlobalSection(ProjectConfigurationPlatforms) = postSolution

-		{7DC1433E-3225-42C7-B7EA-546D56E27A4B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU

-		{7DC1433E-3225-42C7-B7EA-546D56E27A4B}.Debug|Any CPU.Build.0 = Debug|Any CPU

-		{7DC1433E-3225-42C7-B7EA-546D56E27A4B}.Release|Any CPU.ActiveCfg = Release|Any CPU

-		{7DC1433E-3225-42C7-B7EA-546D56E27A4B}.Release|Any CPU.Build.0 = Release|Any CPU

-		{7DC1433E-3225-42C7-B7EA-546D56E27A4B}.ReleaseSigned|Any CPU.ActiveCfg = ReleaseSigned|Any CPU

-		{7DC1433E-3225-42C7-B7EA-546D56E27A4B}.ReleaseSigned|Any CPU.Build.0 = ReleaseSigned|Any CPU

-		{CCC4440E-49F7-4790-B0AF-FEABB0837AE7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU

-		{CCC4440E-49F7-4790-B0AF-FEABB0837AE7}.Debug|Any CPU.Build.0 = Debug|Any CPU

-		{CCC4440E-49F7-4790-B0AF-FEABB0837AE7}.Release|Any CPU.ActiveCfg = Release|Any CPU

-		{CCC4440E-49F7-4790-B0AF-FEABB0837AE7}.Release|Any CPU.Build.0 = Release|Any CPU

-		{CCC4440E-49F7-4790-B0AF-FEABB0837AE7}.ReleaseSigned|Any CPU.ActiveCfg = ReleaseSigned|Any CPU

-		{CCC4440E-49F7-4790-B0AF-FEABB0837AE7}.ReleaseSigned|Any CPU.Build.0 = ReleaseSigned|Any CPU

-		{86EC5CB4-4EA2-40A2-8057-86542A0353BB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU

-		{86EC5CB4-4EA2-40A2-8057-86542A0353BB}.Debug|Any CPU.Build.0 = Debug|Any CPU

-		{86EC5CB4-4EA2-40A2-8057-86542A0353BB}.Release|Any CPU.ActiveCfg = Release|Any CPU

-		{86EC5CB4-4EA2-40A2-8057-86542A0353BB}.Release|Any CPU.Build.0 = Release|Any CPU

-		{86EC5CB4-4EA2-40A2-8057-86542A0353BB}.ReleaseSigned|Any CPU.ActiveCfg = ReleaseSigned|Any CPU

-		{86EC5CB4-4EA2-40A2-8057-86542A0353BB}.ReleaseSigned|Any CPU.Build.0 = ReleaseSigned|Any CPU

 		{143B1C29-C442-4BE0-BF3F-A8F92288AC9F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU

 		{143B1C29-C442-4BE0-BF3F-A8F92288AC9F}.Debug|Any CPU.Build.0 = Debug|Any CPU

 		{143B1C29-C442-4BE0-BF3F-A8F92288AC9F}.Release|Any CPU.ActiveCfg = Release|Any CPU

 		{143B1C29-C442-4BE0-BF3F-A8F92288AC9F}.Release|Any CPU.Build.0 = Release|Any CPU

 		{143B1C29-C442-4BE0-BF3F-A8F92288AC9F}.ReleaseSigned|Any CPU.ActiveCfg = ReleaseSigned|Any CPU

 		{143B1C29-C442-4BE0-BF3F-A8F92288AC9F}.ReleaseSigned|Any CPU.Build.0 = ReleaseSigned|Any CPU

-		{61ECB8EE-0C96-4F8E-B187-8E4D227417C0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU

-		{61ECB8EE-0C96-4F8E-B187-8E4D227417C0}.Debug|Any CPU.Build.0 = Debug|Any CPU

-		{61ECB8EE-0C96-4F8E-B187-8E4D227417C0}.Release|Any CPU.ActiveCfg = Release|Any CPU

-		{61ECB8EE-0C96-4F8E-B187-8E4D227417C0}.Release|Any CPU.Build.0 = Release|Any CPU

-		{61ECB8EE-0C96-4F8E-B187-8E4D227417C0}.ReleaseSigned|Any CPU.ActiveCfg = ReleaseSigned|Any CPU

-		{61ECB8EE-0C96-4F8E-B187-8E4D227417C0}.ReleaseSigned|Any CPU.Build.0 = ReleaseSigned|Any CPU

-		{C61154BA-DD4A-4838-8420-0162A28925E0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU

-		{C61154BA-DD4A-4838-8420-0162A28925E0}.Debug|Any CPU.Build.0 = Debug|Any CPU

-		{C61154BA-DD4A-4838-8420-0162A28925E0}.Release|Any CPU.ActiveCfg = Release|Any CPU

-		{C61154BA-DD4A-4838-8420-0162A28925E0}.Release|Any CPU.Build.0 = Release|Any CPU

-		{C61154BA-DD4A-4838-8420-0162A28925E0}.ReleaseSigned|Any CPU.ActiveCfg = ReleaseSigned|Any CPU

-		{C61154BA-DD4A-4838-8420-0162A28925E0}.ReleaseSigned|Any CPU.Build.0 = ReleaseSigned|Any CPU

 		{3D166931-BA2D-416E-95A3-D36E8F6E90B9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU

 		{3D166931-BA2D-416E-95A3-D36E8F6E90B9}.Debug|Any CPU.Build.0 = Debug|Any CPU

 		{3D166931-BA2D-416E-95A3-D36E8F6E90B9}.Release|Any CPU.ActiveCfg = Release|Any CPU

 		{3D166931-BA2D-416E-95A3-D36E8F6E90B9}.Release|Any CPU.Build.0 = Release|Any CPU

 		{3D166931-BA2D-416E-95A3-D36E8F6E90B9}.ReleaseSigned|Any CPU.ActiveCfg = ReleaseSigned|Any CPU

 		{3D166931-BA2D-416E-95A3-D36E8F6E90B9}.ReleaseSigned|Any CPU.Build.0 = ReleaseSigned|Any CPU

+		{61ECB8EE-0C96-4F8E-B187-8E4D227417C0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU

+		{61ECB8EE-0C96-4F8E-B187-8E4D227417C0}.Debug|Any CPU.Build.0 = Debug|Any CPU

+		{61ECB8EE-0C96-4F8E-B187-8E4D227417C0}.Release|Any CPU.ActiveCfg = Release|Any CPU

+		{61ECB8EE-0C96-4F8E-B187-8E4D227417C0}.Release|Any CPU.Build.0 = Release|Any CPU

+		{61ECB8EE-0C96-4F8E-B187-8E4D227417C0}.ReleaseSigned|Any CPU.ActiveCfg = ReleaseSigned|Any CPU

+		{61ECB8EE-0C96-4F8E-B187-8E4D227417C0}.ReleaseSigned|Any CPU.Build.0 = ReleaseSigned|Any CPU

+		{7DC1433E-3225-42C7-B7EA-546D56E27A4B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU

+		{7DC1433E-3225-42C7-B7EA-546D56E27A4B}.Debug|Any CPU.Build.0 = Debug|Any CPU

+		{7DC1433E-3225-42C7-B7EA-546D56E27A4B}.Release|Any CPU.ActiveCfg = Release|Any CPU

+		{7DC1433E-3225-42C7-B7EA-546D56E27A4B}.Release|Any CPU.Build.0 = Release|Any CPU

+		{7DC1433E-3225-42C7-B7EA-546D56E27A4B}.ReleaseSigned|Any CPU.ActiveCfg = ReleaseSigned|Any CPU

+		{7DC1433E-3225-42C7-B7EA-546D56E27A4B}.ReleaseSigned|Any CPU.Build.0 = ReleaseSigned|Any CPU

+		{86EC5CB4-4EA2-40A2-8057-86542A0353BB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU

+		{86EC5CB4-4EA2-40A2-8057-86542A0353BB}.Debug|Any CPU.Build.0 = Debug|Any CPU

+		{86EC5CB4-4EA2-40A2-8057-86542A0353BB}.Release|Any CPU.ActiveCfg = Release|Any CPU

+		{86EC5CB4-4EA2-40A2-8057-86542A0353BB}.Release|Any CPU.Build.0 = Release|Any CPU

+		{86EC5CB4-4EA2-40A2-8057-86542A0353BB}.ReleaseSigned|Any CPU.ActiveCfg = ReleaseSigned|Any CPU

+		{86EC5CB4-4EA2-40A2-8057-86542A0353BB}.ReleaseSigned|Any CPU.Build.0 = ReleaseSigned|Any CPU

 		{A654F3B8-E859-4E6A-B30D-227527DBEF0D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU

 		{A654F3B8-E859-4E6A-B30D-227527DBEF0D}.Debug|Any CPU.Build.0 = Debug|Any CPU

 		{A654F3B8-E859-4E6A-B30D-227527DBEF0D}.Release|Any CPU.ActiveCfg = Release|Any CPU

 		{A654F3B8-E859-4E6A-B30D-227527DBEF0D}.Release|Any CPU.Build.0 = Release|Any CPU

 		{A654F3B8-E859-4E6A-B30D-227527DBEF0D}.ReleaseSigned|Any CPU.ActiveCfg = ReleaseSigned|Any CPU

 		{A654F3B8-E859-4E6A-B30D-227527DBEF0D}.ReleaseSigned|Any CPU.Build.0 = ReleaseSigned|Any CPU

-		{BF62FE08-373A-43D6-9D73-41CAA38B7011}.Debug|Any CPU.ActiveCfg = Debug|Any CPU

-		{BF62FE08-373A-43D6-9D73-41CAA38B7011}.Debug|Any CPU.Build.0 = Debug|Any CPU

-		{BF62FE08-373A-43D6-9D73-41CAA38B7011}.Release|Any CPU.ActiveCfg = Release|Any CPU

-		{BF62FE08-373A-43D6-9D73-41CAA38B7011}.Release|Any CPU.Build.0 = Release|Any CPU

-		{BF62FE08-373A-43D6-9D73-41CAA38B7011}.ReleaseSigned|Any CPU.ActiveCfg = ReleaseSigned|Any CPU

-		{BF62FE08-373A-43D6-9D73-41CAA38B7011}.ReleaseSigned|Any CPU.Build.0 = ReleaseSigned|Any CPU

-		{AE21D0EE-9A2C-4C15-AB7F-5224EED5B0EA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU

-		{AE21D0EE-9A2C-4C15-AB7F-5224EED5B0EA}.Debug|Any CPU.Build.0 = Debug|Any CPU

-		{AE21D0EE-9A2C-4C15-AB7F-5224EED5B0EA}.Release|Any CPU.ActiveCfg = Release|Any CPU

-		{AE21D0EE-9A2C-4C15-AB7F-5224EED5B0EA}.Release|Any CPU.Build.0 = Release|Any CPU

-		{AE21D0EE-9A2C-4C15-AB7F-5224EED5B0EA}.ReleaseSigned|Any CPU.ActiveCfg = ReleaseSigned|Any CPU

-		{AE21D0EE-9A2C-4C15-AB7F-5224EED5B0EA}.ReleaseSigned|Any CPU.Build.0 = ReleaseSigned|Any CPU

 		{AA5E328A-8835-49D7-98ED-C29F2B3049F0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU

 		{AA5E328A-8835-49D7-98ED-C29F2B3049F0}.Debug|Any CPU.Build.0 = Debug|Any CPU

 		{AA5E328A-8835-49D7-98ED-C29F2B3049F0}.Release|Any CPU.ActiveCfg = Release|Any CPU

 		{AA5E328A-8835-49D7-98ED-C29F2B3049F0}.Release|Any CPU.Build.0 = Release|Any CPU

 		{AA5E328A-8835-49D7-98ED-C29F2B3049F0}.ReleaseSigned|Any CPU.ActiveCfg = ReleaseSigned|Any CPU

 		{AA5E328A-8835-49D7-98ED-C29F2B3049F0}.ReleaseSigned|Any CPU.Build.0 = ReleaseSigned|Any CPU

+		{AE21D0EE-9A2C-4C15-AB7F-5224EED5B0EA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU

+		{AE21D0EE-9A2C-4C15-AB7F-5224EED5B0EA}.Debug|Any CPU.Build.0 = Debug|Any CPU

+		{AE21D0EE-9A2C-4C15-AB7F-5224EED5B0EA}.Release|Any CPU.ActiveCfg = Release|Any CPU

+		{AE21D0EE-9A2C-4C15-AB7F-5224EED5B0EA}.Release|Any CPU.Build.0 = Release|Any CPU

+		{AE21D0EE-9A2C-4C15-AB7F-5224EED5B0EA}.ReleaseSigned|Any CPU.ActiveCfg = ReleaseSigned|Any CPU

+		{AE21D0EE-9A2C-4C15-AB7F-5224EED5B0EA}.ReleaseSigned|Any CPU.Build.0 = ReleaseSigned|Any CPU

+		{B82B7DFE-7F7B-40EF-B3D6-064FF2B01294}.Debug|Any CPU.ActiveCfg = Debug|Any CPU

+		{B82B7DFE-7F7B-40EF-B3D6-064FF2B01294}.Debug|Any CPU.Build.0 = Debug|Any CPU

+		{B82B7DFE-7F7B-40EF-B3D6-064FF2B01294}.Release|Any CPU.ActiveCfg = Release|Any CPU

+		{B82B7DFE-7F7B-40EF-B3D6-064FF2B01294}.Release|Any CPU.Build.0 = Release|Any CPU

+		{B82B7DFE-7F7B-40EF-B3D6-064FF2B01294}.ReleaseSigned|Any CPU.ActiveCfg = Release|Any CPU

+		{B82B7DFE-7F7B-40EF-B3D6-064FF2B01294}.ReleaseSigned|Any CPU.Build.0 = Release|Any CPU

+		{BF62FE08-373A-43D6-9D73-41CAA38B7011}.Debug|Any CPU.ActiveCfg = Debug|Any CPU

+		{BF62FE08-373A-43D6-9D73-41CAA38B7011}.Debug|Any CPU.Build.0 = Debug|Any CPU

+		{BF62FE08-373A-43D6-9D73-41CAA38B7011}.Release|Any CPU.ActiveCfg = Release|Any CPU

+		{BF62FE08-373A-43D6-9D73-41CAA38B7011}.Release|Any CPU.Build.0 = Release|Any CPU

+		{BF62FE08-373A-43D6-9D73-41CAA38B7011}.ReleaseSigned|Any CPU.ActiveCfg = ReleaseSigned|Any CPU

+		{BF62FE08-373A-43D6-9D73-41CAA38B7011}.ReleaseSigned|Any CPU.Build.0 = ReleaseSigned|Any CPU

+		{C61154BA-DD4A-4838-8420-0162A28925E0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU

+		{C61154BA-DD4A-4838-8420-0162A28925E0}.Debug|Any CPU.Build.0 = Debug|Any CPU

+		{C61154BA-DD4A-4838-8420-0162A28925E0}.Release|Any CPU.ActiveCfg = Release|Any CPU

+		{C61154BA-DD4A-4838-8420-0162A28925E0}.Release|Any CPU.Build.0 = Release|Any CPU

+		{C61154BA-DD4A-4838-8420-0162A28925E0}.ReleaseSigned|Any CPU.ActiveCfg = ReleaseSigned|Any CPU

+		{C61154BA-DD4A-4838-8420-0162A28925E0}.ReleaseSigned|Any CPU.Build.0 = ReleaseSigned|Any CPU

+		{CCC4440E-49F7-4790-B0AF-FEABB0837AE7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU

+		{CCC4440E-49F7-4790-B0AF-FEABB0837AE7}.Debug|Any CPU.Build.0 = Debug|Any CPU

+		{CCC4440E-49F7-4790-B0AF-FEABB0837AE7}.Release|Any CPU.ActiveCfg = Release|Any CPU

+		{CCC4440E-49F7-4790-B0AF-FEABB0837AE7}.Release|Any CPU.Build.0 = Release|Any CPU

+		{CCC4440E-49F7-4790-B0AF-FEABB0837AE7}.ReleaseSigned|Any CPU.ActiveCfg = ReleaseSigned|Any CPU

+		{CCC4440E-49F7-4790-B0AF-FEABB0837AE7}.ReleaseSigned|Any CPU.Build.0 = ReleaseSigned|Any CPU

 		{F8C6D937-C44B-4EE3-A431-B0FBAEACE47D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU

 		{F8C6D937-C44B-4EE3-A431-B0FBAEACE47D}.Debug|Any CPU.Build.0 = Debug|Any CPU

 		{F8C6D937-C44B-4EE3-A431-B0FBAEACE47D}.Release|Any CPU.ActiveCfg = Release|Any CPU

@@ -112,6 +120,8 @@
 		{F8C6D937-C44B-4EE3-A431-B0FBAEACE47D}.ReleaseSigned|Any CPU.ActiveCfg = ReleaseSigned|Any CPU

 		{F8C6D937-C44B-4EE3-A431-B0FBAEACE47D}.ReleaseSigned|Any CPU.Build.0 = ReleaseSigned|Any CPU

 	EndGlobalSection

+	GlobalSection(NestedProjects) = preSolution

+	EndGlobalSection

 	GlobalSection(SolutionProperties) = preSolution

 		HideSolutionNode = FALSE

 	EndGlobalSection

diff --git a/src/csharp/ext/grpc_csharp_ext.c b/src/csharp/ext/grpc_csharp_ext.c
index 679ca43..1839319 100644
--- a/src/csharp/ext/grpc_csharp_ext.c
+++ b/src/csharp/ext/grpc_csharp_ext.c
@@ -785,9 +785,10 @@
                                NULL);
 }
 
-GPR_EXPORT grpc_call_error GPR_CALLTYPE grpcsharp_call_set_credentials(grpc_call *call,
-                                                            grpc_credentials *creds) {
-	return grpc_call_set_credentials(call, creds);
+GPR_EXPORT grpc_call_error GPR_CALLTYPE grpcsharp_call_set_credentials(
+    grpc_call *call,
+    grpc_call_credentials *creds) {
+  return grpc_call_set_credentials(call, creds);
 }
 
 /* Server */
@@ -834,7 +835,7 @@
 
 /* Security */
 
-GPR_EXPORT grpc_credentials *GPR_CALLTYPE
+GPR_EXPORT grpc_channel_credentials *GPR_CALLTYPE
 grpcsharp_ssl_credentials_create(const char *pem_root_certs,
                                  const char *key_cert_pair_cert_chain,
                                  const char *key_cert_pair_private_key) {
@@ -850,12 +851,19 @@
   }
 }
 
-GPR_EXPORT void GPR_CALLTYPE grpcsharp_credentials_release(grpc_credentials *creds) {
-  grpc_credentials_release(creds);
+GPR_EXPORT void GPR_CALLTYPE grpcsharp_channel_credentials_release(
+    grpc_channel_credentials *creds) {
+  grpc_channel_credentials_release(creds);
+}
+
+GPR_EXPORT void GPR_CALLTYPE grpcsharp_call_credentials_release(
+    grpc_call_credentials *creds) {
+  grpc_call_credentials_release(creds);
 }
 
 GPR_EXPORT grpc_channel *GPR_CALLTYPE
-grpcsharp_secure_channel_create(grpc_credentials *creds, const char *target,
+grpcsharp_secure_channel_create(grpc_channel_credentials *creds,
+                                const char *target,
                                 const grpc_channel_args *args) {
   return grpc_secure_channel_create(creds, target, args, NULL);
 }
@@ -897,10 +905,16 @@
   return grpc_server_add_secure_http2_port(server, addr, creds);
 }
 
-GPR_EXPORT grpc_credentials *GPR_CALLTYPE grpcsharp_composite_credentials_create(
-  grpc_credentials *creds1,
-  grpc_credentials *creds2) {
-  return grpc_composite_credentials_create(creds1, creds2, NULL);
+GPR_EXPORT grpc_channel_credentials *GPR_CALLTYPE grpcsharp_composite_channel_credentials_create(
+  grpc_channel_credentials *channel_creds,
+  grpc_call_credentials *call_creds) {
+  return grpc_composite_channel_credentials_create(channel_creds, call_creds, NULL);
+}
+
+GPR_EXPORT grpc_call_credentials *GPR_CALLTYPE grpcsharp_composite_call_credentials_create(
+  grpc_call_credentials *creds1,
+  grpc_call_credentials *creds2) {
+  return grpc_composite_call_credentials_create(creds1, creds2, NULL);
 }
 
 /* Metadata credentials plugin */
@@ -929,7 +943,7 @@
   interceptor(state, NULL, NULL, NULL, 1);
 }
 
-GPR_EXPORT grpc_credentials *GPR_CALLTYPE grpcsharp_metadata_credentials_create_from_plugin(
+GPR_EXPORT grpc_call_credentials *GPR_CALLTYPE grpcsharp_metadata_credentials_create_from_plugin(
   grpcsharp_metadata_interceptor_func metadata_interceptor) {
   grpc_metadata_credentials_plugin plugin;
   plugin.get_metadata = grpcsharp_get_metadata_handler;
diff --git a/src/csharp/generate_proto_csharp.sh b/src/csharp/generate_proto_csharp.sh
index f879e07..92348d1 100755
--- a/src/csharp/generate_proto_csharp.sh
+++ b/src/csharp/generate_proto_csharp.sh
@@ -35,14 +35,14 @@
 PROTOC=../../bins/opt/protobuf/protoc
 PLUGIN=protoc-gen-grpc=../../bins/opt/grpc_csharp_plugin
 EXAMPLES_DIR=Grpc.Examples
-INTEROP_DIR=Grpc.IntegrationTesting
+TESTING_DIR=Grpc.IntegrationTesting
 HEALTHCHECK_DIR=Grpc.HealthCheck
 
 $PROTOC --plugin=$PLUGIN --csharp_out=$EXAMPLES_DIR --grpc_out=$EXAMPLES_DIR \
     -I $EXAMPLES_DIR/proto $EXAMPLES_DIR/proto/math.proto
 
-$PROTOC --plugin=$PLUGIN --csharp_out=$INTEROP_DIR --grpc_out=$INTEROP_DIR \
-    -I ../.. ../../test/proto/*.proto
+$PROTOC --plugin=$PLUGIN --csharp_out=$TESTING_DIR --grpc_out=$TESTING_DIR \
+    -I ../.. ../../test/proto/*.proto ../../test/proto/benchmarks/*.proto
 
 $PROTOC --plugin=$PLUGIN --csharp_out=$HEALTHCHECK_DIR --grpc_out=$HEALTHCHECK_DIR \
     -I $HEALTHCHECK_DIR/proto $HEALTHCHECK_DIR/proto/health.proto
diff --git a/src/node/ext/call.cc b/src/node/ext/call.cc
index fe11905..a98ae85 100644
--- a/src/node/ext/call.cc
+++ b/src/node/ext/call.cc
@@ -757,7 +757,7 @@
   Call *call = ObjectWrap::Unwrap<Call>(info.This());
   CallCredentials *creds_object = ObjectWrap::Unwrap<CallCredentials>(
       Nan::To<Object>(info[0]).ToLocalChecked());
-  grpc_credentials *creds = creds_object->GetWrappedCredentials();
+  grpc_call_credentials *creds = creds_object->GetWrappedCredentials();
   grpc_call_error error = GRPC_CALL_ERROR;
   if (creds) {
     error = grpc_call_set_credentials(call->wrapped_call, creds);
diff --git a/src/node/ext/call_credentials.cc b/src/node/ext/call_credentials.cc
index ff16a1f..9c5d9d2 100644
--- a/src/node/ext/call_credentials.cc
+++ b/src/node/ext/call_credentials.cc
@@ -64,11 +64,11 @@
 Nan::Callback *CallCredentials::constructor;
 Persistent<FunctionTemplate> CallCredentials::fun_tpl;
 
-CallCredentials::CallCredentials(grpc_credentials *credentials)
+CallCredentials::CallCredentials(grpc_call_credentials *credentials)
     : wrapped_credentials(credentials) {}
 
 CallCredentials::~CallCredentials() {
-  grpc_credentials_release(wrapped_credentials);
+  grpc_call_credentials_release(wrapped_credentials);
 }
 
 void CallCredentials::Init(Local<Object> exports) {
@@ -91,7 +91,7 @@
   return Nan::New(fun_tpl)->HasInstance(val);
 }
 
-Local<Value> CallCredentials::WrapStruct(grpc_credentials *credentials) {
+Local<Value> CallCredentials::WrapStruct(grpc_call_credentials *credentials) {
   EscapableHandleScope scope;
   const int argc = 1;
   if (credentials == NULL) {
@@ -108,7 +108,7 @@
   }
 }
 
-grpc_credentials *CallCredentials::GetWrappedCredentials() {
+grpc_call_credentials *CallCredentials::GetWrappedCredentials() {
   return wrapped_credentials;
 }
 
@@ -119,8 +119,8 @@
           "CallCredentials can only be created with the provided functions");
     }
     Local<External> ext = info[0].As<External>();
-    grpc_credentials *creds_value =
-        reinterpret_cast<grpc_credentials *>(ext->Value());
+    grpc_call_credentials *creds_value =
+        reinterpret_cast<grpc_call_credentials *>(ext->Value());
     CallCredentials *credentials = new CallCredentials(creds_value);
     credentials->Wrap(info.This());
     info.GetReturnValue().Set(info.This());
@@ -144,7 +144,7 @@
   CallCredentials *self = ObjectWrap::Unwrap<CallCredentials>(info.This());
   CallCredentials *other = ObjectWrap::Unwrap<CallCredentials>(
       Nan::To<Object>(info[0]).ToLocalChecked());
-  grpc_credentials *creds = grpc_composite_credentials_create(
+  grpc_call_credentials *creds = grpc_composite_call_credentials_create(
       self->wrapped_credentials, other->wrapped_credentials, NULL);
   info.GetReturnValue().Set(WrapStruct(creds));
 }
@@ -162,8 +162,8 @@
   plugin.get_metadata = plugin_get_metadata;
   plugin.destroy = plugin_destroy_state;
   plugin.state = reinterpret_cast<void*>(state);
-  grpc_credentials *creds = grpc_metadata_credentials_create_from_plugin(plugin,
-                                                                         NULL);
+  grpc_call_credentials *creds = grpc_metadata_credentials_create_from_plugin(
+      plugin, NULL);
   info.GetReturnValue().Set(WrapStruct(creds));
 }
 
diff --git a/src/node/ext/call_credentials.h b/src/node/ext/call_credentials.h
index 618292d..1cd8d8d 100644
--- a/src/node/ext/call_credentials.h
+++ b/src/node/ext/call_credentials.h
@@ -45,14 +45,14 @@
  public:
   static void Init(v8::Local<v8::Object> exports);
   static bool HasInstance(v8::Local<v8::Value> val);
-  /* Wrap a grpc_credentials struct in a javascript object */
-  static v8::Local<v8::Value> WrapStruct(grpc_credentials *credentials);
+  /* Wrap a grpc_call_credentials struct in a javascript object */
+  static v8::Local<v8::Value> WrapStruct(grpc_call_credentials *credentials);
 
-  /* Returns the grpc_credentials struct that this object wraps */
-  grpc_credentials *GetWrappedCredentials();
+  /* Returns the grpc_call_credentials struct that this object wraps */
+  grpc_call_credentials *GetWrappedCredentials();
 
  private:
-  explicit CallCredentials(grpc_credentials *credentials);
+  explicit CallCredentials(grpc_call_credentials *credentials);
   ~CallCredentials();
 
   // Prevent copying
@@ -68,7 +68,7 @@
   // Used for typechecking instances of this javascript class
   static Nan::Persistent<v8::FunctionTemplate> fun_tpl;
 
-  grpc_credentials *wrapped_credentials;
+  grpc_call_credentials *wrapped_credentials;
 };
 
 /* Auth metadata plugin functionality */
diff --git a/src/node/ext/channel.cc b/src/node/ext/channel.cc
index c11734d..00fcca6 100644
--- a/src/node/ext/channel.cc
+++ b/src/node/ext/channel.cc
@@ -177,7 +177,7 @@
     grpc_channel *wrapped_channel;
     // Owned by the Channel object
     Utf8String host(info[0]);
-    grpc_credentials *creds;
+    grpc_channel_credentials *creds;
     if (!ChannelCredentials::HasInstance(info[1])) {
       return Nan::ThrowTypeError(
           "Channel's second argument must be a ChannelCredentials");
diff --git a/src/node/ext/channel_credentials.cc b/src/node/ext/channel_credentials.cc
index 7ca3b98..b77ff80 100644
--- a/src/node/ext/channel_credentials.cc
+++ b/src/node/ext/channel_credentials.cc
@@ -65,11 +65,11 @@
 Nan::Callback *ChannelCredentials::constructor;
 Persistent<FunctionTemplate> ChannelCredentials::fun_tpl;
 
-ChannelCredentials::ChannelCredentials(grpc_credentials *credentials)
+ChannelCredentials::ChannelCredentials(grpc_channel_credentials *credentials)
     : wrapped_credentials(credentials) {}
 
 ChannelCredentials::~ChannelCredentials() {
-  grpc_credentials_release(wrapped_credentials);
+  grpc_channel_credentials_release(wrapped_credentials);
 }
 
 void ChannelCredentials::Init(Local<Object> exports) {
@@ -95,7 +95,8 @@
   return Nan::New(fun_tpl)->HasInstance(val);
 }
 
-Local<Value> ChannelCredentials::WrapStruct(grpc_credentials *credentials) {
+Local<Value> ChannelCredentials::WrapStruct(
+    grpc_channel_credentials *credentials) {
   EscapableHandleScope scope;
   const int argc = 1;
   Local<Value> argv[argc] = {
@@ -109,7 +110,7 @@
   }
 }
 
-grpc_credentials *ChannelCredentials::GetWrappedCredentials() {
+grpc_channel_credentials *ChannelCredentials::GetWrappedCredentials() {
   return wrapped_credentials;
 }
 
@@ -120,8 +121,8 @@
           "ChannelCredentials can only be created with the provided functions");
     }
     Local<External> ext = info[0].As<External>();
-    grpc_credentials *creds_value =
-        reinterpret_cast<grpc_credentials *>(ext->Value());
+    grpc_channel_credentials *creds_value =
+        reinterpret_cast<grpc_channel_credentials *>(ext->Value());
     ChannelCredentials *credentials = new ChannelCredentials(creds_value);
     credentials->Wrap(info.This());
     info.GetReturnValue().Set(info.This());
@@ -153,7 +154,7 @@
     return Nan::ThrowTypeError(
         "createSSl's third argument must be a Buffer if provided");
   }
-  grpc_credentials *creds = grpc_ssl_credentials_create(
+  grpc_channel_credentials *creds = grpc_ssl_credentials_create(
       root_certs, key_cert_pair.private_key == NULL ? NULL : &key_cert_pair,
       NULL);
   if (creds == NULL) {
@@ -180,7 +181,7 @@
   }
   CallCredentials *other = ObjectWrap::Unwrap<CallCredentials>(
       Nan::To<Object>(info[0]).ToLocalChecked());
-  grpc_credentials *creds = grpc_composite_credentials_create(
+  grpc_channel_credentials *creds = grpc_composite_channel_credentials_create(
       self->wrapped_credentials, other->GetWrappedCredentials(), NULL);
   if (creds == NULL) {
     info.GetReturnValue().SetNull();
diff --git a/src/node/ext/channel_credentials.h b/src/node/ext/channel_credentials.h
index 31ea098..89b1152 100644
--- a/src/node/ext/channel_credentials.h
+++ b/src/node/ext/channel_credentials.h
@@ -42,19 +42,19 @@
 namespace grpc {
 namespace node {
 
-/* Wrapper class for grpc_credentials structs */
+/* Wrapper class for grpc_channel_credentials structs */
 class ChannelCredentials : public Nan::ObjectWrap {
  public:
   static void Init(v8::Local<v8::Object> exports);
   static bool HasInstance(v8::Local<v8::Value> val);
-  /* Wrap a grpc_credentials struct in a javascript object */
-  static v8::Local<v8::Value> WrapStruct(grpc_credentials *credentials);
+  /* Wrap a grpc_channel_credentials struct in a javascript object */
+  static v8::Local<v8::Value> WrapStruct(grpc_channel_credentials *credentials);
 
-  /* Returns the grpc_credentials struct that this object wraps */
-  grpc_credentials *GetWrappedCredentials();
+  /* Returns the grpc_channel_credentials struct that this object wraps */
+  grpc_channel_credentials *GetWrappedCredentials();
 
  private:
-  explicit ChannelCredentials(grpc_credentials *credentials);
+  explicit ChannelCredentials(grpc_channel_credentials *credentials);
   ~ChannelCredentials();
 
   // Prevent copying
@@ -70,7 +70,7 @@
   // Used for typechecking instances of this javascript class
   static Nan::Persistent<v8::FunctionTemplate> fun_tpl;
 
-  grpc_credentials *wrapped_credentials;
+  grpc_channel_credentials *wrapped_credentials;
 };
 
 }  // namespace node
diff --git a/src/node/test/credentials_test.js b/src/node/test/credentials_test.js
index 3e01b62..647f648 100644
--- a/src/node/test/credentials_test.js
+++ b/src/node/test/credentials_test.js
@@ -71,7 +71,7 @@
 var fakeFailingGoogleCredentials = {
   getRequestMetadata: function(service_url, callback) {
     setTimeout(function() {
-      callback(new Error('Authorization failure'));
+      callback(new Error('Authentication failure'));
     }, 0);
   }
 };
@@ -218,6 +218,25 @@
       done();
     });
   });
+  it('Should not add metadata with just SSL credentials', function(done) {
+    // Tests idempotency of credentials composition
+    var metadataUpdater = function(service_url, callback) {
+      var metadata = new grpc.Metadata();
+      metadata.set('plugin_key', 'plugin_value');
+      callback(null, metadata);
+    };
+    var creds = grpc.credentials.createFromMetadataGenerator(metadataUpdater);
+    grpc.credentials.combineChannelCredentials(client_ssl_creds, creds);
+    var client = new Client('localhost:' + port, client_ssl_creds,
+                            client_options);
+    var call = client.unary({}, function(err, data) {
+      assert.ifError(err);
+    });
+    call.on('metadata', function(metadata) {
+      assert.deepEqual(metadata.get('plugin_key'), []);
+      done();
+    });
+  });
   it.skip('should get an error from a Google credential', function(done) {
     var creds = grpc.credentials.createFromGoogleCredential(
         fakeFailingGoogleCredentials);
@@ -227,7 +246,7 @@
                             client_options);
     client.unary({}, function(err, data) {
       assert(err);
-      assert.strictEqual(err.message, 'Authorization failure');
+      assert.strictEqual(err.message, 'Authentication failure');
       done();
     });
   });
diff --git a/src/node/test/data/server1.pem b/src/node/test/data/server1.pem
index 8e582e5..f3d43fc 100644
--- a/src/node/test/data/server1.pem
+++ b/src/node/test/data/server1.pem
@@ -1,16 +1,16 @@
 -----BEGIN CERTIFICATE-----
-MIICmzCCAgSgAwIBAgIBAzANBgkqhkiG9w0BAQUFADBWMQswCQYDVQQGEwJBVTET
-MBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQ
-dHkgTHRkMQ8wDQYDVQQDDAZ0ZXN0Y2EwHhcNMTQwNzIyMDYwMDU3WhcNMjQwNzE5
-MDYwMDU3WjBkMQswCQYDVQQGEwJVUzERMA8GA1UECBMISWxsaW5vaXMxEDAOBgNV
-BAcTB0NoaWNhZ28xFDASBgNVBAoTC0dvb2dsZSBJbmMuMRowGAYDVQQDFBEqLnRl
-c3QuZ29vZ2xlLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA4cMVJygs
-JUmlgMMzgdi0h1XoCR7+ww1pop04OMMyy7H/i0PJ2W6Y35+b4CM8QrkYeEafUGDO
-RYX6yV/cHGGsD/x02ye6ey1UDtkGAD/mpDEx8YCrjAc1Vfvt8Fk6Cn1WVIxV/J30
-3xjBsFgByQ55RBp1OLZfVLo6AleBDSbcxaECAwEAAaNrMGkwCQYDVR0TBAIwADAL
-BgNVHQ8EBAMCBeAwTwYDVR0RBEgwRoIQKi50ZXN0Lmdvb2dsZS5mcoIYd2F0ZXJ6
-b29pLnRlc3QuZ29vZ2xlLmJlghIqLnRlc3QueW91dHViZS5jb22HBMCoAQMwDQYJ
-KoZIhvcNAQEFBQADgYEAM2Ii0LgTGbJ1j4oqX9bxVcxm+/R5Yf8oi0aZqTJlnLYS
-wXcBykxTx181s7WyfJ49WwrYXo78zTDAnf1ma0fPq3e4mpspvyndLh1a+OarHa1e
-aT0DIIYk7qeEa1YcVljx2KyLd0r1BBAfrwyGaEPVeJQVYWaOJRU2we/KD4ojf9s=
+MIICnDCCAgWgAwIBAgIBBzANBgkqhkiG9w0BAQsFADBWMQswCQYDVQQGEwJBVTET
+MBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQ
+dHkgTHRkMQ8wDQYDVQQDEwZ0ZXN0Y2EwHhcNMTUxMTA0MDIyMDI0WhcNMjUxMTAx
+MDIyMDI0WjBlMQswCQYDVQQGEwJVUzERMA8GA1UECBMISWxsaW5vaXMxEDAOBgNV
+BAcTB0NoaWNhZ28xFTATBgNVBAoTDEV4YW1wbGUsIENvLjEaMBgGA1UEAxQRKi50
+ZXN0Lmdvb2dsZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAOHDFSco
+LCVJpYDDM4HYtIdV6Ake/sMNaaKdODjDMsux/4tDydlumN+fm+AjPEK5GHhGn1Bg
+zkWF+slf3BxhrA/8dNsnunstVA7ZBgA/5qQxMfGAq4wHNVX77fBZOgp9VlSMVfyd
+9N8YwbBYAckOeUQadTi2X1S6OgJXgQ0m3MWhAgMBAAGjazBpMAkGA1UdEwQCMAAw
+CwYDVR0PBAQDAgXgME8GA1UdEQRIMEaCECoudGVzdC5nb29nbGUuZnKCGHdhdGVy
+em9vaS50ZXN0Lmdvb2dsZS5iZYISKi50ZXN0LnlvdXR1YmUuY29thwTAqAEDMA0G
+CSqGSIb3DQEBCwUAA4GBAJFXVifQNub1LUP4JlnX5lXNlo8FxZ2a12AFQs+bzoJ6
+hM044EDjqyxUqSbVePK0ni3w1fHQB5rY9yYC5f8G7aqqTY1QOhoUk8ZTSTRpnkTh
+y4jjdvTZeLDVBlueZUTDRmy2feY5aZIU18vFDK08dTG0A87pppuv1LNIR3loveU8
 -----END CERTIFICATE-----
diff --git a/src/objective-c/GRPCClient/private/GRPCSecureChannel.h b/src/objective-c/GRPCClient/private/GRPCSecureChannel.h
index 4e0881e..b82b9fe 100644
--- a/src/objective-c/GRPCClient/private/GRPCSecureChannel.h
+++ b/src/objective-c/GRPCClient/private/GRPCSecureChannel.h
@@ -35,7 +35,7 @@
 
 #import "GRPCChannel.h"
 
-struct grpc_credentials;
+struct grpc_channel_credentials;
 
 @interface GRPCSecureChannel : GRPCChannel
 - (instancetype)initWithHost:(NSString *)host;
@@ -50,6 +50,6 @@
 
 /** The passed arguments aren't required to be valid beyond the invocation of this initializer. */
 - (instancetype)initWithHost:(NSString *)host
-                 credentials:(struct grpc_credentials *)credentials
+                 credentials:(struct grpc_channel_credentials *)credentials
                         args:(grpc_channel_args *)args NS_DESIGNATED_INITIALIZER;
 @end
diff --git a/src/objective-c/GRPCClient/private/GRPCSecureChannel.m b/src/objective-c/GRPCClient/private/GRPCSecureChannel.m
index ce16655..a573c17 100644
--- a/src/objective-c/GRPCClient/private/GRPCSecureChannel.m
+++ b/src/objective-c/GRPCClient/private/GRPCSecureChannel.m
@@ -37,7 +37,7 @@
 
 // Returns NULL if the file at path couldn't be read. In that case, if errorPtr isn't NULL,
 // *errorPtr will be an object describing what went wrong.
-static grpc_credentials *CertificatesAtPath(NSString *path, NSError **errorPtr) {
+static grpc_channel_credentials *CertificatesAtPath(NSString *path, NSError **errorPtr) {
   // Files in PEM format can have non-ASCII characters in their comments (e.g. for the name of the
   // issuer). Load them as UTF8 and produce an ASCII equivalent.
   NSString *contentInUTF8 = [NSString stringWithContentsOfFile:path
@@ -62,7 +62,7 @@
           pathToCertificates:(NSString *)path
             hostNameOverride:(NSString *)hostNameOverride {
   // Load default SSL certificates once.
-  static grpc_credentials *kDefaultCertificates;
+  static grpc_channel_credentials *kDefaultCertificates;
   static dispatch_once_t loading;
   dispatch_once(&loading, ^{
     NSString *defaultPath = @"gRPCCertificates.bundle/roots"; // .pem
@@ -79,7 +79,9 @@
   });
 
   //TODO(jcanizales): Add NSError** parameter to the initializer.
-  grpc_credentials *certificates = path ? CertificatesAtPath(path, NULL) : kDefaultCertificates;
+  grpc_channel_credentials *certificates = path
+      ? CertificatesAtPath(path, NULL)
+      : kDefaultCertificates;
   if (!certificates) {
     return nil;
   }
@@ -99,7 +101,7 @@
 }
 
 - (instancetype)initWithHost:(NSString *)host
-                 credentials:(grpc_credentials *)credentials
+                 credentials:(grpc_channel_credentials *)credentials
                         args:(grpc_channel_args *)args {
   return (self = [super
               initWithChannel:grpc_secure_channel_create(
diff --git a/src/php/ext/grpc/call_credentials.c b/src/php/ext/grpc/call_credentials.c
new file mode 100644
index 0000000..17f167b
--- /dev/null
+++ b/src/php/ext/grpc/call_credentials.c
@@ -0,0 +1,138 @@
+/*
+ *
+ * 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 "channel_credentials.h"
+#include "call_credentials.h"
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <php.h>
+#include <php_ini.h>
+#include <ext/standard/info.h>
+#include <ext/spl/spl_exceptions.h>
+#include "php_grpc.h"
+
+#include <zend_exceptions.h>
+#include <zend_hash.h>
+
+#include <grpc/grpc.h>
+#include <grpc/grpc_security.h>
+
+zend_class_entry *grpc_ce_call_credentials;
+
+/* Frees and destroys an instance of wrapped_grpc_call_credentials */
+void free_wrapped_grpc_call_credentials(void *object TSRMLS_DC) {
+  wrapped_grpc_call_credentials *creds =
+      (wrapped_grpc_call_credentials *)object;
+  if (creds->wrapped != NULL) {
+    grpc_call_credentials_release(creds->wrapped);
+  }
+  efree(creds);
+}
+
+/* Initializes an instance of wrapped_grpc_call_credentials to be
+ * associated with an object of a class specified by class_type */
+zend_object_value create_wrapped_grpc_call_credentials(
+    zend_class_entry *class_type TSRMLS_DC) {
+  zend_object_value retval;
+  wrapped_grpc_call_credentials *intern;
+
+  intern = (wrapped_grpc_call_credentials *)emalloc(
+      sizeof(wrapped_grpc_call_credentials));
+  memset(intern, 0, sizeof(wrapped_grpc_call_credentials));
+
+  zend_object_std_init(&intern->std, class_type TSRMLS_CC);
+  object_properties_init(&intern->std, class_type);
+  retval.handle = zend_objects_store_put(
+      intern, (zend_objects_store_dtor_t)zend_objects_destroy_object,
+      free_wrapped_grpc_call_credentials, NULL TSRMLS_CC);
+  retval.handlers = zend_get_std_object_handlers();
+  return retval;
+}
+
+zval *grpc_php_wrap_call_credentials(grpc_call_credentials *wrapped) {
+  zval *credentials_object;
+  MAKE_STD_ZVAL(credentials_object);
+  object_init_ex(credentials_object, grpc_ce_call_credentials);
+  wrapped_grpc_call_credentials *credentials =
+      (wrapped_grpc_call_credentials *)zend_object_store_get_object(
+          credentials_object TSRMLS_CC);
+  credentials->wrapped = wrapped;
+  return credentials_object;
+}
+
+/**
+ * Create composite credentials from two existing credentials.
+ * @param CallCredentials cred1 The first credential
+ * @param CallCredentials cred2 The second credential
+ * @return CallCredentials The new composite credentials object
+ */
+PHP_METHOD(CallCredentials, createComposite) {
+  zval *cred1_obj;
+  zval *cred2_obj;
+
+  /* "OO" == 3 Objects */
+  if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "OO", &cred1_obj,
+                            grpc_ce_call_credentials, &cred2_obj,
+                            grpc_ce_call_credentials) == FAILURE) {
+    zend_throw_exception(spl_ce_InvalidArgumentException,
+                         "createComposite expects 2 CallCredentials",
+                         1 TSRMLS_CC);
+    return;
+  }
+  wrapped_grpc_call_credentials *cred1 =
+      (wrapped_grpc_call_credentials *)zend_object_store_get_object(
+          cred1_obj TSRMLS_CC);
+  wrapped_grpc_call_credentials *cred2 =
+      (wrapped_grpc_call_credentials *)zend_object_store_get_object(
+          cred2_obj TSRMLS_CC);
+  grpc_call_credentials *creds =
+      grpc_composite_call_credentials_create(cred1->wrapped, cred2->wrapped,
+                                             NULL);
+  zval *creds_object = grpc_php_wrap_call_credentials(creds);
+  RETURN_DESTROY_ZVAL(creds_object);
+}
+
+static zend_function_entry call_credentials_methods[] = {
+  PHP_ME(CallCredentials, createComposite, NULL,
+         ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
+  PHP_FE_END};
+
+void grpc_init_call_credentials(TSRMLS_D) {
+  zend_class_entry ce;
+  INIT_CLASS_ENTRY(ce, "Grpc\\CallCredentials", call_credentials_methods);
+  ce.create_object = create_wrapped_grpc_call_credentials;
+  grpc_ce_call_credentials = zend_register_internal_class(&ce TSRMLS_CC);
+}
diff --git a/src/php/ext/grpc/credentials.h b/src/php/ext/grpc/call_credentials.h
similarity index 76%
rename from src/php/ext/grpc/credentials.h
rename to src/php/ext/grpc/call_credentials.h
index 86d7ae5..8f35ac6 100755
--- a/src/php/ext/grpc/credentials.h
+++ b/src/php/ext/grpc/call_credentials.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef NET_GRPC_PHP_GRPC_CREDENTIALS_H_
-#define NET_GRPC_PHP_GRPC_CREDENTIALS_H_
+#ifndef NET_GRPC_PHP_GRPC_CALL_CREDENTIALS_H_
+#define NET_GRPC_PHP_GRPC_CALL_CREDENTIALS_H_
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
@@ -46,18 +46,18 @@
 #include "grpc/grpc.h"
 #include "grpc/grpc_security.h"
 
-/* Class entry for the Credentials PHP class */
-extern zend_class_entry *grpc_ce_credentials;
+/* Class entry for the CallCredentials PHP class */
+extern zend_class_entry *grpc_ce_call_credentials;
 
-/* Wrapper struct for grpc_credentials that can be associated with a PHP
- * object */
-typedef struct wrapped_grpc_credentials {
+/* Wrapper struct for grpc_call_credentials that can be associated
+ * with a PHP object */
+typedef struct wrapped_grpc_call_credentials {
   zend_object std;
 
-  grpc_credentials *wrapped;
-} wrapped_grpc_credentials;
+  grpc_call_credentials *wrapped;
+} wrapped_grpc_call_credentials;
 
-/* Initializes the Credentials PHP class */
-void grpc_init_credentials(TSRMLS_D);
+/* Initializes the CallCredentials PHP class */
+void grpc_init_call_credentials(TSRMLS_D);
 
-#endif /* NET_GRPC_PHP_GRPC_CREDENTIALS_H_ */
+#endif /* NET_GRPC_PHP_GRPC_CALL_CREDENTIALS_H_ */
diff --git a/src/php/ext/grpc/channel.c b/src/php/ext/grpc/channel.c
index a4313b6..f8c4f04 100644
--- a/src/php/ext/grpc/channel.c
+++ b/src/php/ext/grpc/channel.c
@@ -52,7 +52,7 @@
 #include <grpc/grpc_security.h>
 
 #include "completion_queue.h"
-#include "credentials.h"
+#include "channel_credentials.h"
 #include "server.h"
 #include "timeval.h"
 
@@ -125,21 +125,22 @@
 
 /**
  * Construct an instance of the Channel class. If the $args array contains a
- * "credentials" key mapping to a Credentials object, a secure channel will be
- * created with those credentials.
+ * "credentials" key mapping to a ChannelCredentials object, a secure channel
+ * will be created with those credentials.
  * @param string $target The hostname to associate with this channel
  * @param array $args The arguments to pass to the Channel (optional)
  */
 PHP_METHOD(Channel, __construct) {
   wrapped_grpc_channel *channel =
-      (wrapped_grpc_channel *)zend_object_store_get_object(getThis() TSRMLS_CC);
+      (wrapped_grpc_channel *)zend_object_store_get_object(
+          getThis() TSRMLS_CC);
   char *target;
   int target_length;
   zval *args_array = NULL;
   grpc_channel_args args;
   HashTable *array_hash;
   zval **creds_obj = NULL;
-  wrapped_grpc_credentials *creds = NULL;
+  wrapped_grpc_channel_credentials *creds = NULL;
   /* "s|a" == 1 string, 1 optional array */
   if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|a", &target,
                             &target_length, &args_array) == FAILURE) {
@@ -153,13 +154,14 @@
     array_hash = Z_ARRVAL_P(args_array);
     if (zend_hash_find(array_hash, "credentials", sizeof("credentials"),
                        (void **)&creds_obj) == SUCCESS) {
-      if (zend_get_class_entry(*creds_obj TSRMLS_CC) != grpc_ce_credentials) {
+      if (zend_get_class_entry(*creds_obj TSRMLS_CC) !=
+          grpc_ce_channel_credentials) {
         zend_throw_exception(spl_ce_InvalidArgumentException,
-                             "credentials must be a Credentials object",
+                             "credentials must be a ChannelCredentials object",
                              1 TSRMLS_CC);
         return;
       }
-      creds = (wrapped_grpc_credentials *)zend_object_store_get_object(
+      creds = (wrapped_grpc_channel_credentials *)zend_object_store_get_object(
           *creds_obj TSRMLS_CC);
       zend_hash_del(array_hash, "credentials", 12);
     }
diff --git a/src/php/ext/grpc/channel_credentials.c b/src/php/ext/grpc/channel_credentials.c
new file mode 100644
index 0000000..df4a5d5
--- /dev/null
+++ b/src/php/ext/grpc/channel_credentials.c
@@ -0,0 +1,187 @@
+/*
+ *
+ * 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 "channel_credentials.h"
+#include "call_credentials.h"
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <php.h>
+#include <php_ini.h>
+#include <ext/standard/info.h>
+#include <ext/spl/spl_exceptions.h>
+#include "php_grpc.h"
+
+#include <zend_exceptions.h>
+#include <zend_hash.h>
+
+#include <grpc/grpc.h>
+#include <grpc/grpc_security.h>
+
+zend_class_entry *grpc_ce_channel_credentials;
+
+/* Frees and destroys an instance of wrapped_grpc_channel_credentials */
+void free_wrapped_grpc_channel_credentials(void *object TSRMLS_DC) {
+  wrapped_grpc_channel_credentials *creds =
+      (wrapped_grpc_channel_credentials *)object;
+  if (creds->wrapped != NULL) {
+    grpc_channel_credentials_release(creds->wrapped);
+  }
+  efree(creds);
+}
+
+/* Initializes an instance of wrapped_grpc_channel_credentials to be
+ * associated with an object of a class specified by class_type */
+zend_object_value create_wrapped_grpc_channel_credentials(
+    zend_class_entry *class_type TSRMLS_DC) {
+  zend_object_value retval;
+  wrapped_grpc_channel_credentials *intern;
+
+  intern = (wrapped_grpc_channel_credentials *)emalloc(
+      sizeof(wrapped_grpc_channel_credentials));
+  memset(intern, 0, sizeof(wrapped_grpc_channel_credentials));
+
+  zend_object_std_init(&intern->std, class_type TSRMLS_CC);
+  object_properties_init(&intern->std, class_type);
+  retval.handle = zend_objects_store_put(
+      intern, (zend_objects_store_dtor_t)zend_objects_destroy_object,
+      free_wrapped_grpc_channel_credentials, NULL TSRMLS_CC);
+  retval.handlers = zend_get_std_object_handlers();
+  return retval;
+}
+
+zval *grpc_php_wrap_channel_credentials(grpc_channel_credentials *wrapped) {
+  zval *credentials_object;
+  MAKE_STD_ZVAL(credentials_object);
+  object_init_ex(credentials_object, grpc_ce_channel_credentials);
+  wrapped_grpc_channel_credentials *credentials =
+      (wrapped_grpc_channel_credentials *)zend_object_store_get_object(
+          credentials_object TSRMLS_CC);
+  credentials->wrapped = wrapped;
+  return credentials_object;
+}
+
+/**
+ * Create a default channel credentials object.
+ * @return ChannelCredentials The new default channel credentials object
+ */
+PHP_METHOD(ChannelCredentials, createDefault) {
+  grpc_channel_credentials *creds = grpc_google_default_credentials_create();
+  zval *creds_object = grpc_php_wrap_channel_credentials(creds);
+  RETURN_DESTROY_ZVAL(creds_object);
+}
+
+/**
+ * Create SSL credentials.
+ * @param string pem_root_certs PEM encoding of the server root certificates
+ * @param string pem_private_key PEM encoding of the client's private key
+ *     (optional)
+ * @param string pem_cert_chain PEM encoding of the client's certificate chain
+ *     (optional)
+ * @return ChannelCredentials The new SSL credentials object
+ */
+PHP_METHOD(ChannelCredentials, createSsl) {
+  char *pem_root_certs = NULL;
+  grpc_ssl_pem_key_cert_pair pem_key_cert_pair;
+
+  int root_certs_length = 0, private_key_length = 0, cert_chain_length = 0;
+
+  pem_key_cert_pair.private_key = pem_key_cert_pair.cert_chain = NULL;
+
+  /* "|s!s!s! == 3 optional nullable strings */
+  if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s!s!s!",
+                            &pem_root_certs, &root_certs_length,
+                            &pem_key_cert_pair.private_key,
+                            &private_key_length,
+                            &pem_key_cert_pair.cert_chain,
+                            &cert_chain_length) == FAILURE) {
+    zend_throw_exception(spl_ce_InvalidArgumentException,
+                         "createSsl expects 3 optional strings", 1 TSRMLS_CC);
+    return;
+  }
+  grpc_channel_credentials *creds = grpc_ssl_credentials_create(
+      pem_root_certs,
+      pem_key_cert_pair.private_key == NULL ? NULL : &pem_key_cert_pair, NULL);
+  zval *creds_object = grpc_php_wrap_channel_credentials(creds);
+  RETURN_DESTROY_ZVAL(creds_object);
+}
+
+/**
+ * Create composite credentials from two existing credentials.
+ * @param ChannelCredentials cred1 The first credential
+ * @param CallCredentials cred2 The second credential
+ * @return ChannelCredentials The new composite credentials object
+ */
+PHP_METHOD(ChannelCredentials, createComposite) {
+  zval *cred1_obj;
+  zval *cred2_obj;
+
+  /* "OO" == 3 Objects */
+  if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "OO", &cred1_obj,
+                            grpc_ce_channel_credentials, &cred2_obj,
+                            grpc_ce_call_credentials) == FAILURE) {
+    zend_throw_exception(spl_ce_InvalidArgumentException,
+                         "createComposite expects 2 Credentials", 1 TSRMLS_CC);
+    return;
+  }
+  wrapped_grpc_channel_credentials *cred1 =
+      (wrapped_grpc_channel_credentials *)zend_object_store_get_object(
+          cred1_obj TSRMLS_CC);
+  wrapped_grpc_call_credentials *cred2 =
+      (wrapped_grpc_call_credentials *)zend_object_store_get_object(
+          cred2_obj TSRMLS_CC);
+  grpc_channel_credentials *creds =
+      grpc_composite_channel_credentials_create(cred1->wrapped, cred2->wrapped,
+                                                NULL);
+  zval *creds_object = grpc_php_wrap_channel_credentials(creds);
+  RETURN_DESTROY_ZVAL(creds_object);
+}
+
+static zend_function_entry channel_credentials_methods[] = {
+  PHP_ME(ChannelCredentials, createDefault, NULL,
+         ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
+  PHP_ME(ChannelCredentials, createSsl, NULL,
+         ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
+  PHP_ME(ChannelCredentials, createComposite, NULL,
+         ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
+  PHP_FE_END};
+
+void grpc_init_channel_credentials(TSRMLS_D) {
+  zend_class_entry ce;
+  INIT_CLASS_ENTRY(ce, "Grpc\\ChannelCredentials",
+                   channel_credentials_methods);
+  ce.create_object = create_wrapped_grpc_channel_credentials;
+  grpc_ce_channel_credentials = zend_register_internal_class(&ce TSRMLS_CC);
+}
diff --git a/src/php/ext/grpc/credentials.h b/src/php/ext/grpc/channel_credentials.h
similarity index 75%
copy from src/php/ext/grpc/credentials.h
copy to src/php/ext/grpc/channel_credentials.h
index 86d7ae5..d89984c 100755
--- a/src/php/ext/grpc/credentials.h
+++ b/src/php/ext/grpc/channel_credentials.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef NET_GRPC_PHP_GRPC_CREDENTIALS_H_
-#define NET_GRPC_PHP_GRPC_CREDENTIALS_H_
+#ifndef NET_GRPC_PHP_GRPC_CHANNEL_CREDENTIALS_H_
+#define NET_GRPC_PHP_GRPC_CHANNEL_CREDENTIALS_H_
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
@@ -46,18 +46,18 @@
 #include "grpc/grpc.h"
 #include "grpc/grpc_security.h"
 
-/* Class entry for the Credentials PHP class */
-extern zend_class_entry *grpc_ce_credentials;
+/* Class entry for the ChannelCredentials PHP class */
+extern zend_class_entry *grpc_ce_channel_credentials;
 
-/* Wrapper struct for grpc_credentials that can be associated with a PHP
- * object */
-typedef struct wrapped_grpc_credentials {
+/* Wrapper struct for grpc_channel_credentials that can be associated
+ * with a PHP object */
+typedef struct wrapped_grpc_channel_credentials {
   zend_object std;
 
-  grpc_credentials *wrapped;
-} wrapped_grpc_credentials;
+  grpc_channel_credentials *wrapped;
+} wrapped_grpc_channel_credentials;
 
-/* Initializes the Credentials PHP class */
-void grpc_init_credentials(TSRMLS_D);
+/* Initializes the ChannelCredentials PHP class */
+void grpc_init_channel_credentials(TSRMLS_D);
 
-#endif /* NET_GRPC_PHP_GRPC_CREDENTIALS_H_ */
+#endif /* NET_GRPC_PHP_GRPC_CHANNEL_CREDENTIALS_H_ */
diff --git a/src/php/ext/grpc/config.m4 b/src/php/ext/grpc/config.m4
index 8bacdfb..7928687 100755
--- a/src/php/ext/grpc/config.m4
+++ b/src/php/ext/grpc/config.m4
@@ -71,5 +71,7 @@
 
   PHP_SUBST(GRPC_SHARED_LIBADD)
 
-  PHP_NEW_EXTENSION(grpc, byte_buffer.c call.c channel.c completion_queue.c credentials.c timeval.c server.c server_credentials.c php_grpc.c, $ext_shared, , -Wall -Werror -std=c11)
+  PHP_NEW_EXTENSION(grpc, byte_buffer.c call.c call_credentials.c channel.c \
+    channel_credentials.c completion_queue.c timeval.c server.c \
+    server_credentials.c php_grpc.c, $ext_shared, , -Wall -Werror -std=c11)
 fi
diff --git a/src/php/ext/grpc/credentials.c b/src/php/ext/grpc/credentials.c
deleted file mode 100644
index e413070..0000000
--- a/src/php/ext/grpc/credentials.c
+++ /dev/null
@@ -1,191 +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 "credentials.h"
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <php.h>
-#include <php_ini.h>
-#include <ext/standard/info.h>
-#include <ext/spl/spl_exceptions.h>
-#include "php_grpc.h"
-
-#include <zend_exceptions.h>
-#include <zend_hash.h>
-
-#include <grpc/grpc.h>
-#include <grpc/grpc_security.h>
-
-zend_class_entry *grpc_ce_credentials;
-
-/* Frees and destroys an instance of wrapped_grpc_credentials */
-void free_wrapped_grpc_credentials(void *object TSRMLS_DC) {
-  wrapped_grpc_credentials *creds = (wrapped_grpc_credentials *)object;
-  if (creds->wrapped != NULL) {
-    grpc_credentials_release(creds->wrapped);
-  }
-  efree(creds);
-}
-
-/* Initializes an instance of wrapped_grpc_credentials to be associated with an
- * object of a class specified by class_type */
-zend_object_value create_wrapped_grpc_credentials(zend_class_entry *class_type
-                                                      TSRMLS_DC) {
-  zend_object_value retval;
-  wrapped_grpc_credentials *intern;
-
-  intern =
-      (wrapped_grpc_credentials *)emalloc(sizeof(wrapped_grpc_credentials));
-  memset(intern, 0, sizeof(wrapped_grpc_credentials));
-
-  zend_object_std_init(&intern->std, class_type TSRMLS_CC);
-  object_properties_init(&intern->std, class_type);
-  retval.handle = zend_objects_store_put(
-      intern, (zend_objects_store_dtor_t)zend_objects_destroy_object,
-      free_wrapped_grpc_credentials, NULL TSRMLS_CC);
-  retval.handlers = zend_get_std_object_handlers();
-  return retval;
-}
-
-zval *grpc_php_wrap_credentials(grpc_credentials *wrapped) {
-  zval *credentials_object;
-  MAKE_STD_ZVAL(credentials_object);
-  object_init_ex(credentials_object, grpc_ce_credentials);
-  wrapped_grpc_credentials *credentials =
-      (wrapped_grpc_credentials *)zend_object_store_get_object(
-          credentials_object TSRMLS_CC);
-  credentials->wrapped = wrapped;
-  return credentials_object;
-}
-
-/**
- * Create a default credentials object.
- * @return Credentials The new default credentials object
- */
-PHP_METHOD(Credentials, createDefault) {
-  grpc_credentials *creds = grpc_google_default_credentials_create();
-  zval *creds_object = grpc_php_wrap_credentials(creds);
-  RETURN_DESTROY_ZVAL(creds_object);
-}
-
-/**
- * Create SSL credentials.
- * @param string pem_root_certs PEM encoding of the server root certificates
- * @param string pem_private_key PEM encoding of the client's private key
- *     (optional)
- * @param string pem_cert_chain PEM encoding of the client's certificate chain
- *     (optional)
- * @return Credentials The new SSL credentials object
- */
-PHP_METHOD(Credentials, createSsl) {
-  char *pem_root_certs = NULL;
-  grpc_ssl_pem_key_cert_pair pem_key_cert_pair;
-
-  int root_certs_length = 0, private_key_length = 0, cert_chain_length = 0;
-
-  pem_key_cert_pair.private_key = pem_key_cert_pair.cert_chain = NULL;
-
-  /* "|s!s!s! == 3 optional nullable strings */
-  if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s!s!s!",
-                            &pem_root_certs, &root_certs_length,
-                            &pem_key_cert_pair.private_key, &private_key_length,
-                            &pem_key_cert_pair.cert_chain,
-                            &cert_chain_length) == FAILURE) {
-    zend_throw_exception(spl_ce_InvalidArgumentException,
-                         "createSsl expects 3 optional strings", 1 TSRMLS_CC);
-    return;
-  }
-  grpc_credentials *creds = grpc_ssl_credentials_create(
-      pem_root_certs,
-      pem_key_cert_pair.private_key == NULL ? NULL : &pem_key_cert_pair, NULL);
-  zval *creds_object = grpc_php_wrap_credentials(creds);
-  RETURN_DESTROY_ZVAL(creds_object);
-}
-
-/**
- * Create composite credentials from two existing credentials.
- * @param Credentials cred1 The first credential
- * @param Credentials cred2 The second credential
- * @return Credentials The new composite credentials object
- */
-PHP_METHOD(Credentials, createComposite) {
-  zval *cred1_obj;
-  zval *cred2_obj;
-
-  /* "OO" == 3 Objects */
-  if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "OO", &cred1_obj,
-                            grpc_ce_credentials, &cred2_obj,
-                            grpc_ce_credentials) == FAILURE) {
-    zend_throw_exception(spl_ce_InvalidArgumentException,
-                         "createComposite expects 2 Credentials", 1 TSRMLS_CC);
-    return;
-  }
-  wrapped_grpc_credentials *cred1 =
-      (wrapped_grpc_credentials *)zend_object_store_get_object(
-          cred1_obj TSRMLS_CC);
-  wrapped_grpc_credentials *cred2 =
-      (wrapped_grpc_credentials *)zend_object_store_get_object(
-          cred2_obj TSRMLS_CC);
-  grpc_credentials *creds =
-      grpc_composite_credentials_create(cred1->wrapped, cred2->wrapped, NULL);
-  zval *creds_object = grpc_php_wrap_credentials(creds);
-  RETURN_DESTROY_ZVAL(creds_object);
-}
-
-/**
- * Create Google Compute Engine credentials
- * @return Credentials The new GCE credentials object
- */
-PHP_METHOD(Credentials, createGce) {
-  grpc_credentials *creds = grpc_google_compute_engine_credentials_create(NULL);
-  zval *creds_object = grpc_php_wrap_credentials(creds);
-  RETURN_DESTROY_ZVAL(creds_object);
-}
-
-static zend_function_entry credentials_methods[] = {
-    PHP_ME(Credentials, createDefault, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
-    PHP_ME(Credentials, createSsl, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
-    PHP_ME(Credentials, createComposite, NULL,
-           ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
-    PHP_ME(Credentials, createGce, NULL, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC)
-    PHP_FE_END};
-
-void grpc_init_credentials(TSRMLS_D) {
-  zend_class_entry ce;
-  INIT_CLASS_ENTRY(ce, "Grpc\\Credentials", credentials_methods);
-  ce.create_object = create_wrapped_grpc_credentials;
-  grpc_ce_credentials = zend_register_internal_class(&ce TSRMLS_CC);
-}
diff --git a/src/php/ext/grpc/package.xml b/src/php/ext/grpc/package.xml
index 921cfc6..a2e3e28 100644
--- a/src/php/ext/grpc/package.xml
+++ b/src/php/ext/grpc/package.xml
@@ -10,8 +10,8 @@
   <email>grpc-packages@google.com</email>
   <active>yes</active>
  </lead>
- <date>2015-10-07</date>
- <time>13:40:54</time>
+ <date>2015-10-21</date>
+ <time>17:04:32</time>
  <version>
   <release>0.6.1</release>
   <api>0.6.0</api>
@@ -30,16 +30,18 @@
    <file baseinstalldir="/" md5sum="c8de0f819499c48adfc8d7f472c0196b" name="byte_buffer.h" role="src" />
    <file baseinstalldir="/" md5sum="d64c9005993de02abac55664b0b9e0b2" name="call.c" role="src" />
    <file baseinstalldir="/" md5sum="26acbf04c30162c2d2aca4688bb2aec8" name="call.h" role="src" />
-   <file baseinstalldir="/" md5sum="15e56239b32c803f073e8a2b9f96e8c3" name="channel.c" role="src" />
+   <file baseinstalldir="/" md5sum="6fa13d260dfde216f795225644f04e7a" name="call_credentials.c" role="src" />
+   <file baseinstalldir="/" md5sum="e45269975f9a30fd349a90daf6b31aa2" name="call_credentials.h" role="src" />
+   <file baseinstalldir="/" md5sum="0779db3b196c98081b2260ceec22cd4d" name="channel.c" role="src" />
    <file baseinstalldir="/" md5sum="ed4b00c0cf3702b115d0cfa87450dc09" name="channel.h" role="src" />
+   <file baseinstalldir="/" md5sum="1b40f50fa6184ad7d24a961ac76151ff" name="channel_credentials.c" role="src" />
+   <file baseinstalldir="/" md5sum="a86250e03f610ce6c2c7595a84e08821" name="channel_credentials.h" role="src" />
    <file baseinstalldir="/" md5sum="55ab7a42f9dd9bfc7e28a61cfc5fca63" name="completion_queue.c" role="src" />
    <file baseinstalldir="/" md5sum="f10b5bb232d74a6878e829e2e76cdaa2" name="completion_queue.h" role="src" />
-   <file baseinstalldir="/" md5sum="a22f8eac0164761058cc4d9eb2ceb069" name="config.m4" role="src" />
-   <file baseinstalldir="/" md5sum="588752c908f7bc1663f7b8fc922ae661" name="credentials.c" role="src" />
-   <file baseinstalldir="/" md5sum="6988d6e97c19c8f8e3eb92371cf8246b" name="credentials.h" role="src" />
+   <file baseinstalldir="/" md5sum="c7bba7f0f00d1b1483de457d55311382" name="config.m4" role="src" />
    <file baseinstalldir="/" md5sum="38a1bc979d810c36ebc2a52d4b7b5319" name="CREDITS" role="doc" />
    <file baseinstalldir="/" md5sum="3f35b472bbdef5a788cd90617d7d0847" name="LICENSE" role="doc" />
-   <file baseinstalldir="/" md5sum="b77f1f3941aaf7a21090b493e9f26037" name="php_grpc.c" role="src" />
+   <file baseinstalldir="/" md5sum="3131a8af38fe5918e5409016b89d6cdb" name="php_grpc.c" role="src" />
    <file baseinstalldir="/" md5sum="673b07859d9f69232f8a754c56780686" name="php_grpc.h" role="src" />
    <file baseinstalldir="/" md5sum="7533a6d3ea02c78cad23a9651de0825d" name="README.md" role="doc" />
    <file baseinstalldir="/" md5sum="3e4e960454ebb2fc7b78a840493f5315" name="server.c" role="src" />
@@ -122,7 +124,7 @@
     <release>beta</release>
     <api>beta</api>
    </stability>
-   <date>2015-10-07</date>
+   <date>2015-10-21</date>
    <license>BSD</license>
    <notes>
 - fixed undefined constant fatal error when run with apache/nginx #2275
diff --git a/src/php/ext/grpc/php_grpc.c b/src/php/ext/grpc/php_grpc.c
index fcd94a6..762c013 100644
--- a/src/php/ext/grpc/php_grpc.c
+++ b/src/php/ext/grpc/php_grpc.c
@@ -35,7 +35,8 @@
 #include "channel.h"
 #include "server.h"
 #include "timeval.h"
-#include "credentials.h"
+#include "channel_credentials.h"
+#include "call_credentials.h"
 #include "server_credentials.h"
 #include "completion_queue.h"
 
@@ -233,7 +234,8 @@
   grpc_init_channel(TSRMLS_C);
   grpc_init_server(TSRMLS_C);
   grpc_init_timeval(TSRMLS_C);
-  grpc_init_credentials(TSRMLS_C);
+  grpc_init_channel_credentials(TSRMLS_C);
+  grpc_init_call_credentials(TSRMLS_C);
   grpc_init_server_credentials(TSRMLS_C);
   grpc_php_init_completion_queue(TSRMLS_C);
   return SUCCESS;
diff --git a/src/php/tests/data/server1.pem b/src/php/tests/data/server1.pem
index 8e582e5..f3d43fc 100755
--- a/src/php/tests/data/server1.pem
+++ b/src/php/tests/data/server1.pem
@@ -1,16 +1,16 @@
 -----BEGIN CERTIFICATE-----
-MIICmzCCAgSgAwIBAgIBAzANBgkqhkiG9w0BAQUFADBWMQswCQYDVQQGEwJBVTET
-MBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQ
-dHkgTHRkMQ8wDQYDVQQDDAZ0ZXN0Y2EwHhcNMTQwNzIyMDYwMDU3WhcNMjQwNzE5
-MDYwMDU3WjBkMQswCQYDVQQGEwJVUzERMA8GA1UECBMISWxsaW5vaXMxEDAOBgNV
-BAcTB0NoaWNhZ28xFDASBgNVBAoTC0dvb2dsZSBJbmMuMRowGAYDVQQDFBEqLnRl
-c3QuZ29vZ2xlLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA4cMVJygs
-JUmlgMMzgdi0h1XoCR7+ww1pop04OMMyy7H/i0PJ2W6Y35+b4CM8QrkYeEafUGDO
-RYX6yV/cHGGsD/x02ye6ey1UDtkGAD/mpDEx8YCrjAc1Vfvt8Fk6Cn1WVIxV/J30
-3xjBsFgByQ55RBp1OLZfVLo6AleBDSbcxaECAwEAAaNrMGkwCQYDVR0TBAIwADAL
-BgNVHQ8EBAMCBeAwTwYDVR0RBEgwRoIQKi50ZXN0Lmdvb2dsZS5mcoIYd2F0ZXJ6
-b29pLnRlc3QuZ29vZ2xlLmJlghIqLnRlc3QueW91dHViZS5jb22HBMCoAQMwDQYJ
-KoZIhvcNAQEFBQADgYEAM2Ii0LgTGbJ1j4oqX9bxVcxm+/R5Yf8oi0aZqTJlnLYS
-wXcBykxTx181s7WyfJ49WwrYXo78zTDAnf1ma0fPq3e4mpspvyndLh1a+OarHa1e
-aT0DIIYk7qeEa1YcVljx2KyLd0r1BBAfrwyGaEPVeJQVYWaOJRU2we/KD4ojf9s=
+MIICnDCCAgWgAwIBAgIBBzANBgkqhkiG9w0BAQsFADBWMQswCQYDVQQGEwJBVTET
+MBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQ
+dHkgTHRkMQ8wDQYDVQQDEwZ0ZXN0Y2EwHhcNMTUxMTA0MDIyMDI0WhcNMjUxMTAx
+MDIyMDI0WjBlMQswCQYDVQQGEwJVUzERMA8GA1UECBMISWxsaW5vaXMxEDAOBgNV
+BAcTB0NoaWNhZ28xFTATBgNVBAoTDEV4YW1wbGUsIENvLjEaMBgGA1UEAxQRKi50
+ZXN0Lmdvb2dsZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAOHDFSco
+LCVJpYDDM4HYtIdV6Ake/sMNaaKdODjDMsux/4tDydlumN+fm+AjPEK5GHhGn1Bg
+zkWF+slf3BxhrA/8dNsnunstVA7ZBgA/5qQxMfGAq4wHNVX77fBZOgp9VlSMVfyd
+9N8YwbBYAckOeUQadTi2X1S6OgJXgQ0m3MWhAgMBAAGjazBpMAkGA1UdEwQCMAAw
+CwYDVR0PBAQDAgXgME8GA1UdEQRIMEaCECoudGVzdC5nb29nbGUuZnKCGHdhdGVy
+em9vaS50ZXN0Lmdvb2dsZS5iZYISKi50ZXN0LnlvdXR1YmUuY29thwTAqAEDMA0G
+CSqGSIb3DQEBCwUAA4GBAJFXVifQNub1LUP4JlnX5lXNlo8FxZ2a12AFQs+bzoJ6
+hM044EDjqyxUqSbVePK0ni3w1fHQB5rY9yYC5f8G7aqqTY1QOhoUk8ZTSTRpnkTh
+y4jjdvTZeLDVBlueZUTDRmy2feY5aZIU18vFDK08dTG0A87pppuv1LNIR3loveU8
 -----END CERTIFICATE-----
diff --git a/src/php/tests/interop/interop_client.php b/src/php/tests/interop/interop_client.php
index 3019866..9aab5c9 100755
--- a/src/php/tests/interop/interop_client.php
+++ b/src/php/tests/interop/interop_client.php
@@ -423,10 +423,10 @@
 
 if ($use_tls) {
     if ($use_test_ca) {
-        $ssl_credentials = Grpc\Credentials::createSsl(
-        file_get_contents(dirname(__FILE__).'/../data/ca.pem'));
+        $ssl_credentials = Grpc\ChannelCredentials::createSsl(
+            file_get_contents(dirname(__FILE__).'/../data/ca.pem'));
     } else {
-        $ssl_credentials = Grpc\Credentials::createSsl();
+        $ssl_credentials = Grpc\ChannelCredentials::createSsl();
     }
     $opts['credentials'] = $ssl_credentials;
     $opts['grpc.ssl_target_name_override'] = $host_override;
diff --git a/src/php/tests/unit_tests/SecureEndToEndTest.php b/src/php/tests/unit_tests/SecureEndToEndTest.php
index e66bde3..c388ee5 100755
--- a/src/php/tests/unit_tests/SecureEndToEndTest.php
+++ b/src/php/tests/unit_tests/SecureEndToEndTest.php
@@ -35,7 +35,7 @@
 {
     public function setUp()
     {
-        $credentials = Grpc\Credentials::createSsl(
+        $credentials = Grpc\ChannelCredentials::createSsl(
             file_get_contents(dirname(__FILE__).'/../data/ca.pem'));
         $server_credentials = Grpc\ServerCredentials::createSsl(
             null,
diff --git a/src/python/grpcio/grpc/_adapter/_c/types.c b/src/python/grpcio/grpc/_adapter/_c/types.c
index 8855c32..8dedf59 100644
--- a/src/python/grpcio/grpc/_adapter/_c/types.c
+++ b/src/python/grpcio/grpc/_adapter/_c/types.c
@@ -40,7 +40,8 @@
 int pygrpc_module_add_types(PyObject *module) {
   int i;
   PyTypeObject *types[] = {
-      &pygrpc_ClientCredentials_type,
+      &pygrpc_CallCredentials_type,
+      &pygrpc_ChannelCredentials_type,
       &pygrpc_ServerCredentials_type,
       &pygrpc_CompletionQueue_type,
       &pygrpc_Call_type,
diff --git a/src/python/grpcio/grpc/_adapter/_c/types.h b/src/python/grpcio/grpc/_adapter/_c/types.h
index 31fd470..9ab415d 100644
--- a/src/python/grpcio/grpc/_adapter/_c/types.h
+++ b/src/python/grpcio/grpc/_adapter/_c/types.h
@@ -44,27 +44,35 @@
 /* Client-side credentials */
 /*=========================*/
 
-typedef struct ClientCredentials {
+typedef struct ChannelCredentials {
   PyObject_HEAD
-  grpc_credentials *c_creds;
-} ClientCredentials;
-void pygrpc_ClientCredentials_dealloc(ClientCredentials *self);
-ClientCredentials *pygrpc_ClientCredentials_google_default(
+  grpc_channel_credentials *c_creds;
+} ChannelCredentials;
+void pygrpc_ChannelCredentials_dealloc(ChannelCredentials *self);
+ChannelCredentials *pygrpc_ChannelCredentials_google_default(
     PyTypeObject *type, PyObject *ignored);
-ClientCredentials *pygrpc_ClientCredentials_ssl(
+ChannelCredentials *pygrpc_ChannelCredentials_ssl(
     PyTypeObject *type, PyObject *args, PyObject *kwargs);
-ClientCredentials *pygrpc_ClientCredentials_composite(
+ChannelCredentials *pygrpc_ChannelCredentials_composite(
     PyTypeObject *type, PyObject *args, PyObject *kwargs);
-ClientCredentials *pygrpc_ClientCredentials_compute_engine(
-    PyTypeObject *type, PyObject *ignored);
-ClientCredentials *pygrpc_ClientCredentials_jwt(
-    PyTypeObject *type, PyObject *args, PyObject *kwargs);
-ClientCredentials *pygrpc_ClientCredentials_refresh_token(
-    PyTypeObject *type, PyObject *args, PyObject *kwargs);
-ClientCredentials *pygrpc_ClientCredentials_iam(
-    PyTypeObject *type, PyObject *args, PyObject *kwargs);
-extern PyTypeObject pygrpc_ClientCredentials_type;
+extern PyTypeObject pygrpc_ChannelCredentials_type;
 
+typedef struct CallCredentials {
+  PyObject_HEAD
+  grpc_call_credentials *c_creds;
+} CallCredentials;
+void pygrpc_CallCredentials_dealloc(CallCredentials *self);
+CallCredentials *pygrpc_CallCredentials_composite(
+    PyTypeObject *type, PyObject *args, PyObject *kwargs);
+CallCredentials *pygrpc_CallCredentials_compute_engine(
+    PyTypeObject *type, PyObject *ignored);
+CallCredentials *pygrpc_CallCredentials_jwt(
+    PyTypeObject *type, PyObject *args, PyObject *kwargs);
+CallCredentials *pygrpc_CallCredentials_refresh_token(
+    PyTypeObject *type, PyObject *args, PyObject *kwargs);
+CallCredentials *pygrpc_CallCredentials_iam(
+    PyTypeObject *type, PyObject *args, PyObject *kwargs);
+extern PyTypeObject pygrpc_CallCredentials_type;
 
 /*=========================*/
 /* Server-side credentials */
diff --git a/src/python/grpcio/grpc/_adapter/_c/types/call.c b/src/python/grpcio/grpc/_adapter/_c/types/call.c
index 5604aba..04ec871 100644
--- a/src/python/grpcio/grpc/_adapter/_c/types/call.c
+++ b/src/python/grpcio/grpc/_adapter/_c/types/call.c
@@ -173,12 +173,12 @@
 }
 PyObject *pygrpc_Call_set_credentials(Call *self, PyObject *args,
                                       PyObject *kwargs) {
-  ClientCredentials *creds;
+  CallCredentials *creds;
   grpc_call_error errcode;
   static char *keywords[] = {"creds", NULL};
   if (!PyArg_ParseTupleAndKeywords(
       args, kwargs, "O!:set_credentials", keywords,
-      &pygrpc_ClientCredentials_type, &creds)) {
+      &pygrpc_CallCredentials_type, &creds)) {
     return NULL;
   }
   errcode = grpc_call_set_credentials(self->c_call, creds->c_creds);
diff --git a/src/python/grpcio/grpc/_adapter/_c/types/client_credentials.c b/src/python/grpcio/grpc/_adapter/_c/types/call_credentials.c
similarity index 66%
rename from src/python/grpcio/grpc/_adapter/_c/types/client_credentials.c
rename to src/python/grpcio/grpc/_adapter/_c/types/call_credentials.c
index 90652b7..5a15a6e 100644
--- a/src/python/grpcio/grpc/_adapter/_c/types/client_credentials.c
+++ b/src/python/grpcio/grpc/_adapter/_c/types/call_credentials.c
@@ -39,31 +39,28 @@
 #include <grpc/grpc_security.h>
 
 
-PyMethodDef pygrpc_ClientCredentials_methods[] = {
-    {"google_default", (PyCFunction)pygrpc_ClientCredentials_google_default,
+PyMethodDef pygrpc_CallCredentials_methods[] = {
+    {"composite", (PyCFunction)pygrpc_CallCredentials_composite,
+     METH_CLASS|METH_KEYWORDS, ""},
+    {"compute_engine", (PyCFunction)pygrpc_CallCredentials_compute_engine,
      METH_CLASS|METH_NOARGS, ""},
-    {"ssl", (PyCFunction)pygrpc_ClientCredentials_ssl,
+    {"jwt", (PyCFunction)pygrpc_CallCredentials_jwt,
      METH_CLASS|METH_KEYWORDS, ""},
-    {"composite", (PyCFunction)pygrpc_ClientCredentials_composite,
+    {"refresh_token", (PyCFunction)pygrpc_CallCredentials_refresh_token,
      METH_CLASS|METH_KEYWORDS, ""},
-    {"compute_engine", (PyCFunction)pygrpc_ClientCredentials_compute_engine,
-     METH_CLASS|METH_NOARGS, ""},
-    {"jwt", (PyCFunction)pygrpc_ClientCredentials_jwt,
-     METH_CLASS|METH_KEYWORDS, ""},
-    {"refresh_token", (PyCFunction)pygrpc_ClientCredentials_refresh_token,
-     METH_CLASS|METH_KEYWORDS, ""},
-    {"iam", (PyCFunction)pygrpc_ClientCredentials_iam,
+    {"iam", (PyCFunction)pygrpc_CallCredentials_iam,
      METH_CLASS|METH_KEYWORDS, ""},
     {NULL}
 };
-const char pygrpc_ClientCredentials_doc[] = "";
-PyTypeObject pygrpc_ClientCredentials_type = {
+
+const char pygrpc_CallCredentials_doc[] = "";
+PyTypeObject pygrpc_CallCredentials_type = {
     PyObject_HEAD_INIT(NULL)
     0,                                        /* ob_size */
-    "ClientCredentials",                      /* tp_name */
-    sizeof(ClientCredentials),                /* tp_basicsize */
+    "CallCredentials",                        /* tp_name */
+    sizeof(CallCredentials),                  /* tp_basicsize */
     0,                                        /* tp_itemsize */
-    (destructor)pygrpc_ClientCredentials_dealloc, /* tp_dealloc */
+    (destructor)pygrpc_CallCredentials_dealloc, /* tp_dealloc */
     0,                                        /* tp_print */
     0,                                        /* tp_getattr */
     0,                                        /* tp_setattr */
@@ -79,14 +76,14 @@
     0,                                        /* tp_setattro */
     0,                                        /* tp_as_buffer */
     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
-    pygrpc_ClientCredentials_doc,             /* tp_doc */
+    pygrpc_CallCredentials_doc,             /* tp_doc */
     0,                                        /* tp_traverse */
     0,                                        /* tp_clear */
     0,                                        /* tp_richcompare */
     0,                                        /* tp_weaklistoffset */
     0,                                        /* tp_iter */
     0,                                        /* tp_iternext */
-    pygrpc_ClientCredentials_methods,         /* tp_methods */
+    pygrpc_CallCredentials_methods,         /* tp_methods */
     0,                                        /* tp_members */
     0,                                        /* tp_getset */
     0,                                        /* tp_base */
@@ -99,67 +96,26 @@
     0                                         /* tp_new */
 };
 
-void pygrpc_ClientCredentials_dealloc(ClientCredentials *self) {
-  grpc_credentials_release(self->c_creds);
+void pygrpc_CallCredentials_dealloc(CallCredentials *self) {
+  grpc_call_credentials_release(self->c_creds);
   self->ob_type->tp_free((PyObject *)self);
 }
 
-ClientCredentials *pygrpc_ClientCredentials_google_default(
-    PyTypeObject *type, PyObject *ignored) {
-  ClientCredentials *self = (ClientCredentials *)type->tp_alloc(type, 0);
-  self->c_creds = grpc_google_default_credentials_create();
-  if (!self->c_creds) {
-    Py_DECREF(self);
-    PyErr_SetString(PyExc_RuntimeError,
-                    "couldn't create Google default credentials");
-    return NULL;
-  }
-  return self;
-}
-
-ClientCredentials *pygrpc_ClientCredentials_ssl(
+CallCredentials *pygrpc_CallCredentials_composite(
     PyTypeObject *type, PyObject *args, PyObject *kwargs) {
-  ClientCredentials *self;
-  const char *root_certs;
-  const char *private_key = NULL;
-  const char *cert_chain = NULL;
-  grpc_ssl_pem_key_cert_pair key_cert_pair;
-  static char *keywords[] = {"root_certs", "private_key", "cert_chain", NULL};
-  if (!PyArg_ParseTupleAndKeywords(args, kwargs, "z|zz:ssl", keywords,
-        &root_certs, &private_key, &cert_chain)) {
-    return NULL;
-  }
-  self = (ClientCredentials *)type->tp_alloc(type, 0);
-  if (private_key && cert_chain) {
-    key_cert_pair.private_key = private_key;
-    key_cert_pair.cert_chain = cert_chain;
-    self->c_creds =
-        grpc_ssl_credentials_create(root_certs, &key_cert_pair, NULL);
-  } else {
-    self->c_creds = grpc_ssl_credentials_create(root_certs, NULL, NULL);
-  }
-  if (!self->c_creds) {
-    Py_DECREF(self);
-    PyErr_SetString(PyExc_RuntimeError, "couldn't create ssl credentials");
-    return NULL;
-  }
-  return self;
-}
-
-ClientCredentials *pygrpc_ClientCredentials_composite(
-    PyTypeObject *type, PyObject *args, PyObject *kwargs) {
-  ClientCredentials *self;
-  ClientCredentials *creds1;
-  ClientCredentials *creds2;
+  CallCredentials *self;
+  CallCredentials *creds1;
+  CallCredentials *creds2;
   static char *keywords[] = {"creds1", "creds2", NULL};
   if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!O!:composite", keywords,
-        &pygrpc_ClientCredentials_type, &creds1,
-        &pygrpc_ClientCredentials_type, &creds2)) {
+        &pygrpc_CallCredentials_type, &creds1,
+        &pygrpc_CallCredentials_type, &creds2)) {
     return NULL;
   }
-  self = (ClientCredentials *)type->tp_alloc(type, 0);
+  self = (CallCredentials *)type->tp_alloc(type, 0);
   self->c_creds =
-      grpc_composite_credentials_create(creds1->c_creds, creds2->c_creds, NULL);
+      grpc_composite_call_credentials_create(
+          creds1->c_creds, creds2->c_creds, NULL);
   if (!self->c_creds) {
     Py_DECREF(self);
     PyErr_SetString(PyExc_RuntimeError, "couldn't create composite credentials");
@@ -168,9 +124,9 @@
   return self;
 }
 
-ClientCredentials *pygrpc_ClientCredentials_compute_engine(
+CallCredentials *pygrpc_CallCredentials_compute_engine(
     PyTypeObject *type, PyObject *ignored) {
-  ClientCredentials *self = (ClientCredentials *)type->tp_alloc(type, 0);
+  CallCredentials *self = (CallCredentials *)type->tp_alloc(type, 0);
   self->c_creds = grpc_google_compute_engine_credentials_create(NULL);
   if (!self->c_creds) {
     Py_DECREF(self);
@@ -182,9 +138,9 @@
 }
 
 /* TODO: Rename this credentials to something like service_account_jwt_access */
-ClientCredentials *pygrpc_ClientCredentials_jwt(
+CallCredentials *pygrpc_CallCredentials_jwt(
     PyTypeObject *type, PyObject *args, PyObject *kwargs) {
-  ClientCredentials *self;
+  CallCredentials *self;
   const char *json_key;
   double lifetime;
   static char *keywords[] = {"json_key", "token_lifetime", NULL};
@@ -192,7 +148,7 @@
         &json_key, &lifetime)) {
     return NULL;
   }
-  self = (ClientCredentials *)type->tp_alloc(type, 0);
+  self = (CallCredentials *)type->tp_alloc(type, 0);
   self->c_creds = grpc_service_account_jwt_access_credentials_create(
       json_key, pygrpc_cast_double_to_gpr_timespec(lifetime), NULL);
   if (!self->c_creds) {
@@ -203,16 +159,16 @@
   return self;
 }
 
-ClientCredentials *pygrpc_ClientCredentials_refresh_token(
+CallCredentials *pygrpc_CallCredentials_refresh_token(
     PyTypeObject *type, PyObject *args, PyObject *kwargs) {
-  ClientCredentials *self;
+  CallCredentials *self;
   const char *json_refresh_token;
   static char *keywords[] = {"json_refresh_token", NULL};
   if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s:refresh_token", keywords,
         &json_refresh_token)) {
     return NULL;
   }
-  self = (ClientCredentials *)type->tp_alloc(type, 0);
+  self = (CallCredentials *)type->tp_alloc(type, 0);
   self->c_creds =
       grpc_google_refresh_token_credentials_create(json_refresh_token, NULL);
   if (!self->c_creds) {
@@ -224,9 +180,9 @@
   return self;
 }
 
-ClientCredentials *pygrpc_ClientCredentials_iam(
+CallCredentials *pygrpc_CallCredentials_iam(
     PyTypeObject *type, PyObject *args, PyObject *kwargs) {
-  ClientCredentials *self;
+  CallCredentials *self;
   const char *authorization_token;
   const char *authority_selector;
   static char *keywords[] = {"authorization_token", "authority_selector", NULL};
@@ -234,7 +190,7 @@
         &authorization_token, &authority_selector)) {
     return NULL;
   }
-  self = (ClientCredentials *)type->tp_alloc(type, 0);
+  self = (CallCredentials *)type->tp_alloc(type, 0);
   self->c_creds = grpc_google_iam_credentials_create(authorization_token,
                                                      authority_selector, NULL);
   if (!self->c_creds) {
diff --git a/src/python/grpcio/grpc/_adapter/_c/types/channel.c b/src/python/grpcio/grpc/_adapter/_c/types/channel.c
index 79d39c4..c4db2a0 100644
--- a/src/python/grpcio/grpc/_adapter/_c/types/channel.c
+++ b/src/python/grpcio/grpc/_adapter/_c/types/channel.c
@@ -94,11 +94,11 @@
   Channel *self;
   const char *target;
   PyObject *py_args;
-  ClientCredentials *creds = NULL;
+  ChannelCredentials *creds = NULL;
   grpc_channel_args c_args;
   char *keywords[] = {"target", "args", "creds", NULL};
   if (!PyArg_ParseTupleAndKeywords(args, kwargs, "sO|O!:Channel", keywords,
-        &target, &py_args, &pygrpc_ClientCredentials_type, &creds)) {
+        &target, &py_args, &pygrpc_ChannelCredentials_type, &creds)) {
     return NULL;
   }
   if (!pygrpc_produce_channel_args(py_args, &c_args)) {
diff --git a/src/python/grpcio/grpc/_adapter/_c/types/channel_credentials.c b/src/python/grpcio/grpc/_adapter/_c/types/channel_credentials.c
new file mode 100644
index 0000000..83b1fc0
--- /dev/null
+++ b/src/python/grpcio/grpc/_adapter/_c/types/channel_credentials.c
@@ -0,0 +1,165 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "grpc/_adapter/_c/types.h"
+
+#define PY_SSIZE_T_CLEAN
+#include <Python.h>
+#include <grpc/grpc.h>
+#include <grpc/grpc_security.h>
+
+
+PyMethodDef pygrpc_ChannelCredentials_methods[] = {
+    {"google_default", (PyCFunction)pygrpc_ChannelCredentials_google_default,
+     METH_CLASS|METH_NOARGS, ""},
+    {"ssl", (PyCFunction)pygrpc_ChannelCredentials_ssl,
+     METH_CLASS|METH_KEYWORDS, ""},
+    {"composite", (PyCFunction)pygrpc_ChannelCredentials_composite,
+     METH_CLASS|METH_KEYWORDS, ""},
+    {NULL}
+};
+
+const char pygrpc_ChannelCredentials_doc[] = "";
+PyTypeObject pygrpc_ChannelCredentials_type = {
+    PyObject_HEAD_INIT(NULL)
+    0,                                        /* ob_size */
+    "ChannelCredentials",                     /* tp_name */
+    sizeof(ChannelCredentials),               /* tp_basicsize */
+    0,                                        /* tp_itemsize */
+    (destructor)pygrpc_ChannelCredentials_dealloc, /* tp_dealloc */
+    0,                                        /* tp_print */
+    0,                                        /* tp_getattr */
+    0,                                        /* tp_setattr */
+    0,                                        /* tp_compare */
+    0,                                        /* tp_repr */
+    0,                                        /* tp_as_number */
+    0,                                        /* tp_as_sequence */
+    0,                                        /* tp_as_mapping */
+    0,                                        /* tp_hash */
+    0,                                        /* tp_call */
+    0,                                        /* tp_str */
+    0,                                        /* tp_getattro */
+    0,                                        /* tp_setattro */
+    0,                                        /* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
+    pygrpc_ChannelCredentials_doc,             /* tp_doc */
+    0,                                        /* tp_traverse */
+    0,                                        /* tp_clear */
+    0,                                        /* tp_richcompare */
+    0,                                        /* tp_weaklistoffset */
+    0,                                        /* tp_iter */
+    0,                                        /* tp_iternext */
+    pygrpc_ChannelCredentials_methods,         /* tp_methods */
+    0,                                        /* tp_members */
+    0,                                        /* tp_getset */
+    0,                                        /* tp_base */
+    0,                                        /* tp_dict */
+    0,                                        /* tp_descr_get */
+    0,                                        /* tp_descr_set */
+    0,                                        /* tp_dictoffset */
+    0,                                        /* tp_init */
+    0,                                        /* tp_alloc */
+    0                                         /* tp_new */
+};
+
+void pygrpc_ChannelCredentials_dealloc(ChannelCredentials *self) {
+  grpc_channel_credentials_release(self->c_creds);
+  self->ob_type->tp_free((PyObject *)self);
+}
+
+ChannelCredentials *pygrpc_ChannelCredentials_google_default(
+    PyTypeObject *type, PyObject *ignored) {
+  ChannelCredentials *self = (ChannelCredentials *)type->tp_alloc(type, 0);
+  self->c_creds = grpc_google_default_credentials_create();
+  if (!self->c_creds) {
+    Py_DECREF(self);
+    PyErr_SetString(PyExc_RuntimeError,
+                    "couldn't create Google default credentials");
+    return NULL;
+  }
+  return self;
+}
+
+ChannelCredentials *pygrpc_ChannelCredentials_ssl(
+    PyTypeObject *type, PyObject *args, PyObject *kwargs) {
+  ChannelCredentials *self;
+  const char *root_certs;
+  const char *private_key = NULL;
+  const char *cert_chain = NULL;
+  grpc_ssl_pem_key_cert_pair key_cert_pair;
+  static char *keywords[] = {"root_certs", "private_key", "cert_chain", NULL};
+  if (!PyArg_ParseTupleAndKeywords(args, kwargs, "z|zz:ssl", keywords,
+        &root_certs, &private_key, &cert_chain)) {
+    return NULL;
+  }
+  self = (ChannelCredentials *)type->tp_alloc(type, 0);
+  if (private_key && cert_chain) {
+    key_cert_pair.private_key = private_key;
+    key_cert_pair.cert_chain = cert_chain;
+    self->c_creds =
+        grpc_ssl_credentials_create(root_certs, &key_cert_pair, NULL);
+  } else {
+    self->c_creds = grpc_ssl_credentials_create(root_certs, NULL, NULL);
+  }
+  if (!self->c_creds) {
+    Py_DECREF(self);
+    PyErr_SetString(PyExc_RuntimeError, "couldn't create ssl credentials");
+    return NULL;
+  }
+  return self;
+}
+
+ChannelCredentials *pygrpc_ChannelCredentials_composite(
+    PyTypeObject *type, PyObject *args, PyObject *kwargs) {
+  ChannelCredentials *self;
+  ChannelCredentials *creds1;
+  CallCredentials *creds2;
+  static char *keywords[] = {"creds1", "creds2", NULL};
+  if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!O!:composite", keywords,
+        &pygrpc_ChannelCredentials_type, &creds1,
+        &pygrpc_CallCredentials_type, &creds2)) {
+    return NULL;
+  }
+  self = (ChannelCredentials *)type->tp_alloc(type, 0);
+  self->c_creds =
+      grpc_composite_channel_credentials_create(
+          creds1->c_creds, creds2->c_creds, NULL);
+  if (!self->c_creds) {
+    Py_DECREF(self);
+    PyErr_SetString(
+        PyExc_RuntimeError, "couldn't create composite credentials");
+    return NULL;
+  }
+  return self;
+}
+
diff --git a/src/python/grpcio/grpc/_adapter/_intermediary_low.py b/src/python/grpcio/grpc/_adapter/_intermediary_low.py
index e2feec6..5634c20 100644
--- a/src/python/grpcio/grpc/_adapter/_intermediary_low.py
+++ b/src/python/grpcio/grpc/_adapter/_intermediary_low.py
@@ -253,10 +253,10 @@
 
 
 class ClientCredentials(object):
-  """Adapter from old _low.ClientCredentials interface to new _low.ClientCredentials."""
+  """Adapter from old _low.ClientCredentials interface to new _low.ChannelCredentials."""
 
   def __init__(self, root_certificates, private_key, certificate_chain):
-    self._internal = _low.ClientCredentials.ssl(root_certificates, private_key, certificate_chain)
+    self._internal = _low.ChannelCredentials.ssl(root_certificates, private_key, certificate_chain)
 
 
 class ServerCredentials(object):
diff --git a/src/python/grpcio/grpc/_adapter/_low.py b/src/python/grpcio/grpc/_adapter/_low.py
index 70ceb2a..57146aa 100644
--- a/src/python/grpcio/grpc/_adapter/_low.py
+++ b/src/python/grpcio/grpc/_adapter/_low.py
@@ -33,7 +33,8 @@
 
 _USER_AGENT = 'Python-gRPC-{}'.format(_grpcio_metadata.__version__)
 
-ClientCredentials = _c.ClientCredentials
+ChannelCredentials = _c.ChannelCredentials
+CallCredentials = _c.CallCredentials
 ServerCredentials = _c.ServerCredentials
 
 
diff --git a/src/python/grpcio/grpc/_adapter/_types.py b/src/python/grpcio/grpc/_adapter/_types.py
index 5470d2d..ca0fa06 100644
--- a/src/python/grpcio/grpc/_adapter/_types.py
+++ b/src/python/grpcio/grpc/_adapter/_types.py
@@ -323,6 +323,14 @@
     """
     return None
 
+  def set_credentials(self, creds):
+    """Set per-call credentials.
+
+    Args:
+      creds (CallCredentials): Credentials to be set for this call.
+    """
+    return None
+
 
 class Channel:
   __metaclass__ = abc.ABCMeta
@@ -334,7 +342,7 @@
     Args:
       target (str): ...
       args (sequence of 2-sequence of str, (str|integer)): ...
-      credentials (ClientCredentials): If None, create an insecure channel,
+      credentials (ChannelCredentials): If None, create an insecure channel,
         else create a secure channel using the client credentials.
     """
 
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/call.pyx b/src/python/grpcio/grpc/_cython/_cygrpc/call.pyx
index ed037b6..51c4668 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/call.pyx
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/call.pyx
@@ -29,6 +29,7 @@
 
 cimport cpython
 
+from grpc._cython._cygrpc cimport credentials
 from grpc._cython._cygrpc cimport grpc
 from grpc._cython._cygrpc cimport records
 
@@ -73,6 +74,11 @@
     else:
       return grpc.grpc_call_cancel(self.c_call, NULL)
 
+  def set_credentials(
+      self, credentials.CallCredentials call_credentials not None):
+    return grpc.grpc_call_set_credentials(
+        self.c_call, call_credentials.c_credentials)
+
   def __dealloc__(self):
     if self.c_call != NULL:
       grpc.grpc_call_destroy(self.c_call)
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx b/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx
index b52ddb6..e25db3e 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx
@@ -37,7 +37,7 @@
 cdef class Channel:
 
   def __cinit__(self, target, records.ChannelArgs arguments=None,
-                credentials.ClientCredentials client_credentials=None):
+                credentials.ChannelCredentials channel_credentials=None):
     cdef grpc.grpc_channel_args *c_arguments = NULL
     self.c_channel = NULL
     self.references = []
@@ -49,13 +49,13 @@
       target = target.encode()
     else:
       raise TypeError("expected target to be str or bytes")
-    if client_credentials is None:
+    if channel_credentials is None:
       self.c_channel = grpc.grpc_insecure_channel_create(target, c_arguments,
                                                          NULL)
     else:
       self.c_channel = grpc.grpc_secure_channel_create(
-          client_credentials.c_credentials, target, c_arguments, NULL)
-      self.references.append(client_credentials)
+          channel_credentials.c_credentials, target, c_arguments, NULL)
+      self.references.append(channel_credentials)
     self.references.append(target)
     self.references.append(arguments)
 
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pxd b/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pxd
index 6b74a26..7a9fa7b 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pxd
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pxd
@@ -30,13 +30,19 @@
 from grpc._cython._cygrpc cimport grpc
 
 
-cdef class ClientCredentials:
+cdef class ChannelCredentials:
 
-  cdef grpc.grpc_credentials *c_credentials
+  cdef grpc.grpc_channel_credentials *c_credentials
   cdef grpc.grpc_ssl_pem_key_cert_pair c_ssl_pem_key_cert_pair
   cdef list references
 
 
+cdef class CallCredentials:
+
+  cdef grpc.grpc_call_credentials *c_credentials
+  cdef list references
+
+
 cdef class ServerCredentials:
 
   cdef grpc.grpc_server_credentials *c_credentials
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx b/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx
index 608207f..e9836fe 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx
@@ -31,7 +31,7 @@
 from grpc._cython._cygrpc cimport records
 
 
-cdef class ClientCredentials:
+cdef class ChannelCredentials:
 
   def __cinit__(self):
     self.c_credentials = NULL
@@ -47,7 +47,24 @@
 
   def __dealloc__(self):
     if self.c_credentials != NULL:
-      grpc.grpc_credentials_release(self.c_credentials)
+      grpc.grpc_channel_credentials_release(self.c_credentials)
+
+
+cdef class CallCredentials:
+
+  def __cinit__(self):
+    self.c_credentials = NULL
+    self.references = []
+
+  # The object *can* be invalid in Python if we fail to make the credentials
+  # (and the core thus returns NULL credentials). Used primarily for debugging.
+  @property
+  def is_valid(self):
+    return self.c_credentials != NULL
+
+  def __dealloc__(self):
+    if self.c_credentials != NULL:
+      grpc.grpc_call_credentials_release(self.c_credentials)
 
 
 cdef class ServerCredentials:
@@ -60,12 +77,12 @@
       grpc.grpc_server_credentials_release(self.c_credentials)
 
 
-def client_credentials_google_default():
-  cdef ClientCredentials credentials = ClientCredentials();
+def channel_credentials_google_default():
+  cdef ChannelCredentials credentials = ChannelCredentials();
   credentials.c_credentials = grpc.grpc_google_default_credentials_create()
   return credentials
 
-def client_credentials_ssl(pem_root_certificates,
+def channel_credentials_ssl(pem_root_certificates,
                            records.SslPemKeyCertPair ssl_pem_key_cert_pair):
   if pem_root_certificates is None:
     pass
@@ -75,7 +92,7 @@
     pem_root_certificates = pem_root_certificates.encode()
   else:
     raise TypeError("expected str or bytes for pem_root_certificates")
-  cdef ClientCredentials credentials = ClientCredentials()
+  cdef ChannelCredentials credentials = ChannelCredentials()
   cdef const char *c_pem_root_certificates = NULL
   if pem_root_certificates is not None:
     c_pem_root_certificates = pem_root_certificates
@@ -88,26 +105,38 @@
     credentials.c_credentials = grpc.grpc_ssl_credentials_create(
       c_pem_root_certificates, NULL, NULL)
 
-def client_credentials_composite_credentials(
-    ClientCredentials credentials_1 not None,
-    ClientCredentials credentials_2 not None):
+def channel_credentials_composite(
+    ChannelCredentials credentials_1 not None,
+    CallCredentials credentials_2 not None):
   if not credentials_1.is_valid or not credentials_2.is_valid:
     raise ValueError("passed credentials must both be valid")
-  cdef ClientCredentials credentials = ClientCredentials()
-  credentials.c_credentials = grpc.grpc_composite_credentials_create(
+  cdef ChannelCredentials credentials = ChannelCredentials()
+  credentials.c_credentials = grpc.grpc_composite_channel_credentials_create(
       credentials_1.c_credentials, credentials_2.c_credentials, NULL)
   credentials.references.append(credentials_1)
   credentials.references.append(credentials_2)
   return credentials
 
-def client_credentials_google_compute_engine():
-  cdef ClientCredentials credentials = ClientCredentials()
+def call_credentials_composite(
+    CallCredentials credentials_1 not None,
+    CallCredentials credentials_2 not None):
+  if not credentials_1.is_valid or not credentials_2.is_valid:
+    raise ValueError("passed credentials must both be valid")
+  cdef CallCredentials credentials = CallCredentials()
+  credentials.c_credentials = grpc.grpc_composite_call_credentials_create(
+      credentials_1.c_credentials, credentials_2.c_credentials, NULL)
+  credentials.references.append(credentials_1)
+  credentials.references.append(credentials_2)
+  return credentials
+
+def call_credentials_google_compute_engine():
+  cdef CallCredentials credentials = CallCredentials()
   credentials.c_credentials = (
       grpc.grpc_google_compute_engine_credentials_create(NULL))
   return credentials
 
 #TODO rename to something like client_credentials_service_account_jwt_access.
-def client_credentials_service_account_jwt_access(
+def call_credentials_service_account_jwt_access(
     json_key, records.Timespec token_lifetime not None):
   if isinstance(json_key, bytes):
     pass
@@ -115,27 +144,27 @@
     json_key = json_key.encode()
   else:
     raise TypeError("expected json_key to be str or bytes")
-  cdef ClientCredentials credentials = ClientCredentials()
+  cdef CallCredentials credentials = CallCredentials()
   credentials.c_credentials = (
       grpc.grpc_service_account_jwt_access_credentials_create(
           json_key, token_lifetime.c_time, NULL))
   credentials.references.append(json_key)
   return credentials
 
-def client_credentials_google_refresh_token(json_refresh_token):
+def call_credentials_google_refresh_token(json_refresh_token):
   if isinstance(json_refresh_token, bytes):
     pass
   elif isinstance(json_refresh_token, basestring):
     json_refresh_token = json_refresh_token.encode()
   else:
     raise TypeError("expected json_refresh_token to be str or bytes")
-  cdef ClientCredentials credentials = ClientCredentials()
+  cdef CallCredentials credentials = CallCredentials()
   credentials.c_credentials = grpc.grpc_google_refresh_token_credentials_create(
       json_refresh_token, NULL)
   credentials.references.append(json_refresh_token)
   return credentials
 
-def client_credentials_google_iam(authorization_token, authority_selector):
+def call_credentials_google_iam(authorization_token, authority_selector):
   if isinstance(authorization_token, bytes):
     pass
   elif isinstance(authorization_token, basestring):
@@ -148,7 +177,7 @@
     authority_selector = authority_selector.encode()
   else:
     raise TypeError("expected authority_selector to be str or bytes")
-  cdef ClientCredentials credentials = ClientCredentials()
+  cdef CallCredentials credentials = CallCredentials()
   credentials.c_credentials = grpc.grpc_google_iam_credentials_create(
       authorization_token, authority_selector, NULL)
   credentials.references.append(authorization_token)
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxd b/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxd
index 62d40e7..36aea81 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxd
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxd
@@ -316,32 +316,40 @@
     const char *private_key
     const char *certificate_chain "cert_chain"
 
-  ctypedef struct grpc_credentials:
+  ctypedef struct grpc_channel_credentials:
     # We don't care about the internals (and in fact don't know them)
     pass
 
-  grpc_credentials *grpc_google_default_credentials_create()
-  grpc_credentials *grpc_ssl_credentials_create(
+  ctypedef struct grpc_call_credentials:
+    # We don't care about the internals (and in fact don't know them)
+    pass
+
+  grpc_channel_credentials *grpc_google_default_credentials_create()
+  grpc_channel_credentials *grpc_ssl_credentials_create(
       const char *pem_root_certs, grpc_ssl_pem_key_cert_pair *pem_key_cert_pair,
       void *reserved)
-
-  grpc_credentials *grpc_composite_credentials_create(grpc_credentials *creds1,
-                                                      grpc_credentials *creds2,
-                                                      void *reserved)
-  grpc_credentials *grpc_google_compute_engine_credentials_create(
+  grpc_channel_credentials *grpc_composite_channel_credentials_create(
+      grpc_channel_credentials *creds1, grpc_call_credentials *creds2,
       void *reserved)
-  grpc_credentials *grpc_service_account_jwt_access_credentials_create(
+  void grpc_channel_credentials_release(grpc_channel_credentials *creds)
+
+  grpc_call_credentials *grpc_composite_call_credentials_create(
+      grpc_call_credentials *creds1, grpc_call_credentials *creds2,
+      void *reserved)
+  grpc_call_credentials *grpc_google_compute_engine_credentials_create(
+      void *reserved)
+  grpc_call_credentials *grpc_service_account_jwt_access_credentials_create(
       const char *json_key,
       gpr_timespec token_lifetime, void *reserved)
-  grpc_credentials *grpc_google_refresh_token_credentials_create(
+  grpc_call_credentials *grpc_google_refresh_token_credentials_create(
       const char *json_refresh_token, void *reserved)
-  grpc_credentials *grpc_google_iam_credentials_create(
+  grpc_call_credentials *grpc_google_iam_credentials_create(
       const char *authorization_token, const char *authority_selector,
       void *reserved)
-  void grpc_credentials_release(grpc_credentials *creds)
+  void grpc_call_credentials_release(grpc_call_credentials *creds)
 
   grpc_channel *grpc_secure_channel_create(
-      grpc_credentials *creds, const char *target,
+      grpc_channel_credentials *creds, const char *target,
       const grpc_channel_args *args, void *reserved)
 
   ctypedef struct grpc_server_credentials:
@@ -358,4 +366,4 @@
                                         grpc_server_credentials *creds)
 
   grpc_call_error grpc_call_set_credentials(grpc_call *call,
-                                            grpc_credentials *creds)
+                                            grpc_call_credentials *creds)
diff --git a/src/python/grpcio/grpc/_cython/cygrpc.pyx b/src/python/grpcio/grpc/_cython/cygrpc.pyx
index 1ef2997..b20dda8 100644
--- a/src/python/grpcio/grpc/_cython/cygrpc.pyx
+++ b/src/python/grpcio/grpc/_cython/cygrpc.pyx
@@ -70,21 +70,24 @@
 
 Operations = records.Operations
 
-ClientCredentials = credentials.ClientCredentials
+CallCredentials = credentials.CallCredentials
+ChannelCredentials = credentials.ChannelCredentials
 ServerCredentials = credentials.ServerCredentials
 
-client_credentials_google_default = (
-    credentials.client_credentials_google_default)
-client_credentials_ssl = credentials.client_credentials_ssl
-client_credentials_composite_credentials = (
-    credentials.client_credentials_composite_credentials)
-client_credentials_google_compute_engine = (
-    credentials.client_credentials_google_compute_engine)
-client_credentials_jwt_access = (
-    credentials.client_credentials_service_account_jwt_access)
-client_credentials_refresh_token = (
-    credentials.client_credentials_google_refresh_token)
-client_credentials_google_iam = credentials.client_credentials_google_iam
+channel_credentials_google_default = (
+    credentials.channel_credentials_google_default)
+channel_credentials_ssl = credentials.channel_credentials_ssl
+channel_credentials_composite = (
+    credentials.channel_credentials_composite)
+call_credentials_composite = (
+    credentials.call_credentials_composite)
+call_credentials_google_compute_engine = (
+    credentials.call_credentials_google_compute_engine)
+call_credentials_jwt_access = (
+    credentials.call_credentials_service_account_jwt_access)
+call_credentials_refresh_token = (
+    credentials.call_credentials_google_refresh_token)
+call_credentials_google_iam = credentials.call_credentials_google_iam
 server_credentials_ssl = credentials.server_credentials_ssl
 
 CompletionQueue = completion_queue.CompletionQueue
diff --git a/src/python/grpcio/grpc/beta/interfaces.py b/src/python/grpcio/grpc/beta/interfaces.py
index 07c8618..d4ca565 100644
--- a/src/python/grpcio/grpc/beta/interfaces.py
+++ b/src/python/grpcio/grpc/beta/interfaces.py
@@ -100,8 +100,11 @@
     disable_compression: A boolean indicating whether or not compression should
       be disabled for the request object of the RPC. Only valid for
       request-unary RPCs.
-    credentials: A ClientCredentials object to use for the invoked RPC.
+    credentials: Reserved for gRPC per-call credentials. The type for this does
+      not exist yet at the Python level.
   """
+  if credentials is not None:
+    raise ValueError('`credentials` is a reserved argument')
   return GRPCCallOptions(disable_compression, None, credentials)
 
 
diff --git a/src/python/grpcio/grpc/framework/interfaces/face/face.py b/src/python/grpcio/grpc/framework/interfaces/face/face.py
index bc9a434..3b40235 100644
--- a/src/python/grpcio/grpc/framework/interfaces/face/face.py
+++ b/src/python/grpcio/grpc/framework/interfaces/face/face.py
@@ -117,6 +117,10 @@
     self.code = code
     self.details = details
 
+  def __str__(self):
+    return '%s(code=%s, details="%s")' % (
+        self.__class__.__name__, self.code, self.details)
+
 
 class CancellationError(AbortionError):
   """Indicates that an RPC has been cancelled."""
diff --git a/src/python/grpcio/setup.py b/src/python/grpcio/setup.py
index 97fa4fe..ec68eb6 100644
--- a/src/python/grpcio/setup.py
+++ b/src/python/grpcio/setup.py
@@ -52,7 +52,8 @@
     'grpc/_adapter/_c/module.c',
     'grpc/_adapter/_c/types.c',
     'grpc/_adapter/_c/utility.c',
-    'grpc/_adapter/_c/types/client_credentials.c',
+    'grpc/_adapter/_c/types/call_credentials.c',
+    'grpc/_adapter/_c/types/channel_credentials.c',
     'grpc/_adapter/_c/types/server_credentials.c',
     'grpc/_adapter/_c/types/completion_queue.c',
     'grpc/_adapter/_c/types/call.c',
diff --git a/src/python/grpcio_test/grpc_interop/credentials/server1.pem b/src/python/grpcio_test/grpc_interop/credentials/server1.pem
index 8e582e5..f3d43fc 100755
--- a/src/python/grpcio_test/grpc_interop/credentials/server1.pem
+++ b/src/python/grpcio_test/grpc_interop/credentials/server1.pem
@@ -1,16 +1,16 @@
 -----BEGIN CERTIFICATE-----
-MIICmzCCAgSgAwIBAgIBAzANBgkqhkiG9w0BAQUFADBWMQswCQYDVQQGEwJBVTET
-MBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQ
-dHkgTHRkMQ8wDQYDVQQDDAZ0ZXN0Y2EwHhcNMTQwNzIyMDYwMDU3WhcNMjQwNzE5
-MDYwMDU3WjBkMQswCQYDVQQGEwJVUzERMA8GA1UECBMISWxsaW5vaXMxEDAOBgNV
-BAcTB0NoaWNhZ28xFDASBgNVBAoTC0dvb2dsZSBJbmMuMRowGAYDVQQDFBEqLnRl
-c3QuZ29vZ2xlLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA4cMVJygs
-JUmlgMMzgdi0h1XoCR7+ww1pop04OMMyy7H/i0PJ2W6Y35+b4CM8QrkYeEafUGDO
-RYX6yV/cHGGsD/x02ye6ey1UDtkGAD/mpDEx8YCrjAc1Vfvt8Fk6Cn1WVIxV/J30
-3xjBsFgByQ55RBp1OLZfVLo6AleBDSbcxaECAwEAAaNrMGkwCQYDVR0TBAIwADAL
-BgNVHQ8EBAMCBeAwTwYDVR0RBEgwRoIQKi50ZXN0Lmdvb2dsZS5mcoIYd2F0ZXJ6
-b29pLnRlc3QuZ29vZ2xlLmJlghIqLnRlc3QueW91dHViZS5jb22HBMCoAQMwDQYJ
-KoZIhvcNAQEFBQADgYEAM2Ii0LgTGbJ1j4oqX9bxVcxm+/R5Yf8oi0aZqTJlnLYS
-wXcBykxTx181s7WyfJ49WwrYXo78zTDAnf1ma0fPq3e4mpspvyndLh1a+OarHa1e
-aT0DIIYk7qeEa1YcVljx2KyLd0r1BBAfrwyGaEPVeJQVYWaOJRU2we/KD4ojf9s=
+MIICnDCCAgWgAwIBAgIBBzANBgkqhkiG9w0BAQsFADBWMQswCQYDVQQGEwJBVTET
+MBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQ
+dHkgTHRkMQ8wDQYDVQQDEwZ0ZXN0Y2EwHhcNMTUxMTA0MDIyMDI0WhcNMjUxMTAx
+MDIyMDI0WjBlMQswCQYDVQQGEwJVUzERMA8GA1UECBMISWxsaW5vaXMxEDAOBgNV
+BAcTB0NoaWNhZ28xFTATBgNVBAoTDEV4YW1wbGUsIENvLjEaMBgGA1UEAxQRKi50
+ZXN0Lmdvb2dsZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAOHDFSco
+LCVJpYDDM4HYtIdV6Ake/sMNaaKdODjDMsux/4tDydlumN+fm+AjPEK5GHhGn1Bg
+zkWF+slf3BxhrA/8dNsnunstVA7ZBgA/5qQxMfGAq4wHNVX77fBZOgp9VlSMVfyd
+9N8YwbBYAckOeUQadTi2X1S6OgJXgQ0m3MWhAgMBAAGjazBpMAkGA1UdEwQCMAAw
+CwYDVR0PBAQDAgXgME8GA1UdEQRIMEaCECoudGVzdC5nb29nbGUuZnKCGHdhdGVy
+em9vaS50ZXN0Lmdvb2dsZS5iZYISKi50ZXN0LnlvdXR1YmUuY29thwTAqAEDMA0G
+CSqGSIb3DQEBCwUAA4GBAJFXVifQNub1LUP4JlnX5lXNlo8FxZ2a12AFQs+bzoJ6
+hM044EDjqyxUqSbVePK0ni3w1fHQB5rY9yYC5f8G7aqqTY1QOhoUk8ZTSTRpnkTh
+y4jjdvTZeLDVBlueZUTDRmy2feY5aZIU18vFDK08dTG0A87pppuv1LNIR3loveU8
 -----END CERTIFICATE-----
diff --git a/src/python/grpcio_test/grpc_test/beta/_beta_features_test.py b/src/python/grpcio_test/grpc_test/beta/_beta_features_test.py
index fad57da..5916a9e 100644
--- a/src/python/grpcio_test/grpc_test/beta/_beta_features_test.py
+++ b/src/python/grpcio_test/grpc_test/beta/_beta_features_test.py
@@ -181,24 +181,21 @@
     self._server.stop(test_constants.SHORT_TIMEOUT).wait()
 
   def test_unary_unary(self):
-    call_options = interfaces.grpc_call_options(
-        disable_compression=True, credentials=self._client_credentials)
+    call_options = interfaces.grpc_call_options(disable_compression=True)
     response = getattr(self._dynamic_stub, _UNARY_UNARY)(
         _REQUEST, test_constants.LONG_TIMEOUT, protocol_options=call_options)
     self.assertEqual(_RESPONSE, response)
     self.assertIsNotNone(self._servicer.peer())
 
   def test_unary_stream(self):
-    call_options = interfaces.grpc_call_options(
-        disable_compression=True, credentials=self._client_credentials)
+    call_options = interfaces.grpc_call_options(disable_compression=True)
     response_iterator = getattr(self._dynamic_stub, _UNARY_STREAM)(
         _REQUEST, test_constants.LONG_TIMEOUT, protocol_options=call_options)
     self._servicer.block_until_serviced()
     self.assertIsNotNone(self._servicer.peer())
 
   def test_stream_unary(self):
-    call_options = interfaces.grpc_call_options(
-        credentials=self._client_credentials)
+    call_options = interfaces.grpc_call_options()
     request_iterator = _BlockingIterator(iter((_REQUEST,)))
     response_future = getattr(self._dynamic_stub, _STREAM_UNARY).future(
         request_iterator, test_constants.LONG_TIMEOUT,
@@ -212,8 +209,7 @@
     self.assertEqual(_RESPONSE, response_future.result())
 
   def test_stream_stream(self):
-    call_options = interfaces.grpc_call_options(
-        credentials=self._client_credentials)
+    call_options = interfaces.grpc_call_options()
     request_iterator = _BlockingIterator(iter((_REQUEST,)))
     response_iterator = getattr(self._dynamic_stub, _STREAM_STREAM)(
         request_iterator, test_constants.SHORT_TIMEOUT,
diff --git a/src/python/grpcio_test/grpc_test/credentials/server1.pem b/src/python/grpcio_test/grpc_test/credentials/server1.pem
index 8e582e5..f3d43fc 100755
--- a/src/python/grpcio_test/grpc_test/credentials/server1.pem
+++ b/src/python/grpcio_test/grpc_test/credentials/server1.pem
@@ -1,16 +1,16 @@
 -----BEGIN CERTIFICATE-----
-MIICmzCCAgSgAwIBAgIBAzANBgkqhkiG9w0BAQUFADBWMQswCQYDVQQGEwJBVTET
-MBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQ
-dHkgTHRkMQ8wDQYDVQQDDAZ0ZXN0Y2EwHhcNMTQwNzIyMDYwMDU3WhcNMjQwNzE5
-MDYwMDU3WjBkMQswCQYDVQQGEwJVUzERMA8GA1UECBMISWxsaW5vaXMxEDAOBgNV
-BAcTB0NoaWNhZ28xFDASBgNVBAoTC0dvb2dsZSBJbmMuMRowGAYDVQQDFBEqLnRl
-c3QuZ29vZ2xlLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA4cMVJygs
-JUmlgMMzgdi0h1XoCR7+ww1pop04OMMyy7H/i0PJ2W6Y35+b4CM8QrkYeEafUGDO
-RYX6yV/cHGGsD/x02ye6ey1UDtkGAD/mpDEx8YCrjAc1Vfvt8Fk6Cn1WVIxV/J30
-3xjBsFgByQ55RBp1OLZfVLo6AleBDSbcxaECAwEAAaNrMGkwCQYDVR0TBAIwADAL
-BgNVHQ8EBAMCBeAwTwYDVR0RBEgwRoIQKi50ZXN0Lmdvb2dsZS5mcoIYd2F0ZXJ6
-b29pLnRlc3QuZ29vZ2xlLmJlghIqLnRlc3QueW91dHViZS5jb22HBMCoAQMwDQYJ
-KoZIhvcNAQEFBQADgYEAM2Ii0LgTGbJ1j4oqX9bxVcxm+/R5Yf8oi0aZqTJlnLYS
-wXcBykxTx181s7WyfJ49WwrYXo78zTDAnf1ma0fPq3e4mpspvyndLh1a+OarHa1e
-aT0DIIYk7qeEa1YcVljx2KyLd0r1BBAfrwyGaEPVeJQVYWaOJRU2we/KD4ojf9s=
+MIICnDCCAgWgAwIBAgIBBzANBgkqhkiG9w0BAQsFADBWMQswCQYDVQQGEwJBVTET
+MBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQ
+dHkgTHRkMQ8wDQYDVQQDEwZ0ZXN0Y2EwHhcNMTUxMTA0MDIyMDI0WhcNMjUxMTAx
+MDIyMDI0WjBlMQswCQYDVQQGEwJVUzERMA8GA1UECBMISWxsaW5vaXMxEDAOBgNV
+BAcTB0NoaWNhZ28xFTATBgNVBAoTDEV4YW1wbGUsIENvLjEaMBgGA1UEAxQRKi50
+ZXN0Lmdvb2dsZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAOHDFSco
+LCVJpYDDM4HYtIdV6Ake/sMNaaKdODjDMsux/4tDydlumN+fm+AjPEK5GHhGn1Bg
+zkWF+slf3BxhrA/8dNsnunstVA7ZBgA/5qQxMfGAq4wHNVX77fBZOgp9VlSMVfyd
+9N8YwbBYAckOeUQadTi2X1S6OgJXgQ0m3MWhAgMBAAGjazBpMAkGA1UdEwQCMAAw
+CwYDVR0PBAQDAgXgME8GA1UdEQRIMEaCECoudGVzdC5nb29nbGUuZnKCGHdhdGVy
+em9vaS50ZXN0Lmdvb2dsZS5iZYISKi50ZXN0LnlvdXR1YmUuY29thwTAqAEDMA0G
+CSqGSIb3DQEBCwUAA4GBAJFXVifQNub1LUP4JlnX5lXNlo8FxZ2a12AFQs+bzoJ6
+hM044EDjqyxUqSbVePK0ni3w1fHQB5rY9yYC5f8G7aqqTY1QOhoUk8ZTSTRpnkTh
+y4jjdvTZeLDVBlueZUTDRmy2feY5aZIU18vFDK08dTG0A87pppuv1LNIR3loveU8
 -----END CERTIFICATE-----
diff --git a/src/ruby/bin/apis/pubsub_demo.rb b/src/ruby/bin/apis/pubsub_demo.rb
index a039d03..003e91a 100755
--- a/src/ruby/bin/apis/pubsub_demo.rb
+++ b/src/ruby/bin/apis/pubsub_demo.rb
@@ -66,7 +66,7 @@
 
 # creates a SSL Credentials from the production certificates.
 def ssl_creds
-  GRPC::Core::Credentials.new(load_prod_cert)
+  GRPC::Core::ChannelCredentials.new(load_prod_cert)
 end
 
 # Builds the metadata authentication update proc.
diff --git a/src/ruby/bin/math_client.rb b/src/ruby/bin/math_client.rb
index 0ebd26f..d7e00e4 100755
--- a/src/ruby/bin/math_client.rb
+++ b/src/ruby/bin/math_client.rb
@@ -102,7 +102,7 @@
 
 def test_creds
   certs = load_test_certs
-  GRPC::Core::Credentials.new(certs[0])
+  GRPC::Core::ChannelCredentials.new(certs[0])
 end
 
 def main
diff --git a/src/ruby/bin/noproto_client.rb b/src/ruby/bin/noproto_client.rb
index 390a9c5..3aa1187 100755
--- a/src/ruby/bin/noproto_client.rb
+++ b/src/ruby/bin/noproto_client.rb
@@ -68,7 +68,7 @@
 
 def test_creds
   certs = load_test_certs
-  GRPC::Core::Credentials.new(certs[0])
+  GRPC::Core::ChannelCredentials.new(certs[0])
 end
 
 def main
diff --git a/src/ruby/ext/grpc/rb_channel.c b/src/ruby/ext/grpc/rb_channel.c
index cd0b966..d5d8242 100644
--- a/src/ruby/ext/grpc/rb_channel.c
+++ b/src/ruby/ext/grpc/rb_channel.c
@@ -41,8 +41,8 @@
 #include "rb_grpc.h"
 #include "rb_call.h"
 #include "rb_channel_args.h"
+#include "rb_channel_credentials.h"
 #include "rb_completion_queue.h"
-#include "rb_credentials.h"
 #include "rb_server.h"
 
 /* id_channel is the name of the hidden ivar that preserves a reference to the
@@ -136,8 +136,8 @@
   VALUE credentials = Qnil;
   VALUE target = Qnil;
   grpc_rb_channel *wrapper = NULL;
-  grpc_credentials *creds = NULL;
   grpc_channel *ch = NULL;
+  grpc_channel_credentials *creds = NULL;
   char *target_chars = NULL;
   grpc_channel_args args;
   MEMZERO(&args, grpc_channel_args, 1);
@@ -151,7 +151,7 @@
   if (credentials == Qnil) {
     ch = grpc_insecure_channel_create(target_chars, &args, NULL);
   } else {
-    creds = grpc_rb_get_wrapped_credentials(credentials);
+    creds = grpc_rb_get_wrapped_channel_credentials(credentials);
     ch = grpc_secure_channel_create(creds, target_chars, &args, NULL);
   }
   if (args.args != NULL) {
diff --git a/src/ruby/ext/grpc/rb_channel_credentials.c b/src/ruby/ext/grpc/rb_channel_credentials.c
new file mode 100644
index 0000000..072a6f5
--- /dev/null
+++ b/src/ruby/ext/grpc/rb_channel_credentials.c
@@ -0,0 +1,228 @@
+/*
+ *
+ * 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 "rb_channel_credentials.h"
+
+#include <ruby/ruby.h>
+
+#include <grpc/grpc.h>
+#include <grpc/grpc_security.h>
+
+#include "rb_grpc.h"
+
+/* grpc_rb_cChannelCredentials is the ruby class that proxies
+   grpc_channel_credentials. */
+static VALUE grpc_rb_cChannelCredentials = Qnil;
+
+/* grpc_rb_channel_credentials wraps a grpc_channel_credentials.  It provides a
+ * peer ruby object, 'mark' to minimize copying when a credential is
+ * created from ruby. */
+typedef struct grpc_rb_channel_credentials {
+  /* Holder of ruby objects involved in constructing the credentials */
+  VALUE mark;
+
+  /* The actual credentials */
+  grpc_channel_credentials *wrapped;
+} grpc_rb_channel_credentials;
+
+/* Destroys the credentials instances. */
+static void grpc_rb_channel_credentials_free(void *p) {
+  grpc_rb_channel_credentials *wrapper = NULL;
+  if (p == NULL) {
+    return;
+  };
+  wrapper = (grpc_rb_channel_credentials *)p;
+
+  /* Delete the wrapped object if the mark object is Qnil, which indicates that
+   * no other object is the actual owner. */
+  if (wrapper->wrapped != NULL && wrapper->mark == Qnil) {
+    grpc_channel_credentials_release(wrapper->wrapped);
+    wrapper->wrapped = NULL;
+  }
+
+  xfree(p);
+}
+
+/* Protects the mark object from GC */
+static void grpc_rb_channel_credentials_mark(void *p) {
+  grpc_rb_channel_credentials *wrapper = NULL;
+  if (p == NULL) {
+    return;
+  }
+  wrapper = (grpc_rb_channel_credentials *)p;
+
+  /* If it's not already cleaned up, mark the mark object */
+  if (wrapper->mark != Qnil) {
+    rb_gc_mark(wrapper->mark);
+  }
+}
+
+static rb_data_type_t grpc_rb_channel_credentials_data_type = {
+    "grpc_channel_credentials",
+    {grpc_rb_channel_credentials_mark, grpc_rb_channel_credentials_free,
+     GRPC_RB_MEMSIZE_UNAVAILABLE, {NULL, NULL}},
+    NULL,
+    NULL,
+#ifdef RUBY_TYPED_FREE_IMMEDIATELY
+    RUBY_TYPED_FREE_IMMEDIATELY
+#endif
+};
+
+/* Allocates ChannelCredential instances.
+   Provides safe initial defaults for the instance fields. */
+static VALUE grpc_rb_channel_credentials_alloc(VALUE cls) {
+  grpc_rb_channel_credentials *wrapper = ALLOC(grpc_rb_channel_credentials);
+  wrapper->wrapped = NULL;
+  wrapper->mark = Qnil;
+  return TypedData_Wrap_Struct(cls, &grpc_rb_channel_credentials_data_type, wrapper);
+}
+
+/* Clones ChannelCredentials instances.
+   Gives ChannelCredentials a consistent implementation of Ruby's object copy/dup
+   protocol. */
+static VALUE grpc_rb_channel_credentials_init_copy(VALUE copy, VALUE orig) {
+  grpc_rb_channel_credentials *orig_cred = NULL;
+  grpc_rb_channel_credentials *copy_cred = NULL;
+
+  if (copy == orig) {
+    return copy;
+  }
+
+  /* Raise an error if orig is not a credentials object or a subclass. */
+  if (TYPE(orig) != T_DATA ||
+      RDATA(orig)->dfree != (RUBY_DATA_FUNC)grpc_rb_channel_credentials_free) {
+    rb_raise(rb_eTypeError, "not a %s",
+             rb_obj_classname(grpc_rb_cChannelCredentials));
+  }
+
+  TypedData_Get_Struct(orig, grpc_rb_channel_credentials,
+                       &grpc_rb_channel_credentials_data_type, orig_cred);
+  TypedData_Get_Struct(copy, grpc_rb_channel_credentials,
+                       &grpc_rb_channel_credentials_data_type, copy_cred);
+
+  /* use ruby's MEMCPY to make a byte-for-byte copy of the credentials
+   * wrapper object. */
+  MEMCPY(copy_cred, orig_cred, grpc_rb_channel_credentials, 1);
+  return copy;
+}
+
+
+/* The attribute used on the mark object to hold the pem_root_certs. */
+static ID id_pem_root_certs;
+
+/* The attribute used on the mark object to hold the pem_private_key. */
+static ID id_pem_private_key;
+
+/* The attribute used on the mark object to hold the pem_private_key. */
+static ID id_pem_cert_chain;
+
+/*
+  call-seq:
+    creds1 = Credentials.new(pem_root_certs)
+    ...
+    creds2 = Credentials.new(pem_root_certs, pem_private_key,
+                             pem_cert_chain)
+    pem_root_certs: (required) PEM encoding of the server root certificate
+    pem_private_key: (optional) PEM encoding of the client's private key
+    pem_cert_chain: (optional) PEM encoding of the client's cert chain
+    Initializes Credential instances. */
+static VALUE grpc_rb_channel_credentials_init(int argc, VALUE *argv, VALUE self) {
+  VALUE pem_root_certs = Qnil;
+  VALUE pem_private_key = Qnil;
+  VALUE pem_cert_chain = Qnil;
+  grpc_rb_channel_credentials *wrapper = NULL;
+  grpc_channel_credentials *creds = NULL;
+  grpc_ssl_pem_key_cert_pair key_cert_pair;
+  MEMZERO(&key_cert_pair, grpc_ssl_pem_key_cert_pair, 1);
+  /* TODO: Remove mandatory arg when we support default roots. */
+  /* "12" == 1 mandatory arg, 2 (credentials) is optional */
+  rb_scan_args(argc, argv, "12", &pem_root_certs, &pem_private_key,
+               &pem_cert_chain);
+
+  TypedData_Get_Struct(self, grpc_rb_channel_credentials,
+                       &grpc_rb_channel_credentials_data_type, wrapper);
+  if (pem_root_certs == Qnil) {
+    rb_raise(rb_eRuntimeError,
+             "could not create a credential: nil pem_root_certs");
+    return Qnil;
+  }
+  if (pem_private_key == Qnil && pem_cert_chain == Qnil) {
+    creds =
+        grpc_ssl_credentials_create(RSTRING_PTR(pem_root_certs), NULL, NULL);
+  } else {
+    key_cert_pair.private_key = RSTRING_PTR(pem_private_key);
+    key_cert_pair.cert_chain = RSTRING_PTR(pem_cert_chain);
+    creds = grpc_ssl_credentials_create(RSTRING_PTR(pem_root_certs),
+                                        &key_cert_pair, NULL);
+  }
+  if (creds == NULL) {
+    rb_raise(rb_eRuntimeError, "could not create a credentials, not sure why");
+    return Qnil;
+  }
+  wrapper->wrapped = creds;
+
+  /* Add the input objects as hidden fields to preserve them. */
+  rb_ivar_set(self, id_pem_cert_chain, pem_cert_chain);
+  rb_ivar_set(self, id_pem_private_key, pem_private_key);
+  rb_ivar_set(self, id_pem_root_certs, pem_root_certs);
+
+  return self;
+}
+
+void Init_grpc_channel_credentials() {
+  grpc_rb_cChannelCredentials =
+      rb_define_class_under(grpc_rb_mGrpcCore, "ChannelCredentials", rb_cObject);
+
+  /* Allocates an object managed by the ruby runtime */
+  rb_define_alloc_func(grpc_rb_cChannelCredentials,
+                       grpc_rb_channel_credentials_alloc);
+
+  /* Provides a ruby constructor and support for dup/clone. */
+  rb_define_method(grpc_rb_cChannelCredentials, "initialize",
+                   grpc_rb_channel_credentials_init, -1);
+  rb_define_method(grpc_rb_cChannelCredentials, "initialize_copy",
+                   grpc_rb_channel_credentials_init_copy, 1);
+
+  id_pem_cert_chain = rb_intern("__pem_cert_chain");
+  id_pem_private_key = rb_intern("__pem_private_key");
+  id_pem_root_certs = rb_intern("__pem_root_certs");
+}
+
+/* Gets the wrapped grpc_channel_credentials from the ruby wrapper */
+grpc_channel_credentials *grpc_rb_get_wrapped_channel_credentials(VALUE v) {
+  grpc_rb_channel_credentials *wrapper = NULL;
+  TypedData_Get_Struct(v, grpc_rb_channel_credentials,
+                       &grpc_rb_channel_credentials_data_type,
+                       wrapper);
+  return wrapper->wrapped;
+}
diff --git a/src/ruby/ext/grpc/rb_credentials.h b/src/ruby/ext/grpc/rb_channel_credentials.h
similarity index 91%
rename from src/ruby/ext/grpc/rb_credentials.h
rename to src/ruby/ext/grpc/rb_channel_credentials.h
index 840f7d5..15229de 100644
--- a/src/ruby/ext/grpc/rb_credentials.h
+++ b/src/ruby/ext/grpc/rb_channel_credentials.h
@@ -38,10 +38,10 @@
 
 #include <grpc/grpc_security.h>
 
-/* Initializes the ruby Credentials class. */
-void Init_grpc_credentials();
+/* Initializes the ruby ChannelCredentials class. */
+void Init_grpc_channel_credentials();
 
 /* Gets the wrapped credentials from the ruby wrapper */
-grpc_credentials* grpc_rb_get_wrapped_credentials(VALUE v);
+grpc_channel_credentials* grpc_rb_get_wrapped_channel_credentials(VALUE v);
 
 #endif /* GRPC_RB_CREDENTIALS_H_ */
diff --git a/src/ruby/ext/grpc/rb_credentials.c b/src/ruby/ext/grpc/rb_credentials.c
deleted file mode 100644
index 486ff79..0000000
--- a/src/ruby/ext/grpc/rb_credentials.c
+++ /dev/null
@@ -1,297 +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 "rb_credentials.h"
-
-#include <ruby/ruby.h>
-
-#include <grpc/grpc.h>
-#include <grpc/grpc_security.h>
-
-#include "rb_grpc.h"
-
-/* grpc_rb_cCredentials is the ruby class that proxies grpc_credentials. */
-static VALUE grpc_rb_cCredentials = Qnil;
-
-/* grpc_rb_credentials wraps a grpc_credentials.  It provides a
- * peer ruby object, 'mark' to minimize copying when a credential is
- * created from ruby. */
-typedef struct grpc_rb_credentials {
-  /* Holder of ruby objects involved in constructing the credentials */
-  VALUE mark;
-
-  /* The actual credentials */
-  grpc_credentials *wrapped;
-} grpc_rb_credentials;
-
-/* Destroys the credentials instances. */
-static void grpc_rb_credentials_free(void *p) {
-  grpc_rb_credentials *wrapper = NULL;
-  if (p == NULL) {
-    return;
-  };
-  wrapper = (grpc_rb_credentials *)p;
-
-  /* Delete the wrapped object if the mark object is Qnil, which indicates that
-   * no other object is the actual owner. */
-  if (wrapper->wrapped != NULL && wrapper->mark == Qnil) {
-    grpc_credentials_release(wrapper->wrapped);
-    wrapper->wrapped = NULL;
-  }
-
-  xfree(p);
-}
-
-/* Protects the mark object from GC */
-static void grpc_rb_credentials_mark(void *p) {
-  grpc_rb_credentials *wrapper = NULL;
-  if (p == NULL) {
-    return;
-  }
-  wrapper = (grpc_rb_credentials *)p;
-
-  /* If it's not already cleaned up, mark the mark object */
-  if (wrapper->mark != Qnil) {
-    rb_gc_mark(wrapper->mark);
-  }
-}
-
-static rb_data_type_t grpc_rb_credentials_data_type = {
-    "grpc_credentials",
-    {grpc_rb_credentials_mark, grpc_rb_credentials_free,
-     GRPC_RB_MEMSIZE_UNAVAILABLE, {NULL, NULL}},
-    NULL,
-    NULL,
-#ifdef RUBY_TYPED_FREE_IMMEDIATELY
-    RUBY_TYPED_FREE_IMMEDIATELY
-#endif
-};
-
-/* Allocates Credential instances.
-   Provides safe initial defaults for the instance fields. */
-static VALUE grpc_rb_credentials_alloc(VALUE cls) {
-  grpc_rb_credentials *wrapper = ALLOC(grpc_rb_credentials);
-  wrapper->wrapped = NULL;
-  wrapper->mark = Qnil;
-  return TypedData_Wrap_Struct(cls, &grpc_rb_credentials_data_type, wrapper);
-}
-
-/* Clones Credentials instances.
-   Gives Credentials a consistent implementation of Ruby's object copy/dup
-   protocol. */
-static VALUE grpc_rb_credentials_init_copy(VALUE copy, VALUE orig) {
-  grpc_rb_credentials *orig_cred = NULL;
-  grpc_rb_credentials *copy_cred = NULL;
-
-  if (copy == orig) {
-    return copy;
-  }
-
-  /* Raise an error if orig is not a credentials object or a subclass. */
-  if (TYPE(orig) != T_DATA ||
-      RDATA(orig)->dfree != (RUBY_DATA_FUNC)grpc_rb_credentials_free) {
-    rb_raise(rb_eTypeError, "not a %s", rb_obj_classname(grpc_rb_cCredentials));
-  }
-
-  TypedData_Get_Struct(orig, grpc_rb_credentials,
-                       &grpc_rb_credentials_data_type, orig_cred);
-  TypedData_Get_Struct(copy, grpc_rb_credentials,
-                       &grpc_rb_credentials_data_type, copy_cred);
-
-  /* use ruby's MEMCPY to make a byte-for-byte copy of the credentials
-   * wrapper object. */
-  MEMCPY(copy_cred, orig_cred, grpc_rb_credentials, 1);
-  return copy;
-}
-
-/*
-  call-seq:
-    creds = Credentials.default()
-    Creates the default credential instances. */
-static VALUE grpc_rb_default_credentials_create(VALUE cls) {
-  grpc_rb_credentials *wrapper = ALLOC(grpc_rb_credentials);
-  wrapper->wrapped = grpc_google_default_credentials_create();
-  if (wrapper->wrapped == NULL) {
-    rb_raise(rb_eRuntimeError,
-             "could not create default credentials, not sure why");
-    return Qnil;
-  }
-
-  wrapper->mark = Qnil;
-  return TypedData_Wrap_Struct(cls, &grpc_rb_credentials_data_type, wrapper);
-}
-
-/*
-  call-seq:
-    creds = Credentials.compute_engine()
-    Creates the default credential instances. */
-static VALUE grpc_rb_compute_engine_credentials_create(VALUE cls) {
-  grpc_rb_credentials *wrapper = ALLOC(grpc_rb_credentials);
-  wrapper->wrapped = grpc_google_compute_engine_credentials_create(NULL);
-  if (wrapper->wrapped == NULL) {
-    rb_raise(rb_eRuntimeError,
-             "could not create composite engine credentials, not sure why");
-    return Qnil;
-  }
-
-  wrapper->mark = Qnil;
-  return TypedData_Wrap_Struct(cls, &grpc_rb_credentials_data_type, wrapper);
-}
-
-/*
-  call-seq:
-    creds1 = ...
-    creds2 = ...
-    creds3 = creds1.add(creds2)
-    Creates the default credential instances. */
-static VALUE grpc_rb_composite_credentials_create(VALUE self, VALUE other) {
-  grpc_rb_credentials *self_wrapper = NULL;
-  grpc_rb_credentials *other_wrapper = NULL;
-  grpc_rb_credentials *wrapper = NULL;
-
-  TypedData_Get_Struct(self, grpc_rb_credentials,
-                       &grpc_rb_credentials_data_type, self_wrapper);
-  TypedData_Get_Struct(other, grpc_rb_credentials,
-                       &grpc_rb_credentials_data_type, other_wrapper);
-  wrapper = ALLOC(grpc_rb_credentials);
-  wrapper->wrapped = grpc_composite_credentials_create(
-      self_wrapper->wrapped, other_wrapper->wrapped, NULL);
-  if (wrapper->wrapped == NULL) {
-    rb_raise(rb_eRuntimeError,
-             "could not create composite credentials, not sure why");
-    return Qnil;
-  }
-
-  wrapper->mark = Qnil;
-  return TypedData_Wrap_Struct(grpc_rb_cCredentials,
-                               &grpc_rb_credentials_data_type, wrapper);
-}
-
-/* The attribute used on the mark object to hold the pem_root_certs. */
-static ID id_pem_root_certs;
-
-/* The attribute used on the mark object to hold the pem_private_key. */
-static ID id_pem_private_key;
-
-/* The attribute used on the mark object to hold the pem_private_key. */
-static ID id_pem_cert_chain;
-
-/*
-  call-seq:
-    creds1 = Credentials.new(pem_root_certs)
-    ...
-    creds2 = Credentials.new(pem_root_certs, pem_private_key,
-                             pem_cert_chain)
-    pem_root_certs: (required) PEM encoding of the server root certificate
-    pem_private_key: (optional) PEM encoding of the client's private key
-    pem_cert_chain: (optional) PEM encoding of the client's cert chain
-    Initializes Credential instances. */
-static VALUE grpc_rb_credentials_init(int argc, VALUE *argv, VALUE self) {
-  VALUE pem_root_certs = Qnil;
-  VALUE pem_private_key = Qnil;
-  VALUE pem_cert_chain = Qnil;
-  grpc_rb_credentials *wrapper = NULL;
-  grpc_credentials *creds = NULL;
-  grpc_ssl_pem_key_cert_pair key_cert_pair;
-  MEMZERO(&key_cert_pair, grpc_ssl_pem_key_cert_pair, 1);
-  /* TODO: Remove mandatory arg when we support default roots. */
-  /* "12" == 1 mandatory arg, 2 (credentials) is optional */
-  rb_scan_args(argc, argv, "12", &pem_root_certs, &pem_private_key,
-               &pem_cert_chain);
-
-  TypedData_Get_Struct(self, grpc_rb_credentials,
-                       &grpc_rb_credentials_data_type, wrapper);
-  if (pem_root_certs == Qnil) {
-    rb_raise(rb_eRuntimeError,
-             "could not create a credential: nil pem_root_certs");
-    return Qnil;
-  }
-  if (pem_private_key == Qnil && pem_cert_chain == Qnil) {
-    creds =
-        grpc_ssl_credentials_create(RSTRING_PTR(pem_root_certs), NULL, NULL);
-  } else {
-    key_cert_pair.private_key = RSTRING_PTR(pem_private_key);
-    key_cert_pair.cert_chain = RSTRING_PTR(pem_cert_chain);
-    creds = grpc_ssl_credentials_create(RSTRING_PTR(pem_root_certs),
-                                        &key_cert_pair, NULL);
-  }
-  if (creds == NULL) {
-    rb_raise(rb_eRuntimeError, "could not create a credentials, not sure why");
-    return Qnil;
-  }
-  wrapper->wrapped = creds;
-
-  /* Add the input objects as hidden fields to preserve them. */
-  rb_ivar_set(self, id_pem_cert_chain, pem_cert_chain);
-  rb_ivar_set(self, id_pem_private_key, pem_private_key);
-  rb_ivar_set(self, id_pem_root_certs, pem_root_certs);
-
-  return self;
-}
-
-void Init_grpc_credentials() {
-  grpc_rb_cCredentials =
-      rb_define_class_under(grpc_rb_mGrpcCore, "Credentials", rb_cObject);
-
-  /* Allocates an object managed by the ruby runtime */
-  rb_define_alloc_func(grpc_rb_cCredentials, grpc_rb_credentials_alloc);
-
-  /* Provides a ruby constructor and support for dup/clone. */
-  rb_define_method(grpc_rb_cCredentials, "initialize", grpc_rb_credentials_init,
-                   -1);
-  rb_define_method(grpc_rb_cCredentials, "initialize_copy",
-                   grpc_rb_credentials_init_copy, 1);
-
-  /* Provide static funcs that create new special instances. */
-  rb_define_singleton_method(grpc_rb_cCredentials, "default",
-                             grpc_rb_default_credentials_create, 0);
-
-  rb_define_singleton_method(grpc_rb_cCredentials, "compute_engine",
-                             grpc_rb_compute_engine_credentials_create, 0);
-
-  /* Provide other methods. */
-  rb_define_method(grpc_rb_cCredentials, "compose",
-                   grpc_rb_composite_credentials_create, 1);
-
-  id_pem_cert_chain = rb_intern("__pem_cert_chain");
-  id_pem_private_key = rb_intern("__pem_private_key");
-  id_pem_root_certs = rb_intern("__pem_root_certs");
-}
-
-/* Gets the wrapped grpc_credentials from the ruby wrapper */
-grpc_credentials *grpc_rb_get_wrapped_credentials(VALUE v) {
-  grpc_rb_credentials *wrapper = NULL;
-  TypedData_Get_Struct(v, grpc_rb_credentials, &grpc_rb_credentials_data_type,
-                       wrapper);
-  return wrapper->wrapped;
-}
diff --git a/src/ruby/ext/grpc/rb_grpc.c b/src/ruby/ext/grpc/rb_grpc.c
index 33f4877..7c7c2d3 100644
--- a/src/ruby/ext/grpc/rb_grpc.c
+++ b/src/ruby/ext/grpc/rb_grpc.c
@@ -42,9 +42,9 @@
 #include <grpc/support/time.h>
 #include "rb_call.h"
 #include "rb_channel.h"
+#include "rb_channel_credentials.h"
 #include "rb_completion_queue.h"
 #include "rb_server.h"
-#include "rb_credentials.h"
 #include "rb_server_credentials.h"
 
 static VALUE grpc_rb_cTimeVal = Qnil;
@@ -318,7 +318,7 @@
   Init_grpc_channel();
   Init_grpc_completion_queue();
   Init_grpc_call();
-  Init_grpc_credentials();
+  Init_grpc_channel_credentials();
   Init_grpc_server();
   Init_grpc_server_credentials();
   Init_grpc_status_codes();
diff --git a/src/ruby/lib/grpc/generic/client_stub.rb b/src/ruby/lib/grpc/generic/client_stub.rb
index b8e33ad..90aaa02 100644
--- a/src/ruby/lib/grpc/generic/client_stub.rb
+++ b/src/ruby/lib/grpc/generic/client_stub.rb
@@ -51,7 +51,9 @@
       end
       kw['grpc.primary_user_agent'] = "grpc-ruby/#{VERSION}"
       return Core::Channel.new(host, kw) if creds.nil?
-      fail(TypeError, '!Credentials') unless creds.is_a?(Core::Credentials)
+      unless creds.is_a?(Core::ChannelCredentials)
+        fail(TypeError, '!ChannelCredentials')
+      end
       Core::Channel.new(host, kw, creds)
     end
 
@@ -106,7 +108,7 @@
     # @param q [Core::CompletionQueue] used to wait for events
     # @param channel_override [Core::Channel] a pre-created channel
     # @param timeout [Number] the default timeout to use in requests
-    # @param creds [Core::Credentials] the channel
+    # @param creds [Core::ChannelCredentials] the channel credentials
     # @param update_metadata a func that updates metadata as described above
     # @param kw [KeywordArgs]the channel arguments
     def initialize(host, q,
diff --git a/src/ruby/pb/test/client.rb b/src/ruby/pb/test/client.rb
index b84cd43..30550d6 100755
--- a/src/ruby/pb/test/client.rb
+++ b/src/ruby/pb/test/client.rb
@@ -103,13 +103,13 @@
 # creates SSL Credentials from the test certificates.
 def test_creds
   certs = load_test_certs
-  GRPC::Core::Credentials.new(certs[0])
+  GRPC::Core::ChannelCredentials.new(certs[0])
 end
 
 # creates SSL Credentials from the production certificates.
 def prod_creds
   cert_text = load_prod_cert
-  GRPC::Core::Credentials.new(cert_text)
+  GRPC::Core::ChannelCredentials.new(cert_text)
 end
 
 # creates the SSL Credentials.
diff --git a/src/ruby/spec/credentials_spec.rb b/src/ruby/spec/channel_credentials_spec.rb
similarity index 78%
rename from src/ruby/spec/credentials_spec.rb
rename to src/ruby/spec/channel_credentials_spec.rb
index b02219d..b2bdf70 100644
--- a/src/ruby/spec/credentials_spec.rb
+++ b/src/ruby/spec/channel_credentials_spec.rb
@@ -29,8 +29,8 @@
 
 require 'grpc'
 
-describe GRPC::Core::Credentials do
-  Credentials = GRPC::Core::Credentials
+describe GRPC::Core::ChannelCredentials do
+  ChannelCredentials = GRPC::Core::ChannelCredentials
 
   def load_test_certs
     test_root = File.join(File.dirname(__FILE__), 'testdata')
@@ -40,32 +40,24 @@
 
   describe '#new' do
     it 'can be constructed with fake inputs' do
-      expect { Credentials.new('root_certs', 'key', 'cert') }.not_to raise_error
+      blk = proc  { ChannelCredentials.new('root_certs', 'key', 'cert') }
+      expect(&blk).not_to raise_error
     end
 
     it 'it can be constructed using specific test certificates' do
       certs = load_test_certs
-      expect { Credentials.new(*certs) }.not_to raise_error
+      expect { ChannelCredentials.new(*certs) }.not_to raise_error
     end
 
     it 'can be constructed with server roots certs only' do
       root_cert, _, _ = load_test_certs
-      expect { Credentials.new(root_cert) }.not_to raise_error
+      expect { ChannelCredentials.new(root_cert) }.not_to raise_error
     end
 
     it 'cannot be constructed with a nil server roots' do
       _, client_key, client_chain = load_test_certs
-      blk = proc { Credentials.new(nil, client_key, client_chain) }
+      blk = proc { ChannelCredentials.new(nil, client_key, client_chain) }
       expect(&blk).to raise_error
     end
   end
-
-  describe '#compose' do
-    it 'cannot be completed OK with 2 SSL creds' do
-      certs = load_test_certs
-      cred1 = Credentials.new(*certs)
-      cred2 = Credentials.new(*certs)
-      expect { cred1.compose(cred2) }.to raise_error
-    end
-  end
 end
diff --git a/src/ruby/spec/channel_spec.rb b/src/ruby/spec/channel_spec.rb
index 25cefcd..b4d2b94 100644
--- a/src/ruby/spec/channel_spec.rb
+++ b/src/ruby/spec/channel_spec.rb
@@ -40,7 +40,7 @@
   let(:cq) { GRPC::Core::CompletionQueue.new }
 
   def create_test_cert
-    GRPC::Core::Credentials.new(load_test_certs[0])
+    GRPC::Core::ChannelCredentials.new(load_test_certs[0])
   end
 
   shared_examples '#new' do
diff --git a/src/ruby/spec/client_server_spec.rb b/src/ruby/spec/client_server_spec.rb
index ad0fb26..734f176 100644
--- a/src/ruby/spec/client_server_spec.rb
+++ b/src/ruby/spec/client_server_spec.rb
@@ -431,7 +431,7 @@
     @server.start
     args = { Channel::SSL_TARGET => 'foo.test.google.fr' }
     @ch = Channel.new("0.0.0.0:#{server_port}", args,
-                      GRPC::Core::Credentials.new(certs[0], nil, nil))
+                      GRPC::Core::ChannelCredentials.new(certs[0], nil, nil))
   end
 
   after(:example) do
diff --git a/src/ruby/spec/generic/client_stub_spec.rb b/src/ruby/spec/generic/client_stub_spec.rb
index c5173ae..da5bc6c 100644
--- a/src/ruby/spec/generic/client_stub_spec.rb
+++ b/src/ruby/spec/generic/client_stub_spec.rb
@@ -113,7 +113,7 @@
         opts = {
           GRPC::Core::Channel::SSL_TARGET => 'foo.test.google.fr',
           a_channel_arg: 'an_arg',
-          creds: GRPC::Core::Credentials.new(certs[0], nil, nil)
+          creds: GRPC::Core::ChannelCredentials.new(certs[0], nil, nil)
         }
         GRPC::ClientStub.new(fake_host, @cq, **opts)
       end
diff --git a/src/ruby/spec/testdata/server1.pem b/src/ruby/spec/testdata/server1.pem
index 8e582e5..f3d43fc 100755
--- a/src/ruby/spec/testdata/server1.pem
+++ b/src/ruby/spec/testdata/server1.pem
@@ -1,16 +1,16 @@
 -----BEGIN CERTIFICATE-----
-MIICmzCCAgSgAwIBAgIBAzANBgkqhkiG9w0BAQUFADBWMQswCQYDVQQGEwJBVTET
-MBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQ
-dHkgTHRkMQ8wDQYDVQQDDAZ0ZXN0Y2EwHhcNMTQwNzIyMDYwMDU3WhcNMjQwNzE5
-MDYwMDU3WjBkMQswCQYDVQQGEwJVUzERMA8GA1UECBMISWxsaW5vaXMxEDAOBgNV
-BAcTB0NoaWNhZ28xFDASBgNVBAoTC0dvb2dsZSBJbmMuMRowGAYDVQQDFBEqLnRl
-c3QuZ29vZ2xlLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA4cMVJygs
-JUmlgMMzgdi0h1XoCR7+ww1pop04OMMyy7H/i0PJ2W6Y35+b4CM8QrkYeEafUGDO
-RYX6yV/cHGGsD/x02ye6ey1UDtkGAD/mpDEx8YCrjAc1Vfvt8Fk6Cn1WVIxV/J30
-3xjBsFgByQ55RBp1OLZfVLo6AleBDSbcxaECAwEAAaNrMGkwCQYDVR0TBAIwADAL
-BgNVHQ8EBAMCBeAwTwYDVR0RBEgwRoIQKi50ZXN0Lmdvb2dsZS5mcoIYd2F0ZXJ6
-b29pLnRlc3QuZ29vZ2xlLmJlghIqLnRlc3QueW91dHViZS5jb22HBMCoAQMwDQYJ
-KoZIhvcNAQEFBQADgYEAM2Ii0LgTGbJ1j4oqX9bxVcxm+/R5Yf8oi0aZqTJlnLYS
-wXcBykxTx181s7WyfJ49WwrYXo78zTDAnf1ma0fPq3e4mpspvyndLh1a+OarHa1e
-aT0DIIYk7qeEa1YcVljx2KyLd0r1BBAfrwyGaEPVeJQVYWaOJRU2we/KD4ojf9s=
+MIICnDCCAgWgAwIBAgIBBzANBgkqhkiG9w0BAQsFADBWMQswCQYDVQQGEwJBVTET
+MBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQ
+dHkgTHRkMQ8wDQYDVQQDEwZ0ZXN0Y2EwHhcNMTUxMTA0MDIyMDI0WhcNMjUxMTAx
+MDIyMDI0WjBlMQswCQYDVQQGEwJVUzERMA8GA1UECBMISWxsaW5vaXMxEDAOBgNV
+BAcTB0NoaWNhZ28xFTATBgNVBAoTDEV4YW1wbGUsIENvLjEaMBgGA1UEAxQRKi50
+ZXN0Lmdvb2dsZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAOHDFSco
+LCVJpYDDM4HYtIdV6Ake/sMNaaKdODjDMsux/4tDydlumN+fm+AjPEK5GHhGn1Bg
+zkWF+slf3BxhrA/8dNsnunstVA7ZBgA/5qQxMfGAq4wHNVX77fBZOgp9VlSMVfyd
+9N8YwbBYAckOeUQadTi2X1S6OgJXgQ0m3MWhAgMBAAGjazBpMAkGA1UdEwQCMAAw
+CwYDVR0PBAQDAgXgME8GA1UdEQRIMEaCECoudGVzdC5nb29nbGUuZnKCGHdhdGVy
+em9vaS50ZXN0Lmdvb2dsZS5iZYISKi50ZXN0LnlvdXR1YmUuY29thwTAqAEDMA0G
+CSqGSIb3DQEBCwUAA4GBAJFXVifQNub1LUP4JlnX5lXNlo8FxZ2a12AFQs+bzoJ6
+hM044EDjqyxUqSbVePK0ni3w1fHQB5rY9yYC5f8G7aqqTY1QOhoUk8ZTSTRpnkTh
+y4jjdvTZeLDVBlueZUTDRmy2feY5aZIU18vFDK08dTG0A87pppuv1LNIR3loveU8
 -----END CERTIFICATE-----
diff --git a/templates/binding.gyp.template b/templates/binding.gyp.template
index 52070cf..be80750 100644
--- a/templates/binding.gyp.template
+++ b/templates/binding.gyp.template
@@ -89,8 +89,9 @@
       ]
     },
     'targets': [
+      % for module in node_modules:
       % for lib in libs:
-      % if lib.name == 'gpr' or lib.name == 'grpc':
+      % if lib.name in module.transitive_deps:
       {
         'target_name': '${lib.name}',
         'product_prefix': 'lib',
@@ -142,22 +143,18 @@
             }
           }]
         ],
-        "target_name": "grpc_node",
+        "target_name": "${module.name}",
         "sources": [
-          "src/node/ext/byte_buffer.cc",
-          "src/node/ext/call.cc",
-          "src/node/ext/call_credentials.cc",
-          "src/node/ext/channel.cc",
-          "src/node/ext/channel_credentials.cc",
-          "src/node/ext/completion_queue_async_worker.cc",
-          "src/node/ext/node_grpc.cc",
-          "src/node/ext/server.cc",
-          "src/node/ext/server_credentials.cc",
-          "src/node/ext/timeval.cc"
+          % for source in module.src:
+          "${source}",
+          % endfor
         ],
         "dependencies": [
-          "grpc"
+          % for dep in getattr(module, 'deps', []):
+          "${dep}",
+          % endfor
         ]
-      }
+      },
+      % endfor
     ]
   }
diff --git a/test/core/client_config/lb_policies_test.c b/test/core/client_config/lb_policies_test.c
index 281d2b2..6f218e7 100644
--- a/test/core/client_config/lb_policies_test.c
+++ b/test/core/client_config/lb_policies_test.c
@@ -135,9 +135,8 @@
   gpr_log(GPR_INFO, "KILLING SERVER %d", i);
   GPR_ASSERT(f->servers[i] != NULL);
   grpc_server_shutdown_and_notify(f->servers[i], f->cq, tag(10000));
-  GPR_ASSERT(
-      grpc_completion_queue_pluck(f->cq, tag(10000), n_millis_time(5000), NULL)
-          .type == GRPC_OP_COMPLETE);
+  GPR_ASSERT(grpc_completion_queue_pluck(f->cq, tag(10000), n_millis_time(5000),
+                                         NULL).type == GRPC_OP_COMPLETE);
   grpc_server_destroy(f->servers[i]);
   f->servers[i] = NULL;
 }
@@ -203,8 +202,8 @@
     if (f->servers[i] == NULL) continue;
     grpc_server_shutdown_and_notify(f->servers[i], f->cq, tag(10000));
     GPR_ASSERT(grpc_completion_queue_pluck(f->cq, tag(10000),
-                                           n_millis_time(5000), NULL)
-                   .type == GRPC_OP_COMPLETE);
+                                           n_millis_time(5000),
+                                           NULL).type == GRPC_OP_COMPLETE);
     grpc_server_destroy(f->servers[i]);
   }
   grpc_completion_queue_shutdown(f->cq);
@@ -230,7 +229,6 @@
   grpc_call *c;
   int s_idx;
   int *s_valid;
-  gpr_timespec deadline;
   grpc_op ops[6];
   grpc_op *op;
   int was_cancelled;
@@ -269,9 +267,9 @@
     }
     memset(s_valid, 0, f->num_servers * sizeof(int));
 
-    deadline = n_millis_time(1000);
     c = grpc_channel_create_call(client, NULL, GRPC_PROPAGATE_DEFAULTS, f->cq,
-                                 "/foo", "foo.test.google.fr", deadline, NULL);
+                                 "/foo", "foo.test.google.fr",
+                                 gpr_inf_future(GPR_CLOCK_REALTIME), NULL);
     GPR_ASSERT(c);
     completed_client = 0;
 
@@ -304,8 +302,9 @@
                grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), NULL));
 
     s_idx = -1;
-    while ((ev = grpc_completion_queue_next(f->cq, n_millis_time(300), NULL))
-               .type != GRPC_QUEUE_TIMEOUT) {
+    while ((ev = grpc_completion_queue_next(
+                f->cq, GRPC_TIMEOUT_SECONDS_TO_DEADLINE(1), NULL)).type !=
+           GRPC_QUEUE_TIMEOUT) {
       GPR_ASSERT(ev.type == GRPC_OP_COMPLETE);
       read_tag = ((int)(gpr_intptr)ev.tag);
       gpr_log(GPR_DEBUG, "EVENT: success:%d, type:%d, tag:%d iter:%d",
@@ -316,6 +315,7 @@
         s_idx = read_tag - 1000;
         s_valid[s_idx] = 1;
         connection_sequence[iter_num] = s_idx;
+        break;
       } else if (read_tag == 1) {
         gpr_log(GPR_DEBUG, "client timed out");
         GPR_ASSERT(ev.success);
@@ -371,6 +371,7 @@
                                      &f->request_metadata_recv[s_idx], f->cq,
                                      f->cq, tag(1000 + (int)s_idx)));
     } else {
+      grpc_call_cancel(c, NULL);
       if (!completed_client) {
         cq_expect_completion(cqv, tag(1), 1);
         cq_verify(cqv);
@@ -453,6 +454,8 @@
   int *actual_connection_sequence;
   request_data rdata;
   servers_fixture *f;
+  grpc_channel_args args;
+  grpc_arg arg;
   rdata.call_details =
       gpr_malloc(sizeof(grpc_call_details) * spec->num_servers);
   f = setup_servers("127.0.0.1", &rdata, spec->num_servers);
@@ -462,7 +465,14 @@
                                           f->num_servers, ",", NULL);
   gpr_asprintf(&client_hostport, "ipv4:%s?lb_policy=round_robin",
                servers_hostports_str);
-  client = grpc_insecure_channel_create(client_hostport, NULL, NULL);
+
+  arg.type = GRPC_ARG_INTEGER;
+  arg.key = "grpc.testing.fixed_reconnect_backoff";
+  arg.value.integer = 100;
+  args.num_args = 1;
+  args.args = &arg;
+
+  client = grpc_insecure_channel_create(client_hostport, &args, NULL);
 
   gpr_log(GPR_INFO, "Testing '%s' with servers=%s client=%s", spec->description,
           servers_hostports_str, client_hostport);
diff --git a/test/core/end2end/data/server1_cert.c b/test/core/end2end/data/server1_cert.c
index d31f2e2..82d65cf 100644
--- a/test/core/end2end/data/server1_cert.c
+++ b/test/core/end2end/data/server1_cert.c
@@ -34,82 +34,82 @@
 const char test_server1_cert[] = {
     0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x42, 0x45, 0x47, 0x49, 0x4e, 0x20, 0x43,
     0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d,
-    0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x43, 0x6d, 0x7a, 0x43, 0x43,
-    0x41, 0x67, 0x53, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x42,
-    0x41, 0x7a, 0x41, 0x4e, 0x42, 0x67, 0x6b, 0x71, 0x68, 0x6b, 0x69, 0x47,
-    0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x55, 0x46, 0x41, 0x44, 0x42, 0x57,
+    0x2d, 0x2d, 0x2d, 0x0a, 0x4d, 0x49, 0x49, 0x43, 0x6e, 0x44, 0x43, 0x43,
+    0x41, 0x67, 0x57, 0x67, 0x41, 0x77, 0x49, 0x42, 0x41, 0x67, 0x49, 0x42,
+    0x42, 0x7a, 0x41, 0x4e, 0x42, 0x67, 0x6b, 0x71, 0x68, 0x6b, 0x69, 0x47,
+    0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x73, 0x46, 0x41, 0x44, 0x42, 0x57,
     0x4d, 0x51, 0x73, 0x77, 0x43, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47,
     0x45, 0x77, 0x4a, 0x42, 0x56, 0x54, 0x45, 0x54, 0x0a, 0x4d, 0x42, 0x45,
-    0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x41, 0x77, 0x4b, 0x55, 0x32, 0x39,
+    0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x42, 0x4d, 0x4b, 0x55, 0x32, 0x39,
     0x74, 0x5a, 0x53, 0x31, 0x54, 0x64, 0x47, 0x46, 0x30, 0x5a, 0x54, 0x45,
-    0x68, 0x4d, 0x42, 0x38, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x67, 0x77,
+    0x68, 0x4d, 0x42, 0x38, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43, 0x68, 0x4d,
     0x59, 0x53, 0x57, 0x35, 0x30, 0x5a, 0x58, 0x4a, 0x75, 0x5a, 0x58, 0x51,
     0x67, 0x56, 0x32, 0x6c, 0x6b, 0x5a, 0x32, 0x6c, 0x30, 0x63, 0x79, 0x42,
     0x51, 0x0a, 0x64, 0x48, 0x6b, 0x67, 0x54, 0x48, 0x52, 0x6b, 0x4d, 0x51,
-    0x38, 0x77, 0x44, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x44, 0x44, 0x41,
+    0x38, 0x77, 0x44, 0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x44, 0x45, 0x77,
     0x5a, 0x30, 0x5a, 0x58, 0x4e, 0x30, 0x59, 0x32, 0x45, 0x77, 0x48, 0x68,
-    0x63, 0x4e, 0x4d, 0x54, 0x51, 0x77, 0x4e, 0x7a, 0x49, 0x79, 0x4d, 0x44,
-    0x59, 0x77, 0x4d, 0x44, 0x55, 0x33, 0x57, 0x68, 0x63, 0x4e, 0x4d, 0x6a,
-    0x51, 0x77, 0x4e, 0x7a, 0x45, 0x35, 0x0a, 0x4d, 0x44, 0x59, 0x77, 0x4d,
-    0x44, 0x55, 0x33, 0x57, 0x6a, 0x42, 0x6b, 0x4d, 0x51, 0x73, 0x77, 0x43,
+    0x63, 0x4e, 0x4d, 0x54, 0x55, 0x78, 0x4d, 0x54, 0x41, 0x30, 0x4d, 0x44,
+    0x49, 0x79, 0x4d, 0x44, 0x49, 0x30, 0x57, 0x68, 0x63, 0x4e, 0x4d, 0x6a,
+    0x55, 0x78, 0x4d, 0x54, 0x41, 0x78, 0x0a, 0x4d, 0x44, 0x49, 0x79, 0x4d,
+    0x44, 0x49, 0x30, 0x57, 0x6a, 0x42, 0x6c, 0x4d, 0x51, 0x73, 0x77, 0x43,
     0x51, 0x59, 0x44, 0x56, 0x51, 0x51, 0x47, 0x45, 0x77, 0x4a, 0x56, 0x55,
     0x7a, 0x45, 0x52, 0x4d, 0x41, 0x38, 0x47, 0x41, 0x31, 0x55, 0x45, 0x43,
     0x42, 0x4d, 0x49, 0x53, 0x57, 0x78, 0x73, 0x61, 0x57, 0x35, 0x76, 0x61,
     0x58, 0x4d, 0x78, 0x45, 0x44, 0x41, 0x4f, 0x42, 0x67, 0x4e, 0x56, 0x0a,
     0x42, 0x41, 0x63, 0x54, 0x42, 0x30, 0x4e, 0x6f, 0x61, 0x57, 0x4e, 0x68,
-    0x5a, 0x32, 0x38, 0x78, 0x46, 0x44, 0x41, 0x53, 0x42, 0x67, 0x4e, 0x56,
-    0x42, 0x41, 0x6f, 0x54, 0x43, 0x30, 0x64, 0x76, 0x62, 0x32, 0x64, 0x73,
-    0x5a, 0x53, 0x42, 0x4a, 0x62, 0x6d, 0x4d, 0x75, 0x4d, 0x52, 0x6f, 0x77,
-    0x47, 0x41, 0x59, 0x44, 0x56, 0x51, 0x51, 0x44, 0x46, 0x42, 0x45, 0x71,
-    0x4c, 0x6e, 0x52, 0x6c, 0x0a, 0x63, 0x33, 0x51, 0x75, 0x5a, 0x32, 0x39,
-    0x76, 0x5a, 0x32, 0x78, 0x6c, 0x4c, 0x6d, 0x4e, 0x76, 0x62, 0x54, 0x43,
-    0x42, 0x6e, 0x7a, 0x41, 0x4e, 0x42, 0x67, 0x6b, 0x71, 0x68, 0x6b, 0x69,
-    0x47, 0x39, 0x77, 0x30, 0x42, 0x41, 0x51, 0x45, 0x46, 0x41, 0x41, 0x4f,
-    0x42, 0x6a, 0x51, 0x41, 0x77, 0x67, 0x59, 0x6b, 0x43, 0x67, 0x59, 0x45,
-    0x41, 0x34, 0x63, 0x4d, 0x56, 0x4a, 0x79, 0x67, 0x73, 0x0a, 0x4a, 0x55,
-    0x6d, 0x6c, 0x67, 0x4d, 0x4d, 0x7a, 0x67, 0x64, 0x69, 0x30, 0x68, 0x31,
-    0x58, 0x6f, 0x43, 0x52, 0x37, 0x2b, 0x77, 0x77, 0x31, 0x70, 0x6f, 0x70,
-    0x30, 0x34, 0x4f, 0x4d, 0x4d, 0x79, 0x79, 0x37, 0x48, 0x2f, 0x69, 0x30,
-    0x50, 0x4a, 0x32, 0x57, 0x36, 0x59, 0x33, 0x35, 0x2b, 0x62, 0x34, 0x43,
-    0x4d, 0x38, 0x51, 0x72, 0x6b, 0x59, 0x65, 0x45, 0x61, 0x66, 0x55, 0x47,
-    0x44, 0x4f, 0x0a, 0x52, 0x59, 0x58, 0x36, 0x79, 0x56, 0x2f, 0x63, 0x48,
-    0x47, 0x47, 0x73, 0x44, 0x2f, 0x78, 0x30, 0x32, 0x79, 0x65, 0x36, 0x65,
-    0x79, 0x31, 0x55, 0x44, 0x74, 0x6b, 0x47, 0x41, 0x44, 0x2f, 0x6d, 0x70,
-    0x44, 0x45, 0x78, 0x38, 0x59, 0x43, 0x72, 0x6a, 0x41, 0x63, 0x31, 0x56,
-    0x66, 0x76, 0x74, 0x38, 0x46, 0x6b, 0x36, 0x43, 0x6e, 0x31, 0x57, 0x56,
-    0x49, 0x78, 0x56, 0x2f, 0x4a, 0x33, 0x30, 0x0a, 0x33, 0x78, 0x6a, 0x42,
-    0x73, 0x46, 0x67, 0x42, 0x79, 0x51, 0x35, 0x35, 0x52, 0x42, 0x70, 0x31,
-    0x4f, 0x4c, 0x5a, 0x66, 0x56, 0x4c, 0x6f, 0x36, 0x41, 0x6c, 0x65, 0x42,
-    0x44, 0x53, 0x62, 0x63, 0x78, 0x61, 0x45, 0x43, 0x41, 0x77, 0x45, 0x41,
-    0x41, 0x61, 0x4e, 0x72, 0x4d, 0x47, 0x6b, 0x77, 0x43, 0x51, 0x59, 0x44,
-    0x56, 0x52, 0x30, 0x54, 0x42, 0x41, 0x49, 0x77, 0x41, 0x44, 0x41, 0x4c,
-    0x0a, 0x42, 0x67, 0x4e, 0x56, 0x48, 0x51, 0x38, 0x45, 0x42, 0x41, 0x4d,
-    0x43, 0x42, 0x65, 0x41, 0x77, 0x54, 0x77, 0x59, 0x44, 0x56, 0x52, 0x30,
-    0x52, 0x42, 0x45, 0x67, 0x77, 0x52, 0x6f, 0x49, 0x51, 0x4b, 0x69, 0x35,
-    0x30, 0x5a, 0x58, 0x4e, 0x30, 0x4c, 0x6d, 0x64, 0x76, 0x62, 0x32, 0x64,
-    0x73, 0x5a, 0x53, 0x35, 0x6d, 0x63, 0x6f, 0x49, 0x59, 0x64, 0x32, 0x46,
-    0x30, 0x5a, 0x58, 0x4a, 0x36, 0x0a, 0x62, 0x32, 0x39, 0x70, 0x4c, 0x6e,
-    0x52, 0x6c, 0x63, 0x33, 0x51, 0x75, 0x5a, 0x32, 0x39, 0x76, 0x5a, 0x32,
-    0x78, 0x6c, 0x4c, 0x6d, 0x4a, 0x6c, 0x67, 0x68, 0x49, 0x71, 0x4c, 0x6e,
-    0x52, 0x6c, 0x63, 0x33, 0x51, 0x75, 0x65, 0x57, 0x39, 0x31, 0x64, 0x48,
-    0x56, 0x69, 0x5a, 0x53, 0x35, 0x6a, 0x62, 0x32, 0x32, 0x48, 0x42, 0x4d,
-    0x43, 0x6f, 0x41, 0x51, 0x4d, 0x77, 0x44, 0x51, 0x59, 0x4a, 0x0a, 0x4b,
-    0x6f, 0x5a, 0x49, 0x68, 0x76, 0x63, 0x4e, 0x41, 0x51, 0x45, 0x46, 0x42,
-    0x51, 0x41, 0x44, 0x67, 0x59, 0x45, 0x41, 0x4d, 0x32, 0x49, 0x69, 0x30,
-    0x4c, 0x67, 0x54, 0x47, 0x62, 0x4a, 0x31, 0x6a, 0x34, 0x6f, 0x71, 0x58,
-    0x39, 0x62, 0x78, 0x56, 0x63, 0x78, 0x6d, 0x2b, 0x2f, 0x52, 0x35, 0x59,
-    0x66, 0x38, 0x6f, 0x69, 0x30, 0x61, 0x5a, 0x71, 0x54, 0x4a, 0x6c, 0x6e,
-    0x4c, 0x59, 0x53, 0x0a, 0x77, 0x58, 0x63, 0x42, 0x79, 0x6b, 0x78, 0x54,
-    0x78, 0x31, 0x38, 0x31, 0x73, 0x37, 0x57, 0x79, 0x66, 0x4a, 0x34, 0x39,
-    0x57, 0x77, 0x72, 0x59, 0x58, 0x6f, 0x37, 0x38, 0x7a, 0x54, 0x44, 0x41,
-    0x6e, 0x66, 0x31, 0x6d, 0x61, 0x30, 0x66, 0x50, 0x71, 0x33, 0x65, 0x34,
-    0x6d, 0x70, 0x73, 0x70, 0x76, 0x79, 0x6e, 0x64, 0x4c, 0x68, 0x31, 0x61,
-    0x2b, 0x4f, 0x61, 0x72, 0x48, 0x61, 0x31, 0x65, 0x0a, 0x61, 0x54, 0x30,
-    0x44, 0x49, 0x49, 0x59, 0x6b, 0x37, 0x71, 0x65, 0x45, 0x61, 0x31, 0x59,
-    0x63, 0x56, 0x6c, 0x6a, 0x78, 0x32, 0x4b, 0x79, 0x4c, 0x64, 0x30, 0x72,
-    0x31, 0x42, 0x42, 0x41, 0x66, 0x72, 0x77, 0x79, 0x47, 0x61, 0x45, 0x50,
-    0x56, 0x65, 0x4a, 0x51, 0x56, 0x59, 0x57, 0x61, 0x4f, 0x4a, 0x52, 0x55,
-    0x32, 0x77, 0x65, 0x2f, 0x4b, 0x44, 0x34, 0x6f, 0x6a, 0x66, 0x39, 0x73,
-    0x3d, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x45, 0x4e, 0x44, 0x20, 0x43,
+    0x5a, 0x32, 0x38, 0x78, 0x46, 0x54, 0x41, 0x54, 0x42, 0x67, 0x4e, 0x56,
+    0x42, 0x41, 0x6f, 0x54, 0x44, 0x45, 0x56, 0x34, 0x59, 0x57, 0x31, 0x77,
+    0x62, 0x47, 0x55, 0x73, 0x49, 0x45, 0x4e, 0x76, 0x4c, 0x6a, 0x45, 0x61,
+    0x4d, 0x42, 0x67, 0x47, 0x41, 0x31, 0x55, 0x45, 0x41, 0x78, 0x51, 0x52,
+    0x4b, 0x69, 0x35, 0x30, 0x0a, 0x5a, 0x58, 0x4e, 0x30, 0x4c, 0x6d, 0x64,
+    0x76, 0x62, 0x32, 0x64, 0x73, 0x5a, 0x53, 0x35, 0x6a, 0x62, 0x32, 0x30,
+    0x77, 0x67, 0x5a, 0x38, 0x77, 0x44, 0x51, 0x59, 0x4a, 0x4b, 0x6f, 0x5a,
+    0x49, 0x68, 0x76, 0x63, 0x4e, 0x41, 0x51, 0x45, 0x42, 0x42, 0x51, 0x41,
+    0x44, 0x67, 0x59, 0x30, 0x41, 0x4d, 0x49, 0x47, 0x4a, 0x41, 0x6f, 0x47,
+    0x42, 0x41, 0x4f, 0x48, 0x44, 0x46, 0x53, 0x63, 0x6f, 0x0a, 0x4c, 0x43,
+    0x56, 0x4a, 0x70, 0x59, 0x44, 0x44, 0x4d, 0x34, 0x48, 0x59, 0x74, 0x49,
+    0x64, 0x56, 0x36, 0x41, 0x6b, 0x65, 0x2f, 0x73, 0x4d, 0x4e, 0x61, 0x61,
+    0x4b, 0x64, 0x4f, 0x44, 0x6a, 0x44, 0x4d, 0x73, 0x75, 0x78, 0x2f, 0x34,
+    0x74, 0x44, 0x79, 0x64, 0x6c, 0x75, 0x6d, 0x4e, 0x2b, 0x66, 0x6d, 0x2b,
+    0x41, 0x6a, 0x50, 0x45, 0x4b, 0x35, 0x47, 0x48, 0x68, 0x47, 0x6e, 0x31,
+    0x42, 0x67, 0x0a, 0x7a, 0x6b, 0x57, 0x46, 0x2b, 0x73, 0x6c, 0x66, 0x33,
+    0x42, 0x78, 0x68, 0x72, 0x41, 0x2f, 0x38, 0x64, 0x4e, 0x73, 0x6e, 0x75,
+    0x6e, 0x73, 0x74, 0x56, 0x41, 0x37, 0x5a, 0x42, 0x67, 0x41, 0x2f, 0x35,
+    0x71, 0x51, 0x78, 0x4d, 0x66, 0x47, 0x41, 0x71, 0x34, 0x77, 0x48, 0x4e,
+    0x56, 0x58, 0x37, 0x37, 0x66, 0x42, 0x5a, 0x4f, 0x67, 0x70, 0x39, 0x56,
+    0x6c, 0x53, 0x4d, 0x56, 0x66, 0x79, 0x64, 0x0a, 0x39, 0x4e, 0x38, 0x59,
+    0x77, 0x62, 0x42, 0x59, 0x41, 0x63, 0x6b, 0x4f, 0x65, 0x55, 0x51, 0x61,
+    0x64, 0x54, 0x69, 0x32, 0x58, 0x31, 0x53, 0x36, 0x4f, 0x67, 0x4a, 0x58,
+    0x67, 0x51, 0x30, 0x6d, 0x33, 0x4d, 0x57, 0x68, 0x41, 0x67, 0x4d, 0x42,
+    0x41, 0x41, 0x47, 0x6a, 0x61, 0x7a, 0x42, 0x70, 0x4d, 0x41, 0x6b, 0x47,
+    0x41, 0x31, 0x55, 0x64, 0x45, 0x77, 0x51, 0x43, 0x4d, 0x41, 0x41, 0x77,
+    0x0a, 0x43, 0x77, 0x59, 0x44, 0x56, 0x52, 0x30, 0x50, 0x42, 0x41, 0x51,
+    0x44, 0x41, 0x67, 0x58, 0x67, 0x4d, 0x45, 0x38, 0x47, 0x41, 0x31, 0x55,
+    0x64, 0x45, 0x51, 0x52, 0x49, 0x4d, 0x45, 0x61, 0x43, 0x45, 0x43, 0x6f,
+    0x75, 0x64, 0x47, 0x56, 0x7a, 0x64, 0x43, 0x35, 0x6e, 0x62, 0x32, 0x39,
+    0x6e, 0x62, 0x47, 0x55, 0x75, 0x5a, 0x6e, 0x4b, 0x43, 0x47, 0x48, 0x64,
+    0x68, 0x64, 0x47, 0x56, 0x79, 0x0a, 0x65, 0x6d, 0x39, 0x76, 0x61, 0x53,
+    0x35, 0x30, 0x5a, 0x58, 0x4e, 0x30, 0x4c, 0x6d, 0x64, 0x76, 0x62, 0x32,
+    0x64, 0x73, 0x5a, 0x53, 0x35, 0x69, 0x5a, 0x59, 0x49, 0x53, 0x4b, 0x69,
+    0x35, 0x30, 0x5a, 0x58, 0x4e, 0x30, 0x4c, 0x6e, 0x6c, 0x76, 0x64, 0x58,
+    0x52, 0x31, 0x59, 0x6d, 0x55, 0x75, 0x59, 0x32, 0x39, 0x74, 0x68, 0x77,
+    0x54, 0x41, 0x71, 0x41, 0x45, 0x44, 0x4d, 0x41, 0x30, 0x47, 0x0a, 0x43,
+    0x53, 0x71, 0x47, 0x53, 0x49, 0x62, 0x33, 0x44, 0x51, 0x45, 0x42, 0x43,
+    0x77, 0x55, 0x41, 0x41, 0x34, 0x47, 0x42, 0x41, 0x4a, 0x46, 0x58, 0x56,
+    0x69, 0x66, 0x51, 0x4e, 0x75, 0x62, 0x31, 0x4c, 0x55, 0x50, 0x34, 0x4a,
+    0x6c, 0x6e, 0x58, 0x35, 0x6c, 0x58, 0x4e, 0x6c, 0x6f, 0x38, 0x46, 0x78,
+    0x5a, 0x32, 0x61, 0x31, 0x32, 0x41, 0x46, 0x51, 0x73, 0x2b, 0x62, 0x7a,
+    0x6f, 0x4a, 0x36, 0x0a, 0x68, 0x4d, 0x30, 0x34, 0x34, 0x45, 0x44, 0x6a,
+    0x71, 0x79, 0x78, 0x55, 0x71, 0x53, 0x62, 0x56, 0x65, 0x50, 0x4b, 0x30,
+    0x6e, 0x69, 0x33, 0x77, 0x31, 0x66, 0x48, 0x51, 0x42, 0x35, 0x72, 0x59,
+    0x39, 0x79, 0x59, 0x43, 0x35, 0x66, 0x38, 0x47, 0x37, 0x61, 0x71, 0x71,
+    0x54, 0x59, 0x31, 0x51, 0x4f, 0x68, 0x6f, 0x55, 0x6b, 0x38, 0x5a, 0x54,
+    0x53, 0x54, 0x52, 0x70, 0x6e, 0x6b, 0x54, 0x68, 0x0a, 0x79, 0x34, 0x6a,
+    0x6a, 0x64, 0x76, 0x54, 0x5a, 0x65, 0x4c, 0x44, 0x56, 0x42, 0x6c, 0x75,
+    0x65, 0x5a, 0x55, 0x54, 0x44, 0x52, 0x6d, 0x79, 0x32, 0x66, 0x65, 0x59,
+    0x35, 0x61, 0x5a, 0x49, 0x55, 0x31, 0x38, 0x76, 0x46, 0x44, 0x4b, 0x30,
+    0x38, 0x64, 0x54, 0x47, 0x30, 0x41, 0x38, 0x37, 0x70, 0x70, 0x70, 0x75,
+    0x76, 0x31, 0x4c, 0x4e, 0x49, 0x52, 0x33, 0x6c, 0x6f, 0x76, 0x65, 0x55,
+    0x38, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x45, 0x4e, 0x44, 0x20, 0x43,
     0x45, 0x52, 0x54, 0x49, 0x46, 0x49, 0x43, 0x41, 0x54, 0x45, 0x2d, 0x2d,
     0x2d, 0x2d, 0x2d, 0x0a, 0x00};
diff --git a/test/core/end2end/fixtures/h2_fakesec.c b/test/core/end2end/fixtures/h2_fakesec.c
index 3e64cc0..bc009e1 100644
--- a/test/core/end2end/fixtures/h2_fakesec.c
+++ b/test/core/end2end/fixtures/h2_fakesec.c
@@ -73,14 +73,14 @@
   cb(user_data, NULL, 0, NULL, 0, GRPC_STATUS_UNAUTHENTICATED, NULL);
 }
 
-static void chttp2_init_client_secure_fullstack(grpc_end2end_test_fixture *f,
-                                                grpc_channel_args *client_args,
-                                                grpc_credentials *creds) {
+static void chttp2_init_client_secure_fullstack(
+    grpc_end2end_test_fixture *f, grpc_channel_args *client_args,
+    grpc_channel_credentials *creds) {
   fullstack_secure_fixture_data *ffd = f->fixture_data;
   f->client =
       grpc_secure_channel_create(creds, ffd->localaddr, client_args, NULL);
   GPR_ASSERT(f->client != NULL);
-  grpc_credentials_release(creds);
+  grpc_channel_credentials_release(creds);
 }
 
 static void chttp2_init_server_secure_fullstack(
@@ -106,7 +106,7 @@
 
 static void chttp2_init_client_fake_secure_fullstack(
     grpc_end2end_test_fixture *f, grpc_channel_args *client_args) {
-  grpc_credentials *fake_ts_creds =
+  grpc_channel_credentials *fake_ts_creds =
       grpc_fake_transport_security_credentials_create();
   chttp2_init_client_secure_fullstack(f, client_args, fake_ts_creds);
 }
diff --git a/test/core/end2end/fixtures/h2_oauth2.c b/test/core/end2end/fixtures/h2_oauth2.c
index 10db6c2..7a34cc6 100644
--- a/test/core/end2end/fixtures/h2_oauth2.c
+++ b/test/core/end2end/fixtures/h2_oauth2.c
@@ -118,14 +118,14 @@
   return f;
 }
 
-static void chttp2_init_client_secure_fullstack(grpc_end2end_test_fixture *f,
-                                                grpc_channel_args *client_args,
-                                                grpc_credentials *creds) {
+static void chttp2_init_client_secure_fullstack(
+    grpc_end2end_test_fixture *f, grpc_channel_args *client_args,
+    grpc_channel_credentials *creds) {
   fullstack_secure_fixture_data *ffd = f->fixture_data;
   f->client =
       grpc_secure_channel_create(creds, ffd->localaddr, client_args, NULL);
   GPR_ASSERT(f->client != NULL);
-  grpc_credentials_release(creds);
+  grpc_channel_credentials_release(creds);
 }
 
 static void chttp2_init_server_secure_fullstack(
@@ -151,12 +151,12 @@
 
 static void chttp2_init_client_simple_ssl_with_oauth2_secure_fullstack(
     grpc_end2end_test_fixture *f, grpc_channel_args *client_args) {
-  grpc_credentials *ssl_creds =
+  grpc_channel_credentials *ssl_creds =
       grpc_ssl_credentials_create(test_root_cert, NULL, NULL);
-  grpc_credentials *oauth2_creds =
+  grpc_call_credentials *oauth2_creds =
       grpc_md_only_test_credentials_create("Authorization", oauth2_md, 1);
-  grpc_credentials *ssl_oauth2_creds =
-      grpc_composite_credentials_create(ssl_creds, oauth2_creds, NULL);
+  grpc_channel_credentials *ssl_oauth2_creds =
+      grpc_composite_channel_credentials_create(ssl_creds, oauth2_creds, NULL);
   grpc_arg ssl_name_override = {GRPC_ARG_STRING,
                                 GRPC_SSL_TARGET_NAME_OVERRIDE_ARG,
                                 {"foo.test.google.fr"}};
@@ -164,8 +164,8 @@
       grpc_channel_args_copy_and_add(client_args, &ssl_name_override, 1);
   chttp2_init_client_secure_fullstack(f, new_client_args, ssl_oauth2_creds);
   grpc_channel_args_destroy(new_client_args);
-  grpc_credentials_release(ssl_creds);
-  grpc_credentials_release(oauth2_creds);
+  grpc_channel_credentials_release(ssl_creds);
+  grpc_call_credentials_release(oauth2_creds);
 }
 
 static int fail_server_auth_check(grpc_channel_args *server_args) {
diff --git a/test/core/end2end/fixtures/h2_ssl+poll.c b/test/core/end2end/fixtures/h2_ssl+poll.c
index c2f41f4..37e1758 100644
--- a/test/core/end2end/fixtures/h2_ssl+poll.c
+++ b/test/core/end2end/fixtures/h2_ssl+poll.c
@@ -76,14 +76,14 @@
   cb(user_data, NULL, 0, NULL, 0, GRPC_STATUS_UNAUTHENTICATED, NULL);
 }
 
-static void chttp2_init_client_secure_fullstack(grpc_end2end_test_fixture *f,
-                                                grpc_channel_args *client_args,
-                                                grpc_credentials *creds) {
+static void chttp2_init_client_secure_fullstack(
+    grpc_end2end_test_fixture *f, grpc_channel_args *client_args,
+    grpc_channel_credentials *creds) {
   fullstack_secure_fixture_data *ffd = f->fixture_data;
   f->client =
       grpc_secure_channel_create(creds, ffd->localaddr, client_args, NULL);
   GPR_ASSERT(f->client != NULL);
-  grpc_credentials_release(creds);
+  grpc_channel_credentials_release(creds);
 }
 
 static void chttp2_init_server_secure_fullstack(
@@ -109,7 +109,8 @@
 
 static void chttp2_init_client_simple_ssl_secure_fullstack(
     grpc_end2end_test_fixture *f, grpc_channel_args *client_args) {
-  grpc_credentials *ssl_creds = grpc_ssl_credentials_create(NULL, NULL, NULL);
+  grpc_channel_credentials *ssl_creds =
+      grpc_ssl_credentials_create(NULL, NULL, NULL);
   grpc_arg ssl_name_override = {GRPC_ARG_STRING,
                                 GRPC_SSL_TARGET_NAME_OVERRIDE_ARG,
                                 {"foo.test.google.fr"}};
diff --git a/test/core/end2end/fixtures/h2_ssl.c b/test/core/end2end/fixtures/h2_ssl.c
index 896c60c..f5a006b 100644
--- a/test/core/end2end/fixtures/h2_ssl.c
+++ b/test/core/end2end/fixtures/h2_ssl.c
@@ -76,14 +76,14 @@
   cb(user_data, NULL, 0, NULL, 0, GRPC_STATUS_UNAUTHENTICATED, NULL);
 }
 
-static void chttp2_init_client_secure_fullstack(grpc_end2end_test_fixture *f,
-                                                grpc_channel_args *client_args,
-                                                grpc_credentials *creds) {
+static void chttp2_init_client_secure_fullstack(
+    grpc_end2end_test_fixture *f, grpc_channel_args *client_args,
+    grpc_channel_credentials *creds) {
   fullstack_secure_fixture_data *ffd = f->fixture_data;
   f->client =
       grpc_secure_channel_create(creds, ffd->localaddr, client_args, NULL);
   GPR_ASSERT(f->client != NULL);
-  grpc_credentials_release(creds);
+  grpc_channel_credentials_release(creds);
 }
 
 static void chttp2_init_server_secure_fullstack(
@@ -109,7 +109,8 @@
 
 static void chttp2_init_client_simple_ssl_secure_fullstack(
     grpc_end2end_test_fixture *f, grpc_channel_args *client_args) {
-  grpc_credentials *ssl_creds = grpc_ssl_credentials_create(NULL, NULL, NULL);
+  grpc_channel_credentials *ssl_creds =
+      grpc_ssl_credentials_create(NULL, NULL, NULL);
   grpc_arg ssl_name_override = {GRPC_ARG_STRING,
                                 GRPC_SSL_TARGET_NAME_OVERRIDE_ARG,
                                 {"foo.test.google.fr"}};
diff --git a/test/core/end2end/fixtures/h2_ssl_proxy.c b/test/core/end2end/fixtures/h2_ssl_proxy.c
index 413a8b8..7233cdb 100644
--- a/test/core/end2end/fixtures/h2_ssl_proxy.c
+++ b/test/core/end2end/fixtures/h2_ssl_proxy.c
@@ -66,7 +66,8 @@
 
 static grpc_channel *create_proxy_client(const char *target) {
   grpc_channel *channel;
-  grpc_credentials *ssl_creds = grpc_ssl_credentials_create(NULL, NULL, NULL);
+  grpc_channel_credentials *ssl_creds =
+      grpc_ssl_credentials_create(NULL, NULL, NULL);
   grpc_arg ssl_name_override = {GRPC_ARG_STRING,
                                 GRPC_SSL_TARGET_NAME_OVERRIDE_ARG,
                                 {"foo.test.google.fr"}};
@@ -74,7 +75,7 @@
   client_args.num_args = 1;
   client_args.args = &ssl_name_override;
   channel = grpc_secure_channel_create(ssl_creds, target, &client_args, NULL);
-  grpc_credentials_release(ssl_creds);
+  grpc_channel_credentials_release(ssl_creds);
   return channel;
 }
 
@@ -104,15 +105,15 @@
   cb(user_data, NULL, 0, NULL, 0, GRPC_STATUS_UNAUTHENTICATED, NULL);
 }
 
-static void chttp2_init_client_secure_fullstack(grpc_end2end_test_fixture *f,
-                                                grpc_channel_args *client_args,
-                                                grpc_credentials *creds) {
+static void chttp2_init_client_secure_fullstack(
+    grpc_end2end_test_fixture *f, grpc_channel_args *client_args,
+    grpc_channel_credentials *creds) {
   fullstack_secure_fixture_data *ffd = f->fixture_data;
   f->client = grpc_secure_channel_create(
       creds, grpc_end2end_proxy_get_client_target(ffd->proxy), client_args,
       NULL);
   GPR_ASSERT(f->client != NULL);
-  grpc_credentials_release(creds);
+  grpc_channel_credentials_release(creds);
 }
 
 static void chttp2_init_server_secure_fullstack(
@@ -138,7 +139,8 @@
 
 static void chttp2_init_client_simple_ssl_secure_fullstack(
     grpc_end2end_test_fixture *f, grpc_channel_args *client_args) {
-  grpc_credentials *ssl_creds = grpc_ssl_credentials_create(NULL, NULL, NULL);
+  grpc_channel_credentials *ssl_creds =
+      grpc_ssl_credentials_create(NULL, NULL, NULL);
   grpc_arg ssl_name_override = {GRPC_ARG_STRING,
                                 GRPC_SSL_TARGET_NAME_OVERRIDE_ARG,
                                 {"foo.test.google.fr"}};
diff --git a/test/core/end2end/fixtures/proxy.c b/test/core/end2end/fixtures/proxy.c
index 1090ad6..434e75d 100644
--- a/test/core/end2end/fixtures/proxy.c
+++ b/test/core/end2end/fixtures/proxy.c
@@ -146,7 +146,6 @@
 }
 
 static void unrefpc(proxy_call *pc, const char *reason) {
-  gpr_log(GPR_DEBUG, "PROXY UNREF %s", reason);
   if (gpr_unref(&pc->refs)) {
     grpc_call_destroy(pc->c2p);
     grpc_call_destroy(pc->p2s);
@@ -158,10 +157,7 @@
   }
 }
 
-static void refpc(proxy_call *pc, const char *reason) {
-  gpr_log(GPR_DEBUG, "PROXY   REF %s", reason);
-  gpr_ref(&pc->refs);
-}
+static void refpc(proxy_call *pc, const char *reason) { gpr_ref(&pc->refs); }
 
 static void on_c2p_sent_initial_metadata(void *arg, int success) {
   proxy_call *pc = arg;
diff --git a/test/core/end2end/gen_build_yaml.py b/test/core/end2end/gen_build_yaml.py
index 38d3b22..33687b8 100755
--- a/test/core/end2end/gen_build_yaml.py
+++ b/test/core/end2end/gen_build_yaml.py
@@ -37,8 +37,8 @@
 import hashlib
 
 
-FixtureOptions = collections.namedtuple('FixtureOptions', 'fullstack includes_proxy dns_resolver secure platforms ci_mac')
-default_unsecure_fixture_options = FixtureOptions(True, False, True, False, ['windows', 'linux', 'mac', 'posix'], True)
+FixtureOptions = collections.namedtuple('FixtureOptions', 'fullstack includes_proxy dns_resolver secure platforms ci_mac tracing')
+default_unsecure_fixture_options = FixtureOptions(True, False, True, False, ['windows', 'linux', 'mac', 'posix'], True, False)
 socketpair_unsecure_fixture_options = default_unsecure_fixture_options._replace(fullstack=False, dns_resolver=False)
 default_secure_fixture_options = default_unsecure_fixture_options._replace(secure=True)
 uds_fixture_options = default_unsecure_fixture_options._replace(dns_resolver=False, platforms=['linux', 'mac', 'posix'])
@@ -54,7 +54,7 @@
     'h2_proxy': default_unsecure_fixture_options._replace(includes_proxy=True, ci_mac=False),
     'h2_sockpair_1byte': socketpair_unsecure_fixture_options._replace(ci_mac=False),
     'h2_sockpair': socketpair_unsecure_fixture_options._replace(ci_mac=False),
-    'h2_sockpair+trace': socketpair_unsecure_fixture_options,
+    'h2_sockpair+trace': socketpair_unsecure_fixture_options._replace(tracing=True),
     'h2_ssl': default_secure_fixture_options,
     'h2_ssl+poll': default_secure_fixture_options._replace(platforms=['linux']),
     'h2_ssl_proxy': default_secure_fixture_options._replace(includes_proxy=True, ci_mac=False),
@@ -63,8 +63,8 @@
     'h2_uds': uds_fixture_options,
 }
 
-TestOptions = collections.namedtuple('TestOptions', 'needs_fullstack needs_dns proxyable flaky secure')
-default_test_options = TestOptions(False, False, True, False, False)
+TestOptions = collections.namedtuple('TestOptions', 'needs_fullstack needs_dns proxyable flaky secure traceable')
+default_test_options = TestOptions(False, False, True, False, False, True)
 connectivity_test_options = default_test_options._replace(needs_fullstack=True)
 
 # maps test names to options
@@ -85,6 +85,7 @@
     'disappearing_server': connectivity_test_options,
     'empty_batch': default_test_options,
     'graceful_server_shutdown': default_test_options,
+    'hpack_size': default_test_options._replace(proxyable=False, traceable=False),
     'high_initial_seqno': default_test_options,
     'invoke_large_request': default_test_options,
     'large_metadata': default_test_options,
@@ -117,6 +118,9 @@
   if not END2END_TESTS[t].proxyable:
     if END2END_FIXTURES[f].includes_proxy:
       return False
+  if not END2END_TESTS[t].traceable:
+    if END2END_FIXTURES[f].tracing:
+      return False
   return True
 
 
diff --git a/test/core/end2end/tests/call_creds.c b/test/core/end2end/tests/call_creds.c
index 4aeade1..bbfad21 100644
--- a/test/core/end2end/tests/call_creds.c
+++ b/test/core/end2end/tests/call_creds.c
@@ -132,27 +132,6 @@
   }
 }
 
-static void test_call_creds_failure(grpc_end2end_test_config config) {
-  grpc_call *c;
-  grpc_credentials *creds = NULL;
-  grpc_end2end_test_fixture f =
-      begin_test(config, "test_call_creds_failure", 0);
-  gpr_timespec deadline = five_seconds_time();
-  c = grpc_channel_create_call(f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
-                               "/foo", "foo.test.google.fr", deadline, NULL);
-  GPR_ASSERT(c);
-
-  /* Try with credentials unfit to be set on a call (channel creds). */
-  creds = grpc_fake_transport_security_credentials_create();
-  GPR_ASSERT(grpc_call_set_credentials(c, creds) != GRPC_CALL_OK);
-  grpc_credentials_release(creds);
-
-  grpc_call_destroy(c);
-
-  end_test(&f);
-  config.tear_down_data(&f);
-}
-
 static void request_response_with_payload_and_call_creds(
     const char *test_name, grpc_end2end_test_config config,
     override_mode mode) {
@@ -180,7 +159,7 @@
   char *details = NULL;
   size_t details_capacity = 0;
   int was_cancelled = 2;
-  grpc_credentials *creds = NULL;
+  grpc_call_credentials *creds = NULL;
   grpc_auth_context *s_auth_context = NULL;
   grpc_auth_context *c_auth_context = NULL;
 
@@ -197,7 +176,7 @@
     case NONE:
       break;
     case OVERRIDE:
-      grpc_credentials_release(creds);
+      grpc_call_credentials_release(creds);
       creds = grpc_google_iam_credentials_create(overridden_iam_token,
                                                  overridden_iam_selector, NULL);
       GPR_ASSERT(creds != NULL);
@@ -207,7 +186,7 @@
       GPR_ASSERT(grpc_call_set_credentials(c, NULL) == GRPC_CALL_OK);
       break;
   }
-  grpc_credentials_release(creds);
+  grpc_call_credentials_release(creds);
 
   grpc_metadata_array_init(&initial_metadata_recv);
   grpc_metadata_array_init(&trailing_metadata_recv);
@@ -412,7 +391,7 @@
   gpr_slice request_payload_slice = gpr_slice_from_copied_string("hello world");
   grpc_byte_buffer *request_payload =
       grpc_raw_byte_buffer_create(&request_payload_slice, 1);
-  grpc_credentials *creds;
+  grpc_call_credentials *creds;
 
   f = begin_test(config, "test_request_with_server_rejecting_client_creds", 1);
   cqv = cq_verifier_create(f.cq);
@@ -424,7 +403,7 @@
   creds = grpc_google_iam_credentials_create(iam_token, iam_selector, NULL);
   GPR_ASSERT(creds != NULL);
   GPR_ASSERT(grpc_call_set_credentials(c, creds) == GRPC_CALL_OK);
-  grpc_credentials_release(creds);
+  grpc_call_credentials_release(creds);
 
   grpc_metadata_array_init(&initial_metadata_recv);
   grpc_metadata_array_init(&trailing_metadata_recv);
@@ -490,7 +469,6 @@
 
 void grpc_end2end_tests(grpc_end2end_test_config config) {
   if (config.feature_mask & FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS) {
-    test_call_creds_failure(config);
     test_request_response_with_payload_and_call_creds(config);
     test_request_response_with_payload_and_overridden_call_creds(config);
     test_request_response_with_payload_and_deleted_call_creds(config);
diff --git a/test/core/end2end/tests/cancel_with_status.c b/test/core/end2end/tests/cancel_with_status.c
index eecfa83..2005e5f 100644
--- a/test/core/end2end/tests/cancel_with_status.c
+++ b/test/core/end2end/tests/cancel_with_status.c
@@ -166,7 +166,8 @@
   cq_verifier_destroy(cqv);
 }
 
-static void test_invoke_simple_request(grpc_end2end_test_config config, size_t num_ops) {
+static void test_invoke_simple_request(grpc_end2end_test_config config,
+                                       size_t num_ops) {
   grpc_end2end_test_fixture f;
 
   f = begin_test(config, "test_invoke_simple_request", NULL, NULL);
diff --git a/test/core/end2end/tests/hpack_size.c b/test/core/end2end/tests/hpack_size.c
new file mode 100644
index 0000000..997969d
--- /dev/null
+++ b/test/core/end2end/tests/hpack_size.c
@@ -0,0 +1,446 @@
+/*
+ *
+ * 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 "test/core/end2end/end2end_tests.h"
+
+#include <stdio.h>
+#include <string.h>
+
+#include <grpc/byte_buffer.h>
+#include <grpc/grpc.h>
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/string_util.h>
+#include <grpc/support/time.h>
+#include <grpc/support/useful.h>
+
+#include "src/core/support/string.h"
+#include "test/core/end2end/cq_verifier.h"
+
+static void *tag(gpr_intptr t) { return (void *)t; }
+
+const char *hobbits[][2] = {{"Adaldrida", "Brandybuck"},
+                            {"Adamanta", "Took"},
+                            {"Adalgrim", "Took"},
+                            {"Adelard", "Took"},
+                            {"Amaranth", "Brandybuck"},
+                            {"Andwise", "Roper"},
+                            {"Angelica", "Baggins"},
+                            {"Asphodel", "Burrows"},
+                            {"Balbo", "Baggins"},
+                            {"Bandobras", "Took"},
+                            {"Belba", "Bolger"},
+                            {"Bell", "Gamgee"},
+                            {"Belladonna", "Baggins"},
+                            {"Berylla", "Baggins"},
+                            {"Bilbo", "Baggins"},
+                            {"Bilbo", "Gardner"},
+                            {"Bill", "Butcher"},
+                            {"Bingo", "Baggins"},
+                            {"Bodo", "Proudfoot"},
+                            {"Bowman", "Cotton"},
+                            {"Bungo", "Baggins"},
+                            {"Camellia", "Sackville"},
+                            {"Carl", "Cotton"},
+                            {"Celandine", "Brandybuck"},
+                            {"Chica", "Baggins"},
+                            {"Daddy", "Twofoot"},
+                            {"Daisy", "Boffin"},
+                            {"Diamond", "Took"},
+                            {"Dinodas", "Brandybuck"},
+                            {"Doderic", "Brandybuck"},
+                            {"Dodinas", "Brandybuck"},
+                            {"Donnamira", "Boffin"},
+                            {"Dora", "Baggins"},
+                            {"Drogo", "Baggins"},
+                            {"Dudo", "Baggins"},
+                            {"Eglantine", "Took"},
+                            {"Elanor", "Fairbairn"},
+                            {"Elfstan", "Fairbairn"},
+                            {"Esmeralda", "Brandybuck"},
+                            {"Estella", "Brandybuck"},
+                            {"Everard", "Took"},
+                            {"Falco", "Chubb-Baggins"},
+                            {"Faramir", "Took"},
+                            {"Farmer", "Maggot"},
+                            {"Fastolph", "Bolger"},
+                            {"Ferdibrand", "Took"},
+                            {"Ferdinand", "Took"},
+                            {"Ferumbras", "Took"},
+                            {"Ferumbras", "Took"},
+                            {"Filibert", "Bolger"},
+                            {"Firiel", "Fairbairn"},
+                            {"Flambard", "Took"},
+                            {"Folco", "Boffin"},
+                            {"Fortinbras", "Took"},
+                            {"Fortinbras", "Took"},
+                            {"Fosco", "Baggins"},
+                            {"Fredegar", "Bolger"},
+                            {"Frodo", "Baggins"},
+                            {"Frodo", "Gardner"},
+                            {"Gerontius", "Took"},
+                            {"Gilly", "Baggins"},
+                            {"Goldilocks", "Took"},
+                            {"Gorbadoc", "Brandybuck"},
+                            {"Gorbulas", "Brandybuck"},
+                            {"Gorhendad", "Brandybuck"},
+                            {"Gormadoc", "Brandybuck"},
+                            {"Griffo", "Boffin"},
+                            {"Halfast", "Gamgee"},
+                            {"Halfred", "Gamgee"},
+                            {"Halfred", "Greenhand"},
+                            {"Hanna", "Brandybuck"},
+                            {"Hamfast", "Gamgee"},
+                            {"Hamfast", "Gardner"},
+                            {"Hamson", "Gamgee"},
+                            {"Harding", "Gardner"},
+                            {"Hilda", "Brandybuck"},
+                            {"Hildibrand", "Took"},
+                            {"Hildifons", "Took"},
+                            {"Hildigard", "Took"},
+                            {"Hildigrim", "Took"},
+                            {"Hob", "Gammidge"},
+                            {"Hob", "Hayward"},
+                            {"Hobson", "Gamgee"},
+                            {"Holfast", "Gardner"},
+                            {"Holman", "Cotton"},
+                            {"Holman", "Greenhand"},
+                            {"Hugo", "Boffin"},
+                            {"Hugo", "Bracegirdle"},
+                            {"Ilberic", "Brandybuck"},
+                            {"Isembard", "Took"},
+                            {"Isembold", "Took"},
+                            {"Isengar", "Took"},
+                            {"Isengrim", "Took"},
+                            {"Isengrim", "Took"},
+                            {"Isumbras", "Took"},
+                            {"Isumbras", "Took"},
+                            {"Jolly", "Cotton"},
+                            {"Lalia", "Took"},
+                            {"Largo", "Baggins"},
+                            {"Laura", "Baggins"},
+                            {"Lily", "Goodbody"},
+                            {"Lily", "Cotton"},
+                            {"Linda", "Proudfoot"},
+                            {"Lobelia", "Sackville-Baggins"},
+                            {"Longo", "Baggins"},
+                            {"Lotho", "Sackville-Baggins"},
+                            {"Madoc", "Brandybuck"},
+                            {"Malva", "Brandybuck"},
+                            {"Marigold", "Cotton"},
+                            {"Marmadas", "Brandybuck"},
+                            {"Marmadoc", "Brandybuck"},
+                            {"Marroc", "Brandybuck"},
+                            {"May", "Gamgee"},
+                            {"Melilot", "Brandybuck"},
+                            {"Menegilda", "Brandybuck"},
+                            {"Mentha", "Brandybuck"},
+                            {"Meriadoc", "Brandybuck"},
+                            {"Merimac", "Brandybuck"},
+                            {"Merimas", "Brandybuck"},
+                            {"Merry", "Gardner"},
+                            {"Milo", "Burrows"},
+                            {"Mimosa", "Baggins"},
+                            {"Minto", "Burrows"},
+                            {"Mirabella", "Brandybuck"},
+                            {"Moro", "Burrows"},
+                            {"Mosco", "Burrows"},
+                            {"Mungo", "Baggins"},
+                            {"Myrtle", "Burrows"},
+                            {"Odo", "Proudfoot"},
+                            {"Odovacar", "Bolger"},
+                            {"Olo", "Proudfoot"},
+                            {"Orgulas", "Brandybuck"},
+                            {"Otho", "Sackville-Baggins"},
+                            {"Paladin", "Took"},
+                            {"Pansy", "Bolger"},
+                            {"Pearl", "Took"},
+                            {"Peony", "Burrows"},
+                            {"Peregrin", "Took"},
+                            {"Pervinca", "Took"},
+                            {"Pimpernel", "Took"},
+                            {"Pippin", "Gardner"},
+                            {"Polo", "Baggins"},
+                            {"Ponto", "Baggins"},
+                            {"Porto", "Baggins"},
+                            {"Posco", "Baggins"},
+                            {"Poppy", "Bolger"},
+                            {"Primrose", "Gardner"},
+                            {"Primula", "Baggins"},
+                            {"Prisca", "Bolger"},
+                            {"Reginard", "Took"},
+                            {"Robin", "Smallburrow"},
+                            {"Robin", "Gardner"},
+                            {"Rorimac", "Brandybuck"},
+                            {"Rosa", "Took"},
+                            {"Rosamunda", "Bolger"},
+                            {"Rose", "Gardner"},
+                            {"Ruby", "Baggins"},
+                            {"Ruby", "Gardner"},
+                            {"Rudigar", "Bolger"},
+                            {"Rufus", "Burrows"},
+                            {"Sadoc", "Brandybuck"},
+                            {"Salvia", "Bolger"},
+                            {"Samwise", "Gamgee"},
+                            {"Sancho", "Proudfoot"},
+                            {"Saradas", "Brandybuck"},
+                            {"Saradoc", "Brandybuck"},
+                            {"Seredic", "Brandybuck"},
+                            {"Sigismond", "Took"},
+                            {"Smeagol", "Gollum"},
+                            {"Tanta", "Baggins"},
+                            {"Ted", "Sandyman"},
+                            {"Tobold", "Hornblower"},
+                            {"Togo", "Goodbody"},
+                            {"Tolman", "Cotton"},
+                            {"Tolman", "Gardner"},
+                            {"Widow", "Rumble"},
+                            {"Wilcome", "Cotton"},
+                            {"Wilcome", "Cotton"},
+                            {"Wilibald", "Bolger"},
+                            {"Will", "Whitfoot"},
+                            {"Wiseman", "Gamwich"}};
+
+const char *dragons[] = {"Ancalagon", "Glaurung", "Scatha",
+                         "Smaug the Magnificent"};
+
+static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
+                                            const char *test_name,
+                                            grpc_channel_args *client_args,
+                                            grpc_channel_args *server_args) {
+  grpc_end2end_test_fixture f;
+  gpr_log(GPR_INFO, "%s/%s", test_name, config.name);
+  f = config.create_fixture(client_args, server_args);
+  config.init_client(&f, client_args);
+  config.init_server(&f, server_args);
+  return f;
+}
+
+static gpr_timespec n_seconds_time(int n) {
+  return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n);
+}
+
+static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); }
+
+static void drain_cq(grpc_completion_queue *cq) {
+  grpc_event ev;
+  do {
+    ev = grpc_completion_queue_next(cq, five_seconds_time(), NULL);
+  } while (ev.type != GRPC_QUEUE_SHUTDOWN);
+}
+
+static void shutdown_server(grpc_end2end_test_fixture *f) {
+  if (!f->server) return;
+  grpc_server_shutdown_and_notify(f->server, f->cq, tag(1000));
+  GPR_ASSERT(grpc_completion_queue_pluck(f->cq, tag(1000),
+                                         GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5),
+                                         NULL).type == GRPC_OP_COMPLETE);
+  grpc_server_destroy(f->server);
+  f->server = NULL;
+}
+
+static void shutdown_client(grpc_end2end_test_fixture *f) {
+  if (!f->client) return;
+  grpc_channel_destroy(f->client);
+  f->client = NULL;
+}
+
+static void end_test(grpc_end2end_test_fixture *f) {
+  shutdown_server(f);
+  shutdown_client(f);
+
+  grpc_completion_queue_shutdown(f->cq);
+  drain_cq(f->cq);
+  grpc_completion_queue_destroy(f->cq);
+}
+
+static void simple_request_body(grpc_end2end_test_fixture f, size_t index) {
+  grpc_call *c;
+  grpc_call *s;
+  gpr_timespec deadline = five_seconds_time();
+  cq_verifier *cqv = cq_verifier_create(f.cq);
+  grpc_op ops[6];
+  grpc_op *op;
+  grpc_metadata_array initial_metadata_recv;
+  grpc_metadata_array trailing_metadata_recv;
+  grpc_metadata_array request_metadata_recv;
+  grpc_call_details call_details;
+  grpc_status_code status;
+  grpc_call_error error;
+  grpc_metadata extra_metadata[3];
+  char *details = NULL;
+  size_t details_capacity = 0;
+  int was_cancelled = 2;
+
+  memset(extra_metadata, 0, sizeof(extra_metadata));
+  extra_metadata[0].key = "hobbit-first-name";
+  extra_metadata[0].value = hobbits[index % GPR_ARRAY_SIZE(hobbits)][0];
+  extra_metadata[0].value_length = strlen(extra_metadata[0].value);
+  extra_metadata[1].key = "hobbit-second-name";
+  extra_metadata[1].value = hobbits[index % GPR_ARRAY_SIZE(hobbits)][1];
+  extra_metadata[1].value_length = strlen(extra_metadata[1].value);
+  extra_metadata[2].key = "dragon";
+  extra_metadata[2].value = dragons[index % GPR_ARRAY_SIZE(dragons)];
+  extra_metadata[2].value_length = strlen(extra_metadata[2].value);
+
+  c = grpc_channel_create_call(f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
+                               "/foo", "foo.test.google.fr:1234", deadline,
+                               NULL);
+  GPR_ASSERT(c);
+
+  grpc_metadata_array_init(&initial_metadata_recv);
+  grpc_metadata_array_init(&trailing_metadata_recv);
+  grpc_metadata_array_init(&request_metadata_recv);
+  grpc_call_details_init(&call_details);
+
+  op = ops;
+  op->op = GRPC_OP_SEND_INITIAL_METADATA;
+  op->data.send_initial_metadata.count = GPR_ARRAY_SIZE(extra_metadata);
+  op->data.send_initial_metadata.metadata = extra_metadata;
+  op->flags = 0;
+  op->reserved = NULL;
+  op++;
+  op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
+  op->flags = 0;
+  op->reserved = NULL;
+  op++;
+  op->op = GRPC_OP_RECV_INITIAL_METADATA;
+  op->data.recv_initial_metadata = &initial_metadata_recv;
+  op->flags = 0;
+  op->reserved = NULL;
+  op++;
+  op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
+  op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
+  op->data.recv_status_on_client.status = &status;
+  op->data.recv_status_on_client.status_details = &details;
+  op->data.recv_status_on_client.status_details_capacity = &details_capacity;
+  op->flags = 0;
+  op->reserved = NULL;
+  op++;
+  error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), NULL);
+  GPR_ASSERT(GRPC_CALL_OK == error);
+
+  error =
+      grpc_server_request_call(f.server, &s, &call_details,
+                               &request_metadata_recv, f.cq, f.cq, tag(101));
+  GPR_ASSERT(GRPC_CALL_OK == error);
+  cq_expect_completion(cqv, tag(101), 1);
+  cq_verify(cqv);
+
+  op = ops;
+  op->op = GRPC_OP_SEND_INITIAL_METADATA;
+  op->data.send_initial_metadata.count = 0;
+  op->flags = 0;
+  op->reserved = NULL;
+  op++;
+  op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
+  op->data.send_status_from_server.trailing_metadata_count = 0;
+  op->data.send_status_from_server.status = GRPC_STATUS_UNIMPLEMENTED;
+  op->data.send_status_from_server.status_details = "xyz";
+  op->flags = 0;
+  op->reserved = NULL;
+  op++;
+  op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
+  op->data.recv_close_on_server.cancelled = &was_cancelled;
+  op->flags = 0;
+  op->reserved = NULL;
+  op++;
+  error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), NULL);
+  GPR_ASSERT(GRPC_CALL_OK == error);
+
+  cq_expect_completion(cqv, tag(102), 1);
+  cq_expect_completion(cqv, tag(1), 1);
+  cq_verify(cqv);
+
+  GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED);
+  GPR_ASSERT(0 == strcmp(details, "xyz"));
+  GPR_ASSERT(0 == strcmp(call_details.method, "/foo"));
+  GPR_ASSERT(0 == strcmp(call_details.host, "foo.test.google.fr:1234"));
+  GPR_ASSERT(was_cancelled == 1);
+
+  gpr_free(details);
+  grpc_metadata_array_destroy(&initial_metadata_recv);
+  grpc_metadata_array_destroy(&trailing_metadata_recv);
+  grpc_metadata_array_destroy(&request_metadata_recv);
+  grpc_call_details_destroy(&call_details);
+
+  grpc_call_destroy(c);
+  grpc_call_destroy(s);
+
+  cq_verifier_destroy(cqv);
+}
+
+static void test_size(grpc_end2end_test_config config, int encode_size,
+                      int decode_size) {
+  size_t i;
+  grpc_end2end_test_fixture f;
+  grpc_arg server_arg;
+  grpc_channel_args server_args;
+  grpc_arg client_arg;
+  grpc_channel_args client_args;
+  char *name;
+
+  server_arg.type = GRPC_ARG_INTEGER;
+  server_arg.key = GRPC_ARG_HTTP2_HPACK_TABLE_SIZE_DECODER;
+  server_arg.value.integer = decode_size;
+  server_args.num_args = 1;
+  server_args.args = &server_arg;
+
+  client_arg.type = GRPC_ARG_INTEGER;
+  client_arg.key = GRPC_ARG_HTTP2_HPACK_TABLE_SIZE_ENCODER;
+  client_arg.value.integer = encode_size;
+  client_args.num_args = 1;
+  client_args.args = &client_arg;
+
+  gpr_asprintf(&name, "test_size:e=%d:d=%d", encode_size, decode_size);
+  f = begin_test(config, name, encode_size != 4096 ? &client_args : NULL,
+                 decode_size != 4096 ? &server_args : NULL);
+  for (i = 0; i < 4 * GPR_ARRAY_SIZE(hobbits); i++) {
+    simple_request_body(f, i);
+  }
+  end_test(&f);
+  config.tear_down_data(&f);
+  gpr_free(name);
+}
+
+void grpc_end2end_tests(grpc_end2end_test_config config) {
+  static const int interesting_sizes[] = {4096, 0,     100,
+                                          1000, 32768, 4 * 1024 * 1024};
+  size_t i, j;
+
+  for (i = 0; i < GPR_ARRAY_SIZE(interesting_sizes); i++) {
+    for (j = 0; j < GPR_ARRAY_SIZE(interesting_sizes); j++) {
+      test_size(config, interesting_sizes[i], interesting_sizes[j]);
+    }
+  }
+}
diff --git a/test/core/end2end/tests/negative_deadline.c b/test/core/end2end/tests/negative_deadline.c
index abcc1ba..8fe9e7b 100644
--- a/test/core/end2end/tests/negative_deadline.c
+++ b/test/core/end2end/tests/negative_deadline.c
@@ -163,7 +163,8 @@
   cq_verifier_destroy(cqv);
 }
 
-static void test_invoke_simple_request(grpc_end2end_test_config config, size_t num_ops) {
+static void test_invoke_simple_request(grpc_end2end_test_config config,
+                                       size_t num_ops) {
   grpc_end2end_test_fixture f;
 
   f = begin_test(config, "test_invoke_simple_request", NULL, NULL);
diff --git a/test/core/network_benchmarks/low_level_ping_pong.c b/test/core/network_benchmarks/low_level_ping_pong.c
index 7a2d894..dd1544c 100644
--- a/test/core/network_benchmarks/low_level_ping_pong.c
+++ b/test/core/network_benchmarks/low_level_ping_pong.c
@@ -139,7 +139,7 @@
       gpr_log(GPR_ERROR, "Read failed: %s", strerror(errno));
       return -1;
     }
-    bytes_read += (size_t) err2;
+    bytes_read += (size_t)err2;
   } while (bytes_read < read_size);
   return 0;
 }
@@ -174,11 +174,11 @@
     GPR_ASSERT(ev.data.fd == args->fds.read_fd);
     do {
       do {
-        err2 = read(args->fds.read_fd, buf + bytes_read,
-		    read_size - bytes_read);
+        err2 =
+            read(args->fds.read_fd, buf + bytes_read, read_size - bytes_read);
       } while (err2 < 0 && errno == EINTR);
       if (errno == EAGAIN) break;
-      bytes_read += (size_t) err2;
+      bytes_read += (size_t)err2;
       /* TODO(klempner): This should really be doing an extra call after we are
          done to ensure we see an EAGAIN */
     } while (bytes_read < read_size);
diff --git a/test/core/security/credentials_test.c b/test/core/security/credentials_test.c
index 5c1e0f4..4cfef7b 100644
--- a/test/core/security/credentials_test.c
+++ b/test/core/security/credentials_test.c
@@ -50,11 +50,24 @@
 
 #include <openssl/rsa.h>
 
+/* -- Mock channel credentials. -- */
+
+static grpc_channel_credentials *grpc_mock_channel_credentials_create(
+    const grpc_channel_credentials_vtable *vtable) {
+  grpc_channel_credentials *c = gpr_malloc(sizeof(*c));
+  memset(c, 0, sizeof(*c));
+  c->type = "mock";
+  c->vtable = vtable;
+  gpr_ref_init(&c->refcount, 1);
+  return c;
+}
+
+/* -- Constants. -- */
+
 static const char test_google_iam_authorization_token[] = "blahblahblhahb";
 static const char test_google_iam_authority_selector[] = "respectmyauthoritah";
 static const char test_oauth2_bearer_token[] =
     "Bearer blaaslkdjfaslkdfasdsfasf";
-static const char test_root_cert[] = "I am the root!";
 
 /* This JSON key was generated with the GCE console and revoked immediately.
    The identifiers have been changed as well.
@@ -113,6 +126,8 @@
 static const char test_service_url[] = "https://foo.com/foo.v1";
 static const char other_test_service_url[] = "https://bar.com/bar.v1";
 
+/* -- Utils. -- */
+
 static char *test_json_key_str(void) {
   size_t result_len = strlen(test_json_key_str_part1) +
                       strlen(test_json_key_str_part2) +
@@ -141,6 +156,8 @@
   return response;
 }
 
+/* -- Tests. -- */
+
 static void test_empty_md_store(void) {
   grpc_credentials_md_store *store = grpc_credentials_md_store_create(0);
   GPR_ASSERT(store->num_entries == 0);
@@ -219,7 +236,7 @@
   GPR_ASSERT(token_lifetime.tv_sec == 3599);
   GPR_ASSERT(token_lifetime.tv_nsec == 0);
   GPR_ASSERT(token_md->num_entries == 1);
-  GPR_ASSERT(gpr_slice_str_cmp(token_md->entries[0].key, "Authorization") == 0);
+  GPR_ASSERT(gpr_slice_str_cmp(token_md->entries[0].key, "authorization") == 0);
   GPR_ASSERT(gpr_slice_str_cmp(token_md->entries[0].value,
                                "Bearer ya29.AHES6ZRN3-HlhAPya30GnW_bHSb_") ==
              0);
@@ -319,7 +336,7 @@
                                       grpc_credentials_md *md_elems,
                                       size_t num_md,
                                       grpc_credentials_status status) {
-  grpc_credentials *c = (grpc_credentials *)user_data;
+  grpc_call_credentials *c = (grpc_call_credentials *)user_data;
   expected_md emd[] = {{GRPC_IAM_AUTHORIZATION_TOKEN_METADATA_KEY,
                         test_google_iam_authorization_token},
                        {GRPC_IAM_AUTHORITY_SELECTOR_METADATA_KEY,
@@ -327,19 +344,17 @@
   GPR_ASSERT(status == GRPC_CREDENTIALS_OK);
   GPR_ASSERT(num_md == 2);
   check_metadata(emd, md_elems, num_md);
-  grpc_credentials_unref(c);
+  grpc_call_credentials_unref(c);
 }
 
 static void test_google_iam_creds(void) {
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
-  grpc_credentials *creds = grpc_google_iam_credentials_create(
+  grpc_call_credentials *creds = grpc_google_iam_credentials_create(
       test_google_iam_authorization_token, test_google_iam_authority_selector,
       NULL);
-  GPR_ASSERT(grpc_credentials_has_request_metadata(creds));
-  GPR_ASSERT(grpc_credentials_has_request_metadata_only(creds));
-  grpc_credentials_get_request_metadata(&exec_ctx, creds, NULL,
-                                        test_service_url,
-                                        check_google_iam_metadata, creds);
+  grpc_call_credentials_get_request_metadata(&exec_ctx, creds, NULL,
+                                             test_service_url,
+                                             check_google_iam_metadata, creds);
   grpc_exec_ctx_finish(&exec_ctx);
 }
 
@@ -348,81 +363,58 @@
                                         grpc_credentials_md *md_elems,
                                         size_t num_md,
                                         grpc_credentials_status status) {
-  grpc_credentials *c = (grpc_credentials *)user_data;
+  grpc_call_credentials *c = (grpc_call_credentials *)user_data;
   expected_md emd[] = {{GRPC_AUTHORIZATION_METADATA_KEY, "Bearer blah"}};
   GPR_ASSERT(status == GRPC_CREDENTIALS_OK);
   GPR_ASSERT(num_md == 1);
   check_metadata(emd, md_elems, num_md);
-  grpc_credentials_unref(c);
+  grpc_call_credentials_unref(c);
 }
 
 static void test_access_token_creds(void) {
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
-  grpc_credentials *creds = grpc_access_token_credentials_create("blah", NULL);
-  GPR_ASSERT(grpc_credentials_has_request_metadata(creds));
-  GPR_ASSERT(grpc_credentials_has_request_metadata_only(creds));
-  GPR_ASSERT(strcmp(creds->type, GRPC_CREDENTIALS_TYPE_OAUTH2) == 0);
-  grpc_credentials_get_request_metadata(&exec_ctx, creds, NULL,
-                                        test_service_url,
-                                        check_access_token_metadata, creds);
+  grpc_call_credentials *creds =
+      grpc_access_token_credentials_create("blah", NULL);
+  GPR_ASSERT(strcmp(creds->type, GRPC_CALL_CREDENTIALS_TYPE_OAUTH2) == 0);
+  grpc_call_credentials_get_request_metadata(
+      &exec_ctx, creds, NULL, test_service_url, check_access_token_metadata,
+      creds);
   grpc_exec_ctx_finish(&exec_ctx);
 }
 
-static void check_ssl_oauth2_composite_metadata(
+static grpc_security_status check_channel_oauth2_create_security_connector(
+    grpc_channel_credentials *c, grpc_call_credentials *call_creds,
+    const char *target, const grpc_channel_args *args,
+    grpc_channel_security_connector **sc, grpc_channel_args **new_args) {
+  GPR_ASSERT(strcmp(c->type, "mock") == 0);
+  GPR_ASSERT(call_creds != NULL);
+  GPR_ASSERT(strcmp(call_creds->type, GRPC_CALL_CREDENTIALS_TYPE_OAUTH2) == 0);
+  return GRPC_SECURITY_OK;
+}
+
+static void test_channel_oauth2_composite_creds(void) {
+  grpc_channel_args *new_args;
+  grpc_channel_credentials_vtable vtable = {
+      NULL, check_channel_oauth2_create_security_connector};
+  grpc_channel_credentials *channel_creds =
+      grpc_mock_channel_credentials_create(&vtable);
+  grpc_call_credentials *oauth2_creds =
+      grpc_access_token_credentials_create("blah", NULL);
+  grpc_channel_credentials *channel_oauth2_creds =
+      grpc_composite_channel_credentials_create(channel_creds, oauth2_creds,
+                                                NULL);
+  grpc_channel_credentials_release(channel_creds);
+  grpc_call_credentials_release(oauth2_creds);
+  GPR_ASSERT(grpc_channel_credentials_create_security_connector(
+                 channel_oauth2_creds, NULL, NULL, NULL, &new_args) ==
+             GRPC_SECURITY_OK);
+  grpc_channel_credentials_release(channel_oauth2_creds);
+}
+
+static void check_oauth2_google_iam_composite_metadata(
     grpc_exec_ctx *exec_ctx, void *user_data, grpc_credentials_md *md_elems,
     size_t num_md, grpc_credentials_status status) {
-  grpc_credentials *c = (grpc_credentials *)user_data;
-  expected_md emd[] = {
-      {GRPC_AUTHORIZATION_METADATA_KEY, test_oauth2_bearer_token}};
-  GPR_ASSERT(status == GRPC_CREDENTIALS_OK);
-  GPR_ASSERT(num_md == 1);
-  check_metadata(emd, md_elems, num_md);
-  grpc_credentials_unref(c);
-}
-
-static void test_ssl_oauth2_composite_creds(void) {
-  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
-  grpc_credentials *ssl_creds =
-      grpc_ssl_credentials_create(test_root_cert, NULL, NULL);
-  const grpc_credentials_array *creds_array;
-  grpc_credentials *oauth2_creds = grpc_md_only_test_credentials_create(
-      "Authorization", test_oauth2_bearer_token, 0);
-  grpc_credentials *composite_creds =
-      grpc_composite_credentials_create(ssl_creds, oauth2_creds, NULL);
-  grpc_credentials_unref(ssl_creds);
-  grpc_credentials_unref(oauth2_creds);
-  GPR_ASSERT(strcmp(composite_creds->type, GRPC_CREDENTIALS_TYPE_COMPOSITE) ==
-             0);
-  GPR_ASSERT(grpc_credentials_has_request_metadata(composite_creds));
-  GPR_ASSERT(!grpc_credentials_has_request_metadata_only(composite_creds));
-  creds_array = grpc_composite_credentials_get_credentials(composite_creds);
-  GPR_ASSERT(creds_array->num_creds == 2);
-  GPR_ASSERT(strcmp(creds_array->creds_array[0]->type,
-                    GRPC_CREDENTIALS_TYPE_SSL) == 0);
-  GPR_ASSERT(strcmp(creds_array->creds_array[1]->type,
-                    GRPC_CREDENTIALS_TYPE_OAUTH2) == 0);
-  grpc_credentials_get_request_metadata(
-      &exec_ctx, composite_creds, NULL, test_service_url,
-      check_ssl_oauth2_composite_metadata, composite_creds);
-  grpc_exec_ctx_finish(&exec_ctx);
-}
-
-void test_ssl_fake_transport_security_composite_creds_failure(void) {
-  grpc_credentials *ssl_creds = grpc_ssl_credentials_create(NULL, NULL, NULL);
-  grpc_credentials *fake_transport_security_creds =
-      grpc_fake_transport_security_credentials_create();
-
-  /* 2 connector credentials: should not work. */
-  GPR_ASSERT(grpc_composite_credentials_create(
-                 ssl_creds, fake_transport_security_creds, NULL) == NULL);
-  grpc_credentials_unref(ssl_creds);
-  grpc_credentials_unref(fake_transport_security_creds);
-}
-
-static void check_ssl_oauth2_google_iam_composite_metadata(
-    grpc_exec_ctx *exec_ctx, void *user_data, grpc_credentials_md *md_elems,
-    size_t num_md, grpc_credentials_status status) {
-  grpc_credentials *c = (grpc_credentials *)user_data;
+  grpc_call_credentials *c = (grpc_call_credentials *)user_data;
   expected_md emd[] = {
       {GRPC_AUTHORIZATION_METADATA_KEY, test_oauth2_bearer_token},
       {GRPC_IAM_AUTHORIZATION_TOKEN_METADATA_KEY,
@@ -432,51 +424,90 @@
   GPR_ASSERT(status == GRPC_CREDENTIALS_OK);
   GPR_ASSERT(num_md == 3);
   check_metadata(emd, md_elems, num_md);
-  grpc_credentials_unref(c);
+  grpc_call_credentials_unref(c);
 }
 
-static void test_ssl_oauth2_google_iam_composite_creds(void) {
+static void test_oauth2_google_iam_composite_creds(void) {
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
-  grpc_credentials *ssl_creds =
-      grpc_ssl_credentials_create(test_root_cert, NULL, NULL);
-  const grpc_credentials_array *creds_array;
-  grpc_credentials *oauth2_creds = grpc_md_only_test_credentials_create(
-      "Authorization", test_oauth2_bearer_token, 0);
-  grpc_credentials *aux_creds =
-      grpc_composite_credentials_create(ssl_creds, oauth2_creds, NULL);
-  grpc_credentials *google_iam_creds = grpc_google_iam_credentials_create(
+  const grpc_call_credentials_array *creds_array;
+  grpc_call_credentials *oauth2_creds = grpc_md_only_test_credentials_create(
+      "authorization", test_oauth2_bearer_token, 0);
+  grpc_call_credentials *google_iam_creds = grpc_google_iam_credentials_create(
       test_google_iam_authorization_token, test_google_iam_authority_selector,
       NULL);
-  grpc_credentials *composite_creds =
-      grpc_composite_credentials_create(aux_creds, google_iam_creds, NULL);
-  grpc_credentials_unref(ssl_creds);
-  grpc_credentials_unref(oauth2_creds);
-  grpc_credentials_unref(aux_creds);
-  grpc_credentials_unref(google_iam_creds);
-  GPR_ASSERT(strcmp(composite_creds->type, GRPC_CREDENTIALS_TYPE_COMPOSITE) ==
-             0);
-  GPR_ASSERT(grpc_credentials_has_request_metadata(composite_creds));
-  GPR_ASSERT(!grpc_credentials_has_request_metadata_only(composite_creds));
-  creds_array = grpc_composite_credentials_get_credentials(composite_creds);
-  GPR_ASSERT(creds_array->num_creds == 3);
+  grpc_call_credentials *composite_creds =
+      grpc_composite_call_credentials_create(oauth2_creds, google_iam_creds,
+                                             NULL);
+  grpc_call_credentials_unref(oauth2_creds);
+  grpc_call_credentials_unref(google_iam_creds);
+  GPR_ASSERT(
+      strcmp(composite_creds->type, GRPC_CALL_CREDENTIALS_TYPE_COMPOSITE) == 0);
+  creds_array =
+      grpc_composite_call_credentials_get_credentials(composite_creds);
+  GPR_ASSERT(creds_array->num_creds == 2);
   GPR_ASSERT(strcmp(creds_array->creds_array[0]->type,
-                    GRPC_CREDENTIALS_TYPE_SSL) == 0);
+                    GRPC_CALL_CREDENTIALS_TYPE_OAUTH2) == 0);
   GPR_ASSERT(strcmp(creds_array->creds_array[1]->type,
-                    GRPC_CREDENTIALS_TYPE_OAUTH2) == 0);
-  GPR_ASSERT(strcmp(creds_array->creds_array[2]->type,
-                    GRPC_CREDENTIALS_TYPE_IAM) == 0);
-  grpc_credentials_get_request_metadata(
+                    GRPC_CALL_CREDENTIALS_TYPE_IAM) == 0);
+  grpc_call_credentials_get_request_metadata(
       &exec_ctx, composite_creds, NULL, test_service_url,
-      check_ssl_oauth2_google_iam_composite_metadata, composite_creds);
+      check_oauth2_google_iam_composite_metadata, composite_creds);
   grpc_exec_ctx_finish(&exec_ctx);
 }
 
+static grpc_security_status
+check_channel_oauth2_google_iam_create_security_connector(
+    grpc_channel_credentials *c, grpc_call_credentials *call_creds,
+    const char *target, const grpc_channel_args *args,
+    grpc_channel_security_connector **sc, grpc_channel_args **new_args) {
+  const grpc_call_credentials_array *creds_array;
+  GPR_ASSERT(strcmp(c->type, "mock") == 0);
+  GPR_ASSERT(call_creds != NULL);
+  GPR_ASSERT(strcmp(call_creds->type, GRPC_CALL_CREDENTIALS_TYPE_COMPOSITE) ==
+             0);
+  creds_array = grpc_composite_call_credentials_get_credentials(call_creds);
+  GPR_ASSERT(strcmp(creds_array->creds_array[0]->type,
+                    GRPC_CALL_CREDENTIALS_TYPE_OAUTH2) == 0);
+  GPR_ASSERT(strcmp(creds_array->creds_array[1]->type,
+                    GRPC_CALL_CREDENTIALS_TYPE_IAM) == 0);
+  return GRPC_SECURITY_OK;
+}
+
+static void test_channel_oauth2_google_iam_composite_creds(void) {
+  grpc_channel_args *new_args;
+  grpc_channel_credentials_vtable vtable = {
+      NULL, check_channel_oauth2_google_iam_create_security_connector};
+  grpc_channel_credentials *channel_creds =
+      grpc_mock_channel_credentials_create(&vtable);
+  grpc_call_credentials *oauth2_creds =
+      grpc_access_token_credentials_create("blah", NULL);
+  grpc_channel_credentials *channel_oauth2_creds =
+      grpc_composite_channel_credentials_create(channel_creds, oauth2_creds,
+                                                NULL);
+  grpc_call_credentials *google_iam_creds = grpc_google_iam_credentials_create(
+      test_google_iam_authorization_token, test_google_iam_authority_selector,
+      NULL);
+  grpc_channel_credentials *channel_oauth2_iam_creds =
+      grpc_composite_channel_credentials_create(channel_oauth2_creds,
+                                                google_iam_creds, NULL);
+  grpc_channel_credentials_release(channel_creds);
+  grpc_call_credentials_release(oauth2_creds);
+  grpc_channel_credentials_release(channel_oauth2_creds);
+  grpc_call_credentials_release(google_iam_creds);
+
+  GPR_ASSERT(grpc_channel_credentials_create_security_connector(
+                 channel_oauth2_iam_creds, NULL, NULL, NULL, &new_args) ==
+             GRPC_SECURITY_OK);
+
+  grpc_channel_credentials_release(channel_oauth2_iam_creds);
+}
+
 static void on_oauth2_creds_get_metadata_success(
     grpc_exec_ctx *exec_ctx, void *user_data, grpc_credentials_md *md_elems,
     size_t num_md, grpc_credentials_status status) {
   GPR_ASSERT(status == GRPC_CREDENTIALS_OK);
   GPR_ASSERT(num_md == 1);
-  GPR_ASSERT(gpr_slice_str_cmp(md_elems[0].key, "Authorization") == 0);
+  GPR_ASSERT(gpr_slice_str_cmp(md_elems[0].key, "authorization") == 0);
   GPR_ASSERT(gpr_slice_str_cmp(md_elems[0].value,
                                "Bearer ya29.AHES6ZRN3-HlhAPya30GnW_bHSb_") ==
              0);
@@ -545,15 +576,13 @@
 
 static void test_compute_engine_creds_success(void) {
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
-  grpc_credentials *compute_engine_creds =
+  grpc_call_credentials *compute_engine_creds =
       grpc_google_compute_engine_credentials_create(NULL);
-  GPR_ASSERT(grpc_credentials_has_request_metadata(compute_engine_creds));
-  GPR_ASSERT(grpc_credentials_has_request_metadata_only(compute_engine_creds));
 
   /* First request: http get should be called. */
   grpc_httpcli_set_override(compute_engine_httpcli_get_success_override,
                             httpcli_post_should_not_be_called);
-  grpc_credentials_get_request_metadata(
+  grpc_call_credentials_get_request_metadata(
       &exec_ctx, compute_engine_creds, NULL, test_service_url,
       on_oauth2_creds_get_metadata_success, (void *)test_user_data);
   grpc_exec_ctx_flush(&exec_ctx);
@@ -561,27 +590,25 @@
   /* Second request: the cached token should be served directly. */
   grpc_httpcli_set_override(httpcli_get_should_not_be_called,
                             httpcli_post_should_not_be_called);
-  grpc_credentials_get_request_metadata(
+  grpc_call_credentials_get_request_metadata(
       &exec_ctx, compute_engine_creds, NULL, test_service_url,
       on_oauth2_creds_get_metadata_success, (void *)test_user_data);
   grpc_exec_ctx_finish(&exec_ctx);
 
-  grpc_credentials_unref(compute_engine_creds);
+  grpc_call_credentials_unref(compute_engine_creds);
   grpc_httpcli_set_override(NULL, NULL);
 }
 
 static void test_compute_engine_creds_failure(void) {
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
-  grpc_credentials *compute_engine_creds =
+  grpc_call_credentials *compute_engine_creds =
       grpc_google_compute_engine_credentials_create(NULL);
   grpc_httpcli_set_override(compute_engine_httpcli_get_failure_override,
                             httpcli_post_should_not_be_called);
-  GPR_ASSERT(grpc_credentials_has_request_metadata(compute_engine_creds));
-  GPR_ASSERT(grpc_credentials_has_request_metadata_only(compute_engine_creds));
-  grpc_credentials_get_request_metadata(
+  grpc_call_credentials_get_request_metadata(
       &exec_ctx, compute_engine_creds, NULL, test_service_url,
       on_oauth2_creds_get_metadata_failure, (void *)test_user_data);
-  grpc_credentials_unref(compute_engine_creds);
+  grpc_call_credentials_unref(compute_engine_creds);
   grpc_httpcli_set_override(NULL, NULL);
   grpc_exec_ctx_finish(&exec_ctx);
 }
@@ -631,16 +658,14 @@
 
 static void test_refresh_token_creds_success(void) {
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
-  grpc_credentials *refresh_token_creds =
+  grpc_call_credentials *refresh_token_creds =
       grpc_google_refresh_token_credentials_create(test_refresh_token_str,
                                                    NULL);
-  GPR_ASSERT(grpc_credentials_has_request_metadata(refresh_token_creds));
-  GPR_ASSERT(grpc_credentials_has_request_metadata_only(refresh_token_creds));
 
   /* First request: http get should be called. */
   grpc_httpcli_set_override(httpcli_get_should_not_be_called,
                             refresh_token_httpcli_post_success);
-  grpc_credentials_get_request_metadata(
+  grpc_call_credentials_get_request_metadata(
       &exec_ctx, refresh_token_creds, NULL, test_service_url,
       on_oauth2_creds_get_metadata_success, (void *)test_user_data);
   grpc_exec_ctx_flush(&exec_ctx);
@@ -648,29 +673,27 @@
   /* Second request: the cached token should be served directly. */
   grpc_httpcli_set_override(httpcli_get_should_not_be_called,
                             httpcli_post_should_not_be_called);
-  grpc_credentials_get_request_metadata(
+  grpc_call_credentials_get_request_metadata(
       &exec_ctx, refresh_token_creds, NULL, test_service_url,
       on_oauth2_creds_get_metadata_success, (void *)test_user_data);
   grpc_exec_ctx_flush(&exec_ctx);
 
-  grpc_credentials_unref(refresh_token_creds);
+  grpc_call_credentials_unref(refresh_token_creds);
   grpc_httpcli_set_override(NULL, NULL);
   grpc_exec_ctx_finish(&exec_ctx);
 }
 
 static void test_refresh_token_creds_failure(void) {
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
-  grpc_credentials *refresh_token_creds =
+  grpc_call_credentials *refresh_token_creds =
       grpc_google_refresh_token_credentials_create(test_refresh_token_str,
                                                    NULL);
   grpc_httpcli_set_override(httpcli_get_should_not_be_called,
                             refresh_token_httpcli_post_failure);
-  GPR_ASSERT(grpc_credentials_has_request_metadata(refresh_token_creds));
-  GPR_ASSERT(grpc_credentials_has_request_metadata_only(refresh_token_creds));
-  grpc_credentials_get_request_metadata(
+  grpc_call_credentials_get_request_metadata(
       &exec_ctx, refresh_token_creds, NULL, test_service_url,
       on_oauth2_creds_get_metadata_failure, (void *)test_user_data);
-  grpc_credentials_unref(refresh_token_creds);
+  grpc_call_credentials_unref(refresh_token_creds);
   grpc_httpcli_set_override(NULL, NULL);
   grpc_exec_ctx_finish(&exec_ctx);
 }
@@ -730,7 +753,7 @@
   gpr_asprintf(&expected_md_value, "Bearer %s", test_signed_jwt);
   GPR_ASSERT(status == GRPC_CREDENTIALS_OK);
   GPR_ASSERT(num_md == 1);
-  GPR_ASSERT(gpr_slice_str_cmp(md_elems[0].key, "Authorization") == 0);
+  GPR_ASSERT(gpr_slice_str_cmp(md_elems[0].key, "authorization") == 0);
   GPR_ASSERT(gpr_slice_str_cmp(md_elems[0].value, expected_md_value) == 0);
   GPR_ASSERT(user_data != NULL);
   GPR_ASSERT(strcmp((const char *)user_data, test_user_data) == 0);
@@ -751,15 +774,13 @@
 static void test_jwt_creds_success(void) {
   char *json_key_string = test_json_key_str();
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
-  grpc_credentials *jwt_creds =
+  grpc_call_credentials *jwt_creds =
       grpc_service_account_jwt_access_credentials_create(
           json_key_string, grpc_max_auth_token_lifetime, NULL);
-  GPR_ASSERT(grpc_credentials_has_request_metadata(jwt_creds));
-  GPR_ASSERT(grpc_credentials_has_request_metadata_only(jwt_creds));
 
   /* First request: jwt_encode_and_sign should be called. */
   grpc_jwt_encode_and_sign_set_override(encode_and_sign_jwt_success);
-  grpc_credentials_get_request_metadata(
+  grpc_call_credentials_get_request_metadata(
       &exec_ctx, jwt_creds, NULL, test_service_url,
       on_jwt_creds_get_metadata_success, (void *)test_user_data);
   grpc_exec_ctx_flush(&exec_ctx);
@@ -767,7 +788,7 @@
   /* Second request: the cached token should be served directly. */
   grpc_jwt_encode_and_sign_set_override(
       encode_and_sign_jwt_should_not_be_called);
-  grpc_credentials_get_request_metadata(
+  grpc_call_credentials_get_request_metadata(
       &exec_ctx, jwt_creds, NULL, test_service_url,
       on_jwt_creds_get_metadata_success, (void *)test_user_data);
   grpc_exec_ctx_flush(&exec_ctx);
@@ -775,32 +796,30 @@
   /* Third request: Different service url so jwt_encode_and_sign should be
      called again (no caching). */
   grpc_jwt_encode_and_sign_set_override(encode_and_sign_jwt_success);
-  grpc_credentials_get_request_metadata(
+  grpc_call_credentials_get_request_metadata(
       &exec_ctx, jwt_creds, NULL, other_test_service_url,
       on_jwt_creds_get_metadata_success, (void *)test_user_data);
   grpc_exec_ctx_flush(&exec_ctx);
 
   gpr_free(json_key_string);
-  grpc_credentials_unref(jwt_creds);
+  grpc_call_credentials_unref(jwt_creds);
   grpc_jwt_encode_and_sign_set_override(NULL);
 }
 
 static void test_jwt_creds_signing_failure(void) {
   char *json_key_string = test_json_key_str();
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
-  grpc_credentials *jwt_creds =
+  grpc_call_credentials *jwt_creds =
       grpc_service_account_jwt_access_credentials_create(
           json_key_string, grpc_max_auth_token_lifetime, NULL);
-  GPR_ASSERT(grpc_credentials_has_request_metadata(jwt_creds));
-  GPR_ASSERT(grpc_credentials_has_request_metadata_only(jwt_creds));
 
   grpc_jwt_encode_and_sign_set_override(encode_and_sign_jwt_failure);
-  grpc_credentials_get_request_metadata(
+  grpc_call_credentials_get_request_metadata(
       &exec_ctx, jwt_creds, NULL, test_service_url,
       on_jwt_creds_get_metadata_failure, (void *)test_user_data);
 
   gpr_free(json_key_string);
-  grpc_credentials_unref(jwt_creds);
+  grpc_call_credentials_unref(jwt_creds);
   grpc_jwt_encode_and_sign_set_override(NULL);
   grpc_exec_ctx_finish(&exec_ctx);
 }
@@ -818,52 +837,39 @@
   gpr_free(creds_file_name);
 }
 
-static grpc_credentials *composite_inner_creds(grpc_credentials *creds,
-                                               const char *inner_creds_type) {
-  size_t i;
-  grpc_composite_credentials *composite;
-  GPR_ASSERT(strcmp(creds->type, GRPC_CREDENTIALS_TYPE_COMPOSITE) == 0);
-  composite = (grpc_composite_credentials *)creds;
-  for (i = 0; i < composite->inner.num_creds; i++) {
-    grpc_credentials *c = composite->inner.creds_array[i];
-    if (strcmp(c->type, inner_creds_type) == 0) return c;
-  }
-  GPR_ASSERT(0); /* Not found. */
-}
-
 static void test_google_default_creds_auth_key(void) {
   grpc_service_account_jwt_access_credentials *jwt;
-  grpc_credentials *creds;
+  grpc_composite_channel_credentials *creds;
   char *json_key = test_json_key_str();
   grpc_flush_cached_google_default_credentials();
   set_google_default_creds_env_var_with_file_contents(
       "json_key_google_default_creds", json_key);
   gpr_free(json_key);
-  creds = grpc_google_default_credentials_create();
+  creds = (grpc_composite_channel_credentials *)
+      grpc_google_default_credentials_create();
   GPR_ASSERT(creds != NULL);
-  jwt = (grpc_service_account_jwt_access_credentials *)composite_inner_creds(
-      creds, GRPC_CREDENTIALS_TYPE_JWT);
+  jwt = (grpc_service_account_jwt_access_credentials *)creds->call_creds;
   GPR_ASSERT(
       strcmp(jwt->key.client_id,
              "777-abaslkan11hlb6nmim3bpspl31ud.apps.googleusercontent.com") ==
       0);
-  grpc_credentials_unref(creds);
+  grpc_channel_credentials_unref(&creds->base);
   gpr_setenv(GRPC_GOOGLE_CREDENTIALS_ENV_VAR, ""); /* Reset. */
 }
 
 static void test_google_default_creds_access_token(void) {
   grpc_google_refresh_token_credentials *refresh;
-  grpc_credentials *creds;
+  grpc_composite_channel_credentials *creds;
   grpc_flush_cached_google_default_credentials();
   set_google_default_creds_env_var_with_file_contents(
       "refresh_token_google_default_creds", test_refresh_token_str);
-  creds = grpc_google_default_credentials_create();
+  creds = (grpc_composite_channel_credentials *)
+      grpc_google_default_credentials_create();
   GPR_ASSERT(creds != NULL);
-  refresh = (grpc_google_refresh_token_credentials *)composite_inner_creds(
-      creds, GRPC_CREDENTIALS_TYPE_OAUTH2);
+  refresh = (grpc_google_refresh_token_credentials *)creds->call_creds;
   GPR_ASSERT(strcmp(refresh->refresh_token.client_id,
                     "32555999999.apps.googleusercontent.com") == 0);
-  grpc_credentials_unref(creds);
+  grpc_channel_credentials_unref(&creds->base);
   gpr_setenv(GRPC_GOOGLE_CREDENTIALS_ENV_VAR, ""); /* Reset. */
 }
 
@@ -935,7 +941,7 @@
 }
 
 static void test_metadata_plugin_success(void) {
-  grpc_credentials *creds;
+  grpc_call_credentials *creds;
   plugin_state state = PLUGIN_INITIAL_STATE;
   grpc_metadata_credentials_plugin plugin;
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
@@ -946,17 +952,17 @@
 
   creds = grpc_metadata_credentials_create_from_plugin(plugin, NULL);
   GPR_ASSERT(state == PLUGIN_INITIAL_STATE);
-  grpc_credentials_get_request_metadata(
+  grpc_call_credentials_get_request_metadata(
       &exec_ctx, creds, NULL, test_service_url,
       on_plugin_metadata_received_success, NULL);
   GPR_ASSERT(state == PLUGIN_GET_METADATA_CALLED_STATE);
-  grpc_credentials_release(creds);
+  grpc_call_credentials_release(creds);
   GPR_ASSERT(state == PLUGIN_DESTROY_CALLED_STATE);
   grpc_exec_ctx_finish(&exec_ctx);
 }
 
 static void test_metadata_plugin_failure(void) {
-  grpc_credentials *creds;
+  grpc_call_credentials *creds;
   plugin_state state = PLUGIN_INITIAL_STATE;
   grpc_metadata_credentials_plugin plugin;
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
@@ -967,11 +973,11 @@
 
   creds = grpc_metadata_credentials_create_from_plugin(plugin, NULL);
   GPR_ASSERT(state == PLUGIN_INITIAL_STATE);
-  grpc_credentials_get_request_metadata(
+  grpc_call_credentials_get_request_metadata(
       &exec_ctx, creds, NULL, test_service_url,
       on_plugin_metadata_received_failure, NULL);
   GPR_ASSERT(state == PLUGIN_GET_METADATA_CALLED_STATE);
-  grpc_credentials_release(creds);
+  grpc_call_credentials_release(creds);
   GPR_ASSERT(state == PLUGIN_DESTROY_CALLED_STATE);
   grpc_exec_ctx_finish(&exec_ctx);
 }
@@ -993,8 +999,9 @@
   test_oauth2_token_fetcher_creds_parsing_missing_token_lifetime();
   test_google_iam_creds();
   test_access_token_creds();
-  test_ssl_oauth2_composite_creds();
-  test_ssl_oauth2_google_iam_composite_creds();
+  test_channel_oauth2_composite_creds();
+  test_oauth2_google_iam_composite_creds();
+  test_channel_oauth2_google_iam_composite_creds();
   test_compute_engine_creds_success();
   test_compute_engine_creds_failure();
   test_refresh_token_creds_success();
diff --git a/test/core/security/fetch_oauth2.c b/test/core/security/fetch_oauth2.c
index 764d8da..ee1178c 100644
--- a/test/core/security/fetch_oauth2.c
+++ b/test/core/security/fetch_oauth2.c
@@ -46,7 +46,7 @@
 #include "src/core/support/file.h"
 #include "test/core/security/oauth2_utils.h"
 
-static grpc_credentials *create_refresh_token_creds(
+static grpc_call_credentials *create_refresh_token_creds(
     const char *json_refresh_token_file_path) {
   int success;
   gpr_slice refresh_token =
@@ -60,7 +60,7 @@
 }
 
 int main(int argc, char **argv) {
-  grpc_credentials *creds = NULL;
+  grpc_call_credentials *creds = NULL;
   char *json_key_file_path = NULL;
   char *json_refresh_token_file_path = NULL;
   char *token = NULL;
@@ -115,7 +115,7 @@
     printf("Got token: %s.\n", token);
     gpr_free(token);
   }
-  grpc_credentials_release(creds);
+  grpc_call_credentials_release(creds);
   gpr_cmdline_destroy(cl);
   grpc_shutdown();
   return 0;
diff --git a/test/core/security/oauth2_utils.c b/test/core/security/oauth2_utils.c
index f99d170..fcfe8a6 100644
--- a/test/core/security/oauth2_utils.c
+++ b/test/core/security/oauth2_utils.c
@@ -75,7 +75,8 @@
 
 static void do_nothing(grpc_exec_ctx *exec_ctx, void *unused, int success) {}
 
-char *grpc_test_fetch_oauth2_token_with_credentials(grpc_credentials *creds) {
+char *grpc_test_fetch_oauth2_token_with_credentials(
+    grpc_call_credentials *creds) {
   oauth2_request request;
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   grpc_closure do_nothing_closure;
@@ -84,8 +85,8 @@
 
   grpc_closure_init(&do_nothing_closure, do_nothing, NULL);
 
-  grpc_credentials_get_request_metadata(&exec_ctx, creds, &request.pollset, "",
-                                        on_oauth2_response, &request);
+  grpc_call_credentials_get_request_metadata(&exec_ctx, creds, &request.pollset,
+                                             "", on_oauth2_response, &request);
 
   grpc_exec_ctx_finish(&exec_ctx);
 
diff --git a/test/core/security/oauth2_utils.h b/test/core/security/oauth2_utils.h
index 8082351..b35fe79 100644
--- a/test/core/security/oauth2_utils.h
+++ b/test/core/security/oauth2_utils.h
@@ -42,7 +42,8 @@
 
 /* Fetch oauth2 access token with a credentials object. Does not take ownership.
    Returns NULL on a failure. The caller should call gpr_free on the token. */
-char *grpc_test_fetch_oauth2_token_with_credentials(grpc_credentials *creds);
+char *grpc_test_fetch_oauth2_token_with_credentials(
+    grpc_call_credentials *creds);
 
 #ifdef __cplusplus
 }
diff --git a/test/core/security/print_google_default_creds_token.c b/test/core/security/print_google_default_creds_token.c
index f207e05..eb63724 100644
--- a/test/core/security/print_google_default_creds_token.c
+++ b/test/core/security/print_google_default_creds_token.c
@@ -72,7 +72,7 @@
   int result = 0;
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   synchronizer sync;
-  grpc_credentials *creds = NULL;
+  grpc_channel_credentials *creds = NULL;
   char *service_url = "https://test.foo.google.com/Foo";
   gpr_cmdline *cl = gpr_cmdline_create("print_google_default_creds_token");
   gpr_cmdline_add_string(cl, "service_url",
@@ -91,9 +91,9 @@
   grpc_pollset_init(&sync.pollset);
   sync.is_done = 0;
 
-  grpc_credentials_get_request_metadata(&exec_ctx, creds, &sync.pollset,
-                                        service_url, on_metadata_response,
-                                        &sync);
+  grpc_call_credentials_get_request_metadata(
+      &exec_ctx, ((grpc_composite_channel_credentials *)creds)->call_creds,
+      &sync.pollset, service_url, on_metadata_response, &sync);
 
   gpr_mu_lock(GRPC_POLLSET_MU(&sync.pollset));
   while (!sync.is_done) {
@@ -107,7 +107,7 @@
   }
   gpr_mu_unlock(GRPC_POLLSET_MU(&sync.pollset));
 
-  grpc_credentials_release(creds);
+  grpc_channel_credentials_release(creds);
 
 end:
   gpr_cmdline_destroy(cl);
diff --git a/test/core/surface/byte_buffer_reader_test.c b/test/core/surface/byte_buffer_reader_test.c
index 7f9cd6b..6b41698 100644
--- a/test/core/surface/byte_buffer_reader_test.c
+++ b/test/core/surface/byte_buffer_reader_test.c
@@ -185,8 +185,8 @@
 }
 
 static void test_readall(void) {
-  char* lotsa_as[512];
-  char* lotsa_bs[1024];
+  char *lotsa_as[512];
+  char *lotsa_bs[1024];
   gpr_slice slices[2];
   grpc_byte_buffer *buffer;
   grpc_byte_buffer_reader reader;
diff --git a/test/core/transport/chttp2/hpack_parser_test.c b/test/core/transport/chttp2/hpack_parser_test.c
index 3a31337..c6b35fb 100644
--- a/test/core/transport/chttp2/hpack_parser_test.c
+++ b/test/core/transport/chttp2/hpack_parser_test.c
@@ -151,7 +151,8 @@
   grpc_chttp2_hpack_parser_destroy(&parser);
 
   grpc_chttp2_hpack_parser_init(&parser, mdctx);
-  parser.table.max_bytes = 256;
+  grpc_chttp2_hptbl_set_max_bytes(&parser.table, 256);
+  grpc_chttp2_hptbl_set_current_table_size(&parser.table, 256);
   /* D.5.1 */
   test_vector(&parser, mode,
               "4803 3330 3258 0770 7269 7661 7465 611d"
@@ -184,7 +185,8 @@
   grpc_chttp2_hpack_parser_destroy(&parser);
 
   grpc_chttp2_hpack_parser_init(&parser, mdctx);
-  parser.table.max_bytes = 256;
+  grpc_chttp2_hptbl_set_max_bytes(&parser.table, 256);
+  grpc_chttp2_hptbl_set_current_table_size(&parser.table, 256);
   /* D.6.1 */
   test_vector(&parser, mode,
               "4882 6402 5885 aec3 771a 4b61 96d0 7abe"
diff --git a/test/core/transport/chttp2/hpack_table_test.c b/test/core/transport/chttp2/hpack_table_test.c
index aa3e273..5eb52d6 100644
--- a/test/core/transport/chttp2/hpack_table_test.c
+++ b/test/core/transport/chttp2/hpack_table_test.c
@@ -143,9 +143,12 @@
   grpc_chttp2_hptbl_init(&tbl, mdctx);
 
   for (i = 0; i < 1000000; i++) {
+    grpc_mdelem *elem;
     gpr_asprintf(&key, "K:%d", i);
     gpr_asprintf(&value, "VALUE:%d", i);
-    grpc_chttp2_hptbl_add(&tbl, grpc_mdelem_from_strings(mdctx, key, value));
+    elem = grpc_mdelem_from_strings(mdctx, key, value);
+    GPR_ASSERT(grpc_chttp2_hptbl_add(&tbl, elem));
+    GRPC_MDELEM_UNREF(elem);
     assert_index(&tbl, 1 + GRPC_CHTTP2_LAST_STATIC_ENTRY, key, value);
     gpr_free(key);
     gpr_free(value);
@@ -173,18 +176,25 @@
 
 static void test_find(void) {
   grpc_chttp2_hptbl tbl;
-  int i;
+  gpr_uint32 i;
   char buffer[32];
   grpc_mdctx *mdctx;
+  grpc_mdelem *elem;
   grpc_chttp2_hptbl_find_result r;
 
   LOG_TEST("test_find");
 
   mdctx = grpc_mdctx_create();
   grpc_chttp2_hptbl_init(&tbl, mdctx);
-  grpc_chttp2_hptbl_add(&tbl, grpc_mdelem_from_strings(mdctx, "abc", "xyz"));
-  grpc_chttp2_hptbl_add(&tbl, grpc_mdelem_from_strings(mdctx, "abc", "123"));
-  grpc_chttp2_hptbl_add(&tbl, grpc_mdelem_from_strings(mdctx, "x", "1"));
+  elem = grpc_mdelem_from_strings(mdctx, "abc", "xyz");
+  GPR_ASSERT(grpc_chttp2_hptbl_add(&tbl, elem));
+  GRPC_MDELEM_UNREF(elem);
+  elem = grpc_mdelem_from_strings(mdctx, "abc", "123");
+  GPR_ASSERT(grpc_chttp2_hptbl_add(&tbl, elem));
+  GRPC_MDELEM_UNREF(elem);
+  elem = grpc_mdelem_from_strings(mdctx, "x", "1");
+  GPR_ASSERT(grpc_chttp2_hptbl_add(&tbl, elem));
+  GRPC_MDELEM_UNREF(elem);
 
   r = find_simple(&tbl, "abc", "123");
   GPR_ASSERT(r.index == 2 + GRPC_CHTTP2_LAST_STATIC_ENTRY);
@@ -233,8 +243,9 @@
   /* overflow the string buffer, check find still works */
   for (i = 0; i < 10000; i++) {
     gpr_ltoa(i, buffer);
-    grpc_chttp2_hptbl_add(&tbl,
-                          grpc_mdelem_from_strings(mdctx, "test", buffer));
+    elem = grpc_mdelem_from_strings(mdctx, "test", buffer);
+    GPR_ASSERT(grpc_chttp2_hptbl_add(&tbl, elem));
+    GRPC_MDELEM_UNREF(elem);
   }
 
   r = find_simple(&tbl, "abc", "123");
@@ -250,7 +261,7 @@
   GPR_ASSERT(r.has_value == 1);
 
   for (i = 0; i < tbl.num_ents; i++) {
-    int expect = 9999 - i;
+    gpr_uint32 expect = 9999 - i;
     gpr_ltoa(expect, buffer);
 
     r = find_simple(&tbl, "test", buffer);
diff --git a/test/core/util/reconnect_server.c b/test/core/util/reconnect_server.c
index ee481ef..c064fb3 100644
--- a/test/core/util/reconnect_server.c
+++ b/test/core/util/reconnect_server.c
@@ -113,6 +113,7 @@
 
 void reconnect_server_start(reconnect_server *server, int port) {
   struct sockaddr_in addr;
+  grpc_tcp_listener *listener;
   int port_added;
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
 
@@ -121,8 +122,9 @@
   memset(&addr.sin_addr, 0, sizeof(addr.sin_addr));
 
   server->tcp_server = grpc_tcp_server_create();
-  port_added =
+  listener = 
       grpc_tcp_server_add_port(server->tcp_server, &addr, sizeof(addr));
+  port_added = grpc_tcp_listener_get_port(listener);
   GPR_ASSERT(port_added == port);
 
   grpc_tcp_server_start(&exec_ctx, server->tcp_server, server->pollsets, 1,
diff --git a/test/cpp/client/credentials_test.cc b/test/cpp/client/credentials_test.cc
index 743ad06..418a544 100644
--- a/test/cpp/client/credentials_test.cc
+++ b/test/cpp/client/credentials_test.cc
@@ -46,8 +46,8 @@
 };
 
 TEST_F(CredentialsTest, InvalidGoogleRefreshToken) {
-  std::shared_ptr<Credentials> bad1 = GoogleRefreshTokenCredentials("");
-  EXPECT_EQ(static_cast<Credentials*>(nullptr), bad1.get());
+  std::shared_ptr<CallCredentials> bad1 = GoogleRefreshTokenCredentials("");
+  EXPECT_EQ(static_cast<CallCredentials*>(nullptr), bad1.get());
 }
 
 }  // namespace testing
diff --git a/test/cpp/end2end/async_end2end_test.cc b/test/cpp/end2end/async_end2end_test.cc
index cfb6c21..74290c3 100644
--- a/test/cpp/end2end/async_end2end_test.cc
+++ b/test/cpp/end2end/async_end2end_test.cc
@@ -199,7 +199,7 @@
 
   void ResetStub() {
     std::shared_ptr<Channel> channel =
-        CreateChannel(server_address_.str(), InsecureCredentials());
+        CreateChannel(server_address_.str(), InsecureChannelCredentials());
     stub_ = grpc::cpp::test::util::TestService::NewStub(channel);
   }
 
@@ -749,7 +749,7 @@
 
 TEST_P(AsyncEnd2endTest, UnimplementedRpc) {
   std::shared_ptr<Channel> channel =
-      CreateChannel(server_address_.str(), InsecureCredentials());
+      CreateChannel(server_address_.str(), InsecureChannelCredentials());
   std::unique_ptr<grpc::cpp::test::util::UnimplementedService::Stub> stub;
   stub = grpc::cpp::test::util::UnimplementedService::NewStub(channel);
   EchoRequest send_request;
diff --git a/test/cpp/end2end/client_crash_test.cc b/test/cpp/end2end/client_crash_test.cc
index 058e696..116785b 100644
--- a/test/cpp/end2end/client_crash_test.cc
+++ b/test/cpp/end2end/client_crash_test.cc
@@ -74,7 +74,7 @@
     }));
     GPR_ASSERT(server_);
     return grpc::cpp::test::util::TestService::NewStub(
-        CreateChannel(addr, InsecureCredentials()));
+        CreateChannel(addr, InsecureChannelCredentials()));
   }
 
   void KillServer() { server_.reset(); }
diff --git a/test/cpp/end2end/end2end_test.cc b/test/cpp/end2end/end2end_test.cc
index c5c7185..6da9333 100644
--- a/test/cpp/end2end/end2end_test.cc
+++ b/test/cpp/end2end/end2end_test.cc
@@ -146,13 +146,13 @@
 
   TestAuthMetadataProcessor(bool is_blocking) : is_blocking_(is_blocking) {}
 
-  std::shared_ptr<Credentials> GetCompatibleClientCreds() {
+  std::shared_ptr<CallCredentials> GetCompatibleClientCreds() {
     return MetadataCredentialsFromPlugin(
         std::unique_ptr<MetadataCredentialsPlugin>(
             new TestMetadataCredentialsPlugin(kGoodGuy, is_blocking_, true)));
   }
 
-  std::shared_ptr<Credentials> GetIncompatibleClientCreds() {
+  std::shared_ptr<CallCredentials> GetIncompatibleClientCreds() {
     return MetadataCredentialsFromPlugin(
         std::unique_ptr<MetadataCredentialsPlugin>(
             new TestMetadataCredentialsPlugin("Mr Hyde", is_blocking_, true)));
@@ -407,7 +407,7 @@
     }
     EXPECT_TRUE(is_server_started_);
     ChannelArguments args;
-    auto channel_creds = InsecureCredentials();
+    auto channel_creds = InsecureChannelCredentials();
     if (GetParam().use_tls) {
       SslCredentialsOptions ssl_opts = {test_root_cert, "", ""};
       args.SetSslTargetNameOverride("foo.test.google.fr");
@@ -429,7 +429,7 @@
       builder.RegisterService(proxy_service_.get());
       proxy_server_ = builder.BuildAndStart();
 
-      channel_ = CreateChannel(proxyaddr.str(), InsecureCredentials());
+      channel_ = CreateChannel(proxyaddr.str(), InsecureChannelCredentials());
     }
 
     stub_ = grpc::cpp::test::util::TestService::NewStub(channel_);
@@ -575,6 +575,18 @@
   context->TryCancel();
 }
 
+TEST_P(End2endTest, CancelRpcBeforeStart) {
+  ResetStub();
+  EchoRequest request;
+  EchoResponse response;
+  ClientContext context;
+  request.set_message("hello");
+  context.TryCancel();
+  Status s = stub_->Echo(&context, request, &response);
+  EXPECT_EQ("", response.message());
+  EXPECT_EQ(grpc::StatusCode::CANCELLED, s.error_code());
+}
+
 // Client cancels request stream after sending two messages
 TEST_P(End2endTest, ClientCancelsRequestStream) {
   ResetStub();
@@ -751,7 +763,8 @@
   std::ostringstream server_address;
   server_address << "127.0.0.1:" << port;
   // Channel to non-existing server
-  auto channel = CreateChannel(server_address.str(), InsecureCredentials());
+  auto channel =
+      CreateChannel(server_address.str(), InsecureChannelCredentials());
   // Start IDLE
   EXPECT_EQ(GRPC_CHANNEL_IDLE, channel->GetState(true));
 
@@ -971,33 +984,6 @@
   EXPECT_TRUE(s.ok());
 }
 
-// rpc and stream should fail on bad credentials.
-TEST_P(SecureEnd2endTest, BadCredentials) {
-  std::shared_ptr<Credentials> bad_creds = GoogleRefreshTokenCredentials("");
-  EXPECT_EQ(static_cast<Credentials*>(nullptr), bad_creds.get());
-  std::shared_ptr<Channel> channel =
-      CreateChannel(server_address_.str(), bad_creds);
-  std::unique_ptr<grpc::cpp::test::util::TestService::Stub> stub(
-      grpc::cpp::test::util::TestService::NewStub(channel));
-  EchoRequest request;
-  EchoResponse response;
-  ClientContext context;
-  request.set_message("Hello");
-
-  Status s = stub->Echo(&context, request, &response);
-  EXPECT_EQ("", response.message());
-  EXPECT_FALSE(s.ok());
-  EXPECT_EQ(StatusCode::INVALID_ARGUMENT, s.error_code());
-  EXPECT_EQ("Invalid credentials.", s.error_message());
-
-  ClientContext context2;
-  auto stream = stub->BidiStream(&context2);
-  s = stream->Finish();
-  EXPECT_FALSE(s.ok());
-  EXPECT_EQ(StatusCode::INVALID_ARGUMENT, s.error_code());
-  EXPECT_EQ("Invalid credentials.", s.error_message());
-}
-
 bool MetadataContains(
     const std::multimap<grpc::string_ref, grpc::string_ref>& metadata,
     const grpc::string& key, const grpc::string& value) {
@@ -1055,7 +1041,7 @@
   EchoRequest request;
   EchoResponse response;
   ClientContext context;
-  std::shared_ptr<Credentials> creds =
+  std::shared_ptr<CallCredentials> creds =
       GoogleIAMCredentials("fake_token", "fake_selector");
   context.set_credentials(creds);
   request.set_message("Hello");
@@ -1072,30 +1058,15 @@
                                "fake_selector"));
 }
 
-TEST_P(SecureEnd2endTest, InsecurePerCallCredentials) {
-  ResetStub();
-  EchoRequest request;
-  EchoResponse response;
-  ClientContext context;
-  std::shared_ptr<Credentials> creds = InsecureCredentials();
-  context.set_credentials(creds);
-  request.set_message("Hello");
-  request.mutable_param()->set_echo_metadata(true);
-
-  Status s = stub_->Echo(&context, request, &response);
-  EXPECT_EQ(StatusCode::CANCELLED, s.error_code());
-  EXPECT_EQ("Failed to set credentials to rpc.", s.error_message());
-}
-
 TEST_P(SecureEnd2endTest, OverridePerCallCredentials) {
   ResetStub();
   EchoRequest request;
   EchoResponse response;
   ClientContext context;
-  std::shared_ptr<Credentials> creds1 =
+  std::shared_ptr<CallCredentials> creds1 =
       GoogleIAMCredentials("fake_token1", "fake_selector1");
   context.set_credentials(creds1);
-  std::shared_ptr<Credentials> creds2 =
+  std::shared_ptr<CallCredentials> creds2 =
       GoogleIAMCredentials("fake_token2", "fake_selector2");
   context.set_credentials(creds2);
   request.set_message("Hello");
diff --git a/test/cpp/end2end/generic_end2end_test.cc b/test/cpp/end2end/generic_end2end_test.cc
index 6a46916..082119d 100644
--- a/test/cpp/end2end/generic_end2end_test.cc
+++ b/test/cpp/end2end/generic_end2end_test.cc
@@ -120,7 +120,7 @@
 
   void ResetStub() {
     std::shared_ptr<Channel> channel =
-        CreateChannel(server_address_.str(), InsecureCredentials());
+        CreateChannel(server_address_.str(), InsecureChannelCredentials());
     generic_stub_.reset(new GenericStub(channel));
   }
 
diff --git a/test/cpp/end2end/mock_test.cc b/test/cpp/end2end/mock_test.cc
index 80057d8..bd34cfb 100644
--- a/test/cpp/end2end/mock_test.cc
+++ b/test/cpp/end2end/mock_test.cc
@@ -244,7 +244,7 @@
 
   void ResetStub() {
     std::shared_ptr<Channel> channel =
-        CreateChannel(server_address_.str(), InsecureCredentials());
+        CreateChannel(server_address_.str(), InsecureChannelCredentials());
     stub_ = grpc::cpp::test::util::TestService::NewStub(channel);
   }
 
diff --git a/test/cpp/end2end/server_crash_test_client.cc b/test/cpp/end2end/server_crash_test_client.cc
index 1786936..2baefcb 100644
--- a/test/cpp/end2end/server_crash_test_client.cc
+++ b/test/cpp/end2end/server_crash_test_client.cc
@@ -58,7 +58,7 @@
 int main(int argc, char** argv) {
   ParseCommandLineFlags(&argc, &argv, true);
   auto stub = grpc::cpp::test::util::TestService::NewStub(
-      grpc::CreateChannel(FLAGS_address, grpc::InsecureCredentials()));
+      grpc::CreateChannel(FLAGS_address, grpc::InsecureChannelCredentials()));
 
   EchoRequest request;
   EchoResponse response;
diff --git a/test/cpp/end2end/shutdown_test.cc b/test/cpp/end2end/shutdown_test.cc
index 0549bb8..b1b18b2 100644
--- a/test/cpp/end2end/shutdown_test.cc
+++ b/test/cpp/end2end/shutdown_test.cc
@@ -93,7 +93,7 @@
 
   void ResetStub() {
     string target = "dns:localhost:" + to_string(port_);
-    channel_ = CreateChannel(target, InsecureCredentials());
+    channel_ = CreateChannel(target, InsecureChannelCredentials());
     stub_ = grpc::cpp::test::util::TestService::NewStub(channel_);
   }
 
diff --git a/test/cpp/end2end/streaming_throughput_test.cc b/test/cpp/end2end/streaming_throughput_test.cc
index d4ab148..b7e103a 100644
--- a/test/cpp/end2end/streaming_throughput_test.cc
+++ b/test/cpp/end2end/streaming_throughput_test.cc
@@ -160,7 +160,7 @@
 
   void ResetStub() {
     std::shared_ptr<Channel> channel =
-        CreateChannel(server_address_.str(), InsecureCredentials());
+        CreateChannel(server_address_.str(), InsecureChannelCredentials());
     stub_ = grpc::cpp::test::util::TestService::NewStub(channel);
   }
 
diff --git a/test/cpp/end2end/thread_stress_test.cc b/test/cpp/end2end/thread_stress_test.cc
index 75a07d8..fb82b96 100644
--- a/test/cpp/end2end/thread_stress_test.cc
+++ b/test/cpp/end2end/thread_stress_test.cc
@@ -190,7 +190,7 @@
 
   void ResetStub() {
     std::shared_ptr<Channel> channel =
-        CreateChannel(server_address_.str(), InsecureCredentials());
+        CreateChannel(server_address_.str(), InsecureChannelCredentials());
     stub_ = grpc::cpp::test::util::TestService::NewStub(channel);
   }
 
diff --git a/test/cpp/end2end/zookeeper_test.cc b/test/cpp/end2end/zookeeper_test.cc
index d4c7f04..e88c0f9 100644
--- a/test/cpp/end2end/zookeeper_test.cc
+++ b/test/cpp/end2end/zookeeper_test.cc
@@ -157,7 +157,7 @@
 
   void ResetStub() {
     string target = "zookeeper://" + zookeeper_address_ + "/test";
-    channel_ = CreateChannel(target, InsecureCredentials());
+    channel_ = CreateChannel(target, InsecureChannelCredentials());
     stub_ = std::move(grpc::cpp::test::util::TestService::NewStub(channel_));
   }
 
diff --git a/test/cpp/interop/client_helper.cc b/test/cpp/interop/client_helper.cc
index 61b46d2..5caf0f2 100644
--- a/test/cpp/interop/client_helper.cc
+++ b/test/cpp/interop/client_helper.cc
@@ -76,11 +76,11 @@
 }
 
 grpc::string GetOauth2AccessToken() {
-  std::shared_ptr<Credentials> creds = GoogleComputeEngineCredentials();
-  SecureCredentials* secure_creds =
-      dynamic_cast<SecureCredentials*>(creds.get());
+  std::shared_ptr<CallCredentials> creds = GoogleComputeEngineCredentials();
+  SecureCallCredentials* secure_creds =
+      dynamic_cast<SecureCallCredentials*>(creds.get());
   GPR_ASSERT(secure_creds != nullptr);
-  grpc_credentials* c_creds = secure_creds->GetRawCreds();
+  grpc_call_credentials* c_creds = secure_creds->GetRawCreds();
   char* token = grpc_test_fetch_oauth2_token_with_credentials(c_creds);
   GPR_ASSERT(token != nullptr);
   gpr_log(GPR_INFO, "Get raw oauth2 access token: %s", token);
@@ -98,13 +98,13 @@
            FLAGS_server_port);
 
   if (test_case == "compute_engine_creds") {
-    std::shared_ptr<Credentials> creds;
+    std::shared_ptr<CallCredentials> creds;
     GPR_ASSERT(FLAGS_use_tls);
     creds = GoogleComputeEngineCredentials();
     return CreateTestChannel(host_port, FLAGS_server_host_override,
                              FLAGS_use_tls, !FLAGS_use_test_ca, creds);
   } else if (test_case == "jwt_token_creds") {
-    std::shared_ptr<Credentials> creds;
+    std::shared_ptr<CallCredentials> creds;
     GPR_ASSERT(FLAGS_use_tls);
     grpc::string json_key = GetServiceAccountJsonKey();
     std::chrono::seconds token_lifetime = std::chrono::hours(1);
@@ -114,7 +114,7 @@
                              FLAGS_use_tls, !FLAGS_use_test_ca, creds);
   } else if (test_case == "oauth2_auth_token") {
     grpc::string raw_token = GetOauth2AccessToken();
-    std::shared_ptr<Credentials> creds = AccessTokenCredentials(raw_token);
+    std::shared_ptr<CallCredentials> creds = AccessTokenCredentials(raw_token);
     return CreateTestChannel(host_port, FLAGS_server_host_override,
                              FLAGS_use_tls, !FLAGS_use_test_ca, creds);
   } else {
diff --git a/test/cpp/interop/interop_client.cc b/test/cpp/interop/interop_client.cc
index 46a5255..6340007 100644
--- a/test/cpp/interop/interop_client.cc
+++ b/test/cpp/interop/interop_client.cc
@@ -244,7 +244,7 @@
 
   ClientContext context;
   std::chrono::seconds token_lifetime = std::chrono::hours(1);
-  std::shared_ptr<Credentials> creds =
+  std::shared_ptr<CallCredentials> creds =
       ServiceAccountJWTAccessCredentials(json_key, token_lifetime.count());
 
   context.set_credentials(creds);
diff --git a/test/cpp/interop/metrics_client.cc b/test/cpp/interop/metrics_client.cc
new file mode 100644
index 0000000..5d60a84
--- /dev/null
+++ b/test/cpp/interop/metrics_client.cc
@@ -0,0 +1,102 @@
+/*
+ *
+ * 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.
+ *is % allowed in string
+ */
+
+#include <memory>
+#include <string>
+
+#include <gflags/gflags.h>
+#include <grpc++/grpc++.h>
+
+#include "test/cpp/util/metrics_server.h"
+#include "test/cpp/util/test_config.h"
+#include "test/proto/metrics.grpc.pb.h"
+#include "test/proto/metrics.pb.h"
+
+DEFINE_string(metrics_server_address, "",
+              "The metrics server addresses in the fomrat <hostname>:<port>");
+
+using grpc::testing::EmptyMessage;
+using grpc::testing::GaugeResponse;
+using grpc::testing::MetricsService;
+using grpc::testing::MetricsServiceImpl;
+
+void PrintMetrics(grpc::string& server_address) {
+  gpr_log(GPR_INFO, "creating a channel to %s", server_address.c_str());
+  std::shared_ptr<grpc::Channel> channel(
+      grpc::CreateChannel(server_address, grpc::InsecureChannelCredentials()));
+
+  std::unique_ptr<MetricsService::Stub> stub(MetricsService::NewStub(channel));
+
+  grpc::ClientContext context;
+  EmptyMessage message;
+
+  std::unique_ptr<grpc::ClientReader<GaugeResponse>> reader(
+      stub->GetAllGauges(&context, message));
+
+  GaugeResponse gauge_response;
+  long overall_qps = 0;
+  int idx = 0;
+  while (reader->Read(&gauge_response)) {
+    if (gauge_response.value_case() == GaugeResponse::kLongValue) {
+      gpr_log(GPR_INFO, "Gauge: %d (%s: %ld)", ++idx,
+              gauge_response.name().c_str(), gauge_response.long_value());
+      overall_qps += gauge_response.long_value();
+    } else {
+      gpr_log(GPR_INFO, "Gauge %s is not a long value", gauge_response.name().c_str());
+    }
+  }
+
+  gpr_log(GPR_INFO, "OVERALL: %ld", overall_qps);
+
+  const grpc::Status status = reader->Finish();
+  if (!status.ok()) {
+    gpr_log(GPR_ERROR, "Error in getting metrics from the client");
+  }
+}
+
+int main(int argc, char** argv) {
+  grpc::testing::InitTest(&argc, &argv, true);
+
+  // Make sure server_addresses flag is not empty
+  if (FLAGS_metrics_server_address.empty()) {
+    gpr_log(
+        GPR_ERROR,
+        "Cannot connect to the Metrics server. Please pass the address of the"
+        "metrics server to connect to via the 'metrics_server_address' flag");
+    return 1;
+  }
+
+  PrintMetrics(FLAGS_metrics_server_address);
+
+  return 0;
+}
diff --git a/test/cpp/interop/stress_interop_client.cc b/test/cpp/interop/stress_interop_client.cc
index f8c55cf..5d2951e 100644
--- a/test/cpp/interop/stress_interop_client.cc
+++ b/test/cpp/interop/stress_interop_client.cc
@@ -40,6 +40,7 @@
 #include <grpc++/create_channel.h>
 
 #include "test/cpp/interop/interop_client.h"
+#include "test/cpp/util/metrics_server.h"
 
 namespace grpc {
 namespace testing {
@@ -81,21 +82,19 @@
 
 StressTestInteropClient::StressTestInteropClient(
     int test_id, const grpc::string& server_address,
+    std::shared_ptr<Channel> channel,
     const WeightedRandomTestSelector& test_selector, long test_duration_secs,
-    long sleep_duration_ms)
+    long sleep_duration_ms, long metrics_collection_interval_secs)
     : test_id_(test_id),
       server_address_(server_address),
+      channel_(channel),
+      interop_client_(new InteropClient(channel, false)),
       test_selector_(test_selector),
       test_duration_secs_(test_duration_secs),
-      sleep_duration_ms_(sleep_duration_ms) {
-  // TODO(sreek): This will change once we add support for other tests
-  // that won't work with InsecureCredentials()
-  std::shared_ptr<Channel> channel(
-      CreateChannel(server_address, InsecureCredentials()));
-  interop_client_.reset(new InteropClient(channel, false));
-}
+      sleep_duration_ms_(sleep_duration_ms),
+      metrics_collection_interval_secs_(metrics_collection_interval_secs) {}
 
-void StressTestInteropClient::MainLoop() {
+void StressTestInteropClient::MainLoop(std::shared_ptr<Gauge> qps_gauge) {
   gpr_log(GPR_INFO, "Running test %d. ServerAddr: %s", test_id_,
           server_address_.c_str());
 
@@ -104,21 +103,38 @@
                    gpr_time_from_seconds(test_duration_secs_, GPR_TIMESPAN));
 
   gpr_timespec current_time = gpr_now(GPR_CLOCK_REALTIME);
+  gpr_timespec next_stat_collection_time = current_time;
+  gpr_timespec collection_interval =
+      gpr_time_from_seconds(metrics_collection_interval_secs_, GPR_TIMESPAN);
+  long num_calls_per_interval = 0;
+
   while (test_duration_secs_ < 0 ||
-         gpr_time_cmp(current_time, test_end_time) < 0) {
+         gpr_time_cmp(gpr_now(GPR_CLOCK_REALTIME), test_end_time) < 0) {
     // Select the test case to execute based on the weights and execute it
     TestCaseType test_case = test_selector_.GetNextTest();
     gpr_log(GPR_INFO, "%d - Executing the test case %d", test_id_, test_case);
     RunTest(test_case);
 
-    // Sleep between successive calls if needed
-    if (sleep_duration_ms_ > 0) {
-      gpr_timespec sleep_time = gpr_time_add(
-          current_time, gpr_time_from_millis(sleep_duration_ms_, GPR_TIMESPAN));
-      gpr_sleep_until(sleep_time);
+    num_calls_per_interval++;
+
+    // See if its time to collect stats yet
+    current_time = gpr_now(GPR_CLOCK_REALTIME);
+    if (gpr_time_cmp(next_stat_collection_time, current_time) < 0) {
+      qps_gauge->Set(num_calls_per_interval /
+                     metrics_collection_interval_secs_);
+
+      num_calls_per_interval = 0;
+      next_stat_collection_time =
+          gpr_time_add(current_time, collection_interval);
     }
 
-    current_time = gpr_now(GPR_CLOCK_REALTIME);
+    // Sleep between successive calls if needed
+    if (sleep_duration_ms_ > 0) {
+      gpr_timespec sleep_time =
+          gpr_time_add(gpr_now(GPR_CLOCK_REALTIME),
+                       gpr_time_from_millis(sleep_duration_ms_, GPR_TIMESPAN));
+      gpr_sleep_until(sleep_time);
+    }
   }
 }
 
diff --git a/test/cpp/interop/stress_interop_client.h b/test/cpp/interop/stress_interop_client.h
index 36261e5..6fd303d 100644
--- a/test/cpp/interop/stress_interop_client.h
+++ b/test/cpp/interop/stress_interop_client.h
@@ -41,6 +41,7 @@
 #include <grpc++/create_channel.h>
 
 #include "test/cpp/interop/interop_client.h"
+#include "test/cpp/util/metrics_server.h"
 
 namespace grpc {
 namespace testing {
@@ -84,20 +85,26 @@
 class StressTestInteropClient {
  public:
   StressTestInteropClient(int test_id, const grpc::string& server_address,
+                          std::shared_ptr<Channel> channel,
                           const WeightedRandomTestSelector& test_selector,
-                          long test_duration_secs, long sleep_duration_ms);
+                          long test_duration_secs, long sleep_duration_ms,
+                          long metrics_collection_interval_secs);
 
-  void MainLoop();  // The main function. Use this as the thread entry point.
+  // The main function. Use this as the thread entry point.
+  // qps_gauge is the Gauge to record the requests per second metric
+  void MainLoop(std::shared_ptr<Gauge> qps_gauge);
 
  private:
   void RunTest(TestCaseType test_case);
 
   int test_id_;
-  std::unique_ptr<InteropClient> interop_client_;
   const grpc::string& server_address_;
+  std::shared_ptr<Channel> channel_;
+  std::unique_ptr<InteropClient> interop_client_;
   const WeightedRandomTestSelector& test_selector_;
   long test_duration_secs_;
   long sleep_duration_ms_;
+  long metrics_collection_interval_secs_;
 };
 
 }  // namespace testing
diff --git a/test/cpp/interop/stress_test.cc b/test/cpp/interop/stress_test.cc
index 5d14197..934f4f5 100644
--- a/test/cpp/interop/stress_test.cc
+++ b/test/cpp/interop/stress_test.cc
@@ -38,13 +38,22 @@
 #include <vector>
 
 #include <gflags/gflags.h>
-#include <grpc/support/time.h>
 #include <grpc++/create_channel.h>
 #include <grpc++/grpc++.h>
+#include <grpc++/impl/thd.h>
+#include <grpc/support/time.h>
 
 #include "test/cpp/interop/interop_client.h"
 #include "test/cpp/interop/stress_interop_client.h"
+#include "test/cpp/util/metrics_server.h"
 #include "test/cpp/util/test_config.h"
+#include "test/proto/metrics.grpc.pb.h"
+#include "test/proto/metrics.pb.h"
+
+DEFINE_int32(metrics_port, 8081, "The metrics server port.");
+
+DEFINE_int32(metrics_collection_interval_secs, 5,
+             "How often (in seconds) should metrics be recorded.");
 
 DEFINE_int32(sleep_duration_ms, 0,
              "The duration (in millisec) between two"
@@ -61,6 +70,13 @@
               " \"<name_1>:<port_1>,<name_2>:<port_1>...<name_N>:<port_N>\"\n"
               " Note: <name> can be servername or IP address.");
 
+DEFINE_int32(num_channels_per_server, 1, "Number of channels for each server");
+
+DEFINE_int32(num_stubs_per_channel, 1,
+             "Number of stubs per each channels to server. This number also "
+             "indicates the max number of parallel RPC calls on each channel "
+             "at any given time.");
+
 // TODO(sreek): Add more test cases here in future
 DEFINE_string(test_cases, "",
               "List of test cases to call along with the"
@@ -78,16 +94,13 @@
               " 'large_unary', 10% of the time and 'empty_stream' the remaining"
               " 70% of the time");
 
-using std::make_pair;
-using std::pair;
-using std::thread;
-using std::vector;
-
 using grpc::testing::kTestCaseList;
+using grpc::testing::MetricsService;
+using grpc::testing::MetricsServiceImpl;
 using grpc::testing::StressTestInteropClient;
 using grpc::testing::TestCaseType;
-using grpc::testing::WeightedRandomTestSelector;
 using grpc::testing::UNKNOWN_TEST;
+using grpc::testing::WeightedRandomTestSelector;
 
 TestCaseType GetTestTypeFromName(const grpc::string& test_name) {
   TestCaseType test_case = UNKNOWN_TEST;
@@ -104,7 +117,7 @@
 
 // Converts a string of comma delimited tokens to a vector of tokens
 bool ParseCommaDelimitedString(const grpc::string& comma_delimited_str,
-                               vector<grpc::string>& tokens) {
+                               std::vector<grpc::string>& tokens) {
   size_t bpos = 0;
   size_t epos = grpc::string::npos;
 
@@ -122,10 +135,10 @@
 //   - Whether parsing was successful (return value)
 //   - Vector of (test_type_enum, weight) pairs returned via 'tests' parameter
 bool ParseTestCasesString(const grpc::string& test_cases,
-                          vector<pair<TestCaseType, int>>& tests) {
+                          std::vector<std::pair<TestCaseType, int>>& tests) {
   bool is_success = true;
 
-  vector<grpc::string> tokens;
+  std::vector<grpc::string> tokens;
   ParseCommaDelimitedString(test_cases, tokens);
 
   for (auto it = tokens.begin(); it != tokens.end(); it++) {
@@ -153,8 +166,8 @@
 }
 
 // For debugging purposes
-void LogParameterInfo(const vector<grpc::string>& addresses,
-                      const vector<pair<TestCaseType, int>>& tests) {
+void LogParameterInfo(const std::vector<grpc::string>& addresses,
+                      const std::vector<std::pair<TestCaseType, int>>& tests) {
   gpr_log(GPR_INFO, "server_addresses: %s", FLAGS_server_addresses.c_str());
   gpr_log(GPR_INFO, "test_cases : %s", FLAGS_test_cases.c_str());
   gpr_log(GPR_INFO, "sleep_duration_ms: %d", FLAGS_sleep_duration_ms);
@@ -180,7 +193,7 @@
   srand(time(NULL));
 
   // Parse the server addresses
-  vector<grpc::string> server_addresses;
+  std::vector<grpc::string> server_addresses;
   ParseCommaDelimitedString(FLAGS_server_addresses, server_addresses);
 
   // Parse test cases and weights
@@ -189,7 +202,7 @@
     return 1;
   }
 
-  vector<pair<TestCaseType, int>> tests;
+  std::vector<std::pair<TestCaseType, int>> tests;
   if (!ParseTestCasesString(FLAGS_test_cases, tests)) {
     gpr_log(GPR_ERROR, "Error in parsing test cases string %s ",
             FLAGS_test_cases.c_str());
@@ -199,23 +212,64 @@
   LogParameterInfo(server_addresses, tests);
 
   WeightedRandomTestSelector test_selector(tests);
+  MetricsServiceImpl metrics_service;
 
   gpr_log(GPR_INFO, "Starting test(s)..");
 
-  vector<thread> test_threads;
-  int thread_idx = 0;
-  for (auto it = server_addresses.begin(); it != server_addresses.end(); it++) {
-    StressTestInteropClient* client = new StressTestInteropClient(
-        ++thread_idx, *it, test_selector, FLAGS_test_duration_secs,
-        FLAGS_sleep_duration_ms);
+  std::vector<grpc::thread> test_threads;
 
-    test_threads.emplace_back(
-        thread(&StressTestInteropClient::MainLoop, client));
+  // Create and start the test threads.
+  // Note that:
+  // - Each server can have multiple channels (as configured by
+  // FLAGS_num_channels_per_server).
+  //
+  // - Each channel can have multiple stubs (as configured by
+  // FLAGS_num_stubs_per_channel). This is to test calling multiple RPCs in
+  // parallel on the same channel.
+  int thread_idx = 0;
+  int server_idx = -1;
+  char buffer[256];
+  for (auto it = server_addresses.begin(); it != server_addresses.end(); it++) {
+    ++server_idx;
+    // Create channel(s) for each server
+    for (int channel_idx = 0; channel_idx < FLAGS_num_channels_per_server;
+         channel_idx++) {
+      // TODO (sreek). This won't work for tests that require Authentication
+      std::shared_ptr<grpc::Channel> channel(
+          grpc::CreateChannel(*it, grpc::InsecureChannelCredentials()));
+
+      // Create stub(s) for each channel
+      for (int stub_idx = 0; stub_idx < FLAGS_num_stubs_per_channel;
+           stub_idx++) {
+        StressTestInteropClient* client = new StressTestInteropClient(
+            ++thread_idx, *it, channel, test_selector, FLAGS_test_duration_secs,
+            FLAGS_sleep_duration_ms, FLAGS_metrics_collection_interval_secs);
+
+        bool is_already_created;
+        // Gauge name
+        std::snprintf(buffer, sizeof(buffer),
+                      "/stress_test/server_%d/channel_%d/stub_%d/qps",
+                      server_idx, channel_idx, stub_idx);
+
+        test_threads.emplace_back(grpc::thread(
+            &StressTestInteropClient::MainLoop, client,
+            metrics_service.CreateGauge(buffer, &is_already_created)));
+
+        // The Gauge should not have been already created
+        GPR_ASSERT(!is_already_created);
+      }
+    }
   }
 
+  // Start metrics server before waiting for the stress test threads
+  std::unique_ptr<grpc::Server> metrics_server =
+      metrics_service.StartServer(FLAGS_metrics_port);
+
+  // Wait for the stress test threads to complete
   for (auto it = test_threads.begin(); it != test_threads.end(); it++) {
     it->join();
   }
 
+  metrics_server->Wait();
   return 0;
 }
diff --git a/test/cpp/qps/async_streaming_ping_pong_test.cc b/test/cpp/qps/async_streaming_ping_pong_test.cc
index 9fef93a..0acdf3a 100644
--- a/test/cpp/qps/async_streaming_ping_pong_test.cc
+++ b/test/cpp/qps/async_streaming_ping_pong_test.cc
@@ -58,6 +58,7 @@
 
   ServerConfig server_config;
   server_config.set_server_type(ASYNC_SERVER);
+  server_config.set_host("localhost");
   server_config.set_async_server_threads(1);
 
   const auto result =
diff --git a/test/cpp/qps/async_unary_ping_pong_test.cc b/test/cpp/qps/async_unary_ping_pong_test.cc
index b4ab0e5..d21e116 100644
--- a/test/cpp/qps/async_unary_ping_pong_test.cc
+++ b/test/cpp/qps/async_unary_ping_pong_test.cc
@@ -58,6 +58,7 @@
 
   ServerConfig server_config;
   server_config.set_server_type(ASYNC_SERVER);
+  server_config.set_host("localhost");
   server_config.set_async_server_threads(1);
 
   const auto result =
diff --git a/test/cpp/qps/client.h b/test/cpp/qps/client.h
index f440069..b24a90a 100644
--- a/test/cpp/qps/client.h
+++ b/test/cpp/qps/client.h
@@ -181,29 +181,29 @@
 
     std::unique_ptr<RandomDist> random_dist;
     switch (load.load_case()) {
-    case LoadParams::kClosedLoop:
-      // Closed-loop doesn't use random dist at all
-      break;
-    case LoadParams::kPoisson:
-      random_dist.reset(
-          new ExpDist(load.poisson().offered_load() / num_threads));
-      break;
-    case LoadParams::kUniform:
-      random_dist.reset(
-          new UniformDist(load.uniform().interarrival_lo() * num_threads,
-                          load.uniform().interarrival_hi() * num_threads));
-      break;
-    case LoadParams::kDeterm:
-      random_dist.reset(
-          new DetDist(num_threads / load.determ().offered_load()));
-      break;
-    case LoadParams::kPareto:
-      random_dist.reset(
-          new ParetoDist(load.pareto().interarrival_base() * num_threads,
-                         load.pareto().alpha()));
-      break;
-    default:
-      GPR_ASSERT(false);
+      case LoadParams::kClosedLoop:
+        // Closed-loop doesn't use random dist at all
+        break;
+      case LoadParams::kPoisson:
+        random_dist.reset(
+            new ExpDist(load.poisson().offered_load() / num_threads));
+        break;
+      case LoadParams::kUniform:
+        random_dist.reset(
+            new UniformDist(load.uniform().interarrival_lo() * num_threads,
+                            load.uniform().interarrival_hi() * num_threads));
+        break;
+      case LoadParams::kDeterm:
+        random_dist.reset(
+            new DetDist(num_threads / load.determ().offered_load()));
+        break;
+      case LoadParams::kPareto:
+        random_dist.reset(
+            new ParetoDist(load.pareto().interarrival_base() * num_threads,
+                           load.pareto().alpha()));
+        break;
+      default:
+        GPR_ASSERT(false);
     }
 
     // Set closed_loop_ based on whether or not random_dist is set
diff --git a/test/cpp/qps/driver.cc b/test/cpp/qps/driver.cc
index 2c6247d..20dc650 100644
--- a/test/cpp/qps/driver.cc
+++ b/test/cpp/qps/driver.cc
@@ -110,7 +110,7 @@
   list<ClientContext> contexts;
 
   // To be added to the result, containing the final configuration used for
-  // client and config (incluiding host, etc.)
+  // client and config (including host, etc.)
   ClientConfig result_client_config;
   ServerConfig result_server_config;
 
@@ -162,7 +162,7 @@
   auto* servers = new ServerData[num_servers];
   for (size_t i = 0; i < num_servers; i++) {
     servers[i].stub = WorkerService::NewStub(
-        CreateChannel(workers[i], InsecureCredentials()));
+        CreateChannel(workers[i], InsecureChannelCredentials()));
     ServerArgs args;
     result_server_config = server_config;
     *args.mutable_setup() = server_config;
@@ -189,7 +189,7 @@
   auto* clients = new ClientData[num_clients];
   for (size_t i = 0; i < num_clients; i++) {
     clients[i].stub = WorkerService::NewStub(
-        CreateChannel(workers[i + num_servers], InsecureCredentials()));
+        CreateChannel(workers[i + num_servers], InsecureChannelCredentials()));
     ClientArgs args;
     result_client_config = client_config;
     *args.mutable_setup() = client_config;
diff --git a/test/cpp/qps/histogram.h b/test/cpp/qps/histogram.h
index 35527d2..b45c769 100644
--- a/test/cpp/qps/histogram.h
+++ b/test/cpp/qps/histogram.h
@@ -42,7 +42,9 @@
 
 class Histogram {
  public:
-  Histogram() : impl_(gpr_histogram_create(0.01, 60e9)) {}
+  // TODO: look into making histogram params not hardcoded for C++
+  Histogram() : impl_(gpr_histogram_create(default_resolution(),
+                                           default_max_possible())) {}
   ~Histogram() {
     if (impl_) gpr_histogram_destroy(impl_);
   }
@@ -73,6 +75,9 @@
                                  p.sum_of_squares(), p.count());
   }
 
+  static double default_resolution() { return 0.01; }
+  static double default_max_possible() { return 60e9; }
+
  private:
   Histogram(const Histogram&);
   Histogram& operator=(const Histogram&);
diff --git a/test/cpp/qps/qps_driver.cc b/test/cpp/qps/qps_driver.cc
index 4c93a04..0479e1a 100644
--- a/test/cpp/qps/qps_driver.cc
+++ b/test/cpp/qps/qps_driver.cc
@@ -137,8 +137,14 @@
     // No further load parameters to set up for closed loop
   }
 
+  client_config.mutable_histogram_params()->
+      set_resolution(Histogram::default_resolution());
+  client_config.mutable_histogram_params()->
+      set_max_possible(Histogram::default_max_possible());
+
   ServerConfig server_config;
   server_config.set_server_type(server_type);
+  server_config.set_host("localhost");
   server_config.set_async_server_threads(FLAGS_async_server_threads);
 
   if (FLAGS_secure_test) {
diff --git a/test/cpp/qps/qps_openloop_test.cc b/test/cpp/qps/qps_openloop_test.cc
index dc88c89..51df79e 100644
--- a/test/cpp/qps/qps_openloop_test.cc
+++ b/test/cpp/qps/qps_openloop_test.cc
@@ -59,6 +59,7 @@
 
   ServerConfig server_config;
   server_config.set_server_type(ASYNC_SERVER);
+  server_config.set_host("localhost");
   server_config.set_async_server_threads(4);
 
   const auto result =
diff --git a/test/cpp/qps/qps_test.cc b/test/cpp/qps/qps_test.cc
index 89b35cf..1f87d18 100644
--- a/test/cpp/qps/qps_test.cc
+++ b/test/cpp/qps/qps_test.cc
@@ -58,6 +58,7 @@
 
   ServerConfig server_config;
   server_config.set_server_type(ASYNC_SERVER);
+  server_config.set_host("localhost");
   server_config.set_async_server_threads(8);
 
   const auto result =
diff --git a/test/cpp/qps/qps_test_with_poll.cc b/test/cpp/qps/qps_test_with_poll.cc
index 97da409..dc80009 100644
--- a/test/cpp/qps/qps_test_with_poll.cc
+++ b/test/cpp/qps/qps_test_with_poll.cc
@@ -62,6 +62,7 @@
 
   ServerConfig server_config;
   server_config.set_server_type(ASYNC_SERVER);
+  server_config.set_host("localhost");
   server_config.set_async_server_threads(4);
 
   const auto result =
diff --git a/test/cpp/qps/report.h b/test/cpp/qps/report.h
index 7877923..5caf3fe 100644
--- a/test/cpp/qps/report.h
+++ b/test/cpp/qps/report.h
@@ -115,8 +115,8 @@
         test_name_(test_name),
         sys_info_(sys_info),
         tag_(tag) {
-    perf_db_client_.init(
-        grpc::CreateChannel(server_address, grpc::InsecureCredentials()));
+    perf_db_client_.init(grpc::CreateChannel(
+        server_address, grpc::InsecureChannelCredentials()));
   }
   ~PerfDbReporter() GRPC_OVERRIDE { SendData(); };
 
diff --git a/test/cpp/qps/secure_sync_unary_ping_pong_test.cc b/test/cpp/qps/secure_sync_unary_ping_pong_test.cc
index df06f7e..ce9f02c 100644
--- a/test/cpp/qps/secure_sync_unary_ping_pong_test.cc
+++ b/test/cpp/qps/secure_sync_unary_ping_pong_test.cc
@@ -57,6 +57,7 @@
 
   ServerConfig server_config;
   server_config.set_server_type(SYNC_SERVER);
+  server_config.set_host("localhost");
 
   // Set up security params
   SecurityParams security;
diff --git a/test/cpp/qps/server_async.cc b/test/cpp/qps/server_async.cc
index 2d922fa..c151918 100644
--- a/test/cpp/qps/server_async.cc
+++ b/test/cpp/qps/server_async.cc
@@ -60,7 +60,7 @@
   explicit AsyncQpsServerTest(const ServerConfig &config) : Server(config) {
     char *server_address = NULL;
 
-    gpr_join_host_port(&server_address, "::", port());
+    gpr_join_host_port(&server_address, config.host().c_str(), port());
 
     ServerBuilder builder;
     builder.AddListeningPort(server_address,
diff --git a/test/cpp/qps/server_sync.cc b/test/cpp/qps/server_sync.cc
index a09b174..3a15bec 100644
--- a/test/cpp/qps/server_sync.cc
+++ b/test/cpp/qps/server_sync.cc
@@ -89,7 +89,7 @@
 
     char* server_address = NULL;
 
-    gpr_join_host_port(&server_address, "::", port());
+    gpr_join_host_port(&server_address, config.host().c_str(), port());
     builder.AddListeningPort(server_address,
                              Server::CreateServerCredentials(config));
     gpr_free(server_address);
diff --git a/test/cpp/qps/sync_streaming_ping_pong_test.cc b/test/cpp/qps/sync_streaming_ping_pong_test.cc
index 186afc0..dd8c682 100644
--- a/test/cpp/qps/sync_streaming_ping_pong_test.cc
+++ b/test/cpp/qps/sync_streaming_ping_pong_test.cc
@@ -57,6 +57,7 @@
 
   ServerConfig server_config;
   server_config.set_server_type(SYNC_SERVER);
+  server_config.set_host("localhost");
 
   const auto result =
       RunScenario(client_config, 1, server_config, 1, WARMUP, BENCHMARK, -2);
diff --git a/test/cpp/qps/sync_unary_ping_pong_test.cc b/test/cpp/qps/sync_unary_ping_pong_test.cc
index 2585183..2edb33e 100644
--- a/test/cpp/qps/sync_unary_ping_pong_test.cc
+++ b/test/cpp/qps/sync_unary_ping_pong_test.cc
@@ -57,6 +57,7 @@
 
   ServerConfig server_config;
   server_config.set_server_type(SYNC_SERVER);
+  server_config.set_host("localhost");
 
   const auto result =
       RunScenario(client_config, 1, server_config, 1, WARMUP, BENCHMARK, -2);
diff --git a/test/cpp/util/cli_call_test.cc b/test/cpp/util/cli_call_test.cc
index 9c8d599..32cd8e4 100644
--- a/test/cpp/util/cli_call_test.cc
+++ b/test/cpp/util/cli_call_test.cc
@@ -89,7 +89,8 @@
   void TearDown() GRPC_OVERRIDE { server_->Shutdown(); }
 
   void ResetStub() {
-    channel_ = CreateChannel(server_address_.str(), InsecureCredentials());
+    channel_ =
+        CreateChannel(server_address_.str(), InsecureChannelCredentials());
     stub_ = grpc::cpp::test::util::TestService::NewStub(channel_);
   }
 
diff --git a/test/cpp/util/create_test_channel.cc b/test/cpp/util/create_test_channel.cc
index f0d5bfc..0cd9f9e 100644
--- a/test/cpp/util/create_test_channel.cc
+++ b/test/cpp/util/create_test_channel.cc
@@ -58,13 +58,14 @@
 std::shared_ptr<Channel> CreateTestChannel(
     const grpc::string& server, const grpc::string& override_hostname,
     bool enable_ssl, bool use_prod_roots,
-    const std::shared_ptr<Credentials>& creds) {
+    const std::shared_ptr<CallCredentials>& creds) {
   ChannelArguments channel_args;
   if (enable_ssl) {
     const char* roots_certs = use_prod_roots ? "" : test_root_cert;
     SslCredentialsOptions ssl_opts = {roots_certs, "", ""};
 
-    std::shared_ptr<Credentials> channel_creds = SslCredentials(ssl_opts);
+    std::shared_ptr<ChannelCredentials> channel_creds =
+        SslCredentials(ssl_opts);
 
     if (!server.empty() && !override_hostname.empty()) {
       channel_args.SetSslTargetNameOverride(override_hostname);
@@ -72,11 +73,11 @@
     const grpc::string& connect_to =
         server.empty() ? override_hostname : server;
     if (creds.get()) {
-      channel_creds = CompositeCredentials(creds, channel_creds);
+      channel_creds = CompositeChannelCredentials(channel_creds, creds);
     }
     return CreateCustomChannel(connect_to, channel_creds, channel_args);
   } else {
-    return CreateChannel(server, InsecureCredentials());
+    return CreateChannel(server, InsecureChannelCredentials());
   }
 }
 
@@ -84,7 +85,7 @@
     const grpc::string& server, const grpc::string& override_hostname,
     bool enable_ssl, bool use_prod_roots) {
   return CreateTestChannel(server, override_hostname, enable_ssl,
-                           use_prod_roots, std::shared_ptr<Credentials>());
+                           use_prod_roots, std::shared_ptr<CallCredentials>());
 }
 
 // Shortcut for end2end and interop tests.
diff --git a/test/cpp/util/create_test_channel.h b/test/cpp/util/create_test_channel.h
index a475068..b50d653 100644
--- a/test/cpp/util/create_test_channel.h
+++ b/test/cpp/util/create_test_channel.h
@@ -51,7 +51,7 @@
 std::shared_ptr<Channel> CreateTestChannel(
     const grpc::string& server, const grpc::string& override_hostname,
     bool enable_ssl, bool use_prod_roots,
-    const std::shared_ptr<Credentials>& creds);
+    const std::shared_ptr<CallCredentials>& creds);
 
 }  // namespace grpc
 
diff --git a/test/cpp/util/grpc_cli.cc b/test/cpp/util/grpc_cli.cc
index 334b6ef..3f40b24 100644
--- a/test/cpp/util/grpc_cli.cc
+++ b/test/cpp/util/grpc_cli.cc
@@ -148,9 +148,9 @@
   std::stringstream input_stream;
   input_stream << input_file.rdbuf();
 
-  std::shared_ptr<grpc::Credentials> creds;
+  std::shared_ptr<grpc::ChannelCredentials> creds;
   if (!FLAGS_enable_ssl) {
-    creds = grpc::InsecureCredentials();
+    creds = grpc::InsecureChannelCredentials();
   } else {
     if (FLAGS_use_auth) {
       creds = grpc::GoogleDefaultCredentials();
diff --git a/test/cpp/util/metrics_server.cc b/test/cpp/util/metrics_server.cc
new file mode 100644
index 0000000..426295f
--- /dev/null
+++ b/test/cpp/util/metrics_server.cc
@@ -0,0 +1,119 @@
+/*
+ *
+ * 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.
+ *is % allowed in string
+ */
+
+#include "test/cpp/util/metrics_server.h"
+
+#include <grpc++/server_builder.h>
+
+#include "test/proto/metrics.grpc.pb.h"
+#include "test/proto/metrics.pb.h"
+
+namespace grpc {
+namespace testing {
+
+Gauge::Gauge(long initial_val) : val_(initial_val) {}
+
+void Gauge::Set(long new_val) {
+  std::lock_guard<std::mutex> lock(val_mu_);
+  val_ = new_val;
+}
+
+long Gauge::Get() {
+  std::lock_guard<std::mutex> lock(val_mu_);
+  return val_;
+}
+
+grpc::Status MetricsServiceImpl::GetAllGauges(
+    ServerContext* context, const EmptyMessage* request,
+    ServerWriter<GaugeResponse>* writer) {
+  gpr_log(GPR_INFO, "GetAllGauges called");
+
+  std::lock_guard<std::mutex> lock(mu_);
+  for (auto it = gauges_.begin(); it != gauges_.end(); it++) {
+    GaugeResponse resp;
+    resp.set_name(it->first);                // Gauge name
+    resp.set_long_value(it->second->Get());  // Gauge value
+    writer->Write(resp);
+  }
+
+  return Status::OK;
+}
+
+grpc::Status MetricsServiceImpl::GetGauge(ServerContext* context,
+                                          const GaugeRequest* request,
+                                          GaugeResponse* response) {
+  std::lock_guard<std::mutex> lock(mu_);
+
+  const auto it = gauges_.find(request->name());
+  if (it != gauges_.end()) {
+    response->set_name(it->first);
+    response->set_long_value(it->second->Get());
+  }
+
+  return Status::OK;
+}
+
+std::shared_ptr<Gauge> MetricsServiceImpl::CreateGauge(const grpc::string& name,
+                                                       bool* already_present) {
+  std::lock_guard<std::mutex> lock(mu_);
+
+  std::shared_ptr<Gauge> gauge(new Gauge(0));
+  const auto p = gauges_.emplace(name, gauge);
+
+  // p.first is an iterator pointing to <name, shared_ptr<Gauge>> pair. p.second
+  // is a boolean which is set to 'true' if the Gauge is inserted in the guages_
+  // map and 'false' if it is already present in the map
+  *already_present = !p.second;
+  return p.first->second;
+}
+
+// Starts the metrics server and returns the grpc::Server instance. Call Wait()
+// on the returned server instance.
+std::unique_ptr<grpc::Server> MetricsServiceImpl::StartServer(int port) {
+  gpr_log(GPR_INFO, "Building metrics server..");
+
+  const grpc::string address = "0.0.0.0:" + std::to_string(port);
+
+  ServerBuilder builder;
+  builder.AddListeningPort(address, grpc::InsecureServerCredentials());
+  builder.RegisterService(this);
+
+  std::unique_ptr<grpc::Server> server(builder.BuildAndStart());
+  gpr_log(GPR_INFO, "Metrics server %s started. Ready to receive requests..",
+          address.c_str());
+
+  return server;
+}
+
+}  // namespace testing
+}  // namespace grpc
diff --git a/test/cpp/util/metrics_server.h b/test/cpp/util/metrics_server.h
new file mode 100644
index 0000000..edde37d
--- /dev/null
+++ b/test/cpp/util/metrics_server.h
@@ -0,0 +1,100 @@
+/*
+ *
+ * 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.
+ *is % allowed in string
+ */
+#ifndef GRPC_TEST_CPP_METRICS_SERVER_H
+#define GRPC_TEST_CPP_METRICS_SERVER_H
+
+#include <map>
+#include <mutex>
+
+#include "test/proto/metrics.grpc.pb.h"
+#include "test/proto/metrics.pb.h"
+
+/*
+ * This implements a Metrics server defined in test/proto/metrics.proto. Any
+ * test service can use this to export Metrics (TODO (sreek): Only Gauges for
+ * now).
+ *
+ * Example:
+ *    MetricsServiceImpl metricsImpl;
+ *    ..
+ *    // Create Gauge(s). Note: Gauges can be created even after calling
+ *    // 'StartServer'.
+ *    Gauge gauge1 = metricsImpl.CreateGauge("foo",is_present);
+ *    // gauge1 can now be used anywhere in the program to set values.
+ *    ...
+ *    // Create the metrics server
+ *    std::unique_ptr<grpc::Server> server = metricsImpl.StartServer(port);
+ *    server->Wait(); // Note: This is blocking.
+ */
+namespace grpc {
+namespace testing {
+
+// TODO(sreek): Add support for other types of Gauges like Double, String in
+// future
+class Gauge {
+ public:
+  Gauge(long initial_val);
+  void Set(long new_val);
+  long Get();
+
+ private:
+  long val_;
+  std::mutex val_mu_;
+};
+
+class MetricsServiceImpl GRPC_FINAL : public MetricsService::Service {
+ public:
+  grpc::Status GetAllGauges(ServerContext* context, const EmptyMessage* request,
+                            ServerWriter<GaugeResponse>* writer) GRPC_OVERRIDE;
+
+  grpc::Status GetGauge(ServerContext* context, const GaugeRequest* request,
+                        GaugeResponse* response) GRPC_OVERRIDE;
+
+  // Create a Gauge with name 'name'. is_present is set to true if the Gauge
+  // is already present in the map.
+  // NOTE: CreateGauge can be called anytime (i.e before or after calling
+  // StartServer).
+  std::shared_ptr<Gauge> CreateGauge(const grpc::string& name,
+                                     bool* already_present);
+
+  std::unique_ptr<grpc::Server> StartServer(int port);
+
+ private:
+  std::map<string, std::shared_ptr<Gauge>> gauges_;
+  std::mutex mu_;
+};
+
+}  // namespace testing
+}  // namespace grpc
+
+#endif  // GRPC_TEST_CPP_METRICS_SERVER_H
diff --git a/test/proto/benchmarks/control.proto b/test/proto/benchmarks/control.proto
index 966ab78..42a5dd0 100644
--- a/test/proto/benchmarks/control.proto
+++ b/test/proto/benchmarks/control.proto
@@ -49,7 +49,10 @@
   STREAMING = 1;
 }
 
+// Parameters of poisson process distribution, which is a good representation
+// of activity coming in from independent identical stationary sources.
 message PoissonParams {
+  // The rate of arrivals (a.k.a. lambda parameter of the exp distribution).
   double offered_load = 1;
 }
 
@@ -67,6 +70,8 @@
   double alpha = 2;
 }
 
+// Once an RPC finishes, immediately start a new one.
+// No configuration parameters needed.
 message ClosedLoopParams {
 }
 
@@ -87,16 +92,23 @@
 }
 
 message ClientConfig {
+  // List of targets to connect to. At least one target needs to be specified.
   repeated string server_targets = 1;
   ClientType client_type = 2;
   SecurityParams security_params = 3;
+  // How many concurrent RPCs to start for each channel.
+  // For synchronous client, use a separate thread for each outstanding RPC.
   int32 outstanding_rpcs_per_channel = 4;
+  // Number of independent client channels to create.
+  // i-th channel will connect to server_target[i % server_targets.size()]
   int32 client_channels = 5;
-  // only for async client:
+  // Only for async client. Number of threads to use to start/manage RPCs.
   int32 async_client_threads = 7;
   RpcType rpc_type = 8;
+  // The requested load for the entire client (aggregated over all the threads).
   LoadParams load_params = 10;
   PayloadConfig payload_config = 11;
+  HistogramParams histogram_params = 12;
 }
 
 message ClientStatus {
@@ -105,6 +117,7 @@
 
 // Request current stats
 message Mark {
+  // if true, the stats will be reset after taking their snapshot.
   bool reset = 1;
 }
 
@@ -118,10 +131,13 @@
 message ServerConfig {
   ServerType server_type = 1;
   SecurityParams security_params = 2;
+  // Host on which to listen.
+  string host = 3;
+  // Port on which to listen. Zero means pick unused port.
   int32 port = 4;
-  // only for async server
+  // Only for async server. Number of threads used to serve the requests.
   int32 async_server_threads = 7;
-  // restrict core usage
+  // restrict core usage, currently unused
   int32 core_limit = 8;
   PayloadConfig payload_config = 9;
 }
@@ -135,6 +151,8 @@
 
 message ServerStatus {
   ServerStats stats = 1;
+  // the port bound by the server
   int32 port = 2;
+  // Number of cores on the server. See gpr_cpu_num_cores.
   int32 cores = 3;
 }
diff --git a/test/proto/benchmarks/services.proto b/test/proto/benchmarks/services.proto
index 4c2cbab..ff295ed 100644
--- a/test/proto/benchmarks/services.proto
+++ b/test/proto/benchmarks/services.proto
@@ -47,9 +47,19 @@
 }
 
 service WorkerService {
-  // Start server with specified workload
+  // Start server with specified workload.
+  // First request sent specifies the ServerConfig followed by ServerStatus
+  // response. After that, a "Mark" can be sent anytime to request the latest
+  // stats. Closing the stream will initiate shutdown of the test server
+  // and once the shutdown has finished, the OK status is sent to terminate
+  // this RPC.
   rpc RunServer(stream ServerArgs) returns (stream ServerStatus);
 
-  // Start client with specified workload
+  // Start client with specified workload.
+  // First request sent specifies the ClientConfig followed by ClientStatus
+  // response. After that, a "Mark" can be sent anytime to request the latest
+  // stats. Closing the stream will initiate shutdown of the test client
+  // and once the shutdown has finished, the OK status is sent to terminate
+  // this RPC.
   rpc RunClient(stream ClientArgs) returns (stream ClientStatus);
 }
diff --git a/test/proto/benchmarks/stats.proto b/test/proto/benchmarks/stats.proto
index d52144f..6b045b3 100644
--- a/test/proto/benchmarks/stats.proto
+++ b/test/proto/benchmarks/stats.proto
@@ -32,16 +32,24 @@
 package grpc.testing;
 
 message ServerStats {
-  // wall clock time
+  // wall clock time change in seconds since last reset
   double time_elapsed = 1;
 
-  // user time used by the server process and threads
+  // change in user time (in seconds) used by the server since last reset
   double time_user = 2;
 
-  // server time used by the server process and all threads
+  // change in server time (in seconds) used by the server process and all
+  // threads since last reset
   double time_system = 3;
 }
 
+// Histogram params based on grpc/support/histogram.c
+message HistogramParams {
+  double resolution = 1;  // first bucket is [0, 1 + resolution)
+  double max_possible = 2;  // use enough buckets to allow this value
+}
+
+// Histogram data based on grpc/support/histogram.c
 message HistogramData {
   repeated uint32 bucket = 1;
   double min_seen = 2;
@@ -52,7 +60,10 @@
 }
 
 message ClientStats {
+  // Latency histogram. Data points are in nanoseconds.
   HistogramData latencies = 1;
+
+  // See ServerStats for details.
   double time_elapsed = 2;
   double time_user = 3;
   double time_system = 4;
diff --git a/test/proto/metrics.proto b/test/proto/metrics.proto
new file mode 100644
index 0000000..14740eb
--- /dev/null
+++ b/test/proto/metrics.proto
@@ -0,0 +1,55 @@
+
+// Copyright 2015, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// An integration test service that covers all the method signature permutations
+// of unary/streaming requests/responses.
+syntax = "proto3";
+
+package grpc.testing;
+
+message GaugeResponse {
+  string name = 1;
+  oneof value {
+    int64 long_value = 2;
+    double double_vale = 3;
+    string string_value = 4;
+  }
+}
+
+message GaugeRequest {
+  string name = 1;
+}
+
+message EmptyMessage {}
+
+service MetricsService {
+  rpc GetAllGauges(EmptyMessage) returns (stream GaugeResponse);
+  rpc GetGauge(GaugeRequest) returns (GaugeResponse);
+}
diff --git a/tools/buildgen/plugins/transitive_dependencies.py b/tools/buildgen/plugins/transitive_dependencies.py
new file mode 100644
index 0000000..c2d3da3
--- /dev/null
+++ b/tools/buildgen/plugins/transitive_dependencies.py
@@ -0,0 +1,63 @@
+# 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.
+
+"""Buildgen transitive dependencies
+
+This takes the list of libs, node_modules, and targets from our
+yaml dictionary, and adds to each the transitive closure
+of the list of dependencies.
+
+"""
+
+def get_lib(libs, name):
+  return next(lib for lib in libs if lib['name']==name)
+
+def transitive_deps(lib, libs):
+  if 'deps' in lib:
+    # Recursively call transitive_deps on each dependency, and take the union
+    return set.union(set(lib['deps']),
+                     *[set(transitive_deps(get_lib(libs, dep), libs))
+                       for dep in lib['deps']])
+  else:
+    return set()
+
+def mako_plugin(dictionary):
+  """The exported plugin code for transitive_dependencies.
+
+  Each item in libs, node_modules, and targets can have a deps list.
+  We add a transitive_deps property to each with the transitive closure
+  of those dependency lists.
+  """
+  libs = dictionary.get('libs')
+  node_modules = dictionary.get('node_modules')
+  targets = dictionary.get('targets')
+
+  for target_list in (libs, node_modules, targets):
+    for target in target_list:
+      target['transitive_deps'] = transitive_deps(target, libs)
diff --git a/tools/codegen/core/gen_chttp2_stream_lists.py b/tools/codegen/core/gen_chttp2_stream_lists.py
deleted file mode 100644
index b28b04f..0000000
--- a/tools/codegen/core/gen_chttp2_stream_lists.py
+++ /dev/null
@@ -1,3 +0,0 @@
-
-
-
diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++
index 5d592c8..f077185 100644
--- a/tools/doxygen/Doxyfile.c++
+++ b/tools/doxygen/Doxyfile.c++
@@ -40,7 +40,7 @@
 # could be handy for archiving the generated documentation or if some version
 # control system is used.
 
-PROJECT_NUMBER         = 0.11.0.0
+PROJECT_NUMBER         = 0.12.0.0
 
 # Using the PROJECT_BRIEF tag one can provide an optional one line description
 # for a project that appears at the top of each page and should give viewer a
diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal
index bbd1706..11aaa37 100644
--- a/tools/doxygen/Doxyfile.c++.internal
+++ b/tools/doxygen/Doxyfile.c++.internal
@@ -40,7 +40,7 @@
 # could be handy for archiving the generated documentation or if some version
 # control system is used.
 
-PROJECT_NUMBER         = 0.11.0.0
+PROJECT_NUMBER         = 0.12.0.0
 
 # Using the PROJECT_BRIEF tag one can provide an optional one line description
 # for a project that appears at the top of each page and should give viewer a
diff --git a/tools/doxygen/Doxyfile.core b/tools/doxygen/Doxyfile.core
index beb0128..e411abf 100644
--- a/tools/doxygen/Doxyfile.core
+++ b/tools/doxygen/Doxyfile.core
@@ -40,7 +40,7 @@
 # could be handy for archiving the generated documentation or if some version
 # control system is used.
 
-PROJECT_NUMBER         = 0.11.0.0
+PROJECT_NUMBER         = 0.12.0.0
 
 # Using the PROJECT_BRIEF tag one can provide an optional one line description
 # for a project that appears at the top of each page and should give viewer a
diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal
index 4ce48b4..f0ec37b 100644
--- a/tools/doxygen/Doxyfile.core.internal
+++ b/tools/doxygen/Doxyfile.core.internal
@@ -40,7 +40,7 @@
 # could be handy for archiving the generated documentation or if some version
 # control system is used.
 
-PROJECT_NUMBER         = 0.11.0.0
+PROJECT_NUMBER         = 0.12.0.0
 
 # Using the PROJECT_BRIEF tag one can provide an optional one line description
 # for a project that appears at the top of each page and should give viewer a
diff --git a/tools/gke/kubernetes_api.py b/tools/gke/kubernetes_api.py
new file mode 100755
index 0000000..7dd3015
--- /dev/null
+++ b/tools/gke/kubernetes_api.py
@@ -0,0 +1,216 @@
+#!/usr/bin/env python2.7
+# Copyright 2015, Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import requests
+import json
+
+_REQUEST_TIMEOUT_SECS = 10
+
+def _make_pod_config(pod_name, image_name, container_port_list, cmd_list,
+                    arg_list):
+  """Creates a string containing the Pod defintion as required by the Kubernetes API"""
+  body = {
+      'kind': 'Pod',
+      'apiVersion': 'v1',
+      'metadata': {
+          'name': pod_name,
+          'labels': {'name': pod_name}
+      },
+      'spec': {
+          'containers': [
+              {
+                  'name': pod_name,
+                  'image': image_name,
+                  'ports': []
+              }
+          ]
+      }
+  }
+  # Populate the 'ports' list
+  for port in container_port_list:
+    port_entry = {'containerPort': port, 'protocol': 'TCP'}
+    body['spec']['containers'][0]['ports'].append(port_entry)
+
+  # Add the 'Command' and 'Args' attributes if they are passed.
+  # Note:
+  #  - 'Command' overrides the ENTRYPOINT in the Docker Image
+  #  - 'Args' override the COMMAND in Docker image (yes, it is confusing!)
+  if len(cmd_list) > 0:
+    body['spec']['containers'][0]['command'] = cmd_list
+  if len(arg_list) > 0:
+    body['spec']['containers'][0]['args'] = arg_list
+  return json.dumps(body)
+
+
+def _make_service_config(service_name, pod_name, service_port_list,
+                        container_port_list, is_headless):
+  """Creates a string containing the Service definition as required by the Kubernetes API.
+
+  NOTE:
+  This creates either a Headless Service or 'LoadBalancer' service depending on
+  the is_headless parameter. For Headless services, there is no 'type' attribute
+  and the 'clusterIP' attribute is set to 'None'. Also, if the service is
+  Headless, Kubernetes creates DNS entries for Pods - i.e creates DNS A-records
+  mapping the service's name to the Pods' IPs
+  """
+  if len(container_port_list) != len(service_port_list):
+    print(
+        'ERROR: container_port_list and service_port_list must be of same size')
+    return ''
+  body = {
+      'kind': 'Service',
+      'apiVersion': 'v1',
+      'metadata': {
+          'name': service_name,
+          'labels': {
+              'name': service_name
+          }
+      },
+      'spec': {
+          'ports': [],
+          'selector': {
+              'name': pod_name
+          }
+      }
+  }
+  # Populate the 'ports' list in the 'spec' section. This maps service ports
+  # (port numbers that are exposed by Kubernetes) to container ports (i.e port
+  # numbers that are exposed by your Docker image)
+  for idx in range(len(container_port_list)):
+    port_entry = {
+        'port': service_port_list[idx],
+        'targetPort': container_port_list[idx],
+        'protocol': 'TCP'
+    }
+    body['spec']['ports'].append(port_entry)
+
+  # Make this either a LoadBalancer service or a headless service depending on
+  # the is_headless parameter
+  if is_headless:
+    body['spec']['clusterIP'] = 'None'
+  else:
+    body['spec']['type'] = 'LoadBalancer'
+  return json.dumps(body)
+
+
+def _print_connection_error(msg):
+  print('ERROR: Connection failed. Did you remember to run Kubenetes proxy on '
+        'localhost (i.e kubectl proxy --port=<proxy_port>) ?. Error: %s' % msg)
+
+def _do_post(post_url, api_name, request_body):
+  """Helper to do HTTP POST.
+
+  Note:
+  1) On success, Kubernetes returns a success code of 201(CREATED) not 200(OK)
+  2) A response code of 509(CONFLICT) is interpreted as a success code (since
+  the error is most likely due to the resource already existing). This makes
+  _do_post() idempotent which is semantically desirable.
+  """
+  is_success = True
+  try:
+    r = requests.post(post_url, data=request_body, timeout=_REQUEST_TIMEOUT_SECS)
+    if r.status_code == requests.codes.conflict:
+      print('WARN: Looks like the resource already exists. Api: %s, url: %s' %
+            (api_name, post_url))
+    elif r.status_code != requests.codes.created:
+      print('ERROR: %s API returned error. HTTP response: (%d) %s' %
+            (api_name, r.status_code, r.text))
+      is_success = False
+  except(requests.exceptions.Timeout, requests.exceptions.ConnectionError) as e:
+    is_success = False
+    _print_connection_error(str(e))
+  return is_success
+
+
+def _do_delete(del_url, api_name):
+  """Helper to do HTTP DELETE.
+
+  Note: A response code of 404(NOT_FOUND) is treated as success to keep
+  _do_delete() idempotent.
+  """
+  is_success = True
+  try:
+    r = requests.delete(del_url, timeout=_REQUEST_TIMEOUT_SECS)
+    if r.status_code == requests.codes.not_found:
+      print('WARN: The resource does not exist. Api: %s, url: %s' %
+            (api_name, del_url))
+    elif r.status_code != requests.codes.ok:
+      print('ERROR: %s API returned error. HTTP response: %s' %
+            (api_name, r.text))
+      is_success = False
+  except(requests.exceptions.Timeout, requests.exceptions.ConnectionError) as e:
+    is_success = False
+    _print_connection_error(str(e))
+  return is_success
+
+
+def create_service(kube_host, kube_port, namespace, service_name, pod_name,
+                   service_port_list, container_port_list, is_headless):
+  """Creates either a Headless Service or a LoadBalancer Service depending
+  on the is_headless parameter.
+  """
+  post_url = 'http://%s:%d/api/v1/namespaces/%s/services' % (
+      kube_host, kube_port, namespace)
+  request_body = _make_service_config(service_name, pod_name, service_port_list,
+                                     container_port_list, is_headless)
+  return _do_post(post_url, 'Create Service', request_body)
+
+
+def create_pod(kube_host, kube_port, namespace, pod_name, image_name,
+               container_port_list, cmd_list, arg_list):
+  """Creates a Kubernetes Pod.
+
+  Note that it is generally NOT considered a good practice to directly create
+  Pods. Typically, the recommendation is to create 'Controllers' to create and
+  manage Pods' lifecycle. Currently Kubernetes only supports 'Replication
+  Controller' which creates a configurable number of 'identical Replicas' of
+  Pods and automatically restarts any Pods in case of failures (for eg: Machine
+  failures in Kubernetes). This makes it less flexible for our test use cases
+  where we might want slightly different set of args to each Pod. Hence we
+  directly create Pods and not care much about Kubernetes failures since those
+  are very rare.
+  """
+  post_url = 'http://%s:%d/api/v1/namespaces/%s/pods' % (kube_host, kube_port,
+                                                         namespace)
+  request_body = _make_pod_config(pod_name, image_name, container_port_list,
+                                 cmd_list, arg_list)
+  return _do_post(post_url, 'Create Pod', request_body)
+
+
+def delete_service(kube_host, kube_port, namespace, service_name):
+  del_url = 'http://%s:%d/api/v1/namespaces/%s/services/%s' % (
+      kube_host, kube_port, namespace, service_name)
+  return _do_delete(del_url, 'Delete Service')
+
+
+def delete_pod(kube_host, kube_port, namespace, pod_name):
+  del_url = 'http://%s:%d/api/v1/namespaces/%s/pods/%s' % (kube_host, kube_port,
+                                                           namespace, pod_name)
+  return _do_delete(del_url, 'Delete Pod')
diff --git a/tools/http2_interop/goaway.go b/tools/http2_interop/goaway.go
new file mode 100644
index 0000000..289442d
--- /dev/null
+++ b/tools/http2_interop/goaway.go
@@ -0,0 +1,72 @@
+package http2interop
+
+import (
+	"encoding/binary"
+	"fmt"
+	"io"
+)
+
+type GoAwayFrame struct {
+	Header FrameHeader
+	Reserved
+	StreamID
+	// TODO(carl-mastrangelo): make an enum out of this.
+	Code uint32
+	Data []byte
+}
+
+func (f *GoAwayFrame) GetHeader() *FrameHeader {
+	return &f.Header
+}
+
+func (f *GoAwayFrame) ParsePayload(r io.Reader) error {
+	raw := make([]byte, f.Header.Length)
+	if _, err := io.ReadFull(r, raw); err != nil {
+		return err
+	}
+	return f.UnmarshalPayload(raw)
+}
+
+func (f *GoAwayFrame) UnmarshalPayload(raw []byte) error {
+	if f.Header.Length != len(raw) {
+		return fmt.Errorf("Invalid Payload length %d != %d", f.Header.Length, len(raw))
+	}
+	if f.Header.Length < 8 {
+		return fmt.Errorf("Invalid Payload length %d", f.Header.Length)
+	}
+	*f = GoAwayFrame{
+		Reserved: Reserved(raw[0]>>7 == 1),
+		StreamID: StreamID(binary.BigEndian.Uint32(raw[0:4]) & 0x7fffffff),
+		Code:     binary.BigEndian.Uint32(raw[4:8]),
+		Data:     []byte(string(raw[8:])),
+	}
+
+	return nil
+}
+
+func (f *GoAwayFrame) MarshalPayload() ([]byte, error) {
+	raw := make([]byte, 8, 8+len(f.Data))
+	binary.BigEndian.PutUint32(raw[:4], uint32(f.StreamID))
+	binary.BigEndian.PutUint32(raw[4:8], f.Code)
+	raw = append(raw, f.Data...)
+
+	return raw, nil
+}
+
+func (f *GoAwayFrame) MarshalBinary() ([]byte, error) {
+	payload, err := f.MarshalPayload()
+	if err != nil {
+		return nil, err
+	}
+
+	f.Header.Length = len(payload)
+	f.Header.Type = GoAwayFrameType
+	header, err := f.Header.MarshalBinary()
+	if err != nil {
+		return nil, err
+	}
+
+	header = append(header, payload...)
+
+	return header, nil
+}
diff --git a/tools/http2_interop/http2interop.go b/tools/http2_interop/http2interop.go
index 8585a04..bef8b0b 100644
--- a/tools/http2_interop/http2interop.go
+++ b/tools/http2_interop/http2interop.go
@@ -252,6 +252,58 @@
 	return nil
 }
 
+func testTLSBadCipherSuites(ctx *HTTP2InteropCtx) error {
+	config := buildTlsConfig(ctx)
+	// These are the suites that Go supports, but are forbidden by http2.
+	config.CipherSuites = []uint16{
+		tls.TLS_RSA_WITH_RC4_128_SHA,
+		tls.TLS_RSA_WITH_3DES_EDE_CBC_SHA,
+		tls.TLS_RSA_WITH_AES_128_CBC_SHA,
+		tls.TLS_RSA_WITH_AES_256_CBC_SHA,
+		tls.TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,
+		tls.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
+		tls.TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
+		tls.TLS_ECDHE_RSA_WITH_RC4_128_SHA,
+		tls.TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
+		tls.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
+		tls.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
+	}
+	conn, err := connectWithTls(ctx, config)
+	if err != nil {
+		return err
+	}
+	defer conn.Close()
+	conn.SetDeadline(time.Now().Add(defaultTimeout))
+
+	if err := http2Connect(conn, nil); err != nil {
+		return err
+	}
+
+	for {
+		f, err := parseFrame(conn)
+		if err != nil {
+			return err
+		}
+		if gf, ok := f.(*GoAwayFrame); ok {
+			return fmt.Errorf("Got goaway frame %d", gf.Code)
+		}
+	}
+	return nil
+}
+
+func http2Connect(c net.Conn, sf *SettingsFrame) error {
+	if _, err := c.Write([]byte(Preface)); err != nil {
+		return err
+	}
+	if sf == nil {
+		sf = &SettingsFrame{}
+	}
+	if err := streamFrame(c, sf); err != nil {
+		return err
+	}
+	return nil
+}
+
 func connect(ctx *HTTP2InteropCtx) (net.Conn, error) {
 	var conn net.Conn
 	var err error
diff --git a/tools/http2_interop/http2interop_test.go b/tools/http2_interop/http2interop_test.go
index dc29600..e3d366f 100644
--- a/tools/http2_interop/http2interop_test.go
+++ b/tools/http2_interop/http2interop_test.go
@@ -3,13 +3,13 @@
 import (
 	"crypto/tls"
 	"crypto/x509"
-	"strings"
 	"flag"
 	"fmt"
 	"io"
 	"io/ioutil"
 	"os"
 	"strconv"
+	"strings"
 	"testing"
 )
 
@@ -17,8 +17,7 @@
 	serverHost = flag.String("server_host", "", "The host to test")
 	serverPort = flag.Int("server_port", 443, "The port to test")
 	useTls     = flag.Bool("use_tls", true, "Should TLS tests be run")
-	// TODO: implement
-	testCase              = flag.String("test_case", "", "What test cases to run")
+	testCase   = flag.String("test_case", "", "What test cases to run (tls, framing)")
 
 	// The rest of these are unused, but present to fulfill the client interface
 	serverHostOverride    = flag.String("server_host_override", "", "Unused")
@@ -70,6 +69,9 @@
 }
 
 func TestShortPreface(t *testing.T) {
+	if *testCase != "framing" {
+		t.SkipNow()
+	}
 	ctx := InteropCtx(t)
 	for i := 0; i < len(Preface)-1; i++ {
 		if err := testShortPreface(ctx, Preface[:i]+"X"); err != io.EOF {
@@ -79,6 +81,9 @@
 }
 
 func TestUnknownFrameType(t *testing.T) {
+	if *testCase != "framing" {
+		t.SkipNow()
+	}
 	ctx := InteropCtx(t)
 	if err := testUnknownFrameType(ctx); err != nil {
 		t.Fatal(err)
@@ -86,33 +91,53 @@
 }
 
 func TestTLSApplicationProtocol(t *testing.T) {
+	if *testCase != "tls" {
+		t.SkipNow()
+	}
 	ctx := InteropCtx(t)
-	err := testTLSApplicationProtocol(ctx); 
+	err := testTLSApplicationProtocol(ctx)
 	matchError(t, err, "EOF")
 }
 
 func TestTLSMaxVersion(t *testing.T) {
+	if *testCase != "tls" {
+		t.SkipNow()
+	}
 	ctx := InteropCtx(t)
-	err := testTLSMaxVersion(ctx, tls.VersionTLS11);
+	err := testTLSMaxVersion(ctx, tls.VersionTLS11)
+	// TODO(carl-mastrangelo): maybe this should be some other error.  If the server picks
+	// the wrong protocol version, thats bad too.
 	matchError(t, err, "EOF", "server selected unsupported protocol")
 }
 
+func TestTLSBadCipherSuites(t *testing.T) {
+	if *testCase != "tls" {
+		t.SkipNow()
+	}
+	ctx := InteropCtx(t)
+	err := testTLSBadCipherSuites(ctx)
+	matchError(t, err, "EOF", "Got goaway frame")
+}
+
 func TestClientPrefaceWithStreamId(t *testing.T) {
+	if *testCase != "framing" {
+		t.SkipNow()
+	}
 	ctx := InteropCtx(t)
 	err := testClientPrefaceWithStreamId(ctx)
 	matchError(t, err, "EOF")
 }
 
-func matchError(t *testing.T, err error, matches  ... string) {
-  if err == nil {
-    t.Fatal("Expected an error")
-  }
-  for _, s := range matches {
-    if strings.Contains(err.Error(), s) {
-      return
-    }
-  }
-  t.Fatalf("Error %v not in %+v", err, matches)
+func matchError(t *testing.T, err error, matches ...string) {
+	if err == nil {
+		t.Fatal("Expected an error")
+	}
+	for _, s := range matches {
+		if strings.Contains(err.Error(), s) {
+			return
+		}
+	}
+	t.Fatalf("Error %v not in %+v", err, matches)
 }
 
 func TestMain(m *testing.M) {
diff --git a/tools/run_tests/dockerjob.py b/tools/run_tests/dockerjob.py
index 7d64222..326c4fa 100755
--- a/tools/run_tests/dockerjob.py
+++ b/tools/run_tests/dockerjob.py
@@ -47,6 +47,7 @@
 def docker_kill(cid):
   """Kills a docker container. Returns True if successful."""
   return subprocess.call(['docker','kill', str(cid)],
+                         stdin=subprocess.PIPE,
                          stdout=_DEVNULL,
                          stderr=subprocess.STDOUT) == 0
 
@@ -78,6 +79,7 @@
 def image_exists(image):
   """Returns True if given docker image exists."""
   return subprocess.call(['docker','inspect', image],
+                         stdin=subprocess.PIPE,
                          stdout=_DEVNULL,
                          stderr=subprocess.STDOUT) == 0
 
@@ -88,6 +90,7 @@
     return True
   for attempt in range(0, max_retries):
     if subprocess.call(['docker','rmi', '-f', image],
+                       stdin=subprocess.PIPE,
                        stdout=_DEVNULL,
                        stderr=subprocess.STDOUT) == 0:
       return True
diff --git a/tools/run_tests/report_utils.py b/tools/run_tests/report_utils.py
index bb9eca4..adeb707 100644
--- a/tools/run_tests/report_utils.py
+++ b/tools/run_tests/report_utils.py
@@ -29,6 +29,11 @@
 
 """Generate XML and HTML test reports."""
 
+try:
+  from mako.runtime import Context
+  from mako.template import Template
+except (ImportError):
+  pass  # Mako not installed but it is ok. 
 import os
 import string
 import xml.etree.cElementTree as ET
@@ -49,7 +54,7 @@
     return msg
 
 
-def render_xml_report(resultset, xml_report):
+def render_junit_xml_report(resultset, xml_report):
   """Generate JUnit-like XML report."""
   root = ET.Element('testsuites')
   testsuite = ET.SubElement(root, 'testsuite', id='1', package='grpc', 
@@ -69,147 +74,36 @@
   tree.write(xml_report, encoding='UTF-8')
 
 
-# TODO(adelez): Use mako template.
-def fill_one_test_result(shortname, resultset, html_str):
-  if shortname in resultset:
-    # Because interop tests does not have runs_per_test flag, each test is run
-    # once. So there should only be one element for each result.
-    result = resultset[shortname][0] 
-    if result.state == 'PASSED':
-      html_str = '%s<td bgcolor=\"green\">PASS</td>\n' % html_str
-    else:
-      tooltip = ''
-      if result.returncode > 0 or result.message:
-        if result.returncode > 0:
-          tooltip = 'returncode: %d ' % result.returncode
-        if result.message:
-          escaped_msg = _filter_msg(result.message, 'HTML')
-          tooltip = '%smessage: %s' % (tooltip, escaped_msg)       
-      if result.state == 'FAILED':
-        html_str = '%s<td bgcolor=\"red\">' % html_str
-        if tooltip:  
-          html_str = ('%s<a href=\"#\" data-toggle=\"tooltip\" '
-                      'data-placement=\"auto\" title=\"%s\">FAIL</a></td>\n' % 
-                      (html_str, tooltip))
-        else:
-          html_str = '%sFAIL</td>\n' % html_str
-      elif result.state == 'TIMEOUT':
-        html_str = '%s<td bgcolor=\"yellow\">' % html_str
-        if tooltip:
-          html_str = ('%s<a href=\"#\" data-toggle=\"tooltip\" '
-                      'data-placement=\"auto\" title=\"%s\">TIMEOUT</a></td>\n' 
-                      % (html_str, tooltip))
-        else:
-          html_str = '%sTIMEOUT</td>\n' % html_str
-  else:
-    html_str = '%s<td bgcolor=\"magenta\">Not implemented</td>\n' % html_str
-  
-  return html_str
+def render_interop_html_report(
+  client_langs, server_langs, test_cases, auth_test_cases, http2_cases, 
+  resultset, num_failures, cloud_to_prod, http2_interop):
+  """Generate HTML report for interop tests."""
+  html_report_dir = 'reports'
+  template_file = os.path.join(html_report_dir, 'interop_html_report.template')
+  try:
+    mytemplate = Template(filename=template_file, format_exceptions=True)
+  except NameError:
+    print 'Mako template is not installed. Skipping HTML report generation.'
+    return
+  except IOError as e:
+    print 'Failed to find the template %s: %s' % (template_file, e)
+    return
 
-
-def render_html_report(client_langs, server_langs, test_cases, auth_test_cases,
-                       http2_cases, resultset, num_failures, cloud_to_prod, 
-                       http2_interop):
-  """Generate html report."""
   sorted_test_cases = sorted(test_cases)
   sorted_auth_test_cases = sorted(auth_test_cases)
   sorted_http2_cases = sorted(http2_cases)
   sorted_client_langs = sorted(client_langs)
   sorted_server_langs = sorted(server_langs)
-  html_str = ('<!DOCTYPE html>\n'
-              '<html lang=\"en\">\n'
-              '<head><title>Interop Test Result</title></head>\n'
-              '<body>\n')
-  if num_failures > 1:
-    html_str = (
-        '%s<p><h2><font color=\"red\">%d tests failed!</font></h2></p>\n' % 
-        (html_str, num_failures))
-  elif num_failures:
-    html_str = (
-        '%s<p><h2><font color=\"red\">%d test failed!</font></h2></p>\n' % 
-        (html_str, num_failures))
-  else:
-    html_str = (
-        '%s<p><h2><font color=\"green\">All tests passed!</font></h2></p>\n' % 
-        html_str)
-  if cloud_to_prod:
-    # Each column header is the client language.
-    html_str = ('%s<h2>Cloud to Prod</h2>\n' 
-                '<table style=\"width:100%%\" border=\"1\">\n'
-                '<tr bgcolor=\"#00BFFF\">\n'
-                '<th>Client languages &#9658;</th>\n') % html_str
-    for client_lang in sorted_client_langs:
-      html_str = '%s<th>%s\n' % (html_str, client_lang)
-    html_str = '%s</tr>\n' % html_str
-    for test_case in sorted_test_cases + sorted_auth_test_cases:
-      html_str = '%s<tr><td><b>%s</b></td>\n' % (html_str, test_case)
-      for client_lang in sorted_client_langs:
-        if not test_case in sorted_auth_test_cases:
-          shortname = 'cloud_to_prod:%s:%s' % (client_lang, test_case)
-        else:
-          shortname = 'cloud_to_prod_auth:%s:%s' % (client_lang, test_case)
-        html_str = fill_one_test_result(shortname, resultset, html_str)
-      html_str = '%s</tr>\n' % html_str 
-    html_str = '%s</table>\n' % html_str
-  if http2_interop:
-    # Each column header is the server language.
-    html_str = ('%s<h2>HTTP/2 Interop</h2>\n' 
-                '<table style=\"width:100%%\" border=\"1\">\n'
-                '<tr bgcolor=\"#00BFFF\">\n'
-                '<th>Servers &#9658;<br/>'
-                'Test Cases &#9660;</th>\n') % html_str
-    for server_lang in sorted_server_langs:
-      html_str = '%s<th>%s\n' % (html_str, server_lang)
-    if cloud_to_prod:
-      html_str = '%s<th>%s\n' % (html_str, "prod")
-    html_str = '%s</tr>\n' % html_str
-    for test_case in sorted_http2_cases:
-      html_str = '%s<tr><td><b>%s</b></td>\n' % (html_str, test_case)
-      # Fill up the cells with test result.
-      for server_lang in sorted_server_langs:
-        shortname = 'cloud_to_cloud:%s:%s_server:%s' % (
-            "http2", server_lang, test_case)
-        html_str = fill_one_test_result(shortname, resultset, html_str)
-      if cloud_to_prod:
-        shortname = 'cloud_to_prod:%s:%s' % ("http2", test_case)
-        html_str = fill_one_test_result(shortname, resultset, html_str)
-      html_str = '%s</tr>\n' % html_str
-    html_str = '%s</table>\n' % html_str
-  if server_langs:
-    for test_case in sorted_test_cases:
-      # Each column header is the client language.
-      html_str = ('%s<h2>%s</h2>\n' 
-                  '<table style=\"width:100%%\" border=\"1\">\n'
-                  '<tr bgcolor=\"#00BFFF\">\n'
-                  '<th>Client languages &#9658;<br/>'
-                  'Server languages &#9660;</th>\n') % (html_str, test_case)
-      for client_lang in sorted_client_langs:
-        html_str = '%s<th>%s\n' % (html_str, client_lang)
-      html_str = '%s</tr>\n' % html_str
-      # Each row head is the server language.
-      for server_lang in sorted_server_langs:
-        html_str = '%s<tr><td><b>%s</b></td>\n' % (html_str, server_lang)
-        # Fill up the cells with test result.
-        for client_lang in sorted_client_langs:
-          shortname = 'cloud_to_cloud:%s:%s_server:%s' % (
-              client_lang, server_lang, test_case)
-          html_str = fill_one_test_result(shortname, resultset, html_str)
-        html_str = '%s</tr>\n' % html_str
-      html_str = '%s</table>\n' % html_str
 
-  html_str = ('%s\n'
-              '<script>\n'
-              '$(document).ready(function(){'
-              '$(\'[data-toggle=\"tooltip\"]\').tooltip();\n'   
-              '});\n'
-              '</script>\n'
-              '</body>\n'
-              '</html>') % html_str  
-  
-  # Write to reports/index.html as set up in Jenkins plugin.
-  html_report_dir = 'reports'
-  if not os.path.exists(html_report_dir):
-    os.mkdir(html_report_dir)
+  args = {'client_langs': sorted_client_langs, 
+          'server_langs': sorted_server_langs,
+          'test_cases': sorted_test_cases,
+          'auth_test_cases': sorted_auth_test_cases,
+          'http2_cases': sorted_http2_cases,
+          'resultset': resultset,
+          'num_failures': num_failures,
+          'cloud_to_prod': cloud_to_prod,
+          'http2_interop': http2_interop}
   html_file_path = os.path.join(html_report_dir, 'index.html')
-  with open(html_file_path, 'w') as f:
-    f.write(html_str)
+  with open(html_file_path, 'w') as output_file:
+    mytemplate.render_context(Context(output_file, **args))
diff --git a/tools/run_tests/run_interop_tests.py b/tools/run_tests/run_interop_tests.py
index 2634164..5435a1d 100755
--- a/tools/run_tests/run_interop_tests.py
+++ b/tools/run_tests/run_interop_tests.py
@@ -37,7 +37,6 @@
 import multiprocessing
 import os
 import report_utils
-import subprocess
 import sys
 import tempfile
 import time
@@ -170,7 +169,7 @@
     self.safename = str(self)
 
   def client_args(self):
-    return ['tools/http2_interop/http2_interop.test']
+    return ['tools/http2_interop/http2_interop.test', '-test.v']
 
   def cloud_to_prod_env(self):
     return {}
@@ -306,7 +305,7 @@
 _AUTH_TEST_CASES = ['compute_engine_creds', 'jwt_token_creds',
                     'oauth2_auth_token', 'per_rpc_creds']
 
-_HTTP2_TEST_CASES = ["tls"]
+_HTTP2_TEST_CASES = ["tls", "framing"]
 
 def docker_run_cmdline(cmdline, image, docker_args=[], cwd=None, environ=None):
   """Wraps given cmdline array to create 'docker run' cmdline from it."""
@@ -686,9 +685,9 @@
   else:
     jobset.message('SUCCESS', 'All tests passed', do_newline=True)
 
-  report_utils.render_xml_report(resultset, 'report.xml')
+  report_utils.render_junit_xml_report(resultset, 'report.xml')
   
-  report_utils.render_html_report(
+  report_utils.render_interop_html_report(
       set([str(l) for l in languages]), servers, _TEST_CASES, _AUTH_TEST_CASES, 
       _HTTP2_TEST_CASES, resultset, num_failures,
       args.cloud_to_prod_auth or args.cloud_to_prod, args.http2_interop)
diff --git a/tools/run_tests/run_tests.py b/tools/run_tests/run_tests.py
index ab2b71b..2d12ade 100755
--- a/tools/run_tests/run_tests.py
+++ b/tools/run_tests/run_tests.py
@@ -485,10 +485,10 @@
     'msan': SimpleConfig('msan', timeout_multiplier=1.5),
     'ubsan': SimpleConfig('ubsan'),
     'asan': SimpleConfig('asan', timeout_multiplier=1.5, environ={
-        'ASAN_OPTIONS': 'detect_leaks=1:color=always:suppressions=tools/tsan_suppressions.txt',
+        'ASAN_OPTIONS': 'detect_leaks=1:color=always',
         'LSAN_OPTIONS': 'report_objects=1'}),
     'asan-noleaks': SimpleConfig('asan', environ={
-        'ASAN_OPTIONS': 'detect_leaks=0:color=always:suppressions=tools/tsan_suppressions.txt'}),
+        'ASAN_OPTIONS': 'detect_leaks=0:color=always'}),
     'gcov': SimpleConfig('gcov'),
     'memcheck': ValgrindConfig('valgrind', 'memcheck', ['--leak-check=full']),
     'helgrind': ValgrindConfig('dbg', 'helgrind')
@@ -624,10 +624,15 @@
 if args.travis:
   _FORCE_ENVIRON_FOR_WRAPPERS = {'GRPC_TRACE': 'api'}
 
-languages = set(_LANGUAGES[l]
-                for l in itertools.chain.from_iterable(
-                      _LANGUAGES.iterkeys() if x == 'all' else [x]
-                      for x in args.language))
+if 'all' in args.language:
+  lang_list = _LANGUAGES.keys()  
+else:
+  lang_list = args.language
+# We don't support code coverage on ObjC
+if 'gcov' in args.config and 'objc' in lang_list:
+  lang_list.remove('objc')
+
+languages = set(_LANGUAGES[l] for l in lang_list)
 
 if len(build_configs) > 1:
   for language in languages:
@@ -840,6 +845,7 @@
       num_failures += jobresult.num_failures
   return num_runs, num_failures
 
+
 def _build_and_run(
     check_cancelled, newline_on_success, cache, xml_report=None):
   """Do one pass of building & running tests."""
@@ -902,7 +908,7 @@
     for antagonist in antagonists:
       antagonist.kill()
     if xml_report and resultset:
-      report_utils.render_xml_report(resultset, xml_report)
+      report_utils.render_junit_xml_report(resultset, xml_report)
 
   number_failures, _ = jobset.run(
       post_tests_steps, maxjobs=1, stop_on_failure=True,
diff --git a/tools/run_tests/sources_and_headers.json b/tools/run_tests/sources_and_headers.json
index d3493bb..577cf4a 100644
--- a/tools/run_tests/sources_and_headers.json
+++ b/tools/run_tests/sources_and_headers.json
@@ -1401,6 +1401,25 @@
   {
     "deps": [
       "gpr", 
+      "grpc", 
+      "grpc++", 
+      "grpc++_test_config"
+    ], 
+    "headers": [
+      "test/cpp/util/metrics_server.h", 
+      "test/proto/metrics.grpc.pb.h", 
+      "test/proto/metrics.pb.h"
+    ], 
+    "language": "c++", 
+    "name": "metrics_client", 
+    "src": [
+      "test/cpp/interop/metrics_client.cc", 
+      "test/cpp/util/metrics_server.h"
+    ]
+  }, 
+  {
+    "deps": [
+      "gpr", 
       "gpr_test_util", 
       "grpc", 
       "grpc++", 
@@ -1683,10 +1702,13 @@
       "test/cpp/interop/client_helper.h", 
       "test/cpp/interop/interop_client.h", 
       "test/cpp/interop/stress_interop_client.h", 
+      "test/cpp/util/metrics_server.h", 
       "test/proto/empty.grpc.pb.h", 
       "test/proto/empty.pb.h", 
       "test/proto/messages.grpc.pb.h", 
       "test/proto/messages.pb.h", 
+      "test/proto/metrics.grpc.pb.h", 
+      "test/proto/metrics.pb.h", 
       "test/proto/test.grpc.pb.h", 
       "test/proto/test.pb.h"
     ], 
@@ -1698,7 +1720,9 @@
       "test/cpp/interop/interop_client.h", 
       "test/cpp/interop/stress_interop_client.cc", 
       "test/cpp/interop/stress_interop_client.h", 
-      "test/cpp/interop/stress_test.cc"
+      "test/cpp/interop/stress_test.cc", 
+      "test/cpp/util/metrics_server.cc", 
+      "test/cpp/util/metrics_server.h"
     ]
   }, 
   {
@@ -2027,6 +2051,21 @@
     "deps": [
       "end2end_certs", 
       "end2end_fixture_h2_compress", 
+      "end2end_test_hpack_size", 
+      "gpr", 
+      "gpr_test_util", 
+      "grpc", 
+      "grpc_test_util"
+    ], 
+    "headers": [], 
+    "language": "c", 
+    "name": "h2_compress_hpack_size_test", 
+    "src": []
+  }, 
+  {
+    "deps": [
+      "end2end_certs", 
+      "end2end_fixture_h2_compress", 
       "end2end_test_invoke_large_request", 
       "gpr", 
       "gpr_test_util", 
@@ -2552,6 +2591,21 @@
     "deps": [
       "end2end_certs", 
       "end2end_fixture_h2_fakesec", 
+      "end2end_test_hpack_size", 
+      "gpr", 
+      "gpr_test_util", 
+      "grpc", 
+      "grpc_test_util"
+    ], 
+    "headers": [], 
+    "language": "c", 
+    "name": "h2_fakesec_hpack_size_test", 
+    "src": []
+  }, 
+  {
+    "deps": [
+      "end2end_certs", 
+      "end2end_fixture_h2_fakesec", 
       "end2end_test_invoke_large_request", 
       "gpr", 
       "gpr_test_util", 
@@ -3077,6 +3131,21 @@
     "deps": [
       "end2end_certs", 
       "end2end_fixture_h2_full", 
+      "end2end_test_hpack_size", 
+      "gpr", 
+      "gpr_test_util", 
+      "grpc", 
+      "grpc_test_util"
+    ], 
+    "headers": [], 
+    "language": "c", 
+    "name": "h2_full_hpack_size_test", 
+    "src": []
+  }, 
+  {
+    "deps": [
+      "end2end_certs", 
+      "end2end_fixture_h2_full", 
       "end2end_test_invoke_large_request", 
       "gpr", 
       "gpr_test_util", 
@@ -3602,6 +3671,21 @@
     "deps": [
       "end2end_certs", 
       "end2end_fixture_h2_full+poll", 
+      "end2end_test_hpack_size", 
+      "gpr", 
+      "gpr_test_util", 
+      "grpc", 
+      "grpc_test_util"
+    ], 
+    "headers": [], 
+    "language": "c", 
+    "name": "h2_full+poll_hpack_size_test", 
+    "src": []
+  }, 
+  {
+    "deps": [
+      "end2end_certs", 
+      "end2end_fixture_h2_full+poll", 
       "end2end_test_invoke_large_request", 
       "gpr", 
       "gpr_test_util", 
@@ -4127,6 +4211,21 @@
     "deps": [
       "end2end_certs", 
       "end2end_fixture_h2_oauth2", 
+      "end2end_test_hpack_size", 
+      "gpr", 
+      "gpr_test_util", 
+      "grpc", 
+      "grpc_test_util"
+    ], 
+    "headers": [], 
+    "language": "c", 
+    "name": "h2_oauth2_hpack_size_test", 
+    "src": []
+  }, 
+  {
+    "deps": [
+      "end2end_certs", 
+      "end2end_fixture_h2_oauth2", 
       "end2end_test_invoke_large_request", 
       "gpr", 
       "gpr_test_util", 
@@ -5072,6 +5171,21 @@
     "deps": [
       "end2end_certs", 
       "end2end_fixture_h2_sockpair", 
+      "end2end_test_hpack_size", 
+      "gpr", 
+      "gpr_test_util", 
+      "grpc", 
+      "grpc_test_util"
+    ], 
+    "headers": [], 
+    "language": "c", 
+    "name": "h2_sockpair_hpack_size_test", 
+    "src": []
+  }, 
+  {
+    "deps": [
+      "end2end_certs", 
+      "end2end_fixture_h2_sockpair", 
       "end2end_test_invoke_large_request", 
       "gpr", 
       "gpr_test_util", 
@@ -6002,6 +6116,21 @@
     "deps": [
       "end2end_certs", 
       "end2end_fixture_h2_sockpair_1byte", 
+      "end2end_test_hpack_size", 
+      "gpr", 
+      "gpr_test_util", 
+      "grpc", 
+      "grpc_test_util"
+    ], 
+    "headers": [], 
+    "language": "c", 
+    "name": "h2_sockpair_1byte_hpack_size_test", 
+    "src": []
+  }, 
+  {
+    "deps": [
+      "end2end_certs", 
+      "end2end_fixture_h2_sockpair_1byte", 
       "end2end_test_invoke_large_request", 
       "gpr", 
       "gpr_test_util", 
@@ -6512,6 +6641,21 @@
     "deps": [
       "end2end_certs", 
       "end2end_fixture_h2_ssl", 
+      "end2end_test_hpack_size", 
+      "gpr", 
+      "gpr_test_util", 
+      "grpc", 
+      "grpc_test_util"
+    ], 
+    "headers": [], 
+    "language": "c", 
+    "name": "h2_ssl_hpack_size_test", 
+    "src": []
+  }, 
+  {
+    "deps": [
+      "end2end_certs", 
+      "end2end_fixture_h2_ssl", 
       "end2end_test_invoke_large_request", 
       "gpr", 
       "gpr_test_util", 
@@ -7037,6 +7181,21 @@
     "deps": [
       "end2end_certs", 
       "end2end_fixture_h2_ssl+poll", 
+      "end2end_test_hpack_size", 
+      "gpr", 
+      "gpr_test_util", 
+      "grpc", 
+      "grpc_test_util"
+    ], 
+    "headers": [], 
+    "language": "c", 
+    "name": "h2_ssl+poll_hpack_size_test", 
+    "src": []
+  }, 
+  {
+    "deps": [
+      "end2end_certs", 
+      "end2end_fixture_h2_ssl+poll", 
       "end2end_test_invoke_large_request", 
       "gpr", 
       "gpr_test_util", 
@@ -8027,6 +8186,21 @@
     "deps": [
       "end2end_certs", 
       "end2end_fixture_h2_uchannel", 
+      "end2end_test_hpack_size", 
+      "gpr", 
+      "gpr_test_util", 
+      "grpc", 
+      "grpc_test_util"
+    ], 
+    "headers": [], 
+    "language": "c", 
+    "name": "h2_uchannel_hpack_size_test", 
+    "src": []
+  }, 
+  {
+    "deps": [
+      "end2end_certs", 
+      "end2end_fixture_h2_uchannel", 
       "end2end_test_invoke_large_request", 
       "gpr", 
       "gpr_test_util", 
@@ -8537,6 +8711,21 @@
     "deps": [
       "end2end_certs", 
       "end2end_fixture_h2_uds", 
+      "end2end_test_hpack_size", 
+      "gpr", 
+      "gpr_test_util", 
+      "grpc", 
+      "grpc_test_util"
+    ], 
+    "headers": [], 
+    "language": "c", 
+    "name": "h2_uds_hpack_size_test", 
+    "src": []
+  }, 
+  {
+    "deps": [
+      "end2end_certs", 
+      "end2end_fixture_h2_uds", 
       "end2end_test_invoke_large_request", 
       "gpr", 
       "gpr_test_util", 
@@ -9047,6 +9236,21 @@
     "deps": [
       "end2end_certs", 
       "end2end_fixture_h2_uds+poll", 
+      "end2end_test_hpack_size", 
+      "gpr", 
+      "gpr_test_util", 
+      "grpc", 
+      "grpc_test_util"
+    ], 
+    "headers": [], 
+    "language": "c", 
+    "name": "h2_uds+poll_hpack_size_test", 
+    "src": []
+  }, 
+  {
+    "deps": [
+      "end2end_certs", 
+      "end2end_fixture_h2_uds+poll", 
       "end2end_test_invoke_large_request", 
       "gpr", 
       "gpr_test_util", 
@@ -9540,6 +9744,20 @@
   {
     "deps": [
       "end2end_fixture_h2_compress", 
+      "end2end_test_hpack_size", 
+      "gpr", 
+      "gpr_test_util", 
+      "grpc_test_util_unsecure", 
+      "grpc_unsecure"
+    ], 
+    "headers": [], 
+    "language": "c", 
+    "name": "h2_compress_hpack_size_nosec_test", 
+    "src": []
+  }, 
+  {
+    "deps": [
+      "end2end_fixture_h2_compress", 
       "end2end_test_invoke_large_request", 
       "gpr", 
       "gpr_test_util", 
@@ -10016,6 +10234,20 @@
   {
     "deps": [
       "end2end_fixture_h2_full", 
+      "end2end_test_hpack_size", 
+      "gpr", 
+      "gpr_test_util", 
+      "grpc_test_util_unsecure", 
+      "grpc_unsecure"
+    ], 
+    "headers": [], 
+    "language": "c", 
+    "name": "h2_full_hpack_size_nosec_test", 
+    "src": []
+  }, 
+  {
+    "deps": [
+      "end2end_fixture_h2_full", 
       "end2end_test_invoke_large_request", 
       "gpr", 
       "gpr_test_util", 
@@ -10492,6 +10724,20 @@
   {
     "deps": [
       "end2end_fixture_h2_full+poll", 
+      "end2end_test_hpack_size", 
+      "gpr", 
+      "gpr_test_util", 
+      "grpc_test_util_unsecure", 
+      "grpc_unsecure"
+    ], 
+    "headers": [], 
+    "language": "c", 
+    "name": "h2_full+poll_hpack_size_nosec_test", 
+    "src": []
+  }, 
+  {
+    "deps": [
+      "end2end_fixture_h2_full+poll", 
       "end2end_test_invoke_large_request", 
       "gpr", 
       "gpr_test_util", 
@@ -11346,6 +11592,20 @@
   {
     "deps": [
       "end2end_fixture_h2_sockpair", 
+      "end2end_test_hpack_size", 
+      "gpr", 
+      "gpr_test_util", 
+      "grpc_test_util_unsecure", 
+      "grpc_unsecure"
+    ], 
+    "headers": [], 
+    "language": "c", 
+    "name": "h2_sockpair_hpack_size_nosec_test", 
+    "src": []
+  }, 
+  {
+    "deps": [
+      "end2end_fixture_h2_sockpair", 
       "end2end_test_invoke_large_request", 
       "gpr", 
       "gpr_test_util", 
@@ -12186,6 +12446,20 @@
   {
     "deps": [
       "end2end_fixture_h2_sockpair_1byte", 
+      "end2end_test_hpack_size", 
+      "gpr", 
+      "gpr_test_util", 
+      "grpc_test_util_unsecure", 
+      "grpc_unsecure"
+    ], 
+    "headers": [], 
+    "language": "c", 
+    "name": "h2_sockpair_1byte_hpack_size_nosec_test", 
+    "src": []
+  }, 
+  {
+    "deps": [
+      "end2end_fixture_h2_sockpair_1byte", 
       "end2end_test_invoke_large_request", 
       "gpr", 
       "gpr_test_util", 
@@ -12648,6 +12922,20 @@
   {
     "deps": [
       "end2end_fixture_h2_uchannel", 
+      "end2end_test_hpack_size", 
+      "gpr", 
+      "gpr_test_util", 
+      "grpc_test_util_unsecure", 
+      "grpc_unsecure"
+    ], 
+    "headers": [], 
+    "language": "c", 
+    "name": "h2_uchannel_hpack_size_nosec_test", 
+    "src": []
+  }, 
+  {
+    "deps": [
+      "end2end_fixture_h2_uchannel", 
       "end2end_test_invoke_large_request", 
       "gpr", 
       "gpr_test_util", 
@@ -13110,6 +13398,20 @@
   {
     "deps": [
       "end2end_fixture_h2_uds", 
+      "end2end_test_hpack_size", 
+      "gpr", 
+      "gpr_test_util", 
+      "grpc_test_util_unsecure", 
+      "grpc_unsecure"
+    ], 
+    "headers": [], 
+    "language": "c", 
+    "name": "h2_uds_hpack_size_nosec_test", 
+    "src": []
+  }, 
+  {
+    "deps": [
+      "end2end_fixture_h2_uds", 
       "end2end_test_invoke_large_request", 
       "gpr", 
       "gpr_test_util", 
@@ -13572,6 +13874,20 @@
   {
     "deps": [
       "end2end_fixture_h2_uds+poll", 
+      "end2end_test_hpack_size", 
+      "gpr", 
+      "gpr_test_util", 
+      "grpc_test_util_unsecure", 
+      "grpc_unsecure"
+    ], 
+    "headers": [], 
+    "language": "c", 
+    "name": "h2_uds+poll_hpack_size_nosec_test", 
+    "src": []
+  }, 
+  {
+    "deps": [
+      "end2end_fixture_h2_uds+poll", 
       "end2end_test_invoke_large_request", 
       "gpr", 
       "gpr_test_util", 
@@ -16033,6 +16349,25 @@
       "test/core/end2end/tests/cancel_test_helpers.h"
     ], 
     "language": "c", 
+    "name": "end2end_test_hpack_size", 
+    "src": [
+      "test/core/end2end/end2end_tests.h", 
+      "test/core/end2end/tests/cancel_test_helpers.h", 
+      "test/core/end2end/tests/hpack_size.c"
+    ]
+  }, 
+  {
+    "deps": [
+      "gpr", 
+      "gpr_test_util", 
+      "grpc_test_util_unsecure", 
+      "grpc_unsecure"
+    ], 
+    "headers": [
+      "test/core/end2end/end2end_tests.h", 
+      "test/core/end2end/tests/cancel_test_helpers.h"
+    ], 
+    "language": "c", 
     "name": "end2end_test_invoke_large_request", 
     "src": [
       "test/core/end2end/end2end_tests.h", 
diff --git a/tools/run_tests/tests.json b/tools/run_tests/tests.json
index 00ef157..029fc5e 100644
--- a/tools/run_tests/tests.json
+++ b/tools/run_tests/tests.json
@@ -1965,6 +1965,24 @@
     "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
+    "name": "h2_compress_hpack_size_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ]
+  }, 
+  {
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
     "name": "h2_compress_invoke_large_request_test", 
     "platforms": [
       "linux", 
@@ -2577,6 +2595,23 @@
     "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
+    "name": "h2_fakesec_hpack_size_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ]
+  }, 
+  {
+    "ci_platforms": [
+      "linux", 
+      "posix", 
+      "windows"
+    ], 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
     "name": "h2_fakesec_invoke_large_request_test", 
     "platforms": [
       "linux", 
@@ -3190,6 +3225,24 @@
     "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
+    "name": "h2_full_hpack_size_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ]
+  }, 
+  {
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
     "name": "h2_full_invoke_large_request_test", 
     "platforms": [
       "linux", 
@@ -3715,6 +3768,18 @@
     "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
+    "name": "h2_full+poll_hpack_size_test", 
+    "platforms": [
+      "linux"
+    ]
+  }, 
+  {
+    "ci_platforms": [
+      "linux"
+    ], 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
     "name": "h2_full+poll_invoke_large_request_test", 
     "platforms": [
       "linux"
@@ -4222,6 +4287,23 @@
     "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
+    "name": "h2_oauth2_hpack_size_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ]
+  }, 
+  {
+    "ci_platforms": [
+      "linux", 
+      "posix", 
+      "windows"
+    ], 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
     "name": "h2_oauth2_invoke_large_request_test", 
     "platforms": [
       "linux", 
@@ -5293,6 +5375,23 @@
     "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
+    "name": "h2_sockpair_hpack_size_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ]
+  }, 
+  {
+    "ci_platforms": [
+      "linux", 
+      "posix", 
+      "windows"
+    ], 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
     "name": "h2_sockpair_invoke_large_request_test", 
     "platforms": [
       "linux", 
@@ -6378,6 +6477,23 @@
     "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
+    "name": "h2_sockpair_1byte_hpack_size_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ]
+  }, 
+  {
+    "ci_platforms": [
+      "linux", 
+      "posix", 
+      "windows"
+    ], 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
     "name": "h2_sockpair_1byte_invoke_large_request_test", 
     "platforms": [
       "linux", 
@@ -6974,6 +7090,24 @@
     "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
+    "name": "h2_ssl_hpack_size_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ]
+  }, 
+  {
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
     "name": "h2_ssl_invoke_large_request_test", 
     "platforms": [
       "linux", 
@@ -7499,6 +7633,18 @@
     "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
+    "name": "h2_ssl+poll_hpack_size_test", 
+    "platforms": [
+      "linux"
+    ]
+  }, 
+  {
+    "ci_platforms": [
+      "linux"
+    ], 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
     "name": "h2_ssl+poll_invoke_large_request_test", 
     "platforms": [
       "linux"
@@ -8551,6 +8697,24 @@
     "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
+    "name": "h2_uchannel_hpack_size_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ]
+  }, 
+  {
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
     "name": "h2_uchannel_invoke_large_request_test", 
     "platforms": [
       "linux", 
@@ -9130,6 +9294,22 @@
     "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
+    "name": "h2_uds_hpack_size_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
     "name": "h2_uds_invoke_large_request_test", 
     "platforms": [
       "linux", 
@@ -9608,6 +9788,18 @@
     "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
+    "name": "h2_uds+poll_hpack_size_test", 
+    "platforms": [
+      "linux"
+    ]
+  }, 
+  {
+    "ci_platforms": [
+      "linux"
+    ], 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
     "name": "h2_uds+poll_invoke_large_request_test", 
     "platforms": [
       "linux"
@@ -10115,6 +10307,24 @@
     "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
+    "name": "h2_compress_hpack_size_nosec_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ]
+  }, 
+  {
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
     "name": "h2_compress_invoke_large_request_nosec_test", 
     "platforms": [
       "linux", 
@@ -10727,6 +10937,24 @@
     "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
+    "name": "h2_full_hpack_size_nosec_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ]
+  }, 
+  {
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
     "name": "h2_full_invoke_large_request_nosec_test", 
     "platforms": [
       "linux", 
@@ -11240,6 +11468,18 @@
     "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
+    "name": "h2_full+poll_hpack_size_nosec_test", 
+    "platforms": [
+      "linux"
+    ]
+  }, 
+  {
+    "ci_platforms": [
+      "linux"
+    ], 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
     "name": "h2_full+poll_invoke_large_request_nosec_test", 
     "platforms": [
       "linux"
@@ -12189,6 +12429,23 @@
     "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
+    "name": "h2_sockpair_hpack_size_nosec_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ]
+  }, 
+  {
+    "ci_platforms": [
+      "linux", 
+      "posix", 
+      "windows"
+    ], 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
     "name": "h2_sockpair_invoke_large_request_nosec_test", 
     "platforms": [
       "linux", 
@@ -13239,6 +13496,23 @@
     "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
+    "name": "h2_sockpair_1byte_hpack_size_nosec_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ]
+  }, 
+  {
+    "ci_platforms": [
+      "linux", 
+      "posix", 
+      "windows"
+    ], 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
     "name": "h2_sockpair_1byte_invoke_large_request_nosec_test", 
     "platforms": [
       "linux", 
@@ -13817,6 +14091,24 @@
     "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
+    "name": "h2_uchannel_hpack_size_nosec_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ]
+  }, 
+  {
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
     "name": "h2_uchannel_invoke_large_request_nosec_test", 
     "platforms": [
       "linux", 
@@ -14380,6 +14672,22 @@
     "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
+    "name": "h2_uds_hpack_size_nosec_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
     "name": "h2_uds_invoke_large_request_nosec_test", 
     "platforms": [
       "linux", 
@@ -14846,6 +15154,18 @@
     "exclude_configs": [], 
     "flaky": false, 
     "language": "c", 
+    "name": "h2_uds+poll_hpack_size_nosec_test", 
+    "platforms": [
+      "linux"
+    ]
+  }, 
+  {
+    "ci_platforms": [
+      "linux"
+    ], 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
     "name": "h2_uds+poll_invoke_large_request_nosec_test", 
     "platforms": [
       "linux"
diff --git a/vsprojects/buildtests_c.sln b/vsprojects/buildtests_c.sln
index 48ebdf4..d902ba8 100644
--- a/vsprojects/buildtests_c.sln
+++ b/vsprojects/buildtests_c.sln
@@ -394,6 +394,17 @@
 		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
 	EndProjectSection
 EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "end2end_test_hpack_size", "vcxproj\test\end2end_test_hpack_size\end2end_test_hpack_size.vcxproj", "{22A644D5-9A2B-4EF8-7792-AEB0C66A10E5}"
+	ProjectSection(myProperties) = preProject
+        	lib = "True"
+	EndProjectSection
+	ProjectSection(ProjectDependencies) = postProject
+		{0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF} = {0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF}
+		{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5} = {46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}
+		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
+		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
+	EndProjectSection
+EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "end2end_test_invoke_large_request", "vcxproj\test\end2end_test_invoke_large_request\end2end_test_invoke_large_request.vcxproj", "{30861F4C-E783-96E7-DB51-FD85757347C0}"
 	ProjectSection(myProperties) = preProject
         	lib = "True"
@@ -1506,6 +1517,20 @@
 		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
 	EndProjectSection
 EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "h2_compress_hpack_size_test", "vcxproj\test\h2_compress_hpack_size_test\h2_compress_hpack_size_test.vcxproj", "{8E7B2D33-360B-9A26-8BFD-1BAD10769F33}"
+	ProjectSection(myProperties) = preProject
+        	lib = "False"
+	EndProjectSection
+	ProjectSection(ProjectDependencies) = postProject
+		{C5D3C9A9-C0D2-CBAD-B433-710C5E89AE31} = {C5D3C9A9-C0D2-CBAD-B433-710C5E89AE31}
+		{22A644D5-9A2B-4EF8-7792-AEB0C66A10E5} = {22A644D5-9A2B-4EF8-7792-AEB0C66A10E5}
+		{80EA2691-C037-6DD3-D3AB-21510BF0E64B} = {80EA2691-C037-6DD3-D3AB-21510BF0E64B}
+		{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B} = {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}
+		{29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9}
+		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
+		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
+	EndProjectSection
+EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "h2_compress_invoke_large_request_test", "vcxproj\test\h2_compress_invoke_large_request_test\h2_compress_invoke_large_request_test.vcxproj", "{FE9E76C0-74CB-5085-6CE6-862E49037F0B}"
 	ProjectSection(myProperties) = preProject
         	lib = "False"
@@ -1996,6 +2021,20 @@
 		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
 	EndProjectSection
 EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "h2_fakesec_hpack_size_test", "vcxproj\test\h2_fakesec_hpack_size_test\h2_fakesec_hpack_size_test.vcxproj", "{5CDFA7CB-09E1-E01E-E21D-7446146478CC}"
+	ProjectSection(myProperties) = preProject
+        	lib = "False"
+	EndProjectSection
+	ProjectSection(ProjectDependencies) = postProject
+		{096ABF91-FEC8-9AC9-B877-C683BFD51984} = {096ABF91-FEC8-9AC9-B877-C683BFD51984}
+		{22A644D5-9A2B-4EF8-7792-AEB0C66A10E5} = {22A644D5-9A2B-4EF8-7792-AEB0C66A10E5}
+		{80EA2691-C037-6DD3-D3AB-21510BF0E64B} = {80EA2691-C037-6DD3-D3AB-21510BF0E64B}
+		{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B} = {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}
+		{29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9}
+		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
+		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
+	EndProjectSection
+EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "h2_fakesec_invoke_large_request_test", "vcxproj\test\h2_fakesec_invoke_large_request_test\h2_fakesec_invoke_large_request_test.vcxproj", "{93980DE4-8935-C0F5-86F8-22B3F0811121}"
 	ProjectSection(myProperties) = preProject
         	lib = "False"
@@ -2486,6 +2525,20 @@
 		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
 	EndProjectSection
 EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "h2_full_hpack_size_test", "vcxproj\test\h2_full_hpack_size_test\h2_full_hpack_size_test.vcxproj", "{C655AED5-AF53-D09E-A8EA-60AE0F2D149A}"
+	ProjectSection(myProperties) = preProject
+        	lib = "False"
+	EndProjectSection
+	ProjectSection(ProjectDependencies) = postProject
+		{882B2933-F340-7027-7090-28CEAE9F1BE6} = {882B2933-F340-7027-7090-28CEAE9F1BE6}
+		{22A644D5-9A2B-4EF8-7792-AEB0C66A10E5} = {22A644D5-9A2B-4EF8-7792-AEB0C66A10E5}
+		{80EA2691-C037-6DD3-D3AB-21510BF0E64B} = {80EA2691-C037-6DD3-D3AB-21510BF0E64B}
+		{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B} = {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}
+		{29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9}
+		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
+		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
+	EndProjectSection
+EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "h2_full_invoke_large_request_test", "vcxproj\test\h2_full_invoke_large_request_test\h2_full_invoke_large_request_test.vcxproj", "{F97198F5-D5EC-E06B-C51F-1BF7644D7422}"
 	ProjectSection(myProperties) = preProject
         	lib = "False"
@@ -2976,6 +3029,20 @@
 		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
 	EndProjectSection
 EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "h2_oauth2_hpack_size_test", "vcxproj\test\h2_oauth2_hpack_size_test\h2_oauth2_hpack_size_test.vcxproj", "{CA3C2D7E-58C7-C05E-6D3B-70383020D8C2}"
+	ProjectSection(myProperties) = preProject
+        	lib = "False"
+	EndProjectSection
+	ProjectSection(ProjectDependencies) = postProject
+		{DDFE4EB8-CCD3-DA3F-461A-10F1B94D26AF} = {DDFE4EB8-CCD3-DA3F-461A-10F1B94D26AF}
+		{22A644D5-9A2B-4EF8-7792-AEB0C66A10E5} = {22A644D5-9A2B-4EF8-7792-AEB0C66A10E5}
+		{80EA2691-C037-6DD3-D3AB-21510BF0E64B} = {80EA2691-C037-6DD3-D3AB-21510BF0E64B}
+		{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B} = {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}
+		{29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9}
+		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
+		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
+	EndProjectSection
+EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "h2_oauth2_invoke_large_request_test", "vcxproj\test\h2_oauth2_invoke_large_request_test\h2_oauth2_invoke_large_request_test.vcxproj", "{945F52A3-91ED-5891-9D11-D07A19E4FEA2}"
 	ProjectSection(myProperties) = preProject
         	lib = "False"
@@ -3858,6 +3925,20 @@
 		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
 	EndProjectSection
 EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "h2_sockpair_hpack_size_test", "vcxproj\test\h2_sockpair_hpack_size_test\h2_sockpair_hpack_size_test.vcxproj", "{E96735FF-B1CF-51D2-1923-53292AF72C4E}"
+	ProjectSection(myProperties) = preProject
+        	lib = "False"
+	EndProjectSection
+	ProjectSection(ProjectDependencies) = postProject
+		{67A1675D-FF50-3B78-2706-155D69ADC290} = {67A1675D-FF50-3B78-2706-155D69ADC290}
+		{22A644D5-9A2B-4EF8-7792-AEB0C66A10E5} = {22A644D5-9A2B-4EF8-7792-AEB0C66A10E5}
+		{80EA2691-C037-6DD3-D3AB-21510BF0E64B} = {80EA2691-C037-6DD3-D3AB-21510BF0E64B}
+		{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B} = {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}
+		{29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9}
+		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
+		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
+	EndProjectSection
+EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "h2_sockpair_invoke_large_request_test", "vcxproj\test\h2_sockpair_invoke_large_request_test\h2_sockpair_invoke_large_request_test.vcxproj", "{1A1AA28B-D635-F4BD-DFFA-096D2E4BA9BF}"
 	ProjectSection(myProperties) = preProject
         	lib = "False"
@@ -4726,6 +4807,20 @@
 		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
 	EndProjectSection
 EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "h2_sockpair_1byte_hpack_size_test", "vcxproj\test\h2_sockpair_1byte_hpack_size_test\h2_sockpair_1byte_hpack_size_test.vcxproj", "{0B07D219-39A5-729B-EB0F-8B81E562D808}"
+	ProjectSection(myProperties) = preProject
+        	lib = "False"
+	EndProjectSection
+	ProjectSection(ProjectDependencies) = postProject
+		{B0F4BF34-3C82-EB67-990E-959CDDBEB734} = {B0F4BF34-3C82-EB67-990E-959CDDBEB734}
+		{22A644D5-9A2B-4EF8-7792-AEB0C66A10E5} = {22A644D5-9A2B-4EF8-7792-AEB0C66A10E5}
+		{80EA2691-C037-6DD3-D3AB-21510BF0E64B} = {80EA2691-C037-6DD3-D3AB-21510BF0E64B}
+		{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B} = {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}
+		{29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9}
+		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
+		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
+	EndProjectSection
+EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "h2_sockpair_1byte_invoke_large_request_test", "vcxproj\test\h2_sockpair_1byte_invoke_large_request_test\h2_sockpair_1byte_invoke_large_request_test.vcxproj", "{45EED825-B3C0-63AE-43FE-CFA8DD3164EC}"
 	ProjectSection(myProperties) = preProject
         	lib = "False"
@@ -5202,6 +5297,20 @@
 		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
 	EndProjectSection
 EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "h2_ssl_hpack_size_test", "vcxproj\test\h2_ssl_hpack_size_test\h2_ssl_hpack_size_test.vcxproj", "{856DAD36-A161-9876-9548-48D06BFA35C1}"
+	ProjectSection(myProperties) = preProject
+        	lib = "False"
+	EndProjectSection
+	ProjectSection(ProjectDependencies) = postProject
+		{207BE5BC-25D7-1D2A-C76E-279DB66A1205} = {207BE5BC-25D7-1D2A-C76E-279DB66A1205}
+		{22A644D5-9A2B-4EF8-7792-AEB0C66A10E5} = {22A644D5-9A2B-4EF8-7792-AEB0C66A10E5}
+		{80EA2691-C037-6DD3-D3AB-21510BF0E64B} = {80EA2691-C037-6DD3-D3AB-21510BF0E64B}
+		{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B} = {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}
+		{29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9}
+		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
+		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
+	EndProjectSection
+EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "h2_ssl_invoke_large_request_test", "vcxproj\test\h2_ssl_invoke_large_request_test\h2_ssl_invoke_large_request_test.vcxproj", "{CB6E0DFE-7AA8-5F3A-431E-5D769E9339F7}"
 	ProjectSection(myProperties) = preProject
         	lib = "False"
@@ -6126,6 +6235,20 @@
 		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
 	EndProjectSection
 EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "h2_uchannel_hpack_size_test", "vcxproj\test\h2_uchannel_hpack_size_test\h2_uchannel_hpack_size_test.vcxproj", "{9CFB3202-D95F-E541-9A6F-BE561CAFE1AE}"
+	ProjectSection(myProperties) = preProject
+        	lib = "False"
+	EndProjectSection
+	ProjectSection(ProjectDependencies) = postProject
+		{CE17F95F-4FD3-41C3-E1B9-9B85F1FE7D4A} = {CE17F95F-4FD3-41C3-E1B9-9B85F1FE7D4A}
+		{22A644D5-9A2B-4EF8-7792-AEB0C66A10E5} = {22A644D5-9A2B-4EF8-7792-AEB0C66A10E5}
+		{80EA2691-C037-6DD3-D3AB-21510BF0E64B} = {80EA2691-C037-6DD3-D3AB-21510BF0E64B}
+		{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B} = {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}
+		{29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9}
+		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
+		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
+	EndProjectSection
+EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "h2_uchannel_invoke_large_request_test", "vcxproj\test\h2_uchannel_invoke_large_request_test\h2_uchannel_invoke_large_request_test.vcxproj", "{7B5AE7B2-6D7E-D97F-A6A4-721C7446171F}"
 	ProjectSection(myProperties) = preProject
         	lib = "False"
@@ -6586,6 +6709,19 @@
 		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
 	EndProjectSection
 EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "h2_compress_hpack_size_nosec_test", "vcxproj\test\h2_compress_hpack_size_nosec_test\h2_compress_hpack_size_nosec_test.vcxproj", "{5A641212-7C59-E552-0ED6-F05F710DD4F5}"
+	ProjectSection(myProperties) = preProject
+        	lib = "False"
+	EndProjectSection
+	ProjectSection(ProjectDependencies) = postProject
+		{C5D3C9A9-C0D2-CBAD-B433-710C5E89AE31} = {C5D3C9A9-C0D2-CBAD-B433-710C5E89AE31}
+		{22A644D5-9A2B-4EF8-7792-AEB0C66A10E5} = {22A644D5-9A2B-4EF8-7792-AEB0C66A10E5}
+		{0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF} = {0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF}
+		{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5} = {46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}
+		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
+		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
+	EndProjectSection
+EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "h2_compress_invoke_large_request_nosec_test", "vcxproj\test\h2_compress_invoke_large_request_nosec_test\h2_compress_invoke_large_request_nosec_test.vcxproj", "{C3A6661F-806B-BDE6-AF91-032175B443F8}"
 	ProjectSection(myProperties) = preProject
         	lib = "False"
@@ -7028,6 +7164,19 @@
 		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
 	EndProjectSection
 EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "h2_full_hpack_size_nosec_test", "vcxproj\test\h2_full_hpack_size_nosec_test\h2_full_hpack_size_nosec_test.vcxproj", "{C355D9BD-F3C7-CA89-E125-44D1BAEE22C1}"
+	ProjectSection(myProperties) = preProject
+        	lib = "False"
+	EndProjectSection
+	ProjectSection(ProjectDependencies) = postProject
+		{882B2933-F340-7027-7090-28CEAE9F1BE6} = {882B2933-F340-7027-7090-28CEAE9F1BE6}
+		{22A644D5-9A2B-4EF8-7792-AEB0C66A10E5} = {22A644D5-9A2B-4EF8-7792-AEB0C66A10E5}
+		{0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF} = {0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF}
+		{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5} = {46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}
+		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
+		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
+	EndProjectSection
+EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "h2_full_invoke_large_request_nosec_test", "vcxproj\test\h2_full_invoke_large_request_nosec_test\h2_full_invoke_large_request_nosec_test.vcxproj", "{96C59CF1-6E80-B88D-D99C-0AA4C32F6562}"
 	ProjectSection(myProperties) = preProject
         	lib = "False"
@@ -7821,6 +7970,19 @@
 		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
 	EndProjectSection
 EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "h2_sockpair_hpack_size_nosec_test", "vcxproj\test\h2_sockpair_hpack_size_nosec_test\h2_sockpair_hpack_size_nosec_test.vcxproj", "{B35C9AC3-8160-BFCA-2EA7-0413A7A45EC4}"
+	ProjectSection(myProperties) = preProject
+        	lib = "False"
+	EndProjectSection
+	ProjectSection(ProjectDependencies) = postProject
+		{67A1675D-FF50-3B78-2706-155D69ADC290} = {67A1675D-FF50-3B78-2706-155D69ADC290}
+		{22A644D5-9A2B-4EF8-7792-AEB0C66A10E5} = {22A644D5-9A2B-4EF8-7792-AEB0C66A10E5}
+		{0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF} = {0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF}
+		{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5} = {46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}
+		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
+		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
+	EndProjectSection
+EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "h2_sockpair_invoke_large_request_nosec_test", "vcxproj\test\h2_sockpair_invoke_large_request_nosec_test\h2_sockpair_invoke_large_request_nosec_test.vcxproj", "{8BF0F1D5-3CF2-DFFD-D74D-E2D7D06A65AC}"
 	ProjectSection(myProperties) = preProject
         	lib = "False"
@@ -8601,6 +8763,19 @@
 		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
 	EndProjectSection
 EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "h2_sockpair_1byte_hpack_size_nosec_test", "vcxproj\test\h2_sockpair_1byte_hpack_size_nosec_test\h2_sockpair_1byte_hpack_size_nosec_test.vcxproj", "{93AF9D45-51B5-A902-4537-709FE4ED9830}"
+	ProjectSection(myProperties) = preProject
+        	lib = "False"
+	EndProjectSection
+	ProjectSection(ProjectDependencies) = postProject
+		{B0F4BF34-3C82-EB67-990E-959CDDBEB734} = {B0F4BF34-3C82-EB67-990E-959CDDBEB734}
+		{22A644D5-9A2B-4EF8-7792-AEB0C66A10E5} = {22A644D5-9A2B-4EF8-7792-AEB0C66A10E5}
+		{0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF} = {0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF}
+		{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5} = {46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}
+		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
+		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
+	EndProjectSection
+EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "h2_sockpair_1byte_invoke_large_request_nosec_test", "vcxproj\test\h2_sockpair_1byte_invoke_large_request_nosec_test\h2_sockpair_1byte_invoke_large_request_nosec_test.vcxproj", "{0733C2AA-D898-7145-3F2E-6304DC428C5F}"
 	ProjectSection(myProperties) = preProject
         	lib = "False"
@@ -9030,6 +9205,19 @@
 		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
 	EndProjectSection
 EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "h2_uchannel_hpack_size_nosec_test", "vcxproj\test\h2_uchannel_hpack_size_nosec_test\h2_uchannel_hpack_size_nosec_test.vcxproj", "{EA53DB0D-8BA3-3BCC-10E1-8B5FACB77CA1}"
+	ProjectSection(myProperties) = preProject
+        	lib = "False"
+	EndProjectSection
+	ProjectSection(ProjectDependencies) = postProject
+		{CE17F95F-4FD3-41C3-E1B9-9B85F1FE7D4A} = {CE17F95F-4FD3-41C3-E1B9-9B85F1FE7D4A}
+		{22A644D5-9A2B-4EF8-7792-AEB0C66A10E5} = {22A644D5-9A2B-4EF8-7792-AEB0C66A10E5}
+		{0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF} = {0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF}
+		{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5} = {46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}
+		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
+		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
+	EndProjectSection
+EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "h2_uchannel_invoke_large_request_nosec_test", "vcxproj\test\h2_uchannel_invoke_large_request_nosec_test\h2_uchannel_invoke_large_request_nosec_test.vcxproj", "{0EC09350-0FB9-0208-000E-1B6C534B234C}"
 	ProjectSection(myProperties) = preProject
         	lib = "False"
@@ -9892,6 +10080,22 @@
 		{C3647908-B80D-F566-5659-3E98B09D83F9}.Release-DLL|Win32.Build.0 = Release|Win32
 		{C3647908-B80D-F566-5659-3E98B09D83F9}.Release-DLL|x64.ActiveCfg = Release|x64
 		{C3647908-B80D-F566-5659-3E98B09D83F9}.Release-DLL|x64.Build.0 = Release|x64
+		{22A644D5-9A2B-4EF8-7792-AEB0C66A10E5}.Debug|Win32.ActiveCfg = Debug|Win32
+		{22A644D5-9A2B-4EF8-7792-AEB0C66A10E5}.Debug|x64.ActiveCfg = Debug|x64
+		{22A644D5-9A2B-4EF8-7792-AEB0C66A10E5}.Release|Win32.ActiveCfg = Release|Win32
+		{22A644D5-9A2B-4EF8-7792-AEB0C66A10E5}.Release|x64.ActiveCfg = Release|x64
+		{22A644D5-9A2B-4EF8-7792-AEB0C66A10E5}.Debug|Win32.Build.0 = Debug|Win32
+		{22A644D5-9A2B-4EF8-7792-AEB0C66A10E5}.Debug|x64.Build.0 = Debug|x64
+		{22A644D5-9A2B-4EF8-7792-AEB0C66A10E5}.Release|Win32.Build.0 = Release|Win32
+		{22A644D5-9A2B-4EF8-7792-AEB0C66A10E5}.Release|x64.Build.0 = Release|x64
+		{22A644D5-9A2B-4EF8-7792-AEB0C66A10E5}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
+		{22A644D5-9A2B-4EF8-7792-AEB0C66A10E5}.Debug-DLL|Win32.Build.0 = Debug|Win32
+		{22A644D5-9A2B-4EF8-7792-AEB0C66A10E5}.Debug-DLL|x64.ActiveCfg = Debug|x64
+		{22A644D5-9A2B-4EF8-7792-AEB0C66A10E5}.Debug-DLL|x64.Build.0 = Debug|x64
+		{22A644D5-9A2B-4EF8-7792-AEB0C66A10E5}.Release-DLL|Win32.ActiveCfg = Release|Win32
+		{22A644D5-9A2B-4EF8-7792-AEB0C66A10E5}.Release-DLL|Win32.Build.0 = Release|Win32
+		{22A644D5-9A2B-4EF8-7792-AEB0C66A10E5}.Release-DLL|x64.ActiveCfg = Release|x64
+		{22A644D5-9A2B-4EF8-7792-AEB0C66A10E5}.Release-DLL|x64.Build.0 = Release|x64
 		{30861F4C-E783-96E7-DB51-FD85757347C0}.Debug|Win32.ActiveCfg = Debug|Win32
 		{30861F4C-E783-96E7-DB51-FD85757347C0}.Debug|x64.ActiveCfg = Debug|x64
 		{30861F4C-E783-96E7-DB51-FD85757347C0}.Release|Win32.ActiveCfg = Release|Win32
@@ -11508,6 +11712,22 @@
 		{1B8B71B0-ED48-43BF-0553-092CF96A330B}.Release-DLL|Win32.Build.0 = Release|Win32
 		{1B8B71B0-ED48-43BF-0553-092CF96A330B}.Release-DLL|x64.ActiveCfg = Release|x64
 		{1B8B71B0-ED48-43BF-0553-092CF96A330B}.Release-DLL|x64.Build.0 = Release|x64
+		{8E7B2D33-360B-9A26-8BFD-1BAD10769F33}.Debug|Win32.ActiveCfg = Debug|Win32
+		{8E7B2D33-360B-9A26-8BFD-1BAD10769F33}.Debug|x64.ActiveCfg = Debug|x64
+		{8E7B2D33-360B-9A26-8BFD-1BAD10769F33}.Release|Win32.ActiveCfg = Release|Win32
+		{8E7B2D33-360B-9A26-8BFD-1BAD10769F33}.Release|x64.ActiveCfg = Release|x64
+		{8E7B2D33-360B-9A26-8BFD-1BAD10769F33}.Debug|Win32.Build.0 = Debug|Win32
+		{8E7B2D33-360B-9A26-8BFD-1BAD10769F33}.Debug|x64.Build.0 = Debug|x64
+		{8E7B2D33-360B-9A26-8BFD-1BAD10769F33}.Release|Win32.Build.0 = Release|Win32
+		{8E7B2D33-360B-9A26-8BFD-1BAD10769F33}.Release|x64.Build.0 = Release|x64
+		{8E7B2D33-360B-9A26-8BFD-1BAD10769F33}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
+		{8E7B2D33-360B-9A26-8BFD-1BAD10769F33}.Debug-DLL|Win32.Build.0 = Debug|Win32
+		{8E7B2D33-360B-9A26-8BFD-1BAD10769F33}.Debug-DLL|x64.ActiveCfg = Debug|x64
+		{8E7B2D33-360B-9A26-8BFD-1BAD10769F33}.Debug-DLL|x64.Build.0 = Debug|x64
+		{8E7B2D33-360B-9A26-8BFD-1BAD10769F33}.Release-DLL|Win32.ActiveCfg = Release|Win32
+		{8E7B2D33-360B-9A26-8BFD-1BAD10769F33}.Release-DLL|Win32.Build.0 = Release|Win32
+		{8E7B2D33-360B-9A26-8BFD-1BAD10769F33}.Release-DLL|x64.ActiveCfg = Release|x64
+		{8E7B2D33-360B-9A26-8BFD-1BAD10769F33}.Release-DLL|x64.Build.0 = Release|x64
 		{FE9E76C0-74CB-5085-6CE6-862E49037F0B}.Debug|Win32.ActiveCfg = Debug|Win32
 		{FE9E76C0-74CB-5085-6CE6-862E49037F0B}.Debug|x64.ActiveCfg = Debug|x64
 		{FE9E76C0-74CB-5085-6CE6-862E49037F0B}.Release|Win32.ActiveCfg = Release|Win32
@@ -12068,6 +12288,22 @@
 		{65265C4A-46B8-F54C-96AB-10A292FE851F}.Release-DLL|Win32.Build.0 = Release|Win32
 		{65265C4A-46B8-F54C-96AB-10A292FE851F}.Release-DLL|x64.ActiveCfg = Release|x64
 		{65265C4A-46B8-F54C-96AB-10A292FE851F}.Release-DLL|x64.Build.0 = Release|x64
+		{5CDFA7CB-09E1-E01E-E21D-7446146478CC}.Debug|Win32.ActiveCfg = Debug|Win32
+		{5CDFA7CB-09E1-E01E-E21D-7446146478CC}.Debug|x64.ActiveCfg = Debug|x64
+		{5CDFA7CB-09E1-E01E-E21D-7446146478CC}.Release|Win32.ActiveCfg = Release|Win32
+		{5CDFA7CB-09E1-E01E-E21D-7446146478CC}.Release|x64.ActiveCfg = Release|x64
+		{5CDFA7CB-09E1-E01E-E21D-7446146478CC}.Debug|Win32.Build.0 = Debug|Win32
+		{5CDFA7CB-09E1-E01E-E21D-7446146478CC}.Debug|x64.Build.0 = Debug|x64
+		{5CDFA7CB-09E1-E01E-E21D-7446146478CC}.Release|Win32.Build.0 = Release|Win32
+		{5CDFA7CB-09E1-E01E-E21D-7446146478CC}.Release|x64.Build.0 = Release|x64
+		{5CDFA7CB-09E1-E01E-E21D-7446146478CC}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
+		{5CDFA7CB-09E1-E01E-E21D-7446146478CC}.Debug-DLL|Win32.Build.0 = Debug|Win32
+		{5CDFA7CB-09E1-E01E-E21D-7446146478CC}.Debug-DLL|x64.ActiveCfg = Debug|x64
+		{5CDFA7CB-09E1-E01E-E21D-7446146478CC}.Debug-DLL|x64.Build.0 = Debug|x64
+		{5CDFA7CB-09E1-E01E-E21D-7446146478CC}.Release-DLL|Win32.ActiveCfg = Release|Win32
+		{5CDFA7CB-09E1-E01E-E21D-7446146478CC}.Release-DLL|Win32.Build.0 = Release|Win32
+		{5CDFA7CB-09E1-E01E-E21D-7446146478CC}.Release-DLL|x64.ActiveCfg = Release|x64
+		{5CDFA7CB-09E1-E01E-E21D-7446146478CC}.Release-DLL|x64.Build.0 = Release|x64
 		{93980DE4-8935-C0F5-86F8-22B3F0811121}.Debug|Win32.ActiveCfg = Debug|Win32
 		{93980DE4-8935-C0F5-86F8-22B3F0811121}.Debug|x64.ActiveCfg = Debug|x64
 		{93980DE4-8935-C0F5-86F8-22B3F0811121}.Release|Win32.ActiveCfg = Release|Win32
@@ -12628,6 +12864,22 @@
 		{87CE6537-F5DC-4AF1-6206-D9C31058226D}.Release-DLL|Win32.Build.0 = Release|Win32
 		{87CE6537-F5DC-4AF1-6206-D9C31058226D}.Release-DLL|x64.ActiveCfg = Release|x64
 		{87CE6537-F5DC-4AF1-6206-D9C31058226D}.Release-DLL|x64.Build.0 = Release|x64
+		{C655AED5-AF53-D09E-A8EA-60AE0F2D149A}.Debug|Win32.ActiveCfg = Debug|Win32
+		{C655AED5-AF53-D09E-A8EA-60AE0F2D149A}.Debug|x64.ActiveCfg = Debug|x64
+		{C655AED5-AF53-D09E-A8EA-60AE0F2D149A}.Release|Win32.ActiveCfg = Release|Win32
+		{C655AED5-AF53-D09E-A8EA-60AE0F2D149A}.Release|x64.ActiveCfg = Release|x64
+		{C655AED5-AF53-D09E-A8EA-60AE0F2D149A}.Debug|Win32.Build.0 = Debug|Win32
+		{C655AED5-AF53-D09E-A8EA-60AE0F2D149A}.Debug|x64.Build.0 = Debug|x64
+		{C655AED5-AF53-D09E-A8EA-60AE0F2D149A}.Release|Win32.Build.0 = Release|Win32
+		{C655AED5-AF53-D09E-A8EA-60AE0F2D149A}.Release|x64.Build.0 = Release|x64
+		{C655AED5-AF53-D09E-A8EA-60AE0F2D149A}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
+		{C655AED5-AF53-D09E-A8EA-60AE0F2D149A}.Debug-DLL|Win32.Build.0 = Debug|Win32
+		{C655AED5-AF53-D09E-A8EA-60AE0F2D149A}.Debug-DLL|x64.ActiveCfg = Debug|x64
+		{C655AED5-AF53-D09E-A8EA-60AE0F2D149A}.Debug-DLL|x64.Build.0 = Debug|x64
+		{C655AED5-AF53-D09E-A8EA-60AE0F2D149A}.Release-DLL|Win32.ActiveCfg = Release|Win32
+		{C655AED5-AF53-D09E-A8EA-60AE0F2D149A}.Release-DLL|Win32.Build.0 = Release|Win32
+		{C655AED5-AF53-D09E-A8EA-60AE0F2D149A}.Release-DLL|x64.ActiveCfg = Release|x64
+		{C655AED5-AF53-D09E-A8EA-60AE0F2D149A}.Release-DLL|x64.Build.0 = Release|x64
 		{F97198F5-D5EC-E06B-C51F-1BF7644D7422}.Debug|Win32.ActiveCfg = Debug|Win32
 		{F97198F5-D5EC-E06B-C51F-1BF7644D7422}.Debug|x64.ActiveCfg = Debug|x64
 		{F97198F5-D5EC-E06B-C51F-1BF7644D7422}.Release|Win32.ActiveCfg = Release|Win32
@@ -13188,6 +13440,22 @@
 		{7E1DDE0D-E68B-BF0B-2EE7-AAFE5C9CCD58}.Release-DLL|Win32.Build.0 = Release|Win32
 		{7E1DDE0D-E68B-BF0B-2EE7-AAFE5C9CCD58}.Release-DLL|x64.ActiveCfg = Release|x64
 		{7E1DDE0D-E68B-BF0B-2EE7-AAFE5C9CCD58}.Release-DLL|x64.Build.0 = Release|x64
+		{CA3C2D7E-58C7-C05E-6D3B-70383020D8C2}.Debug|Win32.ActiveCfg = Debug|Win32
+		{CA3C2D7E-58C7-C05E-6D3B-70383020D8C2}.Debug|x64.ActiveCfg = Debug|x64
+		{CA3C2D7E-58C7-C05E-6D3B-70383020D8C2}.Release|Win32.ActiveCfg = Release|Win32
+		{CA3C2D7E-58C7-C05E-6D3B-70383020D8C2}.Release|x64.ActiveCfg = Release|x64
+		{CA3C2D7E-58C7-C05E-6D3B-70383020D8C2}.Debug|Win32.Build.0 = Debug|Win32
+		{CA3C2D7E-58C7-C05E-6D3B-70383020D8C2}.Debug|x64.Build.0 = Debug|x64
+		{CA3C2D7E-58C7-C05E-6D3B-70383020D8C2}.Release|Win32.Build.0 = Release|Win32
+		{CA3C2D7E-58C7-C05E-6D3B-70383020D8C2}.Release|x64.Build.0 = Release|x64
+		{CA3C2D7E-58C7-C05E-6D3B-70383020D8C2}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
+		{CA3C2D7E-58C7-C05E-6D3B-70383020D8C2}.Debug-DLL|Win32.Build.0 = Debug|Win32
+		{CA3C2D7E-58C7-C05E-6D3B-70383020D8C2}.Debug-DLL|x64.ActiveCfg = Debug|x64
+		{CA3C2D7E-58C7-C05E-6D3B-70383020D8C2}.Debug-DLL|x64.Build.0 = Debug|x64
+		{CA3C2D7E-58C7-C05E-6D3B-70383020D8C2}.Release-DLL|Win32.ActiveCfg = Release|Win32
+		{CA3C2D7E-58C7-C05E-6D3B-70383020D8C2}.Release-DLL|Win32.Build.0 = Release|Win32
+		{CA3C2D7E-58C7-C05E-6D3B-70383020D8C2}.Release-DLL|x64.ActiveCfg = Release|x64
+		{CA3C2D7E-58C7-C05E-6D3B-70383020D8C2}.Release-DLL|x64.Build.0 = Release|x64
 		{945F52A3-91ED-5891-9D11-D07A19E4FEA2}.Debug|Win32.ActiveCfg = Debug|Win32
 		{945F52A3-91ED-5891-9D11-D07A19E4FEA2}.Debug|x64.ActiveCfg = Debug|x64
 		{945F52A3-91ED-5891-9D11-D07A19E4FEA2}.Release|Win32.ActiveCfg = Release|Win32
@@ -14196,6 +14464,22 @@
 		{0AE39FD9-59E4-1F8A-E8DD-1FCBFC62D2B3}.Release-DLL|Win32.Build.0 = Release|Win32
 		{0AE39FD9-59E4-1F8A-E8DD-1FCBFC62D2B3}.Release-DLL|x64.ActiveCfg = Release|x64
 		{0AE39FD9-59E4-1F8A-E8DD-1FCBFC62D2B3}.Release-DLL|x64.Build.0 = Release|x64
+		{E96735FF-B1CF-51D2-1923-53292AF72C4E}.Debug|Win32.ActiveCfg = Debug|Win32
+		{E96735FF-B1CF-51D2-1923-53292AF72C4E}.Debug|x64.ActiveCfg = Debug|x64
+		{E96735FF-B1CF-51D2-1923-53292AF72C4E}.Release|Win32.ActiveCfg = Release|Win32
+		{E96735FF-B1CF-51D2-1923-53292AF72C4E}.Release|x64.ActiveCfg = Release|x64
+		{E96735FF-B1CF-51D2-1923-53292AF72C4E}.Debug|Win32.Build.0 = Debug|Win32
+		{E96735FF-B1CF-51D2-1923-53292AF72C4E}.Debug|x64.Build.0 = Debug|x64
+		{E96735FF-B1CF-51D2-1923-53292AF72C4E}.Release|Win32.Build.0 = Release|Win32
+		{E96735FF-B1CF-51D2-1923-53292AF72C4E}.Release|x64.Build.0 = Release|x64
+		{E96735FF-B1CF-51D2-1923-53292AF72C4E}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
+		{E96735FF-B1CF-51D2-1923-53292AF72C4E}.Debug-DLL|Win32.Build.0 = Debug|Win32
+		{E96735FF-B1CF-51D2-1923-53292AF72C4E}.Debug-DLL|x64.ActiveCfg = Debug|x64
+		{E96735FF-B1CF-51D2-1923-53292AF72C4E}.Debug-DLL|x64.Build.0 = Debug|x64
+		{E96735FF-B1CF-51D2-1923-53292AF72C4E}.Release-DLL|Win32.ActiveCfg = Release|Win32
+		{E96735FF-B1CF-51D2-1923-53292AF72C4E}.Release-DLL|Win32.Build.0 = Release|Win32
+		{E96735FF-B1CF-51D2-1923-53292AF72C4E}.Release-DLL|x64.ActiveCfg = Release|x64
+		{E96735FF-B1CF-51D2-1923-53292AF72C4E}.Release-DLL|x64.Build.0 = Release|x64
 		{1A1AA28B-D635-F4BD-DFFA-096D2E4BA9BF}.Debug|Win32.ActiveCfg = Debug|Win32
 		{1A1AA28B-D635-F4BD-DFFA-096D2E4BA9BF}.Debug|x64.ActiveCfg = Debug|x64
 		{1A1AA28B-D635-F4BD-DFFA-096D2E4BA9BF}.Release|Win32.ActiveCfg = Release|Win32
@@ -15188,6 +15472,22 @@
 		{81643723-BBFA-AA83-B6AC-9FF770B4ED34}.Release-DLL|Win32.Build.0 = Release|Win32
 		{81643723-BBFA-AA83-B6AC-9FF770B4ED34}.Release-DLL|x64.ActiveCfg = Release|x64
 		{81643723-BBFA-AA83-B6AC-9FF770B4ED34}.Release-DLL|x64.Build.0 = Release|x64
+		{0B07D219-39A5-729B-EB0F-8B81E562D808}.Debug|Win32.ActiveCfg = Debug|Win32
+		{0B07D219-39A5-729B-EB0F-8B81E562D808}.Debug|x64.ActiveCfg = Debug|x64
+		{0B07D219-39A5-729B-EB0F-8B81E562D808}.Release|Win32.ActiveCfg = Release|Win32
+		{0B07D219-39A5-729B-EB0F-8B81E562D808}.Release|x64.ActiveCfg = Release|x64
+		{0B07D219-39A5-729B-EB0F-8B81E562D808}.Debug|Win32.Build.0 = Debug|Win32
+		{0B07D219-39A5-729B-EB0F-8B81E562D808}.Debug|x64.Build.0 = Debug|x64
+		{0B07D219-39A5-729B-EB0F-8B81E562D808}.Release|Win32.Build.0 = Release|Win32
+		{0B07D219-39A5-729B-EB0F-8B81E562D808}.Release|x64.Build.0 = Release|x64
+		{0B07D219-39A5-729B-EB0F-8B81E562D808}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
+		{0B07D219-39A5-729B-EB0F-8B81E562D808}.Debug-DLL|Win32.Build.0 = Debug|Win32
+		{0B07D219-39A5-729B-EB0F-8B81E562D808}.Debug-DLL|x64.ActiveCfg = Debug|x64
+		{0B07D219-39A5-729B-EB0F-8B81E562D808}.Debug-DLL|x64.Build.0 = Debug|x64
+		{0B07D219-39A5-729B-EB0F-8B81E562D808}.Release-DLL|Win32.ActiveCfg = Release|Win32
+		{0B07D219-39A5-729B-EB0F-8B81E562D808}.Release-DLL|Win32.Build.0 = Release|Win32
+		{0B07D219-39A5-729B-EB0F-8B81E562D808}.Release-DLL|x64.ActiveCfg = Release|x64
+		{0B07D219-39A5-729B-EB0F-8B81E562D808}.Release-DLL|x64.Build.0 = Release|x64
 		{45EED825-B3C0-63AE-43FE-CFA8DD3164EC}.Debug|Win32.ActiveCfg = Debug|Win32
 		{45EED825-B3C0-63AE-43FE-CFA8DD3164EC}.Debug|x64.ActiveCfg = Debug|x64
 		{45EED825-B3C0-63AE-43FE-CFA8DD3164EC}.Release|Win32.ActiveCfg = Release|Win32
@@ -15732,6 +16032,22 @@
 		{82D02001-4051-0130-886D-6EED6E8180D9}.Release-DLL|Win32.Build.0 = Release|Win32
 		{82D02001-4051-0130-886D-6EED6E8180D9}.Release-DLL|x64.ActiveCfg = Release|x64
 		{82D02001-4051-0130-886D-6EED6E8180D9}.Release-DLL|x64.Build.0 = Release|x64
+		{856DAD36-A161-9876-9548-48D06BFA35C1}.Debug|Win32.ActiveCfg = Debug|Win32
+		{856DAD36-A161-9876-9548-48D06BFA35C1}.Debug|x64.ActiveCfg = Debug|x64
+		{856DAD36-A161-9876-9548-48D06BFA35C1}.Release|Win32.ActiveCfg = Release|Win32
+		{856DAD36-A161-9876-9548-48D06BFA35C1}.Release|x64.ActiveCfg = Release|x64
+		{856DAD36-A161-9876-9548-48D06BFA35C1}.Debug|Win32.Build.0 = Debug|Win32
+		{856DAD36-A161-9876-9548-48D06BFA35C1}.Debug|x64.Build.0 = Debug|x64
+		{856DAD36-A161-9876-9548-48D06BFA35C1}.Release|Win32.Build.0 = Release|Win32
+		{856DAD36-A161-9876-9548-48D06BFA35C1}.Release|x64.Build.0 = Release|x64
+		{856DAD36-A161-9876-9548-48D06BFA35C1}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
+		{856DAD36-A161-9876-9548-48D06BFA35C1}.Debug-DLL|Win32.Build.0 = Debug|Win32
+		{856DAD36-A161-9876-9548-48D06BFA35C1}.Debug-DLL|x64.ActiveCfg = Debug|x64
+		{856DAD36-A161-9876-9548-48D06BFA35C1}.Debug-DLL|x64.Build.0 = Debug|x64
+		{856DAD36-A161-9876-9548-48D06BFA35C1}.Release-DLL|Win32.ActiveCfg = Release|Win32
+		{856DAD36-A161-9876-9548-48D06BFA35C1}.Release-DLL|Win32.Build.0 = Release|Win32
+		{856DAD36-A161-9876-9548-48D06BFA35C1}.Release-DLL|x64.ActiveCfg = Release|x64
+		{856DAD36-A161-9876-9548-48D06BFA35C1}.Release-DLL|x64.Build.0 = Release|x64
 		{CB6E0DFE-7AA8-5F3A-431E-5D769E9339F7}.Debug|Win32.ActiveCfg = Debug|Win32
 		{CB6E0DFE-7AA8-5F3A-431E-5D769E9339F7}.Debug|x64.ActiveCfg = Debug|x64
 		{CB6E0DFE-7AA8-5F3A-431E-5D769E9339F7}.Release|Win32.ActiveCfg = Release|Win32
@@ -16788,6 +17104,22 @@
 		{359D18A0-DEE3-EDD5-1C4C-662EC638C910}.Release-DLL|Win32.Build.0 = Release|Win32
 		{359D18A0-DEE3-EDD5-1C4C-662EC638C910}.Release-DLL|x64.ActiveCfg = Release|x64
 		{359D18A0-DEE3-EDD5-1C4C-662EC638C910}.Release-DLL|x64.Build.0 = Release|x64
+		{9CFB3202-D95F-E541-9A6F-BE561CAFE1AE}.Debug|Win32.ActiveCfg = Debug|Win32
+		{9CFB3202-D95F-E541-9A6F-BE561CAFE1AE}.Debug|x64.ActiveCfg = Debug|x64
+		{9CFB3202-D95F-E541-9A6F-BE561CAFE1AE}.Release|Win32.ActiveCfg = Release|Win32
+		{9CFB3202-D95F-E541-9A6F-BE561CAFE1AE}.Release|x64.ActiveCfg = Release|x64
+		{9CFB3202-D95F-E541-9A6F-BE561CAFE1AE}.Debug|Win32.Build.0 = Debug|Win32
+		{9CFB3202-D95F-E541-9A6F-BE561CAFE1AE}.Debug|x64.Build.0 = Debug|x64
+		{9CFB3202-D95F-E541-9A6F-BE561CAFE1AE}.Release|Win32.Build.0 = Release|Win32
+		{9CFB3202-D95F-E541-9A6F-BE561CAFE1AE}.Release|x64.Build.0 = Release|x64
+		{9CFB3202-D95F-E541-9A6F-BE561CAFE1AE}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
+		{9CFB3202-D95F-E541-9A6F-BE561CAFE1AE}.Debug-DLL|Win32.Build.0 = Debug|Win32
+		{9CFB3202-D95F-E541-9A6F-BE561CAFE1AE}.Debug-DLL|x64.ActiveCfg = Debug|x64
+		{9CFB3202-D95F-E541-9A6F-BE561CAFE1AE}.Debug-DLL|x64.Build.0 = Debug|x64
+		{9CFB3202-D95F-E541-9A6F-BE561CAFE1AE}.Release-DLL|Win32.ActiveCfg = Release|Win32
+		{9CFB3202-D95F-E541-9A6F-BE561CAFE1AE}.Release-DLL|Win32.Build.0 = Release|Win32
+		{9CFB3202-D95F-E541-9A6F-BE561CAFE1AE}.Release-DLL|x64.ActiveCfg = Release|x64
+		{9CFB3202-D95F-E541-9A6F-BE561CAFE1AE}.Release-DLL|x64.Build.0 = Release|x64
 		{7B5AE7B2-6D7E-D97F-A6A4-721C7446171F}.Debug|Win32.ActiveCfg = Debug|Win32
 		{7B5AE7B2-6D7E-D97F-A6A4-721C7446171F}.Debug|x64.ActiveCfg = Debug|x64
 		{7B5AE7B2-6D7E-D97F-A6A4-721C7446171F}.Release|Win32.ActiveCfg = Release|Win32
@@ -17332,6 +17664,22 @@
 		{E6C18E4E-ABC4-1C26-BAD6-67F92B80942F}.Release-DLL|Win32.Build.0 = Release|Win32
 		{E6C18E4E-ABC4-1C26-BAD6-67F92B80942F}.Release-DLL|x64.ActiveCfg = Release|x64
 		{E6C18E4E-ABC4-1C26-BAD6-67F92B80942F}.Release-DLL|x64.Build.0 = Release|x64
+		{5A641212-7C59-E552-0ED6-F05F710DD4F5}.Debug|Win32.ActiveCfg = Debug|Win32
+		{5A641212-7C59-E552-0ED6-F05F710DD4F5}.Debug|x64.ActiveCfg = Debug|x64
+		{5A641212-7C59-E552-0ED6-F05F710DD4F5}.Release|Win32.ActiveCfg = Release|Win32
+		{5A641212-7C59-E552-0ED6-F05F710DD4F5}.Release|x64.ActiveCfg = Release|x64
+		{5A641212-7C59-E552-0ED6-F05F710DD4F5}.Debug|Win32.Build.0 = Debug|Win32
+		{5A641212-7C59-E552-0ED6-F05F710DD4F5}.Debug|x64.Build.0 = Debug|x64
+		{5A641212-7C59-E552-0ED6-F05F710DD4F5}.Release|Win32.Build.0 = Release|Win32
+		{5A641212-7C59-E552-0ED6-F05F710DD4F5}.Release|x64.Build.0 = Release|x64
+		{5A641212-7C59-E552-0ED6-F05F710DD4F5}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
+		{5A641212-7C59-E552-0ED6-F05F710DD4F5}.Debug-DLL|Win32.Build.0 = Debug|Win32
+		{5A641212-7C59-E552-0ED6-F05F710DD4F5}.Debug-DLL|x64.ActiveCfg = Debug|x64
+		{5A641212-7C59-E552-0ED6-F05F710DD4F5}.Debug-DLL|x64.Build.0 = Debug|x64
+		{5A641212-7C59-E552-0ED6-F05F710DD4F5}.Release-DLL|Win32.ActiveCfg = Release|Win32
+		{5A641212-7C59-E552-0ED6-F05F710DD4F5}.Release-DLL|Win32.Build.0 = Release|Win32
+		{5A641212-7C59-E552-0ED6-F05F710DD4F5}.Release-DLL|x64.ActiveCfg = Release|x64
+		{5A641212-7C59-E552-0ED6-F05F710DD4F5}.Release-DLL|x64.Build.0 = Release|x64
 		{C3A6661F-806B-BDE6-AF91-032175B443F8}.Debug|Win32.ActiveCfg = Debug|Win32
 		{C3A6661F-806B-BDE6-AF91-032175B443F8}.Debug|x64.ActiveCfg = Debug|x64
 		{C3A6661F-806B-BDE6-AF91-032175B443F8}.Release|Win32.ActiveCfg = Release|Win32
@@ -17876,6 +18224,22 @@
 		{FDA69240-B598-500E-8E6E-741A1290ECB9}.Release-DLL|Win32.Build.0 = Release|Win32
 		{FDA69240-B598-500E-8E6E-741A1290ECB9}.Release-DLL|x64.ActiveCfg = Release|x64
 		{FDA69240-B598-500E-8E6E-741A1290ECB9}.Release-DLL|x64.Build.0 = Release|x64
+		{C355D9BD-F3C7-CA89-E125-44D1BAEE22C1}.Debug|Win32.ActiveCfg = Debug|Win32
+		{C355D9BD-F3C7-CA89-E125-44D1BAEE22C1}.Debug|x64.ActiveCfg = Debug|x64
+		{C355D9BD-F3C7-CA89-E125-44D1BAEE22C1}.Release|Win32.ActiveCfg = Release|Win32
+		{C355D9BD-F3C7-CA89-E125-44D1BAEE22C1}.Release|x64.ActiveCfg = Release|x64
+		{C355D9BD-F3C7-CA89-E125-44D1BAEE22C1}.Debug|Win32.Build.0 = Debug|Win32
+		{C355D9BD-F3C7-CA89-E125-44D1BAEE22C1}.Debug|x64.Build.0 = Debug|x64
+		{C355D9BD-F3C7-CA89-E125-44D1BAEE22C1}.Release|Win32.Build.0 = Release|Win32
+		{C355D9BD-F3C7-CA89-E125-44D1BAEE22C1}.Release|x64.Build.0 = Release|x64
+		{C355D9BD-F3C7-CA89-E125-44D1BAEE22C1}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
+		{C355D9BD-F3C7-CA89-E125-44D1BAEE22C1}.Debug-DLL|Win32.Build.0 = Debug|Win32
+		{C355D9BD-F3C7-CA89-E125-44D1BAEE22C1}.Debug-DLL|x64.ActiveCfg = Debug|x64
+		{C355D9BD-F3C7-CA89-E125-44D1BAEE22C1}.Debug-DLL|x64.Build.0 = Debug|x64
+		{C355D9BD-F3C7-CA89-E125-44D1BAEE22C1}.Release-DLL|Win32.ActiveCfg = Release|Win32
+		{C355D9BD-F3C7-CA89-E125-44D1BAEE22C1}.Release-DLL|Win32.Build.0 = Release|Win32
+		{C355D9BD-F3C7-CA89-E125-44D1BAEE22C1}.Release-DLL|x64.ActiveCfg = Release|x64
+		{C355D9BD-F3C7-CA89-E125-44D1BAEE22C1}.Release-DLL|x64.Build.0 = Release|x64
 		{96C59CF1-6E80-B88D-D99C-0AA4C32F6562}.Debug|Win32.ActiveCfg = Debug|Win32
 		{96C59CF1-6E80-B88D-D99C-0AA4C32F6562}.Debug|x64.ActiveCfg = Debug|x64
 		{96C59CF1-6E80-B88D-D99C-0AA4C32F6562}.Release|Win32.ActiveCfg = Release|Win32
@@ -18852,6 +19216,22 @@
 		{D4F84CA0-7020-BDD6-2EB8-2F773A7884A5}.Release-DLL|Win32.Build.0 = Release|Win32
 		{D4F84CA0-7020-BDD6-2EB8-2F773A7884A5}.Release-DLL|x64.ActiveCfg = Release|x64
 		{D4F84CA0-7020-BDD6-2EB8-2F773A7884A5}.Release-DLL|x64.Build.0 = Release|x64
+		{B35C9AC3-8160-BFCA-2EA7-0413A7A45EC4}.Debug|Win32.ActiveCfg = Debug|Win32
+		{B35C9AC3-8160-BFCA-2EA7-0413A7A45EC4}.Debug|x64.ActiveCfg = Debug|x64
+		{B35C9AC3-8160-BFCA-2EA7-0413A7A45EC4}.Release|Win32.ActiveCfg = Release|Win32
+		{B35C9AC3-8160-BFCA-2EA7-0413A7A45EC4}.Release|x64.ActiveCfg = Release|x64
+		{B35C9AC3-8160-BFCA-2EA7-0413A7A45EC4}.Debug|Win32.Build.0 = Debug|Win32
+		{B35C9AC3-8160-BFCA-2EA7-0413A7A45EC4}.Debug|x64.Build.0 = Debug|x64
+		{B35C9AC3-8160-BFCA-2EA7-0413A7A45EC4}.Release|Win32.Build.0 = Release|Win32
+		{B35C9AC3-8160-BFCA-2EA7-0413A7A45EC4}.Release|x64.Build.0 = Release|x64
+		{B35C9AC3-8160-BFCA-2EA7-0413A7A45EC4}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
+		{B35C9AC3-8160-BFCA-2EA7-0413A7A45EC4}.Debug-DLL|Win32.Build.0 = Debug|Win32
+		{B35C9AC3-8160-BFCA-2EA7-0413A7A45EC4}.Debug-DLL|x64.ActiveCfg = Debug|x64
+		{B35C9AC3-8160-BFCA-2EA7-0413A7A45EC4}.Debug-DLL|x64.Build.0 = Debug|x64
+		{B35C9AC3-8160-BFCA-2EA7-0413A7A45EC4}.Release-DLL|Win32.ActiveCfg = Release|Win32
+		{B35C9AC3-8160-BFCA-2EA7-0413A7A45EC4}.Release-DLL|Win32.Build.0 = Release|Win32
+		{B35C9AC3-8160-BFCA-2EA7-0413A7A45EC4}.Release-DLL|x64.ActiveCfg = Release|x64
+		{B35C9AC3-8160-BFCA-2EA7-0413A7A45EC4}.Release-DLL|x64.Build.0 = Release|x64
 		{8BF0F1D5-3CF2-DFFD-D74D-E2D7D06A65AC}.Debug|Win32.ActiveCfg = Debug|Win32
 		{8BF0F1D5-3CF2-DFFD-D74D-E2D7D06A65AC}.Debug|x64.ActiveCfg = Debug|x64
 		{8BF0F1D5-3CF2-DFFD-D74D-E2D7D06A65AC}.Release|Win32.ActiveCfg = Release|Win32
@@ -19812,6 +20192,22 @@
 		{0ACE1393-1D1C-9563-2EFD-258C38B2C5A5}.Release-DLL|Win32.Build.0 = Release|Win32
 		{0ACE1393-1D1C-9563-2EFD-258C38B2C5A5}.Release-DLL|x64.ActiveCfg = Release|x64
 		{0ACE1393-1D1C-9563-2EFD-258C38B2C5A5}.Release-DLL|x64.Build.0 = Release|x64
+		{93AF9D45-51B5-A902-4537-709FE4ED9830}.Debug|Win32.ActiveCfg = Debug|Win32
+		{93AF9D45-51B5-A902-4537-709FE4ED9830}.Debug|x64.ActiveCfg = Debug|x64
+		{93AF9D45-51B5-A902-4537-709FE4ED9830}.Release|Win32.ActiveCfg = Release|Win32
+		{93AF9D45-51B5-A902-4537-709FE4ED9830}.Release|x64.ActiveCfg = Release|x64
+		{93AF9D45-51B5-A902-4537-709FE4ED9830}.Debug|Win32.Build.0 = Debug|Win32
+		{93AF9D45-51B5-A902-4537-709FE4ED9830}.Debug|x64.Build.0 = Debug|x64
+		{93AF9D45-51B5-A902-4537-709FE4ED9830}.Release|Win32.Build.0 = Release|Win32
+		{93AF9D45-51B5-A902-4537-709FE4ED9830}.Release|x64.Build.0 = Release|x64
+		{93AF9D45-51B5-A902-4537-709FE4ED9830}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
+		{93AF9D45-51B5-A902-4537-709FE4ED9830}.Debug-DLL|Win32.Build.0 = Debug|Win32
+		{93AF9D45-51B5-A902-4537-709FE4ED9830}.Debug-DLL|x64.ActiveCfg = Debug|x64
+		{93AF9D45-51B5-A902-4537-709FE4ED9830}.Debug-DLL|x64.Build.0 = Debug|x64
+		{93AF9D45-51B5-A902-4537-709FE4ED9830}.Release-DLL|Win32.ActiveCfg = Release|Win32
+		{93AF9D45-51B5-A902-4537-709FE4ED9830}.Release-DLL|Win32.Build.0 = Release|Win32
+		{93AF9D45-51B5-A902-4537-709FE4ED9830}.Release-DLL|x64.ActiveCfg = Release|x64
+		{93AF9D45-51B5-A902-4537-709FE4ED9830}.Release-DLL|x64.Build.0 = Release|x64
 		{0733C2AA-D898-7145-3F2E-6304DC428C5F}.Debug|Win32.ActiveCfg = Debug|Win32
 		{0733C2AA-D898-7145-3F2E-6304DC428C5F}.Debug|x64.ActiveCfg = Debug|x64
 		{0733C2AA-D898-7145-3F2E-6304DC428C5F}.Release|Win32.ActiveCfg = Release|Win32
@@ -20340,6 +20736,22 @@
 		{90CCC199-D242-7546-C1C0-4AA6899703DE}.Release-DLL|Win32.Build.0 = Release|Win32
 		{90CCC199-D242-7546-C1C0-4AA6899703DE}.Release-DLL|x64.ActiveCfg = Release|x64
 		{90CCC199-D242-7546-C1C0-4AA6899703DE}.Release-DLL|x64.Build.0 = Release|x64
+		{EA53DB0D-8BA3-3BCC-10E1-8B5FACB77CA1}.Debug|Win32.ActiveCfg = Debug|Win32
+		{EA53DB0D-8BA3-3BCC-10E1-8B5FACB77CA1}.Debug|x64.ActiveCfg = Debug|x64
+		{EA53DB0D-8BA3-3BCC-10E1-8B5FACB77CA1}.Release|Win32.ActiveCfg = Release|Win32
+		{EA53DB0D-8BA3-3BCC-10E1-8B5FACB77CA1}.Release|x64.ActiveCfg = Release|x64
+		{EA53DB0D-8BA3-3BCC-10E1-8B5FACB77CA1}.Debug|Win32.Build.0 = Debug|Win32
+		{EA53DB0D-8BA3-3BCC-10E1-8B5FACB77CA1}.Debug|x64.Build.0 = Debug|x64
+		{EA53DB0D-8BA3-3BCC-10E1-8B5FACB77CA1}.Release|Win32.Build.0 = Release|Win32
+		{EA53DB0D-8BA3-3BCC-10E1-8B5FACB77CA1}.Release|x64.Build.0 = Release|x64
+		{EA53DB0D-8BA3-3BCC-10E1-8B5FACB77CA1}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
+		{EA53DB0D-8BA3-3BCC-10E1-8B5FACB77CA1}.Debug-DLL|Win32.Build.0 = Debug|Win32
+		{EA53DB0D-8BA3-3BCC-10E1-8B5FACB77CA1}.Debug-DLL|x64.ActiveCfg = Debug|x64
+		{EA53DB0D-8BA3-3BCC-10E1-8B5FACB77CA1}.Debug-DLL|x64.Build.0 = Debug|x64
+		{EA53DB0D-8BA3-3BCC-10E1-8B5FACB77CA1}.Release-DLL|Win32.ActiveCfg = Release|Win32
+		{EA53DB0D-8BA3-3BCC-10E1-8B5FACB77CA1}.Release-DLL|Win32.Build.0 = Release|Win32
+		{EA53DB0D-8BA3-3BCC-10E1-8B5FACB77CA1}.Release-DLL|x64.ActiveCfg = Release|x64
+		{EA53DB0D-8BA3-3BCC-10E1-8B5FACB77CA1}.Release-DLL|x64.Build.0 = Release|x64
 		{0EC09350-0FB9-0208-000E-1B6C534B234C}.Debug|Win32.ActiveCfg = Debug|Win32
 		{0EC09350-0FB9-0208-000E-1B6C534B234C}.Debug|x64.ActiveCfg = Debug|x64
 		{0EC09350-0FB9-0208-000E-1B6C534B234C}.Release|Win32.ActiveCfg = Release|Win32
diff --git a/vsprojects/vcxproj/test/end2end_test_hpack_size/end2end_test_hpack_size.vcxproj b/vsprojects/vcxproj/test/end2end_test_hpack_size/end2end_test_hpack_size.vcxproj
new file mode 100644
index 0000000..41c5b93
--- /dev/null
+++ b/vsprojects/vcxproj/test/end2end_test_hpack_size/end2end_test_hpack_size.vcxproj
@@ -0,0 +1,167 @@
+<?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>{22A644D5-9A2B-4EF8-7792-AEB0C66A10E5}</ProjectGuid>
+  </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="'$(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="..\..\..\..\vsprojects\global.props" />
+    <Import Project="..\..\..\..\vsprojects\winsock.props" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup Condition="'$(Configuration)'=='Debug'">
+    <TargetName>end2end_test_hpack_size</TargetName>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)'=='Release'">
+    <TargetName>end2end_test_hpack_size</TargetName>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;_USE_32BIT_TIME_T;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+    </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>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
+      <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;_USE_32BIT_TIME_T;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+    </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>
+      <WarningLevel>Level3</WarningLevel>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+    </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="..\..\..\..\test\core\end2end\tests\cancel_test_helpers.h" />
+    <ClInclude Include="..\..\..\..\test\core\end2end\end2end_tests.h" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="..\..\..\..\test\core\end2end\tests\hpack_size.c">
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\..\..\..\vsprojects\vcxproj\.\grpc_test_util_unsecure\grpc_test_util_unsecure.vcxproj">
+      <Project>{0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF}</Project>
+    </ProjectReference>
+    <ProjectReference Include="..\..\..\..\vsprojects\vcxproj\.\grpc_unsecure\grpc_unsecure.vcxproj">
+      <Project>{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}</Project>
+    </ProjectReference>
+    <ProjectReference Include="..\..\..\..\vsprojects\vcxproj\.\gpr_test_util\gpr_test_util.vcxproj">
+      <Project>{EAB0A629-17A9-44DB-B5FF-E91A721FE037}</Project>
+    </ProjectReference>
+    <ProjectReference Include="..\..\..\..\vsprojects\vcxproj\.\gpr\gpr.vcxproj">
+      <Project>{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}</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/test/end2end_test_hpack_size/end2end_test_hpack_size.vcxproj.filters b/vsprojects/vcxproj/test/end2end_test_hpack_size/end2end_test_hpack_size.vcxproj.filters
new file mode 100644
index 0000000..03caae6
--- /dev/null
+++ b/vsprojects/vcxproj/test/end2end_test_hpack_size/end2end_test_hpack_size.vcxproj.filters
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <ClCompile Include="..\..\..\..\test\core\end2end\tests\hpack_size.c">
+      <Filter>test\core\end2end\tests</Filter>
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="..\..\..\..\test\core\end2end\tests\cancel_test_helpers.h">
+      <Filter>test\core\end2end\tests</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\..\test\core\end2end\end2end_tests.h">
+      <Filter>test\core\end2end</Filter>
+    </ClInclude>
+  </ItemGroup>
+
+  <ItemGroup>
+    <Filter Include="test">
+      <UniqueIdentifier>{c23a0719-53a2-0560-4016-2e8869dd4787}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="test\core">
+      <UniqueIdentifier>{061c394d-81e8-0ac3-7a25-ab563ba0abe3}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="test\core\end2end">
+      <UniqueIdentifier>{8b8f1aa7-7645-4372-1d8a-61cda8284353}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="test\core\end2end\tests">
+      <UniqueIdentifier>{aa7c2d3e-58e5-6898-fb3a-ba5e8868ea09}</UniqueIdentifier>
+    </Filter>
+  </ItemGroup>
+</Project>
+
diff --git a/vsprojects/vcxproj/test/h2_compress_hpack_size_nosec_test/h2_compress_hpack_size_nosec_test.vcxproj b/vsprojects/vcxproj/test/h2_compress_hpack_size_nosec_test/h2_compress_hpack_size_nosec_test.vcxproj
new file mode 100644
index 0000000..116bf2f
--- /dev/null
+++ b/vsprojects/vcxproj/test/h2_compress_hpack_size_nosec_test/h2_compress_hpack_size_nosec_test.vcxproj
@@ -0,0 +1,190 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\grpc.dependencies.openssl.props" Condition="Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\1.0.2.3.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>{5A641212-7C59-E552-0ED6-F05F710DD4F5}</ProjectGuid>
+  </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="'$(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="..\..\..\..\vsprojects\global.props" />
+    <Import Project="..\..\..\..\vsprojects\openssl.props" />
+    <Import Project="..\..\..\..\vsprojects\winsock.props" />
+    <Import Project="..\..\..\..\vsprojects\zlib.props" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup Condition="'$(Configuration)'=='Debug'">
+    <TargetName>h2_compress_hpack_size_nosec_test</TargetName>
+    <Linkage-grpc_dependencies_zlib>static</Linkage-grpc_dependencies_zlib>
+    <Configuration-grpc_dependencies_zlib>Debug</Configuration-grpc_dependencies_zlib>
+    <Configuration-grpc_dependencies_openssl>Debug</Configuration-grpc_dependencies_openssl>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)'=='Release'">
+    <TargetName>h2_compress_hpack_size_nosec_test</TargetName>
+    <Linkage-grpc_dependencies_zlib>static</Linkage-grpc_dependencies_zlib>
+    <Configuration-grpc_dependencies_zlib>Debug</Configuration-grpc_dependencies_zlib>
+    <Configuration-grpc_dependencies_openssl>Debug</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;_USE_32BIT_TIME_T;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+    </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>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
+      <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;_USE_32BIT_TIME_T;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+    </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>
+      <WarningLevel>Level3</WarningLevel>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+    </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="..\..\..\..\vsprojects\dummy.c">
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\..\..\..\vsprojects\vcxproj\test\end2end_fixture_h2_compress\end2end_fixture_h2_compress.vcxproj">
+      <Project>{C5D3C9A9-C0D2-CBAD-B433-710C5E89AE31}</Project>
+    </ProjectReference>
+    <ProjectReference Include="..\..\..\..\vsprojects\vcxproj\test\end2end_test_hpack_size\end2end_test_hpack_size.vcxproj">
+      <Project>{22A644D5-9A2B-4EF8-7792-AEB0C66A10E5}</Project>
+    </ProjectReference>
+    <ProjectReference Include="..\..\..\..\vsprojects\vcxproj\.\grpc_test_util_unsecure\grpc_test_util_unsecure.vcxproj">
+      <Project>{0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF}</Project>
+    </ProjectReference>
+    <ProjectReference Include="..\..\..\..\vsprojects\vcxproj\.\grpc_unsecure\grpc_unsecure.vcxproj">
+      <Project>{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}</Project>
+    </ProjectReference>
+    <ProjectReference Include="..\..\..\..\vsprojects\vcxproj\.\gpr_test_util\gpr_test_util.vcxproj">
+      <Project>{EAB0A629-17A9-44DB-B5FF-E91A721FE037}</Project>
+    </ProjectReference>
+    <ProjectReference Include="..\..\..\..\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="..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.9\build\native\grpc.dependencies.zlib.redist.targets" Condition="Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.9\build\native\grpc.dependencies\grpc.dependencies.zlib.targets')" />
+  <Import Project="..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.9\build\native\grpc.dependencies.zlib.targets" Condition="Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.9\build\native\grpc.dependencies\grpc.dependencies.zlib.targets')" />
+  <Import Project="..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.2.3\build\native\grpc.dependencies.openssl.redist.targets" Condition="Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.2.3\build\native\grpc.dependencies\grpc.dependencies.openssl.targets')" />
+  <Import Project="..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\grpc.dependencies.openssl.targets" Condition="Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\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('..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.9\build\native\grpc.dependencies.zlib.redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.9\build\native\grpc.dependencies.zlib.redist.targets')" />
+    <Error Condition="!Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.9\build\native\grpc.dependencies.zlib.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.9\build\native\grpc.dependencies.zlib.targets')" />
+    <Error Condition="!Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.2.3\build\native\grpc.dependencies.openssl.redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.2.3\build\native\grpc.dependencies.openssl.redist.targets')" />
+    <Error Condition="!Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\grpc.dependencies.openssl.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\grpc.dependencies.openssl.props')" />
+    <Error Condition="!Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\grpc.dependencies.openssl.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\grpc.dependencies.openssl.targets')" />
+  </Target>
+</Project>
+
diff --git a/vsprojects/vcxproj/test/h2_compress_hpack_size_nosec_test/h2_compress_hpack_size_nosec_test.vcxproj.filters b/vsprojects/vcxproj/test/h2_compress_hpack_size_nosec_test/h2_compress_hpack_size_nosec_test.vcxproj.filters
new file mode 100644
index 0000000..00e4276
--- /dev/null
+++ b/vsprojects/vcxproj/test/h2_compress_hpack_size_nosec_test/h2_compress_hpack_size_nosec_test.vcxproj.filters
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+
+  <ItemGroup>
+  </ItemGroup>
+</Project>
+
diff --git a/vsprojects/vcxproj/test/h2_compress_hpack_size_test/h2_compress_hpack_size_test.vcxproj b/vsprojects/vcxproj/test/h2_compress_hpack_size_test/h2_compress_hpack_size_test.vcxproj
new file mode 100644
index 0000000..61c35e5
--- /dev/null
+++ b/vsprojects/vcxproj/test/h2_compress_hpack_size_test/h2_compress_hpack_size_test.vcxproj
@@ -0,0 +1,193 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\grpc.dependencies.openssl.props" Condition="Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\1.0.2.3.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>{8E7B2D33-360B-9A26-8BFD-1BAD10769F33}</ProjectGuid>
+  </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="'$(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="..\..\..\..\vsprojects\global.props" />
+    <Import Project="..\..\..\..\vsprojects\openssl.props" />
+    <Import Project="..\..\..\..\vsprojects\winsock.props" />
+    <Import Project="..\..\..\..\vsprojects\zlib.props" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup Condition="'$(Configuration)'=='Debug'">
+    <TargetName>h2_compress_hpack_size_test</TargetName>
+    <Linkage-grpc_dependencies_zlib>static</Linkage-grpc_dependencies_zlib>
+    <Configuration-grpc_dependencies_zlib>Debug</Configuration-grpc_dependencies_zlib>
+    <Configuration-grpc_dependencies_openssl>Debug</Configuration-grpc_dependencies_openssl>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)'=='Release'">
+    <TargetName>h2_compress_hpack_size_test</TargetName>
+    <Linkage-grpc_dependencies_zlib>static</Linkage-grpc_dependencies_zlib>
+    <Configuration-grpc_dependencies_zlib>Debug</Configuration-grpc_dependencies_zlib>
+    <Configuration-grpc_dependencies_openssl>Debug</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;_USE_32BIT_TIME_T;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+    </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>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
+      <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;_USE_32BIT_TIME_T;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+    </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>
+      <WarningLevel>Level3</WarningLevel>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+    </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="..\..\..\..\vsprojects\dummy.c">
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\..\..\..\vsprojects\vcxproj\test\end2end_fixture_h2_compress\end2end_fixture_h2_compress.vcxproj">
+      <Project>{C5D3C9A9-C0D2-CBAD-B433-710C5E89AE31}</Project>
+    </ProjectReference>
+    <ProjectReference Include="..\..\..\..\vsprojects\vcxproj\test\end2end_test_hpack_size\end2end_test_hpack_size.vcxproj">
+      <Project>{22A644D5-9A2B-4EF8-7792-AEB0C66A10E5}</Project>
+    </ProjectReference>
+    <ProjectReference Include="..\..\..\..\vsprojects\vcxproj\test\end2end_certs\end2end_certs.vcxproj">
+      <Project>{80EA2691-C037-6DD3-D3AB-21510BF0E64B}</Project>
+    </ProjectReference>
+    <ProjectReference Include="..\..\..\..\vsprojects\vcxproj\.\grpc_test_util\grpc_test_util.vcxproj">
+      <Project>{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}</Project>
+    </ProjectReference>
+    <ProjectReference Include="..\..\..\..\vsprojects\vcxproj\.\grpc\grpc.vcxproj">
+      <Project>{29D16885-7228-4C31-81ED-5F9187C7F2A9}</Project>
+    </ProjectReference>
+    <ProjectReference Include="..\..\..\..\vsprojects\vcxproj\.\gpr_test_util\gpr_test_util.vcxproj">
+      <Project>{EAB0A629-17A9-44DB-B5FF-E91A721FE037}</Project>
+    </ProjectReference>
+    <ProjectReference Include="..\..\..\..\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="..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.9\build\native\grpc.dependencies.zlib.redist.targets" Condition="Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.9\build\native\grpc.dependencies\grpc.dependencies.zlib.targets')" />
+  <Import Project="..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.9\build\native\grpc.dependencies.zlib.targets" Condition="Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.9\build\native\grpc.dependencies\grpc.dependencies.zlib.targets')" />
+  <Import Project="..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.2.3\build\native\grpc.dependencies.openssl.redist.targets" Condition="Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.2.3\build\native\grpc.dependencies\grpc.dependencies.openssl.targets')" />
+  <Import Project="..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\grpc.dependencies.openssl.targets" Condition="Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\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('..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.9\build\native\grpc.dependencies.zlib.redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.9\build\native\grpc.dependencies.zlib.redist.targets')" />
+    <Error Condition="!Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.9\build\native\grpc.dependencies.zlib.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.9\build\native\grpc.dependencies.zlib.targets')" />
+    <Error Condition="!Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.2.3\build\native\grpc.dependencies.openssl.redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.2.3\build\native\grpc.dependencies.openssl.redist.targets')" />
+    <Error Condition="!Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\grpc.dependencies.openssl.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\grpc.dependencies.openssl.props')" />
+    <Error Condition="!Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\grpc.dependencies.openssl.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\grpc.dependencies.openssl.targets')" />
+  </Target>
+</Project>
+
diff --git a/vsprojects/vcxproj/test/h2_compress_hpack_size_test/h2_compress_hpack_size_test.vcxproj.filters b/vsprojects/vcxproj/test/h2_compress_hpack_size_test/h2_compress_hpack_size_test.vcxproj.filters
new file mode 100644
index 0000000..00e4276
--- /dev/null
+++ b/vsprojects/vcxproj/test/h2_compress_hpack_size_test/h2_compress_hpack_size_test.vcxproj.filters
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+
+  <ItemGroup>
+  </ItemGroup>
+</Project>
+
diff --git a/vsprojects/vcxproj/test/h2_fakesec_hpack_size_test/h2_fakesec_hpack_size_test.vcxproj b/vsprojects/vcxproj/test/h2_fakesec_hpack_size_test/h2_fakesec_hpack_size_test.vcxproj
new file mode 100644
index 0000000..e7c3a52
--- /dev/null
+++ b/vsprojects/vcxproj/test/h2_fakesec_hpack_size_test/h2_fakesec_hpack_size_test.vcxproj
@@ -0,0 +1,193 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\grpc.dependencies.openssl.props" Condition="Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\1.0.2.3.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>{5CDFA7CB-09E1-E01E-E21D-7446146478CC}</ProjectGuid>
+  </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="'$(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="..\..\..\..\vsprojects\global.props" />
+    <Import Project="..\..\..\..\vsprojects\openssl.props" />
+    <Import Project="..\..\..\..\vsprojects\winsock.props" />
+    <Import Project="..\..\..\..\vsprojects\zlib.props" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup Condition="'$(Configuration)'=='Debug'">
+    <TargetName>h2_fakesec_hpack_size_test</TargetName>
+    <Linkage-grpc_dependencies_zlib>static</Linkage-grpc_dependencies_zlib>
+    <Configuration-grpc_dependencies_zlib>Debug</Configuration-grpc_dependencies_zlib>
+    <Configuration-grpc_dependencies_openssl>Debug</Configuration-grpc_dependencies_openssl>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)'=='Release'">
+    <TargetName>h2_fakesec_hpack_size_test</TargetName>
+    <Linkage-grpc_dependencies_zlib>static</Linkage-grpc_dependencies_zlib>
+    <Configuration-grpc_dependencies_zlib>Debug</Configuration-grpc_dependencies_zlib>
+    <Configuration-grpc_dependencies_openssl>Debug</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;_USE_32BIT_TIME_T;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+    </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>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
+      <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;_USE_32BIT_TIME_T;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+    </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>
+      <WarningLevel>Level3</WarningLevel>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+    </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="..\..\..\..\vsprojects\dummy.c">
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\..\..\..\vsprojects\vcxproj\test\end2end_fixture_h2_fakesec\end2end_fixture_h2_fakesec.vcxproj">
+      <Project>{096ABF91-FEC8-9AC9-B877-C683BFD51984}</Project>
+    </ProjectReference>
+    <ProjectReference Include="..\..\..\..\vsprojects\vcxproj\test\end2end_test_hpack_size\end2end_test_hpack_size.vcxproj">
+      <Project>{22A644D5-9A2B-4EF8-7792-AEB0C66A10E5}</Project>
+    </ProjectReference>
+    <ProjectReference Include="..\..\..\..\vsprojects\vcxproj\test\end2end_certs\end2end_certs.vcxproj">
+      <Project>{80EA2691-C037-6DD3-D3AB-21510BF0E64B}</Project>
+    </ProjectReference>
+    <ProjectReference Include="..\..\..\..\vsprojects\vcxproj\.\grpc_test_util\grpc_test_util.vcxproj">
+      <Project>{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}</Project>
+    </ProjectReference>
+    <ProjectReference Include="..\..\..\..\vsprojects\vcxproj\.\grpc\grpc.vcxproj">
+      <Project>{29D16885-7228-4C31-81ED-5F9187C7F2A9}</Project>
+    </ProjectReference>
+    <ProjectReference Include="..\..\..\..\vsprojects\vcxproj\.\gpr_test_util\gpr_test_util.vcxproj">
+      <Project>{EAB0A629-17A9-44DB-B5FF-E91A721FE037}</Project>
+    </ProjectReference>
+    <ProjectReference Include="..\..\..\..\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="..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.9\build\native\grpc.dependencies.zlib.redist.targets" Condition="Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.9\build\native\grpc.dependencies\grpc.dependencies.zlib.targets')" />
+  <Import Project="..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.9\build\native\grpc.dependencies.zlib.targets" Condition="Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.9\build\native\grpc.dependencies\grpc.dependencies.zlib.targets')" />
+  <Import Project="..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.2.3\build\native\grpc.dependencies.openssl.redist.targets" Condition="Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.2.3\build\native\grpc.dependencies\grpc.dependencies.openssl.targets')" />
+  <Import Project="..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\grpc.dependencies.openssl.targets" Condition="Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\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('..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.9\build\native\grpc.dependencies.zlib.redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.9\build\native\grpc.dependencies.zlib.redist.targets')" />
+    <Error Condition="!Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.9\build\native\grpc.dependencies.zlib.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.9\build\native\grpc.dependencies.zlib.targets')" />
+    <Error Condition="!Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.2.3\build\native\grpc.dependencies.openssl.redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.2.3\build\native\grpc.dependencies.openssl.redist.targets')" />
+    <Error Condition="!Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\grpc.dependencies.openssl.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\grpc.dependencies.openssl.props')" />
+    <Error Condition="!Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\grpc.dependencies.openssl.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\grpc.dependencies.openssl.targets')" />
+  </Target>
+</Project>
+
diff --git a/vsprojects/vcxproj/test/h2_fakesec_hpack_size_test/h2_fakesec_hpack_size_test.vcxproj.filters b/vsprojects/vcxproj/test/h2_fakesec_hpack_size_test/h2_fakesec_hpack_size_test.vcxproj.filters
new file mode 100644
index 0000000..00e4276
--- /dev/null
+++ b/vsprojects/vcxproj/test/h2_fakesec_hpack_size_test/h2_fakesec_hpack_size_test.vcxproj.filters
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+
+  <ItemGroup>
+  </ItemGroup>
+</Project>
+
diff --git a/vsprojects/vcxproj/test/h2_full_hpack_size_nosec_test/h2_full_hpack_size_nosec_test.vcxproj b/vsprojects/vcxproj/test/h2_full_hpack_size_nosec_test/h2_full_hpack_size_nosec_test.vcxproj
new file mode 100644
index 0000000..03b0616
--- /dev/null
+++ b/vsprojects/vcxproj/test/h2_full_hpack_size_nosec_test/h2_full_hpack_size_nosec_test.vcxproj
@@ -0,0 +1,190 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\grpc.dependencies.openssl.props" Condition="Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\1.0.2.3.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>{C355D9BD-F3C7-CA89-E125-44D1BAEE22C1}</ProjectGuid>
+  </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="'$(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="..\..\..\..\vsprojects\global.props" />
+    <Import Project="..\..\..\..\vsprojects\openssl.props" />
+    <Import Project="..\..\..\..\vsprojects\winsock.props" />
+    <Import Project="..\..\..\..\vsprojects\zlib.props" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup Condition="'$(Configuration)'=='Debug'">
+    <TargetName>h2_full_hpack_size_nosec_test</TargetName>
+    <Linkage-grpc_dependencies_zlib>static</Linkage-grpc_dependencies_zlib>
+    <Configuration-grpc_dependencies_zlib>Debug</Configuration-grpc_dependencies_zlib>
+    <Configuration-grpc_dependencies_openssl>Debug</Configuration-grpc_dependencies_openssl>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)'=='Release'">
+    <TargetName>h2_full_hpack_size_nosec_test</TargetName>
+    <Linkage-grpc_dependencies_zlib>static</Linkage-grpc_dependencies_zlib>
+    <Configuration-grpc_dependencies_zlib>Debug</Configuration-grpc_dependencies_zlib>
+    <Configuration-grpc_dependencies_openssl>Debug</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;_USE_32BIT_TIME_T;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+    </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>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
+      <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;_USE_32BIT_TIME_T;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+    </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>
+      <WarningLevel>Level3</WarningLevel>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+    </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="..\..\..\..\vsprojects\dummy.c">
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\..\..\..\vsprojects\vcxproj\test\end2end_fixture_h2_full\end2end_fixture_h2_full.vcxproj">
+      <Project>{882B2933-F340-7027-7090-28CEAE9F1BE6}</Project>
+    </ProjectReference>
+    <ProjectReference Include="..\..\..\..\vsprojects\vcxproj\test\end2end_test_hpack_size\end2end_test_hpack_size.vcxproj">
+      <Project>{22A644D5-9A2B-4EF8-7792-AEB0C66A10E5}</Project>
+    </ProjectReference>
+    <ProjectReference Include="..\..\..\..\vsprojects\vcxproj\.\grpc_test_util_unsecure\grpc_test_util_unsecure.vcxproj">
+      <Project>{0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF}</Project>
+    </ProjectReference>
+    <ProjectReference Include="..\..\..\..\vsprojects\vcxproj\.\grpc_unsecure\grpc_unsecure.vcxproj">
+      <Project>{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}</Project>
+    </ProjectReference>
+    <ProjectReference Include="..\..\..\..\vsprojects\vcxproj\.\gpr_test_util\gpr_test_util.vcxproj">
+      <Project>{EAB0A629-17A9-44DB-B5FF-E91A721FE037}</Project>
+    </ProjectReference>
+    <ProjectReference Include="..\..\..\..\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="..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.9\build\native\grpc.dependencies.zlib.redist.targets" Condition="Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.9\build\native\grpc.dependencies\grpc.dependencies.zlib.targets')" />
+  <Import Project="..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.9\build\native\grpc.dependencies.zlib.targets" Condition="Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.9\build\native\grpc.dependencies\grpc.dependencies.zlib.targets')" />
+  <Import Project="..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.2.3\build\native\grpc.dependencies.openssl.redist.targets" Condition="Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.2.3\build\native\grpc.dependencies\grpc.dependencies.openssl.targets')" />
+  <Import Project="..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\grpc.dependencies.openssl.targets" Condition="Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\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('..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.9\build\native\grpc.dependencies.zlib.redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.9\build\native\grpc.dependencies.zlib.redist.targets')" />
+    <Error Condition="!Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.9\build\native\grpc.dependencies.zlib.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.9\build\native\grpc.dependencies.zlib.targets')" />
+    <Error Condition="!Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.2.3\build\native\grpc.dependencies.openssl.redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.2.3\build\native\grpc.dependencies.openssl.redist.targets')" />
+    <Error Condition="!Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\grpc.dependencies.openssl.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\grpc.dependencies.openssl.props')" />
+    <Error Condition="!Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\grpc.dependencies.openssl.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\grpc.dependencies.openssl.targets')" />
+  </Target>
+</Project>
+
diff --git a/vsprojects/vcxproj/test/h2_full_hpack_size_nosec_test/h2_full_hpack_size_nosec_test.vcxproj.filters b/vsprojects/vcxproj/test/h2_full_hpack_size_nosec_test/h2_full_hpack_size_nosec_test.vcxproj.filters
new file mode 100644
index 0000000..00e4276
--- /dev/null
+++ b/vsprojects/vcxproj/test/h2_full_hpack_size_nosec_test/h2_full_hpack_size_nosec_test.vcxproj.filters
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+
+  <ItemGroup>
+  </ItemGroup>
+</Project>
+
diff --git a/vsprojects/vcxproj/test/h2_full_hpack_size_test/h2_full_hpack_size_test.vcxproj b/vsprojects/vcxproj/test/h2_full_hpack_size_test/h2_full_hpack_size_test.vcxproj
new file mode 100644
index 0000000..9e7fb88
--- /dev/null
+++ b/vsprojects/vcxproj/test/h2_full_hpack_size_test/h2_full_hpack_size_test.vcxproj
@@ -0,0 +1,193 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\grpc.dependencies.openssl.props" Condition="Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\1.0.2.3.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>{C655AED5-AF53-D09E-A8EA-60AE0F2D149A}</ProjectGuid>
+  </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="'$(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="..\..\..\..\vsprojects\global.props" />
+    <Import Project="..\..\..\..\vsprojects\openssl.props" />
+    <Import Project="..\..\..\..\vsprojects\winsock.props" />
+    <Import Project="..\..\..\..\vsprojects\zlib.props" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup Condition="'$(Configuration)'=='Debug'">
+    <TargetName>h2_full_hpack_size_test</TargetName>
+    <Linkage-grpc_dependencies_zlib>static</Linkage-grpc_dependencies_zlib>
+    <Configuration-grpc_dependencies_zlib>Debug</Configuration-grpc_dependencies_zlib>
+    <Configuration-grpc_dependencies_openssl>Debug</Configuration-grpc_dependencies_openssl>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)'=='Release'">
+    <TargetName>h2_full_hpack_size_test</TargetName>
+    <Linkage-grpc_dependencies_zlib>static</Linkage-grpc_dependencies_zlib>
+    <Configuration-grpc_dependencies_zlib>Debug</Configuration-grpc_dependencies_zlib>
+    <Configuration-grpc_dependencies_openssl>Debug</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;_USE_32BIT_TIME_T;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+    </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>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
+      <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;_USE_32BIT_TIME_T;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+    </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>
+      <WarningLevel>Level3</WarningLevel>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+    </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="..\..\..\..\vsprojects\dummy.c">
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\..\..\..\vsprojects\vcxproj\test\end2end_fixture_h2_full\end2end_fixture_h2_full.vcxproj">
+      <Project>{882B2933-F340-7027-7090-28CEAE9F1BE6}</Project>
+    </ProjectReference>
+    <ProjectReference Include="..\..\..\..\vsprojects\vcxproj\test\end2end_test_hpack_size\end2end_test_hpack_size.vcxproj">
+      <Project>{22A644D5-9A2B-4EF8-7792-AEB0C66A10E5}</Project>
+    </ProjectReference>
+    <ProjectReference Include="..\..\..\..\vsprojects\vcxproj\test\end2end_certs\end2end_certs.vcxproj">
+      <Project>{80EA2691-C037-6DD3-D3AB-21510BF0E64B}</Project>
+    </ProjectReference>
+    <ProjectReference Include="..\..\..\..\vsprojects\vcxproj\.\grpc_test_util\grpc_test_util.vcxproj">
+      <Project>{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}</Project>
+    </ProjectReference>
+    <ProjectReference Include="..\..\..\..\vsprojects\vcxproj\.\grpc\grpc.vcxproj">
+      <Project>{29D16885-7228-4C31-81ED-5F9187C7F2A9}</Project>
+    </ProjectReference>
+    <ProjectReference Include="..\..\..\..\vsprojects\vcxproj\.\gpr_test_util\gpr_test_util.vcxproj">
+      <Project>{EAB0A629-17A9-44DB-B5FF-E91A721FE037}</Project>
+    </ProjectReference>
+    <ProjectReference Include="..\..\..\..\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="..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.9\build\native\grpc.dependencies.zlib.redist.targets" Condition="Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.9\build\native\grpc.dependencies\grpc.dependencies.zlib.targets')" />
+  <Import Project="..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.9\build\native\grpc.dependencies.zlib.targets" Condition="Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.9\build\native\grpc.dependencies\grpc.dependencies.zlib.targets')" />
+  <Import Project="..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.2.3\build\native\grpc.dependencies.openssl.redist.targets" Condition="Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.2.3\build\native\grpc.dependencies\grpc.dependencies.openssl.targets')" />
+  <Import Project="..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\grpc.dependencies.openssl.targets" Condition="Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\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('..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.9\build\native\grpc.dependencies.zlib.redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.9\build\native\grpc.dependencies.zlib.redist.targets')" />
+    <Error Condition="!Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.9\build\native\grpc.dependencies.zlib.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.9\build\native\grpc.dependencies.zlib.targets')" />
+    <Error Condition="!Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.2.3\build\native\grpc.dependencies.openssl.redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.2.3\build\native\grpc.dependencies.openssl.redist.targets')" />
+    <Error Condition="!Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\grpc.dependencies.openssl.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\grpc.dependencies.openssl.props')" />
+    <Error Condition="!Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\grpc.dependencies.openssl.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\grpc.dependencies.openssl.targets')" />
+  </Target>
+</Project>
+
diff --git a/vsprojects/vcxproj/test/h2_full_hpack_size_test/h2_full_hpack_size_test.vcxproj.filters b/vsprojects/vcxproj/test/h2_full_hpack_size_test/h2_full_hpack_size_test.vcxproj.filters
new file mode 100644
index 0000000..00e4276
--- /dev/null
+++ b/vsprojects/vcxproj/test/h2_full_hpack_size_test/h2_full_hpack_size_test.vcxproj.filters
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+
+  <ItemGroup>
+  </ItemGroup>
+</Project>
+
diff --git a/vsprojects/vcxproj/test/h2_oauth2_hpack_size_test/h2_oauth2_hpack_size_test.vcxproj b/vsprojects/vcxproj/test/h2_oauth2_hpack_size_test/h2_oauth2_hpack_size_test.vcxproj
new file mode 100644
index 0000000..82c49fe
--- /dev/null
+++ b/vsprojects/vcxproj/test/h2_oauth2_hpack_size_test/h2_oauth2_hpack_size_test.vcxproj
@@ -0,0 +1,193 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\grpc.dependencies.openssl.props" Condition="Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\1.0.2.3.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>{CA3C2D7E-58C7-C05E-6D3B-70383020D8C2}</ProjectGuid>
+  </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="'$(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="..\..\..\..\vsprojects\global.props" />
+    <Import Project="..\..\..\..\vsprojects\openssl.props" />
+    <Import Project="..\..\..\..\vsprojects\winsock.props" />
+    <Import Project="..\..\..\..\vsprojects\zlib.props" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup Condition="'$(Configuration)'=='Debug'">
+    <TargetName>h2_oauth2_hpack_size_test</TargetName>
+    <Linkage-grpc_dependencies_zlib>static</Linkage-grpc_dependencies_zlib>
+    <Configuration-grpc_dependencies_zlib>Debug</Configuration-grpc_dependencies_zlib>
+    <Configuration-grpc_dependencies_openssl>Debug</Configuration-grpc_dependencies_openssl>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)'=='Release'">
+    <TargetName>h2_oauth2_hpack_size_test</TargetName>
+    <Linkage-grpc_dependencies_zlib>static</Linkage-grpc_dependencies_zlib>
+    <Configuration-grpc_dependencies_zlib>Debug</Configuration-grpc_dependencies_zlib>
+    <Configuration-grpc_dependencies_openssl>Debug</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;_USE_32BIT_TIME_T;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+    </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>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
+      <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;_USE_32BIT_TIME_T;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+    </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>
+      <WarningLevel>Level3</WarningLevel>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+    </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="..\..\..\..\vsprojects\dummy.c">
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\..\..\..\vsprojects\vcxproj\test\end2end_fixture_h2_oauth2\end2end_fixture_h2_oauth2.vcxproj">
+      <Project>{DDFE4EB8-CCD3-DA3F-461A-10F1B94D26AF}</Project>
+    </ProjectReference>
+    <ProjectReference Include="..\..\..\..\vsprojects\vcxproj\test\end2end_test_hpack_size\end2end_test_hpack_size.vcxproj">
+      <Project>{22A644D5-9A2B-4EF8-7792-AEB0C66A10E5}</Project>
+    </ProjectReference>
+    <ProjectReference Include="..\..\..\..\vsprojects\vcxproj\test\end2end_certs\end2end_certs.vcxproj">
+      <Project>{80EA2691-C037-6DD3-D3AB-21510BF0E64B}</Project>
+    </ProjectReference>
+    <ProjectReference Include="..\..\..\..\vsprojects\vcxproj\.\grpc_test_util\grpc_test_util.vcxproj">
+      <Project>{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}</Project>
+    </ProjectReference>
+    <ProjectReference Include="..\..\..\..\vsprojects\vcxproj\.\grpc\grpc.vcxproj">
+      <Project>{29D16885-7228-4C31-81ED-5F9187C7F2A9}</Project>
+    </ProjectReference>
+    <ProjectReference Include="..\..\..\..\vsprojects\vcxproj\.\gpr_test_util\gpr_test_util.vcxproj">
+      <Project>{EAB0A629-17A9-44DB-B5FF-E91A721FE037}</Project>
+    </ProjectReference>
+    <ProjectReference Include="..\..\..\..\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="..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.9\build\native\grpc.dependencies.zlib.redist.targets" Condition="Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.9\build\native\grpc.dependencies\grpc.dependencies.zlib.targets')" />
+  <Import Project="..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.9\build\native\grpc.dependencies.zlib.targets" Condition="Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.9\build\native\grpc.dependencies\grpc.dependencies.zlib.targets')" />
+  <Import Project="..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.2.3\build\native\grpc.dependencies.openssl.redist.targets" Condition="Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.2.3\build\native\grpc.dependencies\grpc.dependencies.openssl.targets')" />
+  <Import Project="..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\grpc.dependencies.openssl.targets" Condition="Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\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('..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.9\build\native\grpc.dependencies.zlib.redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.9\build\native\grpc.dependencies.zlib.redist.targets')" />
+    <Error Condition="!Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.9\build\native\grpc.dependencies.zlib.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.9\build\native\grpc.dependencies.zlib.targets')" />
+    <Error Condition="!Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.2.3\build\native\grpc.dependencies.openssl.redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.2.3\build\native\grpc.dependencies.openssl.redist.targets')" />
+    <Error Condition="!Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\grpc.dependencies.openssl.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\grpc.dependencies.openssl.props')" />
+    <Error Condition="!Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\grpc.dependencies.openssl.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\grpc.dependencies.openssl.targets')" />
+  </Target>
+</Project>
+
diff --git a/vsprojects/vcxproj/test/h2_oauth2_hpack_size_test/h2_oauth2_hpack_size_test.vcxproj.filters b/vsprojects/vcxproj/test/h2_oauth2_hpack_size_test/h2_oauth2_hpack_size_test.vcxproj.filters
new file mode 100644
index 0000000..00e4276
--- /dev/null
+++ b/vsprojects/vcxproj/test/h2_oauth2_hpack_size_test/h2_oauth2_hpack_size_test.vcxproj.filters
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+
+  <ItemGroup>
+  </ItemGroup>
+</Project>
+
diff --git a/vsprojects/vcxproj/test/h2_sockpair_1byte_hpack_size_nosec_test/h2_sockpair_1byte_hpack_size_nosec_test.vcxproj b/vsprojects/vcxproj/test/h2_sockpair_1byte_hpack_size_nosec_test/h2_sockpair_1byte_hpack_size_nosec_test.vcxproj
new file mode 100644
index 0000000..c5a13ad
--- /dev/null
+++ b/vsprojects/vcxproj/test/h2_sockpair_1byte_hpack_size_nosec_test/h2_sockpair_1byte_hpack_size_nosec_test.vcxproj
@@ -0,0 +1,190 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\grpc.dependencies.openssl.props" Condition="Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\1.0.2.3.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>{93AF9D45-51B5-A902-4537-709FE4ED9830}</ProjectGuid>
+  </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="'$(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="..\..\..\..\vsprojects\global.props" />
+    <Import Project="..\..\..\..\vsprojects\openssl.props" />
+    <Import Project="..\..\..\..\vsprojects\winsock.props" />
+    <Import Project="..\..\..\..\vsprojects\zlib.props" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup Condition="'$(Configuration)'=='Debug'">
+    <TargetName>h2_sockpair_1byte_hpack_size_nosec_test</TargetName>
+    <Linkage-grpc_dependencies_zlib>static</Linkage-grpc_dependencies_zlib>
+    <Configuration-grpc_dependencies_zlib>Debug</Configuration-grpc_dependencies_zlib>
+    <Configuration-grpc_dependencies_openssl>Debug</Configuration-grpc_dependencies_openssl>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)'=='Release'">
+    <TargetName>h2_sockpair_1byte_hpack_size_nosec_test</TargetName>
+    <Linkage-grpc_dependencies_zlib>static</Linkage-grpc_dependencies_zlib>
+    <Configuration-grpc_dependencies_zlib>Debug</Configuration-grpc_dependencies_zlib>
+    <Configuration-grpc_dependencies_openssl>Debug</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;_USE_32BIT_TIME_T;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+    </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>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
+      <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;_USE_32BIT_TIME_T;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+    </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>
+      <WarningLevel>Level3</WarningLevel>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+    </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="..\..\..\..\vsprojects\dummy.c">
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\..\..\..\vsprojects\vcxproj\test\end2end_fixture_h2_sockpair_1byte\end2end_fixture_h2_sockpair_1byte.vcxproj">
+      <Project>{B0F4BF34-3C82-EB67-990E-959CDDBEB734}</Project>
+    </ProjectReference>
+    <ProjectReference Include="..\..\..\..\vsprojects\vcxproj\test\end2end_test_hpack_size\end2end_test_hpack_size.vcxproj">
+      <Project>{22A644D5-9A2B-4EF8-7792-AEB0C66A10E5}</Project>
+    </ProjectReference>
+    <ProjectReference Include="..\..\..\..\vsprojects\vcxproj\.\grpc_test_util_unsecure\grpc_test_util_unsecure.vcxproj">
+      <Project>{0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF}</Project>
+    </ProjectReference>
+    <ProjectReference Include="..\..\..\..\vsprojects\vcxproj\.\grpc_unsecure\grpc_unsecure.vcxproj">
+      <Project>{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}</Project>
+    </ProjectReference>
+    <ProjectReference Include="..\..\..\..\vsprojects\vcxproj\.\gpr_test_util\gpr_test_util.vcxproj">
+      <Project>{EAB0A629-17A9-44DB-B5FF-E91A721FE037}</Project>
+    </ProjectReference>
+    <ProjectReference Include="..\..\..\..\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="..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.9\build\native\grpc.dependencies.zlib.redist.targets" Condition="Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.9\build\native\grpc.dependencies\grpc.dependencies.zlib.targets')" />
+  <Import Project="..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.9\build\native\grpc.dependencies.zlib.targets" Condition="Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.9\build\native\grpc.dependencies\grpc.dependencies.zlib.targets')" />
+  <Import Project="..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.2.3\build\native\grpc.dependencies.openssl.redist.targets" Condition="Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.2.3\build\native\grpc.dependencies\grpc.dependencies.openssl.targets')" />
+  <Import Project="..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\grpc.dependencies.openssl.targets" Condition="Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\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('..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.9\build\native\grpc.dependencies.zlib.redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.9\build\native\grpc.dependencies.zlib.redist.targets')" />
+    <Error Condition="!Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.9\build\native\grpc.dependencies.zlib.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.9\build\native\grpc.dependencies.zlib.targets')" />
+    <Error Condition="!Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.2.3\build\native\grpc.dependencies.openssl.redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.2.3\build\native\grpc.dependencies.openssl.redist.targets')" />
+    <Error Condition="!Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\grpc.dependencies.openssl.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\grpc.dependencies.openssl.props')" />
+    <Error Condition="!Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\grpc.dependencies.openssl.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\grpc.dependencies.openssl.targets')" />
+  </Target>
+</Project>
+
diff --git a/vsprojects/vcxproj/test/h2_sockpair_1byte_hpack_size_nosec_test/h2_sockpair_1byte_hpack_size_nosec_test.vcxproj.filters b/vsprojects/vcxproj/test/h2_sockpair_1byte_hpack_size_nosec_test/h2_sockpair_1byte_hpack_size_nosec_test.vcxproj.filters
new file mode 100644
index 0000000..00e4276
--- /dev/null
+++ b/vsprojects/vcxproj/test/h2_sockpair_1byte_hpack_size_nosec_test/h2_sockpair_1byte_hpack_size_nosec_test.vcxproj.filters
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+
+  <ItemGroup>
+  </ItemGroup>
+</Project>
+
diff --git a/vsprojects/vcxproj/test/h2_sockpair_1byte_hpack_size_test/h2_sockpair_1byte_hpack_size_test.vcxproj b/vsprojects/vcxproj/test/h2_sockpair_1byte_hpack_size_test/h2_sockpair_1byte_hpack_size_test.vcxproj
new file mode 100644
index 0000000..de13e26
--- /dev/null
+++ b/vsprojects/vcxproj/test/h2_sockpair_1byte_hpack_size_test/h2_sockpair_1byte_hpack_size_test.vcxproj
@@ -0,0 +1,193 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\grpc.dependencies.openssl.props" Condition="Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\1.0.2.3.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>{0B07D219-39A5-729B-EB0F-8B81E562D808}</ProjectGuid>
+  </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="'$(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="..\..\..\..\vsprojects\global.props" />
+    <Import Project="..\..\..\..\vsprojects\openssl.props" />
+    <Import Project="..\..\..\..\vsprojects\winsock.props" />
+    <Import Project="..\..\..\..\vsprojects\zlib.props" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup Condition="'$(Configuration)'=='Debug'">
+    <TargetName>h2_sockpair_1byte_hpack_size_test</TargetName>
+    <Linkage-grpc_dependencies_zlib>static</Linkage-grpc_dependencies_zlib>
+    <Configuration-grpc_dependencies_zlib>Debug</Configuration-grpc_dependencies_zlib>
+    <Configuration-grpc_dependencies_openssl>Debug</Configuration-grpc_dependencies_openssl>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)'=='Release'">
+    <TargetName>h2_sockpair_1byte_hpack_size_test</TargetName>
+    <Linkage-grpc_dependencies_zlib>static</Linkage-grpc_dependencies_zlib>
+    <Configuration-grpc_dependencies_zlib>Debug</Configuration-grpc_dependencies_zlib>
+    <Configuration-grpc_dependencies_openssl>Debug</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;_USE_32BIT_TIME_T;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+    </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>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
+      <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;_USE_32BIT_TIME_T;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+    </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>
+      <WarningLevel>Level3</WarningLevel>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+    </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="..\..\..\..\vsprojects\dummy.c">
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\..\..\..\vsprojects\vcxproj\test\end2end_fixture_h2_sockpair_1byte\end2end_fixture_h2_sockpair_1byte.vcxproj">
+      <Project>{B0F4BF34-3C82-EB67-990E-959CDDBEB734}</Project>
+    </ProjectReference>
+    <ProjectReference Include="..\..\..\..\vsprojects\vcxproj\test\end2end_test_hpack_size\end2end_test_hpack_size.vcxproj">
+      <Project>{22A644D5-9A2B-4EF8-7792-AEB0C66A10E5}</Project>
+    </ProjectReference>
+    <ProjectReference Include="..\..\..\..\vsprojects\vcxproj\test\end2end_certs\end2end_certs.vcxproj">
+      <Project>{80EA2691-C037-6DD3-D3AB-21510BF0E64B}</Project>
+    </ProjectReference>
+    <ProjectReference Include="..\..\..\..\vsprojects\vcxproj\.\grpc_test_util\grpc_test_util.vcxproj">
+      <Project>{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}</Project>
+    </ProjectReference>
+    <ProjectReference Include="..\..\..\..\vsprojects\vcxproj\.\grpc\grpc.vcxproj">
+      <Project>{29D16885-7228-4C31-81ED-5F9187C7F2A9}</Project>
+    </ProjectReference>
+    <ProjectReference Include="..\..\..\..\vsprojects\vcxproj\.\gpr_test_util\gpr_test_util.vcxproj">
+      <Project>{EAB0A629-17A9-44DB-B5FF-E91A721FE037}</Project>
+    </ProjectReference>
+    <ProjectReference Include="..\..\..\..\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="..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.9\build\native\grpc.dependencies.zlib.redist.targets" Condition="Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.9\build\native\grpc.dependencies\grpc.dependencies.zlib.targets')" />
+  <Import Project="..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.9\build\native\grpc.dependencies.zlib.targets" Condition="Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.9\build\native\grpc.dependencies\grpc.dependencies.zlib.targets')" />
+  <Import Project="..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.2.3\build\native\grpc.dependencies.openssl.redist.targets" Condition="Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.2.3\build\native\grpc.dependencies\grpc.dependencies.openssl.targets')" />
+  <Import Project="..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\grpc.dependencies.openssl.targets" Condition="Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\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('..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.9\build\native\grpc.dependencies.zlib.redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.9\build\native\grpc.dependencies.zlib.redist.targets')" />
+    <Error Condition="!Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.9\build\native\grpc.dependencies.zlib.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.9\build\native\grpc.dependencies.zlib.targets')" />
+    <Error Condition="!Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.2.3\build\native\grpc.dependencies.openssl.redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.2.3\build\native\grpc.dependencies.openssl.redist.targets')" />
+    <Error Condition="!Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\grpc.dependencies.openssl.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\grpc.dependencies.openssl.props')" />
+    <Error Condition="!Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\grpc.dependencies.openssl.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\grpc.dependencies.openssl.targets')" />
+  </Target>
+</Project>
+
diff --git a/vsprojects/vcxproj/test/h2_sockpair_1byte_hpack_size_test/h2_sockpair_1byte_hpack_size_test.vcxproj.filters b/vsprojects/vcxproj/test/h2_sockpair_1byte_hpack_size_test/h2_sockpair_1byte_hpack_size_test.vcxproj.filters
new file mode 100644
index 0000000..00e4276
--- /dev/null
+++ b/vsprojects/vcxproj/test/h2_sockpair_1byte_hpack_size_test/h2_sockpair_1byte_hpack_size_test.vcxproj.filters
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+
+  <ItemGroup>
+  </ItemGroup>
+</Project>
+
diff --git a/vsprojects/vcxproj/test/h2_sockpair_hpack_size_nosec_test/h2_sockpair_hpack_size_nosec_test.vcxproj b/vsprojects/vcxproj/test/h2_sockpair_hpack_size_nosec_test/h2_sockpair_hpack_size_nosec_test.vcxproj
new file mode 100644
index 0000000..fedcff8
--- /dev/null
+++ b/vsprojects/vcxproj/test/h2_sockpair_hpack_size_nosec_test/h2_sockpair_hpack_size_nosec_test.vcxproj
@@ -0,0 +1,190 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\grpc.dependencies.openssl.props" Condition="Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\1.0.2.3.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>{B35C9AC3-8160-BFCA-2EA7-0413A7A45EC4}</ProjectGuid>
+  </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="'$(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="..\..\..\..\vsprojects\global.props" />
+    <Import Project="..\..\..\..\vsprojects\openssl.props" />
+    <Import Project="..\..\..\..\vsprojects\winsock.props" />
+    <Import Project="..\..\..\..\vsprojects\zlib.props" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup Condition="'$(Configuration)'=='Debug'">
+    <TargetName>h2_sockpair_hpack_size_nosec_test</TargetName>
+    <Linkage-grpc_dependencies_zlib>static</Linkage-grpc_dependencies_zlib>
+    <Configuration-grpc_dependencies_zlib>Debug</Configuration-grpc_dependencies_zlib>
+    <Configuration-grpc_dependencies_openssl>Debug</Configuration-grpc_dependencies_openssl>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)'=='Release'">
+    <TargetName>h2_sockpair_hpack_size_nosec_test</TargetName>
+    <Linkage-grpc_dependencies_zlib>static</Linkage-grpc_dependencies_zlib>
+    <Configuration-grpc_dependencies_zlib>Debug</Configuration-grpc_dependencies_zlib>
+    <Configuration-grpc_dependencies_openssl>Debug</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;_USE_32BIT_TIME_T;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+    </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>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
+      <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;_USE_32BIT_TIME_T;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+    </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>
+      <WarningLevel>Level3</WarningLevel>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+    </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="..\..\..\..\vsprojects\dummy.c">
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\..\..\..\vsprojects\vcxproj\test\end2end_fixture_h2_sockpair\end2end_fixture_h2_sockpair.vcxproj">
+      <Project>{67A1675D-FF50-3B78-2706-155D69ADC290}</Project>
+    </ProjectReference>
+    <ProjectReference Include="..\..\..\..\vsprojects\vcxproj\test\end2end_test_hpack_size\end2end_test_hpack_size.vcxproj">
+      <Project>{22A644D5-9A2B-4EF8-7792-AEB0C66A10E5}</Project>
+    </ProjectReference>
+    <ProjectReference Include="..\..\..\..\vsprojects\vcxproj\.\grpc_test_util_unsecure\grpc_test_util_unsecure.vcxproj">
+      <Project>{0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF}</Project>
+    </ProjectReference>
+    <ProjectReference Include="..\..\..\..\vsprojects\vcxproj\.\grpc_unsecure\grpc_unsecure.vcxproj">
+      <Project>{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}</Project>
+    </ProjectReference>
+    <ProjectReference Include="..\..\..\..\vsprojects\vcxproj\.\gpr_test_util\gpr_test_util.vcxproj">
+      <Project>{EAB0A629-17A9-44DB-B5FF-E91A721FE037}</Project>
+    </ProjectReference>
+    <ProjectReference Include="..\..\..\..\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="..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.9\build\native\grpc.dependencies.zlib.redist.targets" Condition="Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.9\build\native\grpc.dependencies\grpc.dependencies.zlib.targets')" />
+  <Import Project="..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.9\build\native\grpc.dependencies.zlib.targets" Condition="Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.9\build\native\grpc.dependencies\grpc.dependencies.zlib.targets')" />
+  <Import Project="..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.2.3\build\native\grpc.dependencies.openssl.redist.targets" Condition="Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.2.3\build\native\grpc.dependencies\grpc.dependencies.openssl.targets')" />
+  <Import Project="..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\grpc.dependencies.openssl.targets" Condition="Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\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('..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.9\build\native\grpc.dependencies.zlib.redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.9\build\native\grpc.dependencies.zlib.redist.targets')" />
+    <Error Condition="!Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.9\build\native\grpc.dependencies.zlib.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.9\build\native\grpc.dependencies.zlib.targets')" />
+    <Error Condition="!Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.2.3\build\native\grpc.dependencies.openssl.redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.2.3\build\native\grpc.dependencies.openssl.redist.targets')" />
+    <Error Condition="!Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\grpc.dependencies.openssl.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\grpc.dependencies.openssl.props')" />
+    <Error Condition="!Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\grpc.dependencies.openssl.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\grpc.dependencies.openssl.targets')" />
+  </Target>
+</Project>
+
diff --git a/vsprojects/vcxproj/test/h2_sockpair_hpack_size_nosec_test/h2_sockpair_hpack_size_nosec_test.vcxproj.filters b/vsprojects/vcxproj/test/h2_sockpair_hpack_size_nosec_test/h2_sockpair_hpack_size_nosec_test.vcxproj.filters
new file mode 100644
index 0000000..00e4276
--- /dev/null
+++ b/vsprojects/vcxproj/test/h2_sockpair_hpack_size_nosec_test/h2_sockpair_hpack_size_nosec_test.vcxproj.filters
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+
+  <ItemGroup>
+  </ItemGroup>
+</Project>
+
diff --git a/vsprojects/vcxproj/test/h2_sockpair_hpack_size_test/h2_sockpair_hpack_size_test.vcxproj b/vsprojects/vcxproj/test/h2_sockpair_hpack_size_test/h2_sockpair_hpack_size_test.vcxproj
new file mode 100644
index 0000000..744cb13
--- /dev/null
+++ b/vsprojects/vcxproj/test/h2_sockpair_hpack_size_test/h2_sockpair_hpack_size_test.vcxproj
@@ -0,0 +1,193 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\grpc.dependencies.openssl.props" Condition="Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\1.0.2.3.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>{E96735FF-B1CF-51D2-1923-53292AF72C4E}</ProjectGuid>
+  </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="'$(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="..\..\..\..\vsprojects\global.props" />
+    <Import Project="..\..\..\..\vsprojects\openssl.props" />
+    <Import Project="..\..\..\..\vsprojects\winsock.props" />
+    <Import Project="..\..\..\..\vsprojects\zlib.props" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup Condition="'$(Configuration)'=='Debug'">
+    <TargetName>h2_sockpair_hpack_size_test</TargetName>
+    <Linkage-grpc_dependencies_zlib>static</Linkage-grpc_dependencies_zlib>
+    <Configuration-grpc_dependencies_zlib>Debug</Configuration-grpc_dependencies_zlib>
+    <Configuration-grpc_dependencies_openssl>Debug</Configuration-grpc_dependencies_openssl>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)'=='Release'">
+    <TargetName>h2_sockpair_hpack_size_test</TargetName>
+    <Linkage-grpc_dependencies_zlib>static</Linkage-grpc_dependencies_zlib>
+    <Configuration-grpc_dependencies_zlib>Debug</Configuration-grpc_dependencies_zlib>
+    <Configuration-grpc_dependencies_openssl>Debug</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;_USE_32BIT_TIME_T;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+    </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>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
+      <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;_USE_32BIT_TIME_T;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+    </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>
+      <WarningLevel>Level3</WarningLevel>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+    </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="..\..\..\..\vsprojects\dummy.c">
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\..\..\..\vsprojects\vcxproj\test\end2end_fixture_h2_sockpair\end2end_fixture_h2_sockpair.vcxproj">
+      <Project>{67A1675D-FF50-3B78-2706-155D69ADC290}</Project>
+    </ProjectReference>
+    <ProjectReference Include="..\..\..\..\vsprojects\vcxproj\test\end2end_test_hpack_size\end2end_test_hpack_size.vcxproj">
+      <Project>{22A644D5-9A2B-4EF8-7792-AEB0C66A10E5}</Project>
+    </ProjectReference>
+    <ProjectReference Include="..\..\..\..\vsprojects\vcxproj\test\end2end_certs\end2end_certs.vcxproj">
+      <Project>{80EA2691-C037-6DD3-D3AB-21510BF0E64B}</Project>
+    </ProjectReference>
+    <ProjectReference Include="..\..\..\..\vsprojects\vcxproj\.\grpc_test_util\grpc_test_util.vcxproj">
+      <Project>{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}</Project>
+    </ProjectReference>
+    <ProjectReference Include="..\..\..\..\vsprojects\vcxproj\.\grpc\grpc.vcxproj">
+      <Project>{29D16885-7228-4C31-81ED-5F9187C7F2A9}</Project>
+    </ProjectReference>
+    <ProjectReference Include="..\..\..\..\vsprojects\vcxproj\.\gpr_test_util\gpr_test_util.vcxproj">
+      <Project>{EAB0A629-17A9-44DB-B5FF-E91A721FE037}</Project>
+    </ProjectReference>
+    <ProjectReference Include="..\..\..\..\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="..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.9\build\native\grpc.dependencies.zlib.redist.targets" Condition="Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.9\build\native\grpc.dependencies\grpc.dependencies.zlib.targets')" />
+  <Import Project="..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.9\build\native\grpc.dependencies.zlib.targets" Condition="Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.9\build\native\grpc.dependencies\grpc.dependencies.zlib.targets')" />
+  <Import Project="..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.2.3\build\native\grpc.dependencies.openssl.redist.targets" Condition="Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.2.3\build\native\grpc.dependencies\grpc.dependencies.openssl.targets')" />
+  <Import Project="..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\grpc.dependencies.openssl.targets" Condition="Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\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('..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.9\build\native\grpc.dependencies.zlib.redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.9\build\native\grpc.dependencies.zlib.redist.targets')" />
+    <Error Condition="!Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.9\build\native\grpc.dependencies.zlib.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.9\build\native\grpc.dependencies.zlib.targets')" />
+    <Error Condition="!Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.2.3\build\native\grpc.dependencies.openssl.redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.2.3\build\native\grpc.dependencies.openssl.redist.targets')" />
+    <Error Condition="!Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\grpc.dependencies.openssl.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\grpc.dependencies.openssl.props')" />
+    <Error Condition="!Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\grpc.dependencies.openssl.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\grpc.dependencies.openssl.targets')" />
+  </Target>
+</Project>
+
diff --git a/vsprojects/vcxproj/test/h2_sockpair_hpack_size_test/h2_sockpair_hpack_size_test.vcxproj.filters b/vsprojects/vcxproj/test/h2_sockpair_hpack_size_test/h2_sockpair_hpack_size_test.vcxproj.filters
new file mode 100644
index 0000000..00e4276
--- /dev/null
+++ b/vsprojects/vcxproj/test/h2_sockpair_hpack_size_test/h2_sockpair_hpack_size_test.vcxproj.filters
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+
+  <ItemGroup>
+  </ItemGroup>
+</Project>
+
diff --git a/vsprojects/vcxproj/test/h2_ssl_hpack_size_test/h2_ssl_hpack_size_test.vcxproj b/vsprojects/vcxproj/test/h2_ssl_hpack_size_test/h2_ssl_hpack_size_test.vcxproj
new file mode 100644
index 0000000..2ff0f47
--- /dev/null
+++ b/vsprojects/vcxproj/test/h2_ssl_hpack_size_test/h2_ssl_hpack_size_test.vcxproj
@@ -0,0 +1,193 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\grpc.dependencies.openssl.props" Condition="Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\1.0.2.3.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>{856DAD36-A161-9876-9548-48D06BFA35C1}</ProjectGuid>
+  </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="'$(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="..\..\..\..\vsprojects\global.props" />
+    <Import Project="..\..\..\..\vsprojects\openssl.props" />
+    <Import Project="..\..\..\..\vsprojects\winsock.props" />
+    <Import Project="..\..\..\..\vsprojects\zlib.props" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup Condition="'$(Configuration)'=='Debug'">
+    <TargetName>h2_ssl_hpack_size_test</TargetName>
+    <Linkage-grpc_dependencies_zlib>static</Linkage-grpc_dependencies_zlib>
+    <Configuration-grpc_dependencies_zlib>Debug</Configuration-grpc_dependencies_zlib>
+    <Configuration-grpc_dependencies_openssl>Debug</Configuration-grpc_dependencies_openssl>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)'=='Release'">
+    <TargetName>h2_ssl_hpack_size_test</TargetName>
+    <Linkage-grpc_dependencies_zlib>static</Linkage-grpc_dependencies_zlib>
+    <Configuration-grpc_dependencies_zlib>Debug</Configuration-grpc_dependencies_zlib>
+    <Configuration-grpc_dependencies_openssl>Debug</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;_USE_32BIT_TIME_T;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+    </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>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
+      <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;_USE_32BIT_TIME_T;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+    </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>
+      <WarningLevel>Level3</WarningLevel>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+    </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="..\..\..\..\vsprojects\dummy.c">
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\..\..\..\vsprojects\vcxproj\test\end2end_fixture_h2_ssl\end2end_fixture_h2_ssl.vcxproj">
+      <Project>{207BE5BC-25D7-1D2A-C76E-279DB66A1205}</Project>
+    </ProjectReference>
+    <ProjectReference Include="..\..\..\..\vsprojects\vcxproj\test\end2end_test_hpack_size\end2end_test_hpack_size.vcxproj">
+      <Project>{22A644D5-9A2B-4EF8-7792-AEB0C66A10E5}</Project>
+    </ProjectReference>
+    <ProjectReference Include="..\..\..\..\vsprojects\vcxproj\test\end2end_certs\end2end_certs.vcxproj">
+      <Project>{80EA2691-C037-6DD3-D3AB-21510BF0E64B}</Project>
+    </ProjectReference>
+    <ProjectReference Include="..\..\..\..\vsprojects\vcxproj\.\grpc_test_util\grpc_test_util.vcxproj">
+      <Project>{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}</Project>
+    </ProjectReference>
+    <ProjectReference Include="..\..\..\..\vsprojects\vcxproj\.\grpc\grpc.vcxproj">
+      <Project>{29D16885-7228-4C31-81ED-5F9187C7F2A9}</Project>
+    </ProjectReference>
+    <ProjectReference Include="..\..\..\..\vsprojects\vcxproj\.\gpr_test_util\gpr_test_util.vcxproj">
+      <Project>{EAB0A629-17A9-44DB-B5FF-E91A721FE037}</Project>
+    </ProjectReference>
+    <ProjectReference Include="..\..\..\..\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="..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.9\build\native\grpc.dependencies.zlib.redist.targets" Condition="Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.9\build\native\grpc.dependencies\grpc.dependencies.zlib.targets')" />
+  <Import Project="..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.9\build\native\grpc.dependencies.zlib.targets" Condition="Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.9\build\native\grpc.dependencies\grpc.dependencies.zlib.targets')" />
+  <Import Project="..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.2.3\build\native\grpc.dependencies.openssl.redist.targets" Condition="Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.2.3\build\native\grpc.dependencies\grpc.dependencies.openssl.targets')" />
+  <Import Project="..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\grpc.dependencies.openssl.targets" Condition="Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\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('..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.9\build\native\grpc.dependencies.zlib.redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.9\build\native\grpc.dependencies.zlib.redist.targets')" />
+    <Error Condition="!Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.9\build\native\grpc.dependencies.zlib.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.9\build\native\grpc.dependencies.zlib.targets')" />
+    <Error Condition="!Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.2.3\build\native\grpc.dependencies.openssl.redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.2.3\build\native\grpc.dependencies.openssl.redist.targets')" />
+    <Error Condition="!Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\grpc.dependencies.openssl.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\grpc.dependencies.openssl.props')" />
+    <Error Condition="!Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\grpc.dependencies.openssl.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\grpc.dependencies.openssl.targets')" />
+  </Target>
+</Project>
+
diff --git a/vsprojects/vcxproj/test/h2_ssl_hpack_size_test/h2_ssl_hpack_size_test.vcxproj.filters b/vsprojects/vcxproj/test/h2_ssl_hpack_size_test/h2_ssl_hpack_size_test.vcxproj.filters
new file mode 100644
index 0000000..00e4276
--- /dev/null
+++ b/vsprojects/vcxproj/test/h2_ssl_hpack_size_test/h2_ssl_hpack_size_test.vcxproj.filters
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+
+  <ItemGroup>
+  </ItemGroup>
+</Project>
+
diff --git a/vsprojects/vcxproj/test/h2_uchannel_hpack_size_nosec_test/h2_uchannel_hpack_size_nosec_test.vcxproj b/vsprojects/vcxproj/test/h2_uchannel_hpack_size_nosec_test/h2_uchannel_hpack_size_nosec_test.vcxproj
new file mode 100644
index 0000000..6985300
--- /dev/null
+++ b/vsprojects/vcxproj/test/h2_uchannel_hpack_size_nosec_test/h2_uchannel_hpack_size_nosec_test.vcxproj
@@ -0,0 +1,190 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\grpc.dependencies.openssl.props" Condition="Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\1.0.2.3.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>{EA53DB0D-8BA3-3BCC-10E1-8B5FACB77CA1}</ProjectGuid>
+  </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="'$(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="..\..\..\..\vsprojects\global.props" />
+    <Import Project="..\..\..\..\vsprojects\openssl.props" />
+    <Import Project="..\..\..\..\vsprojects\winsock.props" />
+    <Import Project="..\..\..\..\vsprojects\zlib.props" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup Condition="'$(Configuration)'=='Debug'">
+    <TargetName>h2_uchannel_hpack_size_nosec_test</TargetName>
+    <Linkage-grpc_dependencies_zlib>static</Linkage-grpc_dependencies_zlib>
+    <Configuration-grpc_dependencies_zlib>Debug</Configuration-grpc_dependencies_zlib>
+    <Configuration-grpc_dependencies_openssl>Debug</Configuration-grpc_dependencies_openssl>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)'=='Release'">
+    <TargetName>h2_uchannel_hpack_size_nosec_test</TargetName>
+    <Linkage-grpc_dependencies_zlib>static</Linkage-grpc_dependencies_zlib>
+    <Configuration-grpc_dependencies_zlib>Debug</Configuration-grpc_dependencies_zlib>
+    <Configuration-grpc_dependencies_openssl>Debug</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;_USE_32BIT_TIME_T;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+    </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>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
+      <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;_USE_32BIT_TIME_T;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+    </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>
+      <WarningLevel>Level3</WarningLevel>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+    </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="..\..\..\..\vsprojects\dummy.c">
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\..\..\..\vsprojects\vcxproj\test\end2end_fixture_h2_uchannel\end2end_fixture_h2_uchannel.vcxproj">
+      <Project>{CE17F95F-4FD3-41C3-E1B9-9B85F1FE7D4A}</Project>
+    </ProjectReference>
+    <ProjectReference Include="..\..\..\..\vsprojects\vcxproj\test\end2end_test_hpack_size\end2end_test_hpack_size.vcxproj">
+      <Project>{22A644D5-9A2B-4EF8-7792-AEB0C66A10E5}</Project>
+    </ProjectReference>
+    <ProjectReference Include="..\..\..\..\vsprojects\vcxproj\.\grpc_test_util_unsecure\grpc_test_util_unsecure.vcxproj">
+      <Project>{0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF}</Project>
+    </ProjectReference>
+    <ProjectReference Include="..\..\..\..\vsprojects\vcxproj\.\grpc_unsecure\grpc_unsecure.vcxproj">
+      <Project>{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}</Project>
+    </ProjectReference>
+    <ProjectReference Include="..\..\..\..\vsprojects\vcxproj\.\gpr_test_util\gpr_test_util.vcxproj">
+      <Project>{EAB0A629-17A9-44DB-B5FF-E91A721FE037}</Project>
+    </ProjectReference>
+    <ProjectReference Include="..\..\..\..\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="..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.9\build\native\grpc.dependencies.zlib.redist.targets" Condition="Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.9\build\native\grpc.dependencies\grpc.dependencies.zlib.targets')" />
+  <Import Project="..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.9\build\native\grpc.dependencies.zlib.targets" Condition="Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.9\build\native\grpc.dependencies\grpc.dependencies.zlib.targets')" />
+  <Import Project="..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.2.3\build\native\grpc.dependencies.openssl.redist.targets" Condition="Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.2.3\build\native\grpc.dependencies\grpc.dependencies.openssl.targets')" />
+  <Import Project="..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\grpc.dependencies.openssl.targets" Condition="Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\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('..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.9\build\native\grpc.dependencies.zlib.redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.9\build\native\grpc.dependencies.zlib.redist.targets')" />
+    <Error Condition="!Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.9\build\native\grpc.dependencies.zlib.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.9\build\native\grpc.dependencies.zlib.targets')" />
+    <Error Condition="!Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.2.3\build\native\grpc.dependencies.openssl.redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.2.3\build\native\grpc.dependencies.openssl.redist.targets')" />
+    <Error Condition="!Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\grpc.dependencies.openssl.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\grpc.dependencies.openssl.props')" />
+    <Error Condition="!Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\grpc.dependencies.openssl.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\grpc.dependencies.openssl.targets')" />
+  </Target>
+</Project>
+
diff --git a/vsprojects/vcxproj/test/h2_uchannel_hpack_size_nosec_test/h2_uchannel_hpack_size_nosec_test.vcxproj.filters b/vsprojects/vcxproj/test/h2_uchannel_hpack_size_nosec_test/h2_uchannel_hpack_size_nosec_test.vcxproj.filters
new file mode 100644
index 0000000..00e4276
--- /dev/null
+++ b/vsprojects/vcxproj/test/h2_uchannel_hpack_size_nosec_test/h2_uchannel_hpack_size_nosec_test.vcxproj.filters
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+
+  <ItemGroup>
+  </ItemGroup>
+</Project>
+
diff --git a/vsprojects/vcxproj/test/h2_uchannel_hpack_size_test/h2_uchannel_hpack_size_test.vcxproj b/vsprojects/vcxproj/test/h2_uchannel_hpack_size_test/h2_uchannel_hpack_size_test.vcxproj
new file mode 100644
index 0000000..3b73900
--- /dev/null
+++ b/vsprojects/vcxproj/test/h2_uchannel_hpack_size_test/h2_uchannel_hpack_size_test.vcxproj
@@ -0,0 +1,193 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\grpc.dependencies.openssl.props" Condition="Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\1.0.2.3.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>{9CFB3202-D95F-E541-9A6F-BE561CAFE1AE}</ProjectGuid>
+  </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="'$(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="..\..\..\..\vsprojects\global.props" />
+    <Import Project="..\..\..\..\vsprojects\openssl.props" />
+    <Import Project="..\..\..\..\vsprojects\winsock.props" />
+    <Import Project="..\..\..\..\vsprojects\zlib.props" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup Condition="'$(Configuration)'=='Debug'">
+    <TargetName>h2_uchannel_hpack_size_test</TargetName>
+    <Linkage-grpc_dependencies_zlib>static</Linkage-grpc_dependencies_zlib>
+    <Configuration-grpc_dependencies_zlib>Debug</Configuration-grpc_dependencies_zlib>
+    <Configuration-grpc_dependencies_openssl>Debug</Configuration-grpc_dependencies_openssl>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)'=='Release'">
+    <TargetName>h2_uchannel_hpack_size_test</TargetName>
+    <Linkage-grpc_dependencies_zlib>static</Linkage-grpc_dependencies_zlib>
+    <Configuration-grpc_dependencies_zlib>Debug</Configuration-grpc_dependencies_zlib>
+    <Configuration-grpc_dependencies_openssl>Debug</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;_USE_32BIT_TIME_T;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+    </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>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
+      <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;_USE_32BIT_TIME_T;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+    </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>
+      <WarningLevel>Level3</WarningLevel>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+    </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="..\..\..\..\vsprojects\dummy.c">
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\..\..\..\vsprojects\vcxproj\test\end2end_fixture_h2_uchannel\end2end_fixture_h2_uchannel.vcxproj">
+      <Project>{CE17F95F-4FD3-41C3-E1B9-9B85F1FE7D4A}</Project>
+    </ProjectReference>
+    <ProjectReference Include="..\..\..\..\vsprojects\vcxproj\test\end2end_test_hpack_size\end2end_test_hpack_size.vcxproj">
+      <Project>{22A644D5-9A2B-4EF8-7792-AEB0C66A10E5}</Project>
+    </ProjectReference>
+    <ProjectReference Include="..\..\..\..\vsprojects\vcxproj\test\end2end_certs\end2end_certs.vcxproj">
+      <Project>{80EA2691-C037-6DD3-D3AB-21510BF0E64B}</Project>
+    </ProjectReference>
+    <ProjectReference Include="..\..\..\..\vsprojects\vcxproj\.\grpc_test_util\grpc_test_util.vcxproj">
+      <Project>{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}</Project>
+    </ProjectReference>
+    <ProjectReference Include="..\..\..\..\vsprojects\vcxproj\.\grpc\grpc.vcxproj">
+      <Project>{29D16885-7228-4C31-81ED-5F9187C7F2A9}</Project>
+    </ProjectReference>
+    <ProjectReference Include="..\..\..\..\vsprojects\vcxproj\.\gpr_test_util\gpr_test_util.vcxproj">
+      <Project>{EAB0A629-17A9-44DB-B5FF-E91A721FE037}</Project>
+    </ProjectReference>
+    <ProjectReference Include="..\..\..\..\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="..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.9\build\native\grpc.dependencies.zlib.redist.targets" Condition="Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.9\build\native\grpc.dependencies\grpc.dependencies.zlib.targets')" />
+  <Import Project="..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.9\build\native\grpc.dependencies.zlib.targets" Condition="Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.9\build\native\grpc.dependencies\grpc.dependencies.zlib.targets')" />
+  <Import Project="..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.2.3\build\native\grpc.dependencies.openssl.redist.targets" Condition="Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.2.3\build\native\grpc.dependencies\grpc.dependencies.openssl.targets')" />
+  <Import Project="..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\grpc.dependencies.openssl.targets" Condition="Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\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('..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.9\build\native\grpc.dependencies.zlib.redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.9\build\native\grpc.dependencies.zlib.redist.targets')" />
+    <Error Condition="!Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.9\build\native\grpc.dependencies.zlib.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.9\build\native\grpc.dependencies.zlib.targets')" />
+    <Error Condition="!Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.2.3\build\native\grpc.dependencies.openssl.redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.2.3\build\native\grpc.dependencies.openssl.redist.targets')" />
+    <Error Condition="!Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\grpc.dependencies.openssl.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\grpc.dependencies.openssl.props')" />
+    <Error Condition="!Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\grpc.dependencies.openssl.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\grpc.dependencies.openssl.targets')" />
+  </Target>
+</Project>
+
diff --git a/vsprojects/vcxproj/test/h2_uchannel_hpack_size_test/h2_uchannel_hpack_size_test.vcxproj.filters b/vsprojects/vcxproj/test/h2_uchannel_hpack_size_test/h2_uchannel_hpack_size_test.vcxproj.filters
new file mode 100644
index 0000000..00e4276
--- /dev/null
+++ b/vsprojects/vcxproj/test/h2_uchannel_hpack_size_test/h2_uchannel_hpack_size_test.vcxproj.filters
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+
+  <ItemGroup>
+  </ItemGroup>
+</Project>
+
diff --git a/vsprojects/vcxproj/test/metrics_client/metrics_client.vcxproj b/vsprojects/vcxproj/test/metrics_client/metrics_client.vcxproj
new file mode 100644
index 0000000..11a3e36
--- /dev/null
+++ b/vsprojects/vcxproj/test/metrics_client/metrics_client.vcxproj
@@ -0,0 +1,197 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\grpc.dependencies.openssl.props" Condition="Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\1.0.2.3.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>{FE8631BA-DF40-EC70-6078-C2DAF316E329}</ProjectGuid>
+  </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="'$(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="..\..\..\..\vsprojects\cpptest.props" />
+    <Import Project="..\..\..\..\vsprojects\global.props" />
+    <Import Project="..\..\..\..\vsprojects\openssl.props" />
+    <Import Project="..\..\..\..\vsprojects\protobuf.props" />
+    <Import Project="..\..\..\..\vsprojects\winsock.props" />
+    <Import Project="..\..\..\..\vsprojects\zlib.props" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup Condition="'$(Configuration)'=='Debug'">
+    <TargetName>metrics_client</TargetName>
+    <Linkage-grpc_dependencies_zlib>static</Linkage-grpc_dependencies_zlib>
+    <Configuration-grpc_dependencies_zlib>Debug</Configuration-grpc_dependencies_zlib>
+    <Configuration-grpc_dependencies_openssl>Debug</Configuration-grpc_dependencies_openssl>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)'=='Release'">
+    <TargetName>metrics_client</TargetName>
+    <Linkage-grpc_dependencies_zlib>static</Linkage-grpc_dependencies_zlib>
+    <Configuration-grpc_dependencies_zlib>Debug</Configuration-grpc_dependencies_zlib>
+    <Configuration-grpc_dependencies_openssl>Debug</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;_USE_32BIT_TIME_T;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+    </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>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
+      <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <WarningLevel>Level3</WarningLevel>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;_USE_32BIT_TIME_T;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+    </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>
+      <WarningLevel>Level3</WarningLevel>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
+      <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <ClInclude Include="..\..\..\..\test\cpp\util\metrics_server.h" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="..\..\..\..\test\proto\metrics.pb.cc">
+    </ClCompile>
+    <ClInclude Include="..\..\..\..\test\proto\metrics.pb.h">
+    </ClInclude>
+    <ClCompile Include="..\..\..\..\test\proto\metrics.grpc.pb.cc">
+    </ClCompile>
+    <ClInclude Include="..\..\..\..\test\proto\metrics.grpc.pb.h">
+    </ClInclude>
+    <ClCompile Include="..\..\..\..\test\cpp\interop\metrics_client.cc">
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\..\..\..\vsprojects\vcxproj\.\grpc++\grpc++.vcxproj">
+      <Project>{C187A093-A0FE-489D-A40A-6E33DE0F9FEB}</Project>
+    </ProjectReference>
+    <ProjectReference Include="..\..\..\..\vsprojects\vcxproj\.\grpc\grpc.vcxproj">
+      <Project>{29D16885-7228-4C31-81ED-5F9187C7F2A9}</Project>
+    </ProjectReference>
+    <ProjectReference Include="..\..\..\..\vsprojects\vcxproj\.\gpr\gpr.vcxproj">
+      <Project>{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}</Project>
+    </ProjectReference>
+    <ProjectReference Include="..\..\..\..\vsprojects\vcxproj\.\grpc++_test_config\grpc++_test_config.vcxproj">
+      <Project>{3F7D093D-11F9-C4BC-BEB7-18EB28E3F290}</Project>
+    </ProjectReference>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="packages.config" />
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  <Import Project="..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.9\build\native\grpc.dependencies.zlib.redist.targets" Condition="Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.9\build\native\grpc.dependencies\grpc.dependencies.zlib.targets')" />
+  <Import Project="..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.9\build\native\grpc.dependencies.zlib.targets" Condition="Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.9\build\native\grpc.dependencies\grpc.dependencies.zlib.targets')" />
+  <Import Project="..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.2.3\build\native\grpc.dependencies.openssl.redist.targets" Condition="Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.2.3\build\native\grpc.dependencies\grpc.dependencies.openssl.targets')" />
+  <Import Project="..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\grpc.dependencies.openssl.targets" Condition="Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\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('..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.9\build\native\grpc.dependencies.zlib.redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.9\build\native\grpc.dependencies.zlib.redist.targets')" />
+    <Error Condition="!Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.9\build\native\grpc.dependencies.zlib.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.9\build\native\grpc.dependencies.zlib.targets')" />
+    <Error Condition="!Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.2.3\build\native\grpc.dependencies.openssl.redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.2.3\build\native\grpc.dependencies.openssl.redist.targets')" />
+    <Error Condition="!Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\grpc.dependencies.openssl.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\grpc.dependencies.openssl.props')" />
+    <Error Condition="!Exists('..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\grpc.dependencies.openssl.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\vsprojects\packages\grpc.dependencies.openssl.1.0.2.3\build\native\grpc.dependencies.openssl.targets')" />
+  </Target>
+</Project>
+
diff --git a/vsprojects/vcxproj/test/metrics_client/metrics_client.vcxproj.filters b/vsprojects/vcxproj/test/metrics_client/metrics_client.vcxproj.filters
new file mode 100644
index 0000000..73aaaa2
--- /dev/null
+++ b/vsprojects/vcxproj/test/metrics_client/metrics_client.vcxproj.filters
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <ClCompile Include="..\..\..\..\test\proto\metrics.proto">
+      <Filter>test\proto</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\..\test\cpp\interop\metrics_client.cc">
+      <Filter>test\cpp\interop</Filter>
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="..\..\..\..\test\cpp\util\metrics_server.h">
+      <Filter>test\cpp\util</Filter>
+    </ClInclude>
+  </ItemGroup>
+
+  <ItemGroup>
+    <Filter Include="test">
+      <UniqueIdentifier>{2c00b6b1-865c-55b2-0d9d-8d7b42ad7d03}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="test\cpp">
+      <UniqueIdentifier>{a62a5921-b3d4-6069-e9cc-73f34609c99b}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="test\cpp\interop">
+      <UniqueIdentifier>{fbd5c6ac-f3a9-1b16-6310-c205aadc9075}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="test\cpp\util">
+      <UniqueIdentifier>{16f4e45d-a509-3e4d-4a19-9383576bec54}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="test\proto">
+      <UniqueIdentifier>{c638ed75-9aa0-ccc3-a8d2-a1a6203977b1}</UniqueIdentifier>
+    </Filter>
+  </ItemGroup>
+</Project>
+
diff --git a/vsprojects/vcxproj/test/stress_test/stress_test.vcxproj b/vsprojects/vcxproj/test/stress_test/stress_test.vcxproj
index a385a6d..d449b62 100644
--- a/vsprojects/vcxproj/test/stress_test/stress_test.vcxproj
+++ b/vsprojects/vcxproj/test/stress_test/stress_test.vcxproj
@@ -148,6 +148,7 @@
     <ClInclude Include="..\..\..\..\test\cpp\interop\client_helper.h" />
     <ClInclude Include="..\..\..\..\test\cpp\interop\interop_client.h" />
     <ClInclude Include="..\..\..\..\test\cpp\interop\stress_interop_client.h" />
+    <ClInclude Include="..\..\..\..\test\cpp\util\metrics_server.h" />
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="..\..\..\..\test\proto\empty.pb.cc">
@@ -166,6 +167,14 @@
     </ClCompile>
     <ClInclude Include="..\..\..\..\test\proto\messages.grpc.pb.h">
     </ClInclude>
+    <ClCompile Include="..\..\..\..\test\proto\metrics.pb.cc">
+    </ClCompile>
+    <ClInclude Include="..\..\..\..\test\proto\metrics.pb.h">
+    </ClInclude>
+    <ClCompile Include="..\..\..\..\test\proto\metrics.grpc.pb.cc">
+    </ClCompile>
+    <ClInclude Include="..\..\..\..\test\proto\metrics.grpc.pb.h">
+    </ClInclude>
     <ClCompile Include="..\..\..\..\test\proto\test.pb.cc">
     </ClCompile>
     <ClInclude Include="..\..\..\..\test\proto\test.pb.h">
@@ -180,6 +189,8 @@
     </ClCompile>
     <ClCompile Include="..\..\..\..\test\cpp\interop\stress_test.cc">
     </ClCompile>
+    <ClCompile Include="..\..\..\..\test\cpp\util\metrics_server.cc">
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ProjectReference Include="..\..\..\..\vsprojects\vcxproj\.\grpc++_test_util\grpc++_test_util.vcxproj">
diff --git a/vsprojects/vcxproj/test/stress_test/stress_test.vcxproj.filters b/vsprojects/vcxproj/test/stress_test/stress_test.vcxproj.filters
index 839493a..b20bd35 100644
--- a/vsprojects/vcxproj/test/stress_test/stress_test.vcxproj.filters
+++ b/vsprojects/vcxproj/test/stress_test/stress_test.vcxproj.filters
@@ -7,6 +7,9 @@
     <ClCompile Include="..\..\..\..\test\proto\messages.proto">
       <Filter>test\proto</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\..\..\test\proto\metrics.proto">
+      <Filter>test\proto</Filter>
+    </ClCompile>
     <ClCompile Include="..\..\..\..\test\proto\test.proto">
       <Filter>test\proto</Filter>
     </ClCompile>
@@ -19,6 +22,9 @@
     <ClCompile Include="..\..\..\..\test\cpp\interop\stress_test.cc">
       <Filter>test\cpp\interop</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\..\..\test\cpp\util\metrics_server.cc">
+      <Filter>test\cpp\util</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="..\..\..\..\test\cpp\interop\client_helper.h">
@@ -30,6 +36,9 @@
     <ClInclude Include="..\..\..\..\test\cpp\interop\stress_interop_client.h">
       <Filter>test\cpp\interop</Filter>
     </ClInclude>
+    <ClInclude Include="..\..\..\..\test\cpp\util\metrics_server.h">
+      <Filter>test\cpp\util</Filter>
+    </ClInclude>
   </ItemGroup>
 
   <ItemGroup>
@@ -42,6 +51,9 @@
     <Filter Include="test\cpp\interop">
       <UniqueIdentifier>{7afcf5a8-556a-6be3-15d4-b00b2518f8fb}</UniqueIdentifier>
     </Filter>
+    <Filter Include="test\cpp\util">
+      <UniqueIdentifier>{e4704307-621e-0e9c-08c2-3c698c1b827f}</UniqueIdentifier>
+    </Filter>
     <Filter Include="test\proto">
       <UniqueIdentifier>{7172a335-47bf-8284-380d-a28a05c07311}</UniqueIdentifier>
     </Filter>