diff --git a/Makefile b/Makefile
index 829241b9d5b731e8e57fa57450bdafe1be32693c..2183beb0bf7259711c5073b577a81b8eb6320d22 100644
--- a/Makefile
+++ b/Makefile
@@ -253,6 +253,7 @@ stop:
 gen_hpack_tables: bins/$(CONFIG)/gen_hpack_tables
 cpp_plugin: bins/$(CONFIG)/cpp_plugin
 ruby_plugin: bins/$(CONFIG)/ruby_plugin
+go_plugin: bins/$(CONFIG)/go_plugin
 grpc_byte_buffer_reader_test: bins/$(CONFIG)/grpc_byte_buffer_reader_test
 gpr_cancellable_test: bins/$(CONFIG)/gpr_cancellable_test
 gpr_log_test: bins/$(CONFIG)/gpr_log_test
@@ -288,6 +289,8 @@ grpc_channel_stack_test: bins/$(CONFIG)/grpc_channel_stack_test
 metadata_buffer_test: bins/$(CONFIG)/metadata_buffer_test
 grpc_completion_queue_test: bins/$(CONFIG)/grpc_completion_queue_test
 grpc_completion_queue_benchmark: bins/$(CONFIG)/grpc_completion_queue_benchmark
+census_trace_store_test: bins/$(CONFIG)/census_trace_store_test
+census_stats_store_test: bins/$(CONFIG)/census_stats_store_test
 census_window_stats_test: bins/$(CONFIG)/census_window_stats_test
 census_statistics_quick_test: bins/$(CONFIG)/census_statistics_quick_test
 census_statistics_small_log_test: bins/$(CONFIG)/census_statistics_small_log_test
@@ -326,6 +329,7 @@ interop_server: bins/$(CONFIG)/interop_server
 interop_client: bins/$(CONFIG)/interop_client
 end2end_test: bins/$(CONFIG)/end2end_test
 channel_arguments_test: bins/$(CONFIG)/channel_arguments_test
+credentials_test: bins/$(CONFIG)/credentials_test
 alarm_test: bins/$(CONFIG)/alarm_test
 alarm_list_test: bins/$(CONFIG)/alarm_list_test
 alarm_heap_test: bins/$(CONFIG)/alarm_heap_test
@@ -335,6 +339,7 @@ chttp2_fake_security_cancel_after_accept_and_writes_closed_test: bins/$(CONFIG)/
 chttp2_fake_security_cancel_after_invoke_test: bins/$(CONFIG)/chttp2_fake_security_cancel_after_invoke_test
 chttp2_fake_security_cancel_before_invoke_test: bins/$(CONFIG)/chttp2_fake_security_cancel_before_invoke_test
 chttp2_fake_security_cancel_in_a_vacuum_test: bins/$(CONFIG)/chttp2_fake_security_cancel_in_a_vacuum_test
+chttp2_fake_security_census_simple_request_test: bins/$(CONFIG)/chttp2_fake_security_census_simple_request_test
 chttp2_fake_security_disappearing_server_test: bins/$(CONFIG)/chttp2_fake_security_disappearing_server_test
 chttp2_fake_security_early_server_shutdown_finishes_inflight_calls_test: bins/$(CONFIG)/chttp2_fake_security_early_server_shutdown_finishes_inflight_calls_test
 chttp2_fake_security_early_server_shutdown_finishes_tags_test: bins/$(CONFIG)/chttp2_fake_security_early_server_shutdown_finishes_tags_test
@@ -355,6 +360,7 @@ chttp2_fullstack_cancel_after_accept_and_writes_closed_test: bins/$(CONFIG)/chtt
 chttp2_fullstack_cancel_after_invoke_test: bins/$(CONFIG)/chttp2_fullstack_cancel_after_invoke_test
 chttp2_fullstack_cancel_before_invoke_test: bins/$(CONFIG)/chttp2_fullstack_cancel_before_invoke_test
 chttp2_fullstack_cancel_in_a_vacuum_test: bins/$(CONFIG)/chttp2_fullstack_cancel_in_a_vacuum_test
+chttp2_fullstack_census_simple_request_test: bins/$(CONFIG)/chttp2_fullstack_census_simple_request_test
 chttp2_fullstack_disappearing_server_test: bins/$(CONFIG)/chttp2_fullstack_disappearing_server_test
 chttp2_fullstack_early_server_shutdown_finishes_inflight_calls_test: bins/$(CONFIG)/chttp2_fullstack_early_server_shutdown_finishes_inflight_calls_test
 chttp2_fullstack_early_server_shutdown_finishes_tags_test: bins/$(CONFIG)/chttp2_fullstack_early_server_shutdown_finishes_tags_test
@@ -375,6 +381,7 @@ chttp2_simple_ssl_fullstack_cancel_after_accept_and_writes_closed_test: bins/$(C
 chttp2_simple_ssl_fullstack_cancel_after_invoke_test: bins/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_after_invoke_test
 chttp2_simple_ssl_fullstack_cancel_before_invoke_test: bins/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_before_invoke_test
 chttp2_simple_ssl_fullstack_cancel_in_a_vacuum_test: bins/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_in_a_vacuum_test
+chttp2_simple_ssl_fullstack_census_simple_request_test: bins/$(CONFIG)/chttp2_simple_ssl_fullstack_census_simple_request_test
 chttp2_simple_ssl_fullstack_disappearing_server_test: bins/$(CONFIG)/chttp2_simple_ssl_fullstack_disappearing_server_test
 chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_inflight_calls_test: bins/$(CONFIG)/chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_inflight_calls_test
 chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_tags_test: bins/$(CONFIG)/chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_tags_test
@@ -395,6 +402,7 @@ chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_accept_and_writes_closed_te
 chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_invoke_test: bins/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_invoke_test
 chttp2_simple_ssl_with_oauth2_fullstack_cancel_before_invoke_test: bins/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_before_invoke_test
 chttp2_simple_ssl_with_oauth2_fullstack_cancel_in_a_vacuum_test: bins/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_in_a_vacuum_test
+chttp2_simple_ssl_with_oauth2_fullstack_census_simple_request_test: bins/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_census_simple_request_test
 chttp2_simple_ssl_with_oauth2_fullstack_disappearing_server_test: bins/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_disappearing_server_test
 chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_inflight_calls_test: bins/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_inflight_calls_test
 chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_tags_test: bins/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_tags_test
@@ -415,6 +423,7 @@ chttp2_socket_pair_cancel_after_accept_and_writes_closed_test: bins/$(CONFIG)/ch
 chttp2_socket_pair_cancel_after_invoke_test: bins/$(CONFIG)/chttp2_socket_pair_cancel_after_invoke_test
 chttp2_socket_pair_cancel_before_invoke_test: bins/$(CONFIG)/chttp2_socket_pair_cancel_before_invoke_test
 chttp2_socket_pair_cancel_in_a_vacuum_test: bins/$(CONFIG)/chttp2_socket_pair_cancel_in_a_vacuum_test
+chttp2_socket_pair_census_simple_request_test: bins/$(CONFIG)/chttp2_socket_pair_census_simple_request_test
 chttp2_socket_pair_disappearing_server_test: bins/$(CONFIG)/chttp2_socket_pair_disappearing_server_test
 chttp2_socket_pair_early_server_shutdown_finishes_inflight_calls_test: bins/$(CONFIG)/chttp2_socket_pair_early_server_shutdown_finishes_inflight_calls_test
 chttp2_socket_pair_early_server_shutdown_finishes_tags_test: bins/$(CONFIG)/chttp2_socket_pair_early_server_shutdown_finishes_tags_test
@@ -435,6 +444,7 @@ chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_and_writes_closed_test
 chttp2_socket_pair_one_byte_at_a_time_cancel_after_invoke_test: bins/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_after_invoke_test
 chttp2_socket_pair_one_byte_at_a_time_cancel_before_invoke_test: bins/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_before_invoke_test
 chttp2_socket_pair_one_byte_at_a_time_cancel_in_a_vacuum_test: bins/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_in_a_vacuum_test
+chttp2_socket_pair_one_byte_at_a_time_census_simple_request_test: bins/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_census_simple_request_test
 chttp2_socket_pair_one_byte_at_a_time_disappearing_server_test: bins/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_disappearing_server_test
 chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_inflight_calls_test: bins/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_inflight_calls_test
 chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_tags_test: bins/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_tags_test
@@ -477,15 +487,15 @@ shared_cxx: dep_cxx libs/$(CONFIG)/libgrpc++.$(SHARED_EXT)
 
 privatelibs: privatelibs_c privatelibs_cxx
 
-privatelibs_c: dep_c libs/$(CONFIG)/libgrpc_test_util.a libs/$(CONFIG)/libend2end_fixture_chttp2_fake_security.a libs/$(CONFIG)/libend2end_fixture_chttp2_fullstack.a libs/$(CONFIG)/libend2end_fixture_chttp2_simple_ssl_fullstack.a libs/$(CONFIG)/libend2end_fixture_chttp2_simple_ssl_with_oauth2_fullstack.a libs/$(CONFIG)/libend2end_fixture_chttp2_socket_pair.a libs/$(CONFIG)/libend2end_fixture_chttp2_socket_pair_one_byte_at_a_time.a libs/$(CONFIG)/libend2end_test_cancel_after_accept.a libs/$(CONFIG)/libend2end_test_cancel_after_accept_and_writes_closed.a libs/$(CONFIG)/libend2end_test_cancel_after_invoke.a libs/$(CONFIG)/libend2end_test_cancel_before_invoke.a libs/$(CONFIG)/libend2end_test_cancel_in_a_vacuum.a libs/$(CONFIG)/libend2end_test_disappearing_server.a libs/$(CONFIG)/libend2end_test_early_server_shutdown_finishes_inflight_calls.a libs/$(CONFIG)/libend2end_test_early_server_shutdown_finishes_tags.a libs/$(CONFIG)/libend2end_test_invoke_large_request.a libs/$(CONFIG)/libend2end_test_max_concurrent_streams.a libs/$(CONFIG)/libend2end_test_no_op.a libs/$(CONFIG)/libend2end_test_ping_pong_streaming.a libs/$(CONFIG)/libend2end_test_request_response_with_binary_metadata_and_payload.a libs/$(CONFIG)/libend2end_test_request_response_with_metadata_and_payload.a libs/$(CONFIG)/libend2end_test_request_response_with_payload.a libs/$(CONFIG)/libend2end_test_request_response_with_trailing_metadata_and_payload.a libs/$(CONFIG)/libend2end_test_simple_delayed_request.a libs/$(CONFIG)/libend2end_test_simple_request.a libs/$(CONFIG)/libend2end_test_thread_stress.a libs/$(CONFIG)/libend2end_test_writes_done_hangs_with_pending_read.a libs/$(CONFIG)/libend2end_certs.a
+privatelibs_c: dep_c libs/$(CONFIG)/libgrpc_test_util.a libs/$(CONFIG)/libend2end_fixture_chttp2_fake_security.a libs/$(CONFIG)/libend2end_fixture_chttp2_fullstack.a libs/$(CONFIG)/libend2end_fixture_chttp2_simple_ssl_fullstack.a libs/$(CONFIG)/libend2end_fixture_chttp2_simple_ssl_with_oauth2_fullstack.a libs/$(CONFIG)/libend2end_fixture_chttp2_socket_pair.a libs/$(CONFIG)/libend2end_fixture_chttp2_socket_pair_one_byte_at_a_time.a libs/$(CONFIG)/libend2end_test_cancel_after_accept.a libs/$(CONFIG)/libend2end_test_cancel_after_accept_and_writes_closed.a libs/$(CONFIG)/libend2end_test_cancel_after_invoke.a libs/$(CONFIG)/libend2end_test_cancel_before_invoke.a libs/$(CONFIG)/libend2end_test_cancel_in_a_vacuum.a libs/$(CONFIG)/libend2end_test_census_simple_request.a libs/$(CONFIG)/libend2end_test_disappearing_server.a libs/$(CONFIG)/libend2end_test_early_server_shutdown_finishes_inflight_calls.a libs/$(CONFIG)/libend2end_test_early_server_shutdown_finishes_tags.a libs/$(CONFIG)/libend2end_test_invoke_large_request.a libs/$(CONFIG)/libend2end_test_max_concurrent_streams.a libs/$(CONFIG)/libend2end_test_no_op.a libs/$(CONFIG)/libend2end_test_ping_pong_streaming.a libs/$(CONFIG)/libend2end_test_request_response_with_binary_metadata_and_payload.a libs/$(CONFIG)/libend2end_test_request_response_with_metadata_and_payload.a libs/$(CONFIG)/libend2end_test_request_response_with_payload.a libs/$(CONFIG)/libend2end_test_request_response_with_trailing_metadata_and_payload.a libs/$(CONFIG)/libend2end_test_simple_delayed_request.a libs/$(CONFIG)/libend2end_test_simple_request.a libs/$(CONFIG)/libend2end_test_thread_stress.a libs/$(CONFIG)/libend2end_test_writes_done_hangs_with_pending_read.a libs/$(CONFIG)/libend2end_certs.a
 
-privatelibs_cxx: dep_cxx libs/$(CONFIG)/libgrpc_test_util.a libs/$(CONFIG)/libend2end_fixture_chttp2_fake_security.a libs/$(CONFIG)/libend2end_fixture_chttp2_fullstack.a libs/$(CONFIG)/libend2end_fixture_chttp2_simple_ssl_fullstack.a libs/$(CONFIG)/libend2end_fixture_chttp2_simple_ssl_with_oauth2_fullstack.a libs/$(CONFIG)/libend2end_fixture_chttp2_socket_pair.a libs/$(CONFIG)/libend2end_fixture_chttp2_socket_pair_one_byte_at_a_time.a libs/$(CONFIG)/libend2end_test_cancel_after_accept.a libs/$(CONFIG)/libend2end_test_cancel_after_accept_and_writes_closed.a libs/$(CONFIG)/libend2end_test_cancel_after_invoke.a libs/$(CONFIG)/libend2end_test_cancel_before_invoke.a libs/$(CONFIG)/libend2end_test_cancel_in_a_vacuum.a libs/$(CONFIG)/libend2end_test_disappearing_server.a libs/$(CONFIG)/libend2end_test_early_server_shutdown_finishes_inflight_calls.a libs/$(CONFIG)/libend2end_test_early_server_shutdown_finishes_tags.a libs/$(CONFIG)/libend2end_test_invoke_large_request.a libs/$(CONFIG)/libend2end_test_max_concurrent_streams.a libs/$(CONFIG)/libend2end_test_no_op.a libs/$(CONFIG)/libend2end_test_ping_pong_streaming.a libs/$(CONFIG)/libend2end_test_request_response_with_binary_metadata_and_payload.a libs/$(CONFIG)/libend2end_test_request_response_with_metadata_and_payload.a libs/$(CONFIG)/libend2end_test_request_response_with_payload.a libs/$(CONFIG)/libend2end_test_request_response_with_trailing_metadata_and_payload.a libs/$(CONFIG)/libend2end_test_simple_delayed_request.a libs/$(CONFIG)/libend2end_test_simple_request.a libs/$(CONFIG)/libend2end_test_thread_stress.a libs/$(CONFIG)/libend2end_test_writes_done_hangs_with_pending_read.a libs/$(CONFIG)/libend2end_certs.a
+privatelibs_cxx: dep_cxx libs/$(CONFIG)/libgrpc_test_util.a libs/$(CONFIG)/libend2end_fixture_chttp2_fake_security.a libs/$(CONFIG)/libend2end_fixture_chttp2_fullstack.a libs/$(CONFIG)/libend2end_fixture_chttp2_simple_ssl_fullstack.a libs/$(CONFIG)/libend2end_fixture_chttp2_simple_ssl_with_oauth2_fullstack.a libs/$(CONFIG)/libend2end_fixture_chttp2_socket_pair.a libs/$(CONFIG)/libend2end_fixture_chttp2_socket_pair_one_byte_at_a_time.a libs/$(CONFIG)/libend2end_test_cancel_after_accept.a libs/$(CONFIG)/libend2end_test_cancel_after_accept_and_writes_closed.a libs/$(CONFIG)/libend2end_test_cancel_after_invoke.a libs/$(CONFIG)/libend2end_test_cancel_before_invoke.a libs/$(CONFIG)/libend2end_test_cancel_in_a_vacuum.a libs/$(CONFIG)/libend2end_test_census_simple_request.a libs/$(CONFIG)/libend2end_test_disappearing_server.a libs/$(CONFIG)/libend2end_test_early_server_shutdown_finishes_inflight_calls.a libs/$(CONFIG)/libend2end_test_early_server_shutdown_finishes_tags.a libs/$(CONFIG)/libend2end_test_invoke_large_request.a libs/$(CONFIG)/libend2end_test_max_concurrent_streams.a libs/$(CONFIG)/libend2end_test_no_op.a libs/$(CONFIG)/libend2end_test_ping_pong_streaming.a libs/$(CONFIG)/libend2end_test_request_response_with_binary_metadata_and_payload.a libs/$(CONFIG)/libend2end_test_request_response_with_metadata_and_payload.a libs/$(CONFIG)/libend2end_test_request_response_with_payload.a libs/$(CONFIG)/libend2end_test_request_response_with_trailing_metadata_and_payload.a libs/$(CONFIG)/libend2end_test_simple_delayed_request.a libs/$(CONFIG)/libend2end_test_simple_request.a libs/$(CONFIG)/libend2end_test_thread_stress.a libs/$(CONFIG)/libend2end_test_writes_done_hangs_with_pending_read.a libs/$(CONFIG)/libend2end_certs.a
 
 buildtests: buildtests_c buildtests_cxx
 
-buildtests_c: bins_dep_c privatelibs_c bins/$(CONFIG)/grpc_byte_buffer_reader_test bins/$(CONFIG)/gpr_cancellable_test bins/$(CONFIG)/gpr_log_test bins/$(CONFIG)/gpr_useful_test bins/$(CONFIG)/gpr_cmdline_test bins/$(CONFIG)/gpr_histogram_test bins/$(CONFIG)/gpr_host_port_test bins/$(CONFIG)/gpr_slice_buffer_test bins/$(CONFIG)/gpr_slice_test bins/$(CONFIG)/gpr_string_test bins/$(CONFIG)/gpr_sync_test bins/$(CONFIG)/gpr_thd_test bins/$(CONFIG)/gpr_time_test bins/$(CONFIG)/murmur_hash_test bins/$(CONFIG)/grpc_stream_op_test bins/$(CONFIG)/alpn_test bins/$(CONFIG)/time_averaged_stats_test bins/$(CONFIG)/chttp2_stream_encoder_test bins/$(CONFIG)/hpack_table_test bins/$(CONFIG)/chttp2_stream_map_test bins/$(CONFIG)/hpack_parser_test bins/$(CONFIG)/transport_metadata_test bins/$(CONFIG)/chttp2_status_conversion_test bins/$(CONFIG)/chttp2_transport_end2end_test bins/$(CONFIG)/tcp_posix_test bins/$(CONFIG)/dualstack_socket_test bins/$(CONFIG)/no_server_test bins/$(CONFIG)/resolve_address_test bins/$(CONFIG)/sockaddr_utils_test bins/$(CONFIG)/tcp_server_posix_test bins/$(CONFIG)/tcp_client_posix_test bins/$(CONFIG)/grpc_channel_stack_test bins/$(CONFIG)/metadata_buffer_test bins/$(CONFIG)/grpc_completion_queue_test bins/$(CONFIG)/census_window_stats_test bins/$(CONFIG)/census_statistics_quick_test bins/$(CONFIG)/census_statistics_small_log_test bins/$(CONFIG)/census_statistics_performance_test bins/$(CONFIG)/census_statistics_multiple_writers_test bins/$(CONFIG)/census_statistics_multiple_writers_circular_buffer_test bins/$(CONFIG)/census_stub_test bins/$(CONFIG)/census_hash_table_test bins/$(CONFIG)/fling_server bins/$(CONFIG)/fling_client bins/$(CONFIG)/fling_test bins/$(CONFIG)/echo_server bins/$(CONFIG)/echo_client bins/$(CONFIG)/echo_test bins/$(CONFIG)/message_compress_test bins/$(CONFIG)/bin_encoder_test bins/$(CONFIG)/secure_endpoint_test bins/$(CONFIG)/httpcli_format_request_test bins/$(CONFIG)/httpcli_parser_test bins/$(CONFIG)/httpcli_test bins/$(CONFIG)/grpc_credentials_test bins/$(CONFIG)/grpc_base64_test bins/$(CONFIG)/grpc_json_token_test bins/$(CONFIG)/timeout_encoding_test bins/$(CONFIG)/fd_posix_test bins/$(CONFIG)/fling_stream_test bins/$(CONFIG)/lame_client_test bins/$(CONFIG)/alarm_test bins/$(CONFIG)/alarm_list_test bins/$(CONFIG)/alarm_heap_test bins/$(CONFIG)/time_test bins/$(CONFIG)/chttp2_fake_security_cancel_after_accept_test bins/$(CONFIG)/chttp2_fake_security_cancel_after_accept_and_writes_closed_test bins/$(CONFIG)/chttp2_fake_security_cancel_after_invoke_test bins/$(CONFIG)/chttp2_fake_security_cancel_before_invoke_test bins/$(CONFIG)/chttp2_fake_security_cancel_in_a_vacuum_test bins/$(CONFIG)/chttp2_fake_security_disappearing_server_test bins/$(CONFIG)/chttp2_fake_security_early_server_shutdown_finishes_inflight_calls_test bins/$(CONFIG)/chttp2_fake_security_early_server_shutdown_finishes_tags_test bins/$(CONFIG)/chttp2_fake_security_invoke_large_request_test bins/$(CONFIG)/chttp2_fake_security_max_concurrent_streams_test bins/$(CONFIG)/chttp2_fake_security_no_op_test bins/$(CONFIG)/chttp2_fake_security_ping_pong_streaming_test bins/$(CONFIG)/chttp2_fake_security_request_response_with_binary_metadata_and_payload_test bins/$(CONFIG)/chttp2_fake_security_request_response_with_metadata_and_payload_test bins/$(CONFIG)/chttp2_fake_security_request_response_with_payload_test bins/$(CONFIG)/chttp2_fake_security_request_response_with_trailing_metadata_and_payload_test bins/$(CONFIG)/chttp2_fake_security_simple_delayed_request_test bins/$(CONFIG)/chttp2_fake_security_simple_request_test bins/$(CONFIG)/chttp2_fake_security_thread_stress_test bins/$(CONFIG)/chttp2_fake_security_writes_done_hangs_with_pending_read_test bins/$(CONFIG)/chttp2_fullstack_cancel_after_accept_test bins/$(CONFIG)/chttp2_fullstack_cancel_after_accept_and_writes_closed_test bins/$(CONFIG)/chttp2_fullstack_cancel_after_invoke_test bins/$(CONFIG)/chttp2_fullstack_cancel_before_invoke_test bins/$(CONFIG)/chttp2_fullstack_cancel_in_a_vacuum_test bins/$(CONFIG)/chttp2_fullstack_disappearing_server_test bins/$(CONFIG)/chttp2_fullstack_early_server_shutdown_finishes_inflight_calls_test bins/$(CONFIG)/chttp2_fullstack_early_server_shutdown_finishes_tags_test bins/$(CONFIG)/chttp2_fullstack_invoke_large_request_test bins/$(CONFIG)/chttp2_fullstack_max_concurrent_streams_test bins/$(CONFIG)/chttp2_fullstack_no_op_test bins/$(CONFIG)/chttp2_fullstack_ping_pong_streaming_test bins/$(CONFIG)/chttp2_fullstack_request_response_with_binary_metadata_and_payload_test bins/$(CONFIG)/chttp2_fullstack_request_response_with_metadata_and_payload_test bins/$(CONFIG)/chttp2_fullstack_request_response_with_payload_test bins/$(CONFIG)/chttp2_fullstack_request_response_with_trailing_metadata_and_payload_test bins/$(CONFIG)/chttp2_fullstack_simple_delayed_request_test bins/$(CONFIG)/chttp2_fullstack_simple_request_test bins/$(CONFIG)/chttp2_fullstack_thread_stress_test bins/$(CONFIG)/chttp2_fullstack_writes_done_hangs_with_pending_read_test bins/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_after_accept_test bins/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_after_accept_and_writes_closed_test bins/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_after_invoke_test bins/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_before_invoke_test bins/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_in_a_vacuum_test bins/$(CONFIG)/chttp2_simple_ssl_fullstack_disappearing_server_test bins/$(CONFIG)/chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_inflight_calls_test bins/$(CONFIG)/chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_tags_test bins/$(CONFIG)/chttp2_simple_ssl_fullstack_invoke_large_request_test bins/$(CONFIG)/chttp2_simple_ssl_fullstack_max_concurrent_streams_test bins/$(CONFIG)/chttp2_simple_ssl_fullstack_no_op_test bins/$(CONFIG)/chttp2_simple_ssl_fullstack_ping_pong_streaming_test bins/$(CONFIG)/chttp2_simple_ssl_fullstack_request_response_with_binary_metadata_and_payload_test bins/$(CONFIG)/chttp2_simple_ssl_fullstack_request_response_with_metadata_and_payload_test bins/$(CONFIG)/chttp2_simple_ssl_fullstack_request_response_with_payload_test bins/$(CONFIG)/chttp2_simple_ssl_fullstack_request_response_with_trailing_metadata_and_payload_test bins/$(CONFIG)/chttp2_simple_ssl_fullstack_simple_delayed_request_test bins/$(CONFIG)/chttp2_simple_ssl_fullstack_simple_request_test bins/$(CONFIG)/chttp2_simple_ssl_fullstack_thread_stress_test bins/$(CONFIG)/chttp2_simple_ssl_fullstack_writes_done_hangs_with_pending_read_test bins/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_accept_test bins/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_accept_and_writes_closed_test bins/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_invoke_test bins/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_before_invoke_test bins/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_in_a_vacuum_test bins/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_disappearing_server_test bins/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_inflight_calls_test bins/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_tags_test bins/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_invoke_large_request_test bins/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_max_concurrent_streams_test bins/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_no_op_test bins/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_ping_pong_streaming_test bins/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_binary_metadata_and_payload_test bins/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_metadata_and_payload_test bins/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_payload_test bins/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_trailing_metadata_and_payload_test bins/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_simple_delayed_request_test bins/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_simple_request_test bins/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_thread_stress_test bins/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_writes_done_hangs_with_pending_read_test bins/$(CONFIG)/chttp2_socket_pair_cancel_after_accept_test bins/$(CONFIG)/chttp2_socket_pair_cancel_after_accept_and_writes_closed_test bins/$(CONFIG)/chttp2_socket_pair_cancel_after_invoke_test bins/$(CONFIG)/chttp2_socket_pair_cancel_before_invoke_test bins/$(CONFIG)/chttp2_socket_pair_cancel_in_a_vacuum_test bins/$(CONFIG)/chttp2_socket_pair_disappearing_server_test bins/$(CONFIG)/chttp2_socket_pair_early_server_shutdown_finishes_inflight_calls_test bins/$(CONFIG)/chttp2_socket_pair_early_server_shutdown_finishes_tags_test bins/$(CONFIG)/chttp2_socket_pair_invoke_large_request_test bins/$(CONFIG)/chttp2_socket_pair_max_concurrent_streams_test bins/$(CONFIG)/chttp2_socket_pair_no_op_test bins/$(CONFIG)/chttp2_socket_pair_ping_pong_streaming_test bins/$(CONFIG)/chttp2_socket_pair_request_response_with_binary_metadata_and_payload_test bins/$(CONFIG)/chttp2_socket_pair_request_response_with_metadata_and_payload_test bins/$(CONFIG)/chttp2_socket_pair_request_response_with_payload_test bins/$(CONFIG)/chttp2_socket_pair_request_response_with_trailing_metadata_and_payload_test bins/$(CONFIG)/chttp2_socket_pair_simple_delayed_request_test bins/$(CONFIG)/chttp2_socket_pair_simple_request_test bins/$(CONFIG)/chttp2_socket_pair_thread_stress_test bins/$(CONFIG)/chttp2_socket_pair_writes_done_hangs_with_pending_read_test bins/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_test bins/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_and_writes_closed_test bins/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_after_invoke_test bins/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_before_invoke_test bins/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_in_a_vacuum_test bins/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_disappearing_server_test bins/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_inflight_calls_test bins/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_tags_test bins/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_invoke_large_request_test bins/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_max_concurrent_streams_test bins/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_no_op_test bins/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_ping_pong_streaming_test bins/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_response_with_binary_metadata_and_payload_test bins/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_response_with_metadata_and_payload_test bins/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_response_with_payload_test bins/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_response_with_trailing_metadata_and_payload_test bins/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_simple_delayed_request_test bins/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_simple_request_test bins/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_thread_stress_test bins/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_writes_done_hangs_with_pending_read_test
+buildtests_c: bins_dep_c privatelibs_c bins/$(CONFIG)/grpc_byte_buffer_reader_test bins/$(CONFIG)/gpr_cancellable_test bins/$(CONFIG)/gpr_log_test bins/$(CONFIG)/gpr_useful_test bins/$(CONFIG)/gpr_cmdline_test bins/$(CONFIG)/gpr_histogram_test bins/$(CONFIG)/gpr_host_port_test bins/$(CONFIG)/gpr_slice_buffer_test bins/$(CONFIG)/gpr_slice_test bins/$(CONFIG)/gpr_string_test bins/$(CONFIG)/gpr_sync_test bins/$(CONFIG)/gpr_thd_test bins/$(CONFIG)/gpr_time_test bins/$(CONFIG)/murmur_hash_test bins/$(CONFIG)/grpc_stream_op_test bins/$(CONFIG)/alpn_test bins/$(CONFIG)/time_averaged_stats_test bins/$(CONFIG)/chttp2_stream_encoder_test bins/$(CONFIG)/hpack_table_test bins/$(CONFIG)/chttp2_stream_map_test bins/$(CONFIG)/hpack_parser_test bins/$(CONFIG)/transport_metadata_test bins/$(CONFIG)/chttp2_status_conversion_test bins/$(CONFIG)/chttp2_transport_end2end_test bins/$(CONFIG)/tcp_posix_test bins/$(CONFIG)/dualstack_socket_test bins/$(CONFIG)/no_server_test bins/$(CONFIG)/resolve_address_test bins/$(CONFIG)/sockaddr_utils_test bins/$(CONFIG)/tcp_server_posix_test bins/$(CONFIG)/tcp_client_posix_test bins/$(CONFIG)/grpc_channel_stack_test bins/$(CONFIG)/metadata_buffer_test bins/$(CONFIG)/grpc_completion_queue_test bins/$(CONFIG)/census_window_stats_test bins/$(CONFIG)/census_statistics_quick_test bins/$(CONFIG)/census_statistics_small_log_test bins/$(CONFIG)/census_statistics_performance_test bins/$(CONFIG)/census_statistics_multiple_writers_test bins/$(CONFIG)/census_statistics_multiple_writers_circular_buffer_test bins/$(CONFIG)/census_stub_test bins/$(CONFIG)/census_hash_table_test bins/$(CONFIG)/fling_server bins/$(CONFIG)/fling_client bins/$(CONFIG)/fling_test bins/$(CONFIG)/echo_server bins/$(CONFIG)/echo_client bins/$(CONFIG)/echo_test bins/$(CONFIG)/message_compress_test bins/$(CONFIG)/bin_encoder_test bins/$(CONFIG)/secure_endpoint_test bins/$(CONFIG)/httpcli_format_request_test bins/$(CONFIG)/httpcli_parser_test bins/$(CONFIG)/httpcli_test bins/$(CONFIG)/grpc_credentials_test bins/$(CONFIG)/grpc_base64_test bins/$(CONFIG)/grpc_json_token_test bins/$(CONFIG)/timeout_encoding_test bins/$(CONFIG)/fd_posix_test bins/$(CONFIG)/fling_stream_test bins/$(CONFIG)/lame_client_test bins/$(CONFIG)/alarm_test bins/$(CONFIG)/alarm_list_test bins/$(CONFIG)/alarm_heap_test bins/$(CONFIG)/time_test bins/$(CONFIG)/chttp2_fake_security_cancel_after_accept_test bins/$(CONFIG)/chttp2_fake_security_cancel_after_accept_and_writes_closed_test bins/$(CONFIG)/chttp2_fake_security_cancel_after_invoke_test bins/$(CONFIG)/chttp2_fake_security_cancel_before_invoke_test bins/$(CONFIG)/chttp2_fake_security_cancel_in_a_vacuum_test bins/$(CONFIG)/chttp2_fake_security_census_simple_request_test bins/$(CONFIG)/chttp2_fake_security_disappearing_server_test bins/$(CONFIG)/chttp2_fake_security_early_server_shutdown_finishes_inflight_calls_test bins/$(CONFIG)/chttp2_fake_security_early_server_shutdown_finishes_tags_test bins/$(CONFIG)/chttp2_fake_security_invoke_large_request_test bins/$(CONFIG)/chttp2_fake_security_max_concurrent_streams_test bins/$(CONFIG)/chttp2_fake_security_no_op_test bins/$(CONFIG)/chttp2_fake_security_ping_pong_streaming_test bins/$(CONFIG)/chttp2_fake_security_request_response_with_binary_metadata_and_payload_test bins/$(CONFIG)/chttp2_fake_security_request_response_with_metadata_and_payload_test bins/$(CONFIG)/chttp2_fake_security_request_response_with_payload_test bins/$(CONFIG)/chttp2_fake_security_request_response_with_trailing_metadata_and_payload_test bins/$(CONFIG)/chttp2_fake_security_simple_delayed_request_test bins/$(CONFIG)/chttp2_fake_security_simple_request_test bins/$(CONFIG)/chttp2_fake_security_thread_stress_test bins/$(CONFIG)/chttp2_fake_security_writes_done_hangs_with_pending_read_test bins/$(CONFIG)/chttp2_fullstack_cancel_after_accept_test bins/$(CONFIG)/chttp2_fullstack_cancel_after_accept_and_writes_closed_test bins/$(CONFIG)/chttp2_fullstack_cancel_after_invoke_test bins/$(CONFIG)/chttp2_fullstack_cancel_before_invoke_test bins/$(CONFIG)/chttp2_fullstack_cancel_in_a_vacuum_test bins/$(CONFIG)/chttp2_fullstack_census_simple_request_test bins/$(CONFIG)/chttp2_fullstack_disappearing_server_test bins/$(CONFIG)/chttp2_fullstack_early_server_shutdown_finishes_inflight_calls_test bins/$(CONFIG)/chttp2_fullstack_early_server_shutdown_finishes_tags_test bins/$(CONFIG)/chttp2_fullstack_invoke_large_request_test bins/$(CONFIG)/chttp2_fullstack_max_concurrent_streams_test bins/$(CONFIG)/chttp2_fullstack_no_op_test bins/$(CONFIG)/chttp2_fullstack_ping_pong_streaming_test bins/$(CONFIG)/chttp2_fullstack_request_response_with_binary_metadata_and_payload_test bins/$(CONFIG)/chttp2_fullstack_request_response_with_metadata_and_payload_test bins/$(CONFIG)/chttp2_fullstack_request_response_with_payload_test bins/$(CONFIG)/chttp2_fullstack_request_response_with_trailing_metadata_and_payload_test bins/$(CONFIG)/chttp2_fullstack_simple_delayed_request_test bins/$(CONFIG)/chttp2_fullstack_simple_request_test bins/$(CONFIG)/chttp2_fullstack_thread_stress_test bins/$(CONFIG)/chttp2_fullstack_writes_done_hangs_with_pending_read_test bins/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_after_accept_test bins/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_after_accept_and_writes_closed_test bins/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_after_invoke_test bins/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_before_invoke_test bins/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_in_a_vacuum_test bins/$(CONFIG)/chttp2_simple_ssl_fullstack_census_simple_request_test bins/$(CONFIG)/chttp2_simple_ssl_fullstack_disappearing_server_test bins/$(CONFIG)/chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_inflight_calls_test bins/$(CONFIG)/chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_tags_test bins/$(CONFIG)/chttp2_simple_ssl_fullstack_invoke_large_request_test bins/$(CONFIG)/chttp2_simple_ssl_fullstack_max_concurrent_streams_test bins/$(CONFIG)/chttp2_simple_ssl_fullstack_no_op_test bins/$(CONFIG)/chttp2_simple_ssl_fullstack_ping_pong_streaming_test bins/$(CONFIG)/chttp2_simple_ssl_fullstack_request_response_with_binary_metadata_and_payload_test bins/$(CONFIG)/chttp2_simple_ssl_fullstack_request_response_with_metadata_and_payload_test bins/$(CONFIG)/chttp2_simple_ssl_fullstack_request_response_with_payload_test bins/$(CONFIG)/chttp2_simple_ssl_fullstack_request_response_with_trailing_metadata_and_payload_test bins/$(CONFIG)/chttp2_simple_ssl_fullstack_simple_delayed_request_test bins/$(CONFIG)/chttp2_simple_ssl_fullstack_simple_request_test bins/$(CONFIG)/chttp2_simple_ssl_fullstack_thread_stress_test bins/$(CONFIG)/chttp2_simple_ssl_fullstack_writes_done_hangs_with_pending_read_test bins/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_accept_test bins/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_accept_and_writes_closed_test bins/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_invoke_test bins/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_before_invoke_test bins/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_in_a_vacuum_test bins/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_census_simple_request_test bins/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_disappearing_server_test bins/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_inflight_calls_test bins/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_tags_test bins/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_invoke_large_request_test bins/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_max_concurrent_streams_test bins/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_no_op_test bins/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_ping_pong_streaming_test bins/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_binary_metadata_and_payload_test bins/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_metadata_and_payload_test bins/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_payload_test bins/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_trailing_metadata_and_payload_test bins/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_simple_delayed_request_test bins/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_simple_request_test bins/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_thread_stress_test bins/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_writes_done_hangs_with_pending_read_test bins/$(CONFIG)/chttp2_socket_pair_cancel_after_accept_test bins/$(CONFIG)/chttp2_socket_pair_cancel_after_accept_and_writes_closed_test bins/$(CONFIG)/chttp2_socket_pair_cancel_after_invoke_test bins/$(CONFIG)/chttp2_socket_pair_cancel_before_invoke_test bins/$(CONFIG)/chttp2_socket_pair_cancel_in_a_vacuum_test bins/$(CONFIG)/chttp2_socket_pair_census_simple_request_test bins/$(CONFIG)/chttp2_socket_pair_disappearing_server_test bins/$(CONFIG)/chttp2_socket_pair_early_server_shutdown_finishes_inflight_calls_test bins/$(CONFIG)/chttp2_socket_pair_early_server_shutdown_finishes_tags_test bins/$(CONFIG)/chttp2_socket_pair_invoke_large_request_test bins/$(CONFIG)/chttp2_socket_pair_max_concurrent_streams_test bins/$(CONFIG)/chttp2_socket_pair_no_op_test bins/$(CONFIG)/chttp2_socket_pair_ping_pong_streaming_test bins/$(CONFIG)/chttp2_socket_pair_request_response_with_binary_metadata_and_payload_test bins/$(CONFIG)/chttp2_socket_pair_request_response_with_metadata_and_payload_test bins/$(CONFIG)/chttp2_socket_pair_request_response_with_payload_test bins/$(CONFIG)/chttp2_socket_pair_request_response_with_trailing_metadata_and_payload_test bins/$(CONFIG)/chttp2_socket_pair_simple_delayed_request_test bins/$(CONFIG)/chttp2_socket_pair_simple_request_test bins/$(CONFIG)/chttp2_socket_pair_thread_stress_test bins/$(CONFIG)/chttp2_socket_pair_writes_done_hangs_with_pending_read_test bins/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_test bins/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_and_writes_closed_test bins/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_after_invoke_test bins/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_before_invoke_test bins/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_in_a_vacuum_test bins/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_census_simple_request_test bins/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_disappearing_server_test bins/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_inflight_calls_test bins/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_tags_test bins/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_invoke_large_request_test bins/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_max_concurrent_streams_test bins/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_no_op_test bins/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_ping_pong_streaming_test bins/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_response_with_binary_metadata_and_payload_test bins/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_response_with_metadata_and_payload_test bins/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_response_with_payload_test bins/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_response_with_trailing_metadata_and_payload_test bins/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_simple_delayed_request_test bins/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_simple_request_test bins/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_thread_stress_test bins/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_writes_done_hangs_with_pending_read_test
 
-buildtests_cxx: bins_dep_cxx privatelibs_cxx bins/thread_pool_test bins/status_test bins/sync_client_async_server_test bins/qps_client bins/qps_server bins/interop_server bins/interop_client bins/end2end_test bins/channel_arguments_test
+buildtests_cxx: bins_dep_cxx privatelibs_cxx bins/thread_pool_test bins/status_test bins/sync_client_async_server_test bins/qps_client bins/qps_server bins/interop_server bins/interop_client bins/end2end_test bins/channel_arguments_test bins/credentials_test
 
 test: test_c test_cxx
 
@@ -622,6 +632,8 @@ test_c: buildtests_c
 	$(Q) ./bins/$(CONFIG)/chttp2_fake_security_cancel_before_invoke_test || ( echo test chttp2_fake_security_cancel_before_invoke_test failed ; exit 1 )
 	$(E) "[RUN]     Testing chttp2_fake_security_cancel_in_a_vacuum_test"
 	$(Q) ./bins/$(CONFIG)/chttp2_fake_security_cancel_in_a_vacuum_test || ( echo test chttp2_fake_security_cancel_in_a_vacuum_test failed ; exit 1 )
+	$(E) "[RUN]     Testing chttp2_fake_security_census_simple_request_test"
+	$(Q) ./bins/$(CONFIG)/chttp2_fake_security_census_simple_request_test || ( echo test chttp2_fake_security_census_simple_request_test failed ; exit 1 )
 	$(E) "[RUN]     Testing chttp2_fake_security_disappearing_server_test"
 	$(Q) ./bins/$(CONFIG)/chttp2_fake_security_disappearing_server_test || ( echo test chttp2_fake_security_disappearing_server_test failed ; exit 1 )
 	$(E) "[RUN]     Testing chttp2_fake_security_early_server_shutdown_finishes_inflight_calls_test"
@@ -662,6 +674,8 @@ test_c: buildtests_c
 	$(Q) ./bins/$(CONFIG)/chttp2_fullstack_cancel_before_invoke_test || ( echo test chttp2_fullstack_cancel_before_invoke_test failed ; exit 1 )
 	$(E) "[RUN]     Testing chttp2_fullstack_cancel_in_a_vacuum_test"
 	$(Q) ./bins/$(CONFIG)/chttp2_fullstack_cancel_in_a_vacuum_test || ( echo test chttp2_fullstack_cancel_in_a_vacuum_test failed ; exit 1 )
+	$(E) "[RUN]     Testing chttp2_fullstack_census_simple_request_test"
+	$(Q) ./bins/$(CONFIG)/chttp2_fullstack_census_simple_request_test || ( echo test chttp2_fullstack_census_simple_request_test failed ; exit 1 )
 	$(E) "[RUN]     Testing chttp2_fullstack_disappearing_server_test"
 	$(Q) ./bins/$(CONFIG)/chttp2_fullstack_disappearing_server_test || ( echo test chttp2_fullstack_disappearing_server_test failed ; exit 1 )
 	$(E) "[RUN]     Testing chttp2_fullstack_early_server_shutdown_finishes_inflight_calls_test"
@@ -702,6 +716,8 @@ test_c: buildtests_c
 	$(Q) ./bins/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_before_invoke_test || ( echo test chttp2_simple_ssl_fullstack_cancel_before_invoke_test failed ; exit 1 )
 	$(E) "[RUN]     Testing chttp2_simple_ssl_fullstack_cancel_in_a_vacuum_test"
 	$(Q) ./bins/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_in_a_vacuum_test || ( echo test chttp2_simple_ssl_fullstack_cancel_in_a_vacuum_test failed ; exit 1 )
+	$(E) "[RUN]     Testing chttp2_simple_ssl_fullstack_census_simple_request_test"
+	$(Q) ./bins/$(CONFIG)/chttp2_simple_ssl_fullstack_census_simple_request_test || ( echo test chttp2_simple_ssl_fullstack_census_simple_request_test failed ; exit 1 )
 	$(E) "[RUN]     Testing chttp2_simple_ssl_fullstack_disappearing_server_test"
 	$(Q) ./bins/$(CONFIG)/chttp2_simple_ssl_fullstack_disappearing_server_test || ( echo test chttp2_simple_ssl_fullstack_disappearing_server_test failed ; exit 1 )
 	$(E) "[RUN]     Testing chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_inflight_calls_test"
@@ -742,6 +758,8 @@ test_c: buildtests_c
 	$(Q) ./bins/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_before_invoke_test || ( echo test chttp2_simple_ssl_with_oauth2_fullstack_cancel_before_invoke_test failed ; exit 1 )
 	$(E) "[RUN]     Testing chttp2_simple_ssl_with_oauth2_fullstack_cancel_in_a_vacuum_test"
 	$(Q) ./bins/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_in_a_vacuum_test || ( echo test chttp2_simple_ssl_with_oauth2_fullstack_cancel_in_a_vacuum_test failed ; exit 1 )
+	$(E) "[RUN]     Testing chttp2_simple_ssl_with_oauth2_fullstack_census_simple_request_test"
+	$(Q) ./bins/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_census_simple_request_test || ( echo test chttp2_simple_ssl_with_oauth2_fullstack_census_simple_request_test failed ; exit 1 )
 	$(E) "[RUN]     Testing chttp2_simple_ssl_with_oauth2_fullstack_disappearing_server_test"
 	$(Q) ./bins/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_disappearing_server_test || ( echo test chttp2_simple_ssl_with_oauth2_fullstack_disappearing_server_test failed ; exit 1 )
 	$(E) "[RUN]     Testing chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_inflight_calls_test"
@@ -782,6 +800,8 @@ test_c: buildtests_c
 	$(Q) ./bins/$(CONFIG)/chttp2_socket_pair_cancel_before_invoke_test || ( echo test chttp2_socket_pair_cancel_before_invoke_test failed ; exit 1 )
 	$(E) "[RUN]     Testing chttp2_socket_pair_cancel_in_a_vacuum_test"
 	$(Q) ./bins/$(CONFIG)/chttp2_socket_pair_cancel_in_a_vacuum_test || ( echo test chttp2_socket_pair_cancel_in_a_vacuum_test failed ; exit 1 )
+	$(E) "[RUN]     Testing chttp2_socket_pair_census_simple_request_test"
+	$(Q) ./bins/$(CONFIG)/chttp2_socket_pair_census_simple_request_test || ( echo test chttp2_socket_pair_census_simple_request_test failed ; exit 1 )
 	$(E) "[RUN]     Testing chttp2_socket_pair_disappearing_server_test"
 	$(Q) ./bins/$(CONFIG)/chttp2_socket_pair_disappearing_server_test || ( echo test chttp2_socket_pair_disappearing_server_test failed ; exit 1 )
 	$(E) "[RUN]     Testing chttp2_socket_pair_early_server_shutdown_finishes_inflight_calls_test"
@@ -822,6 +842,8 @@ test_c: buildtests_c
 	$(Q) ./bins/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_before_invoke_test || ( echo test chttp2_socket_pair_one_byte_at_a_time_cancel_before_invoke_test failed ; exit 1 )
 	$(E) "[RUN]     Testing chttp2_socket_pair_one_byte_at_a_time_cancel_in_a_vacuum_test"
 	$(Q) ./bins/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_in_a_vacuum_test || ( echo test chttp2_socket_pair_one_byte_at_a_time_cancel_in_a_vacuum_test failed ; exit 1 )
+	$(E) "[RUN]     Testing chttp2_socket_pair_one_byte_at_a_time_census_simple_request_test"
+	$(Q) ./bins/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_census_simple_request_test || ( echo test chttp2_socket_pair_one_byte_at_a_time_census_simple_request_test failed ; exit 1 )
 	$(E) "[RUN]     Testing chttp2_socket_pair_one_byte_at_a_time_disappearing_server_test"
 	$(Q) ./bins/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_disappearing_server_test || ( echo test chttp2_socket_pair_one_byte_at_a_time_disappearing_server_test failed ; exit 1 )
 	$(E) "[RUN]     Testing chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_inflight_calls_test"
@@ -869,11 +891,13 @@ test_cxx: buildtests_cxx
 	$(Q) ./bins/$(CONFIG)/end2end_test || ( echo test end2end_test failed ; exit 1 )
 	$(E) "[RUN]     Testing channel_arguments_test"
 	$(Q) ./bins/$(CONFIG)/channel_arguments_test || ( echo test channel_arguments_test failed ; exit 1 )
+	$(E) "[RUN]     Testing credentials_test"
+	$(Q) ./bins/$(CONFIG)/credentials_test || ( echo test credentials_test failed ; exit 1 )
 
 
 tools: privatelibs bins/$(CONFIG)/gen_hpack_tables bins/$(CONFIG)/grpc_fetch_oauth2
 
-protoc_plugins: bins/$(CONFIG)/cpp_plugin bins/$(CONFIG)/ruby_plugin
+protoc_plugins: bins/$(CONFIG)/cpp_plugin bins/$(CONFIG)/ruby_plugin bins/$(CONFIG)/go_plugin
 
 buildbenchmarks: privatelibs bins/$(CONFIG)/grpc_completion_queue_benchmark bins/$(CONFIG)/low_level_ping_pong_benchmark
 
@@ -945,6 +969,24 @@ gens/test/cpp/util/echo.pb.cc: test/cpp/util/echo.proto protoc_plugins
 	$(Q) mkdir -p `dirname $@`
 	$(Q) $(PROTOC) --cpp_out=gens --grpc_out=gens --plugin=protoc-gen-grpc=bins/$(CONFIG)/cpp_plugin $<
 
+deps/$(CONFIG)/gens/test/cpp/util/echo_duplicate.pb.dep:
+	$(Q) mkdir -p `dirname $@`
+	$(Q) touch $@
+
+gens/test/cpp/util/echo_duplicate.pb.cc: test/cpp/util/echo_duplicate.proto protoc_plugins
+	$(E) "[PROTOC]  Generating protobuf CC file from $<"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(PROTOC) --cpp_out=gens --grpc_out=gens --plugin=protoc-gen-grpc=bins/$(CONFIG)/cpp_plugin $<
+
+deps/$(CONFIG)/gens/test/cpp/util/messages.pb.dep:
+	$(Q) mkdir -p `dirname $@`
+	$(Q) touch $@
+
+gens/test/cpp/util/messages.pb.cc: test/cpp/util/messages.proto protoc_plugins
+	$(E) "[PROTOC]  Generating protobuf CC file from $<"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(PROTOC) --cpp_out=gens --grpc_out=gens --plugin=protoc-gen-grpc=bins/$(CONFIG)/cpp_plugin $<
+
 
 deps/$(CONFIG)/%.dep : %.c
 	$(E) "[DEP]     Generating dependencies for $<"
@@ -978,13 +1020,13 @@ objs/$(CONFIG)/%.o : %.cc
 
 dep: dep_c dep_cxx
 
-dep_c: deps_libgpr deps_libgrpc deps_libgrpc_unsecure deps_libgrpc_test_util deps_libend2end_fixture_chttp2_fake_security deps_libend2end_fixture_chttp2_fullstack deps_libend2end_fixture_chttp2_simple_ssl_fullstack deps_libend2end_fixture_chttp2_simple_ssl_with_oauth2_fullstack deps_libend2end_fixture_chttp2_socket_pair deps_libend2end_fixture_chttp2_socket_pair_one_byte_at_a_time deps_libend2end_test_cancel_after_accept deps_libend2end_test_cancel_after_accept_and_writes_closed deps_libend2end_test_cancel_after_invoke deps_libend2end_test_cancel_before_invoke deps_libend2end_test_cancel_in_a_vacuum deps_libend2end_test_disappearing_server deps_libend2end_test_early_server_shutdown_finishes_inflight_calls deps_libend2end_test_early_server_shutdown_finishes_tags deps_libend2end_test_invoke_large_request deps_libend2end_test_max_concurrent_streams deps_libend2end_test_no_op deps_libend2end_test_ping_pong_streaming deps_libend2end_test_request_response_with_binary_metadata_and_payload deps_libend2end_test_request_response_with_metadata_and_payload deps_libend2end_test_request_response_with_payload deps_libend2end_test_request_response_with_trailing_metadata_and_payload deps_libend2end_test_simple_delayed_request deps_libend2end_test_simple_request deps_libend2end_test_thread_stress deps_libend2end_test_writes_done_hangs_with_pending_read deps_libend2end_certs
+dep_c: deps_libgpr deps_libgrpc deps_libgrpc_unsecure deps_libgrpc_test_util deps_libend2end_fixture_chttp2_fake_security deps_libend2end_fixture_chttp2_fullstack deps_libend2end_fixture_chttp2_simple_ssl_fullstack deps_libend2end_fixture_chttp2_simple_ssl_with_oauth2_fullstack deps_libend2end_fixture_chttp2_socket_pair deps_libend2end_fixture_chttp2_socket_pair_one_byte_at_a_time deps_libend2end_test_cancel_after_accept deps_libend2end_test_cancel_after_accept_and_writes_closed deps_libend2end_test_cancel_after_invoke deps_libend2end_test_cancel_before_invoke deps_libend2end_test_cancel_in_a_vacuum deps_libend2end_test_census_simple_request deps_libend2end_test_disappearing_server deps_libend2end_test_early_server_shutdown_finishes_inflight_calls deps_libend2end_test_early_server_shutdown_finishes_tags deps_libend2end_test_invoke_large_request deps_libend2end_test_max_concurrent_streams deps_libend2end_test_no_op deps_libend2end_test_ping_pong_streaming deps_libend2end_test_request_response_with_binary_metadata_and_payload deps_libend2end_test_request_response_with_metadata_and_payload deps_libend2end_test_request_response_with_payload deps_libend2end_test_request_response_with_trailing_metadata_and_payload deps_libend2end_test_simple_delayed_request deps_libend2end_test_simple_request deps_libend2end_test_thread_stress deps_libend2end_test_writes_done_hangs_with_pending_read deps_libend2end_certs
 
-bins_dep_c: deps_gen_hpack_tables deps_grpc_byte_buffer_reader_test deps_gpr_cancellable_test deps_gpr_log_test deps_gpr_useful_test deps_gpr_cmdline_test deps_gpr_histogram_test deps_gpr_host_port_test deps_gpr_slice_buffer_test deps_gpr_slice_test deps_gpr_string_test deps_gpr_sync_test deps_gpr_thd_test deps_gpr_time_test deps_murmur_hash_test deps_grpc_stream_op_test deps_alpn_test deps_time_averaged_stats_test deps_chttp2_stream_encoder_test deps_hpack_table_test deps_chttp2_stream_map_test deps_hpack_parser_test deps_transport_metadata_test deps_chttp2_status_conversion_test deps_chttp2_transport_end2end_test deps_tcp_posix_test deps_dualstack_socket_test deps_no_server_test deps_resolve_address_test deps_sockaddr_utils_test deps_tcp_server_posix_test deps_tcp_client_posix_test deps_grpc_channel_stack_test deps_metadata_buffer_test deps_grpc_completion_queue_test deps_grpc_completion_queue_benchmark deps_census_window_stats_test deps_census_statistics_quick_test deps_census_statistics_small_log_test deps_census_statistics_performance_test deps_census_statistics_multiple_writers_test deps_census_statistics_multiple_writers_circular_buffer_test deps_census_stub_test deps_census_hash_table_test deps_fling_server deps_fling_client deps_fling_test deps_echo_server deps_echo_client deps_echo_test deps_low_level_ping_pong_benchmark deps_message_compress_test deps_bin_encoder_test deps_secure_endpoint_test deps_httpcli_format_request_test deps_httpcli_parser_test deps_httpcli_test deps_grpc_credentials_test deps_grpc_fetch_oauth2 deps_grpc_base64_test deps_grpc_json_token_test deps_timeout_encoding_test deps_fd_posix_test deps_fling_stream_test deps_lame_client_test deps_alarm_test deps_alarm_list_test deps_alarm_heap_test deps_time_test deps_chttp2_fake_security_cancel_after_accept_test deps_chttp2_fake_security_cancel_after_accept_and_writes_closed_test deps_chttp2_fake_security_cancel_after_invoke_test deps_chttp2_fake_security_cancel_before_invoke_test deps_chttp2_fake_security_cancel_in_a_vacuum_test deps_chttp2_fake_security_disappearing_server_test deps_chttp2_fake_security_early_server_shutdown_finishes_inflight_calls_test deps_chttp2_fake_security_early_server_shutdown_finishes_tags_test deps_chttp2_fake_security_invoke_large_request_test deps_chttp2_fake_security_max_concurrent_streams_test deps_chttp2_fake_security_no_op_test deps_chttp2_fake_security_ping_pong_streaming_test deps_chttp2_fake_security_request_response_with_binary_metadata_and_payload_test deps_chttp2_fake_security_request_response_with_metadata_and_payload_test deps_chttp2_fake_security_request_response_with_payload_test deps_chttp2_fake_security_request_response_with_trailing_metadata_and_payload_test deps_chttp2_fake_security_simple_delayed_request_test deps_chttp2_fake_security_simple_request_test deps_chttp2_fake_security_thread_stress_test deps_chttp2_fake_security_writes_done_hangs_with_pending_read_test deps_chttp2_fullstack_cancel_after_accept_test deps_chttp2_fullstack_cancel_after_accept_and_writes_closed_test deps_chttp2_fullstack_cancel_after_invoke_test deps_chttp2_fullstack_cancel_before_invoke_test deps_chttp2_fullstack_cancel_in_a_vacuum_test deps_chttp2_fullstack_disappearing_server_test deps_chttp2_fullstack_early_server_shutdown_finishes_inflight_calls_test deps_chttp2_fullstack_early_server_shutdown_finishes_tags_test deps_chttp2_fullstack_invoke_large_request_test deps_chttp2_fullstack_max_concurrent_streams_test deps_chttp2_fullstack_no_op_test deps_chttp2_fullstack_ping_pong_streaming_test deps_chttp2_fullstack_request_response_with_binary_metadata_and_payload_test deps_chttp2_fullstack_request_response_with_metadata_and_payload_test deps_chttp2_fullstack_request_response_with_payload_test deps_chttp2_fullstack_request_response_with_trailing_metadata_and_payload_test deps_chttp2_fullstack_simple_delayed_request_test deps_chttp2_fullstack_simple_request_test deps_chttp2_fullstack_thread_stress_test deps_chttp2_fullstack_writes_done_hangs_with_pending_read_test deps_chttp2_simple_ssl_fullstack_cancel_after_accept_test deps_chttp2_simple_ssl_fullstack_cancel_after_accept_and_writes_closed_test deps_chttp2_simple_ssl_fullstack_cancel_after_invoke_test deps_chttp2_simple_ssl_fullstack_cancel_before_invoke_test deps_chttp2_simple_ssl_fullstack_cancel_in_a_vacuum_test deps_chttp2_simple_ssl_fullstack_disappearing_server_test deps_chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_inflight_calls_test deps_chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_tags_test deps_chttp2_simple_ssl_fullstack_invoke_large_request_test deps_chttp2_simple_ssl_fullstack_max_concurrent_streams_test deps_chttp2_simple_ssl_fullstack_no_op_test deps_chttp2_simple_ssl_fullstack_ping_pong_streaming_test deps_chttp2_simple_ssl_fullstack_request_response_with_binary_metadata_and_payload_test deps_chttp2_simple_ssl_fullstack_request_response_with_metadata_and_payload_test deps_chttp2_simple_ssl_fullstack_request_response_with_payload_test deps_chttp2_simple_ssl_fullstack_request_response_with_trailing_metadata_and_payload_test deps_chttp2_simple_ssl_fullstack_simple_delayed_request_test deps_chttp2_simple_ssl_fullstack_simple_request_test deps_chttp2_simple_ssl_fullstack_thread_stress_test deps_chttp2_simple_ssl_fullstack_writes_done_hangs_with_pending_read_test deps_chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_accept_test deps_chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_accept_and_writes_closed_test deps_chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_invoke_test deps_chttp2_simple_ssl_with_oauth2_fullstack_cancel_before_invoke_test deps_chttp2_simple_ssl_with_oauth2_fullstack_cancel_in_a_vacuum_test deps_chttp2_simple_ssl_with_oauth2_fullstack_disappearing_server_test deps_chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_inflight_calls_test deps_chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_tags_test deps_chttp2_simple_ssl_with_oauth2_fullstack_invoke_large_request_test deps_chttp2_simple_ssl_with_oauth2_fullstack_max_concurrent_streams_test deps_chttp2_simple_ssl_with_oauth2_fullstack_no_op_test deps_chttp2_simple_ssl_with_oauth2_fullstack_ping_pong_streaming_test deps_chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_binary_metadata_and_payload_test deps_chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_metadata_and_payload_test deps_chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_payload_test deps_chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_trailing_metadata_and_payload_test deps_chttp2_simple_ssl_with_oauth2_fullstack_simple_delayed_request_test deps_chttp2_simple_ssl_with_oauth2_fullstack_simple_request_test deps_chttp2_simple_ssl_with_oauth2_fullstack_thread_stress_test deps_chttp2_simple_ssl_with_oauth2_fullstack_writes_done_hangs_with_pending_read_test deps_chttp2_socket_pair_cancel_after_accept_test deps_chttp2_socket_pair_cancel_after_accept_and_writes_closed_test deps_chttp2_socket_pair_cancel_after_invoke_test deps_chttp2_socket_pair_cancel_before_invoke_test deps_chttp2_socket_pair_cancel_in_a_vacuum_test deps_chttp2_socket_pair_disappearing_server_test deps_chttp2_socket_pair_early_server_shutdown_finishes_inflight_calls_test deps_chttp2_socket_pair_early_server_shutdown_finishes_tags_test deps_chttp2_socket_pair_invoke_large_request_test deps_chttp2_socket_pair_max_concurrent_streams_test deps_chttp2_socket_pair_no_op_test deps_chttp2_socket_pair_ping_pong_streaming_test deps_chttp2_socket_pair_request_response_with_binary_metadata_and_payload_test deps_chttp2_socket_pair_request_response_with_metadata_and_payload_test deps_chttp2_socket_pair_request_response_with_payload_test deps_chttp2_socket_pair_request_response_with_trailing_metadata_and_payload_test deps_chttp2_socket_pair_simple_delayed_request_test deps_chttp2_socket_pair_simple_request_test deps_chttp2_socket_pair_thread_stress_test deps_chttp2_socket_pair_writes_done_hangs_with_pending_read_test deps_chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_test deps_chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_and_writes_closed_test deps_chttp2_socket_pair_one_byte_at_a_time_cancel_after_invoke_test deps_chttp2_socket_pair_one_byte_at_a_time_cancel_before_invoke_test deps_chttp2_socket_pair_one_byte_at_a_time_cancel_in_a_vacuum_test deps_chttp2_socket_pair_one_byte_at_a_time_disappearing_server_test deps_chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_inflight_calls_test deps_chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_tags_test deps_chttp2_socket_pair_one_byte_at_a_time_invoke_large_request_test deps_chttp2_socket_pair_one_byte_at_a_time_max_concurrent_streams_test deps_chttp2_socket_pair_one_byte_at_a_time_no_op_test deps_chttp2_socket_pair_one_byte_at_a_time_ping_pong_streaming_test deps_chttp2_socket_pair_one_byte_at_a_time_request_response_with_binary_metadata_and_payload_test deps_chttp2_socket_pair_one_byte_at_a_time_request_response_with_metadata_and_payload_test deps_chttp2_socket_pair_one_byte_at_a_time_request_response_with_payload_test deps_chttp2_socket_pair_one_byte_at_a_time_request_response_with_trailing_metadata_and_payload_test deps_chttp2_socket_pair_one_byte_at_a_time_simple_delayed_request_test deps_chttp2_socket_pair_one_byte_at_a_time_simple_request_test deps_chttp2_socket_pair_one_byte_at_a_time_thread_stress_test deps_chttp2_socket_pair_one_byte_at_a_time_writes_done_hangs_with_pending_read_test
+bins_dep_c: deps_gen_hpack_tables deps_grpc_byte_buffer_reader_test deps_gpr_cancellable_test deps_gpr_log_test deps_gpr_useful_test deps_gpr_cmdline_test deps_gpr_histogram_test deps_gpr_host_port_test deps_gpr_slice_buffer_test deps_gpr_slice_test deps_gpr_string_test deps_gpr_sync_test deps_gpr_thd_test deps_gpr_time_test deps_murmur_hash_test deps_grpc_stream_op_test deps_alpn_test deps_time_averaged_stats_test deps_chttp2_stream_encoder_test deps_hpack_table_test deps_chttp2_stream_map_test deps_hpack_parser_test deps_transport_metadata_test deps_chttp2_status_conversion_test deps_chttp2_transport_end2end_test deps_tcp_posix_test deps_dualstack_socket_test deps_no_server_test deps_resolve_address_test deps_sockaddr_utils_test deps_tcp_server_posix_test deps_tcp_client_posix_test deps_grpc_channel_stack_test deps_metadata_buffer_test deps_grpc_completion_queue_test deps_grpc_completion_queue_benchmark deps_census_trace_store_test deps_census_stats_store_test deps_census_window_stats_test deps_census_statistics_quick_test deps_census_statistics_small_log_test deps_census_statistics_performance_test deps_census_statistics_multiple_writers_test deps_census_statistics_multiple_writers_circular_buffer_test deps_census_stub_test deps_census_hash_table_test deps_fling_server deps_fling_client deps_fling_test deps_echo_server deps_echo_client deps_echo_test deps_low_level_ping_pong_benchmark deps_message_compress_test deps_bin_encoder_test deps_secure_endpoint_test deps_httpcli_format_request_test deps_httpcli_parser_test deps_httpcli_test deps_grpc_credentials_test deps_grpc_fetch_oauth2 deps_grpc_base64_test deps_grpc_json_token_test deps_timeout_encoding_test deps_fd_posix_test deps_fling_stream_test deps_lame_client_test deps_alarm_test deps_alarm_list_test deps_alarm_heap_test deps_time_test deps_chttp2_fake_security_cancel_after_accept_test deps_chttp2_fake_security_cancel_after_accept_and_writes_closed_test deps_chttp2_fake_security_cancel_after_invoke_test deps_chttp2_fake_security_cancel_before_invoke_test deps_chttp2_fake_security_cancel_in_a_vacuum_test deps_chttp2_fake_security_census_simple_request_test deps_chttp2_fake_security_disappearing_server_test deps_chttp2_fake_security_early_server_shutdown_finishes_inflight_calls_test deps_chttp2_fake_security_early_server_shutdown_finishes_tags_test deps_chttp2_fake_security_invoke_large_request_test deps_chttp2_fake_security_max_concurrent_streams_test deps_chttp2_fake_security_no_op_test deps_chttp2_fake_security_ping_pong_streaming_test deps_chttp2_fake_security_request_response_with_binary_metadata_and_payload_test deps_chttp2_fake_security_request_response_with_metadata_and_payload_test deps_chttp2_fake_security_request_response_with_payload_test deps_chttp2_fake_security_request_response_with_trailing_metadata_and_payload_test deps_chttp2_fake_security_simple_delayed_request_test deps_chttp2_fake_security_simple_request_test deps_chttp2_fake_security_thread_stress_test deps_chttp2_fake_security_writes_done_hangs_with_pending_read_test deps_chttp2_fullstack_cancel_after_accept_test deps_chttp2_fullstack_cancel_after_accept_and_writes_closed_test deps_chttp2_fullstack_cancel_after_invoke_test deps_chttp2_fullstack_cancel_before_invoke_test deps_chttp2_fullstack_cancel_in_a_vacuum_test deps_chttp2_fullstack_census_simple_request_test deps_chttp2_fullstack_disappearing_server_test deps_chttp2_fullstack_early_server_shutdown_finishes_inflight_calls_test deps_chttp2_fullstack_early_server_shutdown_finishes_tags_test deps_chttp2_fullstack_invoke_large_request_test deps_chttp2_fullstack_max_concurrent_streams_test deps_chttp2_fullstack_no_op_test deps_chttp2_fullstack_ping_pong_streaming_test deps_chttp2_fullstack_request_response_with_binary_metadata_and_payload_test deps_chttp2_fullstack_request_response_with_metadata_and_payload_test deps_chttp2_fullstack_request_response_with_payload_test deps_chttp2_fullstack_request_response_with_trailing_metadata_and_payload_test deps_chttp2_fullstack_simple_delayed_request_test deps_chttp2_fullstack_simple_request_test deps_chttp2_fullstack_thread_stress_test deps_chttp2_fullstack_writes_done_hangs_with_pending_read_test deps_chttp2_simple_ssl_fullstack_cancel_after_accept_test deps_chttp2_simple_ssl_fullstack_cancel_after_accept_and_writes_closed_test deps_chttp2_simple_ssl_fullstack_cancel_after_invoke_test deps_chttp2_simple_ssl_fullstack_cancel_before_invoke_test deps_chttp2_simple_ssl_fullstack_cancel_in_a_vacuum_test deps_chttp2_simple_ssl_fullstack_census_simple_request_test deps_chttp2_simple_ssl_fullstack_disappearing_server_test deps_chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_inflight_calls_test deps_chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_tags_test deps_chttp2_simple_ssl_fullstack_invoke_large_request_test deps_chttp2_simple_ssl_fullstack_max_concurrent_streams_test deps_chttp2_simple_ssl_fullstack_no_op_test deps_chttp2_simple_ssl_fullstack_ping_pong_streaming_test deps_chttp2_simple_ssl_fullstack_request_response_with_binary_metadata_and_payload_test deps_chttp2_simple_ssl_fullstack_request_response_with_metadata_and_payload_test deps_chttp2_simple_ssl_fullstack_request_response_with_payload_test deps_chttp2_simple_ssl_fullstack_request_response_with_trailing_metadata_and_payload_test deps_chttp2_simple_ssl_fullstack_simple_delayed_request_test deps_chttp2_simple_ssl_fullstack_simple_request_test deps_chttp2_simple_ssl_fullstack_thread_stress_test deps_chttp2_simple_ssl_fullstack_writes_done_hangs_with_pending_read_test deps_chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_accept_test deps_chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_accept_and_writes_closed_test deps_chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_invoke_test deps_chttp2_simple_ssl_with_oauth2_fullstack_cancel_before_invoke_test deps_chttp2_simple_ssl_with_oauth2_fullstack_cancel_in_a_vacuum_test deps_chttp2_simple_ssl_with_oauth2_fullstack_census_simple_request_test deps_chttp2_simple_ssl_with_oauth2_fullstack_disappearing_server_test deps_chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_inflight_calls_test deps_chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_tags_test deps_chttp2_simple_ssl_with_oauth2_fullstack_invoke_large_request_test deps_chttp2_simple_ssl_with_oauth2_fullstack_max_concurrent_streams_test deps_chttp2_simple_ssl_with_oauth2_fullstack_no_op_test deps_chttp2_simple_ssl_with_oauth2_fullstack_ping_pong_streaming_test deps_chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_binary_metadata_and_payload_test deps_chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_metadata_and_payload_test deps_chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_payload_test deps_chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_trailing_metadata_and_payload_test deps_chttp2_simple_ssl_with_oauth2_fullstack_simple_delayed_request_test deps_chttp2_simple_ssl_with_oauth2_fullstack_simple_request_test deps_chttp2_simple_ssl_with_oauth2_fullstack_thread_stress_test deps_chttp2_simple_ssl_with_oauth2_fullstack_writes_done_hangs_with_pending_read_test deps_chttp2_socket_pair_cancel_after_accept_test deps_chttp2_socket_pair_cancel_after_accept_and_writes_closed_test deps_chttp2_socket_pair_cancel_after_invoke_test deps_chttp2_socket_pair_cancel_before_invoke_test deps_chttp2_socket_pair_cancel_in_a_vacuum_test deps_chttp2_socket_pair_census_simple_request_test deps_chttp2_socket_pair_disappearing_server_test deps_chttp2_socket_pair_early_server_shutdown_finishes_inflight_calls_test deps_chttp2_socket_pair_early_server_shutdown_finishes_tags_test deps_chttp2_socket_pair_invoke_large_request_test deps_chttp2_socket_pair_max_concurrent_streams_test deps_chttp2_socket_pair_no_op_test deps_chttp2_socket_pair_ping_pong_streaming_test deps_chttp2_socket_pair_request_response_with_binary_metadata_and_payload_test deps_chttp2_socket_pair_request_response_with_metadata_and_payload_test deps_chttp2_socket_pair_request_response_with_payload_test deps_chttp2_socket_pair_request_response_with_trailing_metadata_and_payload_test deps_chttp2_socket_pair_simple_delayed_request_test deps_chttp2_socket_pair_simple_request_test deps_chttp2_socket_pair_thread_stress_test deps_chttp2_socket_pair_writes_done_hangs_with_pending_read_test deps_chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_test deps_chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_and_writes_closed_test deps_chttp2_socket_pair_one_byte_at_a_time_cancel_after_invoke_test deps_chttp2_socket_pair_one_byte_at_a_time_cancel_before_invoke_test deps_chttp2_socket_pair_one_byte_at_a_time_cancel_in_a_vacuum_test deps_chttp2_socket_pair_one_byte_at_a_time_census_simple_request_test deps_chttp2_socket_pair_one_byte_at_a_time_disappearing_server_test deps_chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_inflight_calls_test deps_chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_tags_test deps_chttp2_socket_pair_one_byte_at_a_time_invoke_large_request_test deps_chttp2_socket_pair_one_byte_at_a_time_max_concurrent_streams_test deps_chttp2_socket_pair_one_byte_at_a_time_no_op_test deps_chttp2_socket_pair_one_byte_at_a_time_ping_pong_streaming_test deps_chttp2_socket_pair_one_byte_at_a_time_request_response_with_binary_metadata_and_payload_test deps_chttp2_socket_pair_one_byte_at_a_time_request_response_with_metadata_and_payload_test deps_chttp2_socket_pair_one_byte_at_a_time_request_response_with_payload_test deps_chttp2_socket_pair_one_byte_at_a_time_request_response_with_trailing_metadata_and_payload_test deps_chttp2_socket_pair_one_byte_at_a_time_simple_delayed_request_test deps_chttp2_socket_pair_one_byte_at_a_time_simple_request_test deps_chttp2_socket_pair_one_byte_at_a_time_thread_stress_test deps_chttp2_socket_pair_one_byte_at_a_time_writes_done_hangs_with_pending_read_test
 
 dep_cxx: deps_libgrpc++ deps_libgrpc++_test_util
 
-bins_dep_cxx: deps_cpp_plugin deps_ruby_plugin deps_thread_pool_test deps_status_test deps_sync_client_async_server_test deps_qps_client deps_qps_server deps_interop_server deps_interop_client deps_end2end_test deps_channel_arguments_test
+bins_dep_cxx: deps_cpp_plugin deps_ruby_plugin deps_go_plugin deps_thread_pool_test deps_status_test deps_sync_client_async_server_test deps_qps_client deps_qps_server deps_interop_server deps_interop_client deps_end2end_test deps_channel_arguments_test deps_credentials_test
 
 install: install_c install_cxx
 
@@ -1074,7 +1116,7 @@ ifneq ($(SYSTEM),Darwin)
 endif
 endif
 
-clean: clean_libgpr clean_libgrpc clean_libgrpc_unsecure clean_libgrpc_test_util clean_libgrpc++ clean_libgrpc++_test_util clean_libend2end_fixture_chttp2_fake_security clean_libend2end_fixture_chttp2_fullstack clean_libend2end_fixture_chttp2_simple_ssl_fullstack clean_libend2end_fixture_chttp2_simple_ssl_with_oauth2_fullstack clean_libend2end_fixture_chttp2_socket_pair clean_libend2end_fixture_chttp2_socket_pair_one_byte_at_a_time clean_libend2end_test_cancel_after_accept clean_libend2end_test_cancel_after_accept_and_writes_closed clean_libend2end_test_cancel_after_invoke clean_libend2end_test_cancel_before_invoke clean_libend2end_test_cancel_in_a_vacuum clean_libend2end_test_disappearing_server clean_libend2end_test_early_server_shutdown_finishes_inflight_calls clean_libend2end_test_early_server_shutdown_finishes_tags clean_libend2end_test_invoke_large_request clean_libend2end_test_max_concurrent_streams clean_libend2end_test_no_op clean_libend2end_test_ping_pong_streaming clean_libend2end_test_request_response_with_binary_metadata_and_payload clean_libend2end_test_request_response_with_metadata_and_payload clean_libend2end_test_request_response_with_payload clean_libend2end_test_request_response_with_trailing_metadata_and_payload clean_libend2end_test_simple_delayed_request clean_libend2end_test_simple_request clean_libend2end_test_thread_stress clean_libend2end_test_writes_done_hangs_with_pending_read clean_libend2end_certs clean_gen_hpack_tables clean_cpp_plugin clean_ruby_plugin clean_grpc_byte_buffer_reader_test clean_gpr_cancellable_test clean_gpr_log_test clean_gpr_useful_test clean_gpr_cmdline_test clean_gpr_histogram_test clean_gpr_host_port_test clean_gpr_slice_buffer_test clean_gpr_slice_test clean_gpr_string_test clean_gpr_sync_test clean_gpr_thd_test clean_gpr_time_test clean_murmur_hash_test clean_grpc_stream_op_test clean_alpn_test clean_time_averaged_stats_test clean_chttp2_stream_encoder_test clean_hpack_table_test clean_chttp2_stream_map_test clean_hpack_parser_test clean_transport_metadata_test clean_chttp2_status_conversion_test clean_chttp2_transport_end2end_test clean_tcp_posix_test clean_dualstack_socket_test clean_no_server_test clean_resolve_address_test clean_sockaddr_utils_test clean_tcp_server_posix_test clean_tcp_client_posix_test clean_grpc_channel_stack_test clean_metadata_buffer_test clean_grpc_completion_queue_test clean_grpc_completion_queue_benchmark clean_census_window_stats_test clean_census_statistics_quick_test clean_census_statistics_small_log_test clean_census_statistics_performance_test clean_census_statistics_multiple_writers_test clean_census_statistics_multiple_writers_circular_buffer_test clean_census_stub_test clean_census_hash_table_test clean_fling_server clean_fling_client clean_fling_test clean_echo_server clean_echo_client clean_echo_test clean_low_level_ping_pong_benchmark clean_message_compress_test clean_bin_encoder_test clean_secure_endpoint_test clean_httpcli_format_request_test clean_httpcli_parser_test clean_httpcli_test clean_grpc_credentials_test clean_grpc_fetch_oauth2 clean_grpc_base64_test clean_grpc_json_token_test clean_timeout_encoding_test clean_fd_posix_test clean_fling_stream_test clean_lame_client_test clean_thread_pool_test clean_status_test clean_sync_client_async_server_test clean_qps_client clean_qps_server clean_interop_server clean_interop_client clean_end2end_test clean_channel_arguments_test clean_alarm_test clean_alarm_list_test clean_alarm_heap_test clean_time_test clean_chttp2_fake_security_cancel_after_accept_test clean_chttp2_fake_security_cancel_after_accept_and_writes_closed_test clean_chttp2_fake_security_cancel_after_invoke_test clean_chttp2_fake_security_cancel_before_invoke_test clean_chttp2_fake_security_cancel_in_a_vacuum_test clean_chttp2_fake_security_disappearing_server_test clean_chttp2_fake_security_early_server_shutdown_finishes_inflight_calls_test clean_chttp2_fake_security_early_server_shutdown_finishes_tags_test clean_chttp2_fake_security_invoke_large_request_test clean_chttp2_fake_security_max_concurrent_streams_test clean_chttp2_fake_security_no_op_test clean_chttp2_fake_security_ping_pong_streaming_test clean_chttp2_fake_security_request_response_with_binary_metadata_and_payload_test clean_chttp2_fake_security_request_response_with_metadata_and_payload_test clean_chttp2_fake_security_request_response_with_payload_test clean_chttp2_fake_security_request_response_with_trailing_metadata_and_payload_test clean_chttp2_fake_security_simple_delayed_request_test clean_chttp2_fake_security_simple_request_test clean_chttp2_fake_security_thread_stress_test clean_chttp2_fake_security_writes_done_hangs_with_pending_read_test clean_chttp2_fullstack_cancel_after_accept_test clean_chttp2_fullstack_cancel_after_accept_and_writes_closed_test clean_chttp2_fullstack_cancel_after_invoke_test clean_chttp2_fullstack_cancel_before_invoke_test clean_chttp2_fullstack_cancel_in_a_vacuum_test clean_chttp2_fullstack_disappearing_server_test clean_chttp2_fullstack_early_server_shutdown_finishes_inflight_calls_test clean_chttp2_fullstack_early_server_shutdown_finishes_tags_test clean_chttp2_fullstack_invoke_large_request_test clean_chttp2_fullstack_max_concurrent_streams_test clean_chttp2_fullstack_no_op_test clean_chttp2_fullstack_ping_pong_streaming_test clean_chttp2_fullstack_request_response_with_binary_metadata_and_payload_test clean_chttp2_fullstack_request_response_with_metadata_and_payload_test clean_chttp2_fullstack_request_response_with_payload_test clean_chttp2_fullstack_request_response_with_trailing_metadata_and_payload_test clean_chttp2_fullstack_simple_delayed_request_test clean_chttp2_fullstack_simple_request_test clean_chttp2_fullstack_thread_stress_test clean_chttp2_fullstack_writes_done_hangs_with_pending_read_test clean_chttp2_simple_ssl_fullstack_cancel_after_accept_test clean_chttp2_simple_ssl_fullstack_cancel_after_accept_and_writes_closed_test clean_chttp2_simple_ssl_fullstack_cancel_after_invoke_test clean_chttp2_simple_ssl_fullstack_cancel_before_invoke_test clean_chttp2_simple_ssl_fullstack_cancel_in_a_vacuum_test clean_chttp2_simple_ssl_fullstack_disappearing_server_test clean_chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_inflight_calls_test clean_chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_tags_test clean_chttp2_simple_ssl_fullstack_invoke_large_request_test clean_chttp2_simple_ssl_fullstack_max_concurrent_streams_test clean_chttp2_simple_ssl_fullstack_no_op_test clean_chttp2_simple_ssl_fullstack_ping_pong_streaming_test clean_chttp2_simple_ssl_fullstack_request_response_with_binary_metadata_and_payload_test clean_chttp2_simple_ssl_fullstack_request_response_with_metadata_and_payload_test clean_chttp2_simple_ssl_fullstack_request_response_with_payload_test clean_chttp2_simple_ssl_fullstack_request_response_with_trailing_metadata_and_payload_test clean_chttp2_simple_ssl_fullstack_simple_delayed_request_test clean_chttp2_simple_ssl_fullstack_simple_request_test clean_chttp2_simple_ssl_fullstack_thread_stress_test clean_chttp2_simple_ssl_fullstack_writes_done_hangs_with_pending_read_test clean_chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_accept_test clean_chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_accept_and_writes_closed_test clean_chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_invoke_test clean_chttp2_simple_ssl_with_oauth2_fullstack_cancel_before_invoke_test clean_chttp2_simple_ssl_with_oauth2_fullstack_cancel_in_a_vacuum_test clean_chttp2_simple_ssl_with_oauth2_fullstack_disappearing_server_test clean_chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_inflight_calls_test clean_chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_tags_test clean_chttp2_simple_ssl_with_oauth2_fullstack_invoke_large_request_test clean_chttp2_simple_ssl_with_oauth2_fullstack_max_concurrent_streams_test clean_chttp2_simple_ssl_with_oauth2_fullstack_no_op_test clean_chttp2_simple_ssl_with_oauth2_fullstack_ping_pong_streaming_test clean_chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_binary_metadata_and_payload_test clean_chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_metadata_and_payload_test clean_chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_payload_test clean_chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_trailing_metadata_and_payload_test clean_chttp2_simple_ssl_with_oauth2_fullstack_simple_delayed_request_test clean_chttp2_simple_ssl_with_oauth2_fullstack_simple_request_test clean_chttp2_simple_ssl_with_oauth2_fullstack_thread_stress_test clean_chttp2_simple_ssl_with_oauth2_fullstack_writes_done_hangs_with_pending_read_test clean_chttp2_socket_pair_cancel_after_accept_test clean_chttp2_socket_pair_cancel_after_accept_and_writes_closed_test clean_chttp2_socket_pair_cancel_after_invoke_test clean_chttp2_socket_pair_cancel_before_invoke_test clean_chttp2_socket_pair_cancel_in_a_vacuum_test clean_chttp2_socket_pair_disappearing_server_test clean_chttp2_socket_pair_early_server_shutdown_finishes_inflight_calls_test clean_chttp2_socket_pair_early_server_shutdown_finishes_tags_test clean_chttp2_socket_pair_invoke_large_request_test clean_chttp2_socket_pair_max_concurrent_streams_test clean_chttp2_socket_pair_no_op_test clean_chttp2_socket_pair_ping_pong_streaming_test clean_chttp2_socket_pair_request_response_with_binary_metadata_and_payload_test clean_chttp2_socket_pair_request_response_with_metadata_and_payload_test clean_chttp2_socket_pair_request_response_with_payload_test clean_chttp2_socket_pair_request_response_with_trailing_metadata_and_payload_test clean_chttp2_socket_pair_simple_delayed_request_test clean_chttp2_socket_pair_simple_request_test clean_chttp2_socket_pair_thread_stress_test clean_chttp2_socket_pair_writes_done_hangs_with_pending_read_test clean_chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_test clean_chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_and_writes_closed_test clean_chttp2_socket_pair_one_byte_at_a_time_cancel_after_invoke_test clean_chttp2_socket_pair_one_byte_at_a_time_cancel_before_invoke_test clean_chttp2_socket_pair_one_byte_at_a_time_cancel_in_a_vacuum_test clean_chttp2_socket_pair_one_byte_at_a_time_disappearing_server_test clean_chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_inflight_calls_test clean_chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_tags_test clean_chttp2_socket_pair_one_byte_at_a_time_invoke_large_request_test clean_chttp2_socket_pair_one_byte_at_a_time_max_concurrent_streams_test clean_chttp2_socket_pair_one_byte_at_a_time_no_op_test clean_chttp2_socket_pair_one_byte_at_a_time_ping_pong_streaming_test clean_chttp2_socket_pair_one_byte_at_a_time_request_response_with_binary_metadata_and_payload_test clean_chttp2_socket_pair_one_byte_at_a_time_request_response_with_metadata_and_payload_test clean_chttp2_socket_pair_one_byte_at_a_time_request_response_with_payload_test clean_chttp2_socket_pair_one_byte_at_a_time_request_response_with_trailing_metadata_and_payload_test clean_chttp2_socket_pair_one_byte_at_a_time_simple_delayed_request_test clean_chttp2_socket_pair_one_byte_at_a_time_simple_request_test clean_chttp2_socket_pair_one_byte_at_a_time_thread_stress_test clean_chttp2_socket_pair_one_byte_at_a_time_writes_done_hangs_with_pending_read_test
+clean: clean_libgpr clean_libgrpc clean_libgrpc_unsecure clean_libgrpc_test_util clean_libgrpc++ clean_libgrpc++_test_util clean_libend2end_fixture_chttp2_fake_security clean_libend2end_fixture_chttp2_fullstack clean_libend2end_fixture_chttp2_simple_ssl_fullstack clean_libend2end_fixture_chttp2_simple_ssl_with_oauth2_fullstack clean_libend2end_fixture_chttp2_socket_pair clean_libend2end_fixture_chttp2_socket_pair_one_byte_at_a_time clean_libend2end_test_cancel_after_accept clean_libend2end_test_cancel_after_accept_and_writes_closed clean_libend2end_test_cancel_after_invoke clean_libend2end_test_cancel_before_invoke clean_libend2end_test_cancel_in_a_vacuum clean_libend2end_test_census_simple_request clean_libend2end_test_disappearing_server clean_libend2end_test_early_server_shutdown_finishes_inflight_calls clean_libend2end_test_early_server_shutdown_finishes_tags clean_libend2end_test_invoke_large_request clean_libend2end_test_max_concurrent_streams clean_libend2end_test_no_op clean_libend2end_test_ping_pong_streaming clean_libend2end_test_request_response_with_binary_metadata_and_payload clean_libend2end_test_request_response_with_metadata_and_payload clean_libend2end_test_request_response_with_payload clean_libend2end_test_request_response_with_trailing_metadata_and_payload clean_libend2end_test_simple_delayed_request clean_libend2end_test_simple_request clean_libend2end_test_thread_stress clean_libend2end_test_writes_done_hangs_with_pending_read clean_libend2end_certs clean_gen_hpack_tables clean_cpp_plugin clean_ruby_plugin clean_go_plugin clean_grpc_byte_buffer_reader_test clean_gpr_cancellable_test clean_gpr_log_test clean_gpr_useful_test clean_gpr_cmdline_test clean_gpr_histogram_test clean_gpr_host_port_test clean_gpr_slice_buffer_test clean_gpr_slice_test clean_gpr_string_test clean_gpr_sync_test clean_gpr_thd_test clean_gpr_time_test clean_murmur_hash_test clean_grpc_stream_op_test clean_alpn_test clean_time_averaged_stats_test clean_chttp2_stream_encoder_test clean_hpack_table_test clean_chttp2_stream_map_test clean_hpack_parser_test clean_transport_metadata_test clean_chttp2_status_conversion_test clean_chttp2_transport_end2end_test clean_tcp_posix_test clean_dualstack_socket_test clean_no_server_test clean_resolve_address_test clean_sockaddr_utils_test clean_tcp_server_posix_test clean_tcp_client_posix_test clean_grpc_channel_stack_test clean_metadata_buffer_test clean_grpc_completion_queue_test clean_grpc_completion_queue_benchmark clean_census_trace_store_test clean_census_stats_store_test clean_census_window_stats_test clean_census_statistics_quick_test clean_census_statistics_small_log_test clean_census_statistics_performance_test clean_census_statistics_multiple_writers_test clean_census_statistics_multiple_writers_circular_buffer_test clean_census_stub_test clean_census_hash_table_test clean_fling_server clean_fling_client clean_fling_test clean_echo_server clean_echo_client clean_echo_test clean_low_level_ping_pong_benchmark clean_message_compress_test clean_bin_encoder_test clean_secure_endpoint_test clean_httpcli_format_request_test clean_httpcli_parser_test clean_httpcli_test clean_grpc_credentials_test clean_grpc_fetch_oauth2 clean_grpc_base64_test clean_grpc_json_token_test clean_timeout_encoding_test clean_fd_posix_test clean_fling_stream_test clean_lame_client_test clean_thread_pool_test clean_status_test clean_sync_client_async_server_test clean_qps_client clean_qps_server clean_interop_server clean_interop_client clean_end2end_test clean_channel_arguments_test clean_credentials_test clean_alarm_test clean_alarm_list_test clean_alarm_heap_test clean_time_test clean_chttp2_fake_security_cancel_after_accept_test clean_chttp2_fake_security_cancel_after_accept_and_writes_closed_test clean_chttp2_fake_security_cancel_after_invoke_test clean_chttp2_fake_security_cancel_before_invoke_test clean_chttp2_fake_security_cancel_in_a_vacuum_test clean_chttp2_fake_security_census_simple_request_test clean_chttp2_fake_security_disappearing_server_test clean_chttp2_fake_security_early_server_shutdown_finishes_inflight_calls_test clean_chttp2_fake_security_early_server_shutdown_finishes_tags_test clean_chttp2_fake_security_invoke_large_request_test clean_chttp2_fake_security_max_concurrent_streams_test clean_chttp2_fake_security_no_op_test clean_chttp2_fake_security_ping_pong_streaming_test clean_chttp2_fake_security_request_response_with_binary_metadata_and_payload_test clean_chttp2_fake_security_request_response_with_metadata_and_payload_test clean_chttp2_fake_security_request_response_with_payload_test clean_chttp2_fake_security_request_response_with_trailing_metadata_and_payload_test clean_chttp2_fake_security_simple_delayed_request_test clean_chttp2_fake_security_simple_request_test clean_chttp2_fake_security_thread_stress_test clean_chttp2_fake_security_writes_done_hangs_with_pending_read_test clean_chttp2_fullstack_cancel_after_accept_test clean_chttp2_fullstack_cancel_after_accept_and_writes_closed_test clean_chttp2_fullstack_cancel_after_invoke_test clean_chttp2_fullstack_cancel_before_invoke_test clean_chttp2_fullstack_cancel_in_a_vacuum_test clean_chttp2_fullstack_census_simple_request_test clean_chttp2_fullstack_disappearing_server_test clean_chttp2_fullstack_early_server_shutdown_finishes_inflight_calls_test clean_chttp2_fullstack_early_server_shutdown_finishes_tags_test clean_chttp2_fullstack_invoke_large_request_test clean_chttp2_fullstack_max_concurrent_streams_test clean_chttp2_fullstack_no_op_test clean_chttp2_fullstack_ping_pong_streaming_test clean_chttp2_fullstack_request_response_with_binary_metadata_and_payload_test clean_chttp2_fullstack_request_response_with_metadata_and_payload_test clean_chttp2_fullstack_request_response_with_payload_test clean_chttp2_fullstack_request_response_with_trailing_metadata_and_payload_test clean_chttp2_fullstack_simple_delayed_request_test clean_chttp2_fullstack_simple_request_test clean_chttp2_fullstack_thread_stress_test clean_chttp2_fullstack_writes_done_hangs_with_pending_read_test clean_chttp2_simple_ssl_fullstack_cancel_after_accept_test clean_chttp2_simple_ssl_fullstack_cancel_after_accept_and_writes_closed_test clean_chttp2_simple_ssl_fullstack_cancel_after_invoke_test clean_chttp2_simple_ssl_fullstack_cancel_before_invoke_test clean_chttp2_simple_ssl_fullstack_cancel_in_a_vacuum_test clean_chttp2_simple_ssl_fullstack_census_simple_request_test clean_chttp2_simple_ssl_fullstack_disappearing_server_test clean_chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_inflight_calls_test clean_chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_tags_test clean_chttp2_simple_ssl_fullstack_invoke_large_request_test clean_chttp2_simple_ssl_fullstack_max_concurrent_streams_test clean_chttp2_simple_ssl_fullstack_no_op_test clean_chttp2_simple_ssl_fullstack_ping_pong_streaming_test clean_chttp2_simple_ssl_fullstack_request_response_with_binary_metadata_and_payload_test clean_chttp2_simple_ssl_fullstack_request_response_with_metadata_and_payload_test clean_chttp2_simple_ssl_fullstack_request_response_with_payload_test clean_chttp2_simple_ssl_fullstack_request_response_with_trailing_metadata_and_payload_test clean_chttp2_simple_ssl_fullstack_simple_delayed_request_test clean_chttp2_simple_ssl_fullstack_simple_request_test clean_chttp2_simple_ssl_fullstack_thread_stress_test clean_chttp2_simple_ssl_fullstack_writes_done_hangs_with_pending_read_test clean_chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_accept_test clean_chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_accept_and_writes_closed_test clean_chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_invoke_test clean_chttp2_simple_ssl_with_oauth2_fullstack_cancel_before_invoke_test clean_chttp2_simple_ssl_with_oauth2_fullstack_cancel_in_a_vacuum_test clean_chttp2_simple_ssl_with_oauth2_fullstack_census_simple_request_test clean_chttp2_simple_ssl_with_oauth2_fullstack_disappearing_server_test clean_chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_inflight_calls_test clean_chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_tags_test clean_chttp2_simple_ssl_with_oauth2_fullstack_invoke_large_request_test clean_chttp2_simple_ssl_with_oauth2_fullstack_max_concurrent_streams_test clean_chttp2_simple_ssl_with_oauth2_fullstack_no_op_test clean_chttp2_simple_ssl_with_oauth2_fullstack_ping_pong_streaming_test clean_chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_binary_metadata_and_payload_test clean_chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_metadata_and_payload_test clean_chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_payload_test clean_chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_trailing_metadata_and_payload_test clean_chttp2_simple_ssl_with_oauth2_fullstack_simple_delayed_request_test clean_chttp2_simple_ssl_with_oauth2_fullstack_simple_request_test clean_chttp2_simple_ssl_with_oauth2_fullstack_thread_stress_test clean_chttp2_simple_ssl_with_oauth2_fullstack_writes_done_hangs_with_pending_read_test clean_chttp2_socket_pair_cancel_after_accept_test clean_chttp2_socket_pair_cancel_after_accept_and_writes_closed_test clean_chttp2_socket_pair_cancel_after_invoke_test clean_chttp2_socket_pair_cancel_before_invoke_test clean_chttp2_socket_pair_cancel_in_a_vacuum_test clean_chttp2_socket_pair_census_simple_request_test clean_chttp2_socket_pair_disappearing_server_test clean_chttp2_socket_pair_early_server_shutdown_finishes_inflight_calls_test clean_chttp2_socket_pair_early_server_shutdown_finishes_tags_test clean_chttp2_socket_pair_invoke_large_request_test clean_chttp2_socket_pair_max_concurrent_streams_test clean_chttp2_socket_pair_no_op_test clean_chttp2_socket_pair_ping_pong_streaming_test clean_chttp2_socket_pair_request_response_with_binary_metadata_and_payload_test clean_chttp2_socket_pair_request_response_with_metadata_and_payload_test clean_chttp2_socket_pair_request_response_with_payload_test clean_chttp2_socket_pair_request_response_with_trailing_metadata_and_payload_test clean_chttp2_socket_pair_simple_delayed_request_test clean_chttp2_socket_pair_simple_request_test clean_chttp2_socket_pair_thread_stress_test clean_chttp2_socket_pair_writes_done_hangs_with_pending_read_test clean_chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_test clean_chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_and_writes_closed_test clean_chttp2_socket_pair_one_byte_at_a_time_cancel_after_invoke_test clean_chttp2_socket_pair_one_byte_at_a_time_cancel_before_invoke_test clean_chttp2_socket_pair_one_byte_at_a_time_cancel_in_a_vacuum_test clean_chttp2_socket_pair_one_byte_at_a_time_census_simple_request_test clean_chttp2_socket_pair_one_byte_at_a_time_disappearing_server_test clean_chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_inflight_calls_test clean_chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_tags_test clean_chttp2_socket_pair_one_byte_at_a_time_invoke_large_request_test clean_chttp2_socket_pair_one_byte_at_a_time_max_concurrent_streams_test clean_chttp2_socket_pair_one_byte_at_a_time_no_op_test clean_chttp2_socket_pair_one_byte_at_a_time_ping_pong_streaming_test clean_chttp2_socket_pair_one_byte_at_a_time_request_response_with_binary_metadata_and_payload_test clean_chttp2_socket_pair_one_byte_at_a_time_request_response_with_metadata_and_payload_test clean_chttp2_socket_pair_one_byte_at_a_time_request_response_with_payload_test clean_chttp2_socket_pair_one_byte_at_a_time_request_response_with_trailing_metadata_and_payload_test clean_chttp2_socket_pair_one_byte_at_a_time_simple_delayed_request_test clean_chttp2_socket_pair_one_byte_at_a_time_simple_request_test clean_chttp2_socket_pair_one_byte_at_a_time_thread_stress_test clean_chttp2_socket_pair_one_byte_at_a_time_writes_done_hangs_with_pending_read_test
 	$(Q) $(RM) -r deps objs libs bins gens
 
 
@@ -1532,7 +1574,7 @@ LIBGRPC++_SRC = \
     src/cpp/client/credentials.cc \
     src/cpp/client/internal_stub.cc \
     src/cpp/proto/proto_utils.cc \
-    src/cpp/rpc_method.cc \
+    src/cpp/common/rpc_method.cc \
     src/cpp/server/async_server.cc \
     src/cpp/server/async_server_context.cc \
     src/cpp/server/completion_queue.cc \
@@ -1556,6 +1598,9 @@ PUBLIC_HEADERS_CXX += \
     include/grpc++/config.h \
     include/grpc++/create_channel.h \
     include/grpc++/credentials.h \
+    include/grpc++/impl/internal_stub.h \
+    include/grpc++/impl/rpc_method.h \
+    include/grpc++/impl/rpc_service_method.h \
     include/grpc++/server_builder.h \
     include/grpc++/server_context.h \
     include/grpc++/server_credentials.h \
@@ -1623,7 +1668,9 @@ clean_libgrpc++:
 
 
 LIBGRPC++_TEST_UTIL_SRC = \
+    gens/test/cpp/util/messages.pb.cc \
     gens/test/cpp/util/echo.pb.cc \
+    gens/test/cpp/util/echo_duplicate.pb.cc \
     test/cpp/util/create_test_channel.cc \
     test/cpp/end2end/async_test_server.cc \
 
@@ -2061,6 +2108,36 @@ clean_libend2end_test_cancel_in_a_vacuum:
 	$(Q) $(RM) libs/$(CONFIG)/libend2end_test_cancel_in_a_vacuum.$(SHARED_EXT)
 
 
+LIBEND2END_TEST_CENSUS_SIMPLE_REQUEST_SRC = \
+    test/core/end2end/tests/census_simple_request.c \
+
+
+LIBEND2END_TEST_CENSUS_SIMPLE_REQUEST_OBJS = $(addprefix objs/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBEND2END_TEST_CENSUS_SIMPLE_REQUEST_SRC))))
+LIBEND2END_TEST_CENSUS_SIMPLE_REQUEST_DEPS = $(addprefix deps/$(CONFIG)/, $(addsuffix .dep, $(basename $(LIBEND2END_TEST_CENSUS_SIMPLE_REQUEST_SRC))))
+
+libs/$(CONFIG)/libend2end_test_census_simple_request.a: $(LIBEND2END_TEST_CENSUS_SIMPLE_REQUEST_OBJS)
+	$(E) "[AR]      Creating $@"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(AR) rcs libs/$(CONFIG)/libend2end_test_census_simple_request.a $(LIBEND2END_TEST_CENSUS_SIMPLE_REQUEST_OBJS)
+
+
+
+
+
+deps_libend2end_test_census_simple_request: $(LIBEND2END_TEST_CENSUS_SIMPLE_REQUEST_DEPS)
+
+ifneq ($(NO_DEPS),true)
+-include $(LIBEND2END_TEST_CENSUS_SIMPLE_REQUEST_DEPS)
+endif
+
+clean_libend2end_test_census_simple_request:
+	$(E) "[CLEAN]   Cleaning libend2end_test_census_simple_request files"
+	$(Q) $(RM) $(LIBEND2END_TEST_CENSUS_SIMPLE_REQUEST_OBJS)
+	$(Q) $(RM) $(LIBEND2END_TEST_CENSUS_SIMPLE_REQUEST_DEPS)
+	$(Q) $(RM) libs/$(CONFIG)/libend2end_test_census_simple_request.a
+	$(Q) $(RM) libs/$(CONFIG)/libend2end_test_census_simple_request.$(SHARED_EXT)
+
+
 LIBEND2END_TEST_DISAPPEARING_SERVER_SRC = \
     test/core/end2end/tests/disappearing_server.c \
 
@@ -2643,6 +2720,31 @@ clean_ruby_plugin:
 	$(Q) $(RM) bins/$(CONFIG)/ruby_plugin
 
 
+GO_PLUGIN_SRC = \
+    src/compiler/go_plugin.cpp \
+    src/compiler/go_generator.cpp \
+
+GO_PLUGIN_OBJS = $(addprefix objs/$(CONFIG)/, $(addsuffix .o, $(basename $(GO_PLUGIN_SRC))))
+GO_PLUGIN_DEPS = $(addprefix deps/$(CONFIG)/, $(addsuffix .dep, $(basename $(GO_PLUGIN_SRC))))
+
+bins/$(CONFIG)/go_plugin: $(GO_PLUGIN_OBJS)
+	$(E) "[HOSTLD]  Linking $@"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(HOST_LDXX) $(HOST_LDFLAGS) $(GO_PLUGIN_OBJS) $(HOST_LDLIBSXX) $(HOST_LDLIBS) $(HOST_LDLIBS_PROTOC) -o bins/$(CONFIG)/go_plugin
+
+deps_go_plugin: $(GO_PLUGIN_DEPS)
+
+ifneq ($(NO_DEPS),true)
+-include $(GO_PLUGIN_DEPS)
+endif
+
+clean_go_plugin:
+	$(E) "[CLEAN]   Cleaning go_plugin files"
+	$(Q) $(RM) $(GO_PLUGIN_OBJS)
+	$(Q) $(RM) $(GO_PLUGIN_DEPS)
+	$(Q) $(RM) bins/$(CONFIG)/go_plugin
+
+
 GRPC_BYTE_BUFFER_READER_TEST_SRC = \
     test/core/surface/byte_buffer_reader_test.c \
 
@@ -3833,6 +3935,74 @@ clean_grpc_completion_queue_benchmark:
 	$(Q) $(RM) bins/$(CONFIG)/grpc_completion_queue_benchmark
 
 
+CENSUS_TRACE_STORE_TEST_SRC = \
+    test/core/statistics/trace_test.c \
+
+CENSUS_TRACE_STORE_TEST_OBJS = $(addprefix objs/$(CONFIG)/, $(addsuffix .o, $(basename $(CENSUS_TRACE_STORE_TEST_SRC))))
+CENSUS_TRACE_STORE_TEST_DEPS = $(addprefix deps/$(CONFIG)/, $(addsuffix .dep, $(basename $(CENSUS_TRACE_STORE_TEST_SRC))))
+
+ifeq ($(NO_SECURE),true)
+
+bins/$(CONFIG)/census_trace_store_test: openssl_dep_error
+
+else
+
+bins/$(CONFIG)/census_trace_store_test: $(CENSUS_TRACE_STORE_TEST_OBJS) libs/$(CONFIG)/libgrpc_test_util.a libs/$(CONFIG)/libgrpc.a libs/$(CONFIG)/libgpr.a
+	$(E) "[LD]      Linking $@"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(LD) $(LDFLAGS) $(CENSUS_TRACE_STORE_TEST_OBJS) libs/$(CONFIG)/libgrpc_test_util.a libs/$(CONFIG)/libgrpc.a libs/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o bins/$(CONFIG)/census_trace_store_test
+
+endif
+
+deps_census_trace_store_test: $(CENSUS_TRACE_STORE_TEST_DEPS)
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(CENSUS_TRACE_STORE_TEST_DEPS)
+endif
+endif
+
+clean_census_trace_store_test:
+	$(E) "[CLEAN]   Cleaning census_trace_store_test files"
+	$(Q) $(RM) $(CENSUS_TRACE_STORE_TEST_OBJS)
+	$(Q) $(RM) $(CENSUS_TRACE_STORE_TEST_DEPS)
+	$(Q) $(RM) bins/$(CONFIG)/census_trace_store_test
+
+
+CENSUS_STATS_STORE_TEST_SRC = \
+    test/core/statistics/rpc_stats_test.c \
+
+CENSUS_STATS_STORE_TEST_OBJS = $(addprefix objs/$(CONFIG)/, $(addsuffix .o, $(basename $(CENSUS_STATS_STORE_TEST_SRC))))
+CENSUS_STATS_STORE_TEST_DEPS = $(addprefix deps/$(CONFIG)/, $(addsuffix .dep, $(basename $(CENSUS_STATS_STORE_TEST_SRC))))
+
+ifeq ($(NO_SECURE),true)
+
+bins/$(CONFIG)/census_stats_store_test: openssl_dep_error
+
+else
+
+bins/$(CONFIG)/census_stats_store_test: $(CENSUS_STATS_STORE_TEST_OBJS) libs/$(CONFIG)/libgrpc_test_util.a libs/$(CONFIG)/libgrpc.a libs/$(CONFIG)/libgpr.a
+	$(E) "[LD]      Linking $@"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(LD) $(LDFLAGS) $(CENSUS_STATS_STORE_TEST_OBJS) libs/$(CONFIG)/libgrpc_test_util.a libs/$(CONFIG)/libgrpc.a libs/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o bins/$(CONFIG)/census_stats_store_test
+
+endif
+
+deps_census_stats_store_test: $(CENSUS_STATS_STORE_TEST_DEPS)
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(CENSUS_STATS_STORE_TEST_DEPS)
+endif
+endif
+
+clean_census_stats_store_test:
+	$(E) "[CLEAN]   Cleaning census_stats_store_test files"
+	$(Q) $(RM) $(CENSUS_STATS_STORE_TEST_OBJS)
+	$(Q) $(RM) $(CENSUS_STATS_STORE_TEST_DEPS)
+	$(Q) $(RM) bins/$(CONFIG)/census_stats_store_test
+
+
 CENSUS_WINDOW_STATS_TEST_SRC = \
     test/core/statistics/window_stats_test.c \
 
@@ -5081,10 +5251,10 @@ bins/$(CONFIG)/end2end_test: openssl_dep_error
 
 else
 
-bins/$(CONFIG)/end2end_test: $(END2END_TEST_OBJS) libs/$(CONFIG)/libgrpc_test_util.a libs/$(CONFIG)/libgrpc++.a libs/$(CONFIG)/libgrpc.a libs/$(CONFIG)/libgpr.a
+bins/$(CONFIG)/end2end_test: $(END2END_TEST_OBJS) libs/$(CONFIG)/libgrpc++_test_util.a libs/$(CONFIG)/libgrpc_test_util.a libs/$(CONFIG)/libgrpc++.a libs/$(CONFIG)/libgrpc.a libs/$(CONFIG)/libgpr.a
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(LDXX) $(LDFLAGS) $(END2END_TEST_OBJS) $(GTEST_LIB) libs/$(CONFIG)/libgrpc_test_util.a libs/$(CONFIG)/libgrpc++.a libs/$(CONFIG)/libgrpc.a libs/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS) $(LDLIBS_SECURE) -o bins/$(CONFIG)/end2end_test
+	$(Q) $(LDXX) $(LDFLAGS) $(END2END_TEST_OBJS) $(GTEST_LIB) libs/$(CONFIG)/libgrpc++_test_util.a libs/$(CONFIG)/libgrpc_test_util.a libs/$(CONFIG)/libgrpc++.a libs/$(CONFIG)/libgrpc.a libs/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS) $(LDLIBS_SECURE) -o bins/$(CONFIG)/end2end_test
 
 endif
 
@@ -5137,6 +5307,40 @@ clean_channel_arguments_test:
 	$(Q) $(RM) bins/$(CONFIG)/channel_arguments_test
 
 
+CREDENTIALS_TEST_SRC = \
+    test/cpp/client/credentials_test.cc \
+
+CREDENTIALS_TEST_OBJS = $(addprefix objs/$(CONFIG)/, $(addsuffix .o, $(basename $(CREDENTIALS_TEST_SRC))))
+CREDENTIALS_TEST_DEPS = $(addprefix deps/$(CONFIG)/, $(addsuffix .dep, $(basename $(CREDENTIALS_TEST_SRC))))
+
+ifeq ($(NO_SECURE),true)
+
+bins/$(CONFIG)/credentials_test: openssl_dep_error
+
+else
+
+bins/$(CONFIG)/credentials_test: $(CREDENTIALS_TEST_OBJS) libs/$(CONFIG)/libgrpc++.a libs/$(CONFIG)/libgrpc.a
+	$(E) "[LD]      Linking $@"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(LDXX) $(LDFLAGS) $(CREDENTIALS_TEST_OBJS) $(GTEST_LIB) libs/$(CONFIG)/libgrpc++.a libs/$(CONFIG)/libgrpc.a $(LDLIBSXX) $(LDLIBS) $(LDLIBS_SECURE) -o bins/$(CONFIG)/credentials_test
+
+endif
+
+deps_credentials_test: $(CREDENTIALS_TEST_DEPS)
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(CREDENTIALS_TEST_DEPS)
+endif
+endif
+
+clean_credentials_test:
+	$(E) "[CLEAN]   Cleaning credentials_test files"
+	$(Q) $(RM) $(CREDENTIALS_TEST_OBJS)
+	$(Q) $(RM) $(CREDENTIALS_TEST_DEPS)
+	$(Q) $(RM) bins/$(CONFIG)/credentials_test
+
+
 ALARM_TEST_SRC = \
     test/core/iomgr/alarm_test.c \
 
@@ -5438,6 +5642,39 @@ clean_chttp2_fake_security_cancel_in_a_vacuum_test:
 	$(Q) $(RM) bins/$(CONFIG)/chttp2_fake_security_cancel_in_a_vacuum_test
 
 
+CHTTP2_FAKE_SECURITY_CENSUS_SIMPLE_REQUEST_TEST_SRC = \
+
+CHTTP2_FAKE_SECURITY_CENSUS_SIMPLE_REQUEST_TEST_OBJS = $(addprefix objs/$(CONFIG)/, $(addsuffix .o, $(basename $(CHTTP2_FAKE_SECURITY_CENSUS_SIMPLE_REQUEST_TEST_SRC))))
+CHTTP2_FAKE_SECURITY_CENSUS_SIMPLE_REQUEST_TEST_DEPS = $(addprefix deps/$(CONFIG)/, $(addsuffix .dep, $(basename $(CHTTP2_FAKE_SECURITY_CENSUS_SIMPLE_REQUEST_TEST_SRC))))
+
+ifeq ($(NO_SECURE),true)
+
+bins/$(CONFIG)/chttp2_fake_security_census_simple_request_test: openssl_dep_error
+
+else
+
+bins/$(CONFIG)/chttp2_fake_security_census_simple_request_test: $(CHTTP2_FAKE_SECURITY_CENSUS_SIMPLE_REQUEST_TEST_OBJS) libs/$(CONFIG)/libend2end_fixture_chttp2_fake_security.a libs/$(CONFIG)/libend2end_test_census_simple_request.a libs/$(CONFIG)/libend2end_certs.a libs/$(CONFIG)/libgrpc_test_util.a libs/$(CONFIG)/libgrpc.a libs/$(CONFIG)/libgpr.a
+	$(E) "[LD]      Linking $@"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(LD) $(LDFLAGS) $(CHTTP2_FAKE_SECURITY_CENSUS_SIMPLE_REQUEST_TEST_OBJS) libs/$(CONFIG)/libend2end_fixture_chttp2_fake_security.a libs/$(CONFIG)/libend2end_test_census_simple_request.a libs/$(CONFIG)/libend2end_certs.a libs/$(CONFIG)/libgrpc_test_util.a libs/$(CONFIG)/libgrpc.a libs/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o bins/$(CONFIG)/chttp2_fake_security_census_simple_request_test
+
+endif
+
+deps_chttp2_fake_security_census_simple_request_test: $(CHTTP2_FAKE_SECURITY_CENSUS_SIMPLE_REQUEST_TEST_DEPS)
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(CHTTP2_FAKE_SECURITY_CENSUS_SIMPLE_REQUEST_TEST_DEPS)
+endif
+endif
+
+clean_chttp2_fake_security_census_simple_request_test:
+	$(E) "[CLEAN]   Cleaning chttp2_fake_security_census_simple_request_test files"
+	$(Q) $(RM) $(CHTTP2_FAKE_SECURITY_CENSUS_SIMPLE_REQUEST_TEST_OBJS)
+	$(Q) $(RM) $(CHTTP2_FAKE_SECURITY_CENSUS_SIMPLE_REQUEST_TEST_DEPS)
+	$(Q) $(RM) bins/$(CONFIG)/chttp2_fake_security_census_simple_request_test
+
+
 CHTTP2_FAKE_SECURITY_DISAPPEARING_SERVER_TEST_SRC = \
 
 CHTTP2_FAKE_SECURITY_DISAPPEARING_SERVER_TEST_OBJS = $(addprefix objs/$(CONFIG)/, $(addsuffix .o, $(basename $(CHTTP2_FAKE_SECURITY_DISAPPEARING_SERVER_TEST_SRC))))
@@ -6098,6 +6335,39 @@ clean_chttp2_fullstack_cancel_in_a_vacuum_test:
 	$(Q) $(RM) bins/$(CONFIG)/chttp2_fullstack_cancel_in_a_vacuum_test
 
 
+CHTTP2_FULLSTACK_CENSUS_SIMPLE_REQUEST_TEST_SRC = \
+
+CHTTP2_FULLSTACK_CENSUS_SIMPLE_REQUEST_TEST_OBJS = $(addprefix objs/$(CONFIG)/, $(addsuffix .o, $(basename $(CHTTP2_FULLSTACK_CENSUS_SIMPLE_REQUEST_TEST_SRC))))
+CHTTP2_FULLSTACK_CENSUS_SIMPLE_REQUEST_TEST_DEPS = $(addprefix deps/$(CONFIG)/, $(addsuffix .dep, $(basename $(CHTTP2_FULLSTACK_CENSUS_SIMPLE_REQUEST_TEST_SRC))))
+
+ifeq ($(NO_SECURE),true)
+
+bins/$(CONFIG)/chttp2_fullstack_census_simple_request_test: openssl_dep_error
+
+else
+
+bins/$(CONFIG)/chttp2_fullstack_census_simple_request_test: $(CHTTP2_FULLSTACK_CENSUS_SIMPLE_REQUEST_TEST_OBJS) libs/$(CONFIG)/libend2end_fixture_chttp2_fullstack.a libs/$(CONFIG)/libend2end_test_census_simple_request.a libs/$(CONFIG)/libend2end_certs.a libs/$(CONFIG)/libgrpc_test_util.a libs/$(CONFIG)/libgrpc.a libs/$(CONFIG)/libgpr.a
+	$(E) "[LD]      Linking $@"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(LD) $(LDFLAGS) $(CHTTP2_FULLSTACK_CENSUS_SIMPLE_REQUEST_TEST_OBJS) libs/$(CONFIG)/libend2end_fixture_chttp2_fullstack.a libs/$(CONFIG)/libend2end_test_census_simple_request.a libs/$(CONFIG)/libend2end_certs.a libs/$(CONFIG)/libgrpc_test_util.a libs/$(CONFIG)/libgrpc.a libs/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o bins/$(CONFIG)/chttp2_fullstack_census_simple_request_test
+
+endif
+
+deps_chttp2_fullstack_census_simple_request_test: $(CHTTP2_FULLSTACK_CENSUS_SIMPLE_REQUEST_TEST_DEPS)
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(CHTTP2_FULLSTACK_CENSUS_SIMPLE_REQUEST_TEST_DEPS)
+endif
+endif
+
+clean_chttp2_fullstack_census_simple_request_test:
+	$(E) "[CLEAN]   Cleaning chttp2_fullstack_census_simple_request_test files"
+	$(Q) $(RM) $(CHTTP2_FULLSTACK_CENSUS_SIMPLE_REQUEST_TEST_OBJS)
+	$(Q) $(RM) $(CHTTP2_FULLSTACK_CENSUS_SIMPLE_REQUEST_TEST_DEPS)
+	$(Q) $(RM) bins/$(CONFIG)/chttp2_fullstack_census_simple_request_test
+
+
 CHTTP2_FULLSTACK_DISAPPEARING_SERVER_TEST_SRC = \
 
 CHTTP2_FULLSTACK_DISAPPEARING_SERVER_TEST_OBJS = $(addprefix objs/$(CONFIG)/, $(addsuffix .o, $(basename $(CHTTP2_FULLSTACK_DISAPPEARING_SERVER_TEST_SRC))))
@@ -6758,6 +7028,39 @@ clean_chttp2_simple_ssl_fullstack_cancel_in_a_vacuum_test:
 	$(Q) $(RM) bins/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_in_a_vacuum_test
 
 
+CHTTP2_SIMPLE_SSL_FULLSTACK_CENSUS_SIMPLE_REQUEST_TEST_SRC = \
+
+CHTTP2_SIMPLE_SSL_FULLSTACK_CENSUS_SIMPLE_REQUEST_TEST_OBJS = $(addprefix objs/$(CONFIG)/, $(addsuffix .o, $(basename $(CHTTP2_SIMPLE_SSL_FULLSTACK_CENSUS_SIMPLE_REQUEST_TEST_SRC))))
+CHTTP2_SIMPLE_SSL_FULLSTACK_CENSUS_SIMPLE_REQUEST_TEST_DEPS = $(addprefix deps/$(CONFIG)/, $(addsuffix .dep, $(basename $(CHTTP2_SIMPLE_SSL_FULLSTACK_CENSUS_SIMPLE_REQUEST_TEST_SRC))))
+
+ifeq ($(NO_SECURE),true)
+
+bins/$(CONFIG)/chttp2_simple_ssl_fullstack_census_simple_request_test: openssl_dep_error
+
+else
+
+bins/$(CONFIG)/chttp2_simple_ssl_fullstack_census_simple_request_test: $(CHTTP2_SIMPLE_SSL_FULLSTACK_CENSUS_SIMPLE_REQUEST_TEST_OBJS) libs/$(CONFIG)/libend2end_fixture_chttp2_simple_ssl_fullstack.a libs/$(CONFIG)/libend2end_test_census_simple_request.a libs/$(CONFIG)/libend2end_certs.a libs/$(CONFIG)/libgrpc_test_util.a libs/$(CONFIG)/libgrpc.a libs/$(CONFIG)/libgpr.a
+	$(E) "[LD]      Linking $@"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(LD) $(LDFLAGS) $(CHTTP2_SIMPLE_SSL_FULLSTACK_CENSUS_SIMPLE_REQUEST_TEST_OBJS) libs/$(CONFIG)/libend2end_fixture_chttp2_simple_ssl_fullstack.a libs/$(CONFIG)/libend2end_test_census_simple_request.a libs/$(CONFIG)/libend2end_certs.a libs/$(CONFIG)/libgrpc_test_util.a libs/$(CONFIG)/libgrpc.a libs/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o bins/$(CONFIG)/chttp2_simple_ssl_fullstack_census_simple_request_test
+
+endif
+
+deps_chttp2_simple_ssl_fullstack_census_simple_request_test: $(CHTTP2_SIMPLE_SSL_FULLSTACK_CENSUS_SIMPLE_REQUEST_TEST_DEPS)
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(CHTTP2_SIMPLE_SSL_FULLSTACK_CENSUS_SIMPLE_REQUEST_TEST_DEPS)
+endif
+endif
+
+clean_chttp2_simple_ssl_fullstack_census_simple_request_test:
+	$(E) "[CLEAN]   Cleaning chttp2_simple_ssl_fullstack_census_simple_request_test files"
+	$(Q) $(RM) $(CHTTP2_SIMPLE_SSL_FULLSTACK_CENSUS_SIMPLE_REQUEST_TEST_OBJS)
+	$(Q) $(RM) $(CHTTP2_SIMPLE_SSL_FULLSTACK_CENSUS_SIMPLE_REQUEST_TEST_DEPS)
+	$(Q) $(RM) bins/$(CONFIG)/chttp2_simple_ssl_fullstack_census_simple_request_test
+
+
 CHTTP2_SIMPLE_SSL_FULLSTACK_DISAPPEARING_SERVER_TEST_SRC = \
 
 CHTTP2_SIMPLE_SSL_FULLSTACK_DISAPPEARING_SERVER_TEST_OBJS = $(addprefix objs/$(CONFIG)/, $(addsuffix .o, $(basename $(CHTTP2_SIMPLE_SSL_FULLSTACK_DISAPPEARING_SERVER_TEST_SRC))))
@@ -7418,6 +7721,39 @@ clean_chttp2_simple_ssl_with_oauth2_fullstack_cancel_in_a_vacuum_test:
 	$(Q) $(RM) bins/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_in_a_vacuum_test
 
 
+CHTTP2_SIMPLE_SSL_WITH_OAUTH2_FULLSTACK_CENSUS_SIMPLE_REQUEST_TEST_SRC = \
+
+CHTTP2_SIMPLE_SSL_WITH_OAUTH2_FULLSTACK_CENSUS_SIMPLE_REQUEST_TEST_OBJS = $(addprefix objs/$(CONFIG)/, $(addsuffix .o, $(basename $(CHTTP2_SIMPLE_SSL_WITH_OAUTH2_FULLSTACK_CENSUS_SIMPLE_REQUEST_TEST_SRC))))
+CHTTP2_SIMPLE_SSL_WITH_OAUTH2_FULLSTACK_CENSUS_SIMPLE_REQUEST_TEST_DEPS = $(addprefix deps/$(CONFIG)/, $(addsuffix .dep, $(basename $(CHTTP2_SIMPLE_SSL_WITH_OAUTH2_FULLSTACK_CENSUS_SIMPLE_REQUEST_TEST_SRC))))
+
+ifeq ($(NO_SECURE),true)
+
+bins/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_census_simple_request_test: openssl_dep_error
+
+else
+
+bins/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_census_simple_request_test: $(CHTTP2_SIMPLE_SSL_WITH_OAUTH2_FULLSTACK_CENSUS_SIMPLE_REQUEST_TEST_OBJS) libs/$(CONFIG)/libend2end_fixture_chttp2_simple_ssl_with_oauth2_fullstack.a libs/$(CONFIG)/libend2end_test_census_simple_request.a libs/$(CONFIG)/libend2end_certs.a libs/$(CONFIG)/libgrpc_test_util.a libs/$(CONFIG)/libgrpc.a libs/$(CONFIG)/libgpr.a
+	$(E) "[LD]      Linking $@"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(LD) $(LDFLAGS) $(CHTTP2_SIMPLE_SSL_WITH_OAUTH2_FULLSTACK_CENSUS_SIMPLE_REQUEST_TEST_OBJS) libs/$(CONFIG)/libend2end_fixture_chttp2_simple_ssl_with_oauth2_fullstack.a libs/$(CONFIG)/libend2end_test_census_simple_request.a libs/$(CONFIG)/libend2end_certs.a libs/$(CONFIG)/libgrpc_test_util.a libs/$(CONFIG)/libgrpc.a libs/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o bins/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_census_simple_request_test
+
+endif
+
+deps_chttp2_simple_ssl_with_oauth2_fullstack_census_simple_request_test: $(CHTTP2_SIMPLE_SSL_WITH_OAUTH2_FULLSTACK_CENSUS_SIMPLE_REQUEST_TEST_DEPS)
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(CHTTP2_SIMPLE_SSL_WITH_OAUTH2_FULLSTACK_CENSUS_SIMPLE_REQUEST_TEST_DEPS)
+endif
+endif
+
+clean_chttp2_simple_ssl_with_oauth2_fullstack_census_simple_request_test:
+	$(E) "[CLEAN]   Cleaning chttp2_simple_ssl_with_oauth2_fullstack_census_simple_request_test files"
+	$(Q) $(RM) $(CHTTP2_SIMPLE_SSL_WITH_OAUTH2_FULLSTACK_CENSUS_SIMPLE_REQUEST_TEST_OBJS)
+	$(Q) $(RM) $(CHTTP2_SIMPLE_SSL_WITH_OAUTH2_FULLSTACK_CENSUS_SIMPLE_REQUEST_TEST_DEPS)
+	$(Q) $(RM) bins/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_census_simple_request_test
+
+
 CHTTP2_SIMPLE_SSL_WITH_OAUTH2_FULLSTACK_DISAPPEARING_SERVER_TEST_SRC = \
 
 CHTTP2_SIMPLE_SSL_WITH_OAUTH2_FULLSTACK_DISAPPEARING_SERVER_TEST_OBJS = $(addprefix objs/$(CONFIG)/, $(addsuffix .o, $(basename $(CHTTP2_SIMPLE_SSL_WITH_OAUTH2_FULLSTACK_DISAPPEARING_SERVER_TEST_SRC))))
@@ -8078,6 +8414,39 @@ clean_chttp2_socket_pair_cancel_in_a_vacuum_test:
 	$(Q) $(RM) bins/$(CONFIG)/chttp2_socket_pair_cancel_in_a_vacuum_test
 
 
+CHTTP2_SOCKET_PAIR_CENSUS_SIMPLE_REQUEST_TEST_SRC = \
+
+CHTTP2_SOCKET_PAIR_CENSUS_SIMPLE_REQUEST_TEST_OBJS = $(addprefix objs/$(CONFIG)/, $(addsuffix .o, $(basename $(CHTTP2_SOCKET_PAIR_CENSUS_SIMPLE_REQUEST_TEST_SRC))))
+CHTTP2_SOCKET_PAIR_CENSUS_SIMPLE_REQUEST_TEST_DEPS = $(addprefix deps/$(CONFIG)/, $(addsuffix .dep, $(basename $(CHTTP2_SOCKET_PAIR_CENSUS_SIMPLE_REQUEST_TEST_SRC))))
+
+ifeq ($(NO_SECURE),true)
+
+bins/$(CONFIG)/chttp2_socket_pair_census_simple_request_test: openssl_dep_error
+
+else
+
+bins/$(CONFIG)/chttp2_socket_pair_census_simple_request_test: $(CHTTP2_SOCKET_PAIR_CENSUS_SIMPLE_REQUEST_TEST_OBJS) libs/$(CONFIG)/libend2end_fixture_chttp2_socket_pair.a libs/$(CONFIG)/libend2end_test_census_simple_request.a libs/$(CONFIG)/libend2end_certs.a libs/$(CONFIG)/libgrpc_test_util.a libs/$(CONFIG)/libgrpc.a libs/$(CONFIG)/libgpr.a
+	$(E) "[LD]      Linking $@"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(LD) $(LDFLAGS) $(CHTTP2_SOCKET_PAIR_CENSUS_SIMPLE_REQUEST_TEST_OBJS) libs/$(CONFIG)/libend2end_fixture_chttp2_socket_pair.a libs/$(CONFIG)/libend2end_test_census_simple_request.a libs/$(CONFIG)/libend2end_certs.a libs/$(CONFIG)/libgrpc_test_util.a libs/$(CONFIG)/libgrpc.a libs/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o bins/$(CONFIG)/chttp2_socket_pair_census_simple_request_test
+
+endif
+
+deps_chttp2_socket_pair_census_simple_request_test: $(CHTTP2_SOCKET_PAIR_CENSUS_SIMPLE_REQUEST_TEST_DEPS)
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(CHTTP2_SOCKET_PAIR_CENSUS_SIMPLE_REQUEST_TEST_DEPS)
+endif
+endif
+
+clean_chttp2_socket_pair_census_simple_request_test:
+	$(E) "[CLEAN]   Cleaning chttp2_socket_pair_census_simple_request_test files"
+	$(Q) $(RM) $(CHTTP2_SOCKET_PAIR_CENSUS_SIMPLE_REQUEST_TEST_OBJS)
+	$(Q) $(RM) $(CHTTP2_SOCKET_PAIR_CENSUS_SIMPLE_REQUEST_TEST_DEPS)
+	$(Q) $(RM) bins/$(CONFIG)/chttp2_socket_pair_census_simple_request_test
+
+
 CHTTP2_SOCKET_PAIR_DISAPPEARING_SERVER_TEST_SRC = \
 
 CHTTP2_SOCKET_PAIR_DISAPPEARING_SERVER_TEST_OBJS = $(addprefix objs/$(CONFIG)/, $(addsuffix .o, $(basename $(CHTTP2_SOCKET_PAIR_DISAPPEARING_SERVER_TEST_SRC))))
@@ -8738,6 +9107,39 @@ clean_chttp2_socket_pair_one_byte_at_a_time_cancel_in_a_vacuum_test:
 	$(Q) $(RM) bins/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_in_a_vacuum_test
 
 
+CHTTP2_SOCKET_PAIR_ONE_BYTE_AT_A_TIME_CENSUS_SIMPLE_REQUEST_TEST_SRC = \
+
+CHTTP2_SOCKET_PAIR_ONE_BYTE_AT_A_TIME_CENSUS_SIMPLE_REQUEST_TEST_OBJS = $(addprefix objs/$(CONFIG)/, $(addsuffix .o, $(basename $(CHTTP2_SOCKET_PAIR_ONE_BYTE_AT_A_TIME_CENSUS_SIMPLE_REQUEST_TEST_SRC))))
+CHTTP2_SOCKET_PAIR_ONE_BYTE_AT_A_TIME_CENSUS_SIMPLE_REQUEST_TEST_DEPS = $(addprefix deps/$(CONFIG)/, $(addsuffix .dep, $(basename $(CHTTP2_SOCKET_PAIR_ONE_BYTE_AT_A_TIME_CENSUS_SIMPLE_REQUEST_TEST_SRC))))
+
+ifeq ($(NO_SECURE),true)
+
+bins/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_census_simple_request_test: openssl_dep_error
+
+else
+
+bins/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_census_simple_request_test: $(CHTTP2_SOCKET_PAIR_ONE_BYTE_AT_A_TIME_CENSUS_SIMPLE_REQUEST_TEST_OBJS) libs/$(CONFIG)/libend2end_fixture_chttp2_socket_pair_one_byte_at_a_time.a libs/$(CONFIG)/libend2end_test_census_simple_request.a libs/$(CONFIG)/libend2end_certs.a libs/$(CONFIG)/libgrpc_test_util.a libs/$(CONFIG)/libgrpc.a libs/$(CONFIG)/libgpr.a
+	$(E) "[LD]      Linking $@"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(LD) $(LDFLAGS) $(CHTTP2_SOCKET_PAIR_ONE_BYTE_AT_A_TIME_CENSUS_SIMPLE_REQUEST_TEST_OBJS) libs/$(CONFIG)/libend2end_fixture_chttp2_socket_pair_one_byte_at_a_time.a libs/$(CONFIG)/libend2end_test_census_simple_request.a libs/$(CONFIG)/libend2end_certs.a libs/$(CONFIG)/libgrpc_test_util.a libs/$(CONFIG)/libgrpc.a libs/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o bins/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_census_simple_request_test
+
+endif
+
+deps_chttp2_socket_pair_one_byte_at_a_time_census_simple_request_test: $(CHTTP2_SOCKET_PAIR_ONE_BYTE_AT_A_TIME_CENSUS_SIMPLE_REQUEST_TEST_DEPS)
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(CHTTP2_SOCKET_PAIR_ONE_BYTE_AT_A_TIME_CENSUS_SIMPLE_REQUEST_TEST_DEPS)
+endif
+endif
+
+clean_chttp2_socket_pair_one_byte_at_a_time_census_simple_request_test:
+	$(E) "[CLEAN]   Cleaning chttp2_socket_pair_one_byte_at_a_time_census_simple_request_test files"
+	$(Q) $(RM) $(CHTTP2_SOCKET_PAIR_ONE_BYTE_AT_A_TIME_CENSUS_SIMPLE_REQUEST_TEST_OBJS)
+	$(Q) $(RM) $(CHTTP2_SOCKET_PAIR_ONE_BYTE_AT_A_TIME_CENSUS_SIMPLE_REQUEST_TEST_DEPS)
+	$(Q) $(RM) bins/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_census_simple_request_test
+
+
 CHTTP2_SOCKET_PAIR_ONE_BYTE_AT_A_TIME_DISAPPEARING_SERVER_TEST_SRC = \
 
 CHTTP2_SOCKET_PAIR_ONE_BYTE_AT_A_TIME_DISAPPEARING_SERVER_TEST_OBJS = $(addprefix objs/$(CONFIG)/, $(addsuffix .o, $(basename $(CHTTP2_SOCKET_PAIR_ONE_BYTE_AT_A_TIME_DISAPPEARING_SERVER_TEST_SRC))))
@@ -9237,4 +9639,4 @@ clean_chttp2_socket_pair_one_byte_at_a_time_writes_done_hangs_with_pending_read_
 
 
 
-.PHONY: all strip tools dep_error openssl_dep_error openssl_dep_message git_update stop buildtests buildtests_c buildtests_cxx test test_c test_cxx install install_c install_cxx install-headers install-headers_c install-headers_cxx install-shared install-shared_c install-shared_cxx install-static install-static_c install-static_cxx strip strip-shared strip-static strip_c strip-shared_c strip-static_c strip_cxx strip-shared_cxx strip-static_cxx clean dep_c dep_cxx bins_dep_c bins_dep_cxx deps_libgpr clean_libgpr deps_libgrpc clean_libgrpc deps_libgrpc_unsecure clean_libgrpc_unsecure deps_libgrpc_test_util clean_libgrpc_test_util deps_libgrpc++ clean_libgrpc++ deps_libgrpc++_test_util clean_libgrpc++_test_util deps_libend2end_fixture_chttp2_fake_security clean_libend2end_fixture_chttp2_fake_security deps_libend2end_fixture_chttp2_fullstack clean_libend2end_fixture_chttp2_fullstack deps_libend2end_fixture_chttp2_simple_ssl_fullstack clean_libend2end_fixture_chttp2_simple_ssl_fullstack deps_libend2end_fixture_chttp2_simple_ssl_with_oauth2_fullstack clean_libend2end_fixture_chttp2_simple_ssl_with_oauth2_fullstack deps_libend2end_fixture_chttp2_socket_pair clean_libend2end_fixture_chttp2_socket_pair deps_libend2end_fixture_chttp2_socket_pair_one_byte_at_a_time clean_libend2end_fixture_chttp2_socket_pair_one_byte_at_a_time deps_libend2end_test_cancel_after_accept clean_libend2end_test_cancel_after_accept deps_libend2end_test_cancel_after_accept_and_writes_closed clean_libend2end_test_cancel_after_accept_and_writes_closed deps_libend2end_test_cancel_after_invoke clean_libend2end_test_cancel_after_invoke deps_libend2end_test_cancel_before_invoke clean_libend2end_test_cancel_before_invoke deps_libend2end_test_cancel_in_a_vacuum clean_libend2end_test_cancel_in_a_vacuum deps_libend2end_test_disappearing_server clean_libend2end_test_disappearing_server deps_libend2end_test_early_server_shutdown_finishes_inflight_calls clean_libend2end_test_early_server_shutdown_finishes_inflight_calls deps_libend2end_test_early_server_shutdown_finishes_tags clean_libend2end_test_early_server_shutdown_finishes_tags deps_libend2end_test_invoke_large_request clean_libend2end_test_invoke_large_request deps_libend2end_test_max_concurrent_streams clean_libend2end_test_max_concurrent_streams deps_libend2end_test_no_op clean_libend2end_test_no_op deps_libend2end_test_ping_pong_streaming clean_libend2end_test_ping_pong_streaming deps_libend2end_test_request_response_with_binary_metadata_and_payload clean_libend2end_test_request_response_with_binary_metadata_and_payload deps_libend2end_test_request_response_with_metadata_and_payload clean_libend2end_test_request_response_with_metadata_and_payload deps_libend2end_test_request_response_with_payload clean_libend2end_test_request_response_with_payload deps_libend2end_test_request_response_with_trailing_metadata_and_payload clean_libend2end_test_request_response_with_trailing_metadata_and_payload deps_libend2end_test_simple_delayed_request clean_libend2end_test_simple_delayed_request deps_libend2end_test_simple_request clean_libend2end_test_simple_request deps_libend2end_test_thread_stress clean_libend2end_test_thread_stress deps_libend2end_test_writes_done_hangs_with_pending_read clean_libend2end_test_writes_done_hangs_with_pending_read deps_libend2end_certs clean_libend2end_certs deps_gen_hpack_tables clean_gen_hpack_tables deps_cpp_plugin clean_cpp_plugin deps_ruby_plugin clean_ruby_plugin deps_grpc_byte_buffer_reader_test clean_grpc_byte_buffer_reader_test deps_gpr_cancellable_test clean_gpr_cancellable_test deps_gpr_log_test clean_gpr_log_test deps_gpr_useful_test clean_gpr_useful_test deps_gpr_cmdline_test clean_gpr_cmdline_test deps_gpr_histogram_test clean_gpr_histogram_test deps_gpr_host_port_test clean_gpr_host_port_test deps_gpr_slice_buffer_test clean_gpr_slice_buffer_test deps_gpr_slice_test clean_gpr_slice_test deps_gpr_string_test clean_gpr_string_test deps_gpr_sync_test clean_gpr_sync_test deps_gpr_thd_test clean_gpr_thd_test deps_gpr_time_test clean_gpr_time_test deps_murmur_hash_test clean_murmur_hash_test deps_grpc_stream_op_test clean_grpc_stream_op_test deps_alpn_test clean_alpn_test deps_time_averaged_stats_test clean_time_averaged_stats_test deps_chttp2_stream_encoder_test clean_chttp2_stream_encoder_test deps_hpack_table_test clean_hpack_table_test deps_chttp2_stream_map_test clean_chttp2_stream_map_test deps_hpack_parser_test clean_hpack_parser_test deps_transport_metadata_test clean_transport_metadata_test deps_chttp2_status_conversion_test clean_chttp2_status_conversion_test deps_chttp2_transport_end2end_test clean_chttp2_transport_end2end_test deps_tcp_posix_test clean_tcp_posix_test deps_dualstack_socket_test clean_dualstack_socket_test deps_no_server_test clean_no_server_test deps_resolve_address_test clean_resolve_address_test deps_sockaddr_utils_test clean_sockaddr_utils_test deps_tcp_server_posix_test clean_tcp_server_posix_test deps_tcp_client_posix_test clean_tcp_client_posix_test deps_grpc_channel_stack_test clean_grpc_channel_stack_test deps_metadata_buffer_test clean_metadata_buffer_test deps_grpc_completion_queue_test clean_grpc_completion_queue_test deps_grpc_completion_queue_benchmark clean_grpc_completion_queue_benchmark deps_census_window_stats_test clean_census_window_stats_test deps_census_statistics_quick_test clean_census_statistics_quick_test deps_census_statistics_small_log_test clean_census_statistics_small_log_test deps_census_statistics_performance_test clean_census_statistics_performance_test deps_census_statistics_multiple_writers_test clean_census_statistics_multiple_writers_test deps_census_statistics_multiple_writers_circular_buffer_test clean_census_statistics_multiple_writers_circular_buffer_test deps_census_stub_test clean_census_stub_test deps_census_hash_table_test clean_census_hash_table_test deps_fling_server clean_fling_server deps_fling_client clean_fling_client deps_fling_test clean_fling_test deps_echo_server clean_echo_server deps_echo_client clean_echo_client deps_echo_test clean_echo_test deps_low_level_ping_pong_benchmark clean_low_level_ping_pong_benchmark deps_message_compress_test clean_message_compress_test deps_bin_encoder_test clean_bin_encoder_test deps_secure_endpoint_test clean_secure_endpoint_test deps_httpcli_format_request_test clean_httpcli_format_request_test deps_httpcli_parser_test clean_httpcli_parser_test deps_httpcli_test clean_httpcli_test deps_grpc_credentials_test clean_grpc_credentials_test deps_grpc_fetch_oauth2 clean_grpc_fetch_oauth2 deps_grpc_base64_test clean_grpc_base64_test deps_grpc_json_token_test clean_grpc_json_token_test deps_timeout_encoding_test clean_timeout_encoding_test deps_fd_posix_test clean_fd_posix_test deps_fling_stream_test clean_fling_stream_test deps_lame_client_test clean_lame_client_test deps_thread_pool_test clean_thread_pool_test deps_status_test clean_status_test deps_sync_client_async_server_test clean_sync_client_async_server_test deps_qps_client clean_qps_client deps_qps_server clean_qps_server deps_interop_server clean_interop_server deps_interop_client clean_interop_client deps_end2end_test clean_end2end_test deps_channel_arguments_test clean_channel_arguments_test deps_alarm_test clean_alarm_test deps_alarm_list_test clean_alarm_list_test deps_alarm_heap_test clean_alarm_heap_test deps_time_test clean_time_test deps_chttp2_fake_security_cancel_after_accept_test clean_chttp2_fake_security_cancel_after_accept_test deps_chttp2_fake_security_cancel_after_accept_and_writes_closed_test clean_chttp2_fake_security_cancel_after_accept_and_writes_closed_test deps_chttp2_fake_security_cancel_after_invoke_test clean_chttp2_fake_security_cancel_after_invoke_test deps_chttp2_fake_security_cancel_before_invoke_test clean_chttp2_fake_security_cancel_before_invoke_test deps_chttp2_fake_security_cancel_in_a_vacuum_test clean_chttp2_fake_security_cancel_in_a_vacuum_test deps_chttp2_fake_security_disappearing_server_test clean_chttp2_fake_security_disappearing_server_test deps_chttp2_fake_security_early_server_shutdown_finishes_inflight_calls_test clean_chttp2_fake_security_early_server_shutdown_finishes_inflight_calls_test deps_chttp2_fake_security_early_server_shutdown_finishes_tags_test clean_chttp2_fake_security_early_server_shutdown_finishes_tags_test deps_chttp2_fake_security_invoke_large_request_test clean_chttp2_fake_security_invoke_large_request_test deps_chttp2_fake_security_max_concurrent_streams_test clean_chttp2_fake_security_max_concurrent_streams_test deps_chttp2_fake_security_no_op_test clean_chttp2_fake_security_no_op_test deps_chttp2_fake_security_ping_pong_streaming_test clean_chttp2_fake_security_ping_pong_streaming_test deps_chttp2_fake_security_request_response_with_binary_metadata_and_payload_test clean_chttp2_fake_security_request_response_with_binary_metadata_and_payload_test deps_chttp2_fake_security_request_response_with_metadata_and_payload_test clean_chttp2_fake_security_request_response_with_metadata_and_payload_test deps_chttp2_fake_security_request_response_with_payload_test clean_chttp2_fake_security_request_response_with_payload_test deps_chttp2_fake_security_request_response_with_trailing_metadata_and_payload_test clean_chttp2_fake_security_request_response_with_trailing_metadata_and_payload_test deps_chttp2_fake_security_simple_delayed_request_test clean_chttp2_fake_security_simple_delayed_request_test deps_chttp2_fake_security_simple_request_test clean_chttp2_fake_security_simple_request_test deps_chttp2_fake_security_thread_stress_test clean_chttp2_fake_security_thread_stress_test deps_chttp2_fake_security_writes_done_hangs_with_pending_read_test clean_chttp2_fake_security_writes_done_hangs_with_pending_read_test deps_chttp2_fullstack_cancel_after_accept_test clean_chttp2_fullstack_cancel_after_accept_test deps_chttp2_fullstack_cancel_after_accept_and_writes_closed_test clean_chttp2_fullstack_cancel_after_accept_and_writes_closed_test deps_chttp2_fullstack_cancel_after_invoke_test clean_chttp2_fullstack_cancel_after_invoke_test deps_chttp2_fullstack_cancel_before_invoke_test clean_chttp2_fullstack_cancel_before_invoke_test deps_chttp2_fullstack_cancel_in_a_vacuum_test clean_chttp2_fullstack_cancel_in_a_vacuum_test deps_chttp2_fullstack_disappearing_server_test clean_chttp2_fullstack_disappearing_server_test deps_chttp2_fullstack_early_server_shutdown_finishes_inflight_calls_test clean_chttp2_fullstack_early_server_shutdown_finishes_inflight_calls_test deps_chttp2_fullstack_early_server_shutdown_finishes_tags_test clean_chttp2_fullstack_early_server_shutdown_finishes_tags_test deps_chttp2_fullstack_invoke_large_request_test clean_chttp2_fullstack_invoke_large_request_test deps_chttp2_fullstack_max_concurrent_streams_test clean_chttp2_fullstack_max_concurrent_streams_test deps_chttp2_fullstack_no_op_test clean_chttp2_fullstack_no_op_test deps_chttp2_fullstack_ping_pong_streaming_test clean_chttp2_fullstack_ping_pong_streaming_test deps_chttp2_fullstack_request_response_with_binary_metadata_and_payload_test clean_chttp2_fullstack_request_response_with_binary_metadata_and_payload_test deps_chttp2_fullstack_request_response_with_metadata_and_payload_test clean_chttp2_fullstack_request_response_with_metadata_and_payload_test deps_chttp2_fullstack_request_response_with_payload_test clean_chttp2_fullstack_request_response_with_payload_test deps_chttp2_fullstack_request_response_with_trailing_metadata_and_payload_test clean_chttp2_fullstack_request_response_with_trailing_metadata_and_payload_test deps_chttp2_fullstack_simple_delayed_request_test clean_chttp2_fullstack_simple_delayed_request_test deps_chttp2_fullstack_simple_request_test clean_chttp2_fullstack_simple_request_test deps_chttp2_fullstack_thread_stress_test clean_chttp2_fullstack_thread_stress_test deps_chttp2_fullstack_writes_done_hangs_with_pending_read_test clean_chttp2_fullstack_writes_done_hangs_with_pending_read_test deps_chttp2_simple_ssl_fullstack_cancel_after_accept_test clean_chttp2_simple_ssl_fullstack_cancel_after_accept_test deps_chttp2_simple_ssl_fullstack_cancel_after_accept_and_writes_closed_test clean_chttp2_simple_ssl_fullstack_cancel_after_accept_and_writes_closed_test deps_chttp2_simple_ssl_fullstack_cancel_after_invoke_test clean_chttp2_simple_ssl_fullstack_cancel_after_invoke_test deps_chttp2_simple_ssl_fullstack_cancel_before_invoke_test clean_chttp2_simple_ssl_fullstack_cancel_before_invoke_test deps_chttp2_simple_ssl_fullstack_cancel_in_a_vacuum_test clean_chttp2_simple_ssl_fullstack_cancel_in_a_vacuum_test deps_chttp2_simple_ssl_fullstack_disappearing_server_test clean_chttp2_simple_ssl_fullstack_disappearing_server_test deps_chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_inflight_calls_test clean_chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_inflight_calls_test deps_chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_tags_test clean_chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_tags_test deps_chttp2_simple_ssl_fullstack_invoke_large_request_test clean_chttp2_simple_ssl_fullstack_invoke_large_request_test deps_chttp2_simple_ssl_fullstack_max_concurrent_streams_test clean_chttp2_simple_ssl_fullstack_max_concurrent_streams_test deps_chttp2_simple_ssl_fullstack_no_op_test clean_chttp2_simple_ssl_fullstack_no_op_test deps_chttp2_simple_ssl_fullstack_ping_pong_streaming_test clean_chttp2_simple_ssl_fullstack_ping_pong_streaming_test deps_chttp2_simple_ssl_fullstack_request_response_with_binary_metadata_and_payload_test clean_chttp2_simple_ssl_fullstack_request_response_with_binary_metadata_and_payload_test deps_chttp2_simple_ssl_fullstack_request_response_with_metadata_and_payload_test clean_chttp2_simple_ssl_fullstack_request_response_with_metadata_and_payload_test deps_chttp2_simple_ssl_fullstack_request_response_with_payload_test clean_chttp2_simple_ssl_fullstack_request_response_with_payload_test deps_chttp2_simple_ssl_fullstack_request_response_with_trailing_metadata_and_payload_test clean_chttp2_simple_ssl_fullstack_request_response_with_trailing_metadata_and_payload_test deps_chttp2_simple_ssl_fullstack_simple_delayed_request_test clean_chttp2_simple_ssl_fullstack_simple_delayed_request_test deps_chttp2_simple_ssl_fullstack_simple_request_test clean_chttp2_simple_ssl_fullstack_simple_request_test deps_chttp2_simple_ssl_fullstack_thread_stress_test clean_chttp2_simple_ssl_fullstack_thread_stress_test deps_chttp2_simple_ssl_fullstack_writes_done_hangs_with_pending_read_test clean_chttp2_simple_ssl_fullstack_writes_done_hangs_with_pending_read_test deps_chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_accept_test clean_chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_accept_test deps_chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_accept_and_writes_closed_test clean_chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_accept_and_writes_closed_test deps_chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_invoke_test clean_chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_invoke_test deps_chttp2_simple_ssl_with_oauth2_fullstack_cancel_before_invoke_test clean_chttp2_simple_ssl_with_oauth2_fullstack_cancel_before_invoke_test deps_chttp2_simple_ssl_with_oauth2_fullstack_cancel_in_a_vacuum_test clean_chttp2_simple_ssl_with_oauth2_fullstack_cancel_in_a_vacuum_test deps_chttp2_simple_ssl_with_oauth2_fullstack_disappearing_server_test clean_chttp2_simple_ssl_with_oauth2_fullstack_disappearing_server_test deps_chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_inflight_calls_test clean_chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_inflight_calls_test deps_chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_tags_test clean_chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_tags_test deps_chttp2_simple_ssl_with_oauth2_fullstack_invoke_large_request_test clean_chttp2_simple_ssl_with_oauth2_fullstack_invoke_large_request_test deps_chttp2_simple_ssl_with_oauth2_fullstack_max_concurrent_streams_test clean_chttp2_simple_ssl_with_oauth2_fullstack_max_concurrent_streams_test deps_chttp2_simple_ssl_with_oauth2_fullstack_no_op_test clean_chttp2_simple_ssl_with_oauth2_fullstack_no_op_test deps_chttp2_simple_ssl_with_oauth2_fullstack_ping_pong_streaming_test clean_chttp2_simple_ssl_with_oauth2_fullstack_ping_pong_streaming_test deps_chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_binary_metadata_and_payload_test clean_chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_binary_metadata_and_payload_test deps_chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_metadata_and_payload_test clean_chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_metadata_and_payload_test deps_chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_payload_test clean_chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_payload_test deps_chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_trailing_metadata_and_payload_test clean_chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_trailing_metadata_and_payload_test deps_chttp2_simple_ssl_with_oauth2_fullstack_simple_delayed_request_test clean_chttp2_simple_ssl_with_oauth2_fullstack_simple_delayed_request_test deps_chttp2_simple_ssl_with_oauth2_fullstack_simple_request_test clean_chttp2_simple_ssl_with_oauth2_fullstack_simple_request_test deps_chttp2_simple_ssl_with_oauth2_fullstack_thread_stress_test clean_chttp2_simple_ssl_with_oauth2_fullstack_thread_stress_test deps_chttp2_simple_ssl_with_oauth2_fullstack_writes_done_hangs_with_pending_read_test clean_chttp2_simple_ssl_with_oauth2_fullstack_writes_done_hangs_with_pending_read_test deps_chttp2_socket_pair_cancel_after_accept_test clean_chttp2_socket_pair_cancel_after_accept_test deps_chttp2_socket_pair_cancel_after_accept_and_writes_closed_test clean_chttp2_socket_pair_cancel_after_accept_and_writes_closed_test deps_chttp2_socket_pair_cancel_after_invoke_test clean_chttp2_socket_pair_cancel_after_invoke_test deps_chttp2_socket_pair_cancel_before_invoke_test clean_chttp2_socket_pair_cancel_before_invoke_test deps_chttp2_socket_pair_cancel_in_a_vacuum_test clean_chttp2_socket_pair_cancel_in_a_vacuum_test deps_chttp2_socket_pair_disappearing_server_test clean_chttp2_socket_pair_disappearing_server_test deps_chttp2_socket_pair_early_server_shutdown_finishes_inflight_calls_test clean_chttp2_socket_pair_early_server_shutdown_finishes_inflight_calls_test deps_chttp2_socket_pair_early_server_shutdown_finishes_tags_test clean_chttp2_socket_pair_early_server_shutdown_finishes_tags_test deps_chttp2_socket_pair_invoke_large_request_test clean_chttp2_socket_pair_invoke_large_request_test deps_chttp2_socket_pair_max_concurrent_streams_test clean_chttp2_socket_pair_max_concurrent_streams_test deps_chttp2_socket_pair_no_op_test clean_chttp2_socket_pair_no_op_test deps_chttp2_socket_pair_ping_pong_streaming_test clean_chttp2_socket_pair_ping_pong_streaming_test deps_chttp2_socket_pair_request_response_with_binary_metadata_and_payload_test clean_chttp2_socket_pair_request_response_with_binary_metadata_and_payload_test deps_chttp2_socket_pair_request_response_with_metadata_and_payload_test clean_chttp2_socket_pair_request_response_with_metadata_and_payload_test deps_chttp2_socket_pair_request_response_with_payload_test clean_chttp2_socket_pair_request_response_with_payload_test deps_chttp2_socket_pair_request_response_with_trailing_metadata_and_payload_test clean_chttp2_socket_pair_request_response_with_trailing_metadata_and_payload_test deps_chttp2_socket_pair_simple_delayed_request_test clean_chttp2_socket_pair_simple_delayed_request_test deps_chttp2_socket_pair_simple_request_test clean_chttp2_socket_pair_simple_request_test deps_chttp2_socket_pair_thread_stress_test clean_chttp2_socket_pair_thread_stress_test deps_chttp2_socket_pair_writes_done_hangs_with_pending_read_test clean_chttp2_socket_pair_writes_done_hangs_with_pending_read_test deps_chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_test clean_chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_test deps_chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_and_writes_closed_test clean_chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_and_writes_closed_test deps_chttp2_socket_pair_one_byte_at_a_time_cancel_after_invoke_test clean_chttp2_socket_pair_one_byte_at_a_time_cancel_after_invoke_test deps_chttp2_socket_pair_one_byte_at_a_time_cancel_before_invoke_test clean_chttp2_socket_pair_one_byte_at_a_time_cancel_before_invoke_test deps_chttp2_socket_pair_one_byte_at_a_time_cancel_in_a_vacuum_test clean_chttp2_socket_pair_one_byte_at_a_time_cancel_in_a_vacuum_test deps_chttp2_socket_pair_one_byte_at_a_time_disappearing_server_test clean_chttp2_socket_pair_one_byte_at_a_time_disappearing_server_test deps_chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_inflight_calls_test clean_chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_inflight_calls_test deps_chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_tags_test clean_chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_tags_test deps_chttp2_socket_pair_one_byte_at_a_time_invoke_large_request_test clean_chttp2_socket_pair_one_byte_at_a_time_invoke_large_request_test deps_chttp2_socket_pair_one_byte_at_a_time_max_concurrent_streams_test clean_chttp2_socket_pair_one_byte_at_a_time_max_concurrent_streams_test deps_chttp2_socket_pair_one_byte_at_a_time_no_op_test clean_chttp2_socket_pair_one_byte_at_a_time_no_op_test deps_chttp2_socket_pair_one_byte_at_a_time_ping_pong_streaming_test clean_chttp2_socket_pair_one_byte_at_a_time_ping_pong_streaming_test deps_chttp2_socket_pair_one_byte_at_a_time_request_response_with_binary_metadata_and_payload_test clean_chttp2_socket_pair_one_byte_at_a_time_request_response_with_binary_metadata_and_payload_test deps_chttp2_socket_pair_one_byte_at_a_time_request_response_with_metadata_and_payload_test clean_chttp2_socket_pair_one_byte_at_a_time_request_response_with_metadata_and_payload_test deps_chttp2_socket_pair_one_byte_at_a_time_request_response_with_payload_test clean_chttp2_socket_pair_one_byte_at_a_time_request_response_with_payload_test deps_chttp2_socket_pair_one_byte_at_a_time_request_response_with_trailing_metadata_and_payload_test clean_chttp2_socket_pair_one_byte_at_a_time_request_response_with_trailing_metadata_and_payload_test deps_chttp2_socket_pair_one_byte_at_a_time_simple_delayed_request_test clean_chttp2_socket_pair_one_byte_at_a_time_simple_delayed_request_test deps_chttp2_socket_pair_one_byte_at_a_time_simple_request_test clean_chttp2_socket_pair_one_byte_at_a_time_simple_request_test deps_chttp2_socket_pair_one_byte_at_a_time_thread_stress_test clean_chttp2_socket_pair_one_byte_at_a_time_thread_stress_test deps_chttp2_socket_pair_one_byte_at_a_time_writes_done_hangs_with_pending_read_test clean_chttp2_socket_pair_one_byte_at_a_time_writes_done_hangs_with_pending_read_test
+.PHONY: all strip tools dep_error openssl_dep_error openssl_dep_message git_update stop buildtests buildtests_c buildtests_cxx test test_c test_cxx install install_c install_cxx install-headers install-headers_c install-headers_cxx install-shared install-shared_c install-shared_cxx install-static install-static_c install-static_cxx strip strip-shared strip-static strip_c strip-shared_c strip-static_c strip_cxx strip-shared_cxx strip-static_cxx clean dep_c dep_cxx bins_dep_c bins_dep_cxx deps_libgpr clean_libgpr deps_libgrpc clean_libgrpc deps_libgrpc_unsecure clean_libgrpc_unsecure deps_libgrpc_test_util clean_libgrpc_test_util deps_libgrpc++ clean_libgrpc++ deps_libgrpc++_test_util clean_libgrpc++_test_util deps_libend2end_fixture_chttp2_fake_security clean_libend2end_fixture_chttp2_fake_security deps_libend2end_fixture_chttp2_fullstack clean_libend2end_fixture_chttp2_fullstack deps_libend2end_fixture_chttp2_simple_ssl_fullstack clean_libend2end_fixture_chttp2_simple_ssl_fullstack deps_libend2end_fixture_chttp2_simple_ssl_with_oauth2_fullstack clean_libend2end_fixture_chttp2_simple_ssl_with_oauth2_fullstack deps_libend2end_fixture_chttp2_socket_pair clean_libend2end_fixture_chttp2_socket_pair deps_libend2end_fixture_chttp2_socket_pair_one_byte_at_a_time clean_libend2end_fixture_chttp2_socket_pair_one_byte_at_a_time deps_libend2end_test_cancel_after_accept clean_libend2end_test_cancel_after_accept deps_libend2end_test_cancel_after_accept_and_writes_closed clean_libend2end_test_cancel_after_accept_and_writes_closed deps_libend2end_test_cancel_after_invoke clean_libend2end_test_cancel_after_invoke deps_libend2end_test_cancel_before_invoke clean_libend2end_test_cancel_before_invoke deps_libend2end_test_cancel_in_a_vacuum clean_libend2end_test_cancel_in_a_vacuum deps_libend2end_test_census_simple_request clean_libend2end_test_census_simple_request deps_libend2end_test_disappearing_server clean_libend2end_test_disappearing_server deps_libend2end_test_early_server_shutdown_finishes_inflight_calls clean_libend2end_test_early_server_shutdown_finishes_inflight_calls deps_libend2end_test_early_server_shutdown_finishes_tags clean_libend2end_test_early_server_shutdown_finishes_tags deps_libend2end_test_invoke_large_request clean_libend2end_test_invoke_large_request deps_libend2end_test_max_concurrent_streams clean_libend2end_test_max_concurrent_streams deps_libend2end_test_no_op clean_libend2end_test_no_op deps_libend2end_test_ping_pong_streaming clean_libend2end_test_ping_pong_streaming deps_libend2end_test_request_response_with_binary_metadata_and_payload clean_libend2end_test_request_response_with_binary_metadata_and_payload deps_libend2end_test_request_response_with_metadata_and_payload clean_libend2end_test_request_response_with_metadata_and_payload deps_libend2end_test_request_response_with_payload clean_libend2end_test_request_response_with_payload deps_libend2end_test_request_response_with_trailing_metadata_and_payload clean_libend2end_test_request_response_with_trailing_metadata_and_payload deps_libend2end_test_simple_delayed_request clean_libend2end_test_simple_delayed_request deps_libend2end_test_simple_request clean_libend2end_test_simple_request deps_libend2end_test_thread_stress clean_libend2end_test_thread_stress deps_libend2end_test_writes_done_hangs_with_pending_read clean_libend2end_test_writes_done_hangs_with_pending_read deps_libend2end_certs clean_libend2end_certs deps_gen_hpack_tables clean_gen_hpack_tables deps_cpp_plugin clean_cpp_plugin deps_ruby_plugin clean_ruby_plugin deps_go_plugin clean_go_plugin deps_grpc_byte_buffer_reader_test clean_grpc_byte_buffer_reader_test deps_gpr_cancellable_test clean_gpr_cancellable_test deps_gpr_log_test clean_gpr_log_test deps_gpr_useful_test clean_gpr_useful_test deps_gpr_cmdline_test clean_gpr_cmdline_test deps_gpr_histogram_test clean_gpr_histogram_test deps_gpr_host_port_test clean_gpr_host_port_test deps_gpr_slice_buffer_test clean_gpr_slice_buffer_test deps_gpr_slice_test clean_gpr_slice_test deps_gpr_string_test clean_gpr_string_test deps_gpr_sync_test clean_gpr_sync_test deps_gpr_thd_test clean_gpr_thd_test deps_gpr_time_test clean_gpr_time_test deps_murmur_hash_test clean_murmur_hash_test deps_grpc_stream_op_test clean_grpc_stream_op_test deps_alpn_test clean_alpn_test deps_time_averaged_stats_test clean_time_averaged_stats_test deps_chttp2_stream_encoder_test clean_chttp2_stream_encoder_test deps_hpack_table_test clean_hpack_table_test deps_chttp2_stream_map_test clean_chttp2_stream_map_test deps_hpack_parser_test clean_hpack_parser_test deps_transport_metadata_test clean_transport_metadata_test deps_chttp2_status_conversion_test clean_chttp2_status_conversion_test deps_chttp2_transport_end2end_test clean_chttp2_transport_end2end_test deps_tcp_posix_test clean_tcp_posix_test deps_dualstack_socket_test clean_dualstack_socket_test deps_no_server_test clean_no_server_test deps_resolve_address_test clean_resolve_address_test deps_sockaddr_utils_test clean_sockaddr_utils_test deps_tcp_server_posix_test clean_tcp_server_posix_test deps_tcp_client_posix_test clean_tcp_client_posix_test deps_grpc_channel_stack_test clean_grpc_channel_stack_test deps_metadata_buffer_test clean_metadata_buffer_test deps_grpc_completion_queue_test clean_grpc_completion_queue_test deps_grpc_completion_queue_benchmark clean_grpc_completion_queue_benchmark deps_census_trace_store_test clean_census_trace_store_test deps_census_stats_store_test clean_census_stats_store_test deps_census_window_stats_test clean_census_window_stats_test deps_census_statistics_quick_test clean_census_statistics_quick_test deps_census_statistics_small_log_test clean_census_statistics_small_log_test deps_census_statistics_performance_test clean_census_statistics_performance_test deps_census_statistics_multiple_writers_test clean_census_statistics_multiple_writers_test deps_census_statistics_multiple_writers_circular_buffer_test clean_census_statistics_multiple_writers_circular_buffer_test deps_census_stub_test clean_census_stub_test deps_census_hash_table_test clean_census_hash_table_test deps_fling_server clean_fling_server deps_fling_client clean_fling_client deps_fling_test clean_fling_test deps_echo_server clean_echo_server deps_echo_client clean_echo_client deps_echo_test clean_echo_test deps_low_level_ping_pong_benchmark clean_low_level_ping_pong_benchmark deps_message_compress_test clean_message_compress_test deps_bin_encoder_test clean_bin_encoder_test deps_secure_endpoint_test clean_secure_endpoint_test deps_httpcli_format_request_test clean_httpcli_format_request_test deps_httpcli_parser_test clean_httpcli_parser_test deps_httpcli_test clean_httpcli_test deps_grpc_credentials_test clean_grpc_credentials_test deps_grpc_fetch_oauth2 clean_grpc_fetch_oauth2 deps_grpc_base64_test clean_grpc_base64_test deps_grpc_json_token_test clean_grpc_json_token_test deps_timeout_encoding_test clean_timeout_encoding_test deps_fd_posix_test clean_fd_posix_test deps_fling_stream_test clean_fling_stream_test deps_lame_client_test clean_lame_client_test deps_thread_pool_test clean_thread_pool_test deps_status_test clean_status_test deps_sync_client_async_server_test clean_sync_client_async_server_test deps_qps_client clean_qps_client deps_qps_server clean_qps_server deps_interop_server clean_interop_server deps_interop_client clean_interop_client deps_end2end_test clean_end2end_test deps_channel_arguments_test clean_channel_arguments_test deps_credentials_test clean_credentials_test deps_alarm_test clean_alarm_test deps_alarm_list_test clean_alarm_list_test deps_alarm_heap_test clean_alarm_heap_test deps_time_test clean_time_test deps_chttp2_fake_security_cancel_after_accept_test clean_chttp2_fake_security_cancel_after_accept_test deps_chttp2_fake_security_cancel_after_accept_and_writes_closed_test clean_chttp2_fake_security_cancel_after_accept_and_writes_closed_test deps_chttp2_fake_security_cancel_after_invoke_test clean_chttp2_fake_security_cancel_after_invoke_test deps_chttp2_fake_security_cancel_before_invoke_test clean_chttp2_fake_security_cancel_before_invoke_test deps_chttp2_fake_security_cancel_in_a_vacuum_test clean_chttp2_fake_security_cancel_in_a_vacuum_test deps_chttp2_fake_security_census_simple_request_test clean_chttp2_fake_security_census_simple_request_test deps_chttp2_fake_security_disappearing_server_test clean_chttp2_fake_security_disappearing_server_test deps_chttp2_fake_security_early_server_shutdown_finishes_inflight_calls_test clean_chttp2_fake_security_early_server_shutdown_finishes_inflight_calls_test deps_chttp2_fake_security_early_server_shutdown_finishes_tags_test clean_chttp2_fake_security_early_server_shutdown_finishes_tags_test deps_chttp2_fake_security_invoke_large_request_test clean_chttp2_fake_security_invoke_large_request_test deps_chttp2_fake_security_max_concurrent_streams_test clean_chttp2_fake_security_max_concurrent_streams_test deps_chttp2_fake_security_no_op_test clean_chttp2_fake_security_no_op_test deps_chttp2_fake_security_ping_pong_streaming_test clean_chttp2_fake_security_ping_pong_streaming_test deps_chttp2_fake_security_request_response_with_binary_metadata_and_payload_test clean_chttp2_fake_security_request_response_with_binary_metadata_and_payload_test deps_chttp2_fake_security_request_response_with_metadata_and_payload_test clean_chttp2_fake_security_request_response_with_metadata_and_payload_test deps_chttp2_fake_security_request_response_with_payload_test clean_chttp2_fake_security_request_response_with_payload_test deps_chttp2_fake_security_request_response_with_trailing_metadata_and_payload_test clean_chttp2_fake_security_request_response_with_trailing_metadata_and_payload_test deps_chttp2_fake_security_simple_delayed_request_test clean_chttp2_fake_security_simple_delayed_request_test deps_chttp2_fake_security_simple_request_test clean_chttp2_fake_security_simple_request_test deps_chttp2_fake_security_thread_stress_test clean_chttp2_fake_security_thread_stress_test deps_chttp2_fake_security_writes_done_hangs_with_pending_read_test clean_chttp2_fake_security_writes_done_hangs_with_pending_read_test deps_chttp2_fullstack_cancel_after_accept_test clean_chttp2_fullstack_cancel_after_accept_test deps_chttp2_fullstack_cancel_after_accept_and_writes_closed_test clean_chttp2_fullstack_cancel_after_accept_and_writes_closed_test deps_chttp2_fullstack_cancel_after_invoke_test clean_chttp2_fullstack_cancel_after_invoke_test deps_chttp2_fullstack_cancel_before_invoke_test clean_chttp2_fullstack_cancel_before_invoke_test deps_chttp2_fullstack_cancel_in_a_vacuum_test clean_chttp2_fullstack_cancel_in_a_vacuum_test deps_chttp2_fullstack_census_simple_request_test clean_chttp2_fullstack_census_simple_request_test deps_chttp2_fullstack_disappearing_server_test clean_chttp2_fullstack_disappearing_server_test deps_chttp2_fullstack_early_server_shutdown_finishes_inflight_calls_test clean_chttp2_fullstack_early_server_shutdown_finishes_inflight_calls_test deps_chttp2_fullstack_early_server_shutdown_finishes_tags_test clean_chttp2_fullstack_early_server_shutdown_finishes_tags_test deps_chttp2_fullstack_invoke_large_request_test clean_chttp2_fullstack_invoke_large_request_test deps_chttp2_fullstack_max_concurrent_streams_test clean_chttp2_fullstack_max_concurrent_streams_test deps_chttp2_fullstack_no_op_test clean_chttp2_fullstack_no_op_test deps_chttp2_fullstack_ping_pong_streaming_test clean_chttp2_fullstack_ping_pong_streaming_test deps_chttp2_fullstack_request_response_with_binary_metadata_and_payload_test clean_chttp2_fullstack_request_response_with_binary_metadata_and_payload_test deps_chttp2_fullstack_request_response_with_metadata_and_payload_test clean_chttp2_fullstack_request_response_with_metadata_and_payload_test deps_chttp2_fullstack_request_response_with_payload_test clean_chttp2_fullstack_request_response_with_payload_test deps_chttp2_fullstack_request_response_with_trailing_metadata_and_payload_test clean_chttp2_fullstack_request_response_with_trailing_metadata_and_payload_test deps_chttp2_fullstack_simple_delayed_request_test clean_chttp2_fullstack_simple_delayed_request_test deps_chttp2_fullstack_simple_request_test clean_chttp2_fullstack_simple_request_test deps_chttp2_fullstack_thread_stress_test clean_chttp2_fullstack_thread_stress_test deps_chttp2_fullstack_writes_done_hangs_with_pending_read_test clean_chttp2_fullstack_writes_done_hangs_with_pending_read_test deps_chttp2_simple_ssl_fullstack_cancel_after_accept_test clean_chttp2_simple_ssl_fullstack_cancel_after_accept_test deps_chttp2_simple_ssl_fullstack_cancel_after_accept_and_writes_closed_test clean_chttp2_simple_ssl_fullstack_cancel_after_accept_and_writes_closed_test deps_chttp2_simple_ssl_fullstack_cancel_after_invoke_test clean_chttp2_simple_ssl_fullstack_cancel_after_invoke_test deps_chttp2_simple_ssl_fullstack_cancel_before_invoke_test clean_chttp2_simple_ssl_fullstack_cancel_before_invoke_test deps_chttp2_simple_ssl_fullstack_cancel_in_a_vacuum_test clean_chttp2_simple_ssl_fullstack_cancel_in_a_vacuum_test deps_chttp2_simple_ssl_fullstack_census_simple_request_test clean_chttp2_simple_ssl_fullstack_census_simple_request_test deps_chttp2_simple_ssl_fullstack_disappearing_server_test clean_chttp2_simple_ssl_fullstack_disappearing_server_test deps_chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_inflight_calls_test clean_chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_inflight_calls_test deps_chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_tags_test clean_chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_tags_test deps_chttp2_simple_ssl_fullstack_invoke_large_request_test clean_chttp2_simple_ssl_fullstack_invoke_large_request_test deps_chttp2_simple_ssl_fullstack_max_concurrent_streams_test clean_chttp2_simple_ssl_fullstack_max_concurrent_streams_test deps_chttp2_simple_ssl_fullstack_no_op_test clean_chttp2_simple_ssl_fullstack_no_op_test deps_chttp2_simple_ssl_fullstack_ping_pong_streaming_test clean_chttp2_simple_ssl_fullstack_ping_pong_streaming_test deps_chttp2_simple_ssl_fullstack_request_response_with_binary_metadata_and_payload_test clean_chttp2_simple_ssl_fullstack_request_response_with_binary_metadata_and_payload_test deps_chttp2_simple_ssl_fullstack_request_response_with_metadata_and_payload_test clean_chttp2_simple_ssl_fullstack_request_response_with_metadata_and_payload_test deps_chttp2_simple_ssl_fullstack_request_response_with_payload_test clean_chttp2_simple_ssl_fullstack_request_response_with_payload_test deps_chttp2_simple_ssl_fullstack_request_response_with_trailing_metadata_and_payload_test clean_chttp2_simple_ssl_fullstack_request_response_with_trailing_metadata_and_payload_test deps_chttp2_simple_ssl_fullstack_simple_delayed_request_test clean_chttp2_simple_ssl_fullstack_simple_delayed_request_test deps_chttp2_simple_ssl_fullstack_simple_request_test clean_chttp2_simple_ssl_fullstack_simple_request_test deps_chttp2_simple_ssl_fullstack_thread_stress_test clean_chttp2_simple_ssl_fullstack_thread_stress_test deps_chttp2_simple_ssl_fullstack_writes_done_hangs_with_pending_read_test clean_chttp2_simple_ssl_fullstack_writes_done_hangs_with_pending_read_test deps_chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_accept_test clean_chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_accept_test deps_chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_accept_and_writes_closed_test clean_chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_accept_and_writes_closed_test deps_chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_invoke_test clean_chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_invoke_test deps_chttp2_simple_ssl_with_oauth2_fullstack_cancel_before_invoke_test clean_chttp2_simple_ssl_with_oauth2_fullstack_cancel_before_invoke_test deps_chttp2_simple_ssl_with_oauth2_fullstack_cancel_in_a_vacuum_test clean_chttp2_simple_ssl_with_oauth2_fullstack_cancel_in_a_vacuum_test deps_chttp2_simple_ssl_with_oauth2_fullstack_census_simple_request_test clean_chttp2_simple_ssl_with_oauth2_fullstack_census_simple_request_test deps_chttp2_simple_ssl_with_oauth2_fullstack_disappearing_server_test clean_chttp2_simple_ssl_with_oauth2_fullstack_disappearing_server_test deps_chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_inflight_calls_test clean_chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_inflight_calls_test deps_chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_tags_test clean_chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_tags_test deps_chttp2_simple_ssl_with_oauth2_fullstack_invoke_large_request_test clean_chttp2_simple_ssl_with_oauth2_fullstack_invoke_large_request_test deps_chttp2_simple_ssl_with_oauth2_fullstack_max_concurrent_streams_test clean_chttp2_simple_ssl_with_oauth2_fullstack_max_concurrent_streams_test deps_chttp2_simple_ssl_with_oauth2_fullstack_no_op_test clean_chttp2_simple_ssl_with_oauth2_fullstack_no_op_test deps_chttp2_simple_ssl_with_oauth2_fullstack_ping_pong_streaming_test clean_chttp2_simple_ssl_with_oauth2_fullstack_ping_pong_streaming_test deps_chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_binary_metadata_and_payload_test clean_chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_binary_metadata_and_payload_test deps_chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_metadata_and_payload_test clean_chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_metadata_and_payload_test deps_chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_payload_test clean_chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_payload_test deps_chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_trailing_metadata_and_payload_test clean_chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_trailing_metadata_and_payload_test deps_chttp2_simple_ssl_with_oauth2_fullstack_simple_delayed_request_test clean_chttp2_simple_ssl_with_oauth2_fullstack_simple_delayed_request_test deps_chttp2_simple_ssl_with_oauth2_fullstack_simple_request_test clean_chttp2_simple_ssl_with_oauth2_fullstack_simple_request_test deps_chttp2_simple_ssl_with_oauth2_fullstack_thread_stress_test clean_chttp2_simple_ssl_with_oauth2_fullstack_thread_stress_test deps_chttp2_simple_ssl_with_oauth2_fullstack_writes_done_hangs_with_pending_read_test clean_chttp2_simple_ssl_with_oauth2_fullstack_writes_done_hangs_with_pending_read_test deps_chttp2_socket_pair_cancel_after_accept_test clean_chttp2_socket_pair_cancel_after_accept_test deps_chttp2_socket_pair_cancel_after_accept_and_writes_closed_test clean_chttp2_socket_pair_cancel_after_accept_and_writes_closed_test deps_chttp2_socket_pair_cancel_after_invoke_test clean_chttp2_socket_pair_cancel_after_invoke_test deps_chttp2_socket_pair_cancel_before_invoke_test clean_chttp2_socket_pair_cancel_before_invoke_test deps_chttp2_socket_pair_cancel_in_a_vacuum_test clean_chttp2_socket_pair_cancel_in_a_vacuum_test deps_chttp2_socket_pair_census_simple_request_test clean_chttp2_socket_pair_census_simple_request_test deps_chttp2_socket_pair_disappearing_server_test clean_chttp2_socket_pair_disappearing_server_test deps_chttp2_socket_pair_early_server_shutdown_finishes_inflight_calls_test clean_chttp2_socket_pair_early_server_shutdown_finishes_inflight_calls_test deps_chttp2_socket_pair_early_server_shutdown_finishes_tags_test clean_chttp2_socket_pair_early_server_shutdown_finishes_tags_test deps_chttp2_socket_pair_invoke_large_request_test clean_chttp2_socket_pair_invoke_large_request_test deps_chttp2_socket_pair_max_concurrent_streams_test clean_chttp2_socket_pair_max_concurrent_streams_test deps_chttp2_socket_pair_no_op_test clean_chttp2_socket_pair_no_op_test deps_chttp2_socket_pair_ping_pong_streaming_test clean_chttp2_socket_pair_ping_pong_streaming_test deps_chttp2_socket_pair_request_response_with_binary_metadata_and_payload_test clean_chttp2_socket_pair_request_response_with_binary_metadata_and_payload_test deps_chttp2_socket_pair_request_response_with_metadata_and_payload_test clean_chttp2_socket_pair_request_response_with_metadata_and_payload_test deps_chttp2_socket_pair_request_response_with_payload_test clean_chttp2_socket_pair_request_response_with_payload_test deps_chttp2_socket_pair_request_response_with_trailing_metadata_and_payload_test clean_chttp2_socket_pair_request_response_with_trailing_metadata_and_payload_test deps_chttp2_socket_pair_simple_delayed_request_test clean_chttp2_socket_pair_simple_delayed_request_test deps_chttp2_socket_pair_simple_request_test clean_chttp2_socket_pair_simple_request_test deps_chttp2_socket_pair_thread_stress_test clean_chttp2_socket_pair_thread_stress_test deps_chttp2_socket_pair_writes_done_hangs_with_pending_read_test clean_chttp2_socket_pair_writes_done_hangs_with_pending_read_test deps_chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_test clean_chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_test deps_chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_and_writes_closed_test clean_chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_and_writes_closed_test deps_chttp2_socket_pair_one_byte_at_a_time_cancel_after_invoke_test clean_chttp2_socket_pair_one_byte_at_a_time_cancel_after_invoke_test deps_chttp2_socket_pair_one_byte_at_a_time_cancel_before_invoke_test clean_chttp2_socket_pair_one_byte_at_a_time_cancel_before_invoke_test deps_chttp2_socket_pair_one_byte_at_a_time_cancel_in_a_vacuum_test clean_chttp2_socket_pair_one_byte_at_a_time_cancel_in_a_vacuum_test deps_chttp2_socket_pair_one_byte_at_a_time_census_simple_request_test clean_chttp2_socket_pair_one_byte_at_a_time_census_simple_request_test deps_chttp2_socket_pair_one_byte_at_a_time_disappearing_server_test clean_chttp2_socket_pair_one_byte_at_a_time_disappearing_server_test deps_chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_inflight_calls_test clean_chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_inflight_calls_test deps_chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_tags_test clean_chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_tags_test deps_chttp2_socket_pair_one_byte_at_a_time_invoke_large_request_test clean_chttp2_socket_pair_one_byte_at_a_time_invoke_large_request_test deps_chttp2_socket_pair_one_byte_at_a_time_max_concurrent_streams_test clean_chttp2_socket_pair_one_byte_at_a_time_max_concurrent_streams_test deps_chttp2_socket_pair_one_byte_at_a_time_no_op_test clean_chttp2_socket_pair_one_byte_at_a_time_no_op_test deps_chttp2_socket_pair_one_byte_at_a_time_ping_pong_streaming_test clean_chttp2_socket_pair_one_byte_at_a_time_ping_pong_streaming_test deps_chttp2_socket_pair_one_byte_at_a_time_request_response_with_binary_metadata_and_payload_test clean_chttp2_socket_pair_one_byte_at_a_time_request_response_with_binary_metadata_and_payload_test deps_chttp2_socket_pair_one_byte_at_a_time_request_response_with_metadata_and_payload_test clean_chttp2_socket_pair_one_byte_at_a_time_request_response_with_metadata_and_payload_test deps_chttp2_socket_pair_one_byte_at_a_time_request_response_with_payload_test clean_chttp2_socket_pair_one_byte_at_a_time_request_response_with_payload_test deps_chttp2_socket_pair_one_byte_at_a_time_request_response_with_trailing_metadata_and_payload_test clean_chttp2_socket_pair_one_byte_at_a_time_request_response_with_trailing_metadata_and_payload_test deps_chttp2_socket_pair_one_byte_at_a_time_simple_delayed_request_test clean_chttp2_socket_pair_one_byte_at_a_time_simple_delayed_request_test deps_chttp2_socket_pair_one_byte_at_a_time_simple_request_test clean_chttp2_socket_pair_one_byte_at_a_time_simple_request_test deps_chttp2_socket_pair_one_byte_at_a_time_thread_stress_test clean_chttp2_socket_pair_one_byte_at_a_time_thread_stress_test deps_chttp2_socket_pair_one_byte_at_a_time_writes_done_hangs_with_pending_read_test clean_chttp2_socket_pair_one_byte_at_a_time_writes_done_hangs_with_pending_read_test
diff --git a/build.json b/build.json
index e0e05c8eaf457185cefc8a76dabf331b731d35ca..219ff23fe137ddeca8dfd0924cf8a08bdf7ad24b 100644
--- a/build.json
+++ b/build.json
@@ -141,6 +141,7 @@
         "src/core/statistics/census_interface.h",
         "src/core/statistics/census_log.h",
         "src/core/statistics/census_rpc_stats.h",
+        "src/core/statistics/census_tracing.h",
         "src/core/statistics/hash_table.h",
         "src/core/statistics/window_stats.h",
         "src/core/surface/call.h",
@@ -334,7 +335,7 @@
         "src/cpp/client/credentials.cc",
         "src/cpp/client/internal_stub.cc",
         "src/cpp/proto/proto_utils.cc",
-        "src/cpp/rpc_method.cc",
+        "src/cpp/common/rpc_method.cc",
         "src/cpp/server/async_server.cc",
         "src/cpp/server/async_server_context.cc",
         "src/cpp/server/completion_queue.cc",
@@ -358,6 +359,9 @@
         "include/grpc++/config.h",
         "include/grpc++/create_channel.h",
         "include/grpc++/credentials.h",
+        "include/grpc++/impl/internal_stub.h",
+        "include/grpc++/impl/rpc_method.h",
+        "include/grpc++/impl/rpc_service_method.h",
         "include/grpc++/server_builder.h",
         "include/grpc++/server_context.h",
         "include/grpc++/server_credentials.h",
@@ -368,10 +372,7 @@
       ],
       "headers": [
         "src/cpp/client/channel.h",
-        "src/cpp/client/internal_stub.h",
         "src/cpp/proto/proto_utils.h",
-        "src/cpp/rpc_method.h",
-        "src/cpp/server/rpc_service_method.h",
         "src/cpp/server/server_rpc_handler.h",
         "src/cpp/server/thread_pool.h",
         "src/cpp/stream/stream_context.h",
@@ -385,7 +386,9 @@
       "name": "grpc++_test_util",
       "build": "test",
       "src": [
+        "test/cpp/util/messages.proto",
         "test/cpp/util/echo.proto",
+        "test/cpp/util/echo_duplicate.proto",
         "test/cpp/util/create_test_channel.cc",
         "test/cpp/end2end/async_test_server.cc"
       ],
@@ -439,6 +442,24 @@
       "deps": []
     },
 
+    {
+      "name": "go_plugin",
+      "build": "protoc",
+      "c++": true,
+      "secure": false,
+      "src": [
+        "src/compiler/go_plugin.cpp",
+        "src/compiler/go_generator.cpp"
+      ],
+      "headers": [
+        "src/compiler/go_generator.h",
+        "src/compiler/go_generator_helpers-inl.h",
+        "src/compiler/go_generator_map-inl.h",
+        "src/compiler/go_generator_string-inl.h"
+      ],
+      "deps": []
+    },
+
     {
       "name": "grpc_byte_buffer_reader_test",
       "build": "test",
@@ -847,6 +868,30 @@
         "gpr"
       ]
     },
+    {
+      "name": "census_trace_store_test",
+      "build": "executable",
+      "src": [
+        "test/core/statistics/trace_test.c"
+      ],
+     "deps": [
+        "grpc_test_util",
+        "grpc",
+        "gpr"
+      ]
+    },
+    {
+      "name": "census_stats_store_test",
+      "build": "executable",
+      "src": [
+        "test/core/statistics/rpc_stats_test.c"
+      ],
+      "deps": [
+        "grpc_test_util",
+        "grpc",
+        "gpr"
+      ]
+    },
     {
       "name": "census_window_stats_test",
       "build": "test",
@@ -1323,6 +1368,7 @@
         "test/cpp/end2end/end2end_test.cc"
       ],
       "deps": [
+        "grpc++_test_util",
         "grpc_test_util",
         "grpc++",
         "grpc",
@@ -1341,6 +1387,18 @@
         "grpc"
       ]
     },
+    {
+      "name": "credentials_test",
+      "build": "test",
+      "c++": true,
+      "src": [
+        "test/cpp/client/credentials_test.cc"
+      ],
+      "deps": [
+        "grpc++",
+        "grpc"
+      ]
+    },
     {
       "name": "alarm_test",
       "build": "test",
diff --git a/include/grpc++/create_channel.h b/include/grpc++/create_channel.h
index 3253c9f18033f53fb56667174fe62757b28e2df3..a8ce8b8ec845458bbace90e62c46d41167b42bf7 100644
--- a/include/grpc++/create_channel.h
+++ b/include/grpc++/create_channel.h
@@ -46,6 +46,7 @@ class ChannelInterface;
 std::shared_ptr<ChannelInterface> CreateChannel(const grpc::string& target,
                                                 const ChannelArguments& args);
 
+// If creds does not hold an object or is invalid, a lame channel is returned.
 std::shared_ptr<ChannelInterface> CreateChannel(
     const grpc::string& target, const std::unique_ptr<Credentials>& creds,
     const ChannelArguments& args);
diff --git a/include/grpc++/credentials.h b/include/grpc++/credentials.h
index 3ad12edaaeb50e91e4236b9ede57d4e5767c7b01..a8debbf7cf2786025b82d6d07546eb1afcb89850 100644
--- a/include/grpc++/credentials.h
+++ b/include/grpc++/credentials.h
@@ -34,6 +34,7 @@
 #ifndef __GRPCPP_CREDENTIALS_H_
 #define __GRPCPP_CREDENTIALS_H_
 
+#include <chrono>
 #include <memory>
 
 #include <grpc++/config.h>
@@ -49,6 +50,7 @@ namespace grpc {
 class Credentials final {
  public:
   ~Credentials();
+
   // TODO(abhikumar): Specify a plugin API here to be implemented by
   // credentials that do not have a corresponding implementation in C.
 
@@ -63,6 +65,15 @@ class Credentials final {
 };
 
 // Options used to build SslCredentials
+// pem_roots_cert is the buffer containing the PEM encoding of the server root
+// certificates. This parameter cannot be empty.
+// pem_private_key is the buffer containing the PEM encoding of the client's
+// private key. This parameter can be empty if the client does not have a
+// private key.
+// pem_cert_chain is the buffer containing the PEM encoding of the client's
+// certificate chain. This parameter can be empty if the client does not have
+// a certificate chain.
+// TODO(jboeuf) Change it to point to a file.
 struct SslCredentialsOptions {
   grpc::string pem_root_certs;
   grpc::string pem_private_key;
@@ -70,6 +81,10 @@ struct SslCredentialsOptions {
 };
 
 // Factory for building different types of Credentials
+// The methods may return empty unique_ptr when credentials cannot be created.
+// If a Credentials pointer is returned, it can still be invalid when used to
+// create a channel. A lame channel will be created then and all rpcs will
+// fail on it.
 class CredentialsFactory {
  public:
   // Builds credentials with reasonable defaults.
@@ -82,6 +97,21 @@ class CredentialsFactory {
   // Builds credentials for use when running in GCE
   static std::unique_ptr<Credentials> ComputeEngineCredentials();
 
+  // Builds service account credentials.
+  // json_key is the JSON key string containing the client's private key.
+  // scope is a space-delimited list of the requested permissions.
+  // token_lifetime is the lifetime of each token acquired through this service
+  // account credentials. It should be positive and should not exceed
+  // grpc_max_auth_token_lifetime or will be cropped to this value.
+  static std::unique_ptr<Credentials> ServiceAccountCredentials(
+      const grpc::string& json_key, const grpc::string& scope,
+      std::chrono::seconds token_lifetime);
+
+  // Builds IAM credentials.
+  static std::unique_ptr<Credentials> IAMCredentials(
+      const grpc::string& authorization_token,
+      const grpc::string& authority_selector);
+
 
   // Combines two credentials objects into a composite credentials
   static std::unique_ptr<Credentials> ComposeCredentials(
diff --git a/src/cpp/client/internal_stub.h b/include/grpc++/impl/internal_stub.h
similarity index 92%
rename from src/cpp/client/internal_stub.h
rename to include/grpc++/impl/internal_stub.h
index 0eaa717d0b65dbcf067bfbc229c5781fd8331c3e..b32fb3a27c00cce6611121400833460b6b8c97af 100644
--- a/src/cpp/client/internal_stub.h
+++ b/include/grpc++/impl/internal_stub.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPCPP_INTERNAL_CLIENT_INTERNAL_STUB_H__
-#define __GRPCPP_INTERNAL_CLIENT_INTERNAL_STUB_H__
+#ifndef __GRPCPP_IMPL_INTERNAL_STUB_H__
+#define __GRPCPP_IMPL_INTERNAL_STUB_H__
 
 #include <memory>
 
@@ -57,4 +57,4 @@ class InternalStub {
 
 }  // namespace grpc
 
-#endif  // __GRPCPP_INTERNAL_CLIENT_INTERNAL_STUB_H__
+#endif  // __GRPCPP_IMPL_INTERNAL_STUB_H__
diff --git a/src/cpp/rpc_method.h b/include/grpc++/impl/rpc_method.h
similarity index 91%
rename from src/cpp/rpc_method.h
rename to include/grpc++/impl/rpc_method.h
index 24a34bed89b9da26c6c91ef5d54b23d7681b0959..75fec356dd47dd0645ea472f741e856f6c47bd7f 100644
--- a/src/cpp/rpc_method.h
+++ b/include/grpc++/impl/rpc_method.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPCPP_INTERNAL_RPC_METHOD_H__
-#define __GRPCPP_INTERNAL_RPC_METHOD_H__
+#ifndef __GRPCPP_IMPL_RPC_METHOD_H__
+#define __GRPCPP_IMPL_RPC_METHOD_H__
 
 namespace google {
 namespace protobuf {
@@ -55,15 +55,15 @@ class RpcMethod {
       : name_(name), method_type_(NORMAL_RPC) {}
   RpcMethod(const char* name, RpcType type) : name_(name), method_type_(type) {}
 
-  const char *name() const { return name_; }
+  const char* name() const { return name_; }
 
   RpcType method_type() const { return method_type_; }
 
  private:
-  const char *name_;
+  const char* name_;
   const RpcType method_type_;
 };
 
 }  // namespace grpc
 
-#endif  // __GRPCPP_INTERNAL_RPC_METHOD_H__
+#endif  // __GRPCPP_IMPL_RPC_METHOD_H__
diff --git a/src/cpp/server/rpc_service_method.h b/include/grpc++/impl/rpc_service_method.h
similarity index 96%
rename from src/cpp/server/rpc_service_method.h
rename to include/grpc++/impl/rpc_service_method.h
index f4fe01c06b64b63e48dd35c633e52357f3288d5d..15ff9cab1a4627e8666b2f1a15ae8596045ec968 100644
--- a/src/cpp/server/rpc_service_method.h
+++ b/include/grpc++/impl/rpc_service_method.h
@@ -31,18 +31,18 @@
  *
  */
 
-#ifndef __GRPCPP_INTERNAL_SERVER_RPC_SERVICE_METHOD_H__
-#define __GRPCPP_INTERNAL_SERVER_RPC_SERVICE_METHOD_H__
+#ifndef __GRPCPP_IMPL_RPC_SERVICE_METHOD_H__
+#define __GRPCPP_IMPL_RPC_SERVICE_METHOD_H__
 
 #include <functional>
 #include <map>
 #include <memory>
 #include <vector>
 
-#include "src/cpp/rpc_method.h"
-#include <google/protobuf/message.h>
+#include <grpc++/impl/rpc_method.h>
 #include <grpc++/status.h>
 #include <grpc++/stream.h>
+#include <google/protobuf/message.h>
 
 namespace grpc {
 class ServerContext;
@@ -200,9 +200,7 @@ class RpcService {
     methods_.push_back(std::unique_ptr<RpcServiceMethod>(method));
   }
 
-  RpcServiceMethod* GetMethod(int i) {
-    return methods_[i].get();
-  }
+  RpcServiceMethod* GetMethod(int i) { return methods_[i].get(); }
   int GetMethodCount() const { return methods_.size(); }
 
  private:
@@ -211,4 +209,4 @@ class RpcService {
 
 }  // namespace grpc
 
-#endif  // __GRPCPP_INTERNAL_SERVER_RPC_SERVICE_METHOD_H__
+#endif  // __GRPCPP_IMPL_RPC_SERVICE_METHOD_H__
diff --git a/include/grpc/support/log.h b/include/grpc/support/log.h
index 5d0b790867376f1f3337c3a3aa0c8b7195078c0d..f92114a8e3eca1f0a58fc4df35f816fda3a39bae 100644
--- a/include/grpc/support/log.h
+++ b/include/grpc/support/log.h
@@ -72,9 +72,21 @@ const char *gpr_log_severity_string(gpr_log_severity severity);
 void gpr_log(const char *file, int line, gpr_log_severity severity,
              const char *format, ...);
 
-/* Same as above, but using a va_list instead. */
-void gpr_vlog(const char *file, int line, gpr_log_severity severity,
-              const char *format, va_list args);
+void gpr_log_message(const char *file, int line, gpr_log_severity severity,
+                     const char *message);
+
+/* Log overrides: applications can use this API to intercept logging calls
+   and use their own implementations */
+
+typedef struct {
+  const char *file;
+  int line;
+  gpr_log_severity severity;
+  const char *message;
+} gpr_log_func_args;
+
+typedef void (*gpr_log_func)(gpr_log_func_args *args);
+void gpr_set_log_function(gpr_log_func func);
 
 /* abort() the process if x is zero, having written a line to the log.
 
diff --git a/include/grpc/support/port_platform.h b/include/grpc/support/port_platform.h
index 978b337724386ec3ea62c0aaafcc046b3715bd10..9c999b9c811e97b3908a02b305ef563f6482477a 100644
--- a/include/grpc/support/port_platform.h
+++ b/include/grpc/support/port_platform.h
@@ -127,7 +127,7 @@
 #endif
 
 #if defined(GPR_CPU_LINUX) + defined(GPR_CPU_POSIX) + defined(GPR_WIN32) != 1
-#error Must define exactly one of GPR_CPU_LINUX, GPR_CPU_POSIX
+#error Must define exactly one of GPR_CPU_LINUX, GPR_CPU_POSIX, GPR_WIN32
 #endif
 
 typedef int16_t gpr_int16;
diff --git a/include/grpc/support/time.h b/include/grpc/support/time.h
index 41d1e88dc945ea134da44ecc89617d9017150565..d5ab9f530529697bdfb8daf22e3b8b563442f03e 100644
--- a/include/grpc/support/time.h
+++ b/include/grpc/support/time.h
@@ -107,6 +107,8 @@ struct timeval gpr_timeval_from_timespec(gpr_timespec t);
 
 gpr_timespec gpr_timespec_from_timeval(struct timeval t);
 
+double gpr_timespec_to_micros(gpr_timespec t);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/src/compiler/cpp_generator.cc b/src/compiler/cpp_generator.cc
index 14d5005dc033d22c0dcff8371246e5217df21933..43a04be931d5d2a1d218e41e9a4e0816f0ac2354 100644
--- a/src/compiler/cpp_generator.cc
+++ b/src/compiler/cpp_generator.cc
@@ -53,8 +53,7 @@ bool ClientOnlyStreaming(const google::protobuf::MethodDescriptor* method) {
 }
 
 bool ServerOnlyStreaming(const google::protobuf::MethodDescriptor* method) {
-  return !method->client_streaming() &&
-         method->server_streaming();
+  return !method->client_streaming() && method->server_streaming();
 }
 
 bool BidiStreaming(const google::protobuf::MethodDescriptor* method) {
@@ -98,7 +97,7 @@ bool HasBidiStreaming(const google::protobuf::FileDescriptor* file) {
 
 string GetHeaderIncludes(const google::protobuf::FileDescriptor* file) {
   string temp =
-      "#include \"src/cpp/client/internal_stub.h\"\n"
+      "#include \"grpc++/impl/internal_stub.h\"\n"
       "#include \"grpc++/status.h\"\n"
       "\n"
       "namespace grpc {\n"
@@ -126,9 +125,9 @@ string GetHeaderIncludes(const google::protobuf::FileDescriptor* file) {
 }
 
 string GetSourceIncludes() {
-  return "#include \"src/cpp/rpc_method.h\"\n"
-         "#include \"src/cpp/server/rpc_service_method.h\"\n"
-         "#include \"grpc++/channel_interface.h\"\n"
+  return "#include \"grpc++/channel_interface.h\"\n"
+         "#include \"grpc++/impl/rpc_method.h\"\n"
+         "#include \"grpc++/impl/rpc_service_method.h\"\n"
          "#include \"grpc++/stream.h\"\n";
 }
 
diff --git a/src/compiler/go_generator.cc b/src/compiler/go_generator.cc
new file mode 100644
index 0000000000000000000000000000000000000000..8beae8dcccf763953ca69653c0a68ae8f8064472
--- /dev/null
+++ b/src/compiler/go_generator.cc
@@ -0,0 +1,520 @@
+/*
+ *
+ * Copyright 2014, 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.
+ *
+ */
+
+using namespace std;
+
+#include "src/compiler/go_generator.h"
+
+#include <cctype>
+
+#include <google/protobuf/io/printer.h>
+#include <google/protobuf/io/zero_copy_stream_impl_lite.h>
+#include <google/protobuf/descriptor.pb.h>
+#include <google/protobuf/descriptor.h>
+
+namespace grpc_go_generator {
+
+bool NoStreaming(const google::protobuf::MethodDescriptor* method) {
+  return !method->client_streaming() &&
+         !method->server_streaming();
+}
+
+bool ClientOnlyStreaming(const google::protobuf::MethodDescriptor* method) {
+  return method->client_streaming() &&
+         !method->server_streaming();
+}
+
+bool ServerOnlyStreaming(const google::protobuf::MethodDescriptor* method) {
+  return !method->client_streaming() &&
+         method->server_streaming();
+}
+
+bool BidiStreaming(const google::protobuf::MethodDescriptor* method) {
+  return method->client_streaming() &&
+         method->server_streaming();
+}
+
+bool HasClientOnlyStreaming(const google::protobuf::FileDescriptor* file) {
+  for (int i = 0; i < file->service_count(); i++) {
+    for (int j = 0; j < file->service(i)->method_count(); j++) {
+      if (ClientOnlyStreaming(file->service(i)->method(j))) {
+        return true;
+      }
+    }
+  }
+  return false;
+}
+
+string LowerCaseService(const string& service) {
+  string ret = service;
+  if (!ret.empty() && ret[0] >= 'A' && ret[0] <= 'Z') {
+    ret[0] = ret[0] - 'A' + 'a';
+  }
+  return ret;
+}
+
+void PrintClientMethodDef(google::protobuf::io::Printer* printer,
+                          const google::protobuf::MethodDescriptor* method,
+                          map<string, string>* vars) {
+  (*vars)["Method"] = method->name();
+  (*vars)["Request"] = method->input_type()->name();
+  (*vars)["Response"] = method->output_type()->name();
+  if (NoStreaming(method)) {
+    printer->Print(*vars,
+        "\t$Method$(ctx context.Context, in *$Request$, opts ...rpc.CallOption) "
+        "(*$Response$, error)\n");
+  } else if (BidiStreaming(method)) {
+    printer->Print(*vars,
+        "\t$Method$(ctx context.Context, opts ...rpc.CallOption) "
+        "($Service$_$Method$Client, error)\n");
+  } else if (ServerOnlyStreaming(method)) {
+    printer->Print(*vars,
+        "\t$Method$(ctx context.Context, m *$Request$, opts ...rpc.CallOption) "
+        "($Service$_$Method$Client, error)\n");
+  } else if (ClientOnlyStreaming(method)) {
+    printer->Print(*vars,
+        "\t$Method$(ctx context.Context, opts ...rpc.CallOption) "
+        "($Service$_$Method$Client, error)\n");
+  }
+}
+
+void PrintClientMethodImpl(google::protobuf::io::Printer* printer,
+                           const google::protobuf::MethodDescriptor* method,
+                           map<string, string>* vars) {
+  (*vars)["Method"] = method->name();
+  (*vars)["Request"] = method->input_type()->name();
+  (*vars)["Response"] = method->output_type()->name();
+
+  if (NoStreaming(method)) {
+    printer->Print(*vars,
+        "func (c *$ServiceStruct$Client) $Method$(ctx context.Context, "
+        "in *$Request$, opts ...rpc.CallOption) (*$Response$, error) {\n");
+    printer->Print(*vars,
+                   "\tout := new($Response$)\n");
+    printer->Print(*vars,
+                   "\terr := rpc.Invoke(ctx, \"/$Package$$Service$/$Method$\", "
+                   "in, out, c.cc, opts...)\n");
+    printer->Print("\tif err != nil {\n");
+    printer->Print("\t\treturn nil, err\n");
+    printer->Print("\t}\n");
+    printer->Print("\treturn out, nil\n");
+    printer->Print("}\n\n");
+  } else if (BidiStreaming(method)) {
+    printer->Print(
+        *vars,
+        "func (c *$ServiceStruct$Client) $Method$(ctx context.Context, opts "
+        "...rpc.CallOption) ($Service$_$Method$Client, error) {\n"
+        "\tstream, err := rpc.NewClientStream(ctx, c.cc, "
+        "\"/$Package$$Service$/$Method$\", opts...)\n"
+        "\tif err != nil {\n"
+        "\t\treturn nil, err\n"
+        "\t}\n"
+        "\treturn &$ServiceStruct$$Method$Client{stream}, nil\n"
+        "}\n\n");
+    printer->Print(*vars,
+        "type $Service$_$Method$Client interface {\n"
+        "\tSend(*$Request$) error\n"
+        "\tRecv() (*$Response$, error)\n"
+        "\trpc.ClientStream\n"
+        "}\n\n");
+    printer->Print(*vars,
+        "type $ServiceStruct$$Method$Client struct {\n"
+        "\trpc.ClientStream\n"
+        "}\n\n");
+    printer->Print(*vars,
+        "func (x *$ServiceStruct$$Method$Client) Send(m *$Request$) error {\n"
+        "\treturn x.ClientStream.SendProto(m)\n"
+        "}\n\n");
+    printer->Print(*vars,
+        "func (x *$ServiceStruct$$Method$Client) Recv() (*$Response$, error) "
+        "{\n"
+        "\tm := new($Response$)\n"
+        "\tif err := x.ClientStream.RecvProto(m); err != nil {\n"
+        "\t\treturn nil, err\n"
+        "\t}\n"
+        "\treturn m, nil\n"
+        "}\n\n");
+  } else if (ServerOnlyStreaming(method)) {
+    printer->Print(
+        *vars,
+        "func (c *$ServiceStruct$Client) $Method$(ctx context.Context, m "
+        "*$Request$, "
+        "opts ...rpc.CallOption) ($Service$_$Method$Client, error) {\n"
+        "\tstream, err := rpc.NewClientStream(ctx, c.cc, "
+        "\"/$Package$$Service$/$Method$\", opts...)\n"
+        "\tif err != nil {\n"
+        "\t\treturn nil, err\n"
+        "\t}\n"
+        "\tx := &$ServiceStruct$$Method$Client{stream}\n"
+        "\tif err := x.ClientStream.SendProto(m); err != nil {\n"
+        "\t\treturn nil, err\n"
+        "\t}\n"
+        "\tif err := x.ClientStream.CloseSend(); err != nil {\n"
+        "\t\treturn nil, err\n"
+        "\t}\n"
+        "\treturn x, nil\n"
+        "}\n\n");
+    printer->Print(*vars,
+        "type $Service$_$Method$Client interface {\n"
+        "\tRecv() (*$Response$, error)\n"
+        "\trpc.ClientStream\n"
+        "}\n\n");
+    printer->Print(*vars,
+        "type $ServiceStruct$$Method$Client struct {\n"
+        "\trpc.ClientStream\n"
+        "}\n\n");
+    printer->Print(*vars,
+        "func (x *$ServiceStruct$$Method$Client) Recv() (*$Response$, error) "
+        "{\n"
+        "\tm := new($Response$)\n"
+        "\tif err := x.ClientStream.RecvProto(m); err != nil {\n"
+        "\t\treturn nil, err\n"
+        "\t}\n"
+        "\treturn m, nil\n"
+        "}\n\n");
+  } else if (ClientOnlyStreaming(method)) {
+    printer->Print(
+        *vars,
+        "func (c *$ServiceStruct$Client) $Method$(ctx context.Context, opts "
+        "...rpc.CallOption) ($Service$_$Method$Client, error) {\n"
+        "\tstream, err := rpc.NewClientStream(ctx, c.cc, "
+        "\"/$Package$$Service$/$Method$\", opts...)\n"
+        "\tif err != nil {\n"
+        "\t\treturn nil, err\n"
+        "\t}\n"
+        "\treturn &$ServiceStruct$$Method$Client{stream}, nil\n"
+        "}\n\n");
+    printer->Print(*vars,
+        "type $Service$_$Method$Client interface {\n"
+        "\tSend(*$Request$) error\n"
+        "\tCloseAndRecv() (*$Response$, error)\n"
+        "\trpc.ClientStream\n"
+        "}\n\n");
+    printer->Print(*vars,
+        "type $ServiceStruct$$Method$Client struct {\n"
+        "\trpc.ClientStream\n"
+        "}\n\n");
+    printer->Print(*vars,
+        "func (x *$ServiceStruct$$Method$Client) Send(m *$Request$) error {\n"
+        "\treturn x.ClientStream.SendProto(m)\n"
+        "}\n\n");
+    printer->Print(*vars,
+        "func (x *$ServiceStruct$$Method$Client) CloseAndRecv() (*$Response$, "
+        "error) {\n"
+        "\tif err := x.ClientStream.CloseSend(); err != nil {\n"
+        "\t\treturn nil, err\n"
+        "\t}\n"
+        "\tm := new($Response$)\n"
+        "\tif err := x.ClientStream.RecvProto(m); err != nil {\n"
+        "\t\treturn nil, err\n"
+        "\t}\n"
+        "\t// Read EOF.\n"
+        "\tif err := x.ClientStream.RecvProto(m); err == io.EOF {\n"
+        "\t\treturn m, io.EOF\n"
+        "\t}\n"
+        "\t// gRPC protocol violation.\n"
+        "\treturn m, fmt.Errorf(\"Violate gRPC client streaming protocol: no "
+        "EOF after the response.\")\n"
+        "}\n\n");
+  }
+}
+
+void PrintClient(google::protobuf::io::Printer* printer,
+                 const google::protobuf::ServiceDescriptor* service,
+                 map<string, string>* vars) {
+  (*vars)["Service"] = service->name();
+  (*vars)["ServiceStruct"] = LowerCaseService(service->name());
+  printer->Print(*vars, "type $Service$Client interface {\n");
+  for (int i = 0; i < service->method_count(); ++i) {
+    PrintClientMethodDef(printer, service->method(i), vars);
+  }
+  printer->Print("}\n\n");
+
+  printer->Print(*vars,
+                 "type $ServiceStruct$Client struct {\n"
+                 "\tcc *rpc.ClientConn\n"
+                 "}\n\n");
+  printer->Print(*vars,
+      "func New$Service$Client(cc *rpc.ClientConn) $Service$Client {\n"
+      "\treturn &$ServiceStruct$Client{cc}\n"
+      "}\n\n");
+  for (int i = 0; i < service->method_count(); ++i) {
+    PrintClientMethodImpl(printer, service->method(i), vars);
+  }
+}
+
+void PrintServerMethodDef(google::protobuf::io::Printer* printer,
+                          const google::protobuf::MethodDescriptor* method,
+                          map<string, string>* vars) {
+  (*vars)["Method"] = method->name();
+  (*vars)["Request"] = method->input_type()->name();
+  (*vars)["Response"] = method->output_type()->name();
+  if (NoStreaming(method)) {
+    printer->Print(*vars,
+        "\t$Method$(context.Context, *$Request$) (*$Response$, error)\n");
+  } else if (BidiStreaming(method)) {
+    printer->Print(*vars,
+        "\t$Method$($Service$_$Method$Server) error\n");
+  } else if (ServerOnlyStreaming(method)) {
+    printer->Print(*vars,
+        "\t$Method$(*$Request$, $Service$_$Method$Server) error\n");
+  } else if (ClientOnlyStreaming(method)) {
+    printer->Print(*vars,
+        "\t$Method$($Service$_$Method$Server) error\n");
+  }
+}
+
+void PrintServerHandler(google::protobuf::io::Printer* printer,
+                        const google::protobuf::MethodDescriptor* method,
+                        map<string, string>* vars) {
+  (*vars)["Method"] = method->name();
+  (*vars)["Request"] = method->input_type()->name();
+  (*vars)["Response"] = method->output_type()->name();
+  if (NoStreaming(method)) {
+    printer->Print(*vars,
+        "func _$Service$_$Method$_Handler(srv interface{}, ctx context.Context,"
+        " buf []byte) (proto.Message, error) {\n");
+    printer->Print(*vars,
+                   "\tin := new($Request$)\n");
+    printer->Print("\tif err := proto.Unmarshal(buf, in); err != nil {\n");
+    printer->Print("\t\treturn nil, err\n");
+    printer->Print("\t}\n");
+    printer->Print(*vars,
+                   "\tout, err := srv.($Service$Server).$Method$(ctx, in)\n");
+    printer->Print("\tif err != nil {\n");
+    printer->Print("\t\treturn nil, err\n");
+    printer->Print("\t}\n");
+    printer->Print("\treturn out, nil\n");
+    printer->Print("}\n\n");
+  } else if (BidiStreaming(method)) {
+    printer->Print(*vars,
+        "func _$Service$_$Method$_Handler(srv interface{}, stream rpc.Stream) "
+        "error {\n"
+        "\treturn srv.($Service$Server).$Method$(&$ServiceStruct$$Method$Server"
+        "{stream})\n"
+        "}\n\n");
+    printer->Print(*vars,
+        "type $Service$_$Method$Server interface {\n"
+        "\tSend(*$Response$) error\n"
+        "\tRecv() (*$Request$, error)\n"
+        "\trpc.Stream\n"
+        "}\n\n");
+    printer->Print(*vars,
+        "type $ServiceStruct$$Method$Server struct {\n"
+        "\trpc.Stream\n"
+        "}\n\n");
+    printer->Print(*vars,
+        "func (x *$ServiceStruct$$Method$Server) Send(m *$Response$) error {\n"
+        "\treturn x.Stream.SendProto(m)\n"
+        "}\n\n");
+    printer->Print(*vars,
+        "func (x *$ServiceStruct$$Method$Server) Recv() (*$Request$, error) "
+        "{\n"
+        "\tm := new($Request$)\n"
+        "\tif err := x.Stream.RecvProto(m); err != nil {\n"
+        "\t\treturn nil, err\n"
+        "\t}\n"
+        "\treturn m, nil\n"
+        "}\n\n");
+  } else if (ServerOnlyStreaming(method)) {
+    printer->Print(*vars,
+        "func _$Service$_$Method$_Handler(srv interface{}, stream rpc.Stream) "
+        "error {\n"
+        "\tm := new($Request$)\n"
+        "\tif err := stream.RecvProto(m); err != nil {\n"
+        "\t\treturn err\n"
+        "\t}\n"
+        "\treturn srv.($Service$Server).$Method$(m, "
+        "&$ServiceStruct$$Method$Server{stream})\n"
+        "}\n\n");
+    printer->Print(*vars,
+        "type $Service$_$Method$Server interface {\n"
+        "\tSend(*$Response$) error\n"
+        "\trpc.Stream\n"
+        "}\n\n");
+    printer->Print(*vars,
+        "type $ServiceStruct$$Method$Server struct {\n"
+        "\trpc.Stream\n"
+        "}\n\n");
+    printer->Print(*vars,
+        "func (x *$ServiceStruct$$Method$Server) Send(m *$Response$) error {\n"
+        "\treturn x.Stream.SendProto(m)\n"
+        "}\n\n");
+  } else if (ClientOnlyStreaming(method)) {
+    printer->Print(*vars,
+        "func _$Service$_$Method$_Handler(srv interface{}, stream rpc.Stream) "
+        "error {\n"
+        "\treturn srv.($Service$Server).$Method$(&$ServiceStruct$$Method$Server"
+        "{stream})\n"
+        "}\n\n");
+    printer->Print(*vars,
+        "type $Service$_$Method$Server interface {\n"
+        "\tSendAndClose(*$Response$) error\n"
+        "\tRecv() (*$Request$, error)\n"
+        "\trpc.Stream\n"
+        "}\n\n");
+    printer->Print(*vars,
+        "type $ServiceStruct$$Method$Server struct {\n"
+        "\trpc.Stream\n"
+        "}\n\n");
+    printer->Print(*vars,
+        "func (x *$ServiceStruct$$Method$Server) SendAndClose(m *$Response$) "
+        "error {\n"
+        "\tif err := x.Stream.SendProto(m); err != nil {\n"
+        "\t\treturn err\n"
+        "\t}\n"
+        "\treturn nil\n"
+        "}\n\n");
+    printer->Print(*vars,
+        "func (x *$ServiceStruct$$Method$Server) Recv() (*$Request$, error) {\n"
+        "\tm := new($Request$)\n"
+        "\tif err := x.Stream.RecvProto(m); err != nil {\n"
+        "\t\treturn nil, err\n"
+        "\t}\n"
+        "\treturn m, nil\n"
+        "}\n\n");
+  }
+}
+
+void PrintServerMethodDesc(google::protobuf::io::Printer* printer,
+                           const google::protobuf::MethodDescriptor* method,
+                           map<string, string>* vars) {
+  (*vars)["Method"] = method->name();
+  printer->Print("\t\t{\n");
+  printer->Print(*vars,
+                 "\t\t\tMethodName:\t\"$Method$\",\n");
+  printer->Print(*vars,
+                 "\t\t\tHandler:\t_$Service$_$Method$_Handler,\n");
+  printer->Print("\t\t},\n");
+}
+
+void PrintServerStreamingMethodDesc(google::protobuf::io::Printer* printer,
+                                    const google::protobuf::MethodDescriptor* method,
+                                    map<string, string>* vars) {
+  (*vars)["Method"] = method->name();
+  printer->Print("\t\t{\n");
+  printer->Print(*vars,
+                 "\t\t\tStreamName:\t\"$Method$\",\n");
+  printer->Print(*vars,
+                 "\t\t\tHandler:\t_$Service$_$Method$_Handler,\n");
+  printer->Print("\t\t},\n");
+}
+
+void PrintServer(google::protobuf::io::Printer* printer,
+                 const google::protobuf::ServiceDescriptor* service,
+                 map<string, string>* vars) {
+  (*vars)["Service"] = service->name();
+  printer->Print(*vars, "type $Service$Server interface {\n");
+  for (int i = 0; i < service->method_count(); ++i) {
+    PrintServerMethodDef(printer, service->method(i), vars);
+  }
+  printer->Print("}\n\n");
+
+  printer->Print(*vars,
+                 "func RegisterService(s *rpc.Server, srv $Service$Server) {\n"
+                 "\ts.RegisterService(&_$Service$_serviceDesc, srv)\n"
+                 "}\n\n");
+
+  for (int i = 0; i < service->method_count(); ++i) {
+    PrintServerHandler(printer, service->method(i), vars);
+  }
+
+  printer->Print(*vars,
+                 "var _$Service$_serviceDesc = rpc.ServiceDesc{\n"
+                 "\tServiceName: \"$Package$$Service$\",\n"
+                 "\tHandlerType: (*$Service$Server)(nil),\n"
+                 "\tMethods: []rpc.MethodDesc{\n");
+  for (int i = 0; i < service->method_count(); ++i) {
+    if (NoStreaming(service->method(i))) {
+      PrintServerMethodDesc(printer, service->method(i), vars);
+    }
+  }
+  printer->Print("\t},\n");
+
+  printer->Print("\tStreams: []rpc.StreamDesc{\n");
+  for (int i = 0; i < service->method_count(); ++i) {
+    if (!NoStreaming(service->method(i))) {
+      PrintServerStreamingMethodDesc(printer, service->method(i), vars);
+    }
+  }
+  printer->Print("\t},\n"
+                 "}\n\n");
+}
+
+std::string BadToUnderscore(std::string str) {
+  for (unsigned i = 0; i < str.size(); ++i) {
+    if (!std::isalnum(str[i])) {
+      str[i] = '_';
+    }
+  }
+  return str;
+}
+
+string GetServices(const google::protobuf::FileDescriptor* file) {
+  string output;
+  google::protobuf::io::StringOutputStream output_stream(&output);
+  google::protobuf::io::Printer printer(&output_stream, '$');
+  map<string, string> vars;
+
+  string package_name = !file->options().go_package().empty()
+                            ? file->options().go_package()
+                            : file->package();
+  vars["PackageName"] = BadToUnderscore(package_name);
+  printer.Print(vars, "package $PackageName$\n\n");
+  printer.Print("import (\n");
+  if (HasClientOnlyStreaming(file)) {
+    printer.Print("\t\"fmt\"\n"
+                  "\t\"io\"\n");
+  }
+  printer.Print(
+      "\t\"google/net/grpc/go/rpc\"\n"
+      "\tcontext \"google/third_party/golang/go_net/context/context\"\n"
+      "\tproto \"google/net/proto2/go/proto\"\n"
+      ")\n\n");
+
+  // $Package$ is used to fully qualify method names.
+  vars["Package"] = file->package();
+  if (!file->package().empty()) {
+    vars["Package"].append(".");
+  }
+
+  for (int i = 0; i < file->service_count(); ++i) {
+    PrintClient(&printer, file->service(0), &vars);
+    printer.Print("\n");
+    PrintServer(&printer, file->service(0), &vars);
+    printer.Print("\n");
+  }
+  return output;
+}
+
+}  // namespace grpc_go_generator
diff --git a/src/compiler/go_generator.h b/src/compiler/go_generator.h
new file mode 100644
index 0000000000000000000000000000000000000000..fd5a05e53741cadb615790daea2dea5131d43d06
--- /dev/null
+++ b/src/compiler/go_generator.h
@@ -0,0 +1,51 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef NET_GRPC_COMPILER_GO_GENERATOR_H_
+#define NET_GRPC_COMPILER_GO_GENERATOR_H_
+
+#include <string>
+
+namespace google {
+namespace protobuf {
+class FileDescriptor;
+}  // namespace protobuf
+}  // namespace google
+
+namespace grpc_go_generator {
+
+string GetServices(const google::protobuf::FileDescriptor* file);
+
+}  // namespace grpc_go_generator
+
+#endif  // NET_GRPC_COMPILER_GO_GENERATOR_H_
diff --git a/src/compiler/go_plugin.cc b/src/compiler/go_plugin.cc
new file mode 100644
index 0000000000000000000000000000000000000000..f941840815e2551bae619822c4088557589ab5f2
--- /dev/null
+++ b/src/compiler/go_plugin.cc
@@ -0,0 +1,83 @@
+/*
+ *
+ * Copyright 2014, 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.
+ *
+ */
+
+// Generates go gRPC service interface out of Protobuf IDL.
+//
+// This is a Proto2 compiler plugin.  See net/proto2/compiler/proto/plugin.proto
+// and net/proto2/compiler/public/plugin.h for more information on plugins.
+
+#include <fstream>
+#include <memory>
+
+using namespace std;
+
+#include "src/compiler/go_generator.h"
+#include <google/protobuf/compiler/code_generator.h>
+#include <google/protobuf/compiler/plugin.h>
+#include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/io/zero_copy_stream.h>
+#include <google/protobuf/descriptor.h>
+
+class GoGrpcGenerator : public google::protobuf::compiler::CodeGenerator {
+ public:
+  GoGrpcGenerator() {}
+  virtual ~GoGrpcGenerator() {}
+
+  virtual bool Generate(const google::protobuf::FileDescriptor* file,
+                        const string& parameter,
+                        google::protobuf::compiler::GeneratorContext* context,
+                        string* error) const {
+    // Get output file name.
+    string file_name;
+    if (file->name().size() > 6 &&
+        file->name().find_last_of(".proto") == file->name().size() - 1) {
+      file_name = file->name().substr(0, file->name().size() - 6) +
+          "_grpc.pb.go";
+    } else {
+      *error = "Invalid proto file name. Proto file must end with .proto";
+      return false;
+    }
+
+    std::unique_ptr<google::protobuf::io::ZeroCopyOutputStream> output(
+        context->Open(file_name));
+    google::protobuf::io::CodedOutputStream coded_out(output.get());
+    string code = grpc_go_generator::GetServices(file);
+    coded_out.WriteRaw(code.data(), code.size());
+    return true;
+  }
+};
+
+int main(int argc, char* argv[]) {
+  GoGrpcGenerator generator;
+  return google::protobuf::compiler::PluginMain(argc, argv, &generator);
+}
diff --git a/src/core/channel/census_filter.c b/src/core/channel/census_filter.c
index d610a6fc9d6fde1eaf876141d9183b53e7c2bffc..2799bded8a6e4d0a054de64e9be89ef56cb391d0 100644
--- a/src/core/channel/census_filter.c
+++ b/src/core/channel/census_filter.c
@@ -60,13 +60,11 @@ static void init_rpc_stats(census_rpc_stats* stats) {
   stats->cnt = 1;
 }
 
-static double gpr_timespec_to_micros(gpr_timespec t) {
-  return t.tv_sec * GPR_US_PER_SEC + t.tv_nsec * 1e-3;
-}
-
 static void extract_and_annotate_method_tag(grpc_call_op* op, call_data* calld,
                                             channel_data* chand) {
   if (op->data.metadata->key == chand->path_str) {
+    gpr_log(GPR_DEBUG,
+            (const char*)GPR_SLICE_START_PTR(op->data.metadata->value->slice));
     census_add_method_tag(calld->op_id, (const char*)GPR_SLICE_START_PTR(
                                             op->data.metadata->value->slice));
   }
@@ -78,7 +76,7 @@ static void client_call_op(grpc_call_element* elem,
   channel_data* chand = elem->channel_data;
   GPR_ASSERT(calld != NULL);
   GPR_ASSERT(chand != NULL);
-  GPR_ASSERT((calld->op_id.upper != 0) && (calld->op_id.lower != 0));
+  GPR_ASSERT((calld->op_id.upper != 0) || (calld->op_id.lower != 0));
   switch (op->type) {
     case GRPC_SEND_METADATA:
       extract_and_annotate_method_tag(op, calld, chand);
@@ -99,7 +97,7 @@ static void server_call_op(grpc_call_element* elem,
   channel_data* chand = elem->channel_data;
   GPR_ASSERT(calld != NULL);
   GPR_ASSERT(chand != NULL);
-  GPR_ASSERT((calld->op_id.upper != 0) && (calld->op_id.lower != 0));
+  GPR_ASSERT((calld->op_id.upper != 0) || (calld->op_id.lower != 0));
   switch (op->type) {
     case GRPC_RECV_METADATA:
       extract_and_annotate_method_tag(op, calld, chand);
@@ -171,7 +169,13 @@ static void init_channel_elem(grpc_channel_element* elem,
   chand->path_str = grpc_mdstr_from_string(mdctx, ":path");
 }
 
-static void destroy_channel_elem(grpc_channel_element* elem) {}
+static void destroy_channel_elem(grpc_channel_element* elem) {
+  channel_data* chand = elem->channel_data;
+  GPR_ASSERT(chand != NULL);
+  if (chand->path_str != NULL) {
+    grpc_mdstr_unref(chand->path_str);
+  }
+}
 
 const grpc_channel_filter grpc_client_census_filter = {
     client_call_op, channel_op,
diff --git a/src/core/channel/connected_channel.c b/src/core/channel/connected_channel.c
index 5faa03c2f446545189840c47fb1dbfd49302737f..e01cb81a890e486fe25f3692af28aa102623d059 100644
--- a/src/core/channel/connected_channel.c
+++ b/src/core/channel/connected_channel.c
@@ -289,12 +289,8 @@ static void accept_stream(void *user_data, grpc_transport *transport,
 }
 
 static void recv_error(channel_data *chand, call_data *calld, int line,
-                       const char *fmt, ...) {
-  va_list a;
-
-  va_start(a, fmt);
-  gpr_vlog(__FILE__, line, GPR_LOG_SEVERITY_ERROR, fmt, a);
-  va_end(a);
+                       const char *message) {
+  gpr_log_message(__FILE__, line, GPR_LOG_SEVERITY_ERROR, message);
 
   if (chand->transport) {
     grpc_transport_abort_stream(chand->transport,
@@ -388,19 +384,23 @@ static void recv_batch(void *user_data, grpc_transport *transport,
       case GRPC_OP_BEGIN_MESSAGE:
         /* can't begin a message when we're still reading a message */
         if (calld->reading_message) {
-          recv_error(chand, calld, __LINE__,
-                     "Message terminated early; read %d bytes, expected %d",
-                     calld->incoming_message.length,
-                     calld->incoming_message_length);
+          char message[128];
+          sprintf(message,
+                  "Message terminated early; read %d bytes, expected %d",
+                  (int)calld->incoming_message.length,
+                  (int)calld->incoming_message_length);
+          recv_error(chand, calld, __LINE__, message);
           return;
         }
         /* stash away parameters, and prepare for incoming slices */
         length = stream_op->data.begin_message.length;
         if (length > calld->max_message_length) {
-          recv_error(
-              chand, calld, __LINE__,
+          char message[128];
+          sprintf(
+              message,
               "Maximum message length of %d exceeded by a message of length %d",
               calld->max_message_length, length);
+          recv_error(chand, calld, __LINE__, message);
         } else if (length > 0) {
           calld->reading_message = 1;
           calld->incoming_message_length = length;
@@ -423,10 +423,12 @@ static void recv_batch(void *user_data, grpc_transport *transport,
         gpr_slice_buffer_add(&calld->incoming_message, stream_op->data.slice);
         if (calld->incoming_message.length > calld->incoming_message_length) {
           /* if we got too many bytes, complain */
-          recv_error(chand, calld, __LINE__,
-                     "Receiving message overflow; read %d bytes, expected %d",
-                     calld->incoming_message.length,
-                     calld->incoming_message_length);
+          char message[128];
+          sprintf(message,
+                  "Receiving message overflow; read %d bytes, expected %d",
+                  (int)calld->incoming_message.length,
+                  (int)calld->incoming_message_length);
+          recv_error(chand, calld, __LINE__, message);
           return;
         } else if (calld->incoming_message.length ==
                    calld->incoming_message_length) {
@@ -439,10 +441,11 @@ static void recv_batch(void *user_data, grpc_transport *transport,
                                  final_state == GRPC_STREAM_CLOSED)) {
     calld->got_read_close = 1;
     if (calld->reading_message) {
-      recv_error(chand, calld, __LINE__,
-                 "Last message truncated; read %d bytes, expected %d",
-                 calld->incoming_message.length,
-                 calld->incoming_message_length);
+      char message[128];
+      sprintf(message, "Last message truncated; read %d bytes, expected %d",
+              (int)calld->incoming_message.length,
+              (int)calld->incoming_message_length);
+      recv_error(chand, calld, __LINE__, message);
     }
     call_op.type = GRPC_RECV_HALF_CLOSE;
     call_op.dir = GRPC_CALL_UP;
diff --git a/src/core/channel/http_server_filter.c b/src/core/channel/http_server_filter.c
index 9a20d79c61fa20d8112e576b9fecba9d37f19f33..44eab43f09d7968c1223416140ca038ef4dddd37 100644
--- a/src/core/channel/http_server_filter.c
+++ b/src/core/channel/http_server_filter.c
@@ -32,13 +32,26 @@
  */
 
 #include "src/core/channel/http_server_filter.h"
+
+#include <string.h>
 #include <grpc/support/log.h>
 
-typedef struct call_data { int sent_status; } call_data;
+typedef struct call_data {
+  int sent_status;
+  int seen_scheme;
+  int seen_method;
+  int seen_te_trailers;
+} call_data;
 
 typedef struct channel_data {
   grpc_mdelem *te_trailers;
-  grpc_mdelem *status_md;
+  grpc_mdelem *method;
+  grpc_mdelem *http_scheme;
+  grpc_mdelem *https_scheme;
+  /* TODO(klempner): Remove this once we stop using it */
+  grpc_mdelem *grpc_scheme;
+  grpc_mdelem *content_type;
+  grpc_mdelem *status;
 } channel_data;
 
 /* used to silence 'variable not used' warnings */
@@ -56,20 +69,54 @@ static void call_op(grpc_call_element *elem, grpc_call_element *from_elem,
   channel_data *channeld = elem->channel_data;
   GRPC_CALL_LOG_OP(GPR_INFO, elem, op);
 
-  ignore_unused(calld);
-  ignore_unused(channeld);
-
   switch (op->type) {
     case GRPC_RECV_METADATA:
-      /* check if it's a te: trailers header */
-      if (op->data.metadata == channeld->te_trailers) {
+      /* Check if it is one of the headers we care about. */
+      if (op->data.metadata == channeld->te_trailers ||
+          op->data.metadata == channeld->method ||
+          op->data.metadata == channeld->http_scheme ||
+          op->data.metadata == channeld->https_scheme ||
+          op->data.metadata == channeld->grpc_scheme ||
+          op->data.metadata == channeld->content_type) {
         /* swallow it */
+        if (op->data.metadata == channeld->method) {
+          calld->seen_method = 1;
+        } else if (op->data.metadata->key == channeld->http_scheme->key) {
+          calld->seen_scheme = 1;
+        } else if (op->data.metadata == channeld->te_trailers) {
+          calld->seen_te_trailers = 1;
+        }
+        /* TODO(klempner): Track that we've seen all the headers we should
+           require */
         grpc_mdelem_unref(op->data.metadata);
         op->done_cb(op->user_data, GRPC_OP_OK);
-      } else if (op->data.metadata->key == channeld->te_trailers->key) {
-        gpr_log(GPR_ERROR, "Invalid te: header: '%s'",
+      } else if (op->data.metadata->key == channeld->content_type->key) {
+        if (strncmp(grpc_mdstr_as_c_string(op->data.metadata->value),
+                    "application/grpc+", 17) == 0) {
+          /* Although the C implementation doesn't (currently) generate them,
+             any
+             custom +-suffix is explicitly valid. */
+          /* TODO(klempner): We should consider preallocating common values such
+             as +proto or +json, or at least stashing them if we see them. */
+          /* TODO(klempner): Should we be surfacing this to application code? */
+        } else {
+          /* TODO(klempner): We're currently allowing this, but we shouldn't
+             see it without a proxy so log for now. */
+          gpr_log(GPR_INFO, "Unexpected content-type %s",
+                  channeld->content_type->key);
+        }
+        grpc_mdelem_unref(op->data.metadata);
+        op->done_cb(op->user_data, GRPC_OP_OK);
+      } else if (op->data.metadata->key == channeld->te_trailers->key ||
+                 op->data.metadata->key == channeld->method->key ||
+                 op->data.metadata->key == channeld->http_scheme->key ||
+                 op->data.metadata->key == channeld->content_type->key) {
+        gpr_log(GPR_ERROR, "Invalid %s: header: '%s'",
+                grpc_mdstr_as_c_string(op->data.metadata->key),
                 grpc_mdstr_as_c_string(op->data.metadata->value));
-        /* swallow it */
+        /* swallow it and error everything out. */
+        /* TODO(klempner): We ought to generate more descriptive error messages
+           on the wire here. */
         grpc_mdelem_unref(op->data.metadata);
         op->done_cb(op->user_data, GRPC_OP_OK);
         grpc_call_element_send_cancel(elem);
@@ -78,14 +125,33 @@ static void call_op(grpc_call_element *elem, grpc_call_element *from_elem,
         grpc_call_next_op(elem, op);
       }
       break;
+    case GRPC_RECV_END_OF_INITIAL_METADATA:
+      /* Have we seen the required http2 transport headers?
+         (:method, :scheme, content-type, with :path and :authority covered
+         at the channel level right now) */
+      if (calld->seen_method && calld->seen_scheme && calld->seen_te_trailers) {
+        grpc_call_next_op(elem, op);
+      } else {
+        if (!calld->seen_method) {
+          gpr_log(GPR_ERROR, "Missing :method header");
+        } else if (!calld->seen_scheme) {
+          gpr_log(GPR_ERROR, "Missing :scheme header");
+        } else if (!calld->seen_te_trailers) {
+          gpr_log(GPR_ERROR, "Missing te trailers header");
+        }
+        /* Error this call out */
+        op->done_cb(op->user_data, GRPC_OP_OK);
+        grpc_call_element_send_cancel(elem);
+      }
+      break;
     case GRPC_SEND_START:
     case GRPC_SEND_METADATA:
       /* If we haven't sent status 200 yet, we need to so so because it needs to
          come before any non : prefixed metadata. */
       if (!calld->sent_status) {
         calld->sent_status = 1;
-        /* status_md is reffed by grpc_call_element_send_metadata */
-        grpc_call_element_send_metadata(elem, channeld->status_md);
+        /* status is reffed by grpc_call_element_send_metadata */
+        grpc_call_element_send_metadata(elem, channeld->status);
       }
       grpc_call_next_op(elem, op);
       break;
@@ -124,6 +190,9 @@ static void init_call_elem(grpc_call_element *elem,
 
   /* initialize members */
   calld->sent_status = 0;
+  calld->seen_scheme = 0;
+  calld->seen_method = 0;
+  calld->seen_te_trailers = 0;
 }
 
 /* Destructor for call_data */
@@ -151,7 +220,13 @@ static void init_channel_elem(grpc_channel_element *elem,
 
   /* initialize members */
   channeld->te_trailers = grpc_mdelem_from_strings(mdctx, "te", "trailers");
-  channeld->status_md = grpc_mdelem_from_strings(mdctx, ":status", "200");
+  channeld->status = grpc_mdelem_from_strings(mdctx, ":status", "200");
+  channeld->method = grpc_mdelem_from_strings(mdctx, ":method", "POST");
+  channeld->http_scheme = grpc_mdelem_from_strings(mdctx, ":scheme", "http");
+  channeld->https_scheme = grpc_mdelem_from_strings(mdctx, ":scheme", "https");
+  channeld->grpc_scheme = grpc_mdelem_from_strings(mdctx, ":scheme", "grpc");
+  channeld->content_type =
+      grpc_mdelem_from_strings(mdctx, "content-type", "application/grpc");
 }
 
 /* Destructor for channel data */
@@ -160,7 +235,12 @@ static void destroy_channel_elem(grpc_channel_element *elem) {
   channel_data *channeld = elem->channel_data;
 
   grpc_mdelem_unref(channeld->te_trailers);
-  grpc_mdelem_unref(channeld->status_md);
+  grpc_mdelem_unref(channeld->status);
+  grpc_mdelem_unref(channeld->method);
+  grpc_mdelem_unref(channeld->http_scheme);
+  grpc_mdelem_unref(channeld->https_scheme);
+  grpc_mdelem_unref(channeld->grpc_scheme);
+  grpc_mdelem_unref(channeld->content_type);
 }
 
 const grpc_channel_filter grpc_http_server_filter = {
diff --git a/src/core/security/security_context.c b/src/core/security/security_context.c
index 13b9a847eeb2a5efbea016570f07614f0b30c802..917a22f453801c06b54aba1f2f95802e7be7a12f 100644
--- a/src/core/security/security_context.c
+++ b/src/core/security/security_context.c
@@ -451,7 +451,7 @@ static grpc_channel *grpc_ssl_channel_create(grpc_credentials *creds,
   grpc_security_status status = GRPC_SECURITY_OK;
   size_t i = 0;
   const char *secure_peer_name = target;
-  for (i = 0; i < args->num_args; i++) {
+  for (i = 0; args && i < args->num_args; i++) {
     grpc_arg *arg = &args->args[i];
     if (!strcmp(arg->key, GRPC_SSL_TARGET_NAME_OVERRIDE_ARG) &&
         arg->type == GRPC_ARG_STRING) {
@@ -492,12 +492,17 @@ static grpc_channel *grpc_channel_create_from_composite_creds(
     return grpc_ssl_channel_create(
         composite_creds, grpc_ssl_credentials_get_config(creds), target, args);
   }
-  return NULL; /* TODO(ctiller): return lame channel. */
+  gpr_log(GPR_ERROR, "Credentials is insufficient to create a secure channel.");
+  return grpc_lame_client_channel_create();
 }
 
 grpc_channel *grpc_secure_channel_create(grpc_credentials *creds,
                                          const char *target,
                                          const grpc_channel_args *args) {
+  if (creds == NULL) {
+    gpr_log(GPR_ERROR, "No credentials to create a secure channel.");
+    return grpc_lame_client_channel_create();
+  }
   if (grpc_credentials_has_request_metadata_only(creds)) {
     gpr_log(GPR_ERROR,
             "Credentials is insufficient to create a secure channel.");
@@ -518,7 +523,8 @@ grpc_channel *grpc_secure_channel_create(grpc_credentials *creds,
     return grpc_channel_create_from_composite_creds(creds, target, args);
   } else {
     gpr_log(GPR_ERROR,
-            "Unknown credentials type %s for creating a secure channel.");
+            "Unknown credentials type %s for creating a secure channel.",
+            creds->type);
     return grpc_lame_client_channel_create();
   }
 }
diff --git a/src/core/statistics/census_init.c b/src/core/statistics/census_init.c
index 340214f8f5504cfd45364c12c0afa9f30158b09c..bcb9ff9ad4e2634958fce861ef84b788ea77414b 100644
--- a/src/core/statistics/census_init.c
+++ b/src/core/statistics/census_init.c
@@ -33,5 +33,18 @@
 
 #include "src/core/statistics/census_interface.h"
 
-void census_init() {}
-void census_shutdown() {}
+#include <grpc/support/log.h>
+#include "src/core/statistics/census_rpc_stats.h"
+#include "src/core/statistics/census_tracing.h"
+
+void census_init() {
+  gpr_log(GPR_INFO, "Initialize census library.");
+  census_tracing_init();
+  census_stats_store_init();
+}
+
+void census_shutdown() {
+  gpr_log(GPR_INFO, "Shutdown census library.");
+  census_stats_store_shutdown();
+  census_tracing_shutdown();
+}
diff --git a/src/core/statistics/census_rpc_stats.c b/src/core/statistics/census_rpc_stats.c
index 28101ac734d0669d2116aaacc14b403a8c820f5e..a1ac2abff3b89d8ec18ffd1526a6455562678fdb 100644
--- a/src/core/statistics/census_rpc_stats.c
+++ b/src/core/statistics/census_rpc_stats.c
@@ -35,7 +35,85 @@
 
 #include "src/core/statistics/census_interface.h"
 #include "src/core/statistics/census_rpc_stats.h"
+#include "src/core/statistics/hash_table.h"
+#include "src/core/statistics/census_tracing.h"
+#include "src/core/statistics/window_stats.h"
+#include "src/core/support/murmur_hash.h"
 #include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/string.h>
+#include <grpc/support/sync.h>
+
+#define NUM_INTERVALS 3
+#define MINUTE_INTERVAL 0
+#define HOUR_INTERVAL 1
+#define TOTAL_INTERVAL 2
+
+/* for easier typing */
+typedef census_per_method_rpc_stats per_method_stats;
+
+/* Ensure mu is only initialized once. */
+static gpr_once g_stats_store_mu_init = GPR_ONCE_INIT;
+/* Guards two stats stores. */
+static gpr_mu g_mu;
+static census_ht* g_client_stats_store = NULL;
+static census_ht* g_server_stats_store = NULL;
+
+static void init_mutex() { gpr_mu_init(&g_mu); }
+
+static void init_mutex_once() {
+  gpr_once_init(&g_stats_store_mu_init, init_mutex);
+}
+
+static int cmp_str_keys(const void* k1, const void* k2) {
+  return strcmp((const char*)k1, (const char*)k2);
+}
+
+/* TODO(hongyu): replace it with cityhash64 */
+static gpr_uint64 simple_hash(const void* k) {
+  size_t len = strlen(k);
+  gpr_uint64 higher = gpr_murmur_hash3((const char*)k, len / 2, 0);
+  return higher << 32 |
+         gpr_murmur_hash3((const char*)k + len / 2, len - len / 2, 0);
+}
+
+static void delete_stats(void* stats) {
+  census_window_stats_destroy((struct census_window_stats*)stats);
+}
+
+static void delete_key(void* key) { gpr_free(key); }
+
+static const census_ht_option ht_opt = {
+    CENSUS_HT_POINTER /* key type */, 1999 /* n_of_buckets */,
+    simple_hash /* hash function */,  cmp_str_keys /* key comparator */,
+    delete_stats /* data deleter */,  delete_key /* key deleter */};
+
+static void init_rpc_stats(void* stats) {
+  memset(stats, 0, sizeof(census_rpc_stats));
+}
+
+static void stat_add_proportion(double p, void* base, const void* addme) {
+  census_rpc_stats* b = (census_rpc_stats*)base;
+  census_rpc_stats* a = (census_rpc_stats*)addme;
+  b->cnt += p * a->cnt;
+  b->rpc_error_cnt += p * a->rpc_error_cnt;
+  b->app_error_cnt += p * a->app_error_cnt;
+  b->elapsed_time_ms += p * a->elapsed_time_ms;
+  b->api_request_bytes += p * a->api_request_bytes;
+  b->wire_request_bytes += p * a->wire_request_bytes;
+  b->api_response_bytes += p * a->api_response_bytes;
+  b->wire_response_bytes += p * a->wire_response_bytes;
+}
+
+static void stat_add(void* base, const void* addme) {
+  stat_add_proportion(1.0, base, addme);
+}
+
+static gpr_timespec min_hour_total_intervals[3] = {
+    {60, 0}, {3600, 0}, {36000000, 0}};
+
+static const census_window_stats_stat_info window_stats_settings = {
+    sizeof(census_rpc_stats), init_rpc_stats, stat_add, stat_add_proportion};
 
 census_rpc_stats* census_rpc_stats_create_empty() {
   census_rpc_stats* ret =
@@ -44,14 +122,132 @@ census_rpc_stats* census_rpc_stats_create_empty() {
   return ret;
 }
 
-void census_aggregated_rpc_stats_destroy(census_aggregated_rpc_stats* data) {}
+void census_aggregated_rpc_stats_set_empty(census_aggregated_rpc_stats* data) {
+  int i = 0;
+  for (i = 0; i < data->num_entries; i++) {
+    if (data->stats[i].method != NULL) {
+      gpr_free((void*)data->stats[i].method);
+    }
+  }
+  if (data->stats != NULL) {
+    gpr_free(data->stats);
+  }
+  data->num_entries = 0;
+  data->stats = NULL;
+}
+
+static void record_stats(census_ht* store, census_op_id op_id,
+                         const census_rpc_stats* stats) {
+  gpr_mu_lock(&g_mu);
+  if (store != NULL) {
+    trace_obj* trace = NULL;
+    census_internal_lock_trace_store();
+    trace = census_get_trace_obj_locked(op_id);
+    if (trace != NULL) {
+      const char* method_name = census_get_trace_method_name(trace);
+      struct census_window_stats* window_stats = NULL;
+      census_ht_key key;
+      key.ptr = (void*)method_name;
+      window_stats = census_ht_find(store, key);
+      census_internal_unlock_trace_store();
+      if (window_stats == NULL) {
+        window_stats = census_window_stats_create(3, min_hour_total_intervals,
+                                                  30, &window_stats_settings);
+        key.ptr = gpr_strdup(key.ptr);
+        census_ht_insert(store, key, (void*)window_stats);
+      }
+      census_window_stats_add(window_stats, gpr_now(), stats);
+    } else {
+      census_internal_unlock_trace_store();
+    }
+  }
+  gpr_mu_unlock(&g_mu);
+}
 
 void census_record_rpc_client_stats(census_op_id op_id,
-                                    const census_rpc_stats* stats) {}
+                                    const census_rpc_stats* stats) {
+  record_stats(g_client_stats_store, op_id, stats);
+}
 
 void census_record_rpc_server_stats(census_op_id op_id,
-                                    const census_rpc_stats* stats) {}
+                                    const census_rpc_stats* stats) {
+  record_stats(g_server_stats_store, op_id, stats);
+}
 
-void census_get_server_stats(census_aggregated_rpc_stats* data) {}
+/* Get stats from input stats store */
+static void get_stats(census_ht* store, census_aggregated_rpc_stats* data) {
+  GPR_ASSERT(data != NULL);
+  if (data->num_entries != 0) {
+    census_aggregated_rpc_stats_set_empty(data);
+  }
+  gpr_mu_lock(&g_mu);
+  if (store != NULL) {
+    size_t n;
+    int i, j;
+    gpr_timespec now = gpr_now();
+    census_ht_kv* kv = census_ht_get_all_elements(store, &n);
+    if (kv != NULL) {
+      data->num_entries = n;
+      data->stats = (per_method_stats*)gpr_malloc(sizeof(per_method_stats) * n);
+      for (i = 0; i < n; i++) {
+        census_window_stats_sums sums[NUM_INTERVALS];
+        for (j = 0; j < NUM_INTERVALS; j++) {
+          sums[j].statistic = (void*)census_rpc_stats_create_empty();
+        }
+        data->stats[i].method = gpr_strdup(kv[i].k.ptr);
+        census_window_stats_get_sums(kv[i].v, now, sums);
+        data->stats[i].minute_stats =
+            *(census_rpc_stats*)sums[MINUTE_INTERVAL].statistic;
+        data->stats[i].hour_stats =
+            *(census_rpc_stats*)sums[HOUR_INTERVAL].statistic;
+        data->stats[i].total_stats =
+            *(census_rpc_stats*)sums[TOTAL_INTERVAL].statistic;
+        for (j = 0; j < NUM_INTERVALS; j++) {
+          gpr_free(sums[j].statistic);
+        }
+      }
+      gpr_free(kv);
+    }
+  }
+  gpr_mu_unlock(&g_mu);
+}
+
+void census_get_client_stats(census_aggregated_rpc_stats* data) {
+  get_stats(g_client_stats_store, data);
+}
+
+void census_get_server_stats(census_aggregated_rpc_stats* data) {
+  get_stats(g_server_stats_store, data);
+}
+
+void census_stats_store_init() {
+  gpr_log(GPR_INFO, "Initialize census stats store.");
+  init_mutex_once();
+  gpr_mu_lock(&g_mu);
+  if (g_client_stats_store == NULL && g_server_stats_store == NULL) {
+    g_client_stats_store = census_ht_create(&ht_opt);
+    g_server_stats_store = census_ht_create(&ht_opt);
+  } else {
+    gpr_log(GPR_ERROR, "Census stats store already initialized.");
+  }
+  gpr_mu_unlock(&g_mu);
+}
 
-void census_get_client_stats(census_aggregated_rpc_stats* data) {}
+void census_stats_store_shutdown() {
+  gpr_log(GPR_INFO, "Shutdown census stats store.");
+  init_mutex_once();
+  gpr_mu_lock(&g_mu);
+  if (g_client_stats_store != NULL) {
+    census_ht_destroy(g_client_stats_store);
+    g_client_stats_store = NULL;
+  } else {
+    gpr_log(GPR_ERROR, "Census server stats store not initialized.");
+  }
+  if (g_server_stats_store != NULL) {
+    census_ht_destroy(g_server_stats_store);
+    g_server_stats_store = NULL;
+  } else {
+    gpr_log(GPR_ERROR, "Census client stats store not initialized.");
+  }
+  gpr_mu_unlock(&g_mu);
+}
diff --git a/src/core/statistics/census_rpc_stats.h b/src/core/statistics/census_rpc_stats.h
index 6ab7614805eb6e0f38e5d9372e0e2c60b3a60cf4..e1ff3ac31b78ca30965abb0d2207c2aa0368ea86 100644
--- a/src/core/statistics/census_rpc_stats.h
+++ b/src/core/statistics/census_rpc_stats.h
@@ -37,6 +37,10 @@
 #include "src/core/statistics/census_interface.h"
 #include <grpc/support/port_platform.h>
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 struct census_rpc_stats {
   gpr_uint64 cnt;
   gpr_uint64 rpc_error_cnt;
@@ -51,19 +55,20 @@ struct census_rpc_stats {
 /* Creates an empty rpc stats object on heap. */
 census_rpc_stats* census_rpc_stats_create_empty();
 
-typedef struct census_per_service_per_method_rpc_stats {
-  const char* service;
+typedef struct census_per_method_rpc_stats {
   const char* method;
-  census_rpc_stats data;
-} census_per_service_per_method_rpc_stats;
+  census_rpc_stats minute_stats; /* cumulative stats in the past minute */
+  census_rpc_stats hour_stats;   /* cumulative stats in the past hour */
+  census_rpc_stats total_stats;  /* cumulative stats from last gc */
+} census_per_method_rpc_stats;
 
 typedef struct census_aggregated_rpc_stats {
   int num_entries;
-  census_per_service_per_method_rpc_stats* stats;
+  census_per_method_rpc_stats* stats;
 } census_aggregated_rpc_stats;
 
-/* Deletes aggregated data. */
-void census_aggregated_rpc_stats_destroy(census_aggregated_rpc_stats* data);
+/* Initializes an aggregated rpc stats object to an empty state. */
+void census_aggregated_rpc_stats_set_empty(census_aggregated_rpc_stats* data);
 
 /* Records client side stats of a rpc. */
 void census_record_rpc_client_stats(census_op_id op_id,
@@ -86,4 +91,11 @@ void census_get_server_stats(census_aggregated_rpc_stats* data_map);
    DO NOT CALL from outside of grpc code. */
 void census_get_client_stats(census_aggregated_rpc_stats* data_map);
 
+void census_stats_store_init();
+void census_stats_store_shutdown();
+
+#ifdef __cplusplus
+}
+#endif
+
 #endif  /* __GRPC_INTERNAL_STATISTICS_CENSUS_RPC_STATS_H__ */
diff --git a/src/core/statistics/census_tracing.c b/src/core/statistics/census_tracing.c
index d0c90328378b70f95cc71bdb26481b7de4162306..45302cd6abedf4ab44624664b105a1b011a9465b 100644
--- a/src/core/statistics/census_tracing.c
+++ b/src/core/statistics/census_tracing.c
@@ -33,15 +33,174 @@
 
 #include "src/core/statistics/census_interface.h"
 
+#include <stdio.h>
+#include <string.h>
+
+#include "src/core/statistics/census_rpc_stats.h"
+#include "src/core/statistics/hash_table.h"
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/port_platform.h>
+#include <grpc/support/string.h>
+#include <grpc/support/sync.h>
+#include <grpc/support/time.h>
+
+/* Struct for a trace annotation. */
+typedef struct annotation {
+  gpr_timespec ts;                            /* timestamp of the annotation */
+  char txt[CENSUS_MAX_ANNOTATION_LENGTH + 1]; /* actual txt annotation */
+  struct annotation* next;
+} annotation;
+
+typedef struct trace_obj {
+  census_op_id id;
+  gpr_timespec ts;
+  census_rpc_stats rpc_stats;
+  char* method;
+  annotation* annotations;
+} trace_obj;
+
+static void trace_obj_destroy(trace_obj* obj) {
+  annotation* p = obj->annotations;
+  while (p != NULL) {
+    annotation* next = p->next;
+    gpr_free(p);
+    p = next;
+  }
+  gpr_free(obj->method);
+  gpr_free(obj);
+}
+
+static void delete_trace_obj(void* obj) { trace_obj_destroy((trace_obj*)obj); }
+
+static const census_ht_option ht_opt = {
+    CENSUS_HT_UINT64 /* key type*/, 571 /* n_of_buckets */, NULL /* hash */,
+    NULL /* compare_keys */, delete_trace_obj /* delete data */,
+    NULL /* delete key */};
+
+static gpr_once g_init_mutex_once = GPR_ONCE_INIT;
+static gpr_mu g_mu; /* Guards following two static variables. */
+static census_ht* g_trace_store = NULL;
+static gpr_uint64 g_id = 0;
+
+static census_ht_key op_id_as_key(census_op_id* id) {
+  return *(census_ht_key*)id;
+}
+
+static gpr_uint64 op_id_2_uint64(census_op_id* id) {
+  gpr_uint64 ret;
+  memcpy(&ret, id, sizeof(census_op_id));
+  return ret;
+}
+
+static void init_mutex() { gpr_mu_init(&g_mu); }
+
+static void init_mutex_once() { gpr_once_init(&g_init_mutex_once, init_mutex); }
+
 census_op_id census_tracing_start_op() {
-  census_op_id empty_op_id = {0, 0};
-  return empty_op_id;
+  gpr_mu_lock(&g_mu);
+  {
+    trace_obj* ret = (trace_obj*)gpr_malloc(sizeof(trace_obj));
+    memset(ret, 0, sizeof(trace_obj));
+    g_id++;
+    memcpy(&ret->id, &g_id, sizeof(census_op_id));
+    ret->rpc_stats.cnt = 1;
+    ret->ts = gpr_now();
+    census_ht_insert(g_trace_store, op_id_as_key(&ret->id), (void*)ret);
+    gpr_log(GPR_DEBUG, "Start tracing for id %lu", g_id);
+    gpr_mu_unlock(&g_mu);
+    return ret->id;
+  }
+}
+
+int census_add_method_tag(census_op_id op_id, const char* method) {
+  int ret = 0;
+  trace_obj* trace = NULL;
+  gpr_mu_lock(&g_mu);
+  trace = census_ht_find(g_trace_store, op_id_as_key(&op_id));
+  if (trace == NULL) {
+    ret = 1;
+  } else {
+    trace->method = gpr_strdup(method);
+  }
+  gpr_mu_unlock(&g_mu);
+  return ret;
 }
 
-int census_add_method_tag(census_op_id op_id, const char* method_name) {
-  return 0;
+void census_tracing_print(census_op_id op_id, const char* anno_txt) {
+  trace_obj* trace = NULL;
+  gpr_mu_lock(&g_mu);
+  trace = census_ht_find(g_trace_store, op_id_as_key(&op_id));
+  if (trace != NULL) {
+    annotation* anno = gpr_malloc(sizeof(annotation));
+    anno->ts = gpr_now();
+    {
+      char* d = anno->txt;
+      const char* s = anno_txt;
+      int n = 0;
+      for (; n < CENSUS_MAX_ANNOTATION_LENGTH && *s != '\0'; ++n) {
+        *d++ = *s++;
+      }
+      *d = '\0';
+    }
+    anno->next = trace->annotations;
+    trace->annotations = anno;
+  }
+  gpr_mu_unlock(&g_mu);
 }
 
-void census_tracing_print(census_op_id op_id, const char* annotation) {}
+void census_tracing_end_op(census_op_id op_id) {
+  trace_obj* trace = NULL;
+  gpr_mu_lock(&g_mu);
+  trace = census_ht_find(g_trace_store, op_id_as_key(&op_id));
+  if (trace != NULL) {
+    trace->rpc_stats.elapsed_time_ms =
+        gpr_timespec_to_micros(gpr_time_sub(gpr_now(), trace->ts));
+    gpr_log(GPR_DEBUG, "End tracing for id %lu, method %s, latency %f us",
+            op_id_2_uint64(&op_id), trace->method,
+            trace->rpc_stats.elapsed_time_ms);
+    census_ht_erase(g_trace_store, op_id_as_key(&op_id));
+  }
+  gpr_mu_unlock(&g_mu);
+}
 
-void census_tracing_end_op(census_op_id op_id) {}
+void census_tracing_init() {
+  gpr_log(GPR_INFO, "Initialize census trace store.");
+  init_mutex_once();
+  gpr_mu_lock(&g_mu);
+  if (g_trace_store == NULL) {
+    g_id = 1;
+    g_trace_store = census_ht_create(&ht_opt);
+  } else {
+    gpr_log(GPR_ERROR, "Census trace store already initialized.");
+  }
+  gpr_mu_unlock(&g_mu);
+}
+
+void census_tracing_shutdown() {
+  gpr_log(GPR_INFO, "Shutdown census trace store.");
+  gpr_mu_lock(&g_mu);
+  if (g_trace_store != NULL) {
+    census_ht_destroy(g_trace_store);
+    g_trace_store = NULL;
+  } else {
+    gpr_log(GPR_ERROR, "Census trace store is not initialized.");
+  }
+  gpr_mu_unlock(&g_mu);
+}
+
+void census_internal_lock_trace_store() { gpr_mu_lock(&g_mu); }
+
+void census_internal_unlock_trace_store() { gpr_mu_unlock(&g_mu); }
+
+trace_obj* census_get_trace_obj_locked(census_op_id op_id) {
+  if (g_trace_store == NULL) {
+    gpr_log(GPR_ERROR, "Census trace store is not initialized.");
+    return NULL;
+  }
+  return (trace_obj*)census_ht_find(g_trace_store, op_id_as_key(&op_id));
+}
+
+const char* census_get_trace_method_name(const trace_obj* trace) {
+  return (const char*)trace->method;
+}
diff --git a/src/core/statistics/census_tracing.h b/src/core/statistics/census_tracing.h
new file mode 100644
index 0000000000000000000000000000000000000000..2285a5cd6bd8e797e6991bb1464911f3daf4eb5f
--- /dev/null
+++ b/src/core/statistics/census_tracing.h
@@ -0,0 +1,59 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef __GRPC_INTERNAL_STATISTICS_CENSUS_TRACING_H_
+#define __GRPC_INTERNAL_STATISTICS_CENSUS_TRACING_H_
+
+/* Opaque structure for trace object */
+typedef struct trace_obj trace_obj;
+
+/* Initializes trace store. This function is thread safe. */
+void census_tracing_init();
+
+/* Shutsdown trace store. This function is thread safe. */
+void census_tracing_shutdown();
+
+/* Gets trace obj corresponding to the input op_id. Returns NULL if trace store
+   is not initialized or trace obj is not found. Requires trace store being
+   locked before calling this function. */
+trace_obj* census_get_trace_obj_locked(census_op_id op_id);
+
+/* The following two functions acquire and release the trace store global lock.
+   They are for census internal use only. */
+void census_internal_lock_trace_store();
+void census_internal_unlock_trace_store();
+
+/* Gets method tag name associated with the input trace object. */
+const char* census_get_trace_method_name(const trace_obj* trace);
+
+#endif /* __GRPC_INTERNAL_STATISTICS_CENSUS_TRACING_H_ */
diff --git a/src/core/statistics/hash_table.c b/src/core/statistics/hash_table.c
index f0105ee6830bc443f7609b2d1b64d824fc050c68..1aee86d3a45e17bbf23d77f72195c0be47680974 100644
--- a/src/core/statistics/hash_table.c
+++ b/src/core/statistics/hash_table.c
@@ -141,10 +141,10 @@ static gpr_int32 find_bucket_idx(const census_ht* ht, census_ht_key key) {
 
 static int keys_match(const census_ht_option* opt, const ht_entry* p,
                       const census_ht_key key) {
+  GPR_ASSERT(opt->key_type == CENSUS_HT_UINT64 ||
+             opt->key_type == CENSUS_HT_POINTER);
   if (opt->key_type == CENSUS_HT_UINT64) return p->key.val == key.val;
-  if (opt->key_type == CENSUS_HT_POINTER)
-    return !opt->compare_keys((p->key).ptr, key.ptr);
-  return 0;
+  return !opt->compare_keys((p->key).ptr, key.ptr);
 }
 
 static entry_locator ht_find(const census_ht* ht, census_ht_key key) {
diff --git a/src/core/support/log.c b/src/core/support/log.c
index b9e2897efc341777a2277f598d3898a4c0193d60..7f102efea8277de4f3e32e1f64db3352e8c22e62 100644
--- a/src/core/support/log.c
+++ b/src/core/support/log.c
@@ -34,6 +34,10 @@
 #include <grpc/support/log.h>
 
 #include <stdio.h>
+#include <string.h>
+
+extern void gpr_default_log(gpr_log_func_args *args);
+static gpr_log_func g_log_func = gpr_default_log;
 
 const char *gpr_log_severity_string(gpr_log_severity severity) {
   switch (severity) {
@@ -47,12 +51,15 @@ const char *gpr_log_severity_string(gpr_log_severity severity) {
   return "UNKNOWN";
 }
 
-void gpr_log(const char *file, int line, gpr_log_severity severity,
-             const char *format, ...) {
-  va_list args;
-  va_start(args, format);
-
-  gpr_vlog(file, line, severity, format, args);
-
-  va_end(args);
+void gpr_log_message(const char *file, int line, gpr_log_severity severity,
+                     const char *message) {
+  gpr_log_func_args lfargs;
+  memset(&lfargs, 0, sizeof(lfargs));
+  lfargs.file = file;
+  lfargs.line = line;
+  lfargs.severity = severity;
+  lfargs.message = message;
+  g_log_func(&lfargs);
 }
+
+void gpr_set_log_function(gpr_log_func f) { g_log_func = f; }
diff --git a/src/core/support/log_android.c b/src/core/support/log_android.c
index 4c83e09914625a4f46eef60b4f082f504a9add70..11129e3e066d598f6f77588ad24e400ec7eda0d8 100644
--- a/src/core/support/log_android.c
+++ b/src/core/support/log_android.c
@@ -54,25 +54,31 @@ static android_LogPriority severity_to_log_priority(gpr_log_severity severity) {
   return ANDROID_LOG_DEFAULT;
 }
 
-void gpr_vlog(const char *file, int line, gpr_log_severity severity,
-              const char *format, va_list args) {
+void gpr_log(const char *file, int line, gpr_log_severity severity,
+             const char *format, ...) {
+  char *message = NULL;
+  va_list args;
+  va_start(args, format);
+  vasprintf(&message, format, args);
+  va_end(args);
+  gpr_log_message(file, line, severity, message);
+  free(message);
+}
+
+void gpr_default_log(gpr_log_func_args *args) {
   char *final_slash;
   const char *display_file;
-  char *prefix = NULL;
-  char *suffix = NULL;
   char *output = NULL;
 
-  final_slash = strrchr(file, '/');
+  final_slash = strrchr(args->file, '/');
   if (final_slash == NULL)
     display_file = file;
   else
     display_file = final_slash + 1;
 
-  asprintf(&prefix, "%s:%d] ", display_file, line);
-  vasprintf(&suffix, format, args);
-  asprintf(&output, "%s%s", prefix, suffix);
+  asprintf(&prefix, "%s:%d] %s", display_file, args->line, args->message);
 
-  __android_log_write(severity_to_log_priority(severity), "GRPC", output);
+  __android_log_write(severity_to_log_priority(args->severity), "GRPC", output);
 
   /* allocated by asprintf => use free, not gpr_free */
   free(prefix);
diff --git a/src/core/support/log_linux.c b/src/core/support/log_linux.c
index 322ff07dd90db33c807a208519283c492f2ed152..f3b528bdc4d357f204a72451ef24b9b6fb56eebf 100644
--- a/src/core/support/log_linux.c
+++ b/src/core/support/log_linux.c
@@ -49,17 +49,27 @@
 
 static long gettid() { return syscall(__NR_gettid); }
 
-void gpr_vlog(const char *file, int line, gpr_log_severity severity,
-              const char *format, va_list args) {
+void gpr_log(const char *file, int line, gpr_log_severity severity,
+             const char *format, ...) {
+  char *message = NULL;
+  va_list args;
+  va_start(args, format);
+  vasprintf(&message, format, args);
+  va_end(args);
+  gpr_log_message(file, line, severity, message);
+  free(message);
+}
+
+void gpr_default_log(gpr_log_func_args *args) {
   char *final_slash;
   const char *display_file;
   char time_buffer[64];
   gpr_timespec now = gpr_now();
   struct tm tm;
 
-  final_slash = strrchr(file, '/');
+  final_slash = strrchr(args->file, '/');
   if (final_slash == NULL)
-    display_file = file;
+    display_file = args->file;
   else
     display_file = final_slash + 1;
 
@@ -70,12 +80,10 @@ void gpr_vlog(const char *file, int line, gpr_log_severity severity,
     strcpy(time_buffer, "error:strftime");
   }
 
-  flockfile(stderr);
-  fprintf(stderr, "%s%s.%09d %7ld %s:%d] ", gpr_log_severity_string(severity),
-          time_buffer, (int)(now.tv_nsec), gettid(), display_file, line);
-  vfprintf(stderr, format, args);
-  fputc('\n', stderr);
-  funlockfile(stderr);
+  fprintf(stderr, "%s%s.%09d %7ld %s:%d] %s\n",
+          gpr_log_severity_string(args->severity), time_buffer,
+          (int)(now.tv_nsec), gettid(), display_file, args->line,
+          args->message);
 }
 
 #endif
diff --git a/src/core/support/log_posix.c b/src/core/support/log_posix.c
index b47c433cd717906b32d0920c2f50484aa35a1c3b..0420570a3ec66087335f5b9a0d16703796737d29 100644
--- a/src/core/support/log_posix.c
+++ b/src/core/support/log_posix.c
@@ -47,17 +47,40 @@
 
 static long gettid() { return pthread_self(); }
 
-void gpr_vlog(const char *file, int line, gpr_log_severity severity,
-              const char *format, va_list args) {
+void gpr_log(const char *file, int line, gpr_log_severity severity,
+             const char *format, ...) {
+  char buf[64];
+  char *allocated = NULL;
+  char *message = NULL;
+  int ret;
+  va_list args;
+  va_start(args, format);
+  ret = vsnprintf(buf, format, args);
+  va_end(args);
+  if (ret < 0) {
+    message = NULL;
+  } else if (ret <= sizeof(buf) - 1) {
+    message = buf;
+  } else {
+    message = allocated = gpr_malloc(ret + 1);
+    va_start(args, format);
+    vsnprintf(message, format, args);
+    va_end(args);
+  }
+  gpr_log_message(file, line, severity, message);
+  gpr_free(allocated);
+}
+
+void gpr_default_log(gpr_log_func_args *args) {
   char *final_slash;
   const char *display_file;
   char time_buffer[64];
   gpr_timespec now = gpr_now();
   struct tm tm;
 
-  final_slash = strrchr(file, '/');
+  final_slash = strrchr(args->file, '/');
   if (final_slash == NULL)
-    display_file = file;
+    display_file = args->file;
   else
     display_file = final_slash + 1;
 
@@ -68,12 +91,10 @@ void gpr_vlog(const char *file, int line, gpr_log_severity severity,
     strcpy(time_buffer, "error:strftime");
   }
 
-  flockfile(stderr);
-  fprintf(stderr, "%s%s.%09d %7ld %s:%d] ", gpr_log_severity_string(severity),
-          time_buffer, (int)(now.tv_nsec), gettid(), display_file, line);
-  vfprintf(stderr, format, args);
-  fputc('\n', stderr);
-  funlockfile(stderr);
+  fprintf(stderr, "%s%s.%09d %7ld %s:%d] %s\n",
+          gpr_log_severity_string(args->severity), time_buffer,
+          (int)(now.tv_nsec), gettid(), display_file, args->line,
+          args->message);
 }
 
 #endif /* defined(GPR_POSIX_LOG) */
diff --git a/src/core/support/log_win32.c b/src/core/support/log_win32.c
index e6567dca7e7e5f8fa9bbc04bb0ea4405e1683fbb..ae5f23a90dc9f406596b39c527ada1b91c3b38e5 100644
--- a/src/core/support/log_win32.c
+++ b/src/core/support/log_win32.c
@@ -39,12 +39,42 @@
 #include <stdio.h>
 #include <stdarg.h>
 
+void gpr_log(const char *file, int line, gpr_log_severity severity,
+             const char *message) {
+  const char *message = NULL;
+  va_list args;
+  int ret;
+
+  /* Determine the length. */
+  va_start(args, format);
+  ret = _vscprintf(format, args);
+  va_end(args);
+  if (!(0 <= ret && ret < ~(size_t)0)) {
+    message = NULL;
+  } else {
+    /* Allocate a new buffer, with space for the NUL terminator. */
+    strp_buflen = (size_t)ret + 1;
+    message = gpr_malloc(strp_buflen);
+
+    /* Print to the buffer. */
+    va_start(args, format);
+    ret = vsnprintf_s(message, strp_buflen, _TRUNCATE, format, args);
+    va_end(args);
+    if (ret != strp_buflen - 1) {
+      /* This should never happen. */
+      gpr_free(message);
+      message = NULL;
+    }
+  }
+
+  gpr_log_message(file, line, severity, message);
+  gpr_free(message);
+}
+
 /* Simple starter implementation */
-void gpr_vlog(const char *file, int line, gpr_log_severity severity,
-              const char *format, va_list args) {
-  fprintf(stderr, "%s %s:%d: ", gpr_log_severity_string(severity), file, line);
-  vfprintf(stderr, format, args);
-  fputc('\n', stderr);
+void gpr_default_log(gpr_log_func_args *args) {
+  fprintf(stderr, "%s %s:%d: %s\n", gpr_log_severity_string(severity),
+          args->file, args->line, args->message);
 }
 
 #endif
diff --git a/src/core/support/time.c b/src/core/support/time.c
index 5330092f56befa7c5c89d77b04228e259a11a8df..0e88c65be0c43341b13a0eb89bca2080aca6457a 100644
--- a/src/core/support/time.c
+++ b/src/core/support/time.c
@@ -264,3 +264,7 @@ gpr_int32 gpr_time_to_millis(gpr_timespec t) {
     return t.tv_sec * GPR_MS_PER_SEC + t.tv_nsec / GPR_NS_PER_MS;
   }
 }
+
+double gpr_timespec_to_micros(gpr_timespec t) {
+  return t.tv_sec * GPR_US_PER_SEC + t.tv_nsec * 1e-3;
+}
diff --git a/src/core/surface/lame_client.c b/src/core/surface/lame_client.c
index 6a832436cae8b67f78e5c5915a48449428c0b7c2..5fa3e42362c1af766b585b47917c43f4c29aa438 100644
--- a/src/core/surface/lame_client.c
+++ b/src/core/surface/lame_client.c
@@ -33,6 +33,8 @@
 
 #include "src/core/surface/lame_client.h"
 
+#include <string.h>
+
 #include "src/core/channel/channel_stack.h"
 #include "src/core/surface/channel.h"
 #include "src/core/surface/call.h"
@@ -42,16 +44,28 @@
 
 typedef struct { void *unused; } call_data;
 
-typedef struct { void *unused; } channel_data;
+typedef struct { grpc_mdelem *message; } channel_data;
+
+static void do_nothing(void *data, grpc_op_error error) {}
 
 static void call_op(grpc_call_element *elem, grpc_call_element *from_elem,
                     grpc_call_op *op) {
+  channel_data *channeld = elem->channel_data;
   GRPC_CALL_LOG_OP(GPR_INFO, elem, op);
 
   switch (op->type) {
-    case GRPC_SEND_START:
+    case GRPC_SEND_START: {
+      grpc_call_op set_status_op;
+      grpc_mdelem_ref(channeld->message);
+      memset(&set_status_op, 0, sizeof(grpc_call_op));
+      set_status_op.dir = GRPC_CALL_UP;
+      set_status_op.type = GRPC_RECV_METADATA;
+      set_status_op.done_cb = do_nothing;
+      set_status_op.data.metadata = channeld->message;
+      grpc_call_recv_metadata(elem, &set_status_op);
       grpc_call_recv_finish(elem, 1);
       break;
+    }
     case GRPC_SEND_METADATA:
       grpc_mdelem_unref(op->data.metadata);
       break;
@@ -81,11 +95,20 @@ static void destroy_call_elem(grpc_call_element *elem) {}
 static void init_channel_elem(grpc_channel_element *elem,
                               const grpc_channel_args *args, grpc_mdctx *mdctx,
                               int is_first, int is_last) {
+  channel_data *channeld = elem->channel_data;
+
   GPR_ASSERT(is_first);
   GPR_ASSERT(is_last);
+
+  channeld->message = grpc_mdelem_from_strings(mdctx, "grpc-message",
+                                               "Rpc sent on a lame channel.");
 }
 
-static void destroy_channel_elem(grpc_channel_element *elem) {}
+static void destroy_channel_elem(grpc_channel_element *elem) {
+  channel_data *channeld = elem->channel_data;
+
+  grpc_mdelem_unref(channeld->message);
+}
 
 static const grpc_channel_filter lame_filter = {
     call_op, channel_op,
diff --git a/src/core/transport/chttp2/stream_encoder.c b/src/core/transport/chttp2/stream_encoder.c
index 8595a598793480487b6cdb2cd54bb69d00f5acd2..92a36d0c160a6b62a7f0601a8dd2e7bef279c871 100644
--- a/src/core/transport/chttp2/stream_encoder.c
+++ b/src/core/transport/chttp2/stream_encoder.c
@@ -68,8 +68,6 @@ typedef struct {
   gpr_uint8 last_was_header;
   /* output stream id */
   gpr_uint32 stream_id;
-  /* number of flow controlled bytes written */
-  gpr_uint32 output_size;
   gpr_slice_buffer *output;
 } framer_state;
 
@@ -464,49 +462,31 @@ void grpc_chttp2_hpack_compressor_destroy(grpc_chttp2_hpack_compressor *c) {
   grpc_mdstr_unref(c->timeout_key_str);
 }
 
-gpr_uint32 grpc_chttp2_encode_some(grpc_stream_op *ops, size_t *ops_count,
-                                   int eof, gpr_slice_buffer *output,
-                                   gpr_uint32 max_bytes, gpr_uint32 stream_id,
-                                   grpc_chttp2_hpack_compressor *compressor) {
-  framer_state st;
+gpr_uint32 grpc_chttp2_preencode(grpc_stream_op *inops, size_t *inops_count,
+                                 gpr_uint32 max_flow_controlled_bytes,
+                                 grpc_stream_op_buffer *outops) {
   gpr_slice slice;
   grpc_stream_op *op;
   gpr_uint32 max_take_size;
+  gpr_uint32 flow_controlled_bytes_taken = 0;
   gpr_uint32 curop = 0;
-  gpr_uint32 nops = *ops_count;
   gpr_uint8 *p;
 
-  GPR_ASSERT(stream_id != 0);
-
-  st.cur_frame_type = NONE;
-  st.last_was_header = 0;
-  st.stream_id = stream_id;
-  st.output = output;
-  st.output_size = 0;
-
-  while (curop < nops) {
-    GPR_ASSERT(st.output_size <= max_bytes);
-    op = &ops[curop];
+  while (curop < *inops_count) {
+    GPR_ASSERT(flow_controlled_bytes_taken <= max_flow_controlled_bytes);
+    op = &inops[curop];
     switch (op->type) {
       case GRPC_NO_OP:
+        /* skip */
         curop++;
         break;
       case GRPC_OP_FLOW_CTL_CB:
-        op->data.flow_ctl_cb.cb(op->data.flow_ctl_cb.arg, GRPC_OP_OK);
-        curop++;
-        break;
-      case GRPC_OP_METADATA:
-        hpack_enc(compressor, op->data.metadata, &st);
-        curop++;
-        break;
       case GRPC_OP_DEADLINE:
-        deadline_enc(compressor, op->data.deadline, &st);
-        curop++;
-        break;
+      case GRPC_OP_METADATA:
       case GRPC_OP_METADATA_BOUNDARY:
-        ensure_frame_type(&st, HEADER, 0);
-        finish_frame(&st, 1, 0);
-        st.last_was_header = 0; /* force a new header frame */
+        /* these just get copied as they don't impact the number of flow
+           controlled bytes */
+        grpc_sopb_append(outops, op, 1);
         curop++;
         break;
       case GRPC_OP_BEGIN_MESSAGE:
@@ -525,42 +505,100 @@ gpr_uint32 grpc_chttp2_encode_some(grpc_stream_op *ops, size_t *ops_count,
       case GRPC_OP_SLICE:
         slice = op->data.slice;
         if (!GPR_SLICE_LENGTH(slice)) {
+          /* skip zero length slices */
+          gpr_slice_unref(slice);
           curop++;
           break;
         }
-        if (st.output_size == max_bytes) {
+        max_take_size = max_flow_controlled_bytes - flow_controlled_bytes_taken;
+        if (max_take_size == 0) {
           goto exit_loop;
         }
+        if (GPR_SLICE_LENGTH(slice) > max_take_size) {
+          slice = gpr_slice_split_head(&op->data.slice, max_take_size);
+          grpc_sopb_add_slice(outops, slice);
+        } else {
+          /* consume this op immediately */
+          grpc_sopb_append(outops, op, 1);
+          curop++;
+        }
+        flow_controlled_bytes_taken += GPR_SLICE_LENGTH(slice);
+        break;
+    }
+  }
+exit_loop:
+  *inops_count -= curop;
+  memmove(inops, inops + curop, *inops_count * sizeof(grpc_stream_op));
+
+  return flow_controlled_bytes_taken;
+}
+
+void grpc_chttp2_encode(grpc_stream_op *ops, size_t ops_count, int eof,
+                        gpr_uint32 stream_id,
+                        grpc_chttp2_hpack_compressor *compressor,
+                        gpr_slice_buffer *output) {
+  framer_state st;
+  gpr_slice slice;
+  grpc_stream_op *op;
+  gpr_uint32 max_take_size;
+  gpr_uint32 curop = 0;
+
+  GPR_ASSERT(stream_id != 0);
+
+  st.cur_frame_type = NONE;
+  st.last_was_header = 0;
+  st.stream_id = stream_id;
+  st.output = output;
+
+  while (curop < ops_count) {
+    op = &ops[curop];
+    switch (op->type) {
+      case GRPC_NO_OP:
+      case GRPC_OP_BEGIN_MESSAGE:
+        gpr_log(
+            GPR_ERROR,
+            "These stream ops should be filtered out by grpc_chttp2_preencode");
+        abort();
+      case GRPC_OP_FLOW_CTL_CB:
+        op->data.flow_ctl_cb.cb(op->data.flow_ctl_cb.arg, GRPC_OP_OK);
+        curop++;
+        break;
+      case GRPC_OP_METADATA:
+        hpack_enc(compressor, op->data.metadata, &st);
+        curop++;
+        break;
+      case GRPC_OP_DEADLINE:
+        deadline_enc(compressor, op->data.deadline, &st);
+        curop++;
+        break;
+      case GRPC_OP_METADATA_BOUNDARY:
+        ensure_frame_type(&st, HEADER, 0);
+        finish_frame(&st, 1, 0);
+        st.last_was_header = 0; /* force a new header frame */
+        curop++;
+        break;
+      case GRPC_OP_SLICE:
+        slice = op->data.slice;
         if (st.cur_frame_type == DATA &&
             st.output->length - st.output_length_at_start_of_frame ==
                 GRPC_CHTTP2_MAX_PAYLOAD_LENGTH) {
           finish_frame(&st, 0, 0);
         }
         ensure_frame_type(&st, DATA, 1);
-        max_take_size =
-            GPR_MIN(max_bytes - st.output_size,
-                    GRPC_CHTTP2_MAX_PAYLOAD_LENGTH +
-                        st.output_length_at_start_of_frame - st.output->length);
+        max_take_size = GRPC_CHTTP2_MAX_PAYLOAD_LENGTH +
+                        st.output_length_at_start_of_frame - st.output->length;
         if (GPR_SLICE_LENGTH(slice) > max_take_size) {
           slice = gpr_slice_split_head(&op->data.slice, max_take_size);
         } else {
           /* consume this op immediately */
           curop++;
         }
-        st.output_size += GPR_SLICE_LENGTH(slice);
         gpr_slice_buffer_add(output, slice);
         break;
     }
   }
-exit_loop:
   if (eof && st.cur_frame_type == NONE) {
     begin_frame(&st, DATA);
   }
-  finish_frame(&st, 1, eof && curop == nops);
-
-  nops -= curop;
-  *ops_count = nops;
-  memmove(ops, ops + curop, nops * sizeof(grpc_stream_op));
-
-  return st.output_size;
+  finish_frame(&st, 1, eof);
 }
diff --git a/src/core/transport/chttp2/stream_encoder.h b/src/core/transport/chttp2/stream_encoder.h
index dad64697a52229575e5d7e5c680cada09db5a3ec..4b093e8495979d3f692a2c3532143bb7a21dba23 100644
--- a/src/core/transport/chttp2/stream_encoder.h
+++ b/src/core/transport/chttp2/stream_encoder.h
@@ -78,9 +78,16 @@ 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);
 
-gpr_uint32 grpc_chttp2_encode_some(grpc_stream_op *ops, size_t *ops_count,
-                                   int eof, gpr_slice_buffer *output,
-                                   gpr_uint32 max_bytes, gpr_uint32 stream_id,
-                                   grpc_chttp2_hpack_compressor *compressor);
+/* select stream ops to be encoded, moving them from inops to outops, and
+   moving subsequent ops in inops forward in the queue */
+gpr_uint32 grpc_chttp2_preencode(grpc_stream_op *inops, size_t *inops_count,
+                                 gpr_uint32 max_flow_controlled_bytes,
+                                 grpc_stream_op_buffer *outops);
+
+/* encode stream ops to output */
+void grpc_chttp2_encode(grpc_stream_op *ops, size_t ops_count, int eof,
+                        gpr_uint32 stream_id,
+                        grpc_chttp2_hpack_compressor *compressor,
+                        gpr_slice_buffer *output);
 
 #endif  /* __GRPC_INTERNAL_TRANSPORT_CHTTP2_STREAM_ENCODER_H__ */
diff --git a/src/core/transport/chttp2_transport.c b/src/core/transport/chttp2_transport.c
index 5bf763e76f5f95e02106e30074d89b6c0f8c6e5e..1b90d4715b3c1520410c6e6c6a2cf0fd35e607d4 100644
--- a/src/core/transport/chttp2_transport.c
+++ b/src/core/transport/chttp2_transport.c
@@ -71,6 +71,13 @@ typedef struct stream stream;
 typedef enum {
   /* streams that have pending writes */
   WRITABLE = 0,
+  /* streams that have been selected to be written */
+  WRITING,
+  /* streams that have just been written, and included a close */
+  WRITTEN_CLOSED,
+  /* streams that have been cancelled and have some pending state updates
+     to perform */
+  CANCELLED,
   /* streams that want to send window updates */
   WINDOW_UPDATE,
   /* streams that are waiting to start because there are too many concurrent
@@ -258,7 +265,12 @@ struct stream {
 
   gpr_uint32 outgoing_window;
   gpr_uint32 incoming_window;
-  gpr_uint8 write_closed;
+  /* when the application requests writes be closed, the write_closed is
+     'queued'; when the close is flow controlled into the send path, we are
+     'sending' it; when the write has been performed it is 'sent' */
+  gpr_uint8 queued_write_closed;
+  gpr_uint8 sending_write_closed;
+  gpr_uint8 sent_write_closed;
   gpr_uint8 read_closed;
   gpr_uint8 cancelled;
   gpr_uint8 allow_window_updates;
@@ -267,7 +279,10 @@ struct stream {
   stream_link links[STREAM_LIST_COUNT];
   gpr_uint8 included[STREAM_LIST_COUNT];
 
+  /* sops from application */
   grpc_stream_op_buffer outgoing_sopb;
+  /* sops that have passed flow control to be written */
+  grpc_stream_op_buffer writing_sopb;
 
   grpc_chttp2_data_parser parser;
 
@@ -284,7 +299,7 @@ static int prepare_callbacks(transport *t);
 static void run_callbacks(transport *t);
 
 static int prepare_write(transport *t);
-static void finish_write(void *t, grpc_endpoint_cb_status status);
+static void perform_write(transport *t, grpc_endpoint *ep);
 
 static void lock(transport *t);
 static void unlock(transport *t);
@@ -303,6 +318,7 @@ static void cancel_stream_id(transport *t, gpr_uint32 id,
 static void cancel_stream(transport *t, stream *s,
                           grpc_status_code local_status,
                           grpc_chttp2_error_code error_code, int send_rst);
+static void finalize_cancellations(transport *t);
 static stream *lookup_stream(transport *t, gpr_uint32 id);
 static void remove_from_stream_map(transport *t, stream *s);
 static void maybe_start_some_streams(transport *t);
@@ -518,7 +534,9 @@ static int init_stream(grpc_transport *gt, grpc_stream *gs,
       t->settings[PEER_SETTINGS][GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE];
   s->incoming_window =
       t->settings[SENT_SETTINGS][GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE];
-  s->write_closed = 0;
+  s->queued_write_closed = 0;
+  s->sending_write_closed = 0;
+  s->sent_write_closed = 0;
   s->read_closed = 0;
   s->cancelled = 0;
   s->allow_window_updates = 0;
@@ -526,8 +544,9 @@ static int init_stream(grpc_transport *gt, grpc_stream *gs,
   memset(&s->links, 0, sizeof(s->links));
   memset(&s->included, 0, sizeof(s->included));
   grpc_sopb_init(&s->outgoing_sopb);
-  grpc_chttp2_data_parser_init(&s->parser);
+  grpc_sopb_init(&s->writing_sopb);
   grpc_sopb_init(&s->callback_sopb);
+  grpc_chttp2_data_parser_init(&s->parser);
 
   if (!server_data) {
     unlock(t);
@@ -565,8 +584,9 @@ static void destroy_stream(grpc_transport *gt, grpc_stream *gs) {
   gpr_mu_unlock(&t->mu);
 
   grpc_sopb_destroy(&s->outgoing_sopb);
-  grpc_chttp2_data_parser_destroy(&s->parser);
+  grpc_sopb_destroy(&s->writing_sopb);
   grpc_sopb_destroy(&s->callback_sopb);
+  grpc_chttp2_data_parser_destroy(&s->parser);
 
   unref_transport(t);
 }
@@ -575,6 +595,10 @@ static void destroy_stream(grpc_transport *gt, grpc_stream *gs) {
  * LIST MANAGEMENT
  */
 
+static int stream_list_empty(transport *t, stream_list_id id) {
+  return t->lists[id].head == NULL;
+}
+
 static stream *stream_list_remove_head(transport *t, stream_list_id id) {
   stream *s = t->lists[id].head;
   if (s) {
@@ -666,6 +690,10 @@ static void unlock(transport *t) {
     }
   }
 
+  if (!t->writing) {
+    finalize_cancellations(t);
+  }
+
   /* gather any callbacks that need to be made */
   if (!t->calling_back && t->cb) {
     perform_callbacks = prepare_callbacks(t);
@@ -709,53 +737,9 @@ static void unlock(transport *t) {
   }
 
   /* write some bytes if necessary */
-  while (start_write) {
-    switch (grpc_endpoint_write(ep, t->outbuf.slices, t->outbuf.count,
-                                finish_write, t)) {
-      case GRPC_ENDPOINT_WRITE_DONE:
-        /* grab the lock directly without wrappers since we just want to
-           continue writes if we loop: no need to check read callbacks again */
-        gpr_mu_lock(&t->mu);
-        t->outbuf.count = 0;
-        t->outbuf.length = 0;
-        t->writing = start_write = prepare_write(t);
-        if (!start_write) {
-          if (!t->reading) {
-            grpc_endpoint_destroy(t->ep);
-            t->ep = NULL;
-            gpr_cv_broadcast(&t->cv);
-            /* endpoint ref: safe because we'll still have the ref for write */
-            unref_transport(t);
-          }
-        }
-        gpr_mu_unlock(&t->mu);
-        if (!start_write) {
-          unref_transport(t);
-        }
-        break;
-      case GRPC_ENDPOINT_WRITE_ERROR:
-        start_write = 0;
-        /* use the wrapper lock/unlock here as we drop_connection, causing
-           read callbacks to be queued (which will be cleared during unlock) */
-        lock(t);
-        t->outbuf.count = 0;
-        t->outbuf.length = 0;
-        t->writing = 0;
-        drop_connection(t);
-        if (!t->reading) {
-          grpc_endpoint_destroy(t->ep);
-          t->ep = NULL;
-          gpr_cv_broadcast(&t->cv);
-          /* endpoint ref: safe because we'll still have the ref for write */
-          unref_transport(t);
-        }
-        unlock(t);
-        unref_transport(t);
-        break;
-      case GRPC_ENDPOINT_WRITE_PENDING:
-        start_write = 0;
-        break;
-    }
+  if (start_write) {
+    /* ultimately calls unref_transport(t); and clears t->writing */
+    perform_write(t, ep);
   }
 
   if (perform_callbacks || call_closed || num_goaways) {
@@ -788,32 +772,10 @@ static void push_setting(transport *t, grpc_chttp2_setting_id id,
   }
 }
 
-static void finish_write(void *tp, grpc_endpoint_cb_status error) {
-  transport *t = tp;
-
-  lock(t);
-  if (error != GRPC_ENDPOINT_CB_OK) {
-    drop_connection(t);
-  }
-  t->outbuf.count = 0;
-  t->outbuf.length = 0;
-  /* leave the writing flag up on shutdown to prevent further writes in unlock()
-     from starting */
-  t->writing = 0;
-  if (!t->reading) {
-    grpc_endpoint_destroy(t->ep);
-    t->ep = NULL;
-    gpr_cv_broadcast(&t->cv);
-    unref_transport(t); /* safe because we'll still have the ref for write */
-  }
-  unlock(t);
-
-  unref_transport(t);
-}
-
 static int prepare_write(transport *t) {
   stream *s;
   gpr_slice_buffer tempbuf;
+  gpr_uint32 window_delta;
 
   /* simple writes are queued to qbuf, and flushed here */
   tempbuf = t->qbuf;
@@ -834,17 +796,16 @@ static int prepare_write(transport *t) {
   /* for each stream that's become writable, frame it's data (according to
      available window sizes) and add to the output buffer */
   while (t->outgoing_window && (s = stream_list_remove_head(t, WRITABLE))) {
-    gpr_uint32 written = grpc_chttp2_encode_some(
-        s->outgoing_sopb.ops, &s->outgoing_sopb.nops, s->write_closed,
-        &t->outbuf, GPR_MIN(t->outgoing_window, s->outgoing_window), s->id,
-        &t->hpack_compressor);
-    t->outgoing_window -= written;
-    s->outgoing_window -= written;
-
-    /* if there are no more writes to do and writes are closed, we need to
-       queue a callback to let the application know */
-    if (s->write_closed && s->outgoing_sopb.nops == 0) {
-      stream_list_join(t, s, PENDING_CALLBACKS);
+    window_delta = grpc_chttp2_preencode(
+        s->outgoing_sopb.ops, &s->outgoing_sopb.nops,
+        GPR_MIN(t->outgoing_window, s->outgoing_window), &s->writing_sopb);
+    t->outgoing_window -= window_delta;
+    s->outgoing_window -= window_delta;
+
+    s->sending_write_closed =
+        s->queued_write_closed && s->outgoing_sopb.nops == 0;
+    if (s->writing_sopb.nops > 0 || s->sending_write_closed) {
+      stream_list_join(t, s, WRITING);
     }
 
     /* if there are still writes to do and the stream still has window
@@ -857,25 +818,89 @@ static int prepare_write(transport *t) {
 
   /* for each stream that wants to update its window, add that window here */
   while ((s = stream_list_remove_head(t, WINDOW_UPDATE))) {
-    gpr_uint32 window_add =
+    window_delta =
         t->settings[LOCAL_SETTINGS][GRPC_CHTTP2_SETTINGS_INITIAL_WINDOW_SIZE] -
         s->incoming_window;
-    if (!s->read_closed && window_add) {
-      gpr_slice_buffer_add(&t->outbuf,
-                           grpc_chttp2_window_update_create(s->id, window_add));
-      s->incoming_window += window_add;
+    if (!s->read_closed && window_delta) {
+      gpr_slice_buffer_add(
+          &t->outbuf, grpc_chttp2_window_update_create(s->id, window_delta));
+      s->incoming_window += window_delta;
     }
   }
 
   /* if the transport is ready to send a window update, do so here also */
   if (t->incoming_window < t->connection_window_target * 3 / 4) {
-    gpr_uint32 window_add = t->connection_window_target - t->incoming_window;
+    window_delta = t->connection_window_target - t->incoming_window;
     gpr_slice_buffer_add(&t->outbuf,
-                         grpc_chttp2_window_update_create(0, window_add));
-    t->incoming_window += window_add;
+                         grpc_chttp2_window_update_create(0, window_delta));
+    t->incoming_window += window_delta;
   }
 
-  return t->outbuf.length > 0;
+  return t->outbuf.length > 0 || !stream_list_empty(t, WRITING);
+}
+
+static void finalize_outbuf(transport *t) {
+  stream *s;
+
+  while ((s = stream_list_remove_head(t, WRITING))) {
+    grpc_chttp2_encode(s->writing_sopb.ops, s->writing_sopb.nops,
+                       s->sending_write_closed, s->id, &t->hpack_compressor,
+                       &t->outbuf);
+    s->writing_sopb.nops = 0;
+    if (s->sending_write_closed) {
+      stream_list_join(t, s, WRITTEN_CLOSED);
+    }
+  }
+}
+
+static void finish_write_common(transport *t, int success) {
+  stream *s;
+
+  lock(t);
+  if (!success) {
+    drop_connection(t);
+  }
+  while ((s = stream_list_remove_head(t, WRITTEN_CLOSED))) {
+    s->sent_write_closed = 1;
+    stream_list_join(t, s, PENDING_CALLBACKS);
+  }
+  t->outbuf.count = 0;
+  t->outbuf.length = 0;
+  /* leave the writing flag up on shutdown to prevent further writes in unlock()
+     from starting */
+  t->writing = 0;
+  if (!t->reading) {
+    grpc_endpoint_destroy(t->ep);
+    t->ep = NULL;
+    gpr_cv_broadcast(&t->cv);
+    unref_transport(t); /* safe because we'll still have the ref for write */
+  }
+  unlock(t);
+
+  unref_transport(t);
+}
+
+static void finish_write(void *tp, grpc_endpoint_cb_status error) {
+  transport *t = tp;
+  finish_write_common(t, error == GRPC_ENDPOINT_CB_OK);
+}
+
+static void perform_write(transport *t, grpc_endpoint *ep) {
+  finalize_outbuf(t);
+
+  GPR_ASSERT(t->outbuf.count > 0);
+
+  switch (grpc_endpoint_write(ep, t->outbuf.slices, t->outbuf.count,
+                              finish_write, t)) {
+    case GRPC_ENDPOINT_WRITE_DONE:
+      finish_write_common(t, 1);
+      break;
+    case GRPC_ENDPOINT_WRITE_ERROR:
+      finish_write_common(t, 0);
+      break;
+    case GRPC_ENDPOINT_WRITE_PENDING:
+      break;
+  }
 }
 
 static void maybe_start_some_streams(transport *t) {
@@ -901,19 +926,14 @@ static void send_batch(grpc_transport *gt, grpc_stream *gs, grpc_stream_op *ops,
   lock(t);
 
   if (is_last) {
-    s->write_closed = 1;
+    s->queued_write_closed = 1;
   }
   if (!s->cancelled) {
     grpc_sopb_append(&s->outgoing_sopb, ops, ops_count);
-    if (is_last && s->outgoing_sopb.nops == 0) {
-      if (s->id != 0) {
-        gpr_slice_buffer_add(&t->qbuf,
-                             grpc_chttp2_data_frame_create_empty_close(s->id));
-      }
-    } else if (s->id == 0) {
+    if (s->id == 0) {
       stream_list_join(t, s, WAITING_FOR_CONCURRENCY);
       maybe_start_some_streams(t);
-    } else if (s->outgoing_window) {
+    } else {
       stream_list_join(t, s, WRITABLE);
     }
   } else {
@@ -967,12 +987,22 @@ static void send_ping(grpc_transport *gt, void (*cb)(void *user_data),
  * INPUT PROCESSING
  */
 
+static void finalize_cancellations(transport *t) {
+  stream *s;
+
+  while ((s = stream_list_remove_head(t, CANCELLED))) {
+    s->read_closed = 1;
+    s->sent_write_closed = 1;
+    stream_list_join(t, s, PENDING_CALLBACKS);
+  }
+}
+
 static void cancel_stream_inner(transport *t, stream *s, gpr_uint32 id,
                                 grpc_status_code local_status,
                                 grpc_chttp2_error_code error_code,
                                 int send_rst) {
-  char buffer[32];
   int had_outgoing;
+  char buffer[32];
 
   if (s) {
     /* clear out any unreported input & output: nobody cares anymore */
@@ -981,10 +1011,9 @@ static void cancel_stream_inner(transport *t, stream *s, gpr_uint32 id,
     grpc_sopb_reset(&s->outgoing_sopb);
     if (s->cancelled) {
       send_rst = 0;
-    } else if (!s->read_closed || !s->write_closed || had_outgoing) {
+    } else if (!s->read_closed || !s->sent_write_closed || had_outgoing) {
       s->cancelled = 1;
-      s->read_closed = 1;
-      s->write_closed = 1;
+      stream_list_join(t, s, CANCELLED);
 
       sprintf(buffer, "%d", local_status);
       grpc_sopb_add_metadata(
@@ -1667,8 +1696,7 @@ static int prepare_callbacks(transport *t) {
     s->parser.incoming_sopb = s->callback_sopb;
     s->callback_sopb = temp_sopb;
 
-    s->callback_state = compute_state(
-        s->write_closed && s->outgoing_sopb.nops == 0, s->read_closed);
+    s->callback_state = compute_state(s->sent_write_closed, s->read_closed);
     if (s->callback_state == GRPC_STREAM_CLOSED) {
       remove_from_stream_map(t, s);
       if (s->published_close) {
diff --git a/src/cpp/client/channel.cc b/src/cpp/client/channel.cc
index 7d95518631f25c31fdbe84c05bc1c7128dc84716..bcda4ed40ccbc845e5c9136594226dd9fd03756b 100644
--- a/src/cpp/client/channel.cc
+++ b/src/cpp/client/channel.cc
@@ -41,13 +41,13 @@
 #include <grpc/support/log.h>
 #include <grpc/support/slice.h>
 
-#include "src/cpp/rpc_method.h"
 #include "src/cpp/proto/proto_utils.h"
 #include "src/cpp/stream/stream_context.h"
 #include <grpc++/channel_arguments.h>
 #include <grpc++/client_context.h>
 #include <grpc++/config.h>
 #include <grpc++/credentials.h>
+#include <grpc++/impl/rpc_method.h>
 #include <grpc++/status.h>
 #include <google/protobuf/message.h>
 
@@ -69,8 +69,9 @@ Channel::Channel(const grpc::string& target,
                   : args.GetSslTargetNameOverride()) {
   grpc_channel_args channel_args;
   args.SetChannelArgs(&channel_args);
+  grpc_credentials* c_creds = creds ? creds->GetRawCreds() : nullptr;
   c_channel_ = grpc_secure_channel_create(
-      creds->GetRawCreds(), target.c_str(),
+      c_creds, target.c_str(),
       channel_args.num_args > 0 ? &channel_args : nullptr);
 }
 
@@ -118,10 +119,15 @@ Status Channel::StartBlockingRpc(const RpcMethod& method,
                                     finished_tag,
                                     GRPC_WRITE_BUFFER_HINT) == GRPC_CALL_OK);
   ev = grpc_completion_queue_pluck(cq, invoke_tag, gpr_inf_future);
+  bool success = ev->data.invoke_accepted == GRPC_OP_OK;
   grpc_event_finish(ev);
+  if (!success) {
+    GetFinalStatus(cq, finished_tag, &status);
+    return status;
+  }
   // write request
   grpc_byte_buffer* write_buffer = nullptr;
-  bool success = SerializeProto(request, &write_buffer);
+  success = SerializeProto(request, &write_buffer);
   if (!success) {
     grpc_call_cancel(call);
     status =
diff --git a/src/cpp/client/credentials.cc b/src/cpp/client/credentials.cc
index 986008f7bb9fb4233f2920aa6d7d35f82f5784cf..cac1d3d106ca5ca2f2585c4a6b2530c1bd157805 100644
--- a/src/cpp/client/credentials.cc
+++ b/src/cpp/client/credentials.cc
@@ -35,6 +35,7 @@
 #include <string>
 
 #include <grpc/grpc_security.h>
+#include <grpc/support/log.h>
 
 #include <grpc++/credentials.h>
 
@@ -58,6 +59,9 @@ std::unique_ptr<Credentials> CredentialsFactory::SslCredentials(
       options.pem_root_certs.empty() ? nullptr
                                      : reinterpret_cast<const unsigned char*>(
                                            options.pem_root_certs.c_str());
+  if (pem_root_certs == nullptr) {
+    return std::unique_ptr<Credentials>();
+  }
   const unsigned char* pem_private_key =
       options.pem_private_key.empty() ? nullptr
                                       : reinterpret_cast<const unsigned char*>(
@@ -71,14 +75,40 @@ std::unique_ptr<Credentials> CredentialsFactory::SslCredentials(
       pem_root_certs, options.pem_root_certs.size(), pem_private_key,
       options.pem_private_key.size(), pem_cert_chain,
       options.pem_cert_chain.size());
-  std::unique_ptr<Credentials> cpp_creds(new Credentials(c_creds));
+  std::unique_ptr<Credentials> cpp_creds(
+      c_creds == nullptr ? nullptr : new Credentials(c_creds));
   return cpp_creds;
 }
 
 // Builds credentials for use when running in GCE
 std::unique_ptr<Credentials> CredentialsFactory::ComputeEngineCredentials() {
   grpc_credentials* c_creds = grpc_compute_engine_credentials_create();
-  std::unique_ptr<Credentials> cpp_creds(new Credentials(c_creds));
+  std::unique_ptr<Credentials> cpp_creds(
+      c_creds == nullptr ? nullptr : new Credentials(c_creds));
+  return cpp_creds;
+}
+
+// Builds service account credentials.
+std::unique_ptr<Credentials> CredentialsFactory::ServiceAccountCredentials(
+    const grpc::string& json_key, const grpc::string& scope,
+    std::chrono::seconds token_lifetime) {
+  gpr_timespec lifetime = gpr_time_from_seconds(
+      token_lifetime.count() > 0 ? token_lifetime.count() : 0);
+  grpc_credentials* c_creds = grpc_service_account_credentials_create(
+      json_key.c_str(), scope.c_str(), lifetime);
+  std::unique_ptr<Credentials> cpp_creds(
+      c_creds == nullptr ? nullptr : new Credentials(c_creds));
+  return cpp_creds;
+}
+
+// Builds IAM credentials.
+std::unique_ptr<Credentials> CredentialsFactory::IAMCredentials(
+    const grpc::string& authorization_token,
+    const grpc::string& authority_selector) {
+  grpc_credentials* c_creds = grpc_iam_credentials_create(
+      authorization_token.c_str(), authority_selector.c_str());
+  std::unique_ptr<Credentials> cpp_creds(
+      c_creds == nullptr ? nullptr : new Credentials(c_creds));
   return cpp_creds;
 }
 
@@ -93,7 +123,8 @@ std::unique_ptr<Credentials> CredentialsFactory::ComposeCredentials(
   // refcounts incremented.
   grpc_credentials* c_creds = grpc_composite_credentials_create(
       creds1->GetRawCreds(), creds2->GetRawCreds());
-  std::unique_ptr<Credentials> cpp_creds(new Credentials(c_creds));
+  std::unique_ptr<Credentials> cpp_creds(
+      c_creds == nullptr ? nullptr : new Credentials(c_creds));
   return cpp_creds;
 }
 
diff --git a/src/cpp/client/internal_stub.cc b/src/cpp/client/internal_stub.cc
index ec88ba5e7ed7ff16c65c79c4ba14af3c1ee16f99..51cb99d1b49c016254767f8bcae858d3ea0195c3 100644
--- a/src/cpp/client/internal_stub.cc
+++ b/src/cpp/client/internal_stub.cc
@@ -31,6 +31,6 @@
  *
  */
 
-#include "src/cpp/client/internal_stub.h"
+#include <grpc++/impl/internal_stub.h>
 
 namespace grpc {}  // namespace grpc
diff --git a/src/cpp/rpc_method.cc b/src/cpp/common/rpc_method.cc
similarity index 97%
rename from src/cpp/rpc_method.cc
rename to src/cpp/common/rpc_method.cc
index 8067f42f85e819c5a49894c67a777d5cd4b71769..c8b2ccb10e26214af7fb41d8241a3eede316e54b 100644
--- a/src/cpp/rpc_method.cc
+++ b/src/cpp/common/rpc_method.cc
@@ -31,6 +31,6 @@
  *
  */
 
-#include "src/cpp/rpc_method.h"
+#include <grpc++/impl/rpc_method.h>
 
 namespace grpc {}  // namespace grpc
diff --git a/src/cpp/server/server.cc b/src/cpp/server/server.cc
index 2130befa7d5344e4ddfeefc7a7cf6568dcc1b0db..d85748eea44b251300151e5e6f1d704ee34d07f2 100644
--- a/src/cpp/server/server.cc
+++ b/src/cpp/server/server.cc
@@ -37,11 +37,11 @@
 #include <grpc/grpc.h>
 #include <grpc/grpc_security.h>
 #include <grpc/support/log.h>
-#include "src/cpp/server/rpc_service_method.h"
 #include "src/cpp/server/server_rpc_handler.h"
 #include "src/cpp/server/thread_pool.h"
 #include <grpc++/async_server_context.h>
 #include <grpc++/completion_queue.h>
+#include <grpc++/impl/rpc_service_method.h>
 #include <grpc++/server_credentials.h>
 
 namespace grpc {
diff --git a/src/cpp/server/server_rpc_handler.cc b/src/cpp/server/server_rpc_handler.cc
index 3954f04f978ebcc9a44020d5e9fa423679d06302..b7b29c24066dbf019399bf33c49d7862f118284b 100644
--- a/src/cpp/server/server_rpc_handler.cc
+++ b/src/cpp/server/server_rpc_handler.cc
@@ -34,10 +34,10 @@
 #include "src/cpp/server/server_rpc_handler.h"
 
 #include <grpc/support/log.h>
-#include "src/cpp/server/rpc_service_method.h"
 #include "src/cpp/server/server_context_impl.h"
 #include "src/cpp/stream/stream_context.h"
 #include <grpc++/async_server_context.h>
+#include <grpc++/impl/rpc_service_method.h>
 
 namespace grpc {
 
diff --git a/src/cpp/stream/stream_context.cc b/src/cpp/stream/stream_context.cc
index 22b7e7d494b2ae89c3a62612bf18644d814e4ea0..6c424b937edefb407a4597a4f03b4d73dcac705d 100644
--- a/src/cpp/stream/stream_context.cc
+++ b/src/cpp/stream/stream_context.cc
@@ -34,11 +34,11 @@
 #include "src/cpp/stream/stream_context.h"
 
 #include <grpc/support/log.h>
-#include "src/cpp/rpc_method.h"
 #include "src/cpp/proto/proto_utils.h"
 #include "src/cpp/util/time.h"
 #include <grpc++/client_context.h>
 #include <grpc++/config.h>
+#include <grpc++/impl/rpc_method.h>
 #include <google/protobuf/message.h>
 
 namespace grpc {
@@ -85,6 +85,10 @@ void StreamContext::Start(bool buffered) {
     GPR_ASSERT(GRPC_CALL_OK == error);
     grpc_event* invoke_ev =
         grpc_completion_queue_pluck(cq(), invoke_tag(), gpr_inf_future);
+    if (invoke_ev->data.invoke_accepted != GRPC_OP_OK) {
+      peer_halfclosed_ = true;
+      self_halfclosed_ = true;
+    }
     grpc_event_finish(invoke_ev);
   } else {
     // TODO(yangg) metadata needs to be added before accept
diff --git a/test/core/end2end/gen_build_json.py b/test/core/end2end/gen_build_json.py
index 6495d6e17e821824e584c7023e228a31c1b451c1..50ae21ce692fc6c9bf1388f52ee15e2e5fade207 100755
--- a/test/core/end2end/gen_build_json.py
+++ b/test/core/end2end/gen_build_json.py
@@ -21,6 +21,7 @@ END2END_TESTS = [
     'cancel_after_invoke',
     'cancel_before_invoke',
     'cancel_in_a_vacuum',
+    'census_simple_request',
     'disappearing_server',
     'early_server_shutdown_finishes_inflight_calls',
     'early_server_shutdown_finishes_tags',
diff --git a/test/core/end2end/tests/census_simple_request.c b/test/core/end2end/tests/census_simple_request.c
new file mode 100644
index 0000000000000000000000000000000000000000..64c0d12ca4a112ec382085f29d128c505b869e3d
--- /dev/null
+++ b/test/core/end2end/tests/census_simple_request.c
@@ -0,0 +1,176 @@
+/*
+ *
+ * Copyright 2014, 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 <unistd.h>
+
+#include <grpc/byte_buffer.h>
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/time.h>
+#include <grpc/support/useful.h>
+#include "test/core/end2end/cq_verifier.h"
+
+static gpr_timespec n_seconds_time(int n) {
+  return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n));
+}
+
+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 void shutdown_server(grpc_end2end_test_fixture *f) {
+  if (!f->server) return;
+  grpc_server_shutdown(f->server);
+  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 drain_cq(grpc_completion_queue *cq) {
+  grpc_event *ev;
+  grpc_completion_type type;
+  do {
+    ev = grpc_completion_queue_next(cq, n_seconds_time(5));
+    GPR_ASSERT(ev);
+    type = ev->type;
+    grpc_event_finish(ev);
+  } while (type != GRPC_QUEUE_SHUTDOWN);
+}
+
+static void end_test(grpc_end2end_test_fixture *f) {
+  shutdown_server(f);
+  shutdown_client(f);
+
+  grpc_completion_queue_shutdown(f->server_cq);
+  drain_cq(f->server_cq);
+  grpc_completion_queue_destroy(f->server_cq);
+  grpc_completion_queue_shutdown(f->client_cq);
+  drain_cq(f->client_cq);
+  grpc_completion_queue_destroy(f->client_cq);
+}
+
+static void *tag(gpr_intptr t) { return (void *)t; }
+
+static void test_body(grpc_end2end_test_fixture f) {
+  grpc_call *c;
+  grpc_call *s;
+  gpr_timespec deadline = n_seconds_time(10);
+  cq_verifier *v_client = cq_verifier_create(f.client_cq);
+  cq_verifier *v_server = cq_verifier_create(f.server_cq);
+
+  c = grpc_channel_create_call(f.client, "/foo", "test.google.com", deadline);
+  GPR_ASSERT(c);
+  tag(1);
+  GPR_ASSERT(GRPC_CALL_OK ==
+             grpc_call_start_invoke(c, f.client_cq, tag(1), tag(2), tag(3), 0));
+  cq_expect_invoke_accepted(v_client, tag(1), GRPC_OP_OK);
+  cq_verify(v_client);
+
+  GPR_ASSERT(GRPC_CALL_OK == grpc_call_writes_done(c, tag(4)));
+  cq_expect_finish_accepted(v_client, tag(4), GRPC_OP_OK);
+  cq_verify(v_client);
+
+  GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call(f.server, tag(100)));
+  cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "test.google.com",
+                           deadline, NULL);
+  cq_verify(v_server);
+
+  GPR_ASSERT(GRPC_CALL_OK == grpc_call_accept(s, f.server_cq, tag(102), 0));
+  cq_expect_client_metadata_read(v_client, tag(2), NULL);
+  cq_verify(v_client);
+
+  GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_write_status(
+                                 s, GRPC_STATUS_UNIMPLEMENTED, "xyz", tag(5)));
+  cq_expect_finished_with_status(v_client, tag(3), GRPC_STATUS_UNIMPLEMENTED,
+                                 "xyz", NULL);
+  cq_verify(v_client);
+
+  cq_expect_finish_accepted(v_server, tag(5), GRPC_OP_OK);
+  cq_verify(v_server);
+  cq_expect_finished(v_server, tag(102), NULL);
+  cq_verify(v_server);
+  grpc_call_destroy(c);
+  grpc_call_destroy(s);
+
+  cq_verifier_destroy(v_client);
+  cq_verifier_destroy(v_server);
+}
+
+static void test_invoke_request_with_census(
+    grpc_end2end_test_config config, const char *name,
+    void (*body)(grpc_end2end_test_fixture f)) {
+  char fullname[64];
+  grpc_end2end_test_fixture f;
+  grpc_arg client_arg, server_arg;
+  grpc_channel_args client_args, server_args;
+
+  client_arg.type = GRPC_ARG_INTEGER;
+  client_arg.key = GRPC_ARG_ENABLE_CENSUS;
+  client_arg.value.integer = 1;
+
+  client_args.num_args = 1;
+  client_args.args = &client_arg;
+
+  server_arg.type = GRPC_ARG_INTEGER;
+  server_arg.key = GRPC_ARG_ENABLE_CENSUS;
+  server_arg.value.integer = 1;
+  server_args.num_args = 1;
+  server_args.args = &server_arg;
+
+  sprintf(fullname, "%s/%s", __FUNCTION__, name);
+  f = begin_test(config, fullname, &client_args, &server_args);
+  body(f);
+  end_test(&f);
+  config.tear_down_data(&f);
+}
+
+void grpc_end2end_tests(grpc_end2end_test_config config) {
+  test_invoke_request_with_census(config, "census_simple_request", test_body);
+}
diff --git a/test/core/statistics/census_stub_test.c b/test/core/statistics/census_stub_test.c
index 7d85550f701e0b8cad8210276c6107719ba97288..a86676fbb1b0b6a0ce44a8b2284815e3f4e130f6 100644
--- a/test/core/statistics/census_stub_test.c
+++ b/test/core/statistics/census_stub_test.c
@@ -44,7 +44,8 @@
 void test_census_stubs() {
   census_op_id op_id;
   census_rpc_stats* stats = census_rpc_stats_create_empty();
-  census_aggregated_rpc_stats data_map;
+  census_aggregated_rpc_stats data_map = {0, NULL};
+
   /* Initializes census library at server start up time. */
   census_init();
   /* Starts tracing at the beginning of a rpc. */
@@ -62,8 +63,9 @@ void test_census_stubs() {
   census_tracing_end_op(op_id);
   /* In process stats queries. */
   census_get_server_stats(&data_map);
+  census_aggregated_rpc_stats_set_empty(&data_map);
   census_get_client_stats(&data_map);
-  census_aggregated_rpc_stats_destroy(&data_map);
+  census_aggregated_rpc_stats_set_empty(&data_map);
   gpr_free(stats);
   census_shutdown();
 }
diff --git a/test/core/statistics/hash_table_test.c b/test/core/statistics/hash_table_test.c
index fb75de520e8096a15bfcc103bd12024aa986701e..8c7682419352b33914be142e06760c5552facbad 100644
--- a/test/core/statistics/hash_table_test.c
+++ b/test/core/statistics/hash_table_test.c
@@ -123,7 +123,8 @@ static void test_value_and_key_deleter() {
                           &free_data, &free_data};
   census_ht* ht = census_ht_create(&opt);
   census_ht_key key;
-  char* val;
+  char* val = NULL;
+  char* val2 = NULL;
   key.ptr = gpr_malloc(100);
   val = gpr_malloc(10);
   strcpy(val, "value");
@@ -132,6 +133,17 @@ static void test_value_and_key_deleter() {
   GPR_ASSERT(census_ht_get_size(ht) == 0);
   census_ht_insert(ht, key, val);
   GPR_ASSERT(census_ht_get_size(ht) == 1);
+  val = census_ht_find(ht, key);
+  GPR_ASSERT(val != NULL);
+  GPR_ASSERT(strcmp(val, "value") == 0);
+  /* Insert same key different value, old value is overwritten. */
+  val2 = gpr_malloc(10);
+  strcpy(val2, "v2");
+  census_ht_insert(ht, key, val2);
+  GPR_ASSERT(census_ht_get_size(ht) == 1);
+  val2 = census_ht_find(ht, key);
+  GPR_ASSERT(val2 != NULL);
+  GPR_ASSERT(strcmp(val2, "v2") == 0);
   census_ht_destroy(ht);
 }
 
diff --git a/test/core/statistics/rpc_stats_test.c b/test/core/statistics/rpc_stats_test.c
new file mode 100644
index 0000000000000000000000000000000000000000..c1014034500cf8b03f9422a4346c17d3b94a65ff
--- /dev/null
+++ b/test/core/statistics/rpc_stats_test.c
@@ -0,0 +1,197 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <string.h>
+
+#include "src/core/statistics/census_interface.h"
+#include "src/core/statistics/census_rpc_stats.h"
+#include "src/core/statistics/census_tracing.h"
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/port_platform.h>
+#include <grpc/support/string.h>
+#include <grpc/support/thd.h>
+#include <grpc/support/time.h>
+#include "test/core/util/test_config.h"
+
+/* Ensure all possible state transitions are called without causing problem */
+static void test_init_shutdown() {
+  census_stats_store_init();
+  census_stats_store_init();
+  census_stats_store_shutdown();
+  census_stats_store_shutdown();
+  census_stats_store_init();
+}
+
+static void test_create_and_destroy() {
+  census_rpc_stats* stats = NULL;
+  census_aggregated_rpc_stats agg_stats = {0, NULL};
+
+  stats = census_rpc_stats_create_empty();
+  GPR_ASSERT(stats != NULL);
+  GPR_ASSERT(stats->cnt == 0 && stats->rpc_error_cnt == 0 &&
+             stats->app_error_cnt == 0 && stats->elapsed_time_ms == 0.0 &&
+             stats->api_request_bytes == 0 && stats->wire_request_bytes == 0 &&
+             stats->api_response_bytes == 0 && stats->wire_response_bytes == 0);
+  gpr_free(stats);
+
+  census_aggregated_rpc_stats_set_empty(&agg_stats);
+  GPR_ASSERT(agg_stats.num_entries == 0);
+  GPR_ASSERT(agg_stats.stats == NULL);
+  agg_stats.num_entries = 1;
+  agg_stats.stats = (census_per_method_rpc_stats*)gpr_malloc(
+      sizeof(census_per_method_rpc_stats));
+  agg_stats.stats[0].method = gpr_strdup("foo");
+  census_aggregated_rpc_stats_set_empty(&agg_stats);
+  GPR_ASSERT(agg_stats.num_entries == 0);
+  GPR_ASSERT(agg_stats.stats == NULL);
+}
+
+#define ASSERT_NEAR(a, b) \
+  GPR_ASSERT((a - b) * (a - b) < 1e-24 * (a + b) * (a + b))
+
+static void test_record_and_get_stats() {
+  census_rpc_stats stats = {1, 2, 3, 4, 5.1, 6.2, 7.3, 8.4};
+  census_op_id id;
+  census_aggregated_rpc_stats agg_stats = {0, NULL};
+
+  /* Record client stats twice with the same op_id. */
+  census_init();
+  id = census_tracing_start_op();
+  census_add_method_tag(id, "m1");
+  census_record_rpc_client_stats(id, &stats);
+  census_record_rpc_client_stats(id, &stats);
+  census_tracing_end_op(id);
+  /* Server stats expect to be empty */
+  census_get_server_stats(&agg_stats);
+  GPR_ASSERT(agg_stats.num_entries == 0);
+  GPR_ASSERT(agg_stats.stats == NULL);
+  /* Client stats expect to have one entry */
+  census_get_client_stats(&agg_stats);
+  GPR_ASSERT(agg_stats.num_entries == 1);
+  GPR_ASSERT(agg_stats.stats != NULL);
+  GPR_ASSERT(strcmp(agg_stats.stats[0].method, "m1") == 0);
+  GPR_ASSERT(agg_stats.stats[0].minute_stats.cnt == 2 &&
+             agg_stats.stats[0].hour_stats.cnt == 2 &&
+             agg_stats.stats[0].total_stats.cnt == 2);
+  ASSERT_NEAR(agg_stats.stats[0].minute_stats.wire_response_bytes, 16.8);
+  ASSERT_NEAR(agg_stats.stats[0].hour_stats.wire_response_bytes, 16.8);
+  ASSERT_NEAR(agg_stats.stats[0].total_stats.wire_response_bytes, 16.8);
+  /* Get stats again, results should be the same. */
+  census_get_client_stats(&agg_stats);
+  GPR_ASSERT(agg_stats.num_entries == 1);
+  census_aggregated_rpc_stats_set_empty(&agg_stats);
+  census_shutdown();
+
+  /* Record both server (once) and client (twice) stats with different op_ids.*/
+  census_init();
+  id = census_tracing_start_op();
+  census_add_method_tag(id, "m2");
+  census_record_rpc_client_stats(id, &stats);
+  census_tracing_end_op(id);
+  id = census_tracing_start_op();
+  census_add_method_tag(id, "m3");
+  census_record_rpc_server_stats(id, &stats);
+  census_tracing_end_op(id);
+  id = census_tracing_start_op();
+  census_add_method_tag(id, "m4");
+  census_record_rpc_client_stats(id, &stats);
+  census_tracing_end_op(id);
+  /* Check server stats */
+  census_get_server_stats(&agg_stats);
+  GPR_ASSERT(agg_stats.num_entries == 1);
+  GPR_ASSERT(strcmp(agg_stats.stats[0].method, "m3") == 0);
+  GPR_ASSERT(agg_stats.stats[0].minute_stats.app_error_cnt == 3 &&
+             agg_stats.stats[0].hour_stats.app_error_cnt == 3 &&
+             agg_stats.stats[0].total_stats.app_error_cnt == 3);
+  census_aggregated_rpc_stats_set_empty(&agg_stats);
+  /* Check client stats */
+  census_get_client_stats(&agg_stats);
+  GPR_ASSERT(agg_stats.num_entries == 2);
+  GPR_ASSERT(agg_stats.stats != NULL);
+  GPR_ASSERT((strcmp(agg_stats.stats[0].method, "m2") == 0 &&
+              strcmp(agg_stats.stats[1].method, "m4") == 0) ||
+             (strcmp(agg_stats.stats[0].method, "m4") == 0 &&
+              strcmp(agg_stats.stats[1].method, "m2") == 0));
+  GPR_ASSERT(agg_stats.stats[0].minute_stats.cnt == 1 &&
+             agg_stats.stats[1].minute_stats.cnt == 1);
+  census_aggregated_rpc_stats_set_empty(&agg_stats);
+  census_shutdown();
+}
+
+static void test_record_stats_on_unknown_op_id() {
+  census_op_id unknown_id = {0xDEAD, 0xBEEF};
+  census_rpc_stats stats = {1, 2, 3, 4, 5.1, 6.2, 7.3, 8.4};
+  census_aggregated_rpc_stats agg_stats = {0, NULL};
+
+  census_init();
+  /* Tests that recording stats against unknown id is noop. */
+  census_record_rpc_client_stats(unknown_id, &stats);
+  census_record_rpc_server_stats(unknown_id, &stats);
+  census_get_server_stats(&agg_stats);
+  GPR_ASSERT(agg_stats.num_entries == 0);
+  GPR_ASSERT(agg_stats.stats == NULL);
+  census_get_client_stats(&agg_stats);
+  GPR_ASSERT(agg_stats.num_entries == 0);
+  GPR_ASSERT(agg_stats.stats == NULL);
+  census_aggregated_rpc_stats_set_empty(&agg_stats);
+  census_shutdown();
+}
+
+/* Test that record stats is noop when trace store is uninitialized. */
+static void test_record_stats_with_trace_store_uninitialized() {
+  census_rpc_stats stats = {1, 2, 3, 4, 5.1, 6.2, 7.3, 8.4};
+  census_op_id id = {0, 0};
+  census_aggregated_rpc_stats agg_stats = {0, NULL};
+
+  census_init();
+  id = census_tracing_start_op();
+  census_add_method_tag(id, "m");
+  census_tracing_end_op(id);
+  /* shuts down trace store only. */
+  census_tracing_shutdown();
+  census_record_rpc_client_stats(id, &stats);
+  census_get_client_stats(&agg_stats);
+  GPR_ASSERT(agg_stats.num_entries == 0);
+  census_stats_store_shutdown();
+}
+
+int main(int argc, char** argv) {
+  grpc_test_init(argc, argv);
+  test_init_shutdown();
+  test_create_and_destroy();
+  test_record_and_get_stats();
+  test_record_stats_on_unknown_op_id();
+  test_record_stats_with_trace_store_uninitialized();
+  return 0;
+}
diff --git a/test/core/statistics/trace_test.c b/test/core/statistics/trace_test.c
new file mode 100644
index 0000000000000000000000000000000000000000..9a6c54b90fee5febbeb00aefcea5f5b5541a9514
--- /dev/null
+++ b/test/core/statistics/trace_test.c
@@ -0,0 +1,184 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <string.h>
+
+#include "src/core/statistics/census_interface.h"
+#include "src/core/statistics/census_tracing.h"
+#include "src/core/statistics/census_tracing.h"
+#include <grpc/support/log.h>
+#include <grpc/support/port_platform.h>
+#include <grpc/support/sync.h>
+#include <grpc/support/thd.h>
+#include <grpc/support/time.h>
+#include <grpc/support/useful.h>
+#include "test/core/util/test_config.h"
+
+/* Ensure all possible state transitions are called without causing problem */
+static void test_init_shutdown() {
+  census_tracing_init();
+  census_tracing_init();
+  census_tracing_shutdown();
+  census_tracing_shutdown();
+  census_tracing_init();
+}
+
+static void test_start_op_generates_locally_unique_ids() {
+/* Check that ids generated within window size of 1000 are unique.
+   TODO(hongyu): Replace O(n^2) duplicate detection algorithm with O(nlogn)
+   algorithm. Enhance the test to larger window size (>10^6) */
+#define WINDOW_SIZE 1000
+  census_op_id ids[WINDOW_SIZE];
+  int i;
+  census_init();
+  for (i = 0; i < WINDOW_SIZE; i++) {
+    ids[i] = census_tracing_start_op();
+    census_tracing_end_op(ids[i]);
+  }
+  for (i = 0; i < WINDOW_SIZE - 1; i++) {
+    int j;
+    for (j = i + 1; j < WINDOW_SIZE; j++) {
+      GPR_ASSERT(ids[i].upper != ids[j].upper || ids[i].lower != ids[j].lower);
+    }
+  }
+#undef WINDOW_SIZE
+  census_shutdown();
+}
+
+static void test_get_trace_method_name() {
+  census_op_id id;
+  const char write_name[] = "service/method";
+  census_tracing_init();
+  id = census_tracing_start_op();
+  census_add_method_tag(id, write_name);
+  census_internal_lock_trace_store();
+  {
+    const char* read_name =
+        census_get_trace_method_name(census_get_trace_obj_locked(id));
+    GPR_ASSERT(strcmp(read_name, write_name) == 0);
+  }
+  census_internal_unlock_trace_store();
+  census_tracing_shutdown();
+}
+
+typedef struct thd_arg {
+  int num_done;
+  gpr_cv done;
+  gpr_mu mu;
+} thd_arg;
+
+static void mimic_trace_op_sequences(void* arg) {
+  census_op_id id;
+  const char* method_name = "service_foo/method_bar";
+  int i = 0;
+  const int num_iter = 200;
+  thd_arg* args = (thd_arg*)arg;
+  GPR_ASSERT(args != NULL);
+  gpr_log(GPR_INFO, "Start trace op sequence thread.");
+  for (i = 0; i < num_iter; i++) {
+    id = census_tracing_start_op();
+    census_add_method_tag(id, method_name);
+    /* pretend doing 1us work. */
+    gpr_sleep_until(gpr_time_add(gpr_now(), gpr_time_from_micros(1)));
+    census_tracing_end_op(id);
+  }
+  gpr_log(GPR_INFO, "End trace op sequence thread.");
+  gpr_mu_lock(&args->mu);
+  args->num_done += 1;
+  gpr_cv_broadcast(&args->done);
+  gpr_mu_unlock(&args->mu);
+}
+
+static void test_concurrency() {
+#define NUM_THREADS 1000
+  gpr_thd_id tid[NUM_THREADS];
+  int i = 0;
+  thd_arg arg;
+  arg.num_done = 0;
+  gpr_mu_init(&arg.mu);
+  gpr_cv_init(&arg.done);
+  census_tracing_init();
+  for (i = 0; i < NUM_THREADS; ++i) {
+    gpr_thd_new(tid + i, mimic_trace_op_sequences, &arg, NULL);
+  }
+  gpr_mu_lock(&arg.mu);
+  while (arg.num_done < NUM_THREADS) {
+    gpr_log(GPR_INFO, "num done %d", arg.num_done);
+    gpr_cv_wait(&arg.done, &arg.mu, gpr_inf_future);
+  }
+  gpr_mu_unlock(&arg.mu);
+  census_tracing_shutdown();
+#undef NUM_THREADS
+}
+
+static void test_add_method_tag_to_unknown_op_id() {
+  census_op_id unknown_id = {0xDEAD, 0xBEEF};
+  int ret = 0;
+  census_tracing_init();
+  ret = census_add_method_tag(unknown_id, "foo");
+  GPR_ASSERT(ret != 0);
+  census_tracing_shutdown();
+}
+
+static void test_trace_print() {
+  census_op_id id;
+  int i;
+  const char* annotation_txt[4] = {"abc", "", "$%^ *()_"};
+  char long_txt[CENSUS_MAX_ANNOTATION_LENGTH + 10];
+
+  memset(long_txt, 'a', GPR_ARRAY_SIZE(long_txt));
+  long_txt[CENSUS_MAX_ANNOTATION_LENGTH + 9] = '\0';
+  annotation_txt[3] = long_txt;
+
+  census_tracing_init();
+  id = census_tracing_start_op();
+  /* Adds large number of annotations to each trace */
+  for (i = 0; i < 1000; i++) {
+    census_tracing_print(id,
+                         annotation_txt[i % GPR_ARRAY_SIZE(annotation_txt)]);
+  }
+  census_tracing_end_op(id);
+
+  census_tracing_shutdown();
+}
+
+int main(int argc, char** argv) {
+  grpc_test_init(argc, argv);
+  test_init_shutdown();
+  test_start_op_generates_locally_unique_ids();
+  test_get_trace_method_name();
+  test_concurrency();
+  test_add_method_tag_to_unknown_op_id();
+  test_trace_print();
+  return 0;
+}
diff --git a/test/core/support/log_test.c b/test/core/support/log_test.c
index fbb7c21ffc3b591fef962a30d418f7a191ccf226..3ee40b6d76d467c8e0bb416b19fec6fd295af7b7 100644
--- a/test/core/support/log_test.c
+++ b/test/core/support/log_test.c
@@ -32,8 +32,17 @@
  */
 
 #include <grpc/support/log.h>
+
+#include <string.h>
+
 #include "test/core/util/test_config.h"
 
+static void test_callback(gpr_log_func_args *args) {
+  GPR_ASSERT(0 == strcmp(__FILE__, args->file));
+  GPR_ASSERT(args->severity == GPR_LOG_SEVERITY_INFO);
+  GPR_ASSERT(0 == strcmp(args->message, "hello 1 2 3"));
+}
+
 int main(int argc, char **argv) {
   grpc_test_init(argc, argv);
   /* test logging at various verbosity levels */
@@ -42,6 +51,9 @@ int main(int argc, char **argv) {
   gpr_log(GPR_ERROR, "%s", "hello world");
   /* should succeed */
   GPR_ASSERT(1);
+  gpr_set_log_function(test_callback);
+  gpr_log_message(GPR_INFO, "hello 1 2 3");
+  gpr_log(GPR_INFO, "hello %d %d %d", 1, 2, 3);
   /* TODO(ctiller): should we add a GPR_ASSERT failure test here */
   return 0;
 }
diff --git a/test/core/transport/chttp2/stream_encoder_test.c b/test/core/transport/chttp2/stream_encoder_test.c
index 3ee11d94e8582849ab7f45f534d61094d131e26c..ba552786db05a943478c8d3241561911d586b26e 100644
--- a/test/core/transport/chttp2/stream_encoder_test.c
+++ b/test/core/transport/chttp2/stream_encoder_test.c
@@ -64,15 +64,20 @@ static gpr_slice create_test_slice(size_t length) {
 static void verify_sopb(size_t window_available, int eof,
                         size_t expect_window_used, const char *expected) {
   gpr_slice_buffer output;
+  grpc_stream_op_buffer encops;
   gpr_slice merged;
   gpr_slice expect = parse_hexstring(expected);
   gpr_slice_buffer_init(&output);
+  grpc_sopb_init(&encops);
   GPR_ASSERT(expect_window_used ==
-             grpc_chttp2_encode_some(g_sopb.ops, &g_sopb.nops, eof, &output,
-                                     window_available, 0xdeadbeef,
-                                     &g_compressor));
+             grpc_chttp2_preencode(g_sopb.ops, &g_sopb.nops, window_available,
+                                   &encops));
+  grpc_chttp2_encode(encops.ops, encops.nops, eof, 0xdeadbeef, &g_compressor,
+                     &output);
+  encops.nops = 0;
   merged = grpc_slice_merge(output.slices, output.count);
   gpr_slice_buffer_destroy(&output);
+  grpc_sopb_destroy(&encops);
 
   if (0 != gpr_slice_cmp(merged, expect)) {
     char *expect_str =
@@ -240,21 +245,25 @@ static void test_decode_random_headers_inner(int max_len) {
   test_decode_random_header_state st;
   gpr_slice_buffer output;
   gpr_slice merged;
+  grpc_stream_op_buffer encops;
   grpc_chttp2_hpack_parser parser;
 
   grpc_chttp2_hpack_parser_init(&parser, g_mdctx);
+  grpc_sopb_init(&encops);
 
   gpr_log(GPR_INFO, "max_len = %d", max_len);
 
-  for (i = 0; i < 100000; i++) {
+  for (i = 0; i < 10000; i++) {
     randstr(st.key, max_len);
     randstr(st.value, max_len);
 
     add_sopb_header(st.key, st.value);
     gpr_slice_buffer_init(&output);
-    GPR_ASSERT(0 == grpc_chttp2_encode_some(g_sopb.ops, &g_sopb.nops, 0,
-                                            &output, 0, 0xdeadbeef,
-                                            &g_compressor));
+    GPR_ASSERT(0 ==
+               grpc_chttp2_preencode(g_sopb.ops, &g_sopb.nops, 0, &encops));
+    grpc_chttp2_encode(encops.ops, encops.nops, 0, 0xdeadbeef, &g_compressor,
+                       &output);
+    encops.nops = 0;
     merged = grpc_slice_merge(output.slices, output.count);
     gpr_slice_buffer_destroy(&output);
 
@@ -269,6 +278,7 @@ static void test_decode_random_headers_inner(int max_len) {
   }
 
   grpc_chttp2_hpack_parser_destroy(&parser);
+  grpc_sopb_destroy(&encops);
 }
 
 #define DECL_TEST_DECODE_RANDOM_HEADERS(n)       \
diff --git a/test/cpp/client/credentials_test.cc b/test/cpp/client/credentials_test.cc
new file mode 100644
index 0000000000000000000000000000000000000000..1bc95f9ff8a3ab63f020f01167548b0a86724426
--- /dev/null
+++ b/test/cpp/client/credentials_test.cc
@@ -0,0 +1,73 @@
+/*
+ *
+ * Copyright 2014, 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++/credentials.h>
+
+#include <memory>
+
+#include <grpc/grpc.h>
+#include <gtest/gtest.h>
+
+namespace grpc {
+namespace testing {
+
+class CredentialsTest : public ::testing::Test {
+ protected:
+};
+
+TEST_F(CredentialsTest, InvalidSslCreds) {
+  std::unique_ptr<Credentials> bad1 =
+      CredentialsFactory::SslCredentials({"", "", ""});
+  EXPECT_EQ(nullptr, bad1.get());
+  std::unique_ptr<Credentials> bad2 =
+      CredentialsFactory::SslCredentials({"", "bla", "bla"});
+  EXPECT_EQ(nullptr, bad2.get());
+}
+
+TEST_F(CredentialsTest, InvalidServiceAccountCreds) {
+  std::unique_ptr<Credentials> bad1 =
+      CredentialsFactory::ServiceAccountCredentials("", "",
+                                                    std::chrono::seconds(1));
+  EXPECT_EQ(nullptr, bad1.get());
+}
+
+}  // namespace testing
+}  // namespace grpc
+
+int main(int argc, char **argv) {
+
+  grpc_init();
+  int ret = RUN_ALL_TESTS();
+  grpc_shutdown();
+  return ret;
+}
diff --git a/test/cpp/end2end/end2end_test.cc b/test/cpp/end2end/end2end_test.cc
index 83037b5ab1836ff201e83e861ecda3dc830ade1d..73b7025cb364708547b9ff051cb5e6885d974b6c 100644
--- a/test/cpp/end2end/end2end_test.cc
+++ b/test/cpp/end2end/end2end_test.cc
@@ -34,13 +34,14 @@
 #include <chrono>
 #include <thread>
 
+#include "net/grpc/cpp/echo_duplicate_proto_cc.pb.h"
 #include "test/cpp/util/echo.pb.h"
-#include "src/cpp/server/rpc_service_method.h"
 #include "src/cpp/util/time.h"
 #include <grpc++/channel_arguments.h>
 #include <grpc++/channel_interface.h>
 #include <grpc++/client_context.h>
 #include <grpc++/create_channel.h>
+#include <grpc++/credentials.h>
 #include <grpc++/server.h>
 #include <grpc++/server_builder.h>
 #include <grpc++/server_context.h>
@@ -55,7 +56,6 @@
 
 using grpc::cpp::test::util::EchoRequest;
 using grpc::cpp::test::util::EchoResponse;
-using grpc::cpp::test::util::TestService;
 using std::chrono::system_clock;
 
 namespace grpc {
@@ -77,10 +77,10 @@ void MaybeEchoDeadline(ServerContext* context, const EchoRequest* request,
 }
 }  // namespace
 
-class TestServiceImpl : public TestService::Service {
+class TestServiceImpl : public ::grpc::cpp::test::util::TestService::Service {
  public:
   Status Echo(ServerContext* context, const EchoRequest* request,
-              EchoResponse* response) {
+              EchoResponse* response) override {
     response->set_message(request->message());
     MaybeEchoDeadline(context, request, response);
     return Status::OK;
@@ -90,7 +90,7 @@ class TestServiceImpl : public TestService::Service {
 
   Status RequestStream(ServerContext* context,
                        ServerReader<EchoRequest>* reader,
-                       EchoResponse* response) {
+                       EchoResponse* response) override {
     EchoRequest request;
     response->set_message("");
     while (reader->Read(&request)) {
@@ -102,7 +102,7 @@ class TestServiceImpl : public TestService::Service {
   // Return 3 messages.
   // TODO(yangg) make it generic by adding a parameter into EchoRequest
   Status ResponseStream(ServerContext* context, const EchoRequest* request,
-                        ServerWriter<EchoResponse>* writer) {
+                        ServerWriter<EchoResponse>* writer) override {
     EchoResponse response;
     response.set_message(request->message() + "0");
     writer->Write(response);
@@ -114,8 +114,9 @@ class TestServiceImpl : public TestService::Service {
     return Status::OK;
   }
 
-  Status BidiStream(ServerContext* context,
-                    ServerReaderWriter<EchoResponse, EchoRequest>* stream) {
+  Status BidiStream(
+      ServerContext* context,
+      ServerReaderWriter<EchoResponse, EchoRequest>* stream) override {
     EchoRequest request;
     EchoResponse response;
     while (stream->Read(&request)) {
@@ -127,6 +128,16 @@ class TestServiceImpl : public TestService::Service {
   }
 };
 
+class TestServiceImplDupPkg
+    : public ::grpc::cpp::test::util::duplicate::TestService::Service {
+ public:
+  Status Echo(ServerContext* context, const EchoRequest* request,
+              EchoResponse* response) override {
+    response->set_message("no package");
+    return Status::OK;
+  }
+};
+
 class End2endTest : public ::testing::Test {
  protected:
   void SetUp() override {
@@ -136,6 +147,7 @@ class End2endTest : public ::testing::Test {
     ServerBuilder builder;
     builder.AddPort(server_address_.str());
     builder.RegisterService(service_.service());
+    builder.RegisterService(dup_pkg_service_.service());
     server_ = builder.BuildAndStart();
   }
 
@@ -143,15 +155,21 @@ class End2endTest : public ::testing::Test {
     server_->Shutdown();
   }
 
+  void ResetStub() {
+    std::shared_ptr<ChannelInterface> channel =
+        CreateChannel(server_address_.str(), ChannelArguments());
+    stub_.reset(grpc::cpp::test::util::TestService::NewStub(channel));
+  }
+
+  std::unique_ptr<grpc::cpp::test::util::TestService::Stub> stub_;
   std::unique_ptr<Server> server_;
   std::ostringstream server_address_;
   TestServiceImpl service_;
+  TestServiceImplDupPkg dup_pkg_service_;
 };
 
-static void SendRpc(const grpc::string& server_address, int num_rpcs) {
-  std::shared_ptr<ChannelInterface> channel =
-      CreateChannel(server_address, ChannelArguments());
-  TestService::Stub* stub = TestService::NewStub(channel);
+static void SendRpc(grpc::cpp::test::util::TestService::Stub* stub,
+                    int num_rpcs) {
   EchoRequest request;
   EchoResponse response;
   request.set_message("Hello");
@@ -162,18 +180,18 @@ static void SendRpc(const grpc::string& server_address, int num_rpcs) {
     EXPECT_EQ(response.message(), request.message());
     EXPECT_TRUE(s.IsOk());
   }
-
-  delete stub;
 }
 
 TEST_F(End2endTest, SimpleRpc) {
-  SendRpc(server_address_.str(), 1);
+  ResetStub();
+  SendRpc(stub_.get(), 1);
 }
 
 TEST_F(End2endTest, MultipleRpcs) {
+  ResetStub();
   vector<std::thread*> threads;
   for (int i = 0; i < 10; ++i) {
-    threads.push_back(new std::thread(SendRpc, server_address_.str(), 10));
+    threads.push_back(new std::thread(SendRpc, stub_.get(), 10));
   }
   for (int i = 0; i < 10; ++i) {
     threads[i]->join();
@@ -183,9 +201,7 @@ TEST_F(End2endTest, MultipleRpcs) {
 
 // Set a 10us deadline and make sure proper error is returned.
 TEST_F(End2endTest, RpcDeadlineExpires) {
-  std::shared_ptr<ChannelInterface> channel =
-      CreateChannel(server_address_.str(), ChannelArguments());
-  TestService::Stub* stub = TestService::NewStub(channel);
+  ResetStub();
   EchoRequest request;
   EchoResponse response;
   request.set_message("Hello");
@@ -194,19 +210,15 @@ TEST_F(End2endTest, RpcDeadlineExpires) {
   std::chrono::system_clock::time_point deadline =
       std::chrono::system_clock::now() + std::chrono::microseconds(10);
   context.set_absolute_deadline(deadline);
-  Status s = stub->Echo(&context, request, &response);
+  Status s = stub_->Echo(&context, request, &response);
   // TODO(yangg) use correct error code when b/18793983 is fixed.
   // EXPECT_EQ(StatusCode::DEADLINE_EXCEEDED, s.code());
   EXPECT_EQ(StatusCode::CANCELLED, s.code());
-
-  delete stub;
 }
 
 // Set a long but finite deadline.
 TEST_F(End2endTest, RpcLongDeadline) {
-  std::shared_ptr<ChannelInterface> channel =
-      CreateChannel(server_address_.str(), ChannelArguments());
-  TestService::Stub* stub = TestService::NewStub(channel);
+  ResetStub();
   EchoRequest request;
   EchoResponse response;
   request.set_message("Hello");
@@ -215,18 +227,14 @@ TEST_F(End2endTest, RpcLongDeadline) {
   std::chrono::system_clock::time_point deadline =
       std::chrono::system_clock::now() + std::chrono::hours(1);
   context.set_absolute_deadline(deadline);
-  Status s = stub->Echo(&context, request, &response);
+  Status s = stub_->Echo(&context, request, &response);
   EXPECT_EQ(response.message(), request.message());
   EXPECT_TRUE(s.IsOk());
-
-  delete stub;
 }
 
 // Ask server to echo back the deadline it sees.
 TEST_F(End2endTest, EchoDeadline) {
-  std::shared_ptr<ChannelInterface> channel =
-      CreateChannel(server_address_.str(), ChannelArguments());
-  TestService::Stub* stub = TestService::NewStub(channel);
+  ResetStub();
   EchoRequest request;
   EchoResponse response;
   request.set_message("Hello");
@@ -236,7 +244,7 @@ TEST_F(End2endTest, EchoDeadline) {
   std::chrono::system_clock::time_point deadline =
       std::chrono::system_clock::now() + std::chrono::seconds(100);
   context.set_absolute_deadline(deadline);
-  Status s = stub->Echo(&context, request, &response);
+  Status s = stub_->Echo(&context, request, &response);
   EXPECT_EQ(response.message(), request.message());
   EXPECT_TRUE(s.IsOk());
   gpr_timespec sent_deadline;
@@ -244,56 +252,44 @@ TEST_F(End2endTest, EchoDeadline) {
   // Allow 1 second error.
   EXPECT_LE(response.param().request_deadline() - sent_deadline.tv_sec, 1);
   EXPECT_GE(response.param().request_deadline() - sent_deadline.tv_sec, -1);
-
-  delete stub;
 }
 
 // Ask server to echo back the deadline it sees. The rpc has no deadline.
 TEST_F(End2endTest, EchoDeadlineForNoDeadlineRpc) {
-  std::shared_ptr<ChannelInterface> channel =
-      CreateChannel(server_address_.str(), ChannelArguments());
-  TestService::Stub* stub = TestService::NewStub(channel);
+  ResetStub();
   EchoRequest request;
   EchoResponse response;
   request.set_message("Hello");
   request.mutable_param()->set_echo_deadline(true);
 
   ClientContext context;
-  Status s = stub->Echo(&context, request, &response);
+  Status s = stub_->Echo(&context, request, &response);
   EXPECT_EQ(response.message(), request.message());
   EXPECT_TRUE(s.IsOk());
   EXPECT_EQ(response.param().request_deadline(), gpr_inf_future.tv_sec);
-
-  delete stub;
 }
 
 TEST_F(End2endTest, UnimplementedRpc) {
-  std::shared_ptr<ChannelInterface> channel =
-      CreateChannel(server_address_.str(), ChannelArguments());
-  TestService::Stub* stub = TestService::NewStub(channel);
+  ResetStub();
   EchoRequest request;
   EchoResponse response;
   request.set_message("Hello");
 
   ClientContext context;
-  Status s = stub->Unimplemented(&context, request, &response);
+  Status s = stub_->Unimplemented(&context, request, &response);
   EXPECT_FALSE(s.IsOk());
   EXPECT_EQ(s.code(), grpc::StatusCode::UNIMPLEMENTED);
   EXPECT_EQ(s.details(), "");
   EXPECT_EQ(response.message(), "");
-
-  delete stub;
 }
 
 TEST_F(End2endTest, RequestStreamOneRequest) {
-  std::shared_ptr<ChannelInterface> channel =
-      CreateChannel(server_address_.str(), ChannelArguments());
-  TestService::Stub* stub = TestService::NewStub(channel);
+  ResetStub();
   EchoRequest request;
   EchoResponse response;
   ClientContext context;
 
-  ClientWriter<EchoRequest>* stream = stub->RequestStream(&context, &response);
+  ClientWriter<EchoRequest>* stream = stub_->RequestStream(&context, &response);
   request.set_message("hello");
   EXPECT_TRUE(stream->Write(request));
   stream->WritesDone();
@@ -302,18 +298,15 @@ TEST_F(End2endTest, RequestStreamOneRequest) {
   EXPECT_TRUE(s.IsOk());
 
   delete stream;
-  delete stub;
 }
 
 TEST_F(End2endTest, RequestStreamTwoRequests) {
-  std::shared_ptr<ChannelInterface> channel =
-      CreateChannel(server_address_.str(), ChannelArguments());
-  TestService::Stub* stub = TestService::NewStub(channel);
+  ResetStub();
   EchoRequest request;
   EchoResponse response;
   ClientContext context;
 
-  ClientWriter<EchoRequest>* stream = stub->RequestStream(&context, &response);
+  ClientWriter<EchoRequest>* stream = stub_->RequestStream(&context, &response);
   request.set_message("hello");
   EXPECT_TRUE(stream->Write(request));
   EXPECT_TRUE(stream->Write(request));
@@ -323,19 +316,17 @@ TEST_F(End2endTest, RequestStreamTwoRequests) {
   EXPECT_TRUE(s.IsOk());
 
   delete stream;
-  delete stub;
 }
 
 TEST_F(End2endTest, ResponseStream) {
-  std::shared_ptr<ChannelInterface> channel =
-      CreateChannel(server_address_.str(), ChannelArguments());
-  TestService::Stub* stub = TestService::NewStub(channel);
+  ResetStub();
   EchoRequest request;
   EchoResponse response;
   ClientContext context;
   request.set_message("hello");
 
-  ClientReader<EchoResponse>* stream = stub->ResponseStream(&context, &request);
+  ClientReader<EchoResponse>* stream =
+      stub_->ResponseStream(&context, &request);
   EXPECT_TRUE(stream->Read(&response));
   EXPECT_EQ(response.message(), request.message() + "0");
   EXPECT_TRUE(stream->Read(&response));
@@ -348,20 +339,17 @@ TEST_F(End2endTest, ResponseStream) {
   EXPECT_TRUE(s.IsOk());
 
   delete stream;
-  delete stub;
 }
 
 TEST_F(End2endTest, BidiStream) {
-  std::shared_ptr<ChannelInterface> channel =
-      CreateChannel(server_address_.str(), ChannelArguments());
-  TestService::Stub* stub = TestService::NewStub(channel);
+  ResetStub();
   EchoRequest request;
   EchoResponse response;
   ClientContext context;
   grpc::string msg("hello");
 
   ClientReaderWriter<EchoRequest, EchoResponse>* stream =
-      stub->BidiStream(&context);
+      stub_->BidiStream(&context);
 
   request.set_message(msg + "0");
   EXPECT_TRUE(stream->Write(request));
@@ -385,7 +373,64 @@ TEST_F(End2endTest, BidiStream) {
   EXPECT_TRUE(s.IsOk());
 
   delete stream;
-  delete stub;
+}
+
+// Talk to the two services with the same name but different package names.
+// The two stubs are created on the same channel.
+TEST_F(End2endTest, DiffPackageServices) {
+  std::shared_ptr<ChannelInterface> channel =
+      CreateChannel(server_address_.str(), ChannelArguments());
+
+  EchoRequest request;
+  EchoResponse response;
+  request.set_message("Hello");
+
+  std::unique_ptr<grpc::cpp::test::util::TestService::Stub> stub(
+      grpc::cpp::test::util::TestService::NewStub(channel));
+  ClientContext context;
+  Status s = stub->Echo(&context, request, &response);
+  EXPECT_EQ(response.message(), request.message());
+  EXPECT_TRUE(s.IsOk());
+
+  std::unique_ptr<grpc::cpp::test::util::duplicate::TestService::Stub>
+      dup_pkg_stub(
+          grpc::cpp::test::util::duplicate::TestService::NewStub(channel));
+  ClientContext context2;
+  s = dup_pkg_stub->Echo(&context2, request, &response);
+  EXPECT_EQ("no package", response.message());
+  EXPECT_TRUE(s.IsOk());
+}
+
+// rpc and stream should fail on bad credentials.
+TEST_F(End2endTest, BadCredentials) {
+  std::unique_ptr<Credentials> bad_creds =
+      CredentialsFactory::ServiceAccountCredentials("", "",
+                                                    std::chrono::seconds(1));
+  EXPECT_EQ(nullptr, bad_creds.get());
+  std::shared_ptr<ChannelInterface> channel =
+      CreateChannel(server_address_.str(), bad_creds, ChannelArguments());
+  std::unique_ptr<grpc::cpp::test::util::TestService::Stub> stub(
+      grpc::cpp::test::util::TestService::NewStub(channel));
+  EchoRequest request;
+  EchoResponse response;
+  ClientContext context;
+  grpc::string msg("hello");
+
+  Status s = stub->Echo(&context, request, &response);
+  EXPECT_EQ("", response.message());
+  EXPECT_FALSE(s.IsOk());
+  EXPECT_EQ(StatusCode::UNKNOWN, s.code());
+  EXPECT_EQ("Rpc sent on a lame channel.", s.details());
+
+  ClientContext context2;
+  ClientReaderWriter<EchoRequest, EchoResponse>* stream =
+      stub->BidiStream(&context2);
+  s = stream->Wait();
+  EXPECT_FALSE(s.IsOk());
+  EXPECT_EQ(StatusCode::UNKNOWN, s.code());
+  EXPECT_EQ("Rpc sent on a lame channel.", s.details());
+
+  delete stream;
 }
 
 }  // namespace testing
diff --git a/test/cpp/end2end/sync_client_async_server_test.cc b/test/cpp/end2end/sync_client_async_server_test.cc
index 839f89cdb1ebd1d28e0717f8bbb3fd335d0017a3..f4dad60e22354202e6ed267317a3e15ed2c0289e 100644
--- a/test/cpp/end2end/sync_client_async_server_test.cc
+++ b/test/cpp/end2end/sync_client_async_server_test.cc
@@ -39,17 +39,17 @@
 
 #include <grpc/grpc.h>
 #include <grpc/support/thd.h>
-#include "src/cpp/client/internal_stub.h"
-#include "src/cpp/rpc_method.h"
 #include "test/cpp/util/echo.pb.h"
-#include "net/util/netutil.h"
 #include <grpc++/channel_arguments.h>
 #include <grpc++/channel_interface.h>
 #include <grpc++/client_context.h>
 #include <grpc++/create_channel.h>
+#include <grpc++/impl/internal_stub.h>
+#include <grpc++/impl/rpc_method.h>
 #include <grpc++/status.h>
 #include <grpc++/stream.h>
 #include "test/cpp/end2end/async_test_server.h"
+#include "net/util/netutil.h"
 #include <gtest/gtest.h>
 
 using grpc::cpp::test::util::EchoRequest;
diff --git a/test/cpp/interop/client.cc b/test/cpp/interop/client.cc
index ee0f62cf20b672ab1c945d34802d2bd521d5868b..36bc580a96cec546daf86ca444e3f2bc5300cf64 100644
--- a/test/cpp/interop/client.cc
+++ b/test/cpp/interop/client.cc
@@ -128,6 +128,152 @@ void DoLargeUnary(std::shared_ptr<ChannelInterface> channel) {
   gpr_log(GPR_INFO, "Large unary done.");
 }
 
+void DoRequestStreaming(std::shared_ptr<ChannelInterface> channel) {
+  gpr_log(GPR_INFO, "Sending request steaming rpc ...");
+  std::unique_ptr<TestService::Stub> stub(TestService::NewStub(channel));
+
+  grpc::ClientContext context;
+  StreamingInputCallRequest request;
+  StreamingInputCallResponse response;
+
+  std::unique_ptr<grpc::ClientWriter<StreamingInputCallRequest>> stream(
+      stub->StreamingInputCall(&context, &response));
+
+  int aggregated_payload_size = 0;
+  for (unsigned int i = 0; i < request_stream_sizes.size(); ++i) {
+    grpc::testing::Payload* payload = request.mutable_payload();
+    payload->set_body(grpc::string(request_stream_sizes[i], '\0'));
+    GPR_ASSERT(stream->Write(request));
+    aggregated_payload_size += request_stream_sizes[i];
+  }
+  stream->WritesDone();
+  grpc::Status s = stream->Wait();
+
+  GPR_ASSERT(response.aggregated_payload_size() == aggregated_payload_size);
+  GPR_ASSERT(s.IsOk());
+  gpr_log(GPR_INFO, "Request streaming done.");
+}
+
+void DoResponseStreaming(std::shared_ptr<ChannelInterface> channel) {
+  gpr_log(GPR_INFO, "Receiving response steaming rpc ...");
+  std::unique_ptr<TestService::Stub> stub(TestService::NewStub(channel));
+
+  grpc::ClientContext context;
+  StreamingOutputCallRequest request;
+  for (unsigned int i = 0; i < response_stream_sizes.size(); ++i) {
+    ResponseParameters* response_parameter = request.add_response_parameters();
+    response_parameter->set_size(response_stream_sizes[i]);
+  }
+  StreamingOutputCallResponse response;
+  std::unique_ptr<grpc::ClientReader<StreamingOutputCallResponse>> stream(
+      stub->StreamingOutputCall(&context, &request));
+
+  unsigned int i = 0;
+  while (stream->Read(&response)) {
+    GPR_ASSERT(response.payload().body() ==
+               grpc::string(response_stream_sizes[i], '\0'));
+    ++i;
+  }
+  GPR_ASSERT(response_stream_sizes.size() == i);
+  grpc::Status s = stream->Wait();
+
+  GPR_ASSERT(s.IsOk());
+  gpr_log(GPR_INFO, "Response streaming done.");
+}
+
+void DoResponseStreamingWithSlowConsumer(
+    std::shared_ptr<ChannelInterface> channel) {
+  gpr_log(GPR_INFO, "Receiving response steaming rpc with slow consumer ...");
+  std::unique_ptr<TestService::Stub> stub(TestService::NewStub(channel));
+
+  grpc::ClientContext context;
+  StreamingOutputCallRequest request;
+
+  for (unsigned int i = 0; i < kNumResponseMessages; ++i) {
+    ResponseParameters* response_parameter = request.add_response_parameters();
+    response_parameter->set_size(kResponseMessageSize);
+  }
+  StreamingOutputCallResponse response;
+  std::unique_ptr<grpc::ClientReader<StreamingOutputCallResponse>> stream(
+      stub->StreamingOutputCall(&context, &request));
+
+  unsigned int i = 0;
+  while (stream->Read(&response)) {
+    GPR_ASSERT(response.payload().body() ==
+               grpc::string(kResponseMessageSize, '\0'));
+    gpr_log(GPR_INFO, "received message %d", i);
+    std::this_thread::sleep_for(
+        std::chrono::milliseconds(kReceiveDelayMilliSeconds));
+    ++i;
+  }
+  GPR_ASSERT(kNumResponseMessages == i);
+  grpc::Status s = stream->Wait();
+
+  GPR_ASSERT(s.IsOk());
+  gpr_log(GPR_INFO, "Response streaming done.");
+}
+
+void DoHalfDuplex(std::shared_ptr<ChannelInterface> channel) {
+  gpr_log(GPR_INFO, "Sending half-duplex streaming rpc ...");
+  std::unique_ptr<TestService::Stub> stub(TestService::NewStub(channel));
+
+  grpc::ClientContext context;
+  std::unique_ptr<grpc::ClientReaderWriter<StreamingOutputCallRequest,
+                                           StreamingOutputCallResponse>>
+      stream(stub->HalfDuplexCall(&context));
+
+  StreamingOutputCallRequest request;
+  ResponseParameters* response_parameter = request.add_response_parameters();
+  for (unsigned int i = 0; i < response_stream_sizes.size(); ++i) {
+    response_parameter->set_size(response_stream_sizes[i]);
+    GPR_ASSERT(stream->Write(request));
+  }
+  stream->WritesDone();
+
+  unsigned int i = 0;
+  StreamingOutputCallResponse response;
+  while (stream->Read(&response)) {
+    GPR_ASSERT(response.payload().has_body());
+    GPR_ASSERT(response.payload().body() ==
+               grpc::string(response_stream_sizes[i], '\0'));
+    ++i;
+  }
+  GPR_ASSERT(response_stream_sizes.size() == i);
+  grpc::Status s = stream->Wait();
+  GPR_ASSERT(s.IsOk());
+  gpr_log(GPR_INFO, "Half-duplex streaming rpc done.");
+}
+
+void DoPingPong(std::shared_ptr<ChannelInterface> channel) {
+  gpr_log(GPR_INFO, "Sending Ping Pong streaming rpc ...");
+  std::unique_ptr<TestService::Stub> stub(TestService::NewStub(channel));
+
+  grpc::ClientContext context;
+  std::unique_ptr<grpc::ClientReaderWriter<StreamingOutputCallRequest,
+                                           StreamingOutputCallResponse>>
+      stream(stub->FullDuplexCall(&context));
+
+  StreamingOutputCallRequest request;
+  request.set_response_type(grpc::testing::PayloadType::COMPRESSABLE);
+  ResponseParameters* response_parameter = request.add_response_parameters();
+  grpc::testing::Payload* payload = request.mutable_payload();
+  StreamingOutputCallResponse response;
+  for (unsigned int i = 0; i < request_stream_sizes.size(); ++i) {
+    response_parameter->set_size(response_stream_sizes[i]);
+    payload->set_body(grpc::string(request_stream_sizes[i], '\0'));
+    GPR_ASSERT(stream->Write(request));
+    GPR_ASSERT(stream->Read(&response));
+    GPR_ASSERT(response.payload().has_body());
+    GPR_ASSERT(response.payload().body() ==
+               grpc::string(response_stream_sizes[i], '\0'));
+  }
+
+  stream->WritesDone();
+  GPR_ASSERT(!stream->Read(&response));
+  grpc::Status s = stream->Wait();
+  GPR_ASSERT(s.IsOk());
+  gpr_log(GPR_INFO, "Ping pong streaming done.");
+}
 
 int main(int argc, char** argv) {
   grpc_init();
@@ -148,6 +294,23 @@ int main(int argc, char** argv) {
     DoEmpty(channel);
   } else if (FLAGS_test_case == "large_unary") {
     DoLargeUnary(channel);
+  } else if (FLAGS_test_case == "client_streaming") {
+    DoRequestStreaming(channel);
+  } else if (FLAGS_test_case == "server_streaming") {
+    DoResponseStreaming(channel);
+  } else if (FLAGS_test_case == "slow_consumer") {
+    DoResponseStreamingWithSlowConsumer(channel);
+  } else if (FLAGS_test_case == "half_duplex") {
+    DoHalfDuplex(channel);
+  } else if (FLAGS_test_case == "ping_pong") {
+    DoPingPong(channel);
+  } else if (FLAGS_test_case == "all") {
+    DoEmpty(channel);
+    DoLargeUnary(channel);
+    DoRequestStreaming(channel);
+    DoResponseStreaming(channel);
+    DoHalfDuplex(channel);
+    DoPingPong(channel);
   } else {
     gpr_log(
         GPR_ERROR,
diff --git a/test/cpp/interop/server.cc b/test/cpp/interop/server.cc
new file mode 100644
index 0000000000000000000000000000000000000000..561b134c279081c518f2ead5475b93ec27f44d68
--- /dev/null
+++ b/test/cpp/interop/server.cc
@@ -0,0 +1,231 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <memory>
+#include <sstream>
+#include <thread>
+
+#include <google/gflags.h>
+#include <grpc/grpc.h>
+#include <grpc/support/log.h>
+#include "test/core/end2end/data/ssl_test_data.h"
+#include <grpc++/config.h>
+#include <grpc++/server.h>
+#include <grpc++/server_builder.h>
+#include <grpc++/server_context.h>
+#include <grpc++/server_credentials.h>
+#include <grpc++/status.h>
+#include <grpc++/stream.h>
+#include "test/cpp/interop/test.pb.h"
+#include "test/cpp/interop/empty.pb.h"
+#include "test/cpp/interop/messages.pb.h"
+
+DEFINE_bool(enable_ssl, false, "Whether to use ssl/tls.");
+DEFINE_int32(port, 0, "Server port.");
+
+using grpc::Server;
+using grpc::ServerBuilder;
+using grpc::ServerContext;
+using grpc::ServerCredentials;
+using grpc::ServerCredentialsFactory;
+using grpc::ServerReader;
+using grpc::ServerReaderWriter;
+using grpc::ServerWriter;
+using grpc::SslServerCredentialsOptions;
+using grpc::testing::Payload;
+using grpc::testing::PayloadType;
+using grpc::testing::SimpleRequest;
+using grpc::testing::SimpleResponse;
+using grpc::testing::StreamingInputCallRequest;
+using grpc::testing::StreamingInputCallResponse;
+using grpc::testing::StreamingOutputCallRequest;
+using grpc::testing::StreamingOutputCallResponse;
+using grpc::testing::TestService;
+using grpc::Status;
+
+bool SetPayload(PayloadType type, int size, Payload* payload) {
+  PayloadType response_type = type;
+  // TODO(yangg): Support UNCOMPRESSABLE payload.
+  if (type != PayloadType::COMPRESSABLE) {
+    return false;
+  }
+  payload->set_type(response_type);
+  std::unique_ptr<char[]> body(new char[size]());
+  payload->set_body(body.get(), size);
+  return true;
+}
+
+class TestServiceImpl : public TestService::Service {
+ public:
+  Status EmptyCall(ServerContext* context, const grpc::testing::Empty* request,
+                   grpc::testing::Empty* response) {
+    return Status::OK;
+  }
+
+  Status UnaryCall(ServerContext* context, const SimpleRequest* request,
+                   SimpleResponse* response) {
+    if (request->has_response_size() && request->response_size() > 0) {
+      if (!SetPayload(request->response_type(), request->response_size(),
+                      response->mutable_payload())) {
+        return Status(grpc::StatusCode::INTERNAL, "Error creating payload.");
+      }
+    }
+    return Status::OK;
+  }
+
+  Status StreamingOutputCall(
+      ServerContext* context, const StreamingOutputCallRequest* request,
+      ServerWriter<StreamingOutputCallResponse>* writer) {
+    StreamingOutputCallResponse response;
+    bool write_success = true;
+    response.mutable_payload()->set_type(request->response_type());
+    for (int i = 0; write_success && i < request->response_parameters_size();
+         i++) {
+      response.mutable_payload()->set_body(
+          grpc::string(request->response_parameters(i).size(), '\0'));
+      write_success = writer->Write(response);
+    }
+    if (write_success) {
+      return Status::OK;
+    } else {
+      return Status(grpc::StatusCode::INTERNAL, "Error writing response.");
+    }
+  }
+
+  Status StreamingInputCall(ServerContext* context,
+                            ServerReader<StreamingInputCallRequest>* reader,
+                            StreamingInputCallResponse* response) {
+    StreamingInputCallRequest request;
+    int aggregated_payload_size = 0;
+    while (reader->Read(&request)) {
+      if (request.has_payload() && request.payload().has_body()) {
+        aggregated_payload_size += request.payload().body().size();
+      }
+    }
+    response->set_aggregated_payload_size(aggregated_payload_size);
+    return Status::OK;
+  }
+
+  Status FullDuplexCall(
+      ServerContext* context,
+      ServerReaderWriter<StreamingOutputCallResponse,
+                         StreamingOutputCallRequest>* stream) {
+    StreamingOutputCallRequest request;
+    StreamingOutputCallResponse response;
+    bool write_success = true;
+    while (write_success && stream->Read(&request)) {
+      response.mutable_payload()->set_type(request.payload().type());
+      if (request.response_parameters_size() == 0) {
+        return Status(grpc::StatusCode::INTERNAL,
+                      "Request does not have response parameters.");
+      }
+      response.mutable_payload()->set_body(
+          grpc::string(request.response_parameters(0).size(), '\0'));
+      write_success = stream->Write(response);
+    }
+    if (write_success) {
+      return Status::OK;
+    } else {
+      return Status(grpc::StatusCode::INTERNAL, "Error writing response.");
+    }
+  }
+
+  Status HalfDuplexCall(
+      ServerContext* context,
+      ServerReaderWriter<StreamingOutputCallResponse,
+                         StreamingOutputCallRequest>* stream) {
+    std::vector<StreamingOutputCallRequest> requests;
+    StreamingOutputCallRequest request;
+    while (stream->Read(&request)) {
+      requests.push_back(request);
+    }
+
+    StreamingOutputCallResponse response;
+    bool write_success = true;
+    for (unsigned int i = 0; write_success && i < requests.size(); i++) {
+      response.mutable_payload()->set_type(requests[i].payload().type());
+      if (requests[i].response_parameters_size() == 0) {
+        return Status(grpc::StatusCode::INTERNAL,
+                      "Request does not have response parameters.");
+      }
+      response.mutable_payload()->set_body(
+          grpc::string(requests[i].response_parameters(0).size(), '\0'));
+      write_success = stream->Write(response);
+    }
+    if (write_success) {
+      return Status::OK;
+    } else {
+      return Status(grpc::StatusCode::INTERNAL, "Error writing response.");
+    }
+  }
+};
+
+void RunServer() {
+  std::ostringstream server_address;
+  server_address << "localhost:" << FLAGS_port;
+  TestServiceImpl service;
+
+  SimpleRequest request;
+  SimpleResponse response;
+
+  ServerBuilder builder;
+  builder.AddPort(server_address.str());
+  builder.RegisterService(service.service());
+  if (FLAGS_enable_ssl) {
+    SslServerCredentialsOptions ssl_opts = {
+        "",
+        {reinterpret_cast<const char*>(test_server1_key),
+         test_server1_key_size},
+        {reinterpret_cast<const char*>(test_server1_cert),
+         test_server1_cert_size}};
+    std::shared_ptr<ServerCredentials> creds =
+        ServerCredentialsFactory::SslCredentials(ssl_opts);
+    builder.SetCredentials(creds);
+  }
+  std::unique_ptr<Server> server(builder.BuildAndStart());
+  gpr_log(GPR_INFO, "Server listening on %s", server_address.str().c_str());
+  while (true) {
+    std::this_thread::sleep_for(std::chrono::seconds(5));
+  }
+}
+
+int main(int argc, char** argv) {
+  grpc_init();
+  google::ParseCommandLineFlags(&argc, &argv, true);
+
+  GPR_ASSERT(FLAGS_port != 0);
+  RunServer();
+
+  grpc_shutdown();
+  return 0;
+}
diff --git a/test/cpp/util/echo.proto b/test/cpp/util/echo.proto
index 1240399bf88df3c013854db73358d37ebdbf2e9c..bd5357fe197524705e4a0da267ac10c2e94e8a24 100644
--- a/test/cpp/util/echo.proto
+++ b/test/cpp/util/echo.proto
@@ -1,24 +1,8 @@
 syntax = "proto2";
 
-package grpc.cpp.test.util;
-
-message RequestParams {
-  optional bool echo_deadline = 1;
-}
-
-message EchoRequest {
-  optional string message = 1;
-  optional RequestParams param = 2;
-}
+import "test/cpp/util/messages.proto";
 
-message ResponseParams {
-  optional int64 request_deadline = 1;
-}
-
-message EchoResponse {
-  optional string message = 1;
-  optional ResponseParams param = 2;
-}
+package grpc.cpp.test.util;
 
 service TestService {
   rpc Echo(EchoRequest) returns (EchoResponse);
diff --git a/test/cpp/util/echo_duplicate.proto b/test/cpp/util/echo_duplicate.proto
new file mode 100644
index 0000000000000000000000000000000000000000..c9266833e22e39aa2fa1e863da02ce300ccf5518
--- /dev/null
+++ b/test/cpp/util/echo_duplicate.proto
@@ -0,0 +1,12 @@
+// This is a partial copy of echo.proto with a different package name.
+
+syntax = "proto2";
+
+import "test/cpp/util/messages.proto";
+
+package grpc.cpp.test.util.duplicate;
+
+service TestService {
+  rpc Echo(grpc.cpp.test.util.EchoRequest)
+      returns (grpc.cpp.test.util.EchoResponse);
+}
diff --git a/test/cpp/util/messages.proto b/test/cpp/util/messages.proto
new file mode 100644
index 0000000000000000000000000000000000000000..d541821b655a274f5c82172f05f327d74c05f59c
--- /dev/null
+++ b/test/cpp/util/messages.proto
@@ -0,0 +1,21 @@
+syntax = "proto2";
+
+package grpc.cpp.test.util;
+
+message RequestParams {
+  optional bool echo_deadline = 1;
+}
+
+message EchoRequest {
+  optional string message = 1;
+  optional RequestParams param = 2;
+}
+
+message ResponseParams {
+  optional int64 request_deadline = 1;
+}
+
+message EchoResponse {
+  optional string message = 1;
+  optional ResponseParams param = 2;
+}
diff --git a/tools/buildgen/generate_projects.sh b/tools/buildgen/generate_projects.sh
index f4e367d620af6095924faed0be3368ec71da417f..8358e3aea677faf571695149f3a7eaa8c386eeb0 100755
--- a/tools/buildgen/generate_projects.sh
+++ b/tools/buildgen/generate_projects.sh
@@ -1,13 +1,13 @@
 #!/bin/bash
 
-set -ex
+set -x
 
 if [ "x$TEST" == "x" ] ; then
   TEST=false
 fi
 
 
-cd `dirname $0`/..
+cd `dirname $0`/../..
 mako_renderer=tools/buildgen/mako_renderer.py
 gen_build_json=test/core/end2end/gen_build_json.py
 
@@ -33,8 +33,6 @@ for dir in . ; do
     if [ $TEST == true ] ; then
       actual_out=$out
       out=`mktemp`
-    else
-      g4 open $out || true
     fi
     $mako_renderer $plugins $data -o $out $file
     if [ $TEST == true ] ; then
diff --git a/tools/dockerfile/grpc_ruby/Dockerfile b/tools/dockerfile/grpc_ruby/Dockerfile
index 209257144b7e022d7b295b9a0d2492806ab88665..9aa34bfcc99a94d0e02452a1fdecaeeb577250c5 100644
--- a/tools/dockerfile/grpc_ruby/Dockerfile
+++ b/tools/dockerfile/grpc_ruby/Dockerfile
@@ -1,6 +1,9 @@
 # Dockerfile for gRPC Ruby
 FROM grpc/ruby_base
 
+# Start the daemon that allows access to the protected git-on-borg repos
+RUN /var/local/git/gcompute-tools/git-cookie-authdaemon
+
 RUN cd /var/local/git/grpc \
   && git pull --recurse-submodules \
   && git submodule update --init --recursive
diff --git a/tools/gce_setup/grpc_docker.sh b/tools/gce_setup/grpc_docker.sh
index 094b97bf3c1db16d49602dc621a9750ec36b1ddd..d2614fbb137ca1f6d97eaad315c6f51a8fed530c 100755
--- a/tools/gce_setup/grpc_docker.sh
+++ b/tools/gce_setup/grpc_docker.sh
@@ -333,6 +333,45 @@ grpc_interop_test_args() {
   }
 }
 
+grpc_update_docker_images_args() {
+  [[ -n $1 ]] && {  # host
+    host=$1
+    shift
+  } || {
+    echo "$FUNCNAME: missing arg: host" 1>&2
+    return 1
+  }
+}
+
+# Updates all the known docker images on a host..
+#
+# call-seq;
+#   grpc_update_docker_images <server_name>
+#
+# Updates the GCE docker instance <server_name>
+grpc_update_docker_images() {
+  # declare vars local so that they don't pollute the shell environment
+  # where they this func is used.
+  local grpc_zone grpc_project dry_run  # set by grpc_set_project_and_zone
+  # set by grpc_update_docker_images_args
+  local host
+
+  # set the project zone and check that all necessary args are provided
+  grpc_set_project_and_zone -f grpc_update_docker_images_args "$@" || return 1
+  gce_has_instance $grpc_project $host || return 1;
+
+  local func_lib="/var/local/startup_scripts/shared_startup_funcs.sh"
+  local cmd="source $func_lib && grpc_docker_pull_known"
+  local project_opt="--project $grpc_project"
+  local zone_opt="--zone $grpc_zone"
+  local ssh_cmd="bash -l -c \"$cmd\""
+  echo "will run:"
+  echo "  $ssh_cmd"
+  echo "on $host"
+  [[ $dry_run == 1 ]] && return 0  # don't run the command on a dry run
+  gcloud compute $project_opt ssh $zone_opt $host --command "$cmd"
+}
+
 grpc_launch_server_args() {
   [[ -n $1 ]] && {  # host
     host=$1
diff --git a/tools/run_tests/jobset.py b/tools/run_tests/jobset.py
index b7bcb7b02c11a031af7af22c2091eb382bd75988..17fb1d6924033e95af1fa9145a9187e0c6237545 100755
--- a/tools/run_tests/jobset.py
+++ b/tools/run_tests/jobset.py
@@ -8,7 +8,7 @@ import tempfile
 import time
 
 
-_MAX_JOBS = 3
+_DEFAULT_MAX_JOBS = 16 * multiprocessing.cpu_count()
 
 
 def shuffle_iteratable(it):
@@ -103,16 +103,17 @@ class Job(object):
 class Jobset(object):
   """Manages one run of jobs."""
 
-  def __init__(self, check_cancelled):
+  def __init__(self, check_cancelled, maxjobs):
     self._running = set()
     self._check_cancelled = check_cancelled
     self._cancelled = False
     self._failures = 0
     self._completed = 0
+    self._maxjobs = maxjobs
 
   def start(self, cmdline):
     """Start a job. Return True on success, False on failure."""
-    while len(self._running) >= _MAX_JOBS:
+    while len(self._running) >= self._maxjobs:
       if self.cancelled(): return False
       self.reap()
     if self.cancelled(): return False
@@ -156,10 +157,10 @@ def _never_cancelled():
   return False
 
 
-def run(cmdlines, check_cancelled=_never_cancelled):
-  js = Jobset(check_cancelled)
+def run(cmdlines, check_cancelled=_never_cancelled, maxjobs=None):
+  js = Jobset(check_cancelled,
+              maxjobs if maxjobs is not None else _DEFAULT_MAX_JOBS)
   for cmdline in shuffle_iteratable(cmdlines):
     if not js.start(cmdline):
       break
   return js.finish()
-
diff --git a/tools/run_tests/run_tests.py b/tools/run_tests/run_tests.py
index 2bd2e6d830cbf9aaa5d2b163004d8d59cc0609be..7ddf50c4a88d2930db2701b1bfd4ec4c47922da1 100755
--- a/tools/run_tests/run_tests.py
+++ b/tools/run_tests/run_tests.py
@@ -76,7 +76,7 @@ def _build_and_run(check_cancelled):
         '-j', '%d' % (multiprocessing.cpu_count() + 1),
         'buildtests_c',
         'CONFIG=%s' % cfg]
-       for cfg in build_configs), check_cancelled):
+       for cfg in build_configs), check_cancelled, maxjobs=1):
     sys.exit(1)
 
   # run all the tests
diff --git a/tools/run_tests/watch_dirs.py b/tools/run_tests/watch_dirs.py
index 8ebbb2718066beb3a2a38e97bc28bc1c38b7306f..056e69a16c413d2d9644c279fae0b16aa22243d4 100755
--- a/tools/run_tests/watch_dirs.py
+++ b/tools/run_tests/watch_dirs.py
@@ -1,7 +1,6 @@
 """Helper to watch a (set) of directories for modifications."""
 
 import os
-import threading
 import time
 
 
@@ -11,7 +10,6 @@ class DirWatcher(object):
   def __init__(self, paths):
     if isinstance(paths, basestring):
       paths = [paths]
-    self._mu = threading.Lock()
     self._done = False
     self.paths = list(paths)
     self.lastrun = time.time()
@@ -35,12 +33,8 @@ class DirWatcher(object):
     return most_recent_change
 
   def most_recent_change(self):
-    self._mu.acquire()
-    try:
-      if time.time() - self.lastrun > 1:
-        self._cache = self._calculate()
-        self.lastrun = time.time()
-      return self._cache
-    finally:
-      self._mu.release()
+    if time.time() - self.lastrun > 1:
+      self._cache = self._calculate()
+      self.lastrun = time.time()
+    return self._cache
 
diff --git a/vsprojects/vs2013/grpc.vcxproj b/vsprojects/vs2013/grpc.vcxproj
index 6cc5a8b2932938636a195057f81821a90a19e123..294b73f155e28a0c442796759040de260f1d722c 100644
--- a/vsprojects/vs2013/grpc.vcxproj
+++ b/vsprojects/vs2013/grpc.vcxproj
@@ -134,6 +134,7 @@
     <ClInclude Include="..\..\src\core\statistics\census_interface.h" />
     <ClInclude Include="..\..\src\core\statistics\census_log.h" />
     <ClInclude Include="..\..\src\core\statistics\census_rpc_stats.h" />
+    <ClInclude Include="..\..\src\core\statistics\census_tracing.h" />
     <ClInclude Include="..\..\src\core\statistics\hash_table.h" />
     <ClInclude Include="..\..\src\core\statistics\window_stats.h" />
     <ClInclude Include="..\..\src\core\surface\call.h" />
diff --git a/vsprojects/vs2013/grpc_unsecure.vcxproj b/vsprojects/vs2013/grpc_unsecure.vcxproj
index 6cc5a8b2932938636a195057f81821a90a19e123..294b73f155e28a0c442796759040de260f1d722c 100644
--- a/vsprojects/vs2013/grpc_unsecure.vcxproj
+++ b/vsprojects/vs2013/grpc_unsecure.vcxproj
@@ -134,6 +134,7 @@
     <ClInclude Include="..\..\src\core\statistics\census_interface.h" />
     <ClInclude Include="..\..\src\core\statistics\census_log.h" />
     <ClInclude Include="..\..\src\core\statistics\census_rpc_stats.h" />
+    <ClInclude Include="..\..\src\core\statistics\census_tracing.h" />
     <ClInclude Include="..\..\src\core\statistics\hash_table.h" />
     <ClInclude Include="..\..\src\core\statistics\window_stats.h" />
     <ClInclude Include="..\..\src\core\surface\call.h" />