Merge pull request #1758 from dgquintas/iomgr_managed_cbs

Revamped iomgr's callback mechanism
diff --git a/BUILD b/BUILD
index 6229cf2..8b8072e 100644
--- a/BUILD
+++ b/BUILD
@@ -143,7 +143,7 @@
     "src/core/tsi/ssl_transport_security.h",
     "src/core/tsi/transport_security.h",
     "src/core/tsi/transport_security_interface.h",
-    "src/core/channel/census_filter.h",
+    "src/core/census/grpc_context.h",
     "src/core/channel/channel_args.h",
     "src/core/channel/channel_stack.h",
     "src/core/channel/child_channel.h",
@@ -192,12 +192,6 @@
     "src/core/json/json_writer.h",
     "src/core/profiling/timers.h",
     "src/core/profiling/timers_preciseclock.h",
-    "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/byte_buffer_queue.h",
     "src/core/surface/call.h",
     "src/core/surface/channel.h",
@@ -230,6 +224,7 @@
     "src/core/transport/stream_op.h",
     "src/core/transport/transport.h",
     "src/core/transport/transport_impl.h",
+    "src/core/census/context.h",
     "src/core/httpcli/format_request.c",
     "src/core/httpcli/httpcli.c",
     "src/core/httpcli/httpcli_security_connector.c",
@@ -253,7 +248,7 @@
     "src/core/tsi/fake_transport_security.c",
     "src/core/tsi/ssl_transport_security.c",
     "src/core/tsi/transport_security.c",
-    "src/core/channel/census_filter.c",
+    "src/core/census/grpc_context.c",
     "src/core/channel/channel_args.c",
     "src/core/channel/channel_stack.c",
     "src/core/channel/child_channel.c",
@@ -305,12 +300,6 @@
     "src/core/json/json_writer.c",
     "src/core/profiling/basic_timers.c",
     "src/core/profiling/stap_timers.c",
-    "src/core/statistics/census_init.c",
-    "src/core/statistics/census_log.c",
-    "src/core/statistics/census_rpc_stats.c",
-    "src/core/statistics/census_tracing.c",
-    "src/core/statistics/hash_table.c",
-    "src/core/statistics/window_stats.c",
     "src/core/surface/byte_buffer.c",
     "src/core/surface/byte_buffer_queue.c",
     "src/core/surface/byte_buffer_reader.c",
@@ -350,6 +339,8 @@
     "src/core/transport/stream_op.c",
     "src/core/transport/transport.c",
     "src/core/transport/transport_op_string.c",
+    "src/core/census/context.c",
+    "src/core/census/initialize.c",
   ],
   hdrs = [
     "include/grpc/grpc_security.h",
@@ -357,6 +348,7 @@
     "include/grpc/byte_buffer_reader.h",
     "include/grpc/grpc.h",
     "include/grpc/status.h",
+    "include/grpc/census.h",
   ],
   includes = [
     "include",
@@ -372,7 +364,7 @@
 cc_library(
   name = "grpc_unsecure",
   srcs = [
-    "src/core/channel/census_filter.h",
+    "src/core/census/grpc_context.h",
     "src/core/channel/channel_args.h",
     "src/core/channel/channel_stack.h",
     "src/core/channel/child_channel.h",
@@ -421,12 +413,6 @@
     "src/core/json/json_writer.h",
     "src/core/profiling/timers.h",
     "src/core/profiling/timers_preciseclock.h",
-    "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/byte_buffer_queue.h",
     "src/core/surface/call.h",
     "src/core/surface/channel.h",
@@ -459,8 +445,9 @@
     "src/core/transport/stream_op.h",
     "src/core/transport/transport.h",
     "src/core/transport/transport_impl.h",
+    "src/core/census/context.h",
     "src/core/surface/init_unsecure.c",
-    "src/core/channel/census_filter.c",
+    "src/core/census/grpc_context.c",
     "src/core/channel/channel_args.c",
     "src/core/channel/channel_stack.c",
     "src/core/channel/child_channel.c",
@@ -512,12 +499,6 @@
     "src/core/json/json_writer.c",
     "src/core/profiling/basic_timers.c",
     "src/core/profiling/stap_timers.c",
-    "src/core/statistics/census_init.c",
-    "src/core/statistics/census_log.c",
-    "src/core/statistics/census_rpc_stats.c",
-    "src/core/statistics/census_tracing.c",
-    "src/core/statistics/hash_table.c",
-    "src/core/statistics/window_stats.c",
     "src/core/surface/byte_buffer.c",
     "src/core/surface/byte_buffer_queue.c",
     "src/core/surface/byte_buffer_reader.c",
@@ -557,12 +538,15 @@
     "src/core/transport/stream_op.c",
     "src/core/transport/transport.c",
     "src/core/transport/transport_op_string.c",
+    "src/core/census/context.c",
+    "src/core/census/initialize.c",
   ],
   hdrs = [
     "include/grpc/byte_buffer.h",
     "include/grpc/byte_buffer_reader.h",
     "include/grpc/grpc.h",
     "include/grpc/status.h",
+    "include/grpc/census.h",
   ],
   includes = [
     "include",
diff --git a/Makefile b/Makefile
index dfdce1d..647847f 100644
--- a/Makefile
+++ b/Makefile
@@ -595,16 +595,6 @@
 alarm_test: $(BINDIR)/$(CONFIG)/alarm_test
 alpn_test: $(BINDIR)/$(CONFIG)/alpn_test
 bin_encoder_test: $(BINDIR)/$(CONFIG)/bin_encoder_test
-census_hash_table_test: $(BINDIR)/$(CONFIG)/census_hash_table_test
-census_statistics_multiple_writers_circular_buffer_test: $(BINDIR)/$(CONFIG)/census_statistics_multiple_writers_circular_buffer_test
-census_statistics_multiple_writers_test: $(BINDIR)/$(CONFIG)/census_statistics_multiple_writers_test
-census_statistics_performance_test: $(BINDIR)/$(CONFIG)/census_statistics_performance_test
-census_statistics_quick_test: $(BINDIR)/$(CONFIG)/census_statistics_quick_test
-census_statistics_small_log_test: $(BINDIR)/$(CONFIG)/census_statistics_small_log_test
-census_stats_store_test: $(BINDIR)/$(CONFIG)/census_stats_store_test
-census_stub_test: $(BINDIR)/$(CONFIG)/census_stub_test
-census_trace_store_test: $(BINDIR)/$(CONFIG)/census_trace_store_test
-census_window_stats_test: $(BINDIR)/$(CONFIG)/census_window_stats_test
 chttp2_status_conversion_test: $(BINDIR)/$(CONFIG)/chttp2_status_conversion_test
 chttp2_stream_encoder_test: $(BINDIR)/$(CONFIG)/chttp2_stream_encoder_test
 chttp2_stream_map_test: $(BINDIR)/$(CONFIG)/chttp2_stream_map_test
@@ -1249,7 +1239,7 @@
 
 buildtests: buildtests_c buildtests_cxx
 
-buildtests_c: privatelibs_c $(BINDIR)/$(CONFIG)/alarm_heap_test $(BINDIR)/$(CONFIG)/alarm_list_test $(BINDIR)/$(CONFIG)/alarm_test $(BINDIR)/$(CONFIG)/alpn_test $(BINDIR)/$(CONFIG)/bin_encoder_test $(BINDIR)/$(CONFIG)/census_hash_table_test $(BINDIR)/$(CONFIG)/census_statistics_multiple_writers_circular_buffer_test $(BINDIR)/$(CONFIG)/census_statistics_multiple_writers_test $(BINDIR)/$(CONFIG)/census_statistics_performance_test $(BINDIR)/$(CONFIG)/census_statistics_quick_test $(BINDIR)/$(CONFIG)/census_statistics_small_log_test $(BINDIR)/$(CONFIG)/census_stub_test $(BINDIR)/$(CONFIG)/census_window_stats_test $(BINDIR)/$(CONFIG)/chttp2_status_conversion_test $(BINDIR)/$(CONFIG)/chttp2_stream_encoder_test $(BINDIR)/$(CONFIG)/chttp2_stream_map_test $(BINDIR)/$(CONFIG)/dualstack_socket_test $(BINDIR)/$(CONFIG)/fd_posix_test $(BINDIR)/$(CONFIG)/fling_client $(BINDIR)/$(CONFIG)/fling_server $(BINDIR)/$(CONFIG)/fling_stream_test $(BINDIR)/$(CONFIG)/fling_test $(BINDIR)/$(CONFIG)/gpr_cancellable_test $(BINDIR)/$(CONFIG)/gpr_cmdline_test $(BINDIR)/$(CONFIG)/gpr_env_test $(BINDIR)/$(CONFIG)/gpr_file_test $(BINDIR)/$(CONFIG)/gpr_histogram_test $(BINDIR)/$(CONFIG)/gpr_host_port_test $(BINDIR)/$(CONFIG)/gpr_log_test $(BINDIR)/$(CONFIG)/gpr_slice_buffer_test $(BINDIR)/$(CONFIG)/gpr_slice_test $(BINDIR)/$(CONFIG)/gpr_string_test $(BINDIR)/$(CONFIG)/gpr_sync_test $(BINDIR)/$(CONFIG)/gpr_thd_test $(BINDIR)/$(CONFIG)/gpr_time_test $(BINDIR)/$(CONFIG)/gpr_tls_test $(BINDIR)/$(CONFIG)/gpr_useful_test $(BINDIR)/$(CONFIG)/grpc_auth_context_test $(BINDIR)/$(CONFIG)/grpc_base64_test $(BINDIR)/$(CONFIG)/grpc_byte_buffer_reader_test $(BINDIR)/$(CONFIG)/grpc_channel_stack_test $(BINDIR)/$(CONFIG)/grpc_completion_queue_test $(BINDIR)/$(CONFIG)/grpc_credentials_test $(BINDIR)/$(CONFIG)/grpc_json_token_test $(BINDIR)/$(CONFIG)/grpc_stream_op_test $(BINDIR)/$(CONFIG)/hpack_parser_test $(BINDIR)/$(CONFIG)/hpack_table_test $(BINDIR)/$(CONFIG)/httpcli_format_request_test $(BINDIR)/$(CONFIG)/httpcli_parser_test $(BINDIR)/$(CONFIG)/httpcli_test $(BINDIR)/$(CONFIG)/json_rewrite $(BINDIR)/$(CONFIG)/json_rewrite_test $(BINDIR)/$(CONFIG)/json_test $(BINDIR)/$(CONFIG)/lame_client_test $(BINDIR)/$(CONFIG)/message_compress_test $(BINDIR)/$(CONFIG)/multi_init_test $(BINDIR)/$(CONFIG)/murmur_hash_test $(BINDIR)/$(CONFIG)/no_server_test $(BINDIR)/$(CONFIG)/poll_kick_posix_test $(BINDIR)/$(CONFIG)/resolve_address_test $(BINDIR)/$(CONFIG)/secure_endpoint_test $(BINDIR)/$(CONFIG)/sockaddr_utils_test $(BINDIR)/$(CONFIG)/tcp_client_posix_test $(BINDIR)/$(CONFIG)/tcp_posix_test $(BINDIR)/$(CONFIG)/tcp_server_posix_test $(BINDIR)/$(CONFIG)/time_averaged_stats_test $(BINDIR)/$(CONFIG)/time_test $(BINDIR)/$(CONFIG)/timeout_encoding_test $(BINDIR)/$(CONFIG)/timers_test $(BINDIR)/$(CONFIG)/transport_metadata_test $(BINDIR)/$(CONFIG)/transport_security_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_bad_hostname_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_after_accept_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_after_accept_and_writes_closed_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_census_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_disappearing_server_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_early_server_shutdown_finishes_inflight_calls_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_early_server_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_empty_batch_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_invoke_large_request_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_max_message_length_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_no_op_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_registered_call_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_response_with_binary_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_response_with_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_response_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_response_with_payload_and_call_creds_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_response_with_trailing_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_with_large_metadata_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_server_finishes_request_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_simple_delayed_request_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_simple_request_with_high_initial_sequence_number_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_bad_hostname_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_after_accept_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_after_accept_and_writes_closed_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_census_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_disappearing_server_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_early_server_shutdown_finishes_inflight_calls_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_early_server_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_empty_batch_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_invoke_large_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_max_message_length_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_no_op_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_registered_call_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_response_with_binary_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_response_with_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_response_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_response_with_payload_and_call_creds_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_response_with_trailing_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_with_large_metadata_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_server_finishes_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_simple_delayed_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_simple_request_with_high_initial_sequence_number_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_bad_hostname_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_cancel_after_accept_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_cancel_after_accept_and_writes_closed_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_census_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_disappearing_server_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_early_server_shutdown_finishes_inflight_calls_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_early_server_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_empty_batch_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_invoke_large_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_max_message_length_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_no_op_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_registered_call_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_request_response_with_binary_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_request_response_with_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_request_response_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_request_response_with_payload_and_call_creds_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_request_response_with_trailing_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_request_with_large_metadata_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_request_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_server_finishes_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_simple_delayed_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_simple_request_with_high_initial_sequence_number_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_bad_hostname_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_cancel_after_accept_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_cancel_after_accept_and_writes_closed_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_census_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_disappearing_server_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_early_server_shutdown_finishes_inflight_calls_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_early_server_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_empty_batch_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_invoke_large_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_max_message_length_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_no_op_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_registered_call_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_request_response_with_binary_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_request_response_with_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_request_response_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_request_response_with_payload_and_call_creds_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_request_response_with_trailing_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_request_with_large_metadata_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_request_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_server_finishes_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_simple_delayed_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_simple_request_with_high_initial_sequence_number_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_bad_hostname_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_after_accept_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_after_accept_and_writes_closed_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_census_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_disappearing_server_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_inflight_calls_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_empty_batch_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_invoke_large_request_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_max_message_length_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_no_op_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_registered_call_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_response_with_binary_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_response_with_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_response_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_response_with_payload_and_call_creds_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_response_with_trailing_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_with_large_metadata_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_server_finishes_request_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_simple_delayed_request_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_simple_request_with_high_initial_sequence_number_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_with_poll_bad_hostname_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_with_poll_cancel_after_accept_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_with_poll_cancel_after_accept_and_writes_closed_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_with_poll_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_with_poll_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_with_poll_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_with_poll_census_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_with_poll_disappearing_server_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_with_poll_early_server_shutdown_finishes_inflight_calls_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_with_poll_early_server_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_with_poll_empty_batch_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_with_poll_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_with_poll_invoke_large_request_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_with_poll_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_with_poll_max_message_length_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_with_poll_no_op_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_with_poll_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_with_poll_registered_call_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_with_poll_request_response_with_binary_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_with_poll_request_response_with_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_with_poll_request_response_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_with_poll_request_response_with_payload_and_call_creds_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_with_poll_request_response_with_trailing_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_with_poll_request_with_large_metadata_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_with_poll_request_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_with_poll_server_finishes_request_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_with_poll_simple_delayed_request_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_with_poll_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_with_poll_simple_request_with_high_initial_sequence_number_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_bad_hostname_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_accept_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_accept_and_writes_closed_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_census_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_disappearing_server_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_inflight_calls_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_empty_batch_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_invoke_large_request_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_max_message_length_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_no_op_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_registered_call_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_binary_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_payload_and_call_creds_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_trailing_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_with_large_metadata_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_server_finishes_request_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_simple_delayed_request_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_simple_request_with_high_initial_sequence_number_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_bad_hostname_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_after_accept_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_after_accept_and_writes_closed_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_census_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_disappearing_server_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_early_server_shutdown_finishes_inflight_calls_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_early_server_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_empty_batch_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_invoke_large_request_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_max_message_length_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_no_op_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_registered_call_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_response_with_binary_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_response_with_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_response_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_response_with_payload_and_call_creds_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_response_with_trailing_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_with_large_metadata_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_server_finishes_request_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_simple_delayed_request_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_simple_request_with_high_initial_sequence_number_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_bad_hostname_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_and_writes_closed_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_census_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_disappearing_server_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_inflight_calls_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_empty_batch_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_invoke_large_request_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_max_message_length_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_no_op_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_registered_call_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_response_with_binary_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_response_with_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_response_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_response_with_payload_and_call_creds_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_response_with_trailing_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_with_large_metadata_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_server_finishes_request_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_simple_delayed_request_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_simple_request_with_high_initial_sequence_number_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_bad_hostname_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_cancel_after_accept_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_cancel_after_accept_and_writes_closed_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_census_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_disappearing_server_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_early_server_shutdown_finishes_inflight_calls_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_early_server_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_empty_batch_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_invoke_large_request_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_max_message_length_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_no_op_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_registered_call_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_request_response_with_binary_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_request_response_with_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_request_response_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_request_response_with_payload_and_call_creds_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_request_response_with_trailing_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_request_with_large_metadata_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_request_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_server_finishes_request_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_simple_delayed_request_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_simple_request_with_high_initial_sequence_number_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_bad_hostname_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_after_accept_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_after_accept_and_writes_closed_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_after_invoke_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_before_invoke_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_in_a_vacuum_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_census_simple_request_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_disappearing_server_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_early_server_shutdown_finishes_inflight_calls_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_early_server_shutdown_finishes_tags_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_empty_batch_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_graceful_server_shutdown_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_invoke_large_request_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_max_concurrent_streams_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_max_message_length_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_no_op_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_ping_pong_streaming_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_registered_call_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_response_with_binary_metadata_and_payload_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_response_with_metadata_and_payload_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_response_with_payload_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_response_with_trailing_metadata_and_payload_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_with_large_metadata_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_with_payload_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_server_finishes_request_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_simple_delayed_request_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_simple_request_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_simple_request_with_high_initial_sequence_number_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_bad_hostname_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_cancel_after_accept_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_cancel_after_accept_and_writes_closed_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_cancel_after_invoke_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_cancel_before_invoke_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_cancel_in_a_vacuum_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_census_simple_request_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_disappearing_server_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_early_server_shutdown_finishes_inflight_calls_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_early_server_shutdown_finishes_tags_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_empty_batch_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_graceful_server_shutdown_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_invoke_large_request_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_max_concurrent_streams_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_max_message_length_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_no_op_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_ping_pong_streaming_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_registered_call_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_request_response_with_binary_metadata_and_payload_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_request_response_with_metadata_and_payload_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_request_response_with_payload_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_request_response_with_trailing_metadata_and_payload_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_request_with_large_metadata_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_request_with_payload_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_server_finishes_request_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_simple_delayed_request_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_simple_request_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_simple_request_with_high_initial_sequence_number_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_bad_hostname_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_cancel_after_accept_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_cancel_after_accept_and_writes_closed_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_cancel_after_invoke_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_cancel_before_invoke_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_cancel_in_a_vacuum_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_census_simple_request_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_disappearing_server_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_early_server_shutdown_finishes_inflight_calls_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_early_server_shutdown_finishes_tags_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_empty_batch_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_graceful_server_shutdown_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_invoke_large_request_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_max_concurrent_streams_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_max_message_length_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_no_op_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_ping_pong_streaming_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_registered_call_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_request_response_with_binary_metadata_and_payload_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_request_response_with_metadata_and_payload_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_request_response_with_payload_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_request_response_with_trailing_metadata_and_payload_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_request_with_large_metadata_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_request_with_payload_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_server_finishes_request_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_simple_delayed_request_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_simple_request_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_simple_request_with_high_initial_sequence_number_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_bad_hostname_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_after_accept_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_after_accept_and_writes_closed_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_after_invoke_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_before_invoke_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_in_a_vacuum_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_census_simple_request_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_disappearing_server_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_early_server_shutdown_finishes_inflight_calls_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_early_server_shutdown_finishes_tags_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_empty_batch_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_graceful_server_shutdown_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_invoke_large_request_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_max_concurrent_streams_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_max_message_length_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_no_op_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_ping_pong_streaming_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_registered_call_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_response_with_binary_metadata_and_payload_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_response_with_metadata_and_payload_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_response_with_payload_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_response_with_trailing_metadata_and_payload_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_with_large_metadata_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_with_payload_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_server_finishes_request_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_simple_delayed_request_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_simple_request_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_simple_request_with_high_initial_sequence_number_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_bad_hostname_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_and_writes_closed_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_after_invoke_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_before_invoke_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_in_a_vacuum_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_census_simple_request_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_disappearing_server_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_inflight_calls_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_tags_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_empty_batch_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_graceful_server_shutdown_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_invoke_large_request_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_max_concurrent_streams_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_max_message_length_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_no_op_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_ping_pong_streaming_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_registered_call_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_response_with_binary_metadata_and_payload_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_response_with_metadata_and_payload_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_response_with_payload_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_response_with_trailing_metadata_and_payload_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_with_large_metadata_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_with_payload_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_server_finishes_request_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_simple_delayed_request_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_simple_request_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_simple_request_with_high_initial_sequence_number_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_bad_hostname_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_cancel_after_accept_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_cancel_after_accept_and_writes_closed_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_cancel_after_invoke_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_cancel_before_invoke_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_cancel_in_a_vacuum_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_census_simple_request_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_disappearing_server_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_early_server_shutdown_finishes_inflight_calls_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_early_server_shutdown_finishes_tags_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_empty_batch_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_graceful_server_shutdown_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_invoke_large_request_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_max_concurrent_streams_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_max_message_length_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_no_op_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_ping_pong_streaming_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_registered_call_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_request_response_with_binary_metadata_and_payload_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_request_response_with_metadata_and_payload_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_request_response_with_payload_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_request_response_with_trailing_metadata_and_payload_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_request_with_large_metadata_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_request_with_payload_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_server_finishes_request_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_simple_delayed_request_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_simple_request_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_simple_request_with_high_initial_sequence_number_unsecure_test $(BINDIR)/$(CONFIG)/connection_prefix_bad_client_test
+buildtests_c: privatelibs_c $(BINDIR)/$(CONFIG)/alarm_heap_test $(BINDIR)/$(CONFIG)/alarm_list_test $(BINDIR)/$(CONFIG)/alarm_test $(BINDIR)/$(CONFIG)/alpn_test $(BINDIR)/$(CONFIG)/bin_encoder_test $(BINDIR)/$(CONFIG)/chttp2_status_conversion_test $(BINDIR)/$(CONFIG)/chttp2_stream_encoder_test $(BINDIR)/$(CONFIG)/chttp2_stream_map_test $(BINDIR)/$(CONFIG)/dualstack_socket_test $(BINDIR)/$(CONFIG)/fd_posix_test $(BINDIR)/$(CONFIG)/fling_client $(BINDIR)/$(CONFIG)/fling_server $(BINDIR)/$(CONFIG)/fling_stream_test $(BINDIR)/$(CONFIG)/fling_test $(BINDIR)/$(CONFIG)/gpr_cancellable_test $(BINDIR)/$(CONFIG)/gpr_cmdline_test $(BINDIR)/$(CONFIG)/gpr_env_test $(BINDIR)/$(CONFIG)/gpr_file_test $(BINDIR)/$(CONFIG)/gpr_histogram_test $(BINDIR)/$(CONFIG)/gpr_host_port_test $(BINDIR)/$(CONFIG)/gpr_log_test $(BINDIR)/$(CONFIG)/gpr_slice_buffer_test $(BINDIR)/$(CONFIG)/gpr_slice_test $(BINDIR)/$(CONFIG)/gpr_string_test $(BINDIR)/$(CONFIG)/gpr_sync_test $(BINDIR)/$(CONFIG)/gpr_thd_test $(BINDIR)/$(CONFIG)/gpr_time_test $(BINDIR)/$(CONFIG)/gpr_tls_test $(BINDIR)/$(CONFIG)/gpr_useful_test $(BINDIR)/$(CONFIG)/grpc_auth_context_test $(BINDIR)/$(CONFIG)/grpc_base64_test $(BINDIR)/$(CONFIG)/grpc_byte_buffer_reader_test $(BINDIR)/$(CONFIG)/grpc_channel_stack_test $(BINDIR)/$(CONFIG)/grpc_completion_queue_test $(BINDIR)/$(CONFIG)/grpc_credentials_test $(BINDIR)/$(CONFIG)/grpc_json_token_test $(BINDIR)/$(CONFIG)/grpc_stream_op_test $(BINDIR)/$(CONFIG)/hpack_parser_test $(BINDIR)/$(CONFIG)/hpack_table_test $(BINDIR)/$(CONFIG)/httpcli_format_request_test $(BINDIR)/$(CONFIG)/httpcli_parser_test $(BINDIR)/$(CONFIG)/httpcli_test $(BINDIR)/$(CONFIG)/json_rewrite $(BINDIR)/$(CONFIG)/json_rewrite_test $(BINDIR)/$(CONFIG)/json_test $(BINDIR)/$(CONFIG)/lame_client_test $(BINDIR)/$(CONFIG)/message_compress_test $(BINDIR)/$(CONFIG)/multi_init_test $(BINDIR)/$(CONFIG)/murmur_hash_test $(BINDIR)/$(CONFIG)/no_server_test $(BINDIR)/$(CONFIG)/poll_kick_posix_test $(BINDIR)/$(CONFIG)/resolve_address_test $(BINDIR)/$(CONFIG)/secure_endpoint_test $(BINDIR)/$(CONFIG)/sockaddr_utils_test $(BINDIR)/$(CONFIG)/tcp_client_posix_test $(BINDIR)/$(CONFIG)/tcp_posix_test $(BINDIR)/$(CONFIG)/tcp_server_posix_test $(BINDIR)/$(CONFIG)/time_averaged_stats_test $(BINDIR)/$(CONFIG)/time_test $(BINDIR)/$(CONFIG)/timeout_encoding_test $(BINDIR)/$(CONFIG)/timers_test $(BINDIR)/$(CONFIG)/transport_metadata_test $(BINDIR)/$(CONFIG)/transport_security_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_bad_hostname_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_after_accept_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_after_accept_and_writes_closed_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_census_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_disappearing_server_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_early_server_shutdown_finishes_inflight_calls_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_early_server_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_empty_batch_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_invoke_large_request_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_max_message_length_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_no_op_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_registered_call_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_response_with_binary_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_response_with_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_response_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_response_with_payload_and_call_creds_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_response_with_trailing_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_with_large_metadata_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_server_finishes_request_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_simple_delayed_request_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_simple_request_with_high_initial_sequence_number_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_bad_hostname_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_after_accept_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_after_accept_and_writes_closed_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_census_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_disappearing_server_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_early_server_shutdown_finishes_inflight_calls_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_early_server_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_empty_batch_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_invoke_large_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_max_message_length_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_no_op_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_registered_call_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_response_with_binary_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_response_with_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_response_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_response_with_payload_and_call_creds_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_response_with_trailing_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_with_large_metadata_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_server_finishes_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_simple_delayed_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_simple_request_with_high_initial_sequence_number_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_bad_hostname_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_cancel_after_accept_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_cancel_after_accept_and_writes_closed_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_census_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_disappearing_server_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_early_server_shutdown_finishes_inflight_calls_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_early_server_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_empty_batch_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_invoke_large_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_max_message_length_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_no_op_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_registered_call_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_request_response_with_binary_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_request_response_with_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_request_response_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_request_response_with_payload_and_call_creds_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_request_response_with_trailing_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_request_with_large_metadata_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_request_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_server_finishes_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_simple_delayed_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_simple_request_with_high_initial_sequence_number_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_bad_hostname_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_cancel_after_accept_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_cancel_after_accept_and_writes_closed_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_census_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_disappearing_server_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_early_server_shutdown_finishes_inflight_calls_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_early_server_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_empty_batch_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_invoke_large_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_max_message_length_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_no_op_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_registered_call_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_request_response_with_binary_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_request_response_with_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_request_response_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_request_response_with_payload_and_call_creds_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_request_response_with_trailing_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_request_with_large_metadata_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_request_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_server_finishes_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_simple_delayed_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_simple_request_with_high_initial_sequence_number_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_bad_hostname_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_after_accept_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_after_accept_and_writes_closed_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_census_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_disappearing_server_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_inflight_calls_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_empty_batch_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_invoke_large_request_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_max_message_length_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_no_op_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_registered_call_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_response_with_binary_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_response_with_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_response_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_response_with_payload_and_call_creds_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_response_with_trailing_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_with_large_metadata_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_server_finishes_request_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_simple_delayed_request_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_simple_request_with_high_initial_sequence_number_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_with_poll_bad_hostname_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_with_poll_cancel_after_accept_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_with_poll_cancel_after_accept_and_writes_closed_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_with_poll_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_with_poll_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_with_poll_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_with_poll_census_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_with_poll_disappearing_server_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_with_poll_early_server_shutdown_finishes_inflight_calls_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_with_poll_early_server_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_with_poll_empty_batch_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_with_poll_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_with_poll_invoke_large_request_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_with_poll_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_with_poll_max_message_length_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_with_poll_no_op_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_with_poll_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_with_poll_registered_call_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_with_poll_request_response_with_binary_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_with_poll_request_response_with_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_with_poll_request_response_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_with_poll_request_response_with_payload_and_call_creds_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_with_poll_request_response_with_trailing_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_with_poll_request_with_large_metadata_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_with_poll_request_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_with_poll_server_finishes_request_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_with_poll_simple_delayed_request_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_with_poll_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_with_poll_simple_request_with_high_initial_sequence_number_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_bad_hostname_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_accept_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_accept_and_writes_closed_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_census_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_disappearing_server_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_inflight_calls_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_empty_batch_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_invoke_large_request_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_max_message_length_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_no_op_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_registered_call_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_binary_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_payload_and_call_creds_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_trailing_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_with_large_metadata_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_server_finishes_request_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_simple_delayed_request_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_simple_request_with_high_initial_sequence_number_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_bad_hostname_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_after_accept_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_after_accept_and_writes_closed_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_census_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_disappearing_server_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_early_server_shutdown_finishes_inflight_calls_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_early_server_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_empty_batch_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_invoke_large_request_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_max_message_length_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_no_op_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_registered_call_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_response_with_binary_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_response_with_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_response_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_response_with_payload_and_call_creds_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_response_with_trailing_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_with_large_metadata_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_server_finishes_request_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_simple_delayed_request_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_simple_request_with_high_initial_sequence_number_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_bad_hostname_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_and_writes_closed_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_census_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_disappearing_server_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_inflight_calls_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_empty_batch_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_invoke_large_request_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_max_message_length_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_no_op_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_registered_call_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_response_with_binary_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_response_with_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_response_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_response_with_payload_and_call_creds_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_response_with_trailing_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_with_large_metadata_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_server_finishes_request_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_simple_delayed_request_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_simple_request_with_high_initial_sequence_number_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_bad_hostname_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_cancel_after_accept_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_cancel_after_accept_and_writes_closed_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_census_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_disappearing_server_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_early_server_shutdown_finishes_inflight_calls_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_early_server_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_empty_batch_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_invoke_large_request_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_max_message_length_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_no_op_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_registered_call_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_request_response_with_binary_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_request_response_with_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_request_response_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_request_response_with_payload_and_call_creds_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_request_response_with_trailing_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_request_with_large_metadata_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_request_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_server_finishes_request_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_simple_delayed_request_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_simple_request_with_high_initial_sequence_number_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_bad_hostname_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_after_accept_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_after_accept_and_writes_closed_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_after_invoke_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_before_invoke_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_in_a_vacuum_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_census_simple_request_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_disappearing_server_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_early_server_shutdown_finishes_inflight_calls_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_early_server_shutdown_finishes_tags_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_empty_batch_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_graceful_server_shutdown_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_invoke_large_request_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_max_concurrent_streams_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_max_message_length_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_no_op_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_ping_pong_streaming_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_registered_call_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_response_with_binary_metadata_and_payload_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_response_with_metadata_and_payload_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_response_with_payload_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_response_with_trailing_metadata_and_payload_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_with_large_metadata_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_with_payload_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_server_finishes_request_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_simple_delayed_request_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_simple_request_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_simple_request_with_high_initial_sequence_number_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_bad_hostname_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_cancel_after_accept_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_cancel_after_accept_and_writes_closed_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_cancel_after_invoke_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_cancel_before_invoke_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_cancel_in_a_vacuum_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_census_simple_request_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_disappearing_server_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_early_server_shutdown_finishes_inflight_calls_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_early_server_shutdown_finishes_tags_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_empty_batch_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_graceful_server_shutdown_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_invoke_large_request_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_max_concurrent_streams_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_max_message_length_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_no_op_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_ping_pong_streaming_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_registered_call_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_request_response_with_binary_metadata_and_payload_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_request_response_with_metadata_and_payload_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_request_response_with_payload_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_request_response_with_trailing_metadata_and_payload_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_request_with_large_metadata_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_request_with_payload_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_server_finishes_request_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_simple_delayed_request_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_simple_request_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_posix_simple_request_with_high_initial_sequence_number_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_bad_hostname_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_cancel_after_accept_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_cancel_after_accept_and_writes_closed_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_cancel_after_invoke_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_cancel_before_invoke_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_cancel_in_a_vacuum_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_census_simple_request_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_disappearing_server_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_early_server_shutdown_finishes_inflight_calls_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_early_server_shutdown_finishes_tags_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_empty_batch_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_graceful_server_shutdown_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_invoke_large_request_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_max_concurrent_streams_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_max_message_length_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_no_op_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_ping_pong_streaming_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_registered_call_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_request_response_with_binary_metadata_and_payload_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_request_response_with_metadata_and_payload_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_request_response_with_payload_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_request_response_with_trailing_metadata_and_payload_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_request_with_large_metadata_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_request_with_payload_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_server_finishes_request_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_simple_delayed_request_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_simple_request_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_with_poll_simple_request_with_high_initial_sequence_number_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_bad_hostname_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_after_accept_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_after_accept_and_writes_closed_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_after_invoke_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_before_invoke_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_in_a_vacuum_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_census_simple_request_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_disappearing_server_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_early_server_shutdown_finishes_inflight_calls_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_early_server_shutdown_finishes_tags_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_empty_batch_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_graceful_server_shutdown_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_invoke_large_request_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_max_concurrent_streams_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_max_message_length_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_no_op_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_ping_pong_streaming_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_registered_call_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_response_with_binary_metadata_and_payload_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_response_with_metadata_and_payload_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_response_with_payload_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_response_with_trailing_metadata_and_payload_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_with_large_metadata_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_with_payload_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_server_finishes_request_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_simple_delayed_request_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_simple_request_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_simple_request_with_high_initial_sequence_number_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_bad_hostname_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_and_writes_closed_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_after_invoke_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_before_invoke_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_in_a_vacuum_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_census_simple_request_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_disappearing_server_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_inflight_calls_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_tags_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_empty_batch_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_graceful_server_shutdown_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_invoke_large_request_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_max_concurrent_streams_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_max_message_length_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_no_op_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_ping_pong_streaming_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_registered_call_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_response_with_binary_metadata_and_payload_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_response_with_metadata_and_payload_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_response_with_payload_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_response_with_trailing_metadata_and_payload_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_with_large_metadata_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_with_payload_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_server_finishes_request_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_simple_delayed_request_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_simple_request_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_simple_request_with_high_initial_sequence_number_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_bad_hostname_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_cancel_after_accept_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_cancel_after_accept_and_writes_closed_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_cancel_after_invoke_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_cancel_before_invoke_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_cancel_in_a_vacuum_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_census_simple_request_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_disappearing_server_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_early_server_shutdown_finishes_inflight_calls_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_early_server_shutdown_finishes_tags_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_empty_batch_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_graceful_server_shutdown_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_invoke_large_request_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_max_concurrent_streams_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_max_message_length_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_no_op_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_ping_pong_streaming_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_registered_call_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_request_response_with_binary_metadata_and_payload_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_request_response_with_metadata_and_payload_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_request_response_with_payload_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_request_response_with_trailing_metadata_and_payload_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_request_with_large_metadata_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_request_with_payload_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_server_finishes_request_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_simple_delayed_request_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_simple_request_unsecure_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_with_grpc_trace_simple_request_with_high_initial_sequence_number_unsecure_test $(BINDIR)/$(CONFIG)/connection_prefix_bad_client_test
 
 buildtests_cxx: privatelibs_cxx $(BINDIR)/$(CONFIG)/async_end2end_test $(BINDIR)/$(CONFIG)/async_streaming_ping_pong_test $(BINDIR)/$(CONFIG)/async_unary_ping_pong_test $(BINDIR)/$(CONFIG)/channel_arguments_test $(BINDIR)/$(CONFIG)/cli_call_test $(BINDIR)/$(CONFIG)/client_crash_test $(BINDIR)/$(CONFIG)/client_crash_test_server $(BINDIR)/$(CONFIG)/credentials_test $(BINDIR)/$(CONFIG)/cxx_time_test $(BINDIR)/$(CONFIG)/end2end_test $(BINDIR)/$(CONFIG)/generic_end2end_test $(BINDIR)/$(CONFIG)/grpc_cli $(BINDIR)/$(CONFIG)/interop_client $(BINDIR)/$(CONFIG)/interop_server $(BINDIR)/$(CONFIG)/interop_test $(BINDIR)/$(CONFIG)/mock_test $(BINDIR)/$(CONFIG)/server_crash_test $(BINDIR)/$(CONFIG)/server_crash_test_client $(BINDIR)/$(CONFIG)/status_test $(BINDIR)/$(CONFIG)/sync_streaming_ping_pong_test $(BINDIR)/$(CONFIG)/sync_unary_ping_pong_test $(BINDIR)/$(CONFIG)/thread_pool_test $(BINDIR)/$(CONFIG)/thread_stress_test
 
@@ -1268,20 +1258,6 @@
 	$(Q) $(BINDIR)/$(CONFIG)/alpn_test || ( echo test alpn_test failed ; exit 1 )
 	$(E) "[RUN]     Testing bin_encoder_test"
 	$(Q) $(BINDIR)/$(CONFIG)/bin_encoder_test || ( echo test bin_encoder_test failed ; exit 1 )
-	$(E) "[RUN]     Testing census_hash_table_test"
-	$(Q) $(BINDIR)/$(CONFIG)/census_hash_table_test || ( echo test census_hash_table_test failed ; exit 1 )
-	$(E) "[RUN]     Testing census_statistics_multiple_writers_test"
-	$(Q) $(BINDIR)/$(CONFIG)/census_statistics_multiple_writers_test || ( echo test census_statistics_multiple_writers_test failed ; exit 1 )
-	$(E) "[RUN]     Testing census_statistics_performance_test"
-	$(Q) $(BINDIR)/$(CONFIG)/census_statistics_performance_test || ( echo test census_statistics_performance_test failed ; exit 1 )
-	$(E) "[RUN]     Testing census_statistics_quick_test"
-	$(Q) $(BINDIR)/$(CONFIG)/census_statistics_quick_test || ( echo test census_statistics_quick_test failed ; exit 1 )
-	$(E) "[RUN]     Testing census_statistics_small_log_test"
-	$(Q) $(BINDIR)/$(CONFIG)/census_statistics_small_log_test || ( echo test census_statistics_small_log_test failed ; exit 1 )
-	$(E) "[RUN]     Testing census_stub_test"
-	$(Q) $(BINDIR)/$(CONFIG)/census_stub_test || ( echo test census_stub_test failed ; exit 1 )
-	$(E) "[RUN]     Testing census_window_stats_test"
-	$(Q) $(BINDIR)/$(CONFIG)/census_window_stats_test || ( echo test census_window_stats_test failed ; exit 1 )
 	$(E) "[RUN]     Testing chttp2_status_conversion_test"
 	$(Q) $(BINDIR)/$(CONFIG)/chttp2_status_conversion_test || ( echo test chttp2_status_conversion_test failed ; exit 1 )
 	$(E) "[RUN]     Testing chttp2_stream_encoder_test"
@@ -2259,8 +2235,6 @@
 
 
 flaky_test_c: buildtests_c
-	$(E) "[RUN]     Testing census_statistics_multiple_writers_circular_buffer_test"
-	$(Q) $(BINDIR)/$(CONFIG)/census_statistics_multiple_writers_circular_buffer_test || ( echo test census_statistics_multiple_writers_circular_buffer_test failed ; exit 1 )
 	$(E) "[RUN]     Testing chttp2_fake_security_cancel_after_accept_test"
 	$(Q) $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_after_accept_test || ( echo test chttp2_fake_security_cancel_after_accept_test failed ; exit 1 )
 	$(E) "[RUN]     Testing chttp2_fake_security_invoke_large_request_test"
@@ -2958,7 +2932,7 @@
     src/core/tsi/fake_transport_security.c \
     src/core/tsi/ssl_transport_security.c \
     src/core/tsi/transport_security.c \
-    src/core/channel/census_filter.c \
+    src/core/census/grpc_context.c \
     src/core/channel/channel_args.c \
     src/core/channel/channel_stack.c \
     src/core/channel/child_channel.c \
@@ -3010,12 +2984,6 @@
     src/core/json/json_writer.c \
     src/core/profiling/basic_timers.c \
     src/core/profiling/stap_timers.c \
-    src/core/statistics/census_init.c \
-    src/core/statistics/census_log.c \
-    src/core/statistics/census_rpc_stats.c \
-    src/core/statistics/census_tracing.c \
-    src/core/statistics/hash_table.c \
-    src/core/statistics/window_stats.c \
     src/core/surface/byte_buffer.c \
     src/core/surface/byte_buffer_queue.c \
     src/core/surface/byte_buffer_reader.c \
@@ -3055,6 +3023,8 @@
     src/core/transport/stream_op.c \
     src/core/transport/transport.c \
     src/core/transport/transport_op_string.c \
+    src/core/census/context.c \
+    src/core/census/initialize.c \
 
 PUBLIC_HEADERS_C += \
     include/grpc/grpc_security.h \
@@ -3062,6 +3032,7 @@
     include/grpc/byte_buffer_reader.h \
     include/grpc/grpc.h \
     include/grpc/status.h \
+    include/grpc/census.h \
 
 LIBGRPC_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC_SRC))))
 
@@ -3131,7 +3102,6 @@
     test/core/end2end/data/test_root_cert.c \
     test/core/end2end/cq_verifier.c \
     test/core/iomgr/endpoint_tests.c \
-    test/core/statistics/census_log_tests.c \
     test/core/util/grpc_profiler.c \
     test/core/util/parse_hexstring.c \
     test/core/util/port_posix.c \
@@ -3176,7 +3146,6 @@
 LIBGRPC_TEST_UTIL_UNSECURE_SRC = \
     test/core/end2end/cq_verifier.c \
     test/core/iomgr/endpoint_tests.c \
-    test/core/statistics/census_log_tests.c \
     test/core/util/grpc_profiler.c \
     test/core/util/parse_hexstring.c \
     test/core/util/port_posix.c \
@@ -3206,7 +3175,7 @@
 
 LIBGRPC_UNSECURE_SRC = \
     src/core/surface/init_unsecure.c \
-    src/core/channel/census_filter.c \
+    src/core/census/grpc_context.c \
     src/core/channel/channel_args.c \
     src/core/channel/channel_stack.c \
     src/core/channel/child_channel.c \
@@ -3258,12 +3227,6 @@
     src/core/json/json_writer.c \
     src/core/profiling/basic_timers.c \
     src/core/profiling/stap_timers.c \
-    src/core/statistics/census_init.c \
-    src/core/statistics/census_log.c \
-    src/core/statistics/census_rpc_stats.c \
-    src/core/statistics/census_tracing.c \
-    src/core/statistics/hash_table.c \
-    src/core/statistics/window_stats.c \
     src/core/surface/byte_buffer.c \
     src/core/surface/byte_buffer_queue.c \
     src/core/surface/byte_buffer_reader.c \
@@ -3303,12 +3266,15 @@
     src/core/transport/stream_op.c \
     src/core/transport/transport.c \
     src/core/transport/transport_op_string.c \
+    src/core/census/context.c \
+    src/core/census/initialize.c \
 
 PUBLIC_HEADERS_C += \
     include/grpc/byte_buffer.h \
     include/grpc/byte_buffer_reader.h \
     include/grpc/grpc.h \
     include/grpc/status.h \
+    include/grpc/census.h \
 
 LIBGRPC_UNSECURE_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC_UNSECURE_SRC))))
 
@@ -5350,296 +5316,6 @@
 endif
 
 
-CENSUS_HASH_TABLE_TEST_SRC = \
-    test/core/statistics/hash_table_test.c \
-
-CENSUS_HASH_TABLE_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(CENSUS_HASH_TABLE_TEST_SRC))))
-ifeq ($(NO_SECURE),true)
-
-# You can't build secure targets if you don't have OpenSSL with ALPN.
-
-$(BINDIR)/$(CONFIG)/census_hash_table_test: openssl_dep_error
-
-else
-
-$(BINDIR)/$(CONFIG)/census_hash_table_test: $(CENSUS_HASH_TABLE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
-	$(E) "[LD]      Linking $@"
-	$(Q) mkdir -p `dirname $@`
-	$(Q) $(LD) $(LDFLAGS) $(CENSUS_HASH_TABLE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/census_hash_table_test
-
-endif
-
-$(OBJDIR)/$(CONFIG)/test/core/statistics/hash_table_test.o:  $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
-deps_census_hash_table_test: $(CENSUS_HASH_TABLE_TEST_OBJS:.o=.dep)
-
-ifneq ($(NO_SECURE),true)
-ifneq ($(NO_DEPS),true)
--include $(CENSUS_HASH_TABLE_TEST_OBJS:.o=.dep)
-endif
-endif
-
-
-CENSUS_STATISTICS_MULTIPLE_WRITERS_CIRCULAR_BUFFER_TEST_SRC = \
-    test/core/statistics/multiple_writers_circular_buffer_test.c \
-
-CENSUS_STATISTICS_MULTIPLE_WRITERS_CIRCULAR_BUFFER_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(CENSUS_STATISTICS_MULTIPLE_WRITERS_CIRCULAR_BUFFER_TEST_SRC))))
-ifeq ($(NO_SECURE),true)
-
-# You can't build secure targets if you don't have OpenSSL with ALPN.
-
-$(BINDIR)/$(CONFIG)/census_statistics_multiple_writers_circular_buffer_test: openssl_dep_error
-
-else
-
-$(BINDIR)/$(CONFIG)/census_statistics_multiple_writers_circular_buffer_test: $(CENSUS_STATISTICS_MULTIPLE_WRITERS_CIRCULAR_BUFFER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
-	$(E) "[LD]      Linking $@"
-	$(Q) mkdir -p `dirname $@`
-	$(Q) $(LD) $(LDFLAGS) $(CENSUS_STATISTICS_MULTIPLE_WRITERS_CIRCULAR_BUFFER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/census_statistics_multiple_writers_circular_buffer_test
-
-endif
-
-$(OBJDIR)/$(CONFIG)/test/core/statistics/multiple_writers_circular_buffer_test.o:  $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
-deps_census_statistics_multiple_writers_circular_buffer_test: $(CENSUS_STATISTICS_MULTIPLE_WRITERS_CIRCULAR_BUFFER_TEST_OBJS:.o=.dep)
-
-ifneq ($(NO_SECURE),true)
-ifneq ($(NO_DEPS),true)
--include $(CENSUS_STATISTICS_MULTIPLE_WRITERS_CIRCULAR_BUFFER_TEST_OBJS:.o=.dep)
-endif
-endif
-
-
-CENSUS_STATISTICS_MULTIPLE_WRITERS_TEST_SRC = \
-    test/core/statistics/multiple_writers_test.c \
-
-CENSUS_STATISTICS_MULTIPLE_WRITERS_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(CENSUS_STATISTICS_MULTIPLE_WRITERS_TEST_SRC))))
-ifeq ($(NO_SECURE),true)
-
-# You can't build secure targets if you don't have OpenSSL with ALPN.
-
-$(BINDIR)/$(CONFIG)/census_statistics_multiple_writers_test: openssl_dep_error
-
-else
-
-$(BINDIR)/$(CONFIG)/census_statistics_multiple_writers_test: $(CENSUS_STATISTICS_MULTIPLE_WRITERS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
-	$(E) "[LD]      Linking $@"
-	$(Q) mkdir -p `dirname $@`
-	$(Q) $(LD) $(LDFLAGS) $(CENSUS_STATISTICS_MULTIPLE_WRITERS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/census_statistics_multiple_writers_test
-
-endif
-
-$(OBJDIR)/$(CONFIG)/test/core/statistics/multiple_writers_test.o:  $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
-deps_census_statistics_multiple_writers_test: $(CENSUS_STATISTICS_MULTIPLE_WRITERS_TEST_OBJS:.o=.dep)
-
-ifneq ($(NO_SECURE),true)
-ifneq ($(NO_DEPS),true)
--include $(CENSUS_STATISTICS_MULTIPLE_WRITERS_TEST_OBJS:.o=.dep)
-endif
-endif
-
-
-CENSUS_STATISTICS_PERFORMANCE_TEST_SRC = \
-    test/core/statistics/performance_test.c \
-
-CENSUS_STATISTICS_PERFORMANCE_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(CENSUS_STATISTICS_PERFORMANCE_TEST_SRC))))
-ifeq ($(NO_SECURE),true)
-
-# You can't build secure targets if you don't have OpenSSL with ALPN.
-
-$(BINDIR)/$(CONFIG)/census_statistics_performance_test: openssl_dep_error
-
-else
-
-$(BINDIR)/$(CONFIG)/census_statistics_performance_test: $(CENSUS_STATISTICS_PERFORMANCE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
-	$(E) "[LD]      Linking $@"
-	$(Q) mkdir -p `dirname $@`
-	$(Q) $(LD) $(LDFLAGS) $(CENSUS_STATISTICS_PERFORMANCE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/census_statistics_performance_test
-
-endif
-
-$(OBJDIR)/$(CONFIG)/test/core/statistics/performance_test.o:  $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
-deps_census_statistics_performance_test: $(CENSUS_STATISTICS_PERFORMANCE_TEST_OBJS:.o=.dep)
-
-ifneq ($(NO_SECURE),true)
-ifneq ($(NO_DEPS),true)
--include $(CENSUS_STATISTICS_PERFORMANCE_TEST_OBJS:.o=.dep)
-endif
-endif
-
-
-CENSUS_STATISTICS_QUICK_TEST_SRC = \
-    test/core/statistics/quick_test.c \
-
-CENSUS_STATISTICS_QUICK_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(CENSUS_STATISTICS_QUICK_TEST_SRC))))
-ifeq ($(NO_SECURE),true)
-
-# You can't build secure targets if you don't have OpenSSL with ALPN.
-
-$(BINDIR)/$(CONFIG)/census_statistics_quick_test: openssl_dep_error
-
-else
-
-$(BINDIR)/$(CONFIG)/census_statistics_quick_test: $(CENSUS_STATISTICS_QUICK_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
-	$(E) "[LD]      Linking $@"
-	$(Q) mkdir -p `dirname $@`
-	$(Q) $(LD) $(LDFLAGS) $(CENSUS_STATISTICS_QUICK_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/census_statistics_quick_test
-
-endif
-
-$(OBJDIR)/$(CONFIG)/test/core/statistics/quick_test.o:  $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
-deps_census_statistics_quick_test: $(CENSUS_STATISTICS_QUICK_TEST_OBJS:.o=.dep)
-
-ifneq ($(NO_SECURE),true)
-ifneq ($(NO_DEPS),true)
--include $(CENSUS_STATISTICS_QUICK_TEST_OBJS:.o=.dep)
-endif
-endif
-
-
-CENSUS_STATISTICS_SMALL_LOG_TEST_SRC = \
-    test/core/statistics/small_log_test.c \
-
-CENSUS_STATISTICS_SMALL_LOG_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(CENSUS_STATISTICS_SMALL_LOG_TEST_SRC))))
-ifeq ($(NO_SECURE),true)
-
-# You can't build secure targets if you don't have OpenSSL with ALPN.
-
-$(BINDIR)/$(CONFIG)/census_statistics_small_log_test: openssl_dep_error
-
-else
-
-$(BINDIR)/$(CONFIG)/census_statistics_small_log_test: $(CENSUS_STATISTICS_SMALL_LOG_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
-	$(E) "[LD]      Linking $@"
-	$(Q) mkdir -p `dirname $@`
-	$(Q) $(LD) $(LDFLAGS) $(CENSUS_STATISTICS_SMALL_LOG_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/census_statistics_small_log_test
-
-endif
-
-$(OBJDIR)/$(CONFIG)/test/core/statistics/small_log_test.o:  $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
-deps_census_statistics_small_log_test: $(CENSUS_STATISTICS_SMALL_LOG_TEST_OBJS:.o=.dep)
-
-ifneq ($(NO_SECURE),true)
-ifneq ($(NO_DEPS),true)
--include $(CENSUS_STATISTICS_SMALL_LOG_TEST_OBJS:.o=.dep)
-endif
-endif
-
-
-CENSUS_STATS_STORE_TEST_SRC = \
-    test/core/statistics/rpc_stats_test.c \
-
-CENSUS_STATS_STORE_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(CENSUS_STATS_STORE_TEST_SRC))))
-ifeq ($(NO_SECURE),true)
-
-# You can't build secure targets if you don't have OpenSSL with ALPN.
-
-$(BINDIR)/$(CONFIG)/census_stats_store_test: openssl_dep_error
-
-else
-
-$(BINDIR)/$(CONFIG)/census_stats_store_test: $(CENSUS_STATS_STORE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
-	$(E) "[LD]      Linking $@"
-	$(Q) mkdir -p `dirname $@`
-	$(Q) $(LD) $(LDFLAGS) $(CENSUS_STATS_STORE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/census_stats_store_test
-
-endif
-
-$(OBJDIR)/$(CONFIG)/test/core/statistics/rpc_stats_test.o:  $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
-deps_census_stats_store_test: $(CENSUS_STATS_STORE_TEST_OBJS:.o=.dep)
-
-ifneq ($(NO_SECURE),true)
-ifneq ($(NO_DEPS),true)
--include $(CENSUS_STATS_STORE_TEST_OBJS:.o=.dep)
-endif
-endif
-
-
-CENSUS_STUB_TEST_SRC = \
-    test/core/statistics/census_stub_test.c \
-
-CENSUS_STUB_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(CENSUS_STUB_TEST_SRC))))
-ifeq ($(NO_SECURE),true)
-
-# You can't build secure targets if you don't have OpenSSL with ALPN.
-
-$(BINDIR)/$(CONFIG)/census_stub_test: openssl_dep_error
-
-else
-
-$(BINDIR)/$(CONFIG)/census_stub_test: $(CENSUS_STUB_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
-	$(E) "[LD]      Linking $@"
-	$(Q) mkdir -p `dirname $@`
-	$(Q) $(LD) $(LDFLAGS) $(CENSUS_STUB_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/census_stub_test
-
-endif
-
-$(OBJDIR)/$(CONFIG)/test/core/statistics/census_stub_test.o:  $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
-deps_census_stub_test: $(CENSUS_STUB_TEST_OBJS:.o=.dep)
-
-ifneq ($(NO_SECURE),true)
-ifneq ($(NO_DEPS),true)
--include $(CENSUS_STUB_TEST_OBJS:.o=.dep)
-endif
-endif
-
-
-CENSUS_TRACE_STORE_TEST_SRC = \
-    test/core/statistics/trace_test.c \
-
-CENSUS_TRACE_STORE_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(CENSUS_TRACE_STORE_TEST_SRC))))
-ifeq ($(NO_SECURE),true)
-
-# You can't build secure targets if you don't have OpenSSL with ALPN.
-
-$(BINDIR)/$(CONFIG)/census_trace_store_test: openssl_dep_error
-
-else
-
-$(BINDIR)/$(CONFIG)/census_trace_store_test: $(CENSUS_TRACE_STORE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
-	$(E) "[LD]      Linking $@"
-	$(Q) mkdir -p `dirname $@`
-	$(Q) $(LD) $(LDFLAGS) $(CENSUS_TRACE_STORE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/census_trace_store_test
-
-endif
-
-$(OBJDIR)/$(CONFIG)/test/core/statistics/trace_test.o:  $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
-deps_census_trace_store_test: $(CENSUS_TRACE_STORE_TEST_OBJS:.o=.dep)
-
-ifneq ($(NO_SECURE),true)
-ifneq ($(NO_DEPS),true)
--include $(CENSUS_TRACE_STORE_TEST_OBJS:.o=.dep)
-endif
-endif
-
-
-CENSUS_WINDOW_STATS_TEST_SRC = \
-    test/core/statistics/window_stats_test.c \
-
-CENSUS_WINDOW_STATS_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(CENSUS_WINDOW_STATS_TEST_SRC))))
-ifeq ($(NO_SECURE),true)
-
-# You can't build secure targets if you don't have OpenSSL with ALPN.
-
-$(BINDIR)/$(CONFIG)/census_window_stats_test: openssl_dep_error
-
-else
-
-$(BINDIR)/$(CONFIG)/census_window_stats_test: $(CENSUS_WINDOW_STATS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
-	$(E) "[LD]      Linking $@"
-	$(Q) mkdir -p `dirname $@`
-	$(Q) $(LD) $(LDFLAGS) $(CENSUS_WINDOW_STATS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/census_window_stats_test
-
-endif
-
-$(OBJDIR)/$(CONFIG)/test/core/statistics/window_stats_test.o:  $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
-deps_census_window_stats_test: $(CENSUS_WINDOW_STATS_TEST_OBJS:.o=.dep)
-
-ifneq ($(NO_SECURE),true)
-ifneq ($(NO_DEPS),true)
--include $(CENSUS_WINDOW_STATS_TEST_OBJS:.o=.dep)
-endif
-endif
-
-
 CHTTP2_STATUS_CONVERSION_TEST_SRC = \
     test/core/transport/chttp2/status_conversion_test.c \
 
diff --git a/build.json b/build.json
index df1a5f0..aaa627a 100644
--- a/build.json
+++ b/build.json
@@ -13,6 +13,19 @@
   },
   "filegroups": [
     {
+      "name": "census",
+      "public_headers": [
+        "include/grpc/census.h"
+      ],
+      "headers": [
+        "src/core/census/context.h"
+      ],
+      "src": [
+        "src/core/census/context.c",
+        "src/core/census/initialize.c"
+      ]
+    },
+    {
       "name": "grpc++_base",
       "public_headers": [
         "include/grpc++/async_generic_service.h",
@@ -91,7 +104,7 @@
         "include/grpc/status.h"
       ],
       "headers": [
-        "src/core/channel/census_filter.h",
+        "src/core/census/grpc_context.h",
         "src/core/channel/channel_args.h",
         "src/core/channel/channel_stack.h",
         "src/core/channel/child_channel.h",
@@ -140,12 +153,6 @@
         "src/core/json/json_writer.h",
         "src/core/profiling/timers.h",
         "src/core/profiling/timers_preciseclock.h",
-        "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/byte_buffer_queue.h",
         "src/core/surface/call.h",
         "src/core/surface/channel.h",
@@ -180,7 +187,7 @@
         "src/core/transport/transport_impl.h"
       ],
       "src": [
-        "src/core/channel/census_filter.c",
+        "src/core/census/grpc_context.c",
         "src/core/channel/channel_args.c",
         "src/core/channel/channel_stack.c",
         "src/core/channel/child_channel.c",
@@ -232,12 +239,6 @@
         "src/core/json/json_writer.c",
         "src/core/profiling/basic_timers.c",
         "src/core/profiling/stap_timers.c",
-        "src/core/statistics/census_init.c",
-        "src/core/statistics/census_log.c",
-        "src/core/statistics/census_rpc_stats.c",
-        "src/core/statistics/census_tracing.c",
-        "src/core/statistics/hash_table.c",
-        "src/core/statistics/window_stats.c",
         "src/core/surface/byte_buffer.c",
         "src/core/surface/byte_buffer_queue.c",
         "src/core/surface/byte_buffer_reader.c",
@@ -284,7 +285,6 @@
       "src": [
         "test/core/end2end/cq_verifier.c",
         "test/core/iomgr/endpoint_tests.c",
-        "test/core/statistics/census_log_tests.c",
         "test/core/util/grpc_profiler.c",
         "test/core/util/parse_hexstring.c",
         "test/core/util/port_posix.c",
@@ -448,7 +448,8 @@
       ],
       "baselib": true,
       "filegroups": [
-        "grpc_base"
+        "grpc_base",
+        "census"
       ],
       "secure": "yes",
       "vs_project_guid": "{29D16885-7228-4C31-81ED-5F9187C7F2A9}"
@@ -499,7 +500,8 @@
       ],
       "baselib": true,
       "filegroups": [
-        "grpc_base"
+        "grpc_base",
+        "census"
       ],
       "secure": "no",
       "vs_project_guid": "{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}"
@@ -802,147 +804,6 @@
       ]
     },
     {
-      "name": "census_hash_table_test",
-      "build": "test",
-      "language": "c",
-      "src": [
-        "test/core/statistics/hash_table_test.c"
-      ],
-      "deps": [
-        "grpc_test_util",
-        "grpc",
-        "gpr_test_util",
-        "gpr"
-      ]
-    },
-    {
-      "name": "census_statistics_multiple_writers_circular_buffer_test",
-      "flaky": true,
-      "build": "test",
-      "language": "c",
-      "src": [
-        "test/core/statistics/multiple_writers_circular_buffer_test.c"
-      ],
-      "deps": [
-        "grpc_test_util",
-        "grpc",
-        "gpr_test_util",
-        "gpr"
-      ]
-    },
-    {
-      "name": "census_statistics_multiple_writers_test",
-      "build": "test",
-      "language": "c",
-      "src": [
-        "test/core/statistics/multiple_writers_test.c"
-      ],
-      "deps": [
-        "grpc_test_util",
-        "grpc",
-        "gpr_test_util",
-        "gpr"
-      ]
-    },
-    {
-      "name": "census_statistics_performance_test",
-      "build": "test",
-      "language": "c",
-      "src": [
-        "test/core/statistics/performance_test.c"
-      ],
-      "deps": [
-        "grpc_test_util",
-        "grpc",
-        "gpr_test_util",
-        "gpr"
-      ]
-    },
-    {
-      "name": "census_statistics_quick_test",
-      "build": "test",
-      "language": "c",
-      "src": [
-        "test/core/statistics/quick_test.c"
-      ],
-      "deps": [
-        "grpc_test_util",
-        "grpc",
-        "gpr_test_util",
-        "gpr"
-      ]
-    },
-    {
-      "name": "census_statistics_small_log_test",
-      "build": "test",
-      "language": "c",
-      "src": [
-        "test/core/statistics/small_log_test.c"
-      ],
-      "deps": [
-        "grpc_test_util",
-        "grpc",
-        "gpr_test_util",
-        "gpr"
-      ]
-    },
-    {
-      "name": "census_stats_store_test",
-      "build": "executable",
-      "language": "c",
-      "src": [
-        "test/core/statistics/rpc_stats_test.c"
-      ],
-      "deps": [
-        "grpc_test_util",
-        "grpc",
-        "gpr_test_util",
-        "gpr"
-      ]
-    },
-    {
-      "name": "census_stub_test",
-      "build": "test",
-      "language": "c",
-      "src": [
-        "test/core/statistics/census_stub_test.c"
-      ],
-      "deps": [
-        "grpc_test_util",
-        "grpc",
-        "gpr_test_util",
-        "gpr"
-      ]
-    },
-    {
-      "name": "census_trace_store_test",
-      "build": "executable",
-      "language": "c",
-      "src": [
-        "test/core/statistics/trace_test.c"
-      ],
-      "deps": [
-        "grpc_test_util",
-        "grpc",
-        "gpr_test_util",
-        "gpr"
-      ]
-    },
-    {
-      "name": "census_window_stats_test",
-      "build": "test",
-      "language": "c",
-      "src": [
-        "test/core/statistics/window_stats_test.c"
-      ],
-      "deps": [
-        "grpc_test_util",
-        "grpc",
-        "gpr_test_util",
-        "gpr"
-      ]
-    },
-    {
       "name": "chttp2_status_conversion_test",
       "build": "test",
       "language": "c",
diff --git a/include/grpc/census.h b/include/grpc/census.h
new file mode 100644
index 0000000..5f08c10
--- /dev/null
+++ b/include/grpc/census.h
@@ -0,0 +1,95 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/* RPC-internal Census API's. These are designed to be generic enough that
+ * they can (ultimately) be used in many different RPC systems (with differing
+ * implementations). */
+
+#ifndef CENSUS_CENSUS_H
+#define CENSUS_CENSUS_H
+
+#include <grpc/grpc.h>
+
+/* Identify census functionality that can be enabled via census_initialize(). */
+enum census_functions {
+  CENSUS_NONE = 0,    /* Do not enable census. */
+  CENSUS_TRACING = 1, /* Enable census tracing. */
+  CENSUS_STATS = 2,   /* Enable Census stats collection. */
+  CENSUS_CPU = 4,     /* Enable Census CPU usage collection. */
+  CENSUS_ALL = CENSUS_TRACING | CENSUS_STATS | CENSUS_CPU
+};
+
+/* Shutdown and startup census subsystem. The 'functions' argument should be
+ * the OR (|) of census_functions values. If census fails to initialize, then
+ * census_initialize() will return a non-zero value. It is an error to call
+ * census_initialize() more than once (without an intervening
+ * census_shutdown()). */
+int census_initialize(int functions);
+void census_shutdown();
+
+/* Internally, Census relies on a context, which should be propagated across
+ * RPC's. From the RPC subsystems viewpoint, this is an opaque data structure.
+ * A context must be used as the first argument to all other census
+ * functions. Conceptually, contexts should be thought of as specific to
+ * single RPC/thread. The context can be serialized for passing across the
+ * wire. */
+typedef struct census_context census_context;
+
+/* This function is called by the RPC subsystem whenever it needs to get a
+ * serialized form of the current census context (presumably to pass across
+ * the wire). Arguments:
+ * 'buffer': pointer to memory into which serialized context will be placed
+ * 'buf_size': size of 'buffer'
+ *
+ * Returns: the number of bytes used in buffer if successful, or 0 if the
+ * buffer is of insufficient size.
+ *
+ * TODO(aveitch): determine how best to communicate required/max buffer size
+ * so caller doesn't have to guess. */
+size_t census_context_serialize(const census_context *context, char *buffer,
+                                size_t buf_size);
+
+/* Create a new census context, possibly from a serialized buffer. If 'buffer'
+ * is non-NULL, it is assumed that it is a buffer encoded by
+ * census_context_serialize(). If `buffer` is NULL, a new, empty context is
+ * created. The decoded/new contest is returned in 'context'.
+ *
+ * Returns 0 if no errors, non-zero if buffer is incorrectly formatted, in
+ * which case a new empty context will be returned. */
+int census_context_deserialize(const char *buffer, census_context **context);
+
+/* The given context is destroyed. Once destroyed, using the context in
+ * future census calls will result in undefined behavior. */
+void census_context_destroy(census_context *context);
+
+#endif /* CENSUS_CENSUS_H */
diff --git a/src/compiler/objective_c_generator.cc b/src/compiler/objective_c_generator.cc
index 1bf0254..b235911 100644
--- a/src/compiler/objective_c_generator.cc
+++ b/src/compiler/objective_c_generator.cc
@@ -32,19 +32,20 @@
  */
 
 #include <map>
+#include <sstream>
 
+#include "src/compiler/config.h"
 #include "src/compiler/objective_c_generator.h"
 #include "src/compiler/objective_c_generator_helpers.h"
 
-#include "src/compiler/config.h"
+#include <google/protobuf/compiler/objectivec/objectivec_helpers.h>
 
-#include <sstream>
-
+using ::google::protobuf::compiler::objectivec::ClassName;
 using ::grpc::protobuf::io::Printer;
 using ::grpc::protobuf::MethodDescriptor;
 using ::grpc::protobuf::ServiceDescriptor;
-using ::std::map;
 using ::grpc::string;
+using ::std::map;
 
 namespace grpc_objective_c_generator {
 namespace {
@@ -69,7 +70,7 @@
   if (method->client_streaming()) {
     printer->Print("RequestsWriter:(id<GRXWriter>)request");
   } else {
-    printer->Print(vars, "Request:($prefix$$request_type$ *)request");
+    printer->Print(vars, "Request:($request_class$ *)request");
   }
 
   // TODO(jcanizales): Put this on a new line and align colons.
@@ -78,8 +79,7 @@
   if (method->server_streaming()) {
     printer->Print("BOOL done, ");
   }
-  printer->Print(vars,
-      "$prefix$$response_type$ *response, NSError *error))handler");
+  printer->Print(vars, "$response_class$ *response, NSError *error))handler");
 }
 
 void PrintSimpleSignature(Printer *printer,
@@ -99,12 +99,17 @@
   PrintMethodSignature(printer, method, vars);
 }
 
+inline map<string, string> GetMethodVars(const MethodDescriptor *method) {
+  return {{ "method_name", method->name() },
+          { "request_type", method->input_type()->name() },
+          { "response_type", method->output_type()->name() },
+          { "request_class", ClassName(method->input_type()) },
+          { "response_class", ClassName(method->output_type()) }};
+}
+
 void PrintMethodDeclarations(Printer *printer,
-                             const MethodDescriptor *method,
-                             map<string, string> vars) {
-  vars["method_name"] = method->name();
-  vars["request_type"] = method->input_type()->name();
-  vars["response_type"] = method->output_type()->name();
+                             const MethodDescriptor *method) {
+  map<string, string> vars = GetMethodVars(method);
 
   PrintProtoRpcDeclarationAsPragma(printer, method, vars);
 
@@ -141,8 +146,7 @@
     printer->Print("[GRXWriter writerWithValue:request]\n");
   }
 
-  printer->Print(vars,
-      "             responseClass:[$prefix$$response_type$ class]\n");
+  printer->Print(vars, "             responseClass:[$response_class$ class]\n");
 
   printer->Print("        responsesWriteable:[GRXWriteable ");
   if (method->server_streaming()) {
@@ -155,11 +159,8 @@
 }
 
 void PrintMethodImplementations(Printer *printer,
-                                const MethodDescriptor *method,
-                                map<string, string> vars) {
-  vars["method_name"] = method->name();
-  vars["request_type"] = method->input_type()->name();
-  vars["response_type"] = method->output_type()->name();
+                                const MethodDescriptor *method) {
+  map<string, string> vars = GetMethodVars(method);
 
   PrintProtoRpcDeclarationAsPragma(printer, method, vars);
 
@@ -174,7 +175,7 @@
 
 } // namespace
 
-string GetHeader(const ServiceDescriptor *service, const string prefix) {
+string GetHeader(const ServiceDescriptor *service) {
   string output;
   {
     // Scope the output stream so it closes and finalizes output to the string.
@@ -184,19 +185,19 @@
     printer.Print("@protocol GRXWriteable;\n");
     printer.Print("@protocol GRXWriter;\n\n");
 
-    map<string, string> vars = {{"service_name", service->name()},
-                                {"prefix",       prefix}};
-    printer.Print(vars, "@protocol $prefix$$service_name$ <NSObject>\n\n");
+    map<string, string> vars = {{"service_class", ServiceClassName(service)}};
+
+    printer.Print(vars, "@protocol $service_class$ <NSObject>\n\n");
 
     for (int i = 0; i < service->method_count(); i++) {
-      PrintMethodDeclarations(&printer, service->method(i), vars);
+      PrintMethodDeclarations(&printer, service->method(i));
     }
     printer.Print("@end\n\n");
 
     printer.Print("// Basic service implementation, over gRPC, that only does"
         " marshalling and parsing.\n");
-    printer.Print(vars, "@interface $prefix$$service_name$ :"
-      " ProtoService<$prefix$$service_name$>\n");
+    printer.Print(vars, "@interface $service_class$ :"
+      " ProtoService<$service_class$>\n");
     printer.Print("- (instancetype)initWithHost:(NSString *)host"
       " NS_DESIGNATED_INITIALIZER;\n");
     printer.Print("@end\n");
@@ -204,7 +205,7 @@
   return output;
 }
 
-string GetSource(const ServiceDescriptor *service, const string prefix) {
+string GetSource(const ServiceDescriptor *service) {
   string output;
   {
     // Scope the output stream so it closes and finalizes output to the string.
@@ -212,15 +213,15 @@
     Printer printer(&output_stream, '$');
 
     map<string, string> vars = {{"service_name", service->name()},
-                                {"package", service->file()->package()},
-                                {"prefix",       prefix}};
+                                {"service_class", ServiceClassName(service)},
+                                {"package", service->file()->package()}};
 
     printer.Print(vars,
         "static NSString *const kPackageName = @\"$package$\";\n");
     printer.Print(vars,
         "static NSString *const kServiceName = @\"$service_name$\";\n\n");
 
-    printer.Print(vars, "@implementation $prefix$$service_name$\n\n");
+    printer.Print(vars, "@implementation $service_class$\n\n");
   
     printer.Print("// Designated initializer\n");
     printer.Print("- (instancetype)initWithHost:(NSString *)host {\n");
@@ -236,7 +237,7 @@
     printer.Print("}\n\n\n");
 
     for (int i = 0; i < service->method_count(); i++) {
-      PrintMethodImplementations(&printer, service->method(i), vars);
+      PrintMethodImplementations(&printer, service->method(i));
     }
 
     printer.Print("@end\n");
diff --git a/src/compiler/objective_c_generator.h b/src/compiler/objective_c_generator.h
index 548e96f..40a0c87 100644
--- a/src/compiler/objective_c_generator.h
+++ b/src/compiler/objective_c_generator.h
@@ -38,15 +38,16 @@
 
 namespace grpc_objective_c_generator {
 
+using ::grpc::protobuf::ServiceDescriptor;
+using ::grpc::string;
+
 // Returns the content to be included in the "global_scope" insertion point of
 // the generated header file.
-grpc::string GetHeader(const grpc::protobuf::ServiceDescriptor *service,
-                       const grpc::string prefix);
+string GetHeader(const ServiceDescriptor *service);
 
 // Returns the content to be included in the "global_scope" insertion point of
 // the generated implementation file.
-grpc::string GetSource(const grpc::protobuf::ServiceDescriptor *service,
-                       const grpc::string prefix);
+string GetSource(const ServiceDescriptor *service);
 
 }  // namespace grpc_objective_c_generator
 
diff --git a/src/compiler/objective_c_generator_helpers.h b/src/compiler/objective_c_generator_helpers.h
index d92a2b5..1f8c800 100644
--- a/src/compiler/objective_c_generator_helpers.h
+++ b/src/compiler/objective_c_generator_helpers.h
@@ -40,9 +40,19 @@
 
 namespace grpc_objective_c_generator {
 
-inline grpc::string MessageHeaderName(const grpc::protobuf::FileDescriptor *file) {
+using ::grpc::protobuf::FileDescriptor;
+using ::grpc::protobuf::ServiceDescriptor;
+using ::grpc::string;
+
+inline string MessageHeaderName(const FileDescriptor *file) {
   return grpc_generator::FileNameInUpperCamel(file) + ".pbobjc.h";
 }
 
+inline string ServiceClassName(const ServiceDescriptor *service) {
+  const FileDescriptor *file = service->file();
+  string prefix = file->options().objc_class_prefix();
+  return prefix + service->name();
+}
+
 }
 #endif  // GRPC_INTERNAL_COMPILER_OBJECTIVE_C_GENERATOR_HELPERS_H
diff --git a/src/compiler/objective_c_plugin.cc b/src/compiler/objective_c_plugin.cc
index 3cb170e..b5ac2ba 100644
--- a/src/compiler/objective_c_plugin.cc
+++ b/src/compiler/objective_c_plugin.cc
@@ -77,7 +77,7 @@
       string declarations;
       for (int i = 0; i < file->service_count(); i++) {
         const grpc::protobuf::ServiceDescriptor *service = file->service(i);
-        declarations += grpc_objective_c_generator::GetHeader(service, prefix);
+        declarations += grpc_objective_c_generator::GetHeader(service);
       }
 
       Write(context, file_name + ".pbrpc.h",
@@ -95,7 +95,7 @@
       string definitions;
       for (int i = 0; i < file->service_count(); i++) {
         const grpc::protobuf::ServiceDescriptor *service = file->service(i);
-        definitions += grpc_objective_c_generator::GetSource(service, prefix);
+        definitions += grpc_objective_c_generator::GetSource(service);
       }
 
       Write(context, file_name + ".pbrpc.m", imports + '\n' + definitions);
diff --git a/src/core/census/README.md b/src/core/census/README.md
new file mode 100644
index 0000000..fb615a2
--- /dev/null
+++ b/src/core/census/README.md
@@ -0,0 +1,76 @@
+<!---
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+-->
+
+# Census - a resource measurement and tracing system
+
+This directory contains code for Census, which will ultimately provide the
+following features for any gRPC-using system:
+* A [dapper](http://research.google.com/pubs/pub36356.html)-like tracing
+  system, enabling tracing across a distributed infrastructure.
+* RPC statistics and measurements for key metrics, such as latency, bytes
+  transferred, number of errors etc.
+* Resource measurement framework which can be used for measuring custom
+  metrics. Through the use of [tags](#Tags), these can be broken down across
+  the entire distributed stack.
+* Easy integration of the above with
+  [Google Cloud Trace](https://cloud.google.com/tools/cloud-trace) and
+  [Google Cloud Monitoring](https://cloud.google.com/monitoring/).
+
+## Concepts
+
+### Context
+
+### Operations
+
+### Tags
+
+### Metrics
+
+## API
+
+### Internal/RPC API
+
+### External/Client API
+
+### RPC API
+
+## Files in this directory
+
+Note that files and functions in this directory can be split into two
+categories:
+* Files that define core census library functions. Functions etc. in these
+  files are named census\_\*, and constitute the core census library
+  functionality. At some time in the future, these will become a standalone
+  library.
+* Files that define functions etc. that provide a convenient interface between
+  grpc and the core census functionality. These files are all named
+  grpc\_\*.{c,h}, and define function names beginning with grpc\_census\_\*.
+
diff --git a/src/python/src/grpc/_adapter/_error.h b/src/core/census/context.c
similarity index 68%
copy from src/python/src/grpc/_adapter/_error.h
copy to src/core/census/context.c
index 6988b1c..1358c51 100644
--- a/src/python/src/grpc/_adapter/_error.h
+++ b/src/core/census/context.c
@@ -31,12 +31,29 @@
  *
  */
 
-#ifndef _ADAPTER__ERROR_H_
-#define _ADAPTER__ERROR_H_
+#include "context.h"
 
-#include <Python.h>
-#include <grpc/grpc.h>
+#include <string.h>
+#include <grpc/census.h>
+#include <grpc/support/alloc.h>
 
-const PyObject *pygrpc_translate_call_error(grpc_call_error call_error);
+/* Placeholder implementation only. */
 
-#endif /* _ADAPTER__ERROR_H_ */
+size_t census_context_serialize(const census_context *context, char *buffer,
+                                size_t buf_size) {
+  /* TODO(aveitch): implement serialization */
+  return 0;
+}
+
+int census_context_deserialize(const char *buffer, census_context **context) {
+  int ret = 0;
+  if (buffer != NULL) {
+    /* TODO(aveitch): implement deserialization. */
+    ret = 1;
+  }
+  *context = gpr_malloc(sizeof(census_context));
+  memset(*context, 0, sizeof(census_context));
+  return ret;
+}
+
+void census_context_destroy(census_context *context) { gpr_free(context); }
diff --git a/src/python/src/grpc/_adapter/_error.h b/src/core/census/context.h
similarity index 73%
copy from src/python/src/grpc/_adapter/_error.h
copy to src/core/census/context.h
index 6988b1c..d43a69f 100644
--- a/src/python/src/grpc/_adapter/_error.h
+++ b/src/core/census/context.h
@@ -31,12 +31,19 @@
  *
  */
 
-#ifndef _ADAPTER__ERROR_H_
-#define _ADAPTER__ERROR_H_
+#ifndef GRPC_INTERNAL_CORE_CENSUS_CONTEXT_H
+#define GRPC_INTERNAL_CORE_CENSUS_CONTEXT_H
 
-#include <Python.h>
-#include <grpc/grpc.h>
+#include <grpc/census.h>
 
-const PyObject *pygrpc_translate_call_error(grpc_call_error call_error);
+/* census_context is the in-memory representation of information needed to
+ * maintain tracing, RPC statistics and resource usage information. */
+struct census_context {
+  gpr_uint64 op_id;    /* Operation identifier - unique per-context */
+  gpr_uint64 trace_id; /* Globally unique trace identifier */
+  /* TODO(aveitch) Add census tags:
+  const census_tag_set *tags;
+  */
+};
 
-#endif /* _ADAPTER__ERROR_H_ */
+#endif /* GRPC_INTERNAL_CORE_CENSUS_CONTEXT_H */
diff --git a/src/python/src/grpc/_adapter/_error.h b/src/core/census/grpc_context.c
similarity index 82%
copy from src/python/src/grpc/_adapter/_error.h
copy to src/core/census/grpc_context.c
index 6988b1c..cf23531 100644
--- a/src/python/src/grpc/_adapter/_error.h
+++ b/src/core/census/grpc_context.c
@@ -31,12 +31,15 @@
  *
  */
 
-#ifndef _ADAPTER__ERROR_H_
-#define _ADAPTER__ERROR_H_
+#include <grpc/census.h>
+#include "src/core/census/grpc_context.h"
 
-#include <Python.h>
-#include <grpc/grpc.h>
+void *grpc_census_context_create() {
+  census_context *context;
+  census_context_deserialize(NULL, &context);
+  return (void *)context;
+}
 
-const PyObject *pygrpc_translate_call_error(grpc_call_error call_error);
-
-#endif /* _ADAPTER__ERROR_H_ */
+void grpc_census_context_destroy(void *context) {
+  census_context_destroy((census_context *)context);
+}
diff --git a/src/python/src/grpc/_adapter/_error.h b/src/core/census/grpc_context.h
similarity index 86%
copy from src/python/src/grpc/_adapter/_error.h
copy to src/core/census/grpc_context.h
index 6988b1c..f610f6c 100644
--- a/src/python/src/grpc/_adapter/_error.h
+++ b/src/core/census/grpc_context.h
@@ -31,12 +31,12 @@
  *
  */
 
-#ifndef _ADAPTER__ERROR_H_
-#define _ADAPTER__ERROR_H_
+/* GRPC <--> CENSUS context interface */
 
-#include <Python.h>
-#include <grpc/grpc.h>
+#ifndef CENSUS_GRPC_CONTEXT_H
+#define CENSUS_GRPC_CONTEXT_H
 
-const PyObject *pygrpc_translate_call_error(grpc_call_error call_error);
+void *grpc_census_context_create();
+void grpc_census_context_destroy(void *context);
 
-#endif /* _ADAPTER__ERROR_H_ */
+#endif /* CENSUS_GRPC_CONTEXT_H */
diff --git a/src/python/src/grpc/_adapter/_error.h b/src/core/census/initialize.c
similarity index 81%
copy from src/python/src/grpc/_adapter/_error.h
copy to src/core/census/initialize.c
index 6988b1c..057ac78 100644
--- a/src/python/src/grpc/_adapter/_error.h
+++ b/src/core/census/initialize.c
@@ -31,12 +31,20 @@
  *
  */
 
-#ifndef _ADAPTER__ERROR_H_
-#define _ADAPTER__ERROR_H_
+#include <grpc/census.h>
 
-#include <Python.h>
-#include <grpc/grpc.h>
+static int census_fns_enabled = CENSUS_NONE;
 
-const PyObject *pygrpc_translate_call_error(grpc_call_error call_error);
+int census_initialize(int functions) {
+  if (census_fns_enabled != CENSUS_NONE) {
+    return 1;
+  }
+  if (functions != CENSUS_NONE) {
+    return 1;
+  } else {
+    census_fns_enabled = functions;
+    return 0;
+  }
+}
 
-#endif /* _ADAPTER__ERROR_H_ */
+void census_shutdown() { census_fns_enabled = CENSUS_NONE; }
diff --git a/src/core/surface/call.c b/src/core/surface/call.c
index 948d0cd..88ff5cf 100644
--- a/src/core/surface/call.c
+++ b/src/core/surface/call.c
@@ -31,6 +31,7 @@
  *
  */
 
+#include "src/core/census/grpc_context.h"
 #include "src/core/surface/call.h"
 #include "src/core/channel/channel_stack.h"
 #include "src/core/iomgr/alarm.h"
@@ -243,9 +244,9 @@
 static void execute_op(grpc_call *call, grpc_transport_op *op);
 static void recv_metadata(grpc_call *call, grpc_metadata_batch *metadata);
 static void finish_read_ops(grpc_call *call);
-static grpc_call_error cancel_with_status(
-    grpc_call *c, grpc_status_code status, const char *description,
-    gpr_uint8 locked);
+static grpc_call_error cancel_with_status(grpc_call *c, grpc_status_code status,
+                                          const char *description,
+                                          gpr_uint8 locked);
 
 grpc_call *grpc_call_create(grpc_channel *channel, grpc_completion_queue *cq,
                             const void *server_transport_data,
@@ -269,6 +270,8 @@
   if (call->is_client) {
     call->request_set[GRPC_IOREQ_SEND_TRAILING_METADATA] = REQSET_DONE;
     call->request_set[GRPC_IOREQ_SEND_STATUS] = REQSET_DONE;
+    call->context[GRPC_CONTEXT_TRACING].value = grpc_census_context_create();
+    call->context[GRPC_CONTEXT_TRACING].destroy = grpc_census_context_destroy;
   }
   GPR_ASSERT(add_initial_metadata_count < MAX_SEND_INITIAL_METADATA_COUNT);
   for (i = 0; i < add_initial_metadata_count; i++) {
@@ -406,7 +409,8 @@
 static int need_more_data(grpc_call *call) {
   if (call->read_state == READ_STATE_STREAM_CLOSED) return 0;
   return is_op_live(call, GRPC_IOREQ_RECV_INITIAL_METADATA) ||
-         (is_op_live(call, GRPC_IOREQ_RECV_MESSAGE) && grpc_bbq_empty(&call->incoming_queue)) ||
+         (is_op_live(call, GRPC_IOREQ_RECV_MESSAGE) &&
+          grpc_bbq_empty(&call->incoming_queue)) ||
          is_op_live(call, GRPC_IOREQ_RECV_TRAILING_METADATA) ||
          is_op_live(call, GRPC_IOREQ_RECV_STATUS) ||
          is_op_live(call, GRPC_IOREQ_RECV_STATUS_DETAILS) ||
@@ -559,13 +563,13 @@
           break;
         case GRPC_IOREQ_RECV_INITIAL_METADATA:
           GPR_SWAP(grpc_metadata_array, call->buffered_metadata[0],
-               *call->request_data[GRPC_IOREQ_RECV_INITIAL_METADATA]
-                    .recv_metadata);
+                   *call->request_data[GRPC_IOREQ_RECV_INITIAL_METADATA]
+                        .recv_metadata);
           break;
         case GRPC_IOREQ_RECV_TRAILING_METADATA:
           GPR_SWAP(grpc_metadata_array, call->buffered_metadata[1],
-               *call->request_data[GRPC_IOREQ_RECV_TRAILING_METADATA]
-                    .recv_metadata);
+                   *call->request_data[GRPC_IOREQ_RECV_TRAILING_METADATA]
+                        .recv_metadata);
           break;
         case GRPC_IOREQ_OP_COUNT:
           abort();
@@ -679,9 +683,8 @@
   }
   /* we have to be reading a message to know what to do here */
   if (!call->reading_message) {
-    cancel_with_status(
-        call, GRPC_STATUS_INVALID_ARGUMENT,
-        "Received payload data while not reading a message", 1);
+    cancel_with_status(call, GRPC_STATUS_INVALID_ARGUMENT,
+                       "Received payload data while not reading a message", 1);
     return 0;
   }
   /* append the slice to the incoming buffer */
@@ -1028,9 +1031,9 @@
   return cancel_with_status(c, status, description, 0);
 }
 
-static grpc_call_error cancel_with_status(
-    grpc_call *c, grpc_status_code status, const char *description,
-    gpr_uint8 locked) {
+static grpc_call_error cancel_with_status(grpc_call *c, grpc_status_code status,
+                                          const char *description,
+                                          gpr_uint8 locked) {
   grpc_transport_op op;
   grpc_mdstr *details =
       description ? grpc_mdstr_from_string(c->metadata_context, description)
@@ -1297,12 +1300,11 @@
 
   grpc_cq_begin_op(call->cq, call);
 
-  return grpc_call_start_ioreq_and_call_back(call, reqs, out, finish_func,
-                                             tag);
+  return grpc_call_start_ioreq_and_call_back(call, reqs, out, finish_func, tag);
 }
 
-void grpc_call_context_set(grpc_call *call, grpc_context_index elem, void *value,
-                           void (*destroy)(void *value)) {
+void grpc_call_context_set(grpc_call *call, grpc_context_index elem,
+                           void *value, void (*destroy)(void *value)) {
   if (call->context[elem].destroy) {
     call->context[elem].destroy(call->context[elem].value);
   }
diff --git a/src/core/surface/channel_create.c b/src/core/surface/channel_create.c
index daa8d3a..9fa6696 100644
--- a/src/core/surface/channel_create.c
+++ b/src/core/surface/channel_create.c
@@ -195,9 +195,10 @@
   const grpc_channel_filter *filters[MAX_FILTERS];
   int n = 0;
   filters[n++] = &grpc_client_surface_filter;
+  /* TODO(census)
   if (grpc_channel_args_is_census_enabled(args)) {
     filters[n++] = &grpc_client_census_filter;
-  }
+    } */
   filters[n++] = &grpc_client_channel_filter;
   GPR_ASSERT(n <= MAX_FILTERS);
   channel = grpc_channel_create_from_filters(filters, n, args, mdctx, 1);
diff --git a/src/core/surface/init.c b/src/core/surface/init.c
index d6eb9b2..ac6871c 100644
--- a/src/core/surface/init.c
+++ b/src/core/surface/init.c
@@ -31,11 +31,11 @@
  *
  */
 
+#include <grpc/census.h>
 #include <grpc/grpc.h>
 #include "src/core/channel/channel_stack.h"
 #include "src/core/debug/trace.h"
 #include "src/core/iomgr/iomgr.h"
-#include "src/core/statistics/census_interface.h"
 #include "src/core/profiling/timers.h"
 #include "src/core/surface/call.h"
 #include "src/core/surface/init.h"
@@ -64,7 +64,9 @@
     grpc_security_pre_init();
     grpc_iomgr_init();
     grpc_tracer_init("GRPC_TRACE");
-    census_init();
+    if (census_initialize(CENSUS_NONE)) {
+      gpr_log(GPR_ERROR, "Could not initialize census.");
+    }
     grpc_timers_global_init();
   }
   gpr_mu_unlock(&g_init_mu);
diff --git a/src/core/surface/secure_channel_create.c b/src/core/surface/secure_channel_create.c
index a71d122..8ef121d 100644
--- a/src/core/surface/secure_channel_create.c
+++ b/src/core/surface/secure_channel_create.c
@@ -234,9 +234,10 @@
       new_args_from_connector != NULL ? new_args_from_connector : args,
       &connector_arg);
   filters[n++] = &grpc_client_surface_filter;
+  /* TODO(census)
   if (grpc_channel_args_is_census_enabled(args)) {
     filters[n++] = &grpc_client_census_filter;
-  }
+    } */
   filters[n++] = &grpc_client_channel_filter;
   GPR_ASSERT(n <= MAX_FILTERS);
   channel = grpc_channel_create_from_filters(filters, n, args_copy, mdctx, 1);
diff --git a/src/core/surface/server.c b/src/core/surface/server.c
index 21b5f91..7e69ec0 100644
--- a/src/core/surface/server.c
+++ b/src/core/surface/server.c
@@ -606,9 +606,15 @@
 }
 
 static const grpc_channel_filter server_surface_filter = {
-    server_start_transport_op, channel_op, sizeof(call_data), init_call_elem,
-    destroy_call_elem, sizeof(channel_data), init_channel_elem,
-    destroy_channel_elem, "server",
+    server_start_transport_op,
+    channel_op,
+    sizeof(call_data),
+    init_call_elem,
+    destroy_call_elem,
+    sizeof(channel_data),
+    init_channel_elem,
+    destroy_channel_elem,
+    "server",
 };
 
 void grpc_server_register_completion_queue(grpc_server *server,
@@ -628,7 +634,9 @@
                                              size_t filter_count,
                                              const grpc_channel_args *args) {
   size_t i;
-  int census_enabled = grpc_channel_args_is_census_enabled(args);
+  /* TODO(census): restore this once we finalize census filter etc.
+     int census_enabled = grpc_channel_args_is_census_enabled(args); */
+  int census_enabled = 0;
 
   grpc_server *server = gpr_malloc(sizeof(grpc_server));
 
@@ -654,9 +662,10 @@
   server->channel_filters =
       gpr_malloc(server->channel_filter_count * sizeof(grpc_channel_filter *));
   server->channel_filters[0] = &server_surface_filter;
+  /* TODO(census): restore this once we rework census filter
   if (census_enabled) {
     server->channel_filters[1] = &grpc_server_census_filter;
-  }
+    } */
   for (i = 0; i < filter_count; i++) {
     server->channel_filters[i + 1 + census_enabled] = filters[i];
   }
diff --git a/src/csharp/Grpc.Tools.nuspec b/src/csharp/Grpc.Tools.nuspec
new file mode 100644
index 0000000..155c2ef
--- /dev/null
+++ b/src/csharp/Grpc.Tools.nuspec
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<package>
+  <metadata>
+    <id>Grpc.Tools</id>
+    <title>gRPC C# Tools</title>
+    <summary>Tools for C# implementation of gRPC - an RPC library and framework</summary>
+    <description>Precompiled Windows binaries for generating protocol buffer messages and gRPC client/server code</description>
+    <version>0.5.0</version>
+    <authors>Google Inc.</authors>
+    <owners>grpc-packages</owners>
+    <licenseUrl>https://github.com/grpc/grpc/blob/master/LICENSE</licenseUrl>
+    <projectUrl>https://github.com/grpc/grpc</projectUrl>
+    <requireLicenseAcceptance>false</requireLicenseAcceptance>
+    <releaseNotes>protoc.exe - protocol buffer compiler v3.0.0-alpha-3; grpc_csharp_plugin.exe - gRPC C# protoc plugin version 0.5.0</releaseNotes>
+    <copyright>Copyright 2015, Google Inc.</copyright>
+    <tags>gRPC RPC Protocol HTTP/2</tags>
+  </metadata>
+  <files>
+    <file src="protoc.exe" target="tools" />
+    <file src="grpc_csharp_plugin.exe" target="tools" />
+  </files>
+</package>
diff --git a/src/csharp/Grpc.nuspec b/src/csharp/Grpc.nuspec
index b9a76f2..263e016 100644
--- a/src/csharp/Grpc.nuspec
+++ b/src/csharp/Grpc.nuspec
@@ -5,7 +5,7 @@
     <title>gRPC C#</title>
     <summary>C# implementation of gRPC - an RPC library and framework</summary>
     <description>C# implementation of gRPC - an RPC library and framework. See project site for more info.</description>
-    <version>0.5.0</version>
+    <version>0.5.0.1</version>
     <authors>Google Inc.</authors>
     <owners>grpc-packages</owners>
     <licenseUrl>https://github.com/grpc/grpc/blob/master/LICENSE</licenseUrl>
@@ -18,8 +18,5 @@
       <dependency id="Grpc.Core" version="0.5.0" />
     </dependencies>
   </metadata>
-  <files>
-     <file src="protoc.exe" target="tools" />
-	 <file src="grpc_csharp_plugin.exe" target="tools" />
-  </files>
+  <files/>
 </package>
diff --git a/src/csharp/build_packages.bat b/src/csharp/build_packages.bat
index 7cb78bd..3412129 100644
--- a/src/csharp/build_packages.bat
+++ b/src/csharp/build_packages.bat
@@ -13,6 +13,7 @@
 %NUGET% pack ..\..\vsprojects\nuget_package\grpc.native.csharp_ext.nuspec || goto :error
 %NUGET% pack Grpc.Core\Grpc.Core.nuspec -Symbols || goto :error
 %NUGET% pack Grpc.Auth\Grpc.Auth.nuspec -Symbols || goto :error
+%NUGET% pack Grpc.Tools.nuspec || goto :error
 %NUGET% pack Grpc.nuspec || goto :error
 
 goto :EOF
diff --git a/src/csharp/buildall.bat b/src/csharp/buildall.bat
index 34ad923..68c61ef 100644
--- a/src/csharp/buildall.bat
+++ b/src/csharp/buildall.bat
@@ -5,7 +5,7 @@
 @call "%VS120COMNTOOLS%\..\..\vc\vcvarsall.bat" x86
 
 @rem Build the C# native extension
-msbuild ..\..\vsprojects\grpc.sln /t:grpc_csharp_ext || goto :error
+msbuild ..\..\vsprojects\grpc.sln /t:grpc_csharp_ext /p:PlatformToolset=v120 || goto :error
 
 msbuild Grpc.sln /p:Configuration=Debug || goto :error
 msbuild Grpc.sln /p:Configuration=Release || goto :error
diff --git a/src/objective-c/GRPCClient/private/GRPCSecureChannel.m b/src/objective-c/GRPCClient/private/GRPCSecureChannel.m
index 47bdfe3..2cbc6e0 100644
--- a/src/objective-c/GRPCClient/private/GRPCSecureChannel.m
+++ b/src/objective-c/GRPCClient/private/GRPCSecureChannel.m
@@ -38,13 +38,17 @@
 @implementation GRPCSecureChannel
 
 - (instancetype)initWithHost:(NSString *)host {
-  // TODO(jcanizales): Load certs only once.
-  NSURL *certsURL = [[NSBundle mainBundle] URLForResource:@"gRPC.bundle/roots" withExtension:@"pem"];
-  NSData *certsData = [NSData dataWithContentsOfURL:certsURL];
-  NSString *certsString = [[NSString alloc] initWithData:certsData encoding:NSUTF8StringEncoding];
-
-  grpc_credentials *credentials = grpc_ssl_credentials_create(certsString.UTF8String, NULL);
-  return (self = [super initWithChannel:grpc_secure_channel_create(credentials,
+  static const grpc_credentials *kCredentials;
+  static dispatch_once_t loading;
+  dispatch_once(&loading, ^{
+    // Do not use NSBundle.mainBundle, as it's nil for tests of library projects.
+    NSBundle *bundle = [NSBundle bundleForClass:self.class];
+    NSString *certsPath = [bundle pathForResource:@"gRPC.bundle/roots" ofType:@"pem"];
+    NSData *certsData = [NSData dataWithContentsOfFile:certsPath];
+    NSString *certsString = [[NSString alloc] initWithData:certsData encoding:NSUTF8StringEncoding];
+    kCredentials = grpc_ssl_credentials_create(certsString.UTF8String, NULL);
+  });
+  return (self = [super initWithChannel:grpc_secure_channel_create(kCredentials,
                                                                    host.UTF8String,
                                                                    NULL)]);
 }
diff --git a/src/objective-c/README.md b/src/objective-c/README.md
index 167016c..921eb69 100644
--- a/src/objective-c/README.md
+++ b/src/objective-c/README.md
@@ -50,13 +50,15 @@
   s.osx.deployment_target = '10.8'
 
   s.subspec 'Messages' do |ms|
-    ms.source_files = '*.pbobjc.{h,m}'
+    ms.source_files = '*.pbobjc.{h,m}', '**/*.pbobjc.{h,m}'
+    ms.header_mappings_dir = '.'
     ms.requires_arc = false
     ms.dependency 'Protobuf', '~> 3.0'
   end
 
   s.subspec 'Services' do |ss|
-    ss.source_files = '*.pbrpc.{h,m}'
+    ss.source_files = '*.pbrpc.{h,m}', '**/*.pbrpc.{h,m}'
+    ss.header_mappings_dir = '.'
     ss.requires_arc = true
     ss.dependency 'gRPC', '~> 0.0'
     ss.dependency '<Podspec file name>/Messages'
diff --git a/src/objective-c/examples/Sample/Podfile b/src/objective-c/examples/Sample/Podfile
index e8b7864..f3c49c1 100644
--- a/src/objective-c/examples/Sample/Podfile
+++ b/src/objective-c/examples/Sample/Podfile
@@ -3,13 +3,7 @@
 
 pod 'gRPC', :path => "../../../.."
 pod 'Protobuf', :git => 'https://github.com/google/protobuf.git'
-pod 'Route_guide', :path => "RouteGuideClient"
-pod 'RemoteTest', :path => "RemoteTestClient"
-
-link_with 'Sample', 'SampleTests'
+pod 'RemoteTest', :path => "../../generated_libraries/RemoteTestClient"
 
 target 'Sample' do
 end
-
-target 'SampleTests' do
-end
diff --git a/src/objective-c/examples/Sample/Sample.xcodeproj/project.pbxproj b/src/objective-c/examples/Sample/Sample.xcodeproj/project.pbxproj
index 17c2255..611eb60 100644
--- a/src/objective-c/examples/Sample/Sample.xcodeproj/project.pbxproj
+++ b/src/objective-c/examples/Sample/Sample.xcodeproj/project.pbxproj
@@ -7,33 +7,16 @@
 	objects = {
 
 /* Begin PBXBuildFile section */
-		60BBBBB15823BBF7639D7AA9 /* libPods.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 2DC7B7C4C0410F43B9621631 /* libPods.a */; };
-		6340F0491AE66E3300FB6A3D /* RemoteProtoTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 6340F0481AE66E3300FB6A3D /* RemoteProtoTests.m */; };
-		6356D1DE1AC11FE00075FBBC /* RemoteTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 6356D1DD1AC11FE00075FBBC /* RemoteTests.m */; };
 		6369A2701A9322E20015FC5C /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 6369A26F1A9322E20015FC5C /* main.m */; };
 		6369A2731A9322E20015FC5C /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 6369A2721A9322E20015FC5C /* AppDelegate.m */; };
 		6369A2761A9322E20015FC5C /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6369A2751A9322E20015FC5C /* ViewController.m */; };
 		6369A2791A9322E20015FC5C /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6369A2771A9322E20015FC5C /* Main.storyboard */; };
 		6369A27B1A9322E20015FC5C /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6369A27A1A9322E20015FC5C /* Images.xcassets */; };
-		6369A27E1A9322E20015FC5C /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 6369A27C1A9322E20015FC5C /* LaunchScreen.xib */; };
-		6369A28A1A9322E20015FC5C /* SampleTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 6369A2891A9322E20015FC5C /* SampleTests.m */; };
 		FC81FE63CA655031F3524EC0 /* libPods.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 2DC7B7C4C0410F43B9621631 /* libPods.a */; };
 /* End PBXBuildFile section */
 
-/* Begin PBXContainerItemProxy section */
-		6369A2841A9322E20015FC5C /* PBXContainerItemProxy */ = {
-			isa = PBXContainerItemProxy;
-			containerPortal = 6369A2621A9322E20015FC5C /* Project object */;
-			proxyType = 1;
-			remoteGlobalIDString = 6369A2691A9322E20015FC5C;
-			remoteInfo = Sample;
-		};
-/* End PBXContainerItemProxy section */
-
 /* Begin PBXFileReference section */
 		2DC7B7C4C0410F43B9621631 /* libPods.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libPods.a; sourceTree = BUILT_PRODUCTS_DIR; };
-		6340F0481AE66E3300FB6A3D /* RemoteProtoTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RemoteProtoTests.m; sourceTree = "<group>"; };
-		6356D1DD1AC11FE00075FBBC /* RemoteTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RemoteTests.m; sourceTree = "<group>"; };
 		6369A26A1A9322E20015FC5C /* Sample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Sample.app; sourceTree = BUILT_PRODUCTS_DIR; };
 		6369A26E1A9322E20015FC5C /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
 		6369A26F1A9322E20015FC5C /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
@@ -43,10 +26,6 @@
 		6369A2751A9322E20015FC5C /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = "<group>"; };
 		6369A2781A9322E20015FC5C /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
 		6369A27A1A9322E20015FC5C /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = "<group>"; };
-		6369A27D1A9322E20015FC5C /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = "<group>"; };
-		6369A2831A9322E20015FC5C /* SampleTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SampleTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
-		6369A2881A9322E20015FC5C /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
-		6369A2891A9322E20015FC5C /* SampleTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SampleTests.m; sourceTree = "<group>"; };
 		AC29DD6FCDF962F519FEBB0D /* Pods.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = Pods.debug.xcconfig; path = "Pods/Target Support Files/Pods/Pods.debug.xcconfig"; sourceTree = "<group>"; };
 		C68330F8D451CC6ACEABA09F /* Pods.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = Pods.release.xcconfig; path = "Pods/Target Support Files/Pods/Pods.release.xcconfig"; sourceTree = "<group>"; };
 /* End PBXFileReference section */
@@ -60,14 +39,6 @@
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
-		6369A2801A9322E20015FC5C /* Frameworks */ = {
-			isa = PBXFrameworksBuildPhase;
-			buildActionMask = 2147483647;
-			files = (
-				60BBBBB15823BBF7639D7AA9 /* libPods.a in Frameworks */,
-			);
-			runOnlyForDeploymentPostprocessing = 0;
-		};
 /* End PBXFrameworksBuildPhase section */
 
 /* Begin PBXGroup section */
@@ -75,7 +46,6 @@
 			isa = PBXGroup;
 			children = (
 				6369A26C1A9322E20015FC5C /* Sample */,
-				6369A2861A9322E20015FC5C /* SampleTests */,
 				6369A26B1A9322E20015FC5C /* Products */,
 				AB3331C9AE6488E61B2B094E /* Pods */,
 				C4C2C5219053E079C9EFB930 /* Frameworks */,
@@ -86,7 +56,6 @@
 			isa = PBXGroup;
 			children = (
 				6369A26A1A9322E20015FC5C /* Sample.app */,
-				6369A2831A9322E20015FC5C /* SampleTests.xctest */,
 			);
 			name = Products;
 			sourceTree = "<group>";
@@ -100,7 +69,6 @@
 				6369A2751A9322E20015FC5C /* ViewController.m */,
 				6369A2771A9322E20015FC5C /* Main.storyboard */,
 				6369A27A1A9322E20015FC5C /* Images.xcassets */,
-				6369A27C1A9322E20015FC5C /* LaunchScreen.xib */,
 				6369A26D1A9322E20015FC5C /* Supporting Files */,
 			);
 			path = Sample;
@@ -115,25 +83,6 @@
 			name = "Supporting Files";
 			sourceTree = "<group>";
 		};
-		6369A2861A9322E20015FC5C /* SampleTests */ = {
-			isa = PBXGroup;
-			children = (
-				6340F0481AE66E3300FB6A3D /* RemoteProtoTests.m */,
-				6369A2891A9322E20015FC5C /* SampleTests.m */,
-				6369A2871A9322E20015FC5C /* Supporting Files */,
-				6356D1DD1AC11FE00075FBBC /* RemoteTests.m */,
-			);
-			path = SampleTests;
-			sourceTree = "<group>";
-		};
-		6369A2871A9322E20015FC5C /* Supporting Files */ = {
-			isa = PBXGroup;
-			children = (
-				6369A2881A9322E20015FC5C /* Info.plist */,
-			);
-			name = "Supporting Files";
-			sourceTree = "<group>";
-		};
 		AB3331C9AE6488E61B2B094E /* Pods */ = {
 			isa = PBXGroup;
 			children = (
@@ -173,26 +122,6 @@
 			productReference = 6369A26A1A9322E20015FC5C /* Sample.app */;
 			productType = "com.apple.product-type.application";
 		};
-		6369A2821A9322E20015FC5C /* SampleTests */ = {
-			isa = PBXNativeTarget;
-			buildConfigurationList = 6369A2901A9322E20015FC5C /* Build configuration list for PBXNativeTarget "SampleTests" */;
-			buildPhases = (
-				75C393B2FDC60A22B2121058 /* Check Pods Manifest.lock */,
-				6369A27F1A9322E20015FC5C /* Sources */,
-				6369A2801A9322E20015FC5C /* Frameworks */,
-				6369A2811A9322E20015FC5C /* Resources */,
-				7B8CDC152F76D6014A96C798 /* Copy Pods Resources */,
-			);
-			buildRules = (
-			);
-			dependencies = (
-				6369A2851A9322E20015FC5C /* PBXTargetDependency */,
-			);
-			name = SampleTests;
-			productName = SampleTests;
-			productReference = 6369A2831A9322E20015FC5C /* SampleTests.xctest */;
-			productType = "com.apple.product-type.bundle.unit-test";
-		};
 /* End PBXNativeTarget section */
 
 /* Begin PBXProject section */
@@ -205,10 +134,6 @@
 					6369A2691A9322E20015FC5C = {
 						CreatedOnToolsVersion = 6.1.1;
 					};
-					6369A2821A9322E20015FC5C = {
-						CreatedOnToolsVersion = 6.1.1;
-						TestTargetID = 6369A2691A9322E20015FC5C;
-					};
 				};
 			};
 			buildConfigurationList = 6369A2651A9322E20015FC5C /* Build configuration list for PBXProject "Sample" */;
@@ -225,7 +150,6 @@
 			projectRoot = "";
 			targets = (
 				6369A2691A9322E20015FC5C /* Sample */,
-				6369A2821A9322E20015FC5C /* SampleTests */,
 			);
 		};
 /* End PBXProject section */
@@ -236,18 +160,10 @@
 			buildActionMask = 2147483647;
 			files = (
 				6369A2791A9322E20015FC5C /* Main.storyboard in Resources */,
-				6369A27E1A9322E20015FC5C /* LaunchScreen.xib in Resources */,
 				6369A27B1A9322E20015FC5C /* Images.xcassets in Resources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
-		6369A2811A9322E20015FC5C /* Resources */ = {
-			isa = PBXResourcesBuildPhase;
-			buildActionMask = 2147483647;
-			files = (
-			);
-			runOnlyForDeploymentPostprocessing = 0;
-		};
 /* End PBXResourcesBuildPhase section */
 
 /* Begin PBXShellScriptBuildPhase section */
@@ -281,36 +197,6 @@
 			shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n    cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n    exit 1\nfi\n";
 			showEnvVarsInLog = 0;
 		};
-		75C393B2FDC60A22B2121058 /* Check Pods Manifest.lock */ = {
-			isa = PBXShellScriptBuildPhase;
-			buildActionMask = 2147483647;
-			files = (
-			);
-			inputPaths = (
-			);
-			name = "Check Pods Manifest.lock";
-			outputPaths = (
-			);
-			runOnlyForDeploymentPostprocessing = 0;
-			shellPath = /bin/sh;
-			shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n    cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n    exit 1\nfi\n";
-			showEnvVarsInLog = 0;
-		};
-		7B8CDC152F76D6014A96C798 /* Copy Pods Resources */ = {
-			isa = PBXShellScriptBuildPhase;
-			buildActionMask = 2147483647;
-			files = (
-			);
-			inputPaths = (
-			);
-			name = "Copy Pods Resources";
-			outputPaths = (
-			);
-			runOnlyForDeploymentPostprocessing = 0;
-			shellPath = /bin/sh;
-			shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods/Pods-resources.sh\"\n";
-			showEnvVarsInLog = 0;
-		};
 /* End PBXShellScriptBuildPhase section */
 
 /* Begin PBXSourcesBuildPhase section */
@@ -324,26 +210,8 @@
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
-		6369A27F1A9322E20015FC5C /* Sources */ = {
-			isa = PBXSourcesBuildPhase;
-			buildActionMask = 2147483647;
-			files = (
-				6369A28A1A9322E20015FC5C /* SampleTests.m in Sources */,
-				6340F0491AE66E3300FB6A3D /* RemoteProtoTests.m in Sources */,
-				6356D1DE1AC11FE00075FBBC /* RemoteTests.m in Sources */,
-			);
-			runOnlyForDeploymentPostprocessing = 0;
-		};
 /* End PBXSourcesBuildPhase section */
 
-/* Begin PBXTargetDependency section */
-		6369A2851A9322E20015FC5C /* PBXTargetDependency */ = {
-			isa = PBXTargetDependency;
-			target = 6369A2691A9322E20015FC5C /* Sample */;
-			targetProxy = 6369A2841A9322E20015FC5C /* PBXContainerItemProxy */;
-		};
-/* End PBXTargetDependency section */
-
 /* Begin PBXVariantGroup section */
 		6369A2771A9322E20015FC5C /* Main.storyboard */ = {
 			isa = PBXVariantGroup;
@@ -353,14 +221,6 @@
 			name = Main.storyboard;
 			sourceTree = "<group>";
 		};
-		6369A27C1A9322E20015FC5C /* LaunchScreen.xib */ = {
-			isa = PBXVariantGroup;
-			children = (
-				6369A27D1A9322E20015FC5C /* Base */,
-			);
-			name = LaunchScreen.xib;
-			sourceTree = "<group>";
-		};
 /* End PBXVariantGroup section */
 
 /* Begin XCBuildConfiguration section */
@@ -464,42 +324,6 @@
 			};
 			name = Release;
 		};
-		6369A2911A9322E20015FC5C /* Debug */ = {
-			isa = XCBuildConfiguration;
-			baseConfigurationReference = AC29DD6FCDF962F519FEBB0D /* Pods.debug.xcconfig */;
-			buildSettings = {
-				BUNDLE_LOADER = "$(TEST_HOST)";
-				FRAMEWORK_SEARCH_PATHS = (
-					"$(SDKROOT)/Developer/Library/Frameworks",
-					"$(inherited)",
-				);
-				GCC_PREPROCESSOR_DEFINITIONS = (
-					"DEBUG=1",
-					"$(inherited)",
-				);
-				INFOPLIST_FILE = SampleTests/Info.plist;
-				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
-				PRODUCT_NAME = "$(TARGET_NAME)";
-				TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Sample.app/Sample";
-			};
-			name = Debug;
-		};
-		6369A2921A9322E20015FC5C /* Release */ = {
-			isa = XCBuildConfiguration;
-			baseConfigurationReference = C68330F8D451CC6ACEABA09F /* Pods.release.xcconfig */;
-			buildSettings = {
-				BUNDLE_LOADER = "$(TEST_HOST)";
-				FRAMEWORK_SEARCH_PATHS = (
-					"$(SDKROOT)/Developer/Library/Frameworks",
-					"$(inherited)",
-				);
-				INFOPLIST_FILE = SampleTests/Info.plist;
-				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
-				PRODUCT_NAME = "$(TARGET_NAME)";
-				TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Sample.app/Sample";
-			};
-			name = Release;
-		};
 /* End XCBuildConfiguration section */
 
 /* Begin XCConfigurationList section */
@@ -521,15 +345,6 @@
 			defaultConfigurationIsVisible = 0;
 			defaultConfigurationName = Release;
 		};
-		6369A2901A9322E20015FC5C /* Build configuration list for PBXNativeTarget "SampleTests" */ = {
-			isa = XCConfigurationList;
-			buildConfigurations = (
-				6369A2911A9322E20015FC5C /* Debug */,
-				6369A2921A9322E20015FC5C /* Release */,
-			);
-			defaultConfigurationIsVisible = 0;
-			defaultConfigurationName = Release;
-		};
 /* End XCConfigurationList section */
 	};
 	rootObject = 6369A2621A9322E20015FC5C /* Project object */;
diff --git a/src/objective-c/examples/Sample/Sample/AppDelegate.h b/src/objective-c/examples/Sample/Sample/AppDelegate.h
index b1857f2..102e7f3 100644
--- a/src/objective-c/examples/Sample/Sample/AppDelegate.h
+++ b/src/objective-c/examples/Sample/Sample/AppDelegate.h
@@ -34,8 +34,5 @@
 #import <UIKit/UIKit.h>
 
 @interface AppDelegate : UIResponder <UIApplicationDelegate>
-
 @property (strong, nonatomic) UIWindow *window;
-
 @end
-
diff --git a/src/objective-c/examples/Sample/Sample/AppDelegate.m b/src/objective-c/examples/Sample/Sample/AppDelegate.m
index 12e1ad9..a38e366 100644
--- a/src/objective-c/examples/Sample/Sample/AppDelegate.m
+++ b/src/objective-c/examples/Sample/Sample/AppDelegate.m
@@ -33,13 +33,5 @@
 
 #import "AppDelegate.h"
 
-@interface AppDelegate ()
-@end
-
 @implementation AppDelegate
-
-- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
-  return YES;
-}
-
 @end
diff --git a/src/objective-c/examples/Sample/Sample/Base.lproj/LaunchScreen.xib b/src/objective-c/examples/Sample/Sample/Base.lproj/LaunchScreen.xib
deleted file mode 100644
index c51a8e1..0000000
--- a/src/objective-c/examples/Sample/Sample/Base.lproj/LaunchScreen.xib
+++ /dev/null
@@ -1,41 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="6214" systemVersion="14A314h" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES">
-    <dependencies>
-        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6207"/>
-        <capability name="Constraints with non-1.0 multipliers" minToolsVersion="5.1"/>
-    </dependencies>
-    <objects>
-        <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
-        <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
-        <view contentMode="scaleToFill" id="iN0-l3-epB">
-            <rect key="frame" x="0.0" y="0.0" width="480" height="480"/>
-            <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
-            <subviews>
-                <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="  Copyright (c) 2015 gRPC. All rights reserved." textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="9" translatesAutoresizingMaskIntoConstraints="NO" id="8ie-xW-0ye">
-                    <rect key="frame" x="20" y="439" width="441" height="21"/>
-                    <fontDescription key="fontDescription" type="system" pointSize="17"/>
-                    <color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
-                    <nil key="highlightedColor"/>
-                </label>
-                <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Sample" textAlignment="center" lineBreakMode="middleTruncation" baselineAdjustment="alignBaselines" minimumFontSize="18" translatesAutoresizingMaskIntoConstraints="NO" id="kId-c2-rCX">
-                    <rect key="frame" x="20" y="140" width="441" height="43"/>
-                    <fontDescription key="fontDescription" type="boldSystem" pointSize="36"/>
-                    <color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
-                    <nil key="highlightedColor"/>
-                </label>
-            </subviews>
-            <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
-            <constraints>
-                <constraint firstItem="kId-c2-rCX" firstAttribute="centerY" secondItem="iN0-l3-epB" secondAttribute="bottom" multiplier="1/3" constant="1" id="5cJ-9S-tgC"/>
-                <constraint firstAttribute="centerX" secondItem="kId-c2-rCX" secondAttribute="centerX" id="Koa-jz-hwk"/>
-                <constraint firstAttribute="bottom" secondItem="8ie-xW-0ye" secondAttribute="bottom" constant="20" id="Kzo-t9-V3l"/>
-                <constraint firstItem="8ie-xW-0ye" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="20" symbolic="YES" id="MfP-vx-nX0"/>
-                <constraint firstAttribute="centerX" secondItem="8ie-xW-0ye" secondAttribute="centerX" id="ZEH-qu-HZ9"/>
-                <constraint firstItem="kId-c2-rCX" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" constant="20" symbolic="YES" id="fvb-Df-36g"/>
-            </constraints>
-            <nil key="simulatedStatusBarMetrics"/>
-            <freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
-            <point key="canvasLocation" x="548" y="455"/>
-        </view>
-    </objects>
-</document>
diff --git a/src/objective-c/examples/Sample/Sample/Base.lproj/Main.storyboard b/src/objective-c/examples/Sample/Sample/Base.lproj/Main.storyboard
index f56d2f3..8887b9e 100644
--- a/src/objective-c/examples/Sample/Sample/Base.lproj/Main.storyboard
+++ b/src/objective-c/examples/Sample/Sample/Base.lproj/Main.storyboard
@@ -1,13 +1,14 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="6211" systemVersion="14A298i" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="BYZ-38-t0r">
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="7702" systemVersion="14D131" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="BYZ-38-t0r">
     <dependencies>
-        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6204"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="7701"/>
+        <capability name="Constraints to layout margins" minToolsVersion="6.0"/>
     </dependencies>
     <scenes>
         <!--View Controller-->
         <scene sceneID="tne-QT-ifu">
             <objects>
-                <viewController id="BYZ-38-t0r" customClass="ViewController" customModuleProvider="" sceneMemberID="viewController">
+                <viewController id="BYZ-38-t0r" customClass="ViewController" sceneMemberID="viewController">
                     <layoutGuides>
                         <viewControllerLayoutGuide type="top" id="y3c-jy-aDJ"/>
                         <viewControllerLayoutGuide type="bottom" id="wfy-db-euE"/>
@@ -15,7 +16,38 @@
                     <view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
                         <rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
                         <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+                        <subviews>
+                            <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" misplaced="YES" lineBreakMode="wordWrap" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="BWr-eN-L3y">
+                                <rect key="frame" x="16" y="20" width="568" height="150"/>
+                                <constraints>
+                                    <constraint firstAttribute="width" constant="385" id="exg-IV-Kl0"/>
+                                </constraints>
+                                <string key="text">Sample app launch finished.
+Check ViewController.m for the gRPC calls made, and the logs of this app for their results.
+(You may need to make XCode's Debug Area visible).</string>
+                                <fontDescription key="fontDescription" type="system" pointSize="17"/>
+                                <color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
+                                <nil key="highlightedColor"/>
+                                <variation key="default">
+                                    <mask key="constraints">
+                                        <exclude reference="exg-IV-Kl0"/>
+                                    </mask>
+                                </variation>
+                            </label>
+                        </subviews>
                         <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
+                        <constraints>
+                            <constraint firstItem="wfy-db-euE" firstAttribute="top" secondItem="BWr-eN-L3y" secondAttribute="bottom" constant="430" id="KFC-7p-hRl"/>
+                            <constraint firstAttribute="trailing" secondItem="BWr-eN-L3y" secondAttribute="trailing" constant="16" id="M9C-nN-tFv"/>
+                            <constraint firstItem="BWr-eN-L3y" firstAttribute="leading" secondItem="8bC-Xf-vdC" secondAttribute="leadingMargin" id="SaP-0S-2LK"/>
+                            <constraint firstItem="wfy-db-euE" firstAttribute="top" secondItem="BWr-eN-L3y" secondAttribute="bottom" id="wjC-O4-kJg"/>
+                            <constraint firstItem="BWr-eN-L3y" firstAttribute="top" secondItem="y3c-jy-aDJ" secondAttribute="bottom" id="ygF-6t-hrg"/>
+                        </constraints>
+                        <variation key="default">
+                            <mask key="constraints">
+                                <exclude reference="KFC-7p-hRl"/>
+                            </mask>
+                        </variation>
                     </view>
                 </viewController>
                 <placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
diff --git a/src/objective-c/examples/Sample/Sample/Info.plist b/src/objective-c/examples/Sample/Sample/Info.plist
index ffdc8b3..4436635 100644
--- a/src/objective-c/examples/Sample/Sample/Info.plist
+++ b/src/objective-c/examples/Sample/Sample/Info.plist
@@ -23,7 +23,7 @@
 	<key>LSRequiresIPhoneOS</key>
 	<true/>
 	<key>UILaunchStoryboardName</key>
-	<string>LaunchScreen</string>
+	<string>Main</string>
 	<key>UIMainStoryboardFile</key>
 	<string>Main</string>
 	<key>UIRequiredDeviceCapabilities</key>
diff --git a/src/objective-c/examples/Sample/Sample/ViewController.m b/src/objective-c/examples/Sample/Sample/ViewController.m
index 9b331fe..0011a45 100644
--- a/src/objective-c/examples/Sample/Sample/ViewController.m
+++ b/src/objective-c/examples/Sample/Sample/ViewController.m
@@ -40,9 +40,6 @@
 #import <RemoteTest/Messages.pbobjc.h>
 #import <RemoteTest/Test.pbrpc.h>
 
-@interface ViewController ()
-@end
-
 @implementation ViewController
 
 - (void)viewDidLoad {
diff --git a/src/objective-c/examples/Sample/RemoteTestClient/Empty.pbobjc.h b/src/objective-c/generated_libraries/RemoteTestClient/Empty.pbobjc.h
similarity index 100%
rename from src/objective-c/examples/Sample/RemoteTestClient/Empty.pbobjc.h
rename to src/objective-c/generated_libraries/RemoteTestClient/Empty.pbobjc.h
diff --git a/src/objective-c/examples/Sample/RemoteTestClient/Empty.pbobjc.m b/src/objective-c/generated_libraries/RemoteTestClient/Empty.pbobjc.m
similarity index 100%
rename from src/objective-c/examples/Sample/RemoteTestClient/Empty.pbobjc.m
rename to src/objective-c/generated_libraries/RemoteTestClient/Empty.pbobjc.m
diff --git a/src/objective-c/examples/Sample/RemoteTestClient/Messages.pbobjc.h b/src/objective-c/generated_libraries/RemoteTestClient/Messages.pbobjc.h
similarity index 100%
rename from src/objective-c/examples/Sample/RemoteTestClient/Messages.pbobjc.h
rename to src/objective-c/generated_libraries/RemoteTestClient/Messages.pbobjc.h
diff --git a/src/objective-c/examples/Sample/RemoteTestClient/Messages.pbobjc.m b/src/objective-c/generated_libraries/RemoteTestClient/Messages.pbobjc.m
similarity index 100%
rename from src/objective-c/examples/Sample/RemoteTestClient/Messages.pbobjc.m
rename to src/objective-c/generated_libraries/RemoteTestClient/Messages.pbobjc.m
diff --git a/src/objective-c/examples/Sample/RemoteTestClient/RemoteTest.podspec b/src/objective-c/generated_libraries/RemoteTestClient/RemoteTest.podspec
similarity index 100%
rename from src/objective-c/examples/Sample/RemoteTestClient/RemoteTest.podspec
rename to src/objective-c/generated_libraries/RemoteTestClient/RemoteTest.podspec
diff --git a/src/objective-c/examples/Sample/RemoteTestClient/Test.pbobjc.h b/src/objective-c/generated_libraries/RemoteTestClient/Test.pbobjc.h
similarity index 100%
rename from src/objective-c/examples/Sample/RemoteTestClient/Test.pbobjc.h
rename to src/objective-c/generated_libraries/RemoteTestClient/Test.pbobjc.h
diff --git a/src/objective-c/examples/Sample/RemoteTestClient/Test.pbobjc.m b/src/objective-c/generated_libraries/RemoteTestClient/Test.pbobjc.m
similarity index 100%
rename from src/objective-c/examples/Sample/RemoteTestClient/Test.pbobjc.m
rename to src/objective-c/generated_libraries/RemoteTestClient/Test.pbobjc.m
diff --git a/src/objective-c/examples/Sample/RemoteTestClient/Test.pbrpc.h b/src/objective-c/generated_libraries/RemoteTestClient/Test.pbrpc.h
similarity index 100%
rename from src/objective-c/examples/Sample/RemoteTestClient/Test.pbrpc.h
rename to src/objective-c/generated_libraries/RemoteTestClient/Test.pbrpc.h
diff --git a/src/objective-c/examples/Sample/RemoteTestClient/Test.pbrpc.m b/src/objective-c/generated_libraries/RemoteTestClient/Test.pbrpc.m
similarity index 100%
rename from src/objective-c/examples/Sample/RemoteTestClient/Test.pbrpc.m
rename to src/objective-c/generated_libraries/RemoteTestClient/Test.pbrpc.m
diff --git a/src/objective-c/examples/Sample/RemoteTestClient/empty.proto b/src/objective-c/generated_libraries/RemoteTestClient/empty.proto
similarity index 100%
rename from src/objective-c/examples/Sample/RemoteTestClient/empty.proto
rename to src/objective-c/generated_libraries/RemoteTestClient/empty.proto
diff --git a/src/objective-c/examples/Sample/RemoteTestClient/messages.proto b/src/objective-c/generated_libraries/RemoteTestClient/messages.proto
similarity index 100%
rename from src/objective-c/examples/Sample/RemoteTestClient/messages.proto
rename to src/objective-c/generated_libraries/RemoteTestClient/messages.proto
diff --git a/src/objective-c/examples/Sample/RemoteTestClient/test.proto b/src/objective-c/generated_libraries/RemoteTestClient/test.proto
similarity index 100%
rename from src/objective-c/examples/Sample/RemoteTestClient/test.proto
rename to src/objective-c/generated_libraries/RemoteTestClient/test.proto
diff --git a/src/objective-c/examples/Sample/RouteGuideClient/RouteGuide.pbobjc.h b/src/objective-c/generated_libraries/RouteGuideClient/RouteGuide.pbobjc.h
similarity index 100%
rename from src/objective-c/examples/Sample/RouteGuideClient/RouteGuide.pbobjc.h
rename to src/objective-c/generated_libraries/RouteGuideClient/RouteGuide.pbobjc.h
diff --git a/src/objective-c/examples/Sample/RouteGuideClient/RouteGuide.pbobjc.m b/src/objective-c/generated_libraries/RouteGuideClient/RouteGuide.pbobjc.m
similarity index 100%
rename from src/objective-c/examples/Sample/RouteGuideClient/RouteGuide.pbobjc.m
rename to src/objective-c/generated_libraries/RouteGuideClient/RouteGuide.pbobjc.m
diff --git a/src/objective-c/examples/Sample/RouteGuideClient/RouteGuide.pbrpc.h b/src/objective-c/generated_libraries/RouteGuideClient/RouteGuide.pbrpc.h
similarity index 100%
rename from src/objective-c/examples/Sample/RouteGuideClient/RouteGuide.pbrpc.h
rename to src/objective-c/generated_libraries/RouteGuideClient/RouteGuide.pbrpc.h
diff --git a/src/objective-c/examples/Sample/RouteGuideClient/RouteGuide.pbrpc.m b/src/objective-c/generated_libraries/RouteGuideClient/RouteGuide.pbrpc.m
similarity index 100%
rename from src/objective-c/examples/Sample/RouteGuideClient/RouteGuide.pbrpc.m
rename to src/objective-c/generated_libraries/RouteGuideClient/RouteGuide.pbrpc.m
diff --git a/src/objective-c/examples/Sample/RouteGuideClient/Route_guide.podspec b/src/objective-c/generated_libraries/RouteGuideClient/Route_guide.podspec
similarity index 100%
rename from src/objective-c/examples/Sample/RouteGuideClient/Route_guide.podspec
rename to src/objective-c/generated_libraries/RouteGuideClient/Route_guide.podspec
diff --git a/src/objective-c/examples/Sample/RouteGuideClient/route_guide.proto b/src/objective-c/generated_libraries/RouteGuideClient/route_guide.proto
similarity index 100%
rename from src/objective-c/examples/Sample/RouteGuideClient/route_guide.proto
rename to src/objective-c/generated_libraries/RouteGuideClient/route_guide.proto
diff --git a/src/objective-c/examples/Sample/SampleTests/RemoteTests.m b/src/objective-c/tests/GRPCClientTests.m
similarity index 95%
rename from src/objective-c/examples/Sample/SampleTests/RemoteTests.m
rename to src/objective-c/tests/GRPCClientTests.m
index ceb72cf..713ea28 100644
--- a/src/objective-c/examples/Sample/SampleTests/RemoteTests.m
+++ b/src/objective-c/tests/GRPCClientTests.m
@@ -40,10 +40,13 @@
 #import <gRPC/GRXWriteable.h>
 #import <RemoteTest/Messages.pbobjc.h>
 
-@interface RemoteTests : XCTestCase
+// These are a few tests similar to InteropTests, but which use the generic gRPC client (GRPCCall)
+// rather than a generated proto library on top of it.
+
+@interface GRPCClientTests : XCTestCase
 @end
 
-@implementation RemoteTests
+@implementation GRPCClientTests
 
 - (void)testConnectionToRemoteServer {
   __weak XCTestExpectation *expectation = [self expectationWithDescription:@"Server reachable."];
diff --git a/src/objective-c/examples/Sample/SampleTests/Info.plist b/src/objective-c/tests/Info.plist
similarity index 91%
rename from src/objective-c/examples/Sample/SampleTests/Info.plist
rename to src/objective-c/tests/Info.plist
index f547b0b..fbeeb96 100644
--- a/src/objective-c/examples/Sample/SampleTests/Info.plist
+++ b/src/objective-c/tests/Info.plist
@@ -7,7 +7,7 @@
 	<key>CFBundleExecutable</key>
 	<string>$(EXECUTABLE_NAME)</string>
 	<key>CFBundleIdentifier</key>
-	<string>org.grpc.$(PRODUCT_NAME:rfc1034identifier)</string>
+	<string>gRPC.$(PRODUCT_NAME:rfc1034identifier)</string>
 	<key>CFBundleInfoDictionaryVersion</key>
 	<string>6.0</string>
 	<key>CFBundleName</key>
diff --git a/src/objective-c/examples/Sample/SampleTests/RemoteProtoTests.m b/src/objective-c/tests/InteropTests.m
similarity index 97%
rename from src/objective-c/examples/Sample/SampleTests/RemoteProtoTests.m
rename to src/objective-c/tests/InteropTests.m
index 8e0e11d..0a512c1 100644
--- a/src/objective-c/examples/Sample/SampleTests/RemoteProtoTests.m
+++ b/src/objective-c/tests/InteropTests.m
@@ -76,10 +76,10 @@
 }
 @end
 
-@interface RemoteProtoTests : XCTestCase
+@interface InteropTests : XCTestCase
 @end
 
-@implementation RemoteProtoTests {
+@implementation InteropTests {
   RMTTestService *_service;
 }
 
@@ -192,7 +192,7 @@
       [expectation fulfill];
     }
   }];
-  
+
   [self waitForExpectationsWithTimeout:4 handler:nil];
 }
 
@@ -230,7 +230,7 @@
         [requestsBuffer writesFinishedWithError:nil];
       }
     }
-                                       
+
     if (done) {
       XCTAssertEqual(index, 4, @"Received %i responses instead of 4.", index);
       [expectation fulfill];
@@ -283,9 +283,9 @@
   [requestsBuffer writeValue:request];
   
   __block ProtoRPC *call = [_service RPCToFullDuplexCallWithRequestsWriter:requestsBuffer
-                                                           handler:^(BOOL done,
-                                                                     RMTStreamingOutputCallResponse *response,
-                                                                     NSError *error) {
+                                                                   handler:^(BOOL done,
+                                                                             RMTStreamingOutputCallResponse *response,
+                                                                             NSError *error) {
     if (receivedResponse) {
       XCTAssert(done, @"Unexpected extra response %@", response);
       XCTAssertEqual(error.code, GRPC_STATUS_CANCELLED);
diff --git a/src/objective-c/examples/Sample/SampleTests/SampleTests.m b/src/objective-c/tests/LocalClearTextTests.m
similarity index 94%
rename from src/objective-c/examples/Sample/SampleTests/SampleTests.m
rename to src/objective-c/tests/LocalClearTextTests.m
index 83cfd8c..6a9496b 100644
--- a/src/objective-c/examples/Sample/SampleTests/SampleTests.m
+++ b/src/objective-c/tests/LocalClearTextTests.m
@@ -41,13 +41,14 @@
 #import <Route_guide/RouteGuide.pbobjc.h>
 #import <Route_guide/RouteGuide.pbrpc.h>
 
-@interface SampleTests : XCTestCase
+// These tests require the gRPC-Java "RouteGuide" sample server to be running locally. To do so,
+// install Gradle by following the instructions here: https://docs.gradle.org/current/userguide/installation.html
+// And use it to run the server by following the instructions here: https://github.com/grpc/grpc-java/tree/master/examples
+
+@interface LocalClearTextTests : XCTestCase
 @end
 
-// These tests require the gRPC-Java "RouteGuide" sample server to be running locally. Install the
-// gRPC-Java library following the instructions here: https://github.com/grpc/grpc-java And run the
-// server by following the instructions here: https://github.com/grpc/grpc-java/tree/master/examples
-@implementation SampleTests
+@implementation LocalClearTextTests
 
 - (void)testConnectionToLocalServer {
   __weak XCTestExpectation *expectation = [self expectationWithDescription:@"Server reachable."];
diff --git a/src/objective-c/tests/Podfile b/src/objective-c/tests/Podfile
new file mode 100644
index 0000000..c099fb5
--- /dev/null
+++ b/src/objective-c/tests/Podfile
@@ -0,0 +1,15 @@
+source 'https://github.com/CocoaPods/Specs.git'
+platform :ios, '8.0'
+
+pod 'gRPC', :path => "../../.."
+pod 'Protobuf', :git => 'https://github.com/google/protobuf.git'
+pod 'RemoteTest', :path => "../generated_libraries/RemoteTestClient"
+pod 'Route_guide', :path => "../generated_libraries/RouteGuideClient"
+
+link_with 'AllTests'
+
+target 'Tests' do
+end
+
+target 'AllTests' do
+end
diff --git a/src/objective-c/tests/RxLibraryUnitTests.m b/src/objective-c/tests/RxLibraryUnitTests.m
new file mode 100644
index 0000000..89984d9
--- /dev/null
+++ b/src/objective-c/tests/RxLibraryUnitTests.m
@@ -0,0 +1,140 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#import <UIKit/UIKit.h>
+#import <XCTest/XCTest.h>
+
+#import <gRPC/GRXBufferedPipe.h>
+#import <gRPC/GRXWriter.h>
+#import <gRPC/GRXWriteable.h>
+
+// A mock of a GRXSingleValueHandler block that can be queried for how many times it was called and
+// what were the last values passed to it.
+//
+// TODO(jcanizales): Move this to a test util library, and add tests for it.
+@interface CapturingSingleValueHandler : NSObject
+@property (nonatomic, readonly) void (^block)(id value, NSError *errorOrNil);
+@property (nonatomic, readonly) NSUInteger timesCalled;
+@property (nonatomic, readonly) id value;
+@property (nonatomic, readonly) NSError *errorOrNil;
++ (instancetype)handler;
+@end
+
+@implementation CapturingSingleValueHandler
++ (instancetype)handler {
+  return [[self alloc] init];
+}
+
+- (GRXSingleValueHandler)block {
+  return ^(id value, NSError *errorOrNil) {
+    ++_timesCalled;
+    _value = value;
+    _errorOrNil = errorOrNil;
+  };
+}
+@end
+
+@interface RxLibraryUnitTests : XCTestCase
+@end
+
+@implementation RxLibraryUnitTests
+
+#pragma mark Writeable
+
+- (void)testWriteableSingleValueHandlerIsCalledForValue {
+  // Given:
+  CapturingSingleValueHandler *handler = [CapturingSingleValueHandler handler];
+  id anyValue = @7;
+
+  // If:
+  id<GRXWriteable> writeable = [GRXWriteable writeableWithSingleValueHandler:handler.block];
+  [writeable writeValue:anyValue];
+
+  // Then:
+  XCTAssertEqual(handler.timesCalled, 1);
+  XCTAssertEqualObjects(handler.value, anyValue);
+  XCTAssertEqualObjects(handler.errorOrNil, nil);
+}
+
+- (void)testWriteableSingleValueHandlerIsCalledForError {
+  // Given:
+  CapturingSingleValueHandler *handler = [CapturingSingleValueHandler handler];
+  NSError *anyError = [NSError errorWithDomain:@"domain" code:7 userInfo:nil];
+
+  // If:
+  id<GRXWriteable> writeable = [GRXWriteable writeableWithSingleValueHandler:handler.block];
+  [writeable writesFinishedWithError:anyError];
+
+  // Then:
+  XCTAssertEqual(handler.timesCalled, 1);
+  XCTAssertEqualObjects(handler.value, nil);
+  XCTAssertEqualObjects(handler.errorOrNil, anyError);
+}
+
+#pragma mark BufferedPipe
+
+- (void)testBufferedPipePropagatesValue {
+  // Given:
+  CapturingSingleValueHandler *handler = [CapturingSingleValueHandler handler];
+  id<GRXWriteable> writeable = [GRXWriteable writeableWithSingleValueHandler:handler.block];
+  id anyValue = @7;
+
+  // If:
+  GRXBufferedPipe *pipe = [GRXBufferedPipe pipe];
+  [pipe startWithWriteable:writeable];
+  [pipe writeValue:anyValue];
+
+  // Then:
+  XCTAssertEqual(handler.timesCalled, 1);
+  XCTAssertEqualObjects(handler.value, anyValue);
+  XCTAssertEqualObjects(handler.errorOrNil, nil);
+}
+
+- (void)testBufferedPipePropagatesError {
+  // Given:
+  CapturingSingleValueHandler *handler = [CapturingSingleValueHandler handler];
+  id<GRXWriteable> writeable = [GRXWriteable writeableWithSingleValueHandler:handler.block];
+  NSError *anyError = [NSError errorWithDomain:@"domain" code:7 userInfo:nil];
+
+  // If:
+  GRXBufferedPipe *pipe = [GRXBufferedPipe pipe];
+  [pipe startWithWriteable:writeable];
+  [pipe writesFinishedWithError:anyError];
+
+  // Then:
+  XCTAssertEqual(handler.timesCalled, 1);
+  XCTAssertEqualObjects(handler.value, nil);
+  XCTAssertEqualObjects(handler.errorOrNil, anyError);
+}
+
+@end
diff --git a/src/python/src/grpc/_adapter/_error.h b/src/objective-c/tests/Tests.m
similarity index 87%
rename from src/python/src/grpc/_adapter/_error.h
rename to src/objective-c/tests/Tests.m
index 6988b1c..b821d38 100644
--- a/src/python/src/grpc/_adapter/_error.h
+++ b/src/objective-c/tests/Tests.m
@@ -31,12 +31,10 @@
  *
  */
 
-#ifndef _ADAPTER__ERROR_H_
-#define _ADAPTER__ERROR_H_
+#import <Foundation/Foundation.h>
 
-#include <Python.h>
-#include <grpc/grpc.h>
+@interface Tests : NSObject
+@end
 
-const PyObject *pygrpc_translate_call_error(grpc_call_error call_error);
-
-#endif /* _ADAPTER__ERROR_H_ */
+@implementation Tests
+@end
diff --git a/src/objective-c/tests/Tests.xcodeproj/project.pbxproj b/src/objective-c/tests/Tests.xcodeproj/project.pbxproj
new file mode 100644
index 0000000..34be705
--- /dev/null
+++ b/src/objective-c/tests/Tests.xcodeproj/project.pbxproj
@@ -0,0 +1,442 @@
+// !$*UTF8*$!
+{
+	archiveVersion = 1;
+	classes = {
+	};
+	objectVersion = 46;
+	objects = {
+
+/* Begin PBXBuildFile section */
+		6312AE4E1B1BF49B00341DEE /* GRPCClientTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 6312AE4D1B1BF49B00341DEE /* GRPCClientTests.m */; };
+		63175DFF1B1B9FAF00027841 /* LocalClearTextTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 63175DFE1B1B9FAF00027841 /* LocalClearTextTests.m */; };
+		63423F4A1B150A5F006CF63C /* libTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 635697C71B14FC11007A7283 /* libTests.a */; };
+		63423F511B151B77006CF63C /* RxLibraryUnitTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 63423F501B151B77006CF63C /* RxLibraryUnitTests.m */; };
+		635697CD1B14FC11007A7283 /* Tests.m in Sources */ = {isa = PBXBuildFile; fileRef = 635697CC1B14FC11007A7283 /* Tests.m */; };
+		635ED2EC1B1A3BC400FDE5C3 /* InteropTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 635ED2EB1B1A3BC400FDE5C3 /* InteropTests.m */; };
+		7D8A186224D39101F90230F6 /* libPods.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 35F2B6BF3BAE8F0DC4AFD76E /* libPods.a */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXContainerItemProxy section */
+		63423F4B1B150A5F006CF63C /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 635697BF1B14FC11007A7283 /* Project object */;
+			proxyType = 1;
+			remoteGlobalIDString = 635697C61B14FC11007A7283;
+			remoteInfo = Tests;
+		};
+/* End PBXContainerItemProxy section */
+
+/* Begin PBXCopyFilesBuildPhase section */
+		635697C51B14FC11007A7283 /* CopyFiles */ = {
+			isa = PBXCopyFilesBuildPhase;
+			buildActionMask = 2147483647;
+			dstPath = "include/$(PRODUCT_NAME)";
+			dstSubfolderSpec = 16;
+			files = (
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXCopyFilesBuildPhase section */
+
+/* Begin PBXFileReference section */
+		0A4F89D9C90E9C30990218F0 /* Pods.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = Pods.release.xcconfig; path = "Pods/Target Support Files/Pods/Pods.release.xcconfig"; sourceTree = "<group>"; };
+		35F2B6BF3BAE8F0DC4AFD76E /* libPods.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libPods.a; sourceTree = BUILT_PRODUCTS_DIR; };
+		6312AE4D1B1BF49B00341DEE /* GRPCClientTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GRPCClientTests.m; sourceTree = "<group>"; };
+		63175DFE1B1B9FAF00027841 /* LocalClearTextTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LocalClearTextTests.m; sourceTree = "<group>"; };
+		63423F441B150A5F006CF63C /* AllTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = AllTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
+		63423F501B151B77006CF63C /* RxLibraryUnitTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RxLibraryUnitTests.m; sourceTree = "<group>"; };
+		635697C71B14FC11007A7283 /* libTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libTests.a; sourceTree = BUILT_PRODUCTS_DIR; };
+		635697CC1B14FC11007A7283 /* Tests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = Tests.m; sourceTree = "<group>"; };
+		635697D81B14FC11007A7283 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
+		635ED2EB1B1A3BC400FDE5C3 /* InteropTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = InteropTests.m; sourceTree = "<group>"; };
+		FF7B5489BCFE40111D768DD0 /* Pods.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = Pods.debug.xcconfig; path = "Pods/Target Support Files/Pods/Pods.debug.xcconfig"; sourceTree = "<group>"; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+		63423F411B150A5F006CF63C /* Frameworks */ = {
+			isa = PBXFrameworksBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				63423F4A1B150A5F006CF63C /* libTests.a in Frameworks */,
+				7D8A186224D39101F90230F6 /* libPods.a in Frameworks */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		635697C41B14FC11007A7283 /* Frameworks */ = {
+			isa = PBXFrameworksBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+		136D535E19727099B941D7B1 /* Frameworks */ = {
+			isa = PBXGroup;
+			children = (
+				35F2B6BF3BAE8F0DC4AFD76E /* libPods.a */,
+			);
+			name = Frameworks;
+			sourceTree = "<group>";
+		};
+		51E4650F34F854F41FF053B3 /* Pods */ = {
+			isa = PBXGroup;
+			children = (
+				FF7B5489BCFE40111D768DD0 /* Pods.debug.xcconfig */,
+				0A4F89D9C90E9C30990218F0 /* Pods.release.xcconfig */,
+			);
+			name = Pods;
+			sourceTree = "<group>";
+		};
+		635697BE1B14FC11007A7283 = {
+			isa = PBXGroup;
+			children = (
+				635697C91B14FC11007A7283 /* Tests */,
+				635697C81B14FC11007A7283 /* Products */,
+				51E4650F34F854F41FF053B3 /* Pods */,
+				136D535E19727099B941D7B1 /* Frameworks */,
+			);
+			sourceTree = "<group>";
+		};
+		635697C81B14FC11007A7283 /* Products */ = {
+			isa = PBXGroup;
+			children = (
+				635697C71B14FC11007A7283 /* libTests.a */,
+				63423F441B150A5F006CF63C /* AllTests.xctest */,
+			);
+			name = Products;
+			sourceTree = "<group>";
+		};
+		635697C91B14FC11007A7283 /* Tests */ = {
+			isa = PBXGroup;
+			children = (
+				6312AE4D1B1BF49B00341DEE /* GRPCClientTests.m */,
+				63175DFE1B1B9FAF00027841 /* LocalClearTextTests.m */,
+				635ED2EB1B1A3BC400FDE5C3 /* InteropTests.m */,
+				63423F501B151B77006CF63C /* RxLibraryUnitTests.m */,
+				635697CC1B14FC11007A7283 /* Tests.m */,
+				635697D71B14FC11007A7283 /* Supporting Files */,
+			);
+			name = Tests;
+			sourceTree = SOURCE_ROOT;
+		};
+		635697D71B14FC11007A7283 /* Supporting Files */ = {
+			isa = PBXGroup;
+			children = (
+				635697D81B14FC11007A7283 /* Info.plist */,
+			);
+			name = "Supporting Files";
+			sourceTree = "<group>";
+		};
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+		63423F431B150A5F006CF63C /* AllTests */ = {
+			isa = PBXNativeTarget;
+			buildConfigurationList = 63423F4D1B150A5F006CF63C /* Build configuration list for PBXNativeTarget "AllTests" */;
+			buildPhases = (
+				914ADDD7106BA9BB8A7E569F /* Check Pods Manifest.lock */,
+				63423F401B150A5F006CF63C /* Sources */,
+				63423F411B150A5F006CF63C /* Frameworks */,
+				63423F421B150A5F006CF63C /* Resources */,
+				A441F71824DCB9D0CA297748 /* Copy Pods Resources */,
+			);
+			buildRules = (
+			);
+			dependencies = (
+				63423F4C1B150A5F006CF63C /* PBXTargetDependency */,
+			);
+			name = AllTests;
+			productName = AllTests;
+			productReference = 63423F441B150A5F006CF63C /* AllTests.xctest */;
+			productType = "com.apple.product-type.bundle.unit-test";
+		};
+		635697C61B14FC11007A7283 /* Tests */ = {
+			isa = PBXNativeTarget;
+			buildConfigurationList = 635697DB1B14FC11007A7283 /* Build configuration list for PBXNativeTarget "Tests" */;
+			buildPhases = (
+				635697C31B14FC11007A7283 /* Sources */,
+				635697C41B14FC11007A7283 /* Frameworks */,
+				635697C51B14FC11007A7283 /* CopyFiles */,
+			);
+			buildRules = (
+			);
+			dependencies = (
+			);
+			name = Tests;
+			productName = Tests;
+			productReference = 635697C71B14FC11007A7283 /* libTests.a */;
+			productType = "com.apple.product-type.library.static";
+		};
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+		635697BF1B14FC11007A7283 /* Project object */ = {
+			isa = PBXProject;
+			attributes = {
+				LastUpgradeCheck = 0630;
+				ORGANIZATIONNAME = gRPC;
+				TargetAttributes = {
+					63423F431B150A5F006CF63C = {
+						CreatedOnToolsVersion = 6.3.1;
+					};
+					635697C61B14FC11007A7283 = {
+						CreatedOnToolsVersion = 6.3.1;
+					};
+				};
+			};
+			buildConfigurationList = 635697C21B14FC11007A7283 /* Build configuration list for PBXProject "Tests" */;
+			compatibilityVersion = "Xcode 3.2";
+			developmentRegion = English;
+			hasScannedForEncodings = 0;
+			knownRegions = (
+				en,
+			);
+			mainGroup = 635697BE1B14FC11007A7283;
+			productRefGroup = 635697C81B14FC11007A7283 /* Products */;
+			projectDirPath = "";
+			projectRoot = "";
+			targets = (
+				635697C61B14FC11007A7283 /* Tests */,
+				63423F431B150A5F006CF63C /* AllTests */,
+			);
+		};
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+		63423F421B150A5F006CF63C /* Resources */ = {
+			isa = PBXResourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXShellScriptBuildPhase section */
+		914ADDD7106BA9BB8A7E569F /* Check Pods Manifest.lock */ = {
+			isa = PBXShellScriptBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			inputPaths = (
+			);
+			name = "Check Pods Manifest.lock";
+			outputPaths = (
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+			shellPath = /bin/sh;
+			shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n    cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n    exit 1\nfi\n";
+			showEnvVarsInLog = 0;
+		};
+		A441F71824DCB9D0CA297748 /* Copy Pods Resources */ = {
+			isa = PBXShellScriptBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			inputPaths = (
+			);
+			name = "Copy Pods Resources";
+			outputPaths = (
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+			shellPath = /bin/sh;
+			shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods/Pods-resources.sh\"\n";
+			showEnvVarsInLog = 0;
+		};
+/* End PBXShellScriptBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+		63423F401B150A5F006CF63C /* Sources */ = {
+			isa = PBXSourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				63175DFF1B1B9FAF00027841 /* LocalClearTextTests.m in Sources */,
+				63423F511B151B77006CF63C /* RxLibraryUnitTests.m in Sources */,
+				6312AE4E1B1BF49B00341DEE /* GRPCClientTests.m in Sources */,
+				635ED2EC1B1A3BC400FDE5C3 /* InteropTests.m in Sources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		635697C31B14FC11007A7283 /* Sources */ = {
+			isa = PBXSourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				635697CD1B14FC11007A7283 /* Tests.m in Sources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXTargetDependency section */
+		63423F4C1B150A5F006CF63C /* PBXTargetDependency */ = {
+			isa = PBXTargetDependency;
+			target = 635697C61B14FC11007A7283 /* Tests */;
+			targetProxy = 63423F4B1B150A5F006CF63C /* PBXContainerItemProxy */;
+		};
+/* End PBXTargetDependency section */
+
+/* Begin XCBuildConfiguration section */
+		63423F4E1B150A5F006CF63C /* Debug */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = FF7B5489BCFE40111D768DD0 /* Pods.debug.xcconfig */;
+			buildSettings = {
+				FRAMEWORK_SEARCH_PATHS = (
+					"$(SDKROOT)/Developer/Library/Frameworks",
+					"$(inherited)",
+				);
+				GCC_PREPROCESSOR_DEFINITIONS = (
+					"DEBUG=1",
+					"$(inherited)",
+				);
+				INFOPLIST_FILE = Info.plist;
+				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
+				PRODUCT_NAME = "$(TARGET_NAME)";
+			};
+			name = Debug;
+		};
+		63423F4F1B150A5F006CF63C /* Release */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = 0A4F89D9C90E9C30990218F0 /* Pods.release.xcconfig */;
+			buildSettings = {
+				FRAMEWORK_SEARCH_PATHS = (
+					"$(SDKROOT)/Developer/Library/Frameworks",
+					"$(inherited)",
+				);
+				INFOPLIST_FILE = Info.plist;
+				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
+				PRODUCT_NAME = "$(TARGET_NAME)";
+			};
+			name = Release;
+		};
+		635697D91B14FC11007A7283 /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ALWAYS_SEARCH_USER_PATHS = NO;
+				CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+				CLANG_CXX_LIBRARY = "libc++";
+				CLANG_ENABLE_MODULES = YES;
+				CLANG_ENABLE_OBJC_ARC = YES;
+				CLANG_WARN_BOOL_CONVERSION = YES;
+				CLANG_WARN_CONSTANT_CONVERSION = YES;
+				CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+				CLANG_WARN_EMPTY_BODY = YES;
+				CLANG_WARN_ENUM_CONVERSION = YES;
+				CLANG_WARN_INT_CONVERSION = YES;
+				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+				CLANG_WARN_UNREACHABLE_CODE = YES;
+				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+				COPY_PHASE_STRIP = NO;
+				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+				ENABLE_STRICT_OBJC_MSGSEND = YES;
+				GCC_C_LANGUAGE_STANDARD = gnu99;
+				GCC_DYNAMIC_NO_PIC = NO;
+				GCC_NO_COMMON_BLOCKS = YES;
+				GCC_OPTIMIZATION_LEVEL = 0;
+				GCC_PREPROCESSOR_DEFINITIONS = (
+					"DEBUG=1",
+					"$(inherited)",
+				);
+				GCC_SYMBOLS_PRIVATE_EXTERN = NO;
+				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+				GCC_WARN_UNDECLARED_SELECTOR = YES;
+				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+				GCC_WARN_UNUSED_FUNCTION = YES;
+				GCC_WARN_UNUSED_VARIABLE = YES;
+				IPHONEOS_DEPLOYMENT_TARGET = 8.3;
+				MTL_ENABLE_DEBUG_INFO = YES;
+				ONLY_ACTIVE_ARCH = YES;
+				SDKROOT = iphoneos;
+			};
+			name = Debug;
+		};
+		635697DA1B14FC11007A7283 /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ALWAYS_SEARCH_USER_PATHS = NO;
+				CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+				CLANG_CXX_LIBRARY = "libc++";
+				CLANG_ENABLE_MODULES = YES;
+				CLANG_ENABLE_OBJC_ARC = YES;
+				CLANG_WARN_BOOL_CONVERSION = YES;
+				CLANG_WARN_CONSTANT_CONVERSION = YES;
+				CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+				CLANG_WARN_EMPTY_BODY = YES;
+				CLANG_WARN_ENUM_CONVERSION = YES;
+				CLANG_WARN_INT_CONVERSION = YES;
+				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+				CLANG_WARN_UNREACHABLE_CODE = YES;
+				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+				COPY_PHASE_STRIP = NO;
+				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+				ENABLE_NS_ASSERTIONS = NO;
+				ENABLE_STRICT_OBJC_MSGSEND = YES;
+				GCC_C_LANGUAGE_STANDARD = gnu99;
+				GCC_NO_COMMON_BLOCKS = YES;
+				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+				GCC_WARN_UNDECLARED_SELECTOR = YES;
+				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+				GCC_WARN_UNUSED_FUNCTION = YES;
+				GCC_WARN_UNUSED_VARIABLE = YES;
+				IPHONEOS_DEPLOYMENT_TARGET = 8.3;
+				MTL_ENABLE_DEBUG_INFO = NO;
+				SDKROOT = iphoneos;
+				VALIDATE_PRODUCT = YES;
+			};
+			name = Release;
+		};
+		635697DC1B14FC11007A7283 /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				OTHER_LDFLAGS = "-ObjC";
+				PRODUCT_NAME = "$(TARGET_NAME)";
+				SKIP_INSTALL = YES;
+			};
+			name = Debug;
+		};
+		635697DD1B14FC11007A7283 /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				OTHER_LDFLAGS = "-ObjC";
+				PRODUCT_NAME = "$(TARGET_NAME)";
+				SKIP_INSTALL = YES;
+			};
+			name = Release;
+		};
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+		63423F4D1B150A5F006CF63C /* Build configuration list for PBXNativeTarget "AllTests" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				63423F4E1B150A5F006CF63C /* Debug */,
+				63423F4F1B150A5F006CF63C /* Release */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
+		635697C21B14FC11007A7283 /* Build configuration list for PBXProject "Tests" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				635697D91B14FC11007A7283 /* Debug */,
+				635697DA1B14FC11007A7283 /* Release */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
+		635697DB1B14FC11007A7283 /* Build configuration list for PBXNativeTarget "Tests" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				635697DC1B14FC11007A7283 /* Debug */,
+				635697DD1B14FC11007A7283 /* Release */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
+/* End XCConfigurationList section */
+	};
+	rootObject = 635697BF1B14FC11007A7283 /* Project object */;
+}
diff --git a/src/objective-c/tests/Tests.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/src/objective-c/tests/Tests.xcodeproj/project.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 0000000..6c0ea84
--- /dev/null
+++ b/src/objective-c/tests/Tests.xcodeproj/project.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Workspace
+   version = "1.0">
+   <FileRef
+      location = "self:Tests.xcodeproj">
+   </FileRef>
+</Workspace>
diff --git a/src/python/src/grpc/_adapter/_c.c b/src/python/src/grpc/_adapter/_c.c
deleted file mode 100644
index f096a55..0000000
--- a/src/python/src/grpc/_adapter/_c.c
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- *
- * Copyright 2015, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#include <Python.h>
-#include <grpc/grpc.h>
-
-#include "grpc/_adapter/_completion_queue.h"
-#include "grpc/_adapter/_channel.h"
-#include "grpc/_adapter/_call.h"
-#include "grpc/_adapter/_server.h"
-#include "grpc/_adapter/_client_credentials.h"
-#include "grpc/_adapter/_server_credentials.h"
-
-static PyObject *init(PyObject *self) {
-  grpc_init();
-  Py_RETURN_NONE;
-}
-
-static PyObject *shutdown(PyObject *self) {
-  grpc_shutdown();
-  Py_RETURN_NONE;
-}
-
-static PyMethodDef _c_methods[] = {
-    {"init", (PyCFunction)init, METH_NOARGS,
-     "Initialize the module's static state."},
-    {"shut_down", (PyCFunction)shutdown, METH_NOARGS,
-     "Shut down the module's static state."},
-    {NULL},
-};
-
-PyMODINIT_FUNC init_c(void) {
-  PyObject *module;
-
-  module = Py_InitModule3("_c", _c_methods,
-                          "Wrappings of C structures and functions.");
-
-  if (pygrpc_add_completion_queue(module) == -1) {
-    return;
-  }
-  if (pygrpc_add_channel(module) == -1) {
-    return;
-  }
-  if (pygrpc_add_call(module) == -1) {
-    return;
-  }
-  if (pygrpc_add_server(module) == -1) {
-    return;
-  }
-  if (pygrpc_add_client_credentials(module) == -1) {
-    return;
-  }
-  if (pygrpc_add_server_credentials(module) == -1) {
-    return;
-  }
-}
diff --git a/src/python/src/grpc/_adapter/_error.h b/src/python/src/grpc/_adapter/_c/module.c
similarity index 73%
copy from src/python/src/grpc/_adapter/_error.h
copy to src/python/src/grpc/_adapter/_c/module.c
index 6988b1c..1f3aedd 100644
--- a/src/python/src/grpc/_adapter/_error.h
+++ b/src/python/src/grpc/_adapter/_c/module.c
@@ -31,12 +31,31 @@
  *
  */
 
-#ifndef _ADAPTER__ERROR_H_
-#define _ADAPTER__ERROR_H_
+#include <stdlib.h>
 
+#define PY_SSIZE_T_CLEAN
 #include <Python.h>
 #include <grpc/grpc.h>
 
-const PyObject *pygrpc_translate_call_error(grpc_call_error call_error);
+#include "grpc/_adapter/_c/types.h"
 
-#endif /* _ADAPTER__ERROR_H_ */
+static PyMethodDef c_methods[] = {
+    {NULL}
+};
+
+PyMODINIT_FUNC init_c(void) {
+  PyObject *module;
+
+  module = Py_InitModule3("_c", c_methods,
+                          "Wrappings of C structures and functions.");
+
+  if (pygrpc_module_add_types(module) < 0) {
+    return;
+  }
+
+  /* GRPC maintains an internal counter of how many times it has been
+     initialized and handles multiple pairs of grpc_init()/grpc_shutdown()
+     invocations accordingly. */
+  grpc_init();
+  atexit(&grpc_shutdown);
+}
diff --git a/src/python/src/grpc/_adapter/_error.h b/src/python/src/grpc/_adapter/_c/types.c
similarity index 70%
copy from src/python/src/grpc/_adapter/_error.h
copy to src/python/src/grpc/_adapter/_c/types.c
index 6988b1c..8855c32 100644
--- a/src/python/src/grpc/_adapter/_error.h
+++ b/src/python/src/grpc/_adapter/_c/types.c
@@ -31,12 +31,30 @@
  *
  */
 
-#ifndef _ADAPTER__ERROR_H_
-#define _ADAPTER__ERROR_H_
+#include "grpc/_adapter/_c/types.h"
 
+#define PY_SSIZE_T_CLEAN
 #include <Python.h>
 #include <grpc/grpc.h>
 
-const PyObject *pygrpc_translate_call_error(grpc_call_error call_error);
-
-#endif /* _ADAPTER__ERROR_H_ */
+int pygrpc_module_add_types(PyObject *module) {
+  int i;
+  PyTypeObject *types[] = {
+      &pygrpc_ClientCredentials_type,
+      &pygrpc_ServerCredentials_type,
+      &pygrpc_CompletionQueue_type,
+      &pygrpc_Call_type,
+      &pygrpc_Channel_type,
+      &pygrpc_Server_type
+  };
+  for (i = 0; i < sizeof(types)/sizeof(PyTypeObject *); ++i) {
+    if (PyType_Ready(types[i]) < 0) {
+      return -1;
+    }
+  }
+  for (i = 0; i < sizeof(types)/sizeof(PyTypeObject *); ++i) {
+    Py_INCREF(types[i]);
+    PyModule_AddObject(module, types[i]->tp_name, (PyObject *)types[i]);
+  }
+  return 0;
+}
diff --git a/src/python/src/grpc/_adapter/_c/types.h b/src/python/src/grpc/_adapter/_c/types.h
new file mode 100644
index 0000000..e189ae2
--- /dev/null
+++ b/src/python/src/grpc/_adapter/_c/types.h
@@ -0,0 +1,271 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef GRPC__ADAPTER__C_TYPES_H_
+#define GRPC__ADAPTER__C_TYPES_H_
+
+#define PY_SSIZE_T_CLEAN
+#include <Python.h>
+#include <grpc/grpc.h>
+#include <grpc/grpc_security.h>
+
+
+/*=========================*/
+/* Client-side credentials */
+/*=========================*/
+
+typedef struct ClientCredentials {
+  PyObject_HEAD
+  grpc_credentials *c_creds;
+} ClientCredentials;
+void pygrpc_ClientCredentials_dealloc(ClientCredentials *self);
+ClientCredentials *pygrpc_ClientCredentials_google_default(
+    PyTypeObject *type, PyObject *ignored);
+ClientCredentials *pygrpc_ClientCredentials_ssl(
+    PyTypeObject *type, PyObject *args, PyObject *kwargs);
+ClientCredentials *pygrpc_ClientCredentials_composite(
+    PyTypeObject *type, PyObject *args, PyObject *kwargs);
+ClientCredentials *pygrpc_ClientCredentials_compute_engine(
+    PyTypeObject *type, PyObject *ignored);
+ClientCredentials *pygrpc_ClientCredentials_service_account(
+    PyTypeObject *type, PyObject *args, PyObject *kwargs);
+ClientCredentials *pygrpc_ClientCredentials_jwt(
+    PyTypeObject *type, PyObject *args, PyObject *kwargs);
+ClientCredentials *pygrpc_ClientCredentials_refresh_token(
+    PyTypeObject *type, PyObject *args, PyObject *kwargs);
+ClientCredentials *pygrpc_ClientCredentials_fake_transport_security(
+    PyTypeObject *type, PyObject *ignored);
+ClientCredentials *pygrpc_ClientCredentials_iam(
+    PyTypeObject *type, PyObject *args, PyObject *kwargs);
+extern PyTypeObject pygrpc_ClientCredentials_type;
+
+
+/*=========================*/
+/* Server-side credentials */
+/*=========================*/
+
+typedef struct ServerCredentials {
+  PyObject_HEAD
+  grpc_server_credentials *c_creds;
+} ServerCredentials;
+void pygrpc_ServerCredentials_dealloc(ServerCredentials *self);
+ServerCredentials *pygrpc_ServerCredentials_ssl(
+    PyTypeObject *type, PyObject *args, PyObject *kwargs);
+ServerCredentials *pygrpc_ServerCredentials_fake_transport_security(
+    PyTypeObject *type, PyObject *ignored);
+extern PyTypeObject pygrpc_ServerCredentials_type;
+
+
+/*==================*/
+/* Completion queue */
+/*==================*/
+
+typedef struct CompletionQueue {
+  PyObject_HEAD
+  grpc_completion_queue *c_cq;
+} CompletionQueue;
+CompletionQueue *pygrpc_CompletionQueue_new(
+    PyTypeObject *type, PyObject *args, PyObject *kwargs);
+void pygrpc_CompletionQueue_dealloc(CompletionQueue *self);
+PyObject *pygrpc_CompletionQueue_next(
+    CompletionQueue *self, PyObject *args, PyObject *kwargs);
+PyObject *pygrpc_CompletionQueue_shutdown(
+    CompletionQueue *self, PyObject *ignored);
+extern PyTypeObject pygrpc_CompletionQueue_type;
+
+
+/*======*/
+/* Call */
+/*======*/
+
+typedef struct Call {
+  PyObject_HEAD
+  grpc_call *c_call;
+  CompletionQueue *cq;
+} Call;
+Call *pygrpc_Call_new_empty(CompletionQueue *cq);
+void pygrpc_Call_dealloc(Call *self);
+PyObject *pygrpc_Call_start_batch(Call *self, PyObject *args, PyObject *kwargs);
+PyObject *pygrpc_Call_cancel(Call *self, PyObject *args, PyObject *kwargs);
+extern PyTypeObject pygrpc_Call_type;
+
+
+/*=========*/
+/* Channel */
+/*=========*/
+
+typedef struct Channel {
+  PyObject_HEAD
+  grpc_channel *c_chan;
+} Channel;
+Channel *pygrpc_Channel_new(
+    PyTypeObject *type, PyObject *args, PyObject *kwargs);
+void pygrpc_Channel_dealloc(Channel *self);
+Call *pygrpc_Channel_create_call(
+    Channel *self, PyObject *args, PyObject *kwargs);
+extern PyTypeObject pygrpc_Channel_type;
+
+
+/*========*/
+/* Server */
+/*========*/
+
+typedef struct Server {
+  PyObject_HEAD
+  grpc_server *c_serv;
+  CompletionQueue *cq;
+} Server;
+Server *pygrpc_Server_new(PyTypeObject *type, PyObject *args, PyObject *kwargs);
+void pygrpc_Server_dealloc(Server *self);
+PyObject *pygrpc_Server_request_call(
+    Server *self, PyObject *args, PyObject *kwargs);
+PyObject *pygrpc_Server_add_http2_port(
+    Server *self, PyObject *args, PyObject *kwargs);
+PyObject *pygrpc_Server_start(Server *self, PyObject *ignored);
+PyObject *pygrpc_Server_shutdown(
+    Server *self, PyObject *args, PyObject *kwargs);
+extern PyTypeObject pygrpc_Server_type;
+
+/*=========*/
+/* Utility */
+/*=========*/
+
+/* Every tag that passes from Python GRPC to GRPC core is of this type. */
+typedef struct pygrpc_tag {
+  PyObject *user_tag;
+  Call *call;
+  grpc_call_details request_call_details;
+  grpc_metadata_array request_metadata;
+  grpc_op *ops;
+  size_t nops;
+  int is_new_call;
+} pygrpc_tag;
+
+/* Construct a tag associated with a batch call. Does not take ownership of the
+   resources in the elements of ops. */
+pygrpc_tag *pygrpc_produce_batch_tag(PyObject *user_tag, Call *call,
+                                     grpc_op *ops, size_t nops);
+
+
+/* Construct a tag associated with a server request. The calling code should
+   use the appropriate fields of the produced tag in the invocation of
+   grpc_server_request_call. */
+pygrpc_tag *pygrpc_produce_request_tag(PyObject *user_tag, Call *empty_call);
+
+/* Construct a tag associated with a server shutdown. */
+pygrpc_tag *pygrpc_produce_server_shutdown_tag(PyObject *user_tag);
+
+/* Frees all resources owned by the tag and the tag itself. */
+void pygrpc_discard_tag(pygrpc_tag *tag);
+
+/* Consumes an event and its associated tag, providing a Python tuple of the
+   form `(type, tag, call, call_details, results)` (where type is an integer
+   corresponding to a grpc_completion_type, tag is an arbitrary PyObject, call
+   is the call object associated with the event [if any], call_details is a
+   tuple of form `(method, host, deadline)` [if such details are available],
+   and resultd is a list of tuples of form `(type, metadata, message, status,
+   cancelled)` [where type corresponds to a grpc_op_type, metadata is a
+   sequence of 2-sequences of strings, message is a byte string, and status is
+   a 2-tuple of an integer corresponding to grpc_status_code and a string of
+   status details]).
+
+   Frees all resources associated with the event tag. */
+PyObject *pygrpc_consume_event(grpc_event event);
+
+/* Transliterate the Python tuple of form `(type, metadata, message,
+   status)` (where type is an integer corresponding to a grpc_op_type, metadata
+   is a sequence of 2-sequences of strings, message is a byte string, and
+   status is 2-tuple of an integer corresponding to grpc_status_code and a
+   string of status details) to a grpc_op suitable for use in a
+   grpc_call_start_batch invocation. The grpc_op is a 'directory' of resources
+   that must be freed after GRPC core is done with them.
+
+   Calls gpr_malloc (or the appropriate type-specific grpc_*_create function)
+   to populate the appropriate union-discriminated members of the op.
+
+   Returns true on success, false on failure. */
+int pygrpc_produce_op(PyObject *op, grpc_op *result);
+
+/* Discards all resources associated with the passed in op that was produced by
+   pygrpc_produce_op. */
+void pygrpc_discard_op(grpc_op op);
+
+/* Transliterate the grpc_ops (which have been sent through a
+   grpc_call_start_batch invocation and whose corresponding event has appeared
+   on a completion queue) to a Python tuple of form `(type, metadata, message,
+   status, cancelled)` (where type is an integer corresponding to a
+   grpc_op_type, metadata is a sequence of 2-sequences of strings, message is a
+   byte string, and status is 2-tuple of an integer corresponding to
+   grpc_status_code and a string of status details).
+
+   Calls gpr_free (or the appropriate type-specific grpc_*_destroy function) on
+   the appropriate union-discriminated populated members of the ops. */
+PyObject *pygrpc_consume_ops(grpc_op *op, size_t nops);
+
+/* Transliterate from a gpr_timespec to a double (in units of seconds, either
+   from the epoch if interpreted absolutely or as a delta otherwise). */
+double pygrpc_cast_gpr_timespec_to_double(gpr_timespec timespec);
+
+/* Transliterate from a double (in units of seconds from the epoch if
+   interpreted absolutely or as a delta otherwise) to a gpr_timespec. */
+gpr_timespec pygrpc_cast_double_to_gpr_timespec(double seconds);
+
+/* Returns true on success, false on failure. */
+int pygrpc_cast_pylist_to_send_metadata(
+    PyObject *pylist, grpc_metadata **metadata, size_t *count);
+/* Returns a metadata array as a Python object on success, else NULL. */
+PyObject *pygrpc_cast_metadata_array_to_pylist(grpc_metadata_array metadata);
+
+/* Transliterate from a list of python channel arguments (2-tuples of string
+   and string|integer|None) to a grpc_channel_args object. The strings placed
+   in the grpc_channel_args object's grpc_arg elements are views of the Python
+   object. The Python object must live long enough for the grpc_channel_args
+   to be used. Arguments set to None are silently ignored. Returns true on
+   success, false on failure. */
+int pygrpc_produce_channel_args(PyObject *py_args, grpc_channel_args *c_args);
+void pygrpc_discard_channel_args(grpc_channel_args args);
+
+/* Read the bytes from grpc_byte_buffer to a gpr_malloc'd array of bytes;
+   output to result and result_size. */
+void pygrpc_byte_buffer_to_bytes(
+    grpc_byte_buffer *buffer, char **result, size_t *result_size);
+
+
+/*========*/
+/* Module */
+/*========*/
+
+/* Returns 0 on success, -1 on failure. */
+int pygrpc_module_add_types(PyObject *module);
+
+#endif  /* GRPC__ADAPTER__C_TYPES_H_ */
diff --git a/src/python/src/grpc/_adapter/_c/types/call.c b/src/python/src/grpc/_adapter/_c/types/call.c
new file mode 100644
index 0000000..0739070
--- /dev/null
+++ b/src/python/src/grpc/_adapter/_c/types/call.c
@@ -0,0 +1,163 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "grpc/_adapter/_c/types.h"
+
+#define PY_SSIZE_T_CLEAN
+#include <Python.h>
+#include <grpc/grpc.h>
+#include <grpc/support/alloc.h>
+
+
+PyMethodDef pygrpc_Call_methods[] = {
+    {"start_batch", (PyCFunction)pygrpc_Call_start_batch, METH_KEYWORDS, ""},
+    {"cancel", (PyCFunction)pygrpc_Call_cancel, METH_KEYWORDS, ""},
+    {NULL}
+};
+const char pygrpc_Call_doc[] = "See grpc._adapter._types.Call.";
+PyTypeObject pygrpc_Call_type = {
+    PyObject_HEAD_INIT(NULL)
+    0,                                        /* ob_size */
+    "Call",                                   /* tp_name */
+    sizeof(Call),                             /* tp_basicsize */
+    0,                                        /* tp_itemsize */
+    (destructor)pygrpc_Call_dealloc,          /* tp_dealloc */
+    0,                                        /* tp_print */
+    0,                                        /* tp_getattr */
+    0,                                        /* tp_setattr */
+    0,                                        /* tp_compare */
+    0,                                        /* tp_repr */
+    0,                                        /* tp_as_number */
+    0,                                        /* tp_as_sequence */
+    0,                                        /* tp_as_mapping */
+    0,                                        /* tp_hash */
+    0,                                        /* tp_call */
+    0,                                        /* tp_str */
+    0,                                        /* tp_getattro */
+    0,                                        /* tp_setattro */
+    0,                                        /* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
+    pygrpc_Call_doc,                          /* tp_doc */
+    0,                                        /* tp_traverse */
+    0,                                        /* tp_clear */
+    0,                                        /* tp_richcompare */
+    0,                                        /* tp_weaklistoffset */
+    0,                                        /* tp_iter */
+    0,                                        /* tp_iternext */
+    pygrpc_Call_methods,                      /* tp_methods */
+    0,                                        /* tp_members */
+    0,                                        /* tp_getset */
+    0,                                        /* tp_base */
+    0,                                        /* tp_dict */
+    0,                                        /* tp_descr_get */
+    0,                                        /* tp_descr_set */
+    0,                                        /* tp_dictoffset */
+    0,                                        /* tp_init */
+    0,                                        /* tp_alloc */
+    0                                         /* tp_new */
+};
+
+Call *pygrpc_Call_new_empty(CompletionQueue *cq) {
+  Call *call = (Call *)pygrpc_Call_type.tp_alloc(&pygrpc_Call_type, 0);
+  call->c_call = NULL;
+  call->cq = cq;
+  Py_XINCREF(call->cq);
+  return call;
+}
+void pygrpc_Call_dealloc(Call *self) {
+  if (self->c_call) {
+    grpc_call_destroy(self->c_call);
+  }
+  Py_XDECREF(self->cq);
+  self->ob_type->tp_free((PyObject *)self);
+}
+PyObject *pygrpc_Call_start_batch(Call *self, PyObject *args, PyObject *kwargs) {
+  PyObject *op_list;
+  PyObject *user_tag;
+  grpc_op *ops;
+  size_t nops;
+  size_t i;
+  size_t j;
+  pygrpc_tag *tag;
+  grpc_call_error errcode;
+  static char *keywords[] = {"ops", "tag", NULL};
+  if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO:start_batch", keywords,
+                                   &op_list, &user_tag)) {
+    return NULL;
+  }
+  if (!PyList_Check(op_list)) {
+    PyErr_SetString(PyExc_TypeError, "expected a list of OpArgs");
+    return NULL;
+  }
+  nops = PyList_Size(op_list);
+  ops = gpr_malloc(sizeof(grpc_op) * nops);
+  for (i = 0; i < nops; ++i) {
+    PyObject *item = PyList_GET_ITEM(op_list, i);
+    if (!pygrpc_produce_op(item, &ops[i])) {
+      for (j = 0; j < i; ++j) {
+        pygrpc_discard_op(ops[j]);
+      }
+      return NULL;
+    }
+  }
+  tag = pygrpc_produce_batch_tag(user_tag, self, ops, nops);
+  errcode = grpc_call_start_batch(self->c_call, tag->ops, tag->nops, tag);
+  gpr_free(ops);
+  return PyInt_FromLong(errcode);
+}
+PyObject *pygrpc_Call_cancel(Call *self, PyObject *args, PyObject *kwargs) {
+  PyObject *py_code = NULL;
+  grpc_call_error errcode;
+  int code;
+  char *details = NULL;
+  static char *keywords[] = {"code", "details", NULL};
+  if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Os:start_batch", keywords,
+                                   &py_code, &details)) {
+    return NULL;
+  }
+  if (py_code != NULL && details != NULL) {
+    if (!PyInt_Check(py_code)) {
+      PyErr_SetString(PyExc_TypeError, "expected integer code");
+      return NULL;
+    }
+    code = PyInt_AsLong(py_code);
+    errcode = grpc_call_cancel_with_status(self->c_call, code, details);
+  } else if (py_code != NULL || details != NULL) {
+    PyErr_SetString(PyExc_ValueError,
+                    "if `code` is specified, so must `details`");
+    return NULL;
+  } else {
+    errcode = grpc_call_cancel(self->c_call);
+  }
+  return PyInt_FromLong(errcode);
+}
diff --git a/src/python/src/grpc/_adapter/_c/types/channel.c b/src/python/src/grpc/_adapter/_c/types/channel.c
new file mode 100644
index 0000000..c235597
--- /dev/null
+++ b/src/python/src/grpc/_adapter/_c/types/channel.c
@@ -0,0 +1,134 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "grpc/_adapter/_c/types.h"
+
+#define PY_SSIZE_T_CLEAN
+#include <Python.h>
+#include <grpc/grpc.h>
+
+
+PyMethodDef pygrpc_Channel_methods[] = {
+    {"create_call", (PyCFunction)pygrpc_Channel_create_call, METH_KEYWORDS, ""},
+    {NULL}
+};
+const char pygrpc_Channel_doc[] = "See grpc._adapter._types.Channel.";
+PyTypeObject pygrpc_Channel_type = {
+    PyObject_HEAD_INIT(NULL)
+    0,                                        /* ob_size */
+    "Channel",                                /* tp_name */
+    sizeof(Channel),                          /* tp_basicsize */
+    0,                                        /* tp_itemsize */
+    (destructor)pygrpc_Channel_dealloc,       /* tp_dealloc */
+    0,                                        /* tp_print */
+    0,                                        /* tp_getattr */
+    0,                                        /* tp_setattr */
+    0,                                        /* tp_compare */
+    0,                                        /* tp_repr */
+    0,                                        /* tp_as_number */
+    0,                                        /* tp_as_sequence */
+    0,                                        /* tp_as_mapping */
+    0,                                        /* tp_hash */
+    0,                                        /* tp_call */
+    0,                                        /* tp_str */
+    0,                                        /* tp_getattro */
+    0,                                        /* tp_setattro */
+    0,                                        /* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
+    pygrpc_Channel_doc,                       /* tp_doc */
+    0,                                        /* tp_traverse */
+    0,                                        /* tp_clear */
+    0,                                        /* tp_richcompare */
+    0,                                        /* tp_weaklistoffset */
+    0,                                        /* tp_iter */
+    0,                                        /* tp_iternext */
+    pygrpc_Channel_methods,                   /* tp_methods */
+    0,                                        /* tp_members */
+    0,                                        /* tp_getset */
+    0,                                        /* tp_base */
+    0,                                        /* tp_dict */
+    0,                                        /* tp_descr_get */
+    0,                                        /* tp_descr_set */
+    0,                                        /* tp_dictoffset */
+    0,                                        /* tp_init */
+    0,                                        /* tp_alloc */
+    (newfunc)pygrpc_Channel_new               /* tp_new */
+};
+
+Channel *pygrpc_Channel_new(
+    PyTypeObject *type, PyObject *args, PyObject *kwargs) {
+  Channel *self;
+  const char *target;
+  PyObject *py_args;
+  ClientCredentials *creds = NULL;
+  grpc_channel_args c_args;
+  char *keywords[] = {"target", "args", "creds", NULL};
+  if (!PyArg_ParseTupleAndKeywords(args, kwargs, "sO|O!:Channel", keywords,
+        &target, &py_args, &pygrpc_ClientCredentials_type, &creds)) {
+    return NULL;
+  }
+  if (!pygrpc_produce_channel_args(py_args, &c_args)) {
+    return NULL;
+  }
+  self = (Channel *)type->tp_alloc(type, 0);
+  if (creds) {
+    self->c_chan = grpc_secure_channel_create(creds->c_creds, target, &c_args);
+  } else {
+    self->c_chan = grpc_channel_create(target, &c_args);
+  }
+  pygrpc_discard_channel_args(c_args);
+  return self;
+}
+void pygrpc_Channel_dealloc(Channel *self) {
+  grpc_channel_destroy(self->c_chan);
+  self->ob_type->tp_free((PyObject *)self);
+}
+
+Call *pygrpc_Channel_create_call(
+    Channel *self, PyObject *args, PyObject *kwargs) {
+  Call *call;
+  CompletionQueue *cq;
+  const char *method;
+  const char *host;
+  double deadline;
+  char *keywords[] = {"cq", "method", "host", "deadline", NULL};
+  if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!ssd:create_call", keywords,
+        &pygrpc_CompletionQueue_type, &cq, &method, &host, &deadline)) {
+    return NULL;
+  }
+  call = pygrpc_Call_new_empty(cq);
+  call->c_call = grpc_channel_create_call(
+      self->c_chan, cq->c_cq, method, host,
+      pygrpc_cast_double_to_gpr_timespec(deadline));
+  return call;
+}
diff --git a/src/python/src/grpc/_adapter/_c/types/client_credentials.c b/src/python/src/grpc/_adapter/_c/types/client_credentials.c
new file mode 100644
index 0000000..6a4561c
--- /dev/null
+++ b/src/python/src/grpc/_adapter/_c/types/client_credentials.c
@@ -0,0 +1,286 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "grpc/_adapter/_c/types.h"
+
+#define PY_SSIZE_T_CLEAN
+#include <Python.h>
+#include <grpc/grpc.h>
+#include <grpc/grpc_security.h>
+
+
+PyMethodDef pygrpc_ClientCredentials_methods[] = {
+    {"google_default", (PyCFunction)pygrpc_ClientCredentials_google_default,
+     METH_CLASS|METH_NOARGS, ""},
+    {"ssl", (PyCFunction)pygrpc_ClientCredentials_ssl,
+     METH_CLASS|METH_KEYWORDS, ""},
+    {"composite", (PyCFunction)pygrpc_ClientCredentials_composite,
+     METH_CLASS|METH_KEYWORDS, ""},
+    {"compute_engine", (PyCFunction)pygrpc_ClientCredentials_compute_engine,
+     METH_CLASS|METH_NOARGS, ""},
+    {"service_account", (PyCFunction)pygrpc_ClientCredentials_service_account,
+     METH_CLASS|METH_KEYWORDS, ""},
+    {"jwt", (PyCFunction)pygrpc_ClientCredentials_jwt,
+     METH_CLASS|METH_KEYWORDS, ""},
+    {"refresh_token", (PyCFunction)pygrpc_ClientCredentials_refresh_token,
+     METH_CLASS|METH_KEYWORDS, ""},
+    {"fake_transport_security",
+     (PyCFunction)pygrpc_ClientCredentials_fake_transport_security,
+     METH_CLASS|METH_NOARGS, ""},
+    {"iam", (PyCFunction)pygrpc_ClientCredentials_iam,
+     METH_CLASS|METH_KEYWORDS, ""},
+    {NULL}
+};
+const char pygrpc_ClientCredentials_doc[] = "";
+PyTypeObject pygrpc_ClientCredentials_type = {
+    PyObject_HEAD_INIT(NULL)
+    0,                                        /* ob_size */
+    "ClientCredentials",                      /* tp_name */
+    sizeof(ClientCredentials),                /* tp_basicsize */
+    0,                                        /* tp_itemsize */
+    (destructor)pygrpc_ClientCredentials_dealloc, /* tp_dealloc */
+    0,                                        /* tp_print */
+    0,                                        /* tp_getattr */
+    0,                                        /* tp_setattr */
+    0,                                        /* tp_compare */
+    0,                                        /* tp_repr */
+    0,                                        /* tp_as_number */
+    0,                                        /* tp_as_sequence */
+    0,                                        /* tp_as_mapping */
+    0,                                        /* tp_hash */
+    0,                                        /* tp_call */
+    0,                                        /* tp_str */
+    0,                                        /* tp_getattro */
+    0,                                        /* tp_setattro */
+    0,                                        /* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
+    pygrpc_ClientCredentials_doc,             /* tp_doc */
+    0,                                        /* tp_traverse */
+    0,                                        /* tp_clear */
+    0,                                        /* tp_richcompare */
+    0,                                        /* tp_weaklistoffset */
+    0,                                        /* tp_iter */
+    0,                                        /* tp_iternext */
+    pygrpc_ClientCredentials_methods,         /* tp_methods */
+    0,                                        /* tp_members */
+    0,                                        /* tp_getset */
+    0,                                        /* tp_base */
+    0,                                        /* tp_dict */
+    0,                                        /* tp_descr_get */
+    0,                                        /* tp_descr_set */
+    0,                                        /* tp_dictoffset */
+    0,                                        /* tp_init */
+    0,                                        /* tp_alloc */
+    0                                         /* tp_new */
+};
+
+void pygrpc_ClientCredentials_dealloc(ClientCredentials *self) {
+  grpc_credentials_release(self->c_creds);
+  self->ob_type->tp_free((PyObject *)self);
+}
+
+ClientCredentials *pygrpc_ClientCredentials_google_default(
+    PyTypeObject *type, PyObject *ignored) {
+  ClientCredentials *self = (ClientCredentials *)type->tp_alloc(type, 0);
+  self->c_creds = grpc_google_default_credentials_create();
+  if (!self->c_creds) {
+    Py_DECREF(self);
+    PyErr_SetString(PyExc_RuntimeError,
+                    "couldn't create Google default credentials");
+    return NULL;
+  }
+  return self;
+}
+
+ClientCredentials *pygrpc_ClientCredentials_ssl(
+    PyTypeObject *type, PyObject *args, PyObject *kwargs) {
+  ClientCredentials *self;
+  const char *root_certs;
+  const char *private_key = NULL;
+  const char *cert_chain = NULL;
+  grpc_ssl_pem_key_cert_pair key_cert_pair;
+  static char *keywords[] = {"root_certs", "private_key", "cert_chain", NULL};
+  if (!PyArg_ParseTupleAndKeywords(args, kwargs, "z|zz:ssl", keywords,
+        &root_certs, &private_key, &cert_chain)) {
+    return NULL;
+  }
+  self = (ClientCredentials *)type->tp_alloc(type, 0);
+  if (private_key && cert_chain) {
+    key_cert_pair.private_key = private_key;
+    key_cert_pair.cert_chain = cert_chain;
+    self->c_creds = grpc_ssl_credentials_create(root_certs, &key_cert_pair);
+  } else {
+    self->c_creds = grpc_ssl_credentials_create(root_certs, NULL);
+  }
+  if (!self->c_creds) {
+    Py_DECREF(self);
+    PyErr_SetString(PyExc_RuntimeError, "couldn't create ssl credentials");
+    return NULL;
+  }
+  return self;
+}
+
+ClientCredentials *pygrpc_ClientCredentials_composite(
+    PyTypeObject *type, PyObject *args, PyObject *kwargs) {
+  ClientCredentials *self;
+  ClientCredentials *creds1;
+  ClientCredentials *creds2;
+  static char *keywords[] = {"creds1", "creds2", NULL};
+  if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!O!:composite", keywords,
+        &pygrpc_ClientCredentials_type, &creds1,
+        &pygrpc_ClientCredentials_type, &creds2)) {
+    return NULL;
+  }
+  self = (ClientCredentials *)type->tp_alloc(type, 0);
+  self->c_creds = grpc_composite_credentials_create(
+      creds1->c_creds, creds2->c_creds);
+  if (!self->c_creds) {
+    Py_DECREF(self);
+    PyErr_SetString(PyExc_RuntimeError, "couldn't create composite credentials");
+    return NULL;
+  }
+  return self;
+}
+
+ClientCredentials *pygrpc_ClientCredentials_compute_engine(
+    PyTypeObject *type, PyObject *ignored) {
+  ClientCredentials *self = (ClientCredentials *)type->tp_alloc(type, 0);
+  self->c_creds = grpc_compute_engine_credentials_create();
+  if (!self->c_creds) {
+    Py_DECREF(self);
+    PyErr_SetString(PyExc_RuntimeError,
+                    "couldn't create compute engine credentials");
+    return NULL;
+  }
+  return self;
+}
+
+ClientCredentials *pygrpc_ClientCredentials_service_account(
+    PyTypeObject *type, PyObject *args, PyObject *kwargs) {
+  ClientCredentials *self;
+  const char *json_key;
+  const char *scope;
+  double lifetime;
+  static char *keywords[] = {"json_key", "scope", "token_lifetime", NULL};
+  if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ssd:service_account", keywords,
+        &json_key, &scope, &lifetime)) {
+    return NULL;
+  }
+  self = (ClientCredentials *)type->tp_alloc(type, 0);
+  self->c_creds = grpc_service_account_credentials_create(
+      json_key, scope, pygrpc_cast_double_to_gpr_timespec(lifetime));
+  if (!self->c_creds) {
+    Py_DECREF(self);
+    PyErr_SetString(PyExc_RuntimeError,
+                    "couldn't create service account credentials");
+    return NULL;
+  }
+  return self;
+}
+
+ClientCredentials *pygrpc_ClientCredentials_jwt(
+    PyTypeObject *type, PyObject *args, PyObject *kwargs) {
+  ClientCredentials *self;
+  const char *json_key;
+  double lifetime;
+  static char *keywords[] = {"json_key", "token_lifetime", NULL};
+  if (!PyArg_ParseTupleAndKeywords(args, kwargs, "sd:jwt", keywords,
+        &json_key, &lifetime)) {
+    return NULL;
+  }
+  self = (ClientCredentials *)type->tp_alloc(type, 0);
+  self->c_creds = grpc_jwt_credentials_create(
+      json_key, pygrpc_cast_double_to_gpr_timespec(lifetime));
+  if (!self->c_creds) {
+    Py_DECREF(self);
+    PyErr_SetString(PyExc_RuntimeError, "couldn't create JWT credentials");
+    return NULL;
+  }
+  return self;
+}
+
+ClientCredentials *pygrpc_ClientCredentials_refresh_token(
+    PyTypeObject *type, PyObject *args, PyObject *kwargs) {
+  ClientCredentials *self;
+  const char *json_refresh_token;
+  static char *keywords[] = {"json_refresh_token", NULL};
+  if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s:refresh_token", keywords,
+        &json_refresh_token)) {
+    return NULL;
+  }
+  self = (ClientCredentials *)type->tp_alloc(type, 0);
+  self->c_creds = grpc_refresh_token_credentials_create(json_refresh_token);
+  if (!self->c_creds) {
+    Py_DECREF(self);
+    PyErr_SetString(PyExc_RuntimeError,
+                    "couldn't create credentials from refresh token");
+    return NULL;
+  }
+  return self;
+}
+
+ClientCredentials *pygrpc_ClientCredentials_fake_transport_security(
+    PyTypeObject *type, PyObject *ignored) {
+  ClientCredentials *self = (ClientCredentials *)type->tp_alloc(type, 0);
+  self->c_creds = grpc_fake_transport_security_credentials_create();
+  if (!self->c_creds) {
+    Py_DECREF(self);
+    PyErr_SetString(PyExc_RuntimeError,
+                    "couldn't create fake credentials; "
+                    "something is horribly wrong with the universe");
+    return NULL;
+  }
+  return self;
+}
+
+ClientCredentials *pygrpc_ClientCredentials_iam(
+    PyTypeObject *type, PyObject *args, PyObject *kwargs) {
+  ClientCredentials *self;
+  const char *authorization_token;
+  const char *authority_selector;
+  static char *keywords[] = {"authorization_token", "authority_selector", NULL};
+  if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ss:iam", keywords,
+        &authorization_token, &authority_selector)) {
+    return NULL;
+  }
+  self = (ClientCredentials *)type->tp_alloc(type, 0);
+  self->c_creds = grpc_iam_credentials_create(authorization_token,
+                                              authority_selector);
+  if (!self->c_creds) {
+    Py_DECREF(self);
+    PyErr_SetString(PyExc_RuntimeError, "couldn't create IAM credentials");
+    return NULL;
+  }
+  return self;
+}
+
diff --git a/src/python/src/grpc/_adapter/_c/types/completion_queue.c b/src/python/src/grpc/_adapter/_c/types/completion_queue.c
new file mode 100644
index 0000000..2dd44b6
--- /dev/null
+++ b/src/python/src/grpc/_adapter/_c/types/completion_queue.c
@@ -0,0 +1,124 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "grpc/_adapter/_c/types.h"
+
+#define PY_SSIZE_T_CLEAN
+#include <Python.h>
+#include <grpc/grpc.h>
+
+
+PyMethodDef pygrpc_CompletionQueue_methods[] = {
+    {"next", (PyCFunction)pygrpc_CompletionQueue_next, METH_KEYWORDS, ""},
+    {"shutdown", (PyCFunction)pygrpc_CompletionQueue_shutdown, METH_NOARGS, ""},
+    {NULL}
+};
+const char pygrpc_CompletionQueue_doc[] =
+    "See grpc._adapter._types.CompletionQueue.";
+PyTypeObject pygrpc_CompletionQueue_type = {
+    PyObject_HEAD_INIT(NULL)
+    0,                                        /* ob_size */
+    "CompletionQueue",                        /* tp_name */
+    sizeof(CompletionQueue),                  /* tp_basicsize */
+    0,                                        /* tp_itemsize */
+    (destructor)pygrpc_CompletionQueue_dealloc, /* tp_dealloc */
+    0,                                        /* tp_print */
+    0,                                        /* tp_getattr */
+    0,                                        /* tp_setattr */
+    0,                                        /* tp_compare */
+    0,                                        /* tp_repr */
+    0,                                        /* tp_as_number */
+    0,                                        /* tp_as_sequence */
+    0,                                        /* tp_as_mapping */
+    0,                                        /* tp_hash */
+    0,                                        /* tp_call */
+    0,                                        /* tp_str */
+    0,                                        /* tp_getattro */
+    0,                                        /* tp_setattro */
+    0,                                        /* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
+    pygrpc_CompletionQueue_doc,               /* tp_doc */
+    0,                                        /* tp_traverse */
+    0,                                        /* tp_clear */
+    0,                                        /* tp_richcompare */
+    0,                                        /* tp_weaklistoffset */
+    0,                                        /* tp_iter */
+    0,                                        /* tp_iternext */
+    pygrpc_CompletionQueue_methods,           /* tp_methods */
+    0,                                        /* tp_members */
+    0,                                        /* tp_getset */
+    0,                                        /* tp_base */
+    0,                                        /* tp_dict */
+    0,                                        /* tp_descr_get */
+    0,                                        /* tp_descr_set */
+    0,                                        /* tp_dictoffset */
+    0,                                        /* tp_init */
+    0,                                        /* tp_alloc */
+    (newfunc)pygrpc_CompletionQueue_new       /* tp_new */
+};
+
+CompletionQueue *pygrpc_CompletionQueue_new(
+    PyTypeObject *type, PyObject *args, PyObject *kwargs) {
+  CompletionQueue *self = (CompletionQueue *)type->tp_alloc(type, 0);
+  self->c_cq = grpc_completion_queue_create();
+  return self;
+}
+
+void pygrpc_CompletionQueue_dealloc(CompletionQueue *self) {
+  grpc_completion_queue_destroy(self->c_cq);
+  self->ob_type->tp_free((PyObject *)self);
+}
+
+PyObject *pygrpc_CompletionQueue_next(
+    CompletionQueue *self, PyObject *args, PyObject *kwargs) {
+  double deadline;
+  grpc_event event;
+  PyObject *transliterated_event;
+  static char *keywords[] = {"deadline", NULL};
+  if (!PyArg_ParseTupleAndKeywords(args, kwargs, "d:next", keywords,
+                                   &deadline)) {
+    return NULL;
+  }
+  Py_BEGIN_ALLOW_THREADS;
+  event = grpc_completion_queue_next(
+      self->c_cq, pygrpc_cast_double_to_gpr_timespec(deadline));
+  Py_END_ALLOW_THREADS;
+  transliterated_event = pygrpc_consume_event(event);
+  return transliterated_event;
+}
+
+PyObject *pygrpc_CompletionQueue_shutdown(
+    CompletionQueue *self, PyObject *ignored) {
+  grpc_completion_queue_shutdown(self->c_cq);
+  Py_RETURN_NONE;
+}
diff --git a/src/python/src/grpc/_adapter/_c/types/server.c b/src/python/src/grpc/_adapter/_c/types/server.c
new file mode 100644
index 0000000..65d84b5
--- /dev/null
+++ b/src/python/src/grpc/_adapter/_c/types/server.c
@@ -0,0 +1,183 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "grpc/_adapter/_c/types.h"
+
+#define PY_SSIZE_T_CLEAN
+#include <Python.h>
+#include <grpc/grpc.h>
+
+
+PyMethodDef pygrpc_Server_methods[] = {
+    {"request_call", (PyCFunction)pygrpc_Server_request_call,
+     METH_KEYWORDS, ""},
+    {"add_http2_port", (PyCFunction)pygrpc_Server_add_http2_port,
+     METH_KEYWORDS, ""},
+    {"start", (PyCFunction)pygrpc_Server_start, METH_NOARGS, ""},
+    {"shutdown", (PyCFunction)pygrpc_Server_shutdown, METH_KEYWORDS, ""},
+    {NULL}
+};
+const char pygrpc_Server_doc[] = "See grpc._adapter._types.Server.";
+PyTypeObject pygrpc_Server_type = {
+    PyObject_HEAD_INIT(NULL)
+    0,                                        /* ob_size */
+    "Server",                                 /* tp_name */
+    sizeof(Server),                           /* tp_basicsize */
+    0,                                        /* tp_itemsize */
+    (destructor)pygrpc_Server_dealloc,        /* tp_dealloc */
+    0,                                        /* tp_print */
+    0,                                        /* tp_getattr */
+    0,                                        /* tp_setattr */
+    0,                                        /* tp_compare */
+    0,                                        /* tp_repr */
+    0,                                        /* tp_as_number */
+    0,                                        /* tp_as_sequence */
+    0,                                        /* tp_as_mapping */
+    0,                                        /* tp_hash */
+    0,                                        /* tp_call */
+    0,                                        /* tp_str */
+    0,                                        /* tp_getattro */
+    0,                                        /* tp_setattro */
+    0,                                        /* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
+    pygrpc_Server_doc,                        /* tp_doc */
+    0,                                        /* tp_traverse */
+    0,                                        /* tp_clear */
+    0,                                        /* tp_richcompare */
+    0,                                        /* tp_weaklistoffset */
+    0,                                        /* tp_iter */
+    0,                                        /* tp_iternext */
+    pygrpc_Server_methods,                    /* tp_methods */
+    0,                                        /* tp_members */
+    0,                                        /* tp_getset */
+    0,                                        /* tp_base */
+    0,                                        /* tp_dict */
+    0,                                        /* tp_descr_get */
+    0,                                        /* tp_descr_set */
+    0,                                        /* tp_dictoffset */
+    0,                                        /* tp_init */
+    0,                                        /* tp_alloc */
+    (newfunc)pygrpc_Server_new                /* tp_new */
+};
+
+Server *pygrpc_Server_new(PyTypeObject *type, PyObject *args, PyObject *kwargs) {
+  Server *self;
+  CompletionQueue *cq;
+  PyObject *py_args;
+  grpc_channel_args c_args;
+  char *keywords[] = {"cq", "args", NULL};
+  if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O!O:Channel", keywords,
+        &pygrpc_CompletionQueue_type, &cq, &py_args)) {
+    return NULL;
+  }
+  if (!pygrpc_produce_channel_args(py_args, &c_args)) {
+    return NULL;
+  }
+  self = (Server *)type->tp_alloc(type, 0);
+  self->c_serv = grpc_server_create(&c_args);
+  pygrpc_discard_channel_args(c_args);
+  self->cq = cq;
+  Py_INCREF(self->cq);
+  return self;
+}
+
+void pygrpc_Server_dealloc(Server *self) {
+  grpc_server_destroy(self->c_serv);
+  Py_XDECREF(self->cq);
+  self->ob_type->tp_free((PyObject *)self);
+}
+
+PyObject *pygrpc_Server_request_call(
+    Server *self, PyObject *args, PyObject *kwargs) {
+  CompletionQueue *cq;
+  PyObject *user_tag;
+  pygrpc_tag *tag;
+  Call *empty_call;
+  grpc_call_error errcode;
+  static char *keywords[] = {"cq", "tag", NULL};
+  if (!PyArg_ParseTupleAndKeywords(
+      args, kwargs, "O!O", keywords,
+      &pygrpc_CompletionQueue_type, &cq, &user_tag)) {
+    return NULL;
+  }
+  empty_call = pygrpc_Call_new_empty(cq);
+  tag = pygrpc_produce_request_tag(user_tag, empty_call);
+  errcode = grpc_server_request_call(
+      self->c_serv, &tag->call->c_call, &tag->request_call_details,
+      &tag->request_metadata, tag->call->cq->c_cq, self->cq->c_cq, tag);
+  Py_DECREF(empty_call);
+  return PyInt_FromLong(errcode);
+}
+
+PyObject *pygrpc_Server_add_http2_port(
+    Server *self, PyObject *args, PyObject *kwargs) {
+  const char *addr;
+  ServerCredentials *creds = NULL;
+  int port;
+  static char *keywords[] = {"addr", "creds", NULL};
+  if (!PyArg_ParseTupleAndKeywords(
+      args, kwargs, "s|O!:add_http2_port", keywords,
+      &addr, &pygrpc_ServerCredentials_type, &creds)) {
+    return NULL;
+  }
+  if (creds) {
+    port = grpc_server_add_secure_http2_port(
+        self->c_serv, addr, creds->c_creds);
+  } else {
+    port = grpc_server_add_http2_port(self->c_serv, addr);
+  }
+  return PyInt_FromLong(port);
+
+}
+
+PyObject *pygrpc_Server_start(Server *self, PyObject *ignored) {
+  grpc_server_start(self->c_serv);
+  Py_RETURN_NONE;
+}
+
+PyObject *pygrpc_Server_shutdown(
+    Server *self, PyObject *args, PyObject *kwargs) {
+  PyObject *user_tag = NULL;
+  pygrpc_tag *tag;
+  static char *keywords[] = {"tag", NULL};
+  if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O", keywords, &user_tag)) {
+    return NULL;
+  }
+  if (user_tag) {
+    tag = pygrpc_produce_server_shutdown_tag(user_tag);
+    grpc_server_shutdown_and_notify(self->c_serv, tag);
+  } else {
+    grpc_server_shutdown(self->c_serv);
+  }
+  Py_RETURN_NONE;
+}
diff --git a/src/python/src/grpc/_adapter/_c/types/server_credentials.c b/src/python/src/grpc/_adapter/_c/types/server_credentials.c
new file mode 100644
index 0000000..2e02c8f
--- /dev/null
+++ b/src/python/src/grpc/_adapter/_c/types/server_credentials.c
@@ -0,0 +1,146 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "grpc/_adapter/_c/types.h"
+
+#define PY_SSIZE_T_CLEAN
+#include <Python.h>
+#include <grpc/grpc.h>
+#include <grpc/grpc_security.h>
+#include <grpc/support/alloc.h>
+
+
+PyMethodDef pygrpc_ServerCredentials_methods[] = {
+    {"ssl", (PyCFunction)pygrpc_ServerCredentials_ssl,
+     METH_CLASS|METH_KEYWORDS, ""},
+    {"fake_transport_security",
+     (PyCFunction)pygrpc_ServerCredentials_fake_transport_security,
+     METH_CLASS|METH_NOARGS, ""},
+    {NULL}
+};
+const char pygrpc_ServerCredentials_doc[] = "";
+PyTypeObject pygrpc_ServerCredentials_type = {
+    PyObject_HEAD_INIT(NULL)
+    0,                                        /* ob_size */
+    "ServerCredentials",                      /* tp_name */
+    sizeof(ServerCredentials),                /* tp_basicsize */
+    0,                                        /* tp_itemsize */
+    (destructor)pygrpc_ServerCredentials_dealloc, /* tp_dealloc */
+    0,                                        /* tp_print */
+    0,                                        /* tp_getattr */
+    0,                                        /* tp_setattr */
+    0,                                        /* tp_compare */
+    0,                                        /* tp_repr */
+    0,                                        /* tp_as_number */
+    0,                                        /* tp_as_sequence */
+    0,                                        /* tp_as_mapping */
+    0,                                        /* tp_hash */
+    0,                                        /* tp_call */
+    0,                                        /* tp_str */
+    0,                                        /* tp_getattro */
+    0,                                        /* tp_setattro */
+    0,                                        /* tp_as_buffer */
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
+    pygrpc_ServerCredentials_doc,             /* tp_doc */
+    0,                                        /* tp_traverse */
+    0,                                        /* tp_clear */
+    0,                                        /* tp_richcompare */
+    0,                                        /* tp_weaklistoffset */
+    0,                                        /* tp_iter */
+    0,                                        /* tp_iternext */
+    pygrpc_ServerCredentials_methods,         /* tp_methods */
+    0,                                        /* tp_members */
+    0,                                        /* tp_getset */
+    0,                                        /* tp_base */
+    0,                                        /* tp_dict */
+    0,                                        /* tp_descr_get */
+    0,                                        /* tp_descr_set */
+    0,                                        /* tp_dictoffset */
+    0,                                        /* tp_init */
+    0,                                        /* tp_alloc */
+    0                                         /* tp_new */
+};
+
+void pygrpc_ServerCredentials_dealloc(ServerCredentials *self) {
+  grpc_server_credentials_release(self->c_creds);
+  self->ob_type->tp_free((PyObject *)self);
+}
+
+ServerCredentials *pygrpc_ServerCredentials_ssl(
+    PyTypeObject *type, PyObject *args, PyObject *kwargs) {
+  ServerCredentials *self;
+  const char *root_certs;
+  PyObject *py_key_cert_pairs;
+  grpc_ssl_pem_key_cert_pair *key_cert_pairs;
+  size_t num_key_cert_pairs;
+  size_t i;
+  static char *keywords[] = {"root_certs", "key_cert_pairs", NULL};
+  if (!PyArg_ParseTupleAndKeywords(args, kwargs, "zO:ssl", keywords,
+        &root_certs, &py_key_cert_pairs)) {
+    return NULL;
+  }
+  if (!PyList_Check(py_key_cert_pairs)) {
+    PyErr_SetString(PyExc_TypeError, "expected a list of 2-tuples of strings");
+    return NULL;
+  }
+  num_key_cert_pairs = PyList_Size(py_key_cert_pairs);
+  key_cert_pairs =
+      gpr_malloc(sizeof(grpc_ssl_pem_key_cert_pair) * num_key_cert_pairs);
+  for (i = 0; i < num_key_cert_pairs; ++i) {
+    PyObject *item = PyList_GET_ITEM(py_key_cert_pairs, i);
+    const char *key;
+    const char *cert;
+    if (!PyArg_ParseTuple(item, "zz", &key, &cert)) {
+      gpr_free(key_cert_pairs);
+      PyErr_SetString(PyExc_TypeError,
+                      "expected a list of 2-tuples of strings");
+      return NULL;
+    }
+    key_cert_pairs[i].private_key = key;
+    key_cert_pairs[i].cert_chain = cert;
+  }
+
+  self = (ServerCredentials *)type->tp_alloc(type, 0);
+  self->c_creds = grpc_ssl_server_credentials_create(
+      root_certs, key_cert_pairs, num_key_cert_pairs);
+  gpr_free(key_cert_pairs);
+  return self;
+}
+
+ServerCredentials *pygrpc_ServerCredentials_fake_transport_security(
+    PyTypeObject *type, PyObject *ignored) {
+  ServerCredentials *self = (ServerCredentials *)type->tp_alloc(type, 0);
+  self->c_creds = grpc_fake_transport_security_server_credentials_create();
+  return self;
+}
+
diff --git a/src/python/src/grpc/_adapter/_c/utility.c b/src/python/src/grpc/_adapter/_c/utility.c
new file mode 100644
index 0000000..6d228c7
--- /dev/null
+++ b/src/python/src/grpc/_adapter/_c/utility.c
@@ -0,0 +1,460 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <math.h>
+
+#define PY_SSIZE_T_CLEAN
+#include <Python.h>
+#include <grpc/grpc.h>
+#include <grpc/support/alloc.h>
+#include <grpc/support/slice.h>
+#include <grpc/support/time.h>
+
+#include "grpc/_adapter/_c/types.h"
+
+pygrpc_tag *pygrpc_produce_batch_tag(
+    PyObject *user_tag, Call *call, grpc_op *ops, size_t nops) {
+  pygrpc_tag *tag = gpr_malloc(sizeof(pygrpc_tag));
+  tag->user_tag = user_tag;
+  Py_XINCREF(tag->user_tag);
+  tag->call = call;
+  Py_XINCREF(tag->call);
+  tag->ops = gpr_malloc(sizeof(grpc_op)*nops);
+  memcpy(tag->ops, ops, sizeof(grpc_op)*nops);
+  tag->nops = nops;
+  grpc_call_details_init(&tag->request_call_details);
+  grpc_metadata_array_init(&tag->request_metadata);
+  tag->is_new_call = 0;
+  return tag;
+}
+
+pygrpc_tag *pygrpc_produce_request_tag(PyObject *user_tag, Call *empty_call) {
+  pygrpc_tag *tag = gpr_malloc(sizeof(pygrpc_tag));
+  tag->user_tag = user_tag;
+  Py_XINCREF(tag->user_tag);
+  tag->call = empty_call;
+  Py_XINCREF(tag->call);
+  tag->ops = NULL;
+  tag->nops = 0;
+  grpc_call_details_init(&tag->request_call_details);
+  grpc_metadata_array_init(&tag->request_metadata);
+  tag->is_new_call = 1;
+  return tag;
+}
+
+pygrpc_tag *pygrpc_produce_server_shutdown_tag(PyObject *user_tag) {
+  pygrpc_tag *tag = gpr_malloc(sizeof(pygrpc_tag));
+  tag->user_tag = user_tag;
+  Py_XINCREF(tag->user_tag);
+  tag->call = NULL;
+  tag->ops = NULL;
+  tag->nops = 0;
+  grpc_call_details_init(&tag->request_call_details);
+  grpc_metadata_array_init(&tag->request_metadata);
+  tag->is_new_call = 0;
+  return tag;
+}
+
+void pygrpc_discard_tag(pygrpc_tag *tag) {
+  if (!tag) {
+    return;
+  }
+  Py_XDECREF(tag->user_tag);
+  Py_XDECREF(tag->call);
+  gpr_free(tag->ops);
+  grpc_call_details_destroy(&tag->request_call_details);
+  grpc_metadata_array_destroy(&tag->request_metadata);
+  gpr_free(tag);
+}
+
+PyObject *pygrpc_consume_event(grpc_event event) {
+  pygrpc_tag *tag;
+  PyObject *result;
+  if (event.type == GRPC_QUEUE_TIMEOUT) {
+    Py_RETURN_NONE;
+  }
+  tag = event.tag;
+  switch (event.type) {
+  case GRPC_QUEUE_SHUTDOWN:
+    result = Py_BuildValue("iOOOOO", GRPC_QUEUE_SHUTDOWN,
+                           Py_None, Py_None, Py_None, Py_None, Py_True);
+    break;
+  case GRPC_OP_COMPLETE:
+    if (tag->is_new_call) {
+      result = Py_BuildValue(
+          "iOO(ssd)[(iNOOOO)]O", GRPC_OP_COMPLETE, tag->user_tag, tag->call,
+          tag->request_call_details.method, tag->request_call_details.host,
+          pygrpc_cast_gpr_timespec_to_double(tag->request_call_details.deadline),
+          GRPC_OP_RECV_INITIAL_METADATA,
+          pygrpc_cast_metadata_array_to_pylist(tag->request_metadata), Py_None,
+          Py_None, Py_None, Py_None,
+          event.success ? Py_True : Py_False);
+    } else {
+      result = Py_BuildValue("iOOONO", GRPC_OP_COMPLETE, tag->user_tag,
+          tag->call, Py_None, pygrpc_consume_ops(tag->ops, tag->nops),
+          event.success ? Py_True : Py_False);
+    }
+    break;
+  default:
+    PyErr_SetString(PyExc_ValueError,
+                    "unknown completion type; could not translate event");
+    return NULL;
+  }
+  pygrpc_discard_tag(tag);
+  return result;
+}
+
+int pygrpc_produce_op(PyObject *op, grpc_op *result) {
+  static const int OP_TUPLE_SIZE = 5;
+  static const int STATUS_TUPLE_SIZE = 2;
+  static const int TYPE_INDEX = 0;
+  static const int INITIAL_METADATA_INDEX = 1;
+  static const int TRAILING_METADATA_INDEX = 2;
+  static const int MESSAGE_INDEX = 3;
+  static const int STATUS_INDEX = 4;
+  static const int STATUS_CODE_INDEX = 0;
+  static const int STATUS_DETAILS_INDEX = 1;
+  grpc_op c_op;
+  if (!PyTuple_Check(op)) {
+    PyErr_SetString(PyExc_TypeError, "expected tuple op");
+    return 0;
+  }
+  if (PyTuple_Size(op) != OP_TUPLE_SIZE) {
+    char buf[64];
+    snprintf(buf, sizeof(buf), "expected tuple op of length %d", OP_TUPLE_SIZE);
+    PyErr_SetString(PyExc_ValueError, buf);
+    return 0;
+  }
+  int type = PyInt_AsLong(PyTuple_GET_ITEM(op, TYPE_INDEX));
+  if (PyErr_Occurred()) {
+    return 0;
+  }
+  Py_ssize_t message_size;
+  char *message;
+  char *status_details;
+  gpr_slice message_slice;
+  c_op.op = type;
+  switch (type) {
+  case GRPC_OP_SEND_INITIAL_METADATA:
+    if (!pygrpc_cast_pylist_to_send_metadata(
+            PyTuple_GetItem(op, INITIAL_METADATA_INDEX),
+            &c_op.data.send_initial_metadata.metadata,
+            &c_op.data.send_initial_metadata.count)) {
+      return 0;
+    }
+    break;
+  case GRPC_OP_SEND_MESSAGE:
+    PyString_AsStringAndSize(
+        PyTuple_GET_ITEM(op, MESSAGE_INDEX), &message, &message_size);
+    message_slice = gpr_slice_from_copied_buffer(message, message_size);
+    c_op.data.send_message = grpc_byte_buffer_create(&message_slice, 1);
+    gpr_slice_unref(message_slice);
+    break;
+  case GRPC_OP_SEND_CLOSE_FROM_CLIENT:
+    /* Don't need to fill in any other fields. */
+    break;
+  case GRPC_OP_SEND_STATUS_FROM_SERVER:
+    if (!pygrpc_cast_pylist_to_send_metadata(
+            PyTuple_GetItem(op, TRAILING_METADATA_INDEX),
+            &c_op.data.send_status_from_server.trailing_metadata,
+            &c_op.data.send_status_from_server.trailing_metadata_count)) {
+      return 0;
+    }
+    if (!PyTuple_Check(PyTuple_GET_ITEM(op, STATUS_INDEX))) {
+      char buf[64];
+      snprintf(buf, sizeof(buf), "expected tuple status in op of length %d",
+               STATUS_TUPLE_SIZE);
+      PyErr_SetString(PyExc_TypeError, buf);
+      return 0;
+    }
+    c_op.data.send_status_from_server.status = PyInt_AsLong(
+        PyTuple_GET_ITEM(PyTuple_GET_ITEM(op, STATUS_INDEX), STATUS_CODE_INDEX));
+    status_details = PyString_AsString(
+        PyTuple_GET_ITEM(PyTuple_GET_ITEM(op, STATUS_INDEX), STATUS_DETAILS_INDEX));
+    if (PyErr_Occurred()) {
+      return 0;
+    }
+    c_op.data.send_status_from_server.status_details =
+        gpr_malloc(strlen(status_details) + 1);
+    strcpy((char *)c_op.data.send_status_from_server.status_details,
+           status_details);
+    break;
+  case GRPC_OP_RECV_INITIAL_METADATA:
+    c_op.data.recv_initial_metadata = gpr_malloc(sizeof(grpc_metadata_array));
+    grpc_metadata_array_init(c_op.data.recv_initial_metadata);
+    break;
+  case GRPC_OP_RECV_MESSAGE:
+    c_op.data.recv_message = gpr_malloc(sizeof(grpc_byte_buffer *));
+    break;
+  case GRPC_OP_RECV_STATUS_ON_CLIENT:
+    c_op.data.recv_status_on_client.trailing_metadata =
+        gpr_malloc(sizeof(grpc_metadata_array));
+    grpc_metadata_array_init(c_op.data.recv_status_on_client.trailing_metadata);
+    c_op.data.recv_status_on_client.status =
+        gpr_malloc(sizeof(grpc_status_code *));
+    c_op.data.recv_status_on_client.status_details =
+        gpr_malloc(sizeof(char *));
+    *c_op.data.recv_status_on_client.status_details = NULL;
+    c_op.data.recv_status_on_client.status_details_capacity =
+        gpr_malloc(sizeof(size_t));
+    *c_op.data.recv_status_on_client.status_details_capacity = 0;
+    break;
+  case GRPC_OP_RECV_CLOSE_ON_SERVER:
+    c_op.data.recv_close_on_server.cancelled = gpr_malloc(sizeof(int));
+    break;
+  default:
+    return 0;
+  }
+  *result = c_op;
+  return 1;
+}
+
+void pygrpc_discard_op(grpc_op op) {
+  switch(op.op) {
+  case GRPC_OP_SEND_INITIAL_METADATA:
+    gpr_free(op.data.send_initial_metadata.metadata);
+    break;
+  case GRPC_OP_SEND_MESSAGE:
+    grpc_byte_buffer_destroy(op.data.send_message);
+    break;
+  case GRPC_OP_SEND_CLOSE_FROM_CLIENT:
+    /* Don't need to free any fields. */
+    break;
+  case GRPC_OP_SEND_STATUS_FROM_SERVER:
+    gpr_free(op.data.send_status_from_server.trailing_metadata);
+    gpr_free((char *)op.data.send_status_from_server.status_details);
+    break;
+  case GRPC_OP_RECV_INITIAL_METADATA:
+    grpc_metadata_array_destroy(op.data.recv_initial_metadata);
+    gpr_free(op.data.recv_initial_metadata);
+    break;
+  case GRPC_OP_RECV_MESSAGE:
+    grpc_byte_buffer_destroy(*op.data.recv_message);
+    gpr_free(op.data.recv_message);
+    break;
+  case GRPC_OP_RECV_STATUS_ON_CLIENT:
+    grpc_metadata_array_destroy(op.data.recv_status_on_client.trailing_metadata);
+    gpr_free(op.data.recv_status_on_client.trailing_metadata);
+    gpr_free(op.data.recv_status_on_client.status);
+    gpr_free(*op.data.recv_status_on_client.status_details);
+    gpr_free(op.data.recv_status_on_client.status_details);
+    gpr_free(op.data.recv_status_on_client.status_details_capacity);
+    break;
+  case GRPC_OP_RECV_CLOSE_ON_SERVER:
+    gpr_free(op.data.recv_close_on_server.cancelled);
+    break;
+  }
+}
+
+PyObject *pygrpc_consume_ops(grpc_op *op, size_t nops) {
+  static const int TYPE_INDEX = 0;
+  static const int INITIAL_METADATA_INDEX = 1;
+  static const int TRAILING_METADATA_INDEX = 2;
+  static const int MESSAGE_INDEX = 3;
+  static const int STATUS_INDEX = 4;
+  static const int CANCELLED_INDEX = 5;
+  static const int OPRESULT_LENGTH = 6;
+  PyObject *list;
+  size_t i;
+  size_t j;
+  char *bytes;
+  size_t bytes_size;
+  PyObject *results = PyList_New(nops);
+  if (!results) {
+    return NULL;
+  }
+  for (i = 0; i < nops; ++i) {
+    PyObject *result = PyTuple_Pack(OPRESULT_LENGTH, Py_None, Py_None, Py_None,
+                                    Py_None, Py_None, Py_None);
+    PyTuple_SetItem(result, TYPE_INDEX, PyInt_FromLong(op[i].op));
+    switch(op[i].op) {
+    case GRPC_OP_RECV_INITIAL_METADATA:
+      PyTuple_SetItem(result, INITIAL_METADATA_INDEX,
+                      list=PyList_New(op[i].data.recv_initial_metadata->count));
+      for (j = 0; j < op[i].data.recv_initial_metadata->count; ++j) {
+        grpc_metadata md = op[i].data.recv_initial_metadata->metadata[j];
+        PyList_SetItem(list, j, Py_BuildValue("ss#", md.key, md.value,
+                                              (Py_ssize_t)md.value_length));
+      }
+      break;
+    case GRPC_OP_RECV_MESSAGE:
+      if (*op[i].data.recv_message) {
+        pygrpc_byte_buffer_to_bytes(
+            *op[i].data.recv_message, &bytes, &bytes_size);
+        PyTuple_SetItem(result, MESSAGE_INDEX,
+                        PyString_FromStringAndSize(bytes, bytes_size));
+        gpr_free(bytes);
+      } else {
+        PyTuple_SetItem(result, MESSAGE_INDEX, Py_BuildValue(""));
+      }
+      break;
+    case GRPC_OP_RECV_STATUS_ON_CLIENT:
+      PyTuple_SetItem(
+          result, TRAILING_METADATA_INDEX,
+          list = PyList_New(op[i].data.recv_status_on_client.trailing_metadata->count));
+      for (j = 0; j < op[i].data.recv_status_on_client.trailing_metadata->count; ++j) {
+        grpc_metadata md =
+            op[i].data.recv_status_on_client.trailing_metadata->metadata[j];
+        PyList_SetItem(list, j, Py_BuildValue("ss#", md.key, md.value,
+                                              (Py_ssize_t)md.value_length));
+      }
+      PyTuple_SetItem(
+          result, STATUS_INDEX, Py_BuildValue(
+              "is", *op[i].data.recv_status_on_client.status,
+              *op[i].data.recv_status_on_client.status_details));
+      break;
+    case GRPC_OP_RECV_CLOSE_ON_SERVER:
+      PyTuple_SetItem(
+          result, CANCELLED_INDEX,
+          PyBool_FromLong(*op[i].data.recv_close_on_server.cancelled));
+      break;
+    default:
+      break;
+    }
+    pygrpc_discard_op(op[i]);
+    PyList_SetItem(results, i, result);
+  }
+  return results;
+}
+
+double pygrpc_cast_gpr_timespec_to_double(gpr_timespec timespec) {
+  return timespec.tv_sec + 1e-9*timespec.tv_nsec;
+}
+
+gpr_timespec pygrpc_cast_double_to_gpr_timespec(double seconds) {
+  gpr_timespec result;
+  if isinf(seconds) {
+    result = seconds > 0.0 ? gpr_inf_future : gpr_inf_past;
+  } else {
+    result.tv_sec = (time_t)seconds;
+    result.tv_nsec = ((seconds - result.tv_sec) * 1e9);
+  }
+  return result;
+}
+
+int pygrpc_produce_channel_args(PyObject *py_args, grpc_channel_args *c_args) {
+  size_t num_args = PyList_Size(py_args);
+  size_t i;
+  grpc_channel_args args = {num_args, gpr_malloc(sizeof(grpc_arg) * num_args)};
+  for (i = 0; i < args.num_args; ++i) {
+    char *key;
+    PyObject *value;
+    if (!PyArg_ParseTuple(PyList_GetItem(py_args, i), "zO", &key, &value)) {
+      gpr_free(args.args);
+      args.num_args = 0;
+      args.args = NULL;
+      PyErr_SetString(PyExc_TypeError,
+                      "expected a list of 2-tuple of str and str|int|None");
+      return 0;
+    }
+    args.args[i].key = key;
+    if (PyInt_Check(value)) {
+      args.args[i].type = GRPC_ARG_INTEGER;
+      args.args[i].value.integer = PyInt_AsLong(value);
+    } else if (PyString_Check(value)) {
+      args.args[i].type = GRPC_ARG_STRING;
+      args.args[i].value.string = PyString_AsString(value);
+    } else if (value == Py_None) {
+      --args.num_args;
+      --i;
+      continue;
+    } else {
+      gpr_free(args.args);
+      args.num_args = 0;
+      args.args = NULL;
+      PyErr_SetString(PyExc_TypeError,
+                      "expected a list of 2-tuple of str and str|int|None");
+      return 0;
+    }
+  }
+  *c_args = args;
+  return 1;
+}
+
+void pygrpc_discard_channel_args(grpc_channel_args args) {
+  gpr_free(args.args);
+}
+
+int pygrpc_cast_pylist_to_send_metadata(
+    PyObject *pylist, grpc_metadata **metadata, size_t *count) {
+  size_t i;
+  Py_ssize_t value_length;
+  *count = PyList_Size(pylist);
+  *metadata = gpr_malloc(sizeof(grpc_metadata) * *count);
+  for (i = 0; i < *count; ++i) {
+    if (!PyArg_ParseTuple(
+        PyList_GetItem(pylist, i), "ss#",
+        &(*metadata)[i].key, &(*metadata)[i].value, &value_length)) {
+      gpr_free(*metadata);
+      *count = 0;
+      *metadata = NULL;
+      return 0;
+    }
+    (*metadata)[i].value_length = value_length;
+  }
+  return 1;
+}
+
+PyObject *pygrpc_cast_metadata_array_to_pylist(grpc_metadata_array metadata) {
+  PyObject *result = PyList_New(metadata.count);
+  size_t i;
+  for (i = 0; i < metadata.count; ++i) {
+    PyList_SetItem(
+        result, i, Py_BuildValue(
+            "ss#", metadata.metadata[i].key, metadata.metadata[i].value,
+            (Py_ssize_t)metadata.metadata[i].value_length));
+    if (PyErr_Occurred()) {
+      Py_DECREF(result);
+      return NULL;
+    }
+  }
+  return result;
+}
+
+void pygrpc_byte_buffer_to_bytes(
+    grpc_byte_buffer *buffer, char **result, size_t *result_size) {
+  grpc_byte_buffer_reader *reader = grpc_byte_buffer_reader_create(buffer);
+  gpr_slice slice;
+  char *read_result = NULL;
+  size_t size = 0;
+  while (grpc_byte_buffer_reader_next(reader, &slice)) {
+    read_result = gpr_realloc(read_result, size + GPR_SLICE_LENGTH(slice));
+    memcpy(read_result + size, GPR_SLICE_START_PTR(slice),
+           GPR_SLICE_LENGTH(slice));
+    size = size + GPR_SLICE_LENGTH(slice);
+    gpr_slice_unref(slice);
+  }
+  grpc_byte_buffer_reader_destroy(reader);
+  *result_size = size;
+  *result = read_result;
+}
diff --git a/src/python/src/grpc/_adapter/_c_test.py b/src/python/src/grpc/_adapter/_c_test.py
index b06215f..133b124 100644
--- a/src/python/src/grpc/_adapter/_c_test.py
+++ b/src/python/src/grpc/_adapter/_c_test.py
@@ -27,193 +27,41 @@
 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-"""Tests for _adapter._c."""
-
-import threading
 import time
 import unittest
 
 from grpc._adapter import _c
-from grpc._adapter import _datatypes
-
-_TIMEOUT = 3
-_FUTURE = time.time() + 60 * 60 * 24
-_IDEMPOTENCE_DEMONSTRATION = 7
+from grpc._adapter import _types
 
 
-class _CTest(unittest.TestCase):
+class CTypeSmokeTest(unittest.TestCase):
 
-  def testUpAndDown(self):
-    _c.init()
-    _c.shut_down()
+  def testClientCredentialsUpDown(self):
+    credentials = _c.ClientCredentials.fake_transport_security()
+    del credentials
 
-  def testCompletionQueue(self):
-    _c.init()
+  def testServerCredentialsUpDown(self):
+    credentials = _c.ServerCredentials.fake_transport_security()
+    del credentials
 
+  def testCompletionQueueUpDown(self):
     completion_queue = _c.CompletionQueue()
-    event = completion_queue.get(0)
-    self.assertIsNone(event)
-    event = completion_queue.get(time.time())
-    self.assertIsNone(event)
-    event = completion_queue.get(time.time() + _TIMEOUT)
-    self.assertIsNone(event)
-    completion_queue.stop()
-    for _ in range(_IDEMPOTENCE_DEMONSTRATION):
-      event = completion_queue.get(time.time() + _TIMEOUT)
-      self.assertIs(event.kind, _datatypes.Event.Kind.STOP)
-
     del completion_queue
-    del event
 
-    _c.shut_down()
+  def testServerUpDown(self):
+    completion_queue = _c.CompletionQueue()
+    serv = _c.Server(completion_queue, [])
+    del serv
+    del completion_queue
 
-  def testChannel(self):
-    _c.init()
-
-    channel = _c.Channel(
-        'test host:12345', None, server_host_override='ignored')
+  def testChannelUpDown(self):
+    channel = _c.Channel('[::]:0', [])
     del channel
 
-    _c.shut_down()
-
-  def testCall(self):
-    method = 'test method'
-    host = 'test host'
-
-    _c.init()
-
-    channel = _c.Channel('%s:%d' % (host, 12345), None)
-    completion_queue = _c.CompletionQueue()
-    call = _c.Call(channel, completion_queue, method, host,
-                   time.time() + _TIMEOUT)
-    del call
-    del completion_queue
+  def testSecureChannelUpDown(self):
+    channel = _c.Channel('[::]:0', [], _c.ClientCredentials.fake_transport_security())
     del channel
 
-    _c.shut_down()
-
-  def testServer(self):
-    _c.init()
-
-    completion_queue = _c.CompletionQueue()
-    server = _c.Server(completion_queue)
-    server.add_http2_addr('[::]:0')
-    server.start()
-    server.stop()
-    completion_queue.stop()
-    del server
-    del completion_queue
-
-    service_tag = object()
-    completion_queue = _c.CompletionQueue()
-    server = _c.Server(completion_queue)
-    server.add_http2_addr('[::]:0')
-    server.start()
-    server.service(service_tag)
-    server.stop()
-    completion_queue.stop()
-    event = completion_queue.get(time.time() + _TIMEOUT)
-    self.assertIs(event.kind, _datatypes.Event.Kind.SERVICE_ACCEPTED)
-    self.assertIs(event.tag, service_tag)
-    self.assertIsNone(event.service_acceptance)
-    for _ in range(_IDEMPOTENCE_DEMONSTRATION):
-      event = completion_queue.get(time.time() + _TIMEOUT)
-      self.assertIs(event.kind, _datatypes.Event.Kind.STOP)
-    del server
-    del completion_queue
-
-    completion_queue = _c.CompletionQueue()
-    server = _c.Server(completion_queue)
-    server.add_http2_addr('[::]:0')
-    server.start()
-    thread = threading.Thread(target=completion_queue.get, args=(_FUTURE,))
-    thread.start()
-    time.sleep(1)
-    server.stop()
-    completion_queue.stop()
-    for _ in range(_IDEMPOTENCE_DEMONSTRATION):
-      event = completion_queue.get(time.time() + _TIMEOUT)
-      self.assertIs(event.kind, _datatypes.Event.Kind.STOP)
-    thread.join()
-    del server
-    del completion_queue
-
-    _c.shut_down()
-
-  def test_client_credentials(self):
-    root_certificates = b'Trust starts here. Really.'
-    private_key = b'This is a really bad private key, yo.'
-    certificate_chain = b'Trust me! Do I not look trustworty?'
-
-    _c.init()
-
-    client_credentials = _c.ClientCredentials(
-        None, None, None)
-    self.assertIsNotNone(client_credentials)
-    client_credentials = _c.ClientCredentials(
-        root_certificates, None, None)
-    self.assertIsNotNone(client_credentials)
-    client_credentials = _c.ClientCredentials(
-        None, private_key, certificate_chain)
-    self.assertIsNotNone(client_credentials)
-    client_credentials = _c.ClientCredentials(
-        root_certificates, private_key, certificate_chain)
-    self.assertIsNotNone(client_credentials)
-    del client_credentials
-
-    _c.shut_down()
-
-  def test_server_credentials(self):
-    root_certificates = b'Trust starts here. Really.'
-    first_private_key = b'This is a really bad private key, yo.'
-    first_certificate_chain = b'Trust me! Do I not look trustworty?'
-    second_private_key = b'This is another bad private key, yo.'
-    second_certificate_chain = b'Look into my eyes; you can totes trust me.'
-
-    _c.init()
-
-    server_credentials = _c.ServerCredentials(
-        None, ((first_private_key, first_certificate_chain),))
-    del server_credentials
-    server_credentials = _c.ServerCredentials(
-        root_certificates, ((first_private_key, first_certificate_chain),))
-    del server_credentials
-    server_credentials = _c.ServerCredentials(
-        root_certificates,
-        ((first_private_key, first_certificate_chain),
-         (second_private_key, second_certificate_chain),))
-    del server_credentials
-    with self.assertRaises(TypeError):
-      _c.ServerCredentials(
-          root_certificates, first_private_key, second_certificate_chain)
-
-    _c.shut_down()
-
-  @unittest.skip('TODO(nathaniel): find and use real-enough test credentials')
-  def test_secure_server(self):
-    _c.init()
-
-    server_credentials = _c.ServerCredentials(
-        'root certificate', (('private key', 'certificate chain'),))
-
-    completion_queue = _c.CompletionQueue()
-    server = _c.Server(completion_queue, server_credentials)
-    server.add_http2_addr('[::]:0')
-    server.start()
-    thread = threading.Thread(target=completion_queue.get, args=(_FUTURE,))
-    thread.start()
-    time.sleep(1)
-    server.stop()
-    completion_queue.stop()
-    for _ in range(_IDEMPOTENCE_DEMONSTRATION):
-      event = completion_queue.get(time.time() + _TIMEOUT)
-      self.assertIs(event.kind, _datatypes.Event.Kind.STOP)
-    thread.join()
-    del server
-    del completion_queue
-
-    _c.shut_down()
-
 
 if __name__ == '__main__':
   unittest.main(verbosity=2)
diff --git a/src/python/src/grpc/_adapter/_call.c b/src/python/src/grpc/_adapter/_call.c
deleted file mode 100644
index d833268..0000000
--- a/src/python/src/grpc/_adapter/_call.c
+++ /dev/null
@@ -1,438 +0,0 @@
-/*
- *
- * Copyright 2015, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#include "grpc/_adapter/_call.h"
-
-#include <math.h>
-#include <Python.h>
-#include <grpc/grpc.h>
-#include <grpc/support/alloc.h>
-
-#include "grpc/_adapter/_channel.h"
-#include "grpc/_adapter/_completion_queue.h"
-#include "grpc/_adapter/_error.h"
-#include "grpc/_adapter/_tag.h"
-
-static PyObject *pygrpc_call_new(PyTypeObject *type, PyObject *args, PyObject *kwds) {
-  Call *self = (Call *)type->tp_alloc(type, 0);
-  Channel *channel;
-  CompletionQueue *completion_queue;
-  const char *method;
-  const char *host;
-  double deadline;
-  static char *kwlist[] = {"channel", "completion_queue",
-    "method", "host", "deadline", NULL};
-
-  if (!PyArg_ParseTupleAndKeywords(
-      args, kwds, "O!O!ssd:Call", kwlist,
-      &pygrpc_ChannelType, &channel,
-      &pygrpc_CompletionQueueType, &completion_queue,
-      &method, &host, &deadline)) {
-    return NULL;
-  }
-
-  /* TODO(nathaniel): Hoist the gpr_timespec <-> PyFloat arithmetic into its own
-   * function with its own test coverage.
-   */
-  self->c_call = grpc_channel_create_call(
-      channel->c_channel, completion_queue->c_completion_queue, method, host,
-      gpr_time_from_nanos(deadline * GPR_NS_PER_SEC));
-  self->completion_queue = completion_queue;
-  Py_INCREF(self->completion_queue);
-  self->channel = channel;
-  Py_INCREF(self->channel);
-  grpc_call_details_init(&self->call_details);
-  grpc_metadata_array_init(&self->recv_metadata);
-  grpc_metadata_array_init(&self->recv_trailing_metadata);
-  self->send_metadata = NULL;
-  self->send_metadata_count = 0;
-  self->send_trailing_metadata = NULL;
-  self->send_trailing_metadata_count = 0;
-  self->send_message = NULL;
-  self->recv_message = NULL;
-  self->adding_to_trailing = 0;
-
-  return (PyObject *)self;
-}
-
-static void pygrpc_call_dealloc(Call *self) {
-  if (self->c_call != NULL) {
-    grpc_call_destroy(self->c_call);
-  }
-  Py_XDECREF(self->completion_queue);
-  Py_XDECREF(self->channel);
-  Py_XDECREF(self->server);
-  grpc_call_details_destroy(&self->call_details);
-  grpc_metadata_array_destroy(&self->recv_metadata);
-  grpc_metadata_array_destroy(&self->recv_trailing_metadata);
-  if (self->send_message) {
-    grpc_byte_buffer_destroy(self->send_message);
-  }
-  if (self->recv_message) {
-    grpc_byte_buffer_destroy(self->recv_message);
-  }
-  gpr_free(self->status_details);
-  gpr_free(self->send_metadata);
-  gpr_free(self->send_trailing_metadata);
-  self->ob_type->tp_free((PyObject *)self);
-}
-
-static const PyObject *pygrpc_call_invoke(Call *self, PyObject *args) {
-  PyObject *completion_queue;
-  PyObject *metadata_tag;
-  PyObject *finish_tag;
-  grpc_call_error call_error;
-  const PyObject *result;
-  pygrpc_tag *c_init_metadata_tag;
-  pygrpc_tag *c_metadata_tag;
-  pygrpc_tag *c_finish_tag;
-  grpc_op send_initial_metadata;
-  grpc_op recv_initial_metadata;
-  grpc_op recv_status_on_client;
-
-  if (!(PyArg_ParseTuple(args, "O!OO:invoke", &pygrpc_CompletionQueueType,
-                         &completion_queue, &metadata_tag, &finish_tag))) {
-    return NULL;
-  }
-  send_initial_metadata.op = GRPC_OP_SEND_INITIAL_METADATA;
-  send_initial_metadata.data.send_initial_metadata.metadata = self->send_metadata;
-  send_initial_metadata.data.send_initial_metadata.count = self->send_metadata_count;
-  recv_initial_metadata.op = GRPC_OP_RECV_INITIAL_METADATA;
-  recv_initial_metadata.data.recv_initial_metadata = &self->recv_metadata;
-  recv_status_on_client.op = GRPC_OP_RECV_STATUS_ON_CLIENT;
-  recv_status_on_client.data.recv_status_on_client.trailing_metadata = &self->recv_trailing_metadata;
-  recv_status_on_client.data.recv_status_on_client.status = &self->status;
-  recv_status_on_client.data.recv_status_on_client.status_details = &self->status_details;
-  recv_status_on_client.data.recv_status_on_client.status_details_capacity = &self->status_details_capacity;
-  c_init_metadata_tag = pygrpc_tag_new(PYGRPC_INITIAL_METADATA, NULL, self);
-  c_metadata_tag = pygrpc_tag_new(PYGRPC_CLIENT_METADATA_READ, metadata_tag, self);
-  c_finish_tag = pygrpc_tag_new(PYGRPC_FINISHED_CLIENT, finish_tag, self);
-
-  call_error = grpc_call_start_batch(self->c_call, &send_initial_metadata, 1, c_init_metadata_tag);
-  result = pygrpc_translate_call_error(call_error);
-  if (result == NULL) {
-    pygrpc_tag_destroy(c_init_metadata_tag);
-    pygrpc_tag_destroy(c_metadata_tag);
-    pygrpc_tag_destroy(c_finish_tag);
-    return result;
-  }
-  call_error = grpc_call_start_batch(self->c_call, &recv_initial_metadata, 1, c_metadata_tag);
-  result = pygrpc_translate_call_error(call_error);
-  if (result == NULL) {
-    pygrpc_tag_destroy(c_metadata_tag);
-    pygrpc_tag_destroy(c_finish_tag);
-    return result;
-  }
-  call_error = grpc_call_start_batch(self->c_call, &recv_status_on_client, 1, c_finish_tag);
-  result = pygrpc_translate_call_error(call_error);
-  if (result == NULL) {
-    pygrpc_tag_destroy(c_finish_tag);
-    return result;
-  }
-
-  return result;
-}
-
-static const PyObject *pygrpc_call_write(Call *self, PyObject *args) {
-  const char *bytes;
-  int length;
-  PyObject *tag;
-  gpr_slice slice;
-  grpc_byte_buffer *byte_buffer;
-  grpc_call_error call_error;
-  const PyObject *result;
-  pygrpc_tag *c_tag;
-  grpc_op op;
-
-  if (!(PyArg_ParseTuple(args, "s#O:write", &bytes, &length, &tag))) {
-    return NULL;
-  }
-  c_tag = pygrpc_tag_new(PYGRPC_WRITE_ACCEPTED, tag, self);
-
-  slice = gpr_slice_from_copied_buffer(bytes, length);
-  byte_buffer = grpc_byte_buffer_create(&slice, 1);
-  gpr_slice_unref(slice);
-
-  if (self->send_message) {
-    grpc_byte_buffer_destroy(self->send_message);
-  }
-  self->send_message = byte_buffer;
-
-  op.op = GRPC_OP_SEND_MESSAGE;
-  op.data.send_message = self->send_message;
-
-  call_error = grpc_call_start_batch(self->c_call, &op, 1, c_tag);
-
-  result = pygrpc_translate_call_error(call_error);
-  if (result == NULL) {
-    pygrpc_tag_destroy(c_tag);
-  }
-  return result;
-}
-
-static const PyObject *pygrpc_call_complete(Call *self, PyObject *tag) {
-  grpc_call_error call_error;
-  const PyObject *result;
-  pygrpc_tag *c_tag = pygrpc_tag_new(PYGRPC_FINISH_ACCEPTED, tag, self);
-  grpc_op op;
-
-  op.op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
-
-  call_error = grpc_call_start_batch(self->c_call, &op, 1, c_tag);
-
-  result = pygrpc_translate_call_error(call_error);
-  if (result == NULL) {
-    pygrpc_tag_destroy(c_tag);
-  }
-  return result;
-}
-
-static const PyObject *pygrpc_call_accept(Call *self, PyObject *args) {
-  PyObject *completion_queue;
-  PyObject *tag;
-  grpc_call_error call_error;
-  const PyObject *result;
-  pygrpc_tag *c_tag;
-  grpc_op op;
-
-  if (!(PyArg_ParseTuple(args, "O!O:accept", &pygrpc_CompletionQueueType,
-                         &completion_queue, &tag))) {
-    return NULL;
-  }
-
-  op.op = GRPC_OP_RECV_CLOSE_ON_SERVER;
-  op.data.recv_close_on_server.cancelled = &self->cancelled;
-  c_tag = pygrpc_tag_new(PYGRPC_FINISHED_SERVER, tag, self);
-
-  call_error = grpc_call_start_batch(self->c_call, &op, 1, c_tag);
-  result = pygrpc_translate_call_error(call_error);
-  if (result == NULL) {
-    pygrpc_tag_destroy(c_tag);
-  }
-  return result;
-}
-
-static const PyObject *pygrpc_call_add_metadata(Call *self, PyObject *args) {
-  const char* key = NULL;
-  const char* value = NULL;
-  int value_length = 0;
-  grpc_metadata metadata;
-  if (!PyArg_ParseTuple(args, "ss#", &key, &value, &value_length)) {
-    return NULL;
-  }
-  metadata.key = key;
-  metadata.value = value;
-  metadata.value_length = value_length;
-  if (self->adding_to_trailing) {
-    self->send_trailing_metadata = gpr_realloc(self->send_trailing_metadata, (self->send_trailing_metadata_count + 1) * sizeof(grpc_metadata));
-    self->send_trailing_metadata[self->send_trailing_metadata_count] = metadata;
-    self->send_trailing_metadata_count = self->send_trailing_metadata_count + 1;
-  } else {
-    self->send_metadata = gpr_realloc(self->send_metadata, (self->send_metadata_count + 1) * sizeof(grpc_metadata));
-    self->send_metadata[self->send_metadata_count] = metadata;
-    self->send_metadata_count = self->send_metadata_count + 1;
-  }
-  return pygrpc_translate_call_error(GRPC_CALL_OK);
-}
-
-static const PyObject *pygrpc_call_premetadata(Call *self) {
-  grpc_op op;
-  grpc_call_error call_error;
-  const PyObject *result;
-  pygrpc_tag *c_tag = pygrpc_tag_new(PYGRPC_INITIAL_METADATA, NULL, self);
-  op.op = GRPC_OP_SEND_INITIAL_METADATA;
-  op.data.send_initial_metadata.metadata = self->send_metadata;
-  op.data.send_initial_metadata.count = self->send_metadata_count;
-  self->adding_to_trailing = 1;
-
-  call_error = grpc_call_start_batch(self->c_call, &op, 1, c_tag);
-  result = pygrpc_translate_call_error(call_error);
-  if (result == NULL) {
-    pygrpc_tag_destroy(c_tag);
-  }
-  return result;
-}
-
-static const PyObject *pygrpc_call_read(Call *self, PyObject *tag) {
-  grpc_op op;
-  grpc_call_error call_error;
-  const PyObject *result;
-  pygrpc_tag *c_tag = pygrpc_tag_new(PYGRPC_READ, tag, self);
-
-  op.op = GRPC_OP_RECV_MESSAGE;
-  if (self->recv_message) {
-    grpc_byte_buffer_destroy(self->recv_message);
-    self->recv_message = NULL;
-  }
-  op.data.recv_message = &self->recv_message;
-  call_error = grpc_call_start_batch(self->c_call, &op, 1, c_tag);
-  result = pygrpc_translate_call_error(call_error);
-  if (result == NULL) {
-    pygrpc_tag_destroy(c_tag);
-  }
-  return result;
-}
-
-static const PyObject *pygrpc_call_status(Call *self, PyObject *args) {
-  PyObject *status;
-  PyObject *code;
-  PyObject *details;
-  PyObject *tag;
-  grpc_status_code c_code;
-  char *c_message;
-  grpc_call_error call_error;
-  const PyObject *result;
-  pygrpc_tag *c_tag;
-  grpc_op op;
-
-  if (!(PyArg_ParseTuple(args, "OO:status", &status, &tag))) {
-    return NULL;
-  }
-  c_tag = pygrpc_tag_new(PYGRPC_FINISH_ACCEPTED, tag, self);
-
-  code = PyObject_GetAttrString(status, "code");
-  if (code == NULL) {
-    return NULL;
-  }
-  details = PyObject_GetAttrString(status, "details");
-  if (details == NULL) {
-    Py_DECREF(code);
-    return NULL;
-  }
-  c_code = PyInt_AsLong(code);
-  Py_DECREF(code);
-  if (c_code == -1 && PyErr_Occurred()) {
-    Py_DECREF(details);
-    return NULL;
-  }
-  c_message = PyBytes_AsString(details);
-  Py_DECREF(details);
-  if (c_message == NULL) {
-    return NULL;
-  }
-  if (self->status_details) {
-    gpr_free(self->status_details);
-  }
-  self->status_details = gpr_malloc(strlen(c_message)+1);
-  strcpy(self->status_details, c_message);
-  op.op = GRPC_OP_SEND_STATUS_FROM_SERVER;
-  op.data.send_status_from_server.trailing_metadata_count = self->send_trailing_metadata_count;
-  op.data.send_status_from_server.trailing_metadata = self->send_trailing_metadata;
-  op.data.send_status_from_server.status = c_code;
-  op.data.send_status_from_server.status_details = self->status_details;
-
-  call_error = grpc_call_start_batch(self->c_call, &op, 1, c_tag);
-  result = pygrpc_translate_call_error(call_error);
-  if (result == NULL) {
-    pygrpc_tag_destroy(c_tag);
-  }
-  return result;
-}
-
-static const PyObject *pygrpc_call_cancel(Call *self) {
-  return pygrpc_translate_call_error(grpc_call_cancel(self->c_call));
-}
-
-static PyMethodDef methods[] = {
-    {"invoke", (PyCFunction)pygrpc_call_invoke, METH_VARARGS,
-     "Invoke this call."},
-    {"write", (PyCFunction)pygrpc_call_write, METH_VARARGS,
-     "Write bytes to this call."},
-    {"complete", (PyCFunction)pygrpc_call_complete, METH_O,
-     "Complete writes to this call."},
-    {"accept", (PyCFunction)pygrpc_call_accept, METH_VARARGS, "Accept an RPC."},
-    {"add_metadata", (PyCFunction)pygrpc_call_add_metadata, METH_VARARGS,
-     "Add metadata to the call. May not be called after invoke on the client "
-     "side. On the server side: when called before premetadata it provides "
-     "'leading' metadata, when called after premetadata but before status it "
-     "provides 'trailing metadata'; may not be called after status."},
-    {"premetadata", (PyCFunction)pygrpc_call_premetadata, METH_VARARGS,
-     "Indicate the end of leading metadata in the response."},
-    {"read", (PyCFunction)pygrpc_call_read, METH_O,
-     "Read bytes from this call."},
-    {"status", (PyCFunction)pygrpc_call_status, METH_VARARGS,
-     "Report this call's status."},
-    {"cancel", (PyCFunction)pygrpc_call_cancel, METH_NOARGS,
-     "Cancel this call."},
-    {NULL}};
-
-PyTypeObject pygrpc_CallType = {
-    PyVarObject_HEAD_INIT(NULL, 0)
-    "_grpc.Call",                    /*tp_name*/
-    sizeof(Call),                    /*tp_basicsize*/
-    0,                               /*tp_itemsize*/
-    (destructor)pygrpc_call_dealloc, /*tp_dealloc*/
-    0,                               /*tp_print*/
-    0,                               /*tp_getattr*/
-    0,                               /*tp_setattr*/
-    0,                               /*tp_compare*/
-    0,                               /*tp_repr*/
-    0,                               /*tp_as_number*/
-    0,                               /*tp_as_sequence*/
-    0,                               /*tp_as_mapping*/
-    0,                               /*tp_hash */
-    0,                               /*tp_call*/
-    0,                               /*tp_str*/
-    0,                               /*tp_getattro*/
-    0,                               /*tp_setattro*/
-    0,                               /*tp_as_buffer*/
-    Py_TPFLAGS_DEFAULT,              /*tp_flags*/
-    "Wrapping of grpc_call.",        /* tp_doc */
-    0,                               /* tp_traverse */
-    0,                               /* tp_clear */
-    0,                               /* tp_richcompare */
-    0,                               /* tp_weaklistoffset */
-    0,                               /* tp_iter */
-    0,                               /* tp_iternext */
-    methods,                         /* tp_methods */
-    0,                               /* tp_members */
-    0,                               /* tp_getset */
-    0,                               /* tp_base */
-    0,                               /* tp_dict */
-    0,                               /* tp_descr_get */
-    0,                               /* tp_descr_set */
-    0,                               /* tp_dictoffset */
-    0,                               /* tp_init */
-    0,                               /* tp_alloc */
-    pygrpc_call_new,                 /* tp_new */
-};
-
-int pygrpc_add_call(PyObject *module) {
-  if (PyType_Ready(&pygrpc_CallType) < 0) {
-    return -1;
-  }
-  if (PyModule_AddObject(module, "Call", (PyObject *)&pygrpc_CallType) == -1) {
-    return -1;
-  }
-  return 0;
-}
diff --git a/src/python/src/grpc/_adapter/_call.h b/src/python/src/grpc/_adapter/_call.h
deleted file mode 100644
index b4cf9d7..0000000
--- a/src/python/src/grpc/_adapter/_call.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- *
- * Copyright 2015, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#ifndef _ADAPTER__CALL_H_
-#define _ADAPTER__CALL_H_
-
-#include <Python.h>
-#include <grpc/grpc.h>
-
-#include "grpc/_adapter/_completion_queue.h"
-#include "grpc/_adapter/_channel.h"
-#include "grpc/_adapter/_server.h"
-
-typedef struct {
-  PyObject_HEAD
-
-  CompletionQueue *completion_queue;
-  Channel *channel;
-  Server *server;
-
-  /* Legacy state. */
-  grpc_call_details call_details;
-  grpc_metadata_array recv_metadata;
-  grpc_metadata_array recv_trailing_metadata;
-  grpc_metadata *send_metadata;
-  size_t send_metadata_count;
-  grpc_metadata *send_trailing_metadata;
-  size_t send_trailing_metadata_count;
-  int adding_to_trailing;
-
-  grpc_byte_buffer *send_message;
-  grpc_byte_buffer *recv_message;
-
-  grpc_status_code status;
-  char *status_details;
-  size_t status_details_capacity;
-
-  int cancelled;
-
-  grpc_call *c_call;
-} Call;
-
-extern PyTypeObject pygrpc_CallType;
-
-int pygrpc_add_call(PyObject *module);
-
-#endif /* _ADAPTER__CALL_H_ */
diff --git a/src/python/src/grpc/_adapter/_channel.c b/src/python/src/grpc/_adapter/_channel.c
deleted file mode 100644
index 6be8f1c..0000000
--- a/src/python/src/grpc/_adapter/_channel.c
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- *
- * Copyright 2015, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#include "grpc/_adapter/_channel.h"
-
-#include <Python.h>
-#include <grpc/grpc.h>
-#include <grpc/grpc_security.h>
-
-#include "grpc/_adapter/_client_credentials.h"
-
-static int pygrpc_channel_init(Channel *self, PyObject *args, PyObject *kwds) {
-  const char *hostport;
-  PyObject *client_credentials;
-  char *server_host_override = NULL;
-  static char *kwlist[] = {"hostport", "client_credentials",
-                           "server_host_override", NULL};
-  grpc_arg server_host_override_arg;
-  grpc_channel_args channel_args;
-
-  if (!(PyArg_ParseTupleAndKeywords(args, kwds, "sO|z:Channel", kwlist,
-                                    &hostport, &client_credentials,
-                                    &server_host_override))) {
-    return -1;
-  }
-  if (client_credentials == Py_None) {
-    self->c_channel = grpc_channel_create(hostport, NULL);
-    return 0;
-  } else {
-    if (server_host_override == NULL) {
-      self->c_channel = grpc_secure_channel_create(
-	  ((ClientCredentials *)client_credentials)->c_client_credentials,
-          hostport, NULL);
-    } else {
-      server_host_override_arg.type = GRPC_ARG_STRING;
-      server_host_override_arg.key = GRPC_SSL_TARGET_NAME_OVERRIDE_ARG;
-      server_host_override_arg.value.string = server_host_override;
-      channel_args.num_args = 1;
-      channel_args.args = &server_host_override_arg;
-      self->c_channel = grpc_secure_channel_create(
-          ((ClientCredentials *)client_credentials)->c_client_credentials,
-          hostport, &channel_args);
-    }
-    return 0;
-  }
-}
-
-static void pygrpc_channel_dealloc(Channel *self) {
-  if (self->c_channel != NULL) {
-    grpc_channel_destroy(self->c_channel);
-  }
-  self->ob_type->tp_free((PyObject *)self);
-}
-
-PyTypeObject pygrpc_ChannelType = {
-    PyVarObject_HEAD_INIT(NULL, 0)
-    "_grpc.Channel",                    /*tp_name*/
-    sizeof(Channel),                    /*tp_basicsize*/
-    0,                                  /*tp_itemsize*/
-    (destructor)pygrpc_channel_dealloc, /*tp_dealloc*/
-    0,                                  /*tp_print*/
-    0,                                  /*tp_getattr*/
-    0,                                  /*tp_setattr*/
-    0,                                  /*tp_compare*/
-    0,                                  /*tp_repr*/
-    0,                                  /*tp_as_number*/
-    0,                                  /*tp_as_sequence*/
-    0,                                  /*tp_as_mapping*/
-    0,                                  /*tp_hash */
-    0,                                  /*tp_call*/
-    0,                                  /*tp_str*/
-    0,                                  /*tp_getattro*/
-    0,                                  /*tp_setattro*/
-    0,                                  /*tp_as_buffer*/
-    Py_TPFLAGS_DEFAULT,                 /*tp_flags*/
-    "Wrapping of grpc_channel.",        /* tp_doc */
-    0,                                  /* tp_traverse */
-    0,                                  /* tp_clear */
-    0,                                  /* tp_richcompare */
-    0,                                  /* tp_weaklistoffset */
-    0,                                  /* tp_iter */
-    0,                                  /* tp_iternext */
-    0,                                  /* tp_methods */
-    0,                                  /* tp_members */
-    0,                                  /* tp_getset */
-    0,                                  /* tp_base */
-    0,                                  /* tp_dict */
-    0,                                  /* tp_descr_get */
-    0,                                  /* tp_descr_set */
-    0,                                  /* tp_dictoffset */
-    (initproc)pygrpc_channel_init,      /* tp_init */
-    0,                                  /* tp_alloc */
-    PyType_GenericNew,                  /* tp_new */
-};
-
-int pygrpc_add_channel(PyObject *module) {
-  if (PyType_Ready(&pygrpc_ChannelType) < 0) {
-    return -1;
-  }
-  if (PyModule_AddObject(module, "Channel", (PyObject *)&pygrpc_ChannelType) ==
-      -1) {
-    return -1;
-  }
-  return 0;
-}
diff --git a/src/python/src/grpc/_adapter/_channel.h b/src/python/src/grpc/_adapter/_channel.h
deleted file mode 100644
index 6589493..0000000
--- a/src/python/src/grpc/_adapter/_channel.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- *
- * Copyright 2015, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#ifndef _ADAPTER__CHANNEL_H_
-#define _ADAPTER__CHANNEL_H_
-
-#include <Python.h>
-#include <grpc/grpc.h>
-
-typedef struct {
-  PyObject_HEAD
-  grpc_channel *c_channel;
-} Channel;
-
-extern PyTypeObject pygrpc_ChannelType;
-
-int pygrpc_add_channel(PyObject *module);
-
-#endif /* _ADAPTER__CHANNEL_H_ */
diff --git a/src/python/src/grpc/_adapter/_client_credentials.c b/src/python/src/grpc/_adapter/_client_credentials.c
deleted file mode 100644
index e8ccff8..0000000
--- a/src/python/src/grpc/_adapter/_client_credentials.c
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- *
- * Copyright 2015, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#include "grpc/_adapter/_client_credentials.h"
-
-#include <Python.h>
-#include <grpc/grpc_security.h>
-#include <grpc/support/alloc.h>
-
-static int pygrpc_client_credentials_init(ClientCredentials *self,
-                                          PyObject *args, PyObject *kwds) {
-  char *root_certificates;
-  grpc_ssl_pem_key_cert_pair key_certificate_pair;
-  static char *kwlist[] = {"root_certificates", "private_key",
-                           "certificate_chain", NULL};
-
-  if (!PyArg_ParseTupleAndKeywords(args, kwds, "zzz:ClientCredentials", kwlist,
-                                   &root_certificates,
-                                   &key_certificate_pair.private_key,
-                                   &key_certificate_pair.cert_chain)) {
-    return -1;
-  }
-
-  if (key_certificate_pair.private_key != NULL && key_certificate_pair.cert_chain != NULL) {
-    self->c_client_credentials =
-        grpc_ssl_credentials_create(root_certificates, &key_certificate_pair);
-  } else {
-    self->c_client_credentials =
-        grpc_ssl_credentials_create(root_certificates, NULL);
-  }
-  return 0;
-}
-
-static void pygrpc_client_credentials_dealloc(ClientCredentials *self) {
-  if (self->c_client_credentials != NULL) {
-    grpc_credentials_release(self->c_client_credentials);
-  }
-  self->ob_type->tp_free((PyObject *)self);
-}
-
-PyTypeObject pygrpc_ClientCredentialsType = {
-    PyVarObject_HEAD_INIT(NULL, 0)
-    "_grpc.ClientCredencials",                      /*tp_name*/
-    sizeof(ClientCredentials),                      /*tp_basicsize*/
-    0,                                              /*tp_itemsize*/
-    (destructor)pygrpc_client_credentials_dealloc,  /*tp_dealloc*/
-    0,                                              /*tp_print*/
-    0,                                              /*tp_getattr*/
-    0,                                              /*tp_setattr*/
-    0,                                              /*tp_compare*/
-    0,                                              /*tp_repr*/
-    0,                                              /*tp_as_number*/
-    0,                                              /*tp_as_sequence*/
-    0,                                              /*tp_as_mapping*/
-    0,                                              /*tp_hash */
-    0,                                              /*tp_call*/
-    0,                                              /*tp_str*/
-    0,                                              /*tp_getattro*/
-    0,                                              /*tp_setattro*/
-    0,                                              /*tp_as_buffer*/
-    Py_TPFLAGS_DEFAULT,                             /*tp_flags*/
-    "Wrapping of grpc_credentials.",                /* tp_doc */
-    0,                                              /* tp_traverse */
-    0,                                              /* tp_clear */
-    0,                                              /* tp_richcompare */
-    0,                                              /* tp_weaklistoffset */
-    0,                                              /* tp_iter */
-    0,                                              /* tp_iternext */
-    0,                                              /* tp_methods */
-    0,                                              /* tp_members */
-    0,                                              /* tp_getset */
-    0,                                              /* tp_base */
-    0,                                              /* tp_dict */
-    0,                                              /* tp_descr_get */
-    0,                                              /* tp_descr_set */
-    0,                                              /* tp_dictoffset */
-    (initproc)pygrpc_client_credentials_init,       /* tp_init */
-    0,                                              /* tp_alloc */
-    PyType_GenericNew,                              /* tp_new */
-};
-
-int pygrpc_add_client_credentials(PyObject *module) {
-  if (PyType_Ready(&pygrpc_ClientCredentialsType) < 0) {
-    return -1;
-  }
-  if (PyModule_AddObject(module, "ClientCredentials",
-                         (PyObject *)&pygrpc_ClientCredentialsType) == -1) {
-    return -1;
-  }
-  return 0;
-}
diff --git a/src/python/src/grpc/_adapter/_client_credentials.h b/src/python/src/grpc/_adapter/_client_credentials.h
deleted file mode 100644
index fe04016..0000000
--- a/src/python/src/grpc/_adapter/_client_credentials.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- *
- * Copyright 2015, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#ifndef _ADAPTER__CLIENT_CREDENTIALS_H_
-#define _ADAPTER__CLIENT_CREDENTIALS_H_
-
-#include <Python.h>
-#include <grpc/grpc_security.h>
-
-typedef struct {
-  PyObject_HEAD
-  grpc_credentials *c_client_credentials;
-} ClientCredentials;
-
-extern PyTypeObject pygrpc_ClientCredentialsType;
-
-int pygrpc_add_client_credentials(PyObject *module);
-
-#endif /* _ADAPTER__CLIENT_CREDENTIALS_H_ */
diff --git a/src/python/src/grpc/_adapter/_completion_queue.c b/src/python/src/grpc/_adapter/_completion_queue.c
deleted file mode 100644
index 97828e6..0000000
--- a/src/python/src/grpc/_adapter/_completion_queue.c
+++ /dev/null
@@ -1,653 +0,0 @@
-/*
- *
- * Copyright 2015, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#include "grpc/_adapter/_completion_queue.h"
-
-#include <Python.h>
-#include <grpc/grpc.h>
-#include <grpc/support/alloc.h>
-
-#include "grpc/_adapter/_call.h"
-#include "grpc/_adapter/_tag.h"
-
-static PyObject *status_class;
-static PyObject *service_acceptance_class;
-static PyObject *event_class;
-
-static PyObject *ok_status_code;
-static PyObject *cancelled_status_code;
-static PyObject *unknown_status_code;
-static PyObject *invalid_argument_status_code;
-static PyObject *expired_status_code;
-static PyObject *not_found_status_code;
-static PyObject *already_exists_status_code;
-static PyObject *permission_denied_status_code;
-static PyObject *unauthenticated_status_code;
-static PyObject *resource_exhausted_status_code;
-static PyObject *failed_precondition_status_code;
-static PyObject *aborted_status_code;
-static PyObject *out_of_range_status_code;
-static PyObject *unimplemented_status_code;
-static PyObject *internal_error_status_code;
-static PyObject *unavailable_status_code;
-static PyObject *data_loss_status_code;
-
-static PyObject *stop_event_kind;
-static PyObject *write_event_kind;
-static PyObject *complete_event_kind;
-static PyObject *service_event_kind;
-static PyObject *read_event_kind;
-static PyObject *metadata_event_kind;
-static PyObject *finish_event_kind;
-
-static PyObject *pygrpc_as_py_time(gpr_timespec *timespec) {
-  return PyFloat_FromDouble(
-                       timespec->tv_sec + ((double)timespec->tv_nsec) / 1.0E9);
-}
-
-static PyObject *pygrpc_status_code(grpc_status_code c_status_code) {
-  switch (c_status_code) {
-    case GRPC_STATUS_OK:
-      return ok_status_code;
-    case GRPC_STATUS_CANCELLED:
-      return cancelled_status_code;
-    case GRPC_STATUS_UNKNOWN:
-      return unknown_status_code;
-    case GRPC_STATUS_INVALID_ARGUMENT:
-      return invalid_argument_status_code;
-    case GRPC_STATUS_DEADLINE_EXCEEDED:
-      return expired_status_code;
-    case GRPC_STATUS_NOT_FOUND:
-      return not_found_status_code;
-    case GRPC_STATUS_ALREADY_EXISTS:
-      return already_exists_status_code;
-    case GRPC_STATUS_PERMISSION_DENIED:
-      return permission_denied_status_code;
-    case GRPC_STATUS_UNAUTHENTICATED:
-      return unauthenticated_status_code;
-    case GRPC_STATUS_RESOURCE_EXHAUSTED:
-      return resource_exhausted_status_code;
-    case GRPC_STATUS_FAILED_PRECONDITION:
-      return failed_precondition_status_code;
-    case GRPC_STATUS_ABORTED:
-      return aborted_status_code;
-    case GRPC_STATUS_OUT_OF_RANGE:
-      return out_of_range_status_code;
-    case GRPC_STATUS_UNIMPLEMENTED:
-      return unimplemented_status_code;
-    case GRPC_STATUS_INTERNAL:
-      return internal_error_status_code;
-    case GRPC_STATUS_UNAVAILABLE:
-      return unavailable_status_code;
-    case GRPC_STATUS_DATA_LOSS:
-      return data_loss_status_code;
-    default:
-      return NULL;
-  }
-}
-
-static PyObject *pygrpc_metadata_collection_get(
-    grpc_metadata *metadata_elements, size_t count) {
-  PyObject *metadata = PyList_New(count);
-  size_t i;
-  for (i = 0; i < count; ++i) {
-    grpc_metadata elem = metadata_elements[i];
-    PyObject *key = PyString_FromString(elem.key);
-    PyObject *value = PyString_FromStringAndSize(elem.value, elem.value_length);
-    PyObject* kvp = PyTuple_Pack(2, key, value);
-    /* n.b. PyList_SetItem *steals* a reference to the set element. */
-    PyList_SetItem(metadata, i, kvp);
-    Py_DECREF(key);
-    Py_DECREF(value);
-  }
-  return metadata;
-}
-
-static PyObject *pygrpc_stop_event_args(grpc_event *c_event) {
-  return PyTuple_Pack(8, stop_event_kind, Py_None, Py_None, Py_None,
-                      Py_None, Py_None, Py_None, Py_None);
-}
-
-static PyObject *pygrpc_write_event_args(grpc_event *c_event) {
-  pygrpc_tag *tag = (pygrpc_tag *)(c_event->tag);
-  PyObject *user_tag = tag->user_tag;
-  PyObject *write_accepted = Py_True;
-  return PyTuple_Pack(8, write_event_kind, user_tag,
-                      write_accepted, Py_None, Py_None, Py_None, Py_None,
-                      Py_None);
-}
-
-static PyObject *pygrpc_complete_event_args(grpc_event *c_event) {
-  pygrpc_tag *tag = (pygrpc_tag *)(c_event->tag);
-  PyObject *user_tag = tag->user_tag;
-  PyObject *complete_accepted = Py_True;
-  return PyTuple_Pack(8, complete_event_kind, user_tag,
-                      Py_None, complete_accepted, Py_None, Py_None, Py_None,
-                      Py_None);
-}
-
-static PyObject *pygrpc_service_event_args(grpc_event *c_event) {
-  pygrpc_tag *tag = (pygrpc_tag *)(c_event->tag);
-  PyObject *user_tag = tag->user_tag;
-  if (tag->call->call_details.method == NULL) {
-    return PyTuple_Pack(
-        8, service_event_kind, user_tag, Py_None, Py_None, Py_None, Py_None,
-        Py_None, Py_None);
-  } else {
-    PyObject *method = NULL;
-    PyObject *host = NULL;
-    PyObject *service_deadline = NULL;
-    PyObject *service_acceptance = NULL;
-    PyObject *metadata = NULL;
-    PyObject *event_args = NULL;
-
-    method = PyBytes_FromString(tag->call->call_details.method);
-    if (method == NULL) {
-      goto error;
-    }
-    host = PyBytes_FromString(tag->call->call_details.host);
-    if (host == NULL) {
-      goto error;
-    }
-    service_deadline =
-        pygrpc_as_py_time(&tag->call->call_details.deadline);
-    if (service_deadline == NULL) {
-      goto error;
-    }
-
-    service_acceptance =
-        PyObject_CallFunctionObjArgs(service_acceptance_class, tag->call,
-                                     method, host, service_deadline, NULL);
-    if (service_acceptance == NULL) {
-      goto error;
-    }
-
-    metadata = pygrpc_metadata_collection_get(
-        tag->call->recv_metadata.metadata,
-        tag->call->recv_metadata.count);
-    event_args = PyTuple_Pack(8, service_event_kind,
-                              user_tag, Py_None, Py_None,
-                              service_acceptance, Py_None, Py_None,
-                              metadata);
-
-    Py_DECREF(service_acceptance);
-    Py_DECREF(metadata);
-error:
-    Py_XDECREF(method);
-    Py_XDECREF(host);
-    Py_XDECREF(service_deadline);
-
-    return event_args;
-  }
-}
-
-static PyObject *pygrpc_read_event_args(grpc_event *c_event) {
-  pygrpc_tag *tag = (pygrpc_tag *)(c_event->tag);
-  PyObject *user_tag = tag->user_tag;
-  if (tag->call->recv_message == NULL) {
-    return PyTuple_Pack(8, read_event_kind, user_tag,
-                        Py_None, Py_None, Py_None, Py_None, Py_None, Py_None);
-  } else {
-    size_t length;
-    size_t offset;
-    grpc_byte_buffer_reader *reader;
-    gpr_slice slice;
-    char *c_bytes;
-    PyObject *bytes;
-    PyObject *event_args;
-
-    length = grpc_byte_buffer_length(tag->call->recv_message);
-    reader = grpc_byte_buffer_reader_create(tag->call->recv_message);
-    c_bytes = gpr_malloc(length);
-    offset = 0;
-    while (grpc_byte_buffer_reader_next(reader, &slice)) {
-      memcpy(c_bytes + offset, GPR_SLICE_START_PTR(slice),
-             GPR_SLICE_LENGTH(slice));
-      offset += GPR_SLICE_LENGTH(slice);
-    }
-    grpc_byte_buffer_reader_destroy(reader);
-    bytes = PyBytes_FromStringAndSize(c_bytes, length);
-    gpr_free(c_bytes);
-    if (bytes == NULL) {
-      return NULL;
-    }
-    event_args = PyTuple_Pack(8, read_event_kind, user_tag,
-                              Py_None, Py_None, Py_None, bytes, Py_None,
-                              Py_None);
-    Py_DECREF(bytes);
-    return event_args;
-  }
-}
-
-static PyObject *pygrpc_metadata_event_args(grpc_event *c_event) {
-  pygrpc_tag *tag = (pygrpc_tag *)(c_event->tag);
-  PyObject *user_tag = tag->user_tag;
-  PyObject *metadata = pygrpc_metadata_collection_get(
-      tag->call->recv_metadata.metadata,
-      tag->call->recv_metadata.count);
-  PyObject* result = PyTuple_Pack(
-      8, metadata_event_kind, user_tag, Py_None, Py_None,
-      Py_None, Py_None, Py_None, metadata);
-  Py_DECREF(metadata);
-  return result;
-}
-
-static PyObject *pygrpc_finished_server_event_args(grpc_event *c_event) {
-  PyObject *code;
-  PyObject *details;
-  PyObject *status;
-  PyObject *event_args;
-  pygrpc_tag *tag = (pygrpc_tag *)(c_event->tag);
-  PyObject *user_tag = tag->user_tag;
-
-  code = pygrpc_status_code(tag->call->cancelled ? GRPC_STATUS_CANCELLED : GRPC_STATUS_OK);
-  if (code == NULL) {
-    PyErr_SetString(PyExc_RuntimeError, "Unrecognized status code!");
-    return NULL;
-  }
-  details = PyBytes_FromString("");
-  if (details == NULL) {
-    return NULL;
-  }
-  status = PyObject_CallFunctionObjArgs(status_class, code, details, NULL);
-  Py_DECREF(details);
-  if (status == NULL) {
-    return NULL;
-  }
-  event_args = PyTuple_Pack(8, finish_event_kind, user_tag,
-                            Py_None, Py_None, Py_None, Py_None, status,
-                            Py_None);
-  Py_DECREF(status);
-  return event_args;
-}
-
-static PyObject *pygrpc_finished_client_event_args(grpc_event *c_event) {
-  PyObject *code;
-  PyObject *details;
-  PyObject *status;
-  PyObject *event_args;
-  PyObject *metadata;
-  pygrpc_tag *tag = (pygrpc_tag *)(c_event->tag);
-  PyObject *user_tag = tag->user_tag;
-
-  code = pygrpc_status_code(tag->call->status);
-  if (code == NULL) {
-    PyErr_SetString(PyExc_RuntimeError, "Unrecognized status code!");
-    return NULL;
-  }
-  if (tag->call->status_details == NULL) {
-    details = PyBytes_FromString("");
-  } else {
-    details = PyBytes_FromString(tag->call->status_details);
-  }
-  if (details == NULL) {
-    return NULL;
-  }
-  status = PyObject_CallFunctionObjArgs(status_class, code, details, NULL);
-  Py_DECREF(details);
-  if (status == NULL) {
-    return NULL;
-  }
-  metadata = pygrpc_metadata_collection_get(
-      tag->call->recv_trailing_metadata.metadata,
-      tag->call->recv_trailing_metadata.count);
-  event_args = PyTuple_Pack(8, finish_event_kind, user_tag,
-                            Py_None, Py_None, Py_None, Py_None, status,
-                            metadata);
-  Py_DECREF(status);
-  Py_DECREF(metadata);
-  return event_args;
-}
-
-static int pygrpc_completion_queue_init(CompletionQueue *self, PyObject *args,
-                                        PyObject *kwds) {
-  static char *kwlist[] = {NULL};
-  if (!PyArg_ParseTupleAndKeywords(args, kwds, ":CompletionQueue", kwlist)) {
-    return -1;
-  }
-  self->c_completion_queue = grpc_completion_queue_create();
-  return 0;
-}
-
-static void pygrpc_completion_queue_dealloc(CompletionQueue *self) {
-  grpc_completion_queue_destroy(self->c_completion_queue);
-  self->ob_type->tp_free((PyObject *)self);
-}
-
-static PyObject *pygrpc_completion_queue_get(CompletionQueue *self,
-                                             PyObject *args) {
-  PyObject *deadline;
-  double double_deadline;
-  gpr_timespec deadline_timespec;
-  grpc_event c_event;
-
-  PyObject *event_args;
-  PyObject *event;
-
-  pygrpc_tag *tag;
-
-  if (!(PyArg_ParseTuple(args, "O:get", &deadline))) {
-    return NULL;
-  }
-
-  if (deadline == Py_None) {
-    deadline_timespec = gpr_inf_future;
-  } else {
-    double_deadline = PyFloat_AsDouble(deadline);
-    if (PyErr_Occurred()) {
-      return NULL;
-    }
-    deadline_timespec = gpr_time_from_nanos((long)(double_deadline * 1.0E9));
-  }
-
-  /* TODO(nathaniel): Suppress clang-format in this block and remove the
-     unnecessary and unPythonic semicolons trailing the _ALLOW_THREADS macros.
-     (Right now clang-format only understands //-demarcated suppressions.) */
-  Py_BEGIN_ALLOW_THREADS;
-  c_event =
-      grpc_completion_queue_next(self->c_completion_queue, deadline_timespec);
-  Py_END_ALLOW_THREADS;
-
-  tag = (pygrpc_tag *)c_event.tag;
-
-  switch (c_event.type) {
-    case GRPC_QUEUE_TIMEOUT:
-      Py_RETURN_NONE;
-      break;
-    case GRPC_QUEUE_SHUTDOWN:
-      event_args = pygrpc_stop_event_args(&c_event);
-      break;
-    case GRPC_OP_COMPLETE: {
-      if (!tag) {
-        PyErr_SetString(PyExc_Exception, "Unrecognized event type!");
-        return NULL;
-      }
-      switch (tag->type) {
-        case PYGRPC_INITIAL_METADATA:
-          if (tag) {
-            pygrpc_tag_destroy(tag);
-          }
-          return pygrpc_completion_queue_get(self, args);
-        case PYGRPC_WRITE_ACCEPTED:
-          event_args = pygrpc_write_event_args(&c_event);
-          break;
-        case PYGRPC_FINISH_ACCEPTED:
-          event_args = pygrpc_complete_event_args(&c_event);
-          break;
-        case PYGRPC_SERVER_RPC_NEW:
-          event_args = pygrpc_service_event_args(&c_event);
-          break;
-        case PYGRPC_READ:
-          event_args = pygrpc_read_event_args(&c_event);
-          break;
-        case PYGRPC_CLIENT_METADATA_READ:
-          event_args = pygrpc_metadata_event_args(&c_event);
-          break;
-        case PYGRPC_FINISHED_CLIENT:
-          event_args = pygrpc_finished_client_event_args(&c_event);
-          break;
-        case PYGRPC_FINISHED_SERVER:
-          event_args = pygrpc_finished_server_event_args(&c_event);
-          break;
-        default:
-          PyErr_SetString(PyExc_Exception, "Unrecognized op event type!");
-          return NULL;
-      }
-      break;
-    }
-    default:
-      PyErr_SetString(PyExc_Exception, "Unrecognized event type!");
-      return NULL;
-  }
-
-  if (event_args == NULL) {
-    return NULL;
-  }
-
-  event = PyObject_CallObject(event_class, event_args);
-
-  Py_DECREF(event_args);
-  if (tag) {
-    pygrpc_tag_destroy(tag);
-  }
-
-  return event;
-}
-
-static PyObject *pygrpc_completion_queue_stop(CompletionQueue *self) {
-  grpc_completion_queue_shutdown(self->c_completion_queue);
-
-  Py_RETURN_NONE;
-}
-
-static PyMethodDef methods[] = {
-    {"get", (PyCFunction)pygrpc_completion_queue_get, METH_VARARGS,
-     "Get the next event."},
-    {"stop", (PyCFunction)pygrpc_completion_queue_stop, METH_NOARGS,
-     "Stop this completion queue."},
-    {NULL}};
-
-PyTypeObject pygrpc_CompletionQueueType = {
-    PyVarObject_HEAD_INIT(NULL, 0)
-    "_gprc.CompletionQueue",                     /*tp_name*/
-    sizeof(CompletionQueue),                     /*tp_basicsize*/
-    0,                                           /*tp_itemsize*/
-    (destructor)pygrpc_completion_queue_dealloc, /*tp_dealloc*/
-    0,                                           /*tp_print*/
-    0,                                           /*tp_getattr*/
-    0,                                           /*tp_setattr*/
-    0,                                           /*tp_compare*/
-    0,                                           /*tp_repr*/
-    0,                                           /*tp_as_number*/
-    0,                                           /*tp_as_sequence*/
-    0,                                           /*tp_as_mapping*/
-    0,                                           /*tp_hash */
-    0,                                           /*tp_call*/
-    0,                                           /*tp_str*/
-    0,                                           /*tp_getattro*/
-    0,                                           /*tp_setattro*/
-    0,                                           /*tp_as_buffer*/
-    Py_TPFLAGS_DEFAULT,                          /*tp_flags*/
-    "Wrapping of grpc_completion_queue.",        /* tp_doc */
-    0,                                           /* tp_traverse */
-    0,                                           /* tp_clear */
-    0,                                           /* tp_richcompare */
-    0,                                           /* tp_weaklistoffset */
-    0,                                           /* tp_iter */
-    0,                                           /* tp_iternext */
-    methods,                                     /* tp_methods */
-    0,                                           /* tp_members */
-    0,                                           /* tp_getset */
-    0,                                           /* tp_base */
-    0,                                           /* tp_dict */
-    0,                                           /* tp_descr_get */
-    0,                                           /* tp_descr_set */
-    0,                                           /* tp_dictoffset */
-    (initproc)pygrpc_completion_queue_init,      /* tp_init */
-    0,                                           /* tp_alloc */
-    PyType_GenericNew,                           /* tp_new */
-};
-
-static int pygrpc_get_status_codes(PyObject *datatypes_module) {
-  PyObject *code_class = PyObject_GetAttrString(datatypes_module, "Code");
-  if (code_class == NULL) {
-    return -1;
-  }
-  ok_status_code = PyObject_GetAttrString(code_class, "OK");
-  if (ok_status_code == NULL) {
-    return -1;
-  }
-  cancelled_status_code = PyObject_GetAttrString(code_class, "CANCELLED");
-  if (cancelled_status_code == NULL) {
-    return -1;
-  }
-  unknown_status_code = PyObject_GetAttrString(code_class, "UNKNOWN");
-  if (unknown_status_code == NULL) {
-    return -1;
-  }
-  invalid_argument_status_code =
-      PyObject_GetAttrString(code_class, "INVALID_ARGUMENT");
-  if (invalid_argument_status_code == NULL) {
-    return -1;
-  }
-  expired_status_code = PyObject_GetAttrString(code_class, "EXPIRED");
-  if (expired_status_code == NULL) {
-    return -1;
-  }
-  not_found_status_code = PyObject_GetAttrString(code_class, "NOT_FOUND");
-  if (not_found_status_code == NULL) {
-    return -1;
-  }
-  already_exists_status_code =
-      PyObject_GetAttrString(code_class, "ALREADY_EXISTS");
-  if (already_exists_status_code == NULL) {
-    return -1;
-  }
-  permission_denied_status_code =
-      PyObject_GetAttrString(code_class, "PERMISSION_DENIED");
-  if (permission_denied_status_code == NULL) {
-    return -1;
-  }
-  unauthenticated_status_code =
-      PyObject_GetAttrString(code_class, "UNAUTHENTICATED");
-  if (unauthenticated_status_code == NULL) {
-    return -1;
-  }
-  resource_exhausted_status_code =
-      PyObject_GetAttrString(code_class, "RESOURCE_EXHAUSTED");
-  if (resource_exhausted_status_code == NULL) {
-    return -1;
-  }
-  failed_precondition_status_code =
-      PyObject_GetAttrString(code_class, "FAILED_PRECONDITION");
-  if (failed_precondition_status_code == NULL) {
-    return -1;
-  }
-  aborted_status_code = PyObject_GetAttrString(code_class, "ABORTED");
-  if (aborted_status_code == NULL) {
-    return -1;
-  }
-  out_of_range_status_code = PyObject_GetAttrString(code_class, "OUT_OF_RANGE");
-  if (out_of_range_status_code == NULL) {
-    return -1;
-  }
-  unimplemented_status_code =
-      PyObject_GetAttrString(code_class, "UNIMPLEMENTED");
-  if (unimplemented_status_code == NULL) {
-    return -1;
-  }
-  internal_error_status_code =
-      PyObject_GetAttrString(code_class, "INTERNAL_ERROR");
-  if (internal_error_status_code == NULL) {
-    return -1;
-  }
-  unavailable_status_code = PyObject_GetAttrString(code_class, "UNAVAILABLE");
-  if (unavailable_status_code == NULL) {
-    return -1;
-  }
-  data_loss_status_code = PyObject_GetAttrString(code_class, "DATA_LOSS");
-  if (data_loss_status_code == NULL) {
-    return -1;
-  }
-  Py_DECREF(code_class);
-  return 0;
-}
-
-static int pygrpc_get_event_kinds(PyObject *event_class) {
-  PyObject *kind_class = PyObject_GetAttrString(event_class, "Kind");
-  if (kind_class == NULL) {
-    return -1;
-  }
-  stop_event_kind = PyObject_GetAttrString(kind_class, "STOP");
-  if (stop_event_kind == NULL) {
-    return -1;
-  }
-  write_event_kind = PyObject_GetAttrString(kind_class, "WRITE_ACCEPTED");
-  if (write_event_kind == NULL) {
-    return -1;
-  }
-  complete_event_kind = PyObject_GetAttrString(kind_class, "COMPLETE_ACCEPTED");
-  if (complete_event_kind == NULL) {
-    return -1;
-  }
-  service_event_kind = PyObject_GetAttrString(kind_class, "SERVICE_ACCEPTED");
-  if (service_event_kind == NULL) {
-    return -1;
-  }
-  read_event_kind = PyObject_GetAttrString(kind_class, "READ_ACCEPTED");
-  if (read_event_kind == NULL) {
-    return -1;
-  }
-  metadata_event_kind = PyObject_GetAttrString(kind_class, "METADATA_ACCEPTED");
-  if (metadata_event_kind == NULL) {
-    return -1;
-  }
-  finish_event_kind = PyObject_GetAttrString(kind_class, "FINISH");
-  if (finish_event_kind == NULL) {
-    return -1;
-  }
-  Py_DECREF(kind_class);
-  return 0;
-}
-
-int pygrpc_add_completion_queue(PyObject *module) {
-  char *datatypes_module_path = "grpc._adapter._datatypes";
-  PyObject *datatypes_module = PyImport_ImportModule(datatypes_module_path);
-  if (datatypes_module == NULL) {
-    return -1;
-  }
-  status_class = PyObject_GetAttrString(datatypes_module, "Status");
-  service_acceptance_class =
-      PyObject_GetAttrString(datatypes_module, "ServiceAcceptance");
-  event_class = PyObject_GetAttrString(datatypes_module, "Event");
-  if (status_class == NULL || service_acceptance_class == NULL ||
-      event_class == NULL) {
-    return -1;
-  }
-  if (pygrpc_get_status_codes(datatypes_module) == -1) {
-    return -1;
-  }
-  if (pygrpc_get_event_kinds(event_class) == -1) {
-    return -1;
-  }
-  Py_DECREF(datatypes_module);
-
-  if (PyType_Ready(&pygrpc_CompletionQueueType) < 0) {
-    return -1;
-  }
-  if (PyModule_AddObject(module, "CompletionQueue",
-                         (PyObject *)&pygrpc_CompletionQueueType) == -1) {
-    return -1;
-  }
-  return 0;
-}
diff --git a/src/python/src/grpc/_adapter/_completion_queue.h b/src/python/src/grpc/_adapter/_completion_queue.h
deleted file mode 100644
index 516694d..0000000
--- a/src/python/src/grpc/_adapter/_completion_queue.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- *
- * Copyright 2015, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#ifndef _ADAPTER__COMPLETION_QUEUE_H_
-#define _ADAPTER__COMPLETION_QUEUE_H_
-
-#include <Python.h>
-#include <grpc/grpc.h>
-
-typedef struct {
-  PyObject_HEAD
-  grpc_completion_queue *c_completion_queue;
-} CompletionQueue;
-
-extern PyTypeObject pygrpc_CompletionQueueType;
-
-int pygrpc_add_completion_queue(PyObject *module);
-
-#endif /* _ADAPTER__COMPLETION_QUEUE_H_ */
diff --git a/src/python/src/grpc/_adapter/_datatypes.py b/src/python/src/grpc/_adapter/_datatypes.py
deleted file mode 100644
index 3b22784..0000000
--- a/src/python/src/grpc/_adapter/_datatypes.py
+++ /dev/null
@@ -1,86 +0,0 @@
-# Copyright 2015, Google Inc.
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-#
-#     * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-#     * Redistributions in binary form must reproduce the above
-# copyright notice, this list of conditions and the following disclaimer
-# in the documentation and/or other materials provided with the
-# distribution.
-#     * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-"""Datatypes passed between Python and C code."""
-
-import collections
-import enum
-
-
-@enum.unique
-class Code(enum.IntEnum):
-  """One Platform error codes (see status.h and codes.proto)."""
-
-  OK = 0
-  CANCELLED = 1
-  UNKNOWN = 2
-  INVALID_ARGUMENT = 3
-  EXPIRED = 4
-  NOT_FOUND = 5
-  ALREADY_EXISTS = 6
-  PERMISSION_DENIED = 7
-  UNAUTHENTICATED = 16
-  RESOURCE_EXHAUSTED = 8
-  FAILED_PRECONDITION = 9
-  ABORTED = 10
-  OUT_OF_RANGE = 11
-  UNIMPLEMENTED = 12
-  INTERNAL_ERROR = 13
-  UNAVAILABLE = 14
-  DATA_LOSS = 15
-
-
-class Status(collections.namedtuple('Status', ['code', 'details'])):
-  """Describes an RPC's overall status."""
-
-
-class ServiceAcceptance(
-    collections.namedtuple(
-        'ServiceAcceptance', ['call', 'method', 'host', 'deadline'])):
-  """Describes an RPC on the service side at the start of service."""
-
-
-class Event(
-    collections.namedtuple(
-        'Event',
-        ['kind', 'tag', 'write_accepted', 'complete_accepted',
-         'service_acceptance', 'bytes', 'status', 'metadata'])):
-  """Describes an event emitted from a completion queue."""
-
-  @enum.unique
-  class Kind(enum.Enum):
-    """Describes the kind of an event."""
-
-    STOP = object()
-    WRITE_ACCEPTED = object()
-    COMPLETE_ACCEPTED = object()
-    SERVICE_ACCEPTED = object()
-    READ_ACCEPTED = object()
-    METADATA_ACCEPTED = object()
-    FINISH = object()
diff --git a/src/python/src/grpc/_adapter/_error.c b/src/python/src/grpc/_adapter/_error.c
deleted file mode 100644
index a8a1dbc..0000000
--- a/src/python/src/grpc/_adapter/_error.c
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- *
- * Copyright 2015, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#include "grpc/_adapter/_error.h"
-
-#include <Python.h>
-#include <grpc/grpc.h>
-
-const PyObject *pygrpc_translate_call_error(grpc_call_error call_error) {
-  switch (call_error) {
-    case GRPC_CALL_OK:
-      Py_RETURN_NONE;
-    case GRPC_CALL_ERROR:
-      PyErr_SetString(PyExc_Exception, "Defect: unknown defect!");
-      return NULL;
-    case GRPC_CALL_ERROR_NOT_ON_SERVER:
-      PyErr_SetString(PyExc_Exception,
-                      "Defect: client-only method called on server!");
-      return NULL;
-    case GRPC_CALL_ERROR_NOT_ON_CLIENT:
-      PyErr_SetString(PyExc_Exception,
-                      "Defect: server-only method called on client!");
-      return NULL;
-    case GRPC_CALL_ERROR_ALREADY_ACCEPTED:
-      PyErr_SetString(PyExc_Exception,
-                      "Defect: attempted to accept already-accepted call!");
-      return NULL;
-    case GRPC_CALL_ERROR_ALREADY_INVOKED:
-      PyErr_SetString(PyExc_Exception,
-                      "Defect: attempted to invoke already-invoked call!");
-      return NULL;
-    case GRPC_CALL_ERROR_NOT_INVOKED:
-      PyErr_SetString(PyExc_Exception, "Defect: Call not yet invoked!");
-      return NULL;
-    case GRPC_CALL_ERROR_ALREADY_FINISHED:
-      PyErr_SetString(PyExc_Exception, "Defect: Call already finished!");
-      return NULL;
-    case GRPC_CALL_ERROR_TOO_MANY_OPERATIONS:
-      PyErr_SetString(PyExc_Exception,
-                      "Defect: Attempted extra read or extra write on call!");
-      return NULL;
-    case GRPC_CALL_ERROR_INVALID_FLAGS:
-      PyErr_SetString(PyExc_Exception, "Defect: invalid flags!");
-      return NULL;
-    default:
-      PyErr_SetString(PyExc_Exception, "Defect: Unknown call error!");
-      return NULL;
-  }
-}
diff --git a/src/python/src/grpc/_adapter/_intermediary_low.py b/src/python/src/grpc/_adapter/_intermediary_low.py
new file mode 100644
index 0000000..a6e325c
--- /dev/null
+++ b/src/python/src/grpc/_adapter/_intermediary_low.py
@@ -0,0 +1,258 @@
+# Copyright 2015, Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"""Temporary old _low-like layer.
+
+Eases refactoring burden while we overhaul the Python framework.
+
+Plan:
+    The layers used to look like:
+        ...                # outside _adapter
+        fore.py + rear.py  # visible outside _adapter
+        _low
+        _c
+    The layers currently look like:
+        ...                # outside _adapter
+        fore.py + rear.py  # visible outside _adapter
+        _low_intermediary  # adapter for new '_low' to old '_low'
+        _low               # new '_low'
+        _c                 # new '_c'
+    We will later remove _low_intermediary after refactoring of fore.py and
+    rear.py according to the ticket system refactoring and get:
+        ...                # outside _adapter, refactored
+        fore.py + rear.py  # visible outside _adapter, refactored
+        _low               # new '_low'
+        _c                 # new '_c'
+"""
+
+import collections
+import enum
+
+from grpc._adapter import _low
+from grpc._adapter import _types
+
+_IGNORE_ME_TAG = object()
+Code = _types.StatusCode
+
+
+class Status(collections.namedtuple('Status', ['code', 'details'])):
+  """Describes an RPC's overall status."""
+
+
+class ServiceAcceptance(
+    collections.namedtuple(
+        'ServiceAcceptance', ['call', 'method', 'host', 'deadline'])):
+  """Describes an RPC on the service side at the start of service."""
+
+
+class Event(
+    collections.namedtuple(
+        'Event',
+        ['kind', 'tag', 'write_accepted', 'complete_accepted',
+         'service_acceptance', 'bytes', 'status', 'metadata'])):
+  """Describes an event emitted from a completion queue."""
+
+  @enum.unique
+  class Kind(enum.Enum):
+    """Describes the kind of an event."""
+
+    STOP = object()
+    WRITE_ACCEPTED = object()
+    COMPLETE_ACCEPTED = object()
+    SERVICE_ACCEPTED = object()
+    READ_ACCEPTED = object()
+    METADATA_ACCEPTED = object()
+    FINISH = object()
+
+
+class _TagAdapter(collections.namedtuple('_TagAdapter', [
+      'user_tag',
+      'kind'
+  ])):
+  pass
+
+
+class Call(object):
+  """Adapter from old _low.Call interface to new _low.Call."""
+  
+  def __init__(self, channel, completion_queue, method, host, deadline):
+    self._internal = channel._internal.create_call(
+        completion_queue._internal, method, host, deadline)
+    self._metadata = []
+
+  @staticmethod
+  def _from_internal(internal):
+    call = Call.__new__(Call)
+    call._internal = internal
+    call._metadata = []
+    return call
+
+  def invoke(self, completion_queue, metadata_tag, finish_tag):
+    err0 = self._internal.start_batch([
+          _types.OpArgs.send_initial_metadata(self._metadata)
+      ], _IGNORE_ME_TAG)
+    err1 = self._internal.start_batch([
+          _types.OpArgs.recv_initial_metadata()
+      ], _TagAdapter(metadata_tag, Event.Kind.METADATA_ACCEPTED))
+    err2 = self._internal.start_batch([
+          _types.OpArgs.recv_status_on_client()
+      ], _TagAdapter(finish_tag, Event.Kind.FINISH))
+    return err0 if err0 != _types.CallError.OK else err1 if err1 != _types.CallError.OK else err2 if err2 != _types.CallError.OK else _types.CallError.OK
+
+  def write(self, message, tag):
+    return self._internal.start_batch([
+          _types.OpArgs.send_message(message)
+      ], _TagAdapter(tag, Event.Kind.WRITE_ACCEPTED))
+
+  def complete(self, tag):
+    return self._internal.start_batch([
+          _types.OpArgs.send_close_from_client()
+      ], _TagAdapter(tag, Event.Kind.COMPLETE_ACCEPTED))
+
+  def accept(self, completion_queue, tag):
+    return self._internal.start_batch([
+          _types.OpArgs.recv_close_on_server()
+      ], _TagAdapter(tag, Event.Kind.FINISH))
+
+  def add_metadata(self, key, value):
+    self._metadata.append((key, value))
+
+  def premetadata(self):
+    return self._internal.start_batch([
+          _types.OpArgs.send_initial_metadata(self._metadata)
+      ], _IGNORE_ME_TAG)
+    self._metadata = []
+
+  def read(self, tag):
+    return self._internal.start_batch([
+          _types.OpArgs.recv_message()
+      ], _TagAdapter(tag, Event.Kind.READ_ACCEPTED))
+
+  def status(self, status, tag):
+    return self._internal.start_batch([
+          _types.OpArgs.send_status_from_server(self._metadata, status.code, status.details)
+      ], _TagAdapter(tag, Event.Kind.COMPLETE_ACCEPTED))
+
+  def cancel(self):
+    return self._internal.cancel()
+
+
+class Channel(object):
+  """Adapter from old _low.Channel interface to new _low.Channel."""
+
+  def __init__(self, hostport, client_credentials, server_host_override=None):
+    args = []
+    if server_host_override:
+      args.append((_types.GrpcChannelArgumentKeys.SSL_TARGET_NAME_OVERRIDE.value, server_host_override))
+    creds = None
+    if client_credentials:
+      creds = client_credentials._internal
+    self._internal = _low.Channel(hostport, args, creds)
+
+
+class CompletionQueue(object):
+  """Adapter from old _low.CompletionQueue interface to new _low.CompletionQueue."""
+
+  def __init__(self):
+    self._internal = _low.CompletionQueue()
+
+  def get(self, deadline=None):
+    if deadline is None:
+      ev = self._internal.next()
+    else:
+      ev = self._internal.next(deadline)
+    if ev is None:
+      return None
+    elif ev.tag is _IGNORE_ME_TAG:
+      return self.get(deadline)
+    elif ev.type == _types.EventType.QUEUE_SHUTDOWN:
+      kind = Event.Kind.STOP
+      tag = None
+      write_accepted = None
+      complete_accepted = None
+      service_acceptance = None
+      message_bytes = None
+      status = None
+      metadata = None
+    elif ev.type == _types.EventType.OP_COMPLETE:
+      kind = ev.tag.kind
+      tag = ev.tag.user_tag
+      write_accepted = ev.success if kind == Event.Kind.WRITE_ACCEPTED else None
+      complete_accepted = ev.success if kind == Event.Kind.COMPLETE_ACCEPTED else None
+      service_acceptance = ServiceAcceptance(Call._from_internal(ev.call), ev.call_details.method, ev.call_details.host, ev.call_details.deadline) if kind == Event.Kind.SERVICE_ACCEPTED else None
+      message_bytes = ev.results[0].message if kind == Event.Kind.READ_ACCEPTED else None
+      status = Status(ev.results[0].status.code, ev.results[0].status.details) if (kind == Event.Kind.FINISH and ev.results[0].status) else Status(_types.StatusCode.CANCELLED if ev.results[0].cancelled else _types.StatusCode.OK, '') if ev.results[0].cancelled is not None else None
+      metadata = ev.results[0].initial_metadata if (kind in [Event.Kind.SERVICE_ACCEPTED, Event.Kind.METADATA_ACCEPTED]) else (ev.results[0].trailing_metadata if kind == Event.Kind.FINISH else None)
+    else:
+      raise RuntimeError('unknown event')
+    result_ev = Event(kind=kind, tag=tag, write_accepted=write_accepted, complete_accepted=complete_accepted, service_acceptance=service_acceptance, bytes=message_bytes, status=status, metadata=metadata)
+    return result_ev
+
+  def stop(self):
+    self._internal.shutdown()
+
+
+class Server(object):
+  """Adapter from old _low.Server interface to new _low.Server."""
+
+  def __init__(self, completion_queue):
+    self._internal = _low.Server(completion_queue._internal, [])
+    self._internal_cq = completion_queue._internal
+
+  def add_http2_addr(self, addr):
+    return self._internal.add_http2_port(addr)
+
+  def add_secure_http2_addr(self, addr, server_credentials):
+    if server_credentials is None:
+      return self._internal.add_http2_port(addr, None)
+    else:
+      return self._internal.add_http2_port(addr, server_credentials._internal)
+
+  def start(self):
+    return self._internal.start()
+
+  def service(self, tag):
+    return self._internal.request_call(self._internal_cq, _TagAdapter(tag, Event.Kind.SERVICE_ACCEPTED))
+
+  def stop(self):
+    return self._internal.shutdown()
+
+
+class ClientCredentials(object):
+  """Adapter from old _low.ClientCredentials interface to new _low.ClientCredentials."""
+
+  def __init__(self, root_certificates, private_key, certificate_chain):
+    self._internal = _low.ClientCredentials.ssl(root_certificates, private_key, certificate_chain)
+
+
+class ServerCredentials(object):
+  """Adapter from old _low.ServerCredentials interface to new _low.ServerCredentials."""
+  
+  def __init__(self, root_credentials, pair_sequence):
+    self._internal = _low.ServerCredentials.ssl(root_credentials, list(pair_sequence))
diff --git a/src/python/src/grpc/_adapter/_intermediary_low_test.py b/src/python/src/grpc/_adapter/_intermediary_low_test.py
new file mode 100644
index 0000000..6ff51c4
--- /dev/null
+++ b/src/python/src/grpc/_adapter/_intermediary_low_test.py
@@ -0,0 +1,421 @@
+# Copyright 2015, Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"""Tests for the old '_low'."""
+
+import time
+import unittest
+
+from grpc._adapter import _intermediary_low as _low
+
+_STREAM_LENGTH = 300
+_TIMEOUT = 5
+_AFTER_DELAY = 2
+_FUTURE = time.time() + 60 * 60 * 24
+_BYTE_SEQUENCE = b'\abcdefghijklmnopqrstuvwxyz0123456789' * 200
+_BYTE_SEQUENCE_SEQUENCE = tuple(
+    bytes(bytearray((row + column) % 256 for column in range(row)))
+    for row in range(_STREAM_LENGTH))
+
+class LonelyClientTest(unittest.TestCase):
+
+  def testLonelyClient(self):
+    host = 'nosuchhostexists'
+    port = 54321
+    method = 'test method'
+    deadline = time.time() + _TIMEOUT
+    after_deadline = deadline + _AFTER_DELAY
+    metadata_tag = object()
+    finish_tag = object()
+
+    completion_queue = _low.CompletionQueue()
+    channel = _low.Channel('%s:%d' % (host, port), None)
+    client_call = _low.Call(channel, completion_queue, method, host, deadline)
+
+    client_call.invoke(completion_queue, metadata_tag, finish_tag)
+    first_event = completion_queue.get(after_deadline)
+    self.assertIsNotNone(first_event)
+    second_event = completion_queue.get(after_deadline)
+    self.assertIsNotNone(second_event)
+    kinds = [event.kind for event in (first_event, second_event)]
+    self.assertItemsEqual(
+        (_low.Event.Kind.METADATA_ACCEPTED, _low.Event.Kind.FINISH),
+        kinds)
+
+    self.assertIsNone(completion_queue.get(after_deadline))
+
+    completion_queue.stop()
+    stop_event = completion_queue.get(_FUTURE)
+    self.assertEqual(_low.Event.Kind.STOP, stop_event.kind)
+
+    del client_call
+    del channel
+    del completion_queue
+
+
+class EchoTest(unittest.TestCase):
+
+  def setUp(self):
+    self.host = 'localhost'
+
+    self.server_completion_queue = _low.CompletionQueue()
+    self.server = _low.Server(self.server_completion_queue)
+    port = self.server.add_http2_addr('[::]:0')
+    self.server.start()
+
+    self.client_completion_queue = _low.CompletionQueue()
+    self.channel = _low.Channel('%s:%d' % (self.host, port), None)
+
+  def tearDown(self):
+    self.server.stop()
+    # NOTE(nathaniel): Yep, this is weird; it's a consequence of
+    # grpc_server_destroy's being what has the effect of telling the server's
+    # completion queue to pump out all pending events/tags immediately rather
+    # than gracefully completing all outstanding RPCs while accepting no new
+    # ones.
+    # TODO(nathaniel): Deallocation of a Python object shouldn't have this kind
+    # of observable side effect let alone such an important one.
+    del self.server
+    self.server_completion_queue.stop()
+    self.client_completion_queue.stop()
+    while True:
+      event = self.server_completion_queue.get(_FUTURE)
+      if event is not None and event.kind is _low.Event.Kind.STOP:
+        break
+    while True:
+      event = self.client_completion_queue.get(_FUTURE)
+      if event is not None and event.kind is _low.Event.Kind.STOP:
+        break
+    self.server_completion_queue = None
+    self.client_completion_queue = None
+
+  def _perform_echo_test(self, test_data):
+    method = 'test method'
+    details = 'test details'
+    server_leading_metadata_key = 'my_server_leading_key'
+    server_leading_metadata_value = 'my_server_leading_value'
+    server_trailing_metadata_key = 'my_server_trailing_key'
+    server_trailing_metadata_value = 'my_server_trailing_value'
+    client_metadata_key = 'my_client_key'
+    client_metadata_value = 'my_client_value'
+    server_leading_binary_metadata_key = 'my_server_leading_key-bin'
+    server_leading_binary_metadata_value = b'\0'*2047
+    server_trailing_binary_metadata_key = 'my_server_trailing_key-bin'
+    server_trailing_binary_metadata_value = b'\0'*2047
+    client_binary_metadata_key = 'my_client_key-bin'
+    client_binary_metadata_value = b'\0'*2047
+    deadline = _FUTURE
+    metadata_tag = object()
+    finish_tag = object()
+    write_tag = object()
+    complete_tag = object()
+    service_tag = object()
+    read_tag = object()
+    status_tag = object()
+
+    server_data = []
+    client_data = []
+
+    client_call = _low.Call(self.channel, self.client_completion_queue,
+                            method, self.host, deadline)
+    client_call.add_metadata(client_metadata_key, client_metadata_value)
+    client_call.add_metadata(client_binary_metadata_key,
+                             client_binary_metadata_value)
+
+    client_call.invoke(self.client_completion_queue, metadata_tag, finish_tag)
+
+    self.server.service(service_tag)
+    service_accepted = self.server_completion_queue.get(_FUTURE)
+    self.assertIsNotNone(service_accepted)
+    self.assertIs(service_accepted.kind, _low.Event.Kind.SERVICE_ACCEPTED)
+    self.assertIs(service_accepted.tag, service_tag)
+    self.assertEqual(method, service_accepted.service_acceptance.method)
+    self.assertEqual(self.host, service_accepted.service_acceptance.host)
+    self.assertIsNotNone(service_accepted.service_acceptance.call)
+    metadata = dict(service_accepted.metadata)
+    self.assertIn(client_metadata_key, metadata)
+    self.assertEqual(client_metadata_value, metadata[client_metadata_key])
+    self.assertIn(client_binary_metadata_key, metadata)
+    self.assertEqual(client_binary_metadata_value,
+                     metadata[client_binary_metadata_key])
+    server_call = service_accepted.service_acceptance.call
+    server_call.accept(self.server_completion_queue, finish_tag)
+    server_call.add_metadata(server_leading_metadata_key,
+                             server_leading_metadata_value)
+    server_call.add_metadata(server_leading_binary_metadata_key,
+                             server_leading_binary_metadata_value)
+    server_call.premetadata()
+
+    metadata_accepted = self.client_completion_queue.get(_FUTURE)
+    self.assertIsNotNone(metadata_accepted)
+    self.assertEqual(_low.Event.Kind.METADATA_ACCEPTED, metadata_accepted.kind)
+    self.assertEqual(metadata_tag, metadata_accepted.tag)
+    metadata = dict(metadata_accepted.metadata)
+    self.assertIn(server_leading_metadata_key, metadata)
+    self.assertEqual(server_leading_metadata_value,
+                     metadata[server_leading_metadata_key])
+    self.assertIn(server_leading_binary_metadata_key, metadata)
+    self.assertEqual(server_leading_binary_metadata_value,
+                     metadata[server_leading_binary_metadata_key])
+
+    for datum in test_data:
+      client_call.write(datum, write_tag)
+      write_accepted = self.client_completion_queue.get(_FUTURE)
+      self.assertIsNotNone(write_accepted)
+      self.assertIs(write_accepted.kind, _low.Event.Kind.WRITE_ACCEPTED)
+      self.assertIs(write_accepted.tag, write_tag)
+      self.assertIs(write_accepted.write_accepted, True)
+
+      server_call.read(read_tag)
+      read_accepted = self.server_completion_queue.get(_FUTURE)
+      self.assertIsNotNone(read_accepted)
+      self.assertEqual(_low.Event.Kind.READ_ACCEPTED, read_accepted.kind)
+      self.assertEqual(read_tag, read_accepted.tag)
+      self.assertIsNotNone(read_accepted.bytes)
+      server_data.append(read_accepted.bytes)
+
+      server_call.write(read_accepted.bytes, write_tag)
+      write_accepted = self.server_completion_queue.get(_FUTURE)
+      self.assertIsNotNone(write_accepted)
+      self.assertEqual(_low.Event.Kind.WRITE_ACCEPTED, write_accepted.kind)
+      self.assertEqual(write_tag, write_accepted.tag)
+      self.assertTrue(write_accepted.write_accepted)
+
+      client_call.read(read_tag)
+      read_accepted = self.client_completion_queue.get(_FUTURE)
+      self.assertIsNotNone(read_accepted)
+      self.assertEqual(_low.Event.Kind.READ_ACCEPTED, read_accepted.kind)
+      self.assertEqual(read_tag, read_accepted.tag)
+      self.assertIsNotNone(read_accepted.bytes)
+      client_data.append(read_accepted.bytes)
+
+    client_call.complete(complete_tag)
+    complete_accepted = self.client_completion_queue.get(_FUTURE)
+    self.assertIsNotNone(complete_accepted)
+    self.assertIs(complete_accepted.kind, _low.Event.Kind.COMPLETE_ACCEPTED)
+    self.assertIs(complete_accepted.tag, complete_tag)
+    self.assertIs(complete_accepted.complete_accepted, True)
+
+    server_call.read(read_tag)
+    read_accepted = self.server_completion_queue.get(_FUTURE)
+    self.assertIsNotNone(read_accepted)
+    self.assertEqual(_low.Event.Kind.READ_ACCEPTED, read_accepted.kind)
+    self.assertEqual(read_tag, read_accepted.tag)
+    self.assertIsNone(read_accepted.bytes)
+
+    server_call.add_metadata(server_trailing_metadata_key,
+                             server_trailing_metadata_value)
+    server_call.add_metadata(server_trailing_binary_metadata_key,
+                             server_trailing_binary_metadata_value)
+
+    server_call.status(_low.Status(_low.Code.OK, details), status_tag)
+    server_terminal_event_one = self.server_completion_queue.get(_FUTURE)
+    server_terminal_event_two = self.server_completion_queue.get(_FUTURE)
+    if server_terminal_event_one.kind == _low.Event.Kind.COMPLETE_ACCEPTED:
+      status_accepted = server_terminal_event_one
+      rpc_accepted = server_terminal_event_two
+    else:
+      status_accepted = server_terminal_event_two
+      rpc_accepted = server_terminal_event_one
+    self.assertIsNotNone(status_accepted)
+    self.assertIsNotNone(rpc_accepted)
+    self.assertEqual(_low.Event.Kind.COMPLETE_ACCEPTED, status_accepted.kind)
+    self.assertEqual(status_tag, status_accepted.tag)
+    self.assertTrue(status_accepted.complete_accepted)
+    self.assertEqual(_low.Event.Kind.FINISH, rpc_accepted.kind)
+    self.assertEqual(finish_tag, rpc_accepted.tag)
+    self.assertEqual(_low.Status(_low.Code.OK, ''), rpc_accepted.status)
+
+    client_call.read(read_tag)
+    client_terminal_event_one = self.client_completion_queue.get(_FUTURE)
+    client_terminal_event_two = self.client_completion_queue.get(_FUTURE)
+    if client_terminal_event_one.kind == _low.Event.Kind.READ_ACCEPTED:
+      read_accepted = client_terminal_event_one
+      finish_accepted = client_terminal_event_two
+    else:
+      read_accepted = client_terminal_event_two
+      finish_accepted = client_terminal_event_one
+    self.assertIsNotNone(read_accepted)
+    self.assertIsNotNone(finish_accepted)
+    self.assertEqual(_low.Event.Kind.READ_ACCEPTED, read_accepted.kind)
+    self.assertEqual(read_tag, read_accepted.tag)
+    self.assertIsNone(read_accepted.bytes)
+    self.assertEqual(_low.Event.Kind.FINISH, finish_accepted.kind)
+    self.assertEqual(finish_tag, finish_accepted.tag)
+    self.assertEqual(_low.Status(_low.Code.OK, details), finish_accepted.status)
+    metadata = dict(finish_accepted.metadata)
+    self.assertIn(server_trailing_metadata_key, metadata)
+    self.assertEqual(server_trailing_metadata_value,
+                     metadata[server_trailing_metadata_key])
+    self.assertIn(server_trailing_binary_metadata_key, metadata)
+    self.assertEqual(server_trailing_binary_metadata_value,
+                     metadata[server_trailing_binary_metadata_key])
+
+    server_timeout_none_event = self.server_completion_queue.get(0)
+    self.assertIsNone(server_timeout_none_event)
+    client_timeout_none_event = self.client_completion_queue.get(0)
+    self.assertIsNone(client_timeout_none_event)
+
+    self.assertSequenceEqual(test_data, server_data)
+    self.assertSequenceEqual(test_data, client_data)
+
+  def testNoEcho(self):
+    self._perform_echo_test(())
+
+  def testOneByteEcho(self):
+    self._perform_echo_test([b'\x07'])
+
+  def testOneManyByteEcho(self):
+    self._perform_echo_test([_BYTE_SEQUENCE])
+
+  def testManyOneByteEchoes(self):
+    self._perform_echo_test(_BYTE_SEQUENCE)
+
+  def testManyManyByteEchoes(self):
+    self._perform_echo_test(_BYTE_SEQUENCE_SEQUENCE)
+
+
+class CancellationTest(unittest.TestCase):
+
+  def setUp(self):
+    self.host = 'localhost'
+
+    self.server_completion_queue = _low.CompletionQueue()
+    self.server = _low.Server(self.server_completion_queue)
+    port = self.server.add_http2_addr('[::]:0')
+    self.server.start()
+
+    self.client_completion_queue = _low.CompletionQueue()
+    self.channel = _low.Channel('%s:%d' % (self.host, port), None)
+
+  def tearDown(self):
+    self.server.stop()
+    del self.server
+    self.server_completion_queue.stop()
+    self.client_completion_queue.stop()
+    while True:
+      event = self.server_completion_queue.get(0)
+      if event is not None and event.kind is _low.Event.Kind.STOP:
+        break
+    while True:
+      event = self.client_completion_queue.get(0)
+      if event is not None and event.kind is _low.Event.Kind.STOP:
+        break
+
+  def testCancellation(self):
+    method = 'test method'
+    deadline = _FUTURE
+    metadata_tag = object()
+    finish_tag = object()
+    write_tag = object()
+    service_tag = object()
+    read_tag = object()
+    test_data = _BYTE_SEQUENCE_SEQUENCE
+
+    server_data = []
+    client_data = []
+
+    client_call = _low.Call(self.channel, self.client_completion_queue,
+                            method, self.host, deadline)
+
+    client_call.invoke(self.client_completion_queue, metadata_tag, finish_tag)
+
+    self.server.service(service_tag)
+    service_accepted = self.server_completion_queue.get(_FUTURE)
+    server_call = service_accepted.service_acceptance.call
+
+    server_call.accept(self.server_completion_queue, finish_tag)
+    server_call.premetadata()
+
+    metadata_accepted = self.client_completion_queue.get(_FUTURE)
+    self.assertIsNotNone(metadata_accepted)
+
+    for datum in test_data:
+      client_call.write(datum, write_tag)
+      write_accepted = self.client_completion_queue.get(_FUTURE)
+
+      server_call.read(read_tag)
+      read_accepted = self.server_completion_queue.get(_FUTURE)
+      server_data.append(read_accepted.bytes)
+
+      server_call.write(read_accepted.bytes, write_tag)
+      write_accepted = self.server_completion_queue.get(_FUTURE)
+      self.assertIsNotNone(write_accepted)
+
+      client_call.read(read_tag)
+      read_accepted = self.client_completion_queue.get(_FUTURE)
+      client_data.append(read_accepted.bytes)
+
+    client_call.cancel()
+    # cancel() is idempotent.
+    client_call.cancel()
+    client_call.cancel()
+    client_call.cancel()
+
+    server_call.read(read_tag)
+
+    server_terminal_event_one = self.server_completion_queue.get(_FUTURE)
+    server_terminal_event_two = self.server_completion_queue.get(_FUTURE)
+    if server_terminal_event_one.kind == _low.Event.Kind.READ_ACCEPTED:
+      read_accepted = server_terminal_event_one
+      rpc_accepted = server_terminal_event_two
+    else:
+      read_accepted = server_terminal_event_two
+      rpc_accepted = server_terminal_event_one
+    self.assertIsNotNone(read_accepted)
+    self.assertIsNotNone(rpc_accepted)
+    self.assertEqual(_low.Event.Kind.READ_ACCEPTED, read_accepted.kind)
+    self.assertIsNone(read_accepted.bytes)
+    self.assertEqual(_low.Event.Kind.FINISH, rpc_accepted.kind)
+    self.assertEqual(_low.Status(_low.Code.CANCELLED, ''), rpc_accepted.status)
+
+    finish_event = self.client_completion_queue.get(_FUTURE)
+    self.assertEqual(_low.Event.Kind.FINISH, finish_event.kind)
+    self.assertEqual(_low.Status(_low.Code.CANCELLED, 'Cancelled'), 
+                                 finish_event.status)
+
+    server_timeout_none_event = self.server_completion_queue.get(0)
+    self.assertIsNone(server_timeout_none_event)
+    client_timeout_none_event = self.client_completion_queue.get(0)
+    self.assertIsNone(client_timeout_none_event)
+
+    self.assertSequenceEqual(test_data, server_data)
+    self.assertSequenceEqual(test_data, client_data)
+
+
+class ExpirationTest(unittest.TestCase):
+
+  @unittest.skip('TODO(nathaniel): Expiration test!')
+  def testExpiration(self):
+    pass
+
+
+if __name__ == '__main__':
+  unittest.main(verbosity=2)
+
diff --git a/src/python/src/grpc/_adapter/_low.py b/src/python/src/grpc/_adapter/_low.py
index a24baae..0c1d3b4 100644
--- a/src/python/src/grpc/_adapter/_low.py
+++ b/src/python/src/grpc/_adapter/_low.py
@@ -27,31 +27,85 @@
 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-"""A Python interface for GRPC C core structures and behaviors."""
-
-import atexit
-import gc
-
 from grpc._adapter import _c
-from grpc._adapter import _datatypes
+from grpc._adapter import _types
 
-def _shut_down():
-  # force garbage collection before shutting down grpc, to ensure all grpc
-  # objects are cleaned up
-  gc.collect()
-  _c.shut_down()
-
-_c.init()
-atexit.register(_shut_down)
-
-# pylint: disable=invalid-name
-Code = _datatypes.Code
-Status = _datatypes.Status
-Event = _datatypes.Event
-Call = _c.Call
-Channel = _c.Channel
-CompletionQueue = _c.CompletionQueue
-Server = _c.Server
 ClientCredentials = _c.ClientCredentials
 ServerCredentials = _c.ServerCredentials
-# pylint: enable=invalid-name
+
+
+class CompletionQueue(_types.CompletionQueue):
+
+  def __init__(self):
+    self.completion_queue = _c.CompletionQueue()
+
+  def next(self, deadline=float('+inf')):
+    raw_event = self.completion_queue.next(deadline)
+    if raw_event is None:
+      return None
+    event = _types.Event(*raw_event)
+    if event.call is not None:
+      event = event._replace(call=Call(event.call))
+    if event.call_details is not None:
+      event = event._replace(call_details=_types.CallDetails(*event.call_details))
+    if event.results is not None:
+      new_results = [_types.OpResult(*r) for r in event.results]
+      new_results = [r if r.status is None else r._replace(status=_types.Status(_types.StatusCode(r.status[0]), r.status[1])) for r in new_results]
+      event = event._replace(results=new_results)
+    return event
+
+  def shutdown(self):
+    self.completion_queue.shutdown()
+
+
+class Call(_types.Call):
+
+  def __init__(self, call):
+    self.call = call
+
+  def start_batch(self, ops, tag):
+    return self.call.start_batch(ops, tag)
+
+  def cancel(self, code=None, details=None):
+    if code is None and details is None:
+      return self.call.cancel()
+    else:
+      return self.call.cancel(code, details)
+
+
+class Channel(_types.Channel):
+
+  def __init__(self, target, args, creds=None):
+    if creds is None:
+      self.channel = _c.Channel(target, args)
+    else:
+      self.channel = _c.Channel(target, args, creds)
+
+  def create_call(self, completion_queue, method, host, deadline=None):
+    return Call(self.channel.create_call(completion_queue.completion_queue, method, host, deadline))
+
+
+_NO_TAG = object()
+
+class Server(_types.Server):
+
+  def __init__(self, completion_queue, args):
+    self.server = _c.Server(completion_queue.completion_queue, args)
+
+  def add_http2_port(self, addr, creds=None):
+    if creds is None:
+      return self.server.add_http2_port(addr)
+    else:
+      return self.server.add_http2_port(addr, creds)
+
+  def start(self):
+    return self.server.start()
+
+  def shutdown(self, tag=_NO_TAG):
+    if tag is _NO_TAG:
+      return self.server.shutdown()
+    else:
+      return self.server.shutdown(tag)
+
+  def request_call(self, completion_queue, tag):
+    return self.server.request_call(completion_queue.completion_queue, tag)
diff --git a/src/python/src/grpc/_adapter/_low_test.py b/src/python/src/grpc/_adapter/_low_test.py
index d4b628c..e53b176 100644
--- a/src/python/src/grpc/_adapter/_low_test.py
+++ b/src/python/src/grpc/_adapter/_low_test.py
@@ -27,388 +27,141 @@
 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-"""Tests for _adapter._low."""
-
 import time
 import unittest
 
+from grpc._adapter import _types
 from grpc._adapter import _low
 
-_STREAM_LENGTH = 300
-_TIMEOUT = 5
-_AFTER_DELAY = 2
-_FUTURE = time.time() + 60 * 60 * 24
-_BYTE_SEQUENCE = b'\abcdefghijklmnopqrstuvwxyz0123456789' * 200
-_BYTE_SEQUENCE_SEQUENCE = tuple(
-    bytes(bytearray((row + column) % 256 for column in range(row)))
-    for row in range(_STREAM_LENGTH))
 
-class LonelyClientTest(unittest.TestCase):
-
-  def testLonelyClient(self):
-    host = 'nosuchhostexists'
-    port = 54321
-    method = 'test method'
-    deadline = time.time() + _TIMEOUT
-    after_deadline = deadline + _AFTER_DELAY
-    metadata_tag = object()
-    finish_tag = object()
-
-    completion_queue = _low.CompletionQueue()
-    channel = _low.Channel('%s:%d' % (host, port), None)
-    client_call = _low.Call(channel, completion_queue, method, host, deadline)
-
-    client_call.invoke(completion_queue, metadata_tag, finish_tag)
-    first_event = completion_queue.get(after_deadline)
-    self.assertIsNotNone(first_event)
-    second_event = completion_queue.get(after_deadline)
-    self.assertIsNotNone(second_event)
-    kinds = [event.kind for event in (first_event, second_event)]
-    self.assertItemsEqual(
-        (_low.Event.Kind.METADATA_ACCEPTED, _low.Event.Kind.FINISH),
-        kinds)
-
-    self.assertIsNone(completion_queue.get(after_deadline))
-
-    completion_queue.stop()
-    stop_event = completion_queue.get(_FUTURE)
-    self.assertEqual(_low.Event.Kind.STOP, stop_event.kind)
-
-
-class EchoTest(unittest.TestCase):
+class InsecureServerInsecureClient(unittest.TestCase):
 
   def setUp(self):
-    self.host = 'localhost'
-
     self.server_completion_queue = _low.CompletionQueue()
-    self.server = _low.Server(self.server_completion_queue)
-    port = self.server.add_http2_addr('[::]:0')
+    self.server = _low.Server(self.server_completion_queue, [])
+    self.port = self.server.add_http2_port('[::]:0')
+    self.client_completion_queue = _low.CompletionQueue()
+    self.client_channel = _low.Channel('localhost:%d'%self.port, [])
+
     self.server.start()
 
-    self.client_completion_queue = _low.CompletionQueue()
-    self.channel = _low.Channel('%s:%d' % (self.host, port), None)
-
   def tearDown(self):
-    self.server.stop()
-    # NOTE(nathaniel): Yep, this is weird; it's a consequence of
-    # grpc_server_destroy's being what has the effect of telling the server's
-    # completion queue to pump out all pending events/tags immediately rather
-    # than gracefully completing all outstanding RPCs while accepting no new
-    # ones.
-    # TODO(nathaniel): Deallocation of a Python object shouldn't have this kind
-    # of observable side effect let alone such an important one.
+    self.server.shutdown()
+    del self.client_channel
     del self.server
-    self.server_completion_queue.stop()
-    self.client_completion_queue.stop()
-    while True:
-      event = self.server_completion_queue.get(_FUTURE)
-      if event is not None and event.kind is _low.Event.Kind.STOP:
-        break
-    while True:
-      event = self.client_completion_queue.get(_FUTURE)
-      if event is not None and event.kind is _low.Event.Kind.STOP:
-        break
-    self.server_completion_queue = None
-    self.client_completion_queue = None
 
-  def _perform_echo_test(self, test_data):
-    method = 'test method'
-    details = 'test details'
-    server_leading_metadata_key = 'my_server_leading_key'
-    server_leading_metadata_value = 'my_server_leading_value'
-    server_trailing_metadata_key = 'my_server_trailing_key'
-    server_trailing_metadata_value = 'my_server_trailing_value'
-    client_metadata_key = 'my_client_key'
-    client_metadata_value = 'my_client_value'
-    server_leading_binary_metadata_key = 'my_server_leading_key-bin'
-    server_leading_binary_metadata_value = b'\0'*2047
-    server_trailing_binary_metadata_key = 'my_server_trailing_key-bin'
-    server_trailing_binary_metadata_value = b'\0'*2047
-    client_binary_metadata_key = 'my_client_key-bin'
-    client_binary_metadata_value = b'\0'*2047
-    deadline = _FUTURE
-    metadata_tag = object()
-    finish_tag = object()
-    write_tag = object()
-    complete_tag = object()
-    service_tag = object()
-    read_tag = object()
-    status_tag = object()
+    self.client_completion_queue.shutdown()
+    while self.client_completion_queue.next().type != _types.EventType.QUEUE_SHUTDOWN:
+      pass
+    self.server_completion_queue.shutdown()
+    while self.server_completion_queue.next().type != _types.EventType.QUEUE_SHUTDOWN:
+      pass
 
-    server_data = []
-    client_data = []
+    del self.client_completion_queue
+    del self.server_completion_queue
 
-    client_call = _low.Call(self.channel, self.client_completion_queue,
-                            method, self.host, deadline)
-    client_call.add_metadata(client_metadata_key, client_metadata_value)
-    client_call.add_metadata(client_binary_metadata_key,
-                             client_binary_metadata_value)
+  def testEcho(self):
+    DEADLINE = time.time()+5
+    DEADLINE_TOLERANCE = 0.25
+    CLIENT_METADATA_ASCII_KEY = 'key'
+    CLIENT_METADATA_ASCII_VALUE = 'val'
+    CLIENT_METADATA_BIN_KEY = 'key-bin'
+    CLIENT_METADATA_BIN_VALUE = b'\0'*1000
+    SERVER_INITIAL_METADATA_KEY = 'init_me_me_me'
+    SERVER_INITIAL_METADATA_VALUE = 'whodawha?'
+    SERVER_TRAILING_METADATA_KEY = 'California_is_in_a_drought'
+    SERVER_TRAILING_METADATA_VALUE = 'zomg it is'
+    SERVER_STATUS_CODE = _types.StatusCode.OK
+    SERVER_STATUS_DETAILS = 'our work is never over'
+    REQUEST = 'in death a member of project mayhem has a name'
+    RESPONSE = 'his name is robert paulson'
+    METHOD = 'twinkies'
+    HOST = 'hostess'
+    server_request_tag = object()
+    request_call_result = self.server.request_call(self.server_completion_queue, server_request_tag)
 
-    client_call.invoke(self.client_completion_queue, metadata_tag, finish_tag)
+    self.assertEquals(_types.CallError.OK, request_call_result)
 
-    self.server.service(service_tag)
-    service_accepted = self.server_completion_queue.get(_FUTURE)
-    self.assertIsNotNone(service_accepted)
-    self.assertIs(service_accepted.kind, _low.Event.Kind.SERVICE_ACCEPTED)
-    self.assertIs(service_accepted.tag, service_tag)
-    self.assertEqual(method, service_accepted.service_acceptance.method)
-    self.assertEqual(self.host, service_accepted.service_acceptance.host)
-    self.assertIsNotNone(service_accepted.service_acceptance.call)
-    metadata = dict(service_accepted.metadata)
-    self.assertIn(client_metadata_key, metadata)
-    self.assertEqual(client_metadata_value, metadata[client_metadata_key])
-    self.assertIn(client_binary_metadata_key, metadata)
-    self.assertEqual(client_binary_metadata_value,
-                     metadata[client_binary_metadata_key])
-    server_call = service_accepted.service_acceptance.call
-    server_call.accept(self.server_completion_queue, finish_tag)
-    server_call.add_metadata(server_leading_metadata_key,
-                             server_leading_metadata_value)
-    server_call.add_metadata(server_leading_binary_metadata_key,
-                             server_leading_binary_metadata_value)
-    server_call.premetadata()
+    client_call_tag = object()
+    client_call = self.client_channel.create_call(self.client_completion_queue, METHOD, HOST, DEADLINE)
+    client_initial_metadata = [(CLIENT_METADATA_ASCII_KEY, CLIENT_METADATA_ASCII_VALUE), (CLIENT_METADATA_BIN_KEY, CLIENT_METADATA_BIN_VALUE)]
+    client_start_batch_result = client_call.start_batch([
+        _types.OpArgs.send_initial_metadata(client_initial_metadata),
+        _types.OpArgs.send_message(REQUEST),
+        _types.OpArgs.send_close_from_client(),
+        _types.OpArgs.recv_initial_metadata(),
+        _types.OpArgs.recv_message(),
+        _types.OpArgs.recv_status_on_client()
+    ], client_call_tag)
+    self.assertEquals(_types.CallError.OK, client_start_batch_result)
 
-    metadata_accepted = self.client_completion_queue.get(_FUTURE)
-    self.assertIsNotNone(metadata_accepted)
-    self.assertEqual(_low.Event.Kind.METADATA_ACCEPTED, metadata_accepted.kind)
-    self.assertEqual(metadata_tag, metadata_accepted.tag)
-    metadata = dict(metadata_accepted.metadata)
-    self.assertIn(server_leading_metadata_key, metadata)
-    self.assertEqual(server_leading_metadata_value,
-                     metadata[server_leading_metadata_key])
-    self.assertIn(server_leading_binary_metadata_key, metadata)
-    self.assertEqual(server_leading_binary_metadata_value,
-                     metadata[server_leading_binary_metadata_key])
+    request_event = self.server_completion_queue.next(DEADLINE)
+    self.assertEquals(_types.EventType.OP_COMPLETE, request_event.type)
+    self.assertIsInstance(request_event.call, _low.Call)
+    self.assertIs(server_request_tag, request_event.tag)
+    self.assertEquals(1, len(request_event.results))
+    self.assertEquals(dict(client_initial_metadata), dict(request_event.results[0].initial_metadata))
+    self.assertEquals(METHOD, request_event.call_details.method)
+    self.assertEquals(HOST, request_event.call_details.host)
+    self.assertLess(abs(DEADLINE - request_event.call_details.deadline), DEADLINE_TOLERANCE)
 
-    for datum in test_data:
-      client_call.write(datum, write_tag)
-      write_accepted = self.client_completion_queue.get(_FUTURE)
-      self.assertIsNotNone(write_accepted)
-      self.assertIs(write_accepted.kind, _low.Event.Kind.WRITE_ACCEPTED)
-      self.assertIs(write_accepted.tag, write_tag)
-      self.assertIs(write_accepted.write_accepted, True)
+    server_call_tag = object()
+    server_call = request_event.call
+    server_initial_metadata = [(SERVER_INITIAL_METADATA_KEY, SERVER_INITIAL_METADATA_VALUE)]
+    server_trailing_metadata = [(SERVER_TRAILING_METADATA_KEY, SERVER_TRAILING_METADATA_VALUE)]
+    server_start_batch_result = server_call.start_batch([
+        _types.OpArgs.send_initial_metadata(server_initial_metadata),
+        _types.OpArgs.recv_message(),
+        _types.OpArgs.send_message(RESPONSE),
+        _types.OpArgs.recv_close_on_server(),
+        _types.OpArgs.send_status_from_server(server_trailing_metadata, SERVER_STATUS_CODE, SERVER_STATUS_DETAILS)
+    ], server_call_tag)
+    self.assertEquals(_types.CallError.OK, server_start_batch_result)
 
-      server_call.read(read_tag)
-      read_accepted = self.server_completion_queue.get(_FUTURE)
-      self.assertIsNotNone(read_accepted)
-      self.assertEqual(_low.Event.Kind.READ_ACCEPTED, read_accepted.kind)
-      self.assertEqual(read_tag, read_accepted.tag)
-      self.assertIsNotNone(read_accepted.bytes)
-      server_data.append(read_accepted.bytes)
+    client_event = self.client_completion_queue.next(DEADLINE)
+    server_event = self.server_completion_queue.next(DEADLINE)
 
-      server_call.write(read_accepted.bytes, write_tag)
-      write_accepted = self.server_completion_queue.get(_FUTURE)
-      self.assertIsNotNone(write_accepted)
-      self.assertEqual(_low.Event.Kind.WRITE_ACCEPTED, write_accepted.kind)
-      self.assertEqual(write_tag, write_accepted.tag)
-      self.assertTrue(write_accepted.write_accepted)
+    self.assertEquals(6, len(client_event.results))
+    found_client_op_types = set()
+    for client_result in client_event.results:
+      self.assertNotIn(client_result.type, found_client_op_types)  # we expect each op type to be unique
+      found_client_op_types.add(client_result.type)
+      if client_result.type == _types.OpType.RECV_INITIAL_METADATA:
+        self.assertEquals(dict(server_initial_metadata), dict(client_result.initial_metadata))
+      elif client_result.type == _types.OpType.RECV_MESSAGE:
+        self.assertEquals(RESPONSE, client_result.message)
+      elif client_result.type == _types.OpType.RECV_STATUS_ON_CLIENT:
+        self.assertEquals(dict(server_trailing_metadata), dict(client_result.trailing_metadata))
+        self.assertEquals(SERVER_STATUS_DETAILS, client_result.status.details)
+        self.assertEquals(SERVER_STATUS_CODE, client_result.status.code)
+    self.assertEquals(set([
+          _types.OpType.SEND_INITIAL_METADATA,
+          _types.OpType.SEND_MESSAGE,
+          _types.OpType.SEND_CLOSE_FROM_CLIENT,
+          _types.OpType.RECV_INITIAL_METADATA,
+          _types.OpType.RECV_MESSAGE,
+          _types.OpType.RECV_STATUS_ON_CLIENT
+      ]), found_client_op_types)
 
-      client_call.read(read_tag)
-      read_accepted = self.client_completion_queue.get(_FUTURE)
-      self.assertIsNotNone(read_accepted)
-      self.assertEqual(_low.Event.Kind.READ_ACCEPTED, read_accepted.kind)
-      self.assertEqual(read_tag, read_accepted.tag)
-      self.assertIsNotNone(read_accepted.bytes)
-      client_data.append(read_accepted.bytes)
+    self.assertEquals(5, len(server_event.results))
+    found_server_op_types = set()
+    for server_result in server_event.results:
+      self.assertNotIn(client_result.type, found_server_op_types)
+      found_server_op_types.add(server_result.type)
+      if server_result.type == _types.OpType.RECV_MESSAGE:
+        self.assertEquals(REQUEST, server_result.message)
+      elif server_result.type == _types.OpType.RECV_CLOSE_ON_SERVER:
+        self.assertFalse(server_result.cancelled)
+    self.assertEquals(set([
+          _types.OpType.SEND_INITIAL_METADATA,
+          _types.OpType.RECV_MESSAGE,
+          _types.OpType.SEND_MESSAGE,
+          _types.OpType.RECV_CLOSE_ON_SERVER,
+          _types.OpType.SEND_STATUS_FROM_SERVER
+      ]), found_server_op_types)
 
-    client_call.complete(complete_tag)
-    complete_accepted = self.client_completion_queue.get(_FUTURE)
-    self.assertIsNotNone(complete_accepted)
-    self.assertIs(complete_accepted.kind, _low.Event.Kind.COMPLETE_ACCEPTED)
-    self.assertIs(complete_accepted.tag, complete_tag)
-    self.assertIs(complete_accepted.complete_accepted, True)
-
-    server_call.read(read_tag)
-    read_accepted = self.server_completion_queue.get(_FUTURE)
-    self.assertIsNotNone(read_accepted)
-    self.assertEqual(_low.Event.Kind.READ_ACCEPTED, read_accepted.kind)
-    self.assertEqual(read_tag, read_accepted.tag)
-    self.assertIsNone(read_accepted.bytes)
-
-    server_call.add_metadata(server_trailing_metadata_key,
-                             server_trailing_metadata_value)
-    server_call.add_metadata(server_trailing_binary_metadata_key,
-                             server_trailing_binary_metadata_value)
-
-    server_call.status(_low.Status(_low.Code.OK, details), status_tag)
-    server_terminal_event_one = self.server_completion_queue.get(_FUTURE)
-    server_terminal_event_two = self.server_completion_queue.get(_FUTURE)
-    if server_terminal_event_one.kind == _low.Event.Kind.COMPLETE_ACCEPTED:
-      status_accepted = server_terminal_event_one
-      rpc_accepted = server_terminal_event_two
-    else:
-      status_accepted = server_terminal_event_two
-      rpc_accepted = server_terminal_event_one
-    self.assertIsNotNone(status_accepted)
-    self.assertIsNotNone(rpc_accepted)
-    self.assertEqual(_low.Event.Kind.COMPLETE_ACCEPTED, status_accepted.kind)
-    self.assertEqual(status_tag, status_accepted.tag)
-    self.assertTrue(status_accepted.complete_accepted)
-    self.assertEqual(_low.Event.Kind.FINISH, rpc_accepted.kind)
-    self.assertEqual(finish_tag, rpc_accepted.tag)
-    self.assertEqual(_low.Status(_low.Code.OK, ''), rpc_accepted.status)
-
-    client_call.read(read_tag)
-    client_terminal_event_one = self.client_completion_queue.get(_FUTURE)
-    client_terminal_event_two = self.client_completion_queue.get(_FUTURE)
-    if client_terminal_event_one.kind == _low.Event.Kind.READ_ACCEPTED:
-      read_accepted = client_terminal_event_one
-      finish_accepted = client_terminal_event_two
-    else:
-      read_accepted = client_terminal_event_two
-      finish_accepted = client_terminal_event_one
-    self.assertIsNotNone(read_accepted)
-    self.assertIsNotNone(finish_accepted)
-    self.assertEqual(_low.Event.Kind.READ_ACCEPTED, read_accepted.kind)
-    self.assertEqual(read_tag, read_accepted.tag)
-    self.assertIsNone(read_accepted.bytes)
-    self.assertEqual(_low.Event.Kind.FINISH, finish_accepted.kind)
-    self.assertEqual(finish_tag, finish_accepted.tag)
-    self.assertEqual(_low.Status(_low.Code.OK, details), finish_accepted.status)
-    metadata = dict(finish_accepted.metadata)
-    self.assertIn(server_trailing_metadata_key, metadata)
-    self.assertEqual(server_trailing_metadata_value,
-                     metadata[server_trailing_metadata_key])
-    self.assertIn(server_trailing_binary_metadata_key, metadata)
-    self.assertEqual(server_trailing_binary_metadata_value,
-                     metadata[server_trailing_binary_metadata_key])
-
-    server_timeout_none_event = self.server_completion_queue.get(0)
-    self.assertIsNone(server_timeout_none_event)
-    client_timeout_none_event = self.client_completion_queue.get(0)
-    self.assertIsNone(client_timeout_none_event)
-
-    self.assertSequenceEqual(test_data, server_data)
-    self.assertSequenceEqual(test_data, client_data)
-
-  def testNoEcho(self):
-    self._perform_echo_test(())
-
-  def testOneByteEcho(self):
-    self._perform_echo_test([b'\x07'])
-
-  def testOneManyByteEcho(self):
-    self._perform_echo_test([_BYTE_SEQUENCE])
-
-  def testManyOneByteEchoes(self):
-    self._perform_echo_test(_BYTE_SEQUENCE)
-
-  def testManyManyByteEchoes(self):
-    self._perform_echo_test(_BYTE_SEQUENCE_SEQUENCE)
-
-class CancellationTest(unittest.TestCase):
-
-  def setUp(self):
-    self.host = 'localhost'
-
-    self.server_completion_queue = _low.CompletionQueue()
-    self.server = _low.Server(self.server_completion_queue)
-    port = self.server.add_http2_addr('[::]:0')
-    self.server.start()
-
-    self.client_completion_queue = _low.CompletionQueue()
-    self.channel = _low.Channel('%s:%d' % (self.host, port), None)
-
-  def tearDown(self):
-    self.server.stop()
-    del self.server
-    self.server_completion_queue.stop()
-    self.client_completion_queue.stop()
-    while True:
-      event = self.server_completion_queue.get(0)
-      if event is not None and event.kind is _low.Event.Kind.STOP:
-        break
-    while True:
-      event = self.client_completion_queue.get(0)
-      if event is not None and event.kind is _low.Event.Kind.STOP:
-        break
-
-  def testCancellation(self):
-    method = 'test method'
-    deadline = _FUTURE
-    metadata_tag = object()
-    finish_tag = object()
-    write_tag = object()
-    service_tag = object()
-    read_tag = object()
-    test_data = _BYTE_SEQUENCE_SEQUENCE
-
-    server_data = []
-    client_data = []
-
-    client_call = _low.Call(self.channel, self.client_completion_queue,
-                            method, self.host, deadline)
-
-    client_call.invoke(self.client_completion_queue, metadata_tag, finish_tag)
-
-    self.server.service(service_tag)
-    service_accepted = self.server_completion_queue.get(_FUTURE)
-    server_call = service_accepted.service_acceptance.call
-
-    server_call.accept(self.server_completion_queue, finish_tag)
-    server_call.premetadata()
-
-    metadata_accepted = self.client_completion_queue.get(_FUTURE)
-    self.assertIsNotNone(metadata_accepted)
-
-    for datum in test_data:
-      client_call.write(datum, write_tag)
-      write_accepted = self.client_completion_queue.get(_FUTURE)
-
-      server_call.read(read_tag)
-      read_accepted = self.server_completion_queue.get(_FUTURE)
-      server_data.append(read_accepted.bytes)
-
-      server_call.write(read_accepted.bytes, write_tag)
-      write_accepted = self.server_completion_queue.get(_FUTURE)
-      self.assertIsNotNone(write_accepted)
-
-      client_call.read(read_tag)
-      read_accepted = self.client_completion_queue.get(_FUTURE)
-      client_data.append(read_accepted.bytes)
-
-    client_call.cancel()
-    # cancel() is idempotent.
-    client_call.cancel()
-    client_call.cancel()
-    client_call.cancel()
-
-    server_call.read(read_tag)
-
-    server_terminal_event_one = self.server_completion_queue.get(_FUTURE)
-    server_terminal_event_two = self.server_completion_queue.get(_FUTURE)
-    if server_terminal_event_one.kind == _low.Event.Kind.READ_ACCEPTED:
-      read_accepted = server_terminal_event_one
-      rpc_accepted = server_terminal_event_two
-    else:
-      read_accepted = server_terminal_event_two
-      rpc_accepted = server_terminal_event_one
-    self.assertIsNotNone(read_accepted)
-    self.assertIsNotNone(rpc_accepted)
-    self.assertEqual(_low.Event.Kind.READ_ACCEPTED, read_accepted.kind)
-    self.assertIsNone(read_accepted.bytes)
-    self.assertEqual(_low.Event.Kind.FINISH, rpc_accepted.kind)
-    self.assertEqual(_low.Status(_low.Code.CANCELLED, ''), rpc_accepted.status)
-
-    finish_event = self.client_completion_queue.get(_FUTURE)
-    self.assertEqual(_low.Event.Kind.FINISH, finish_event.kind)
-    self.assertEqual(_low.Status(_low.Code.CANCELLED, 'Cancelled'), 
-                                 finish_event.status)
-
-    server_timeout_none_event = self.server_completion_queue.get(0)
-    self.assertIsNone(server_timeout_none_event)
-    client_timeout_none_event = self.client_completion_queue.get(0)
-    self.assertIsNone(client_timeout_none_event)
-
-    self.assertSequenceEqual(test_data, server_data)
-    self.assertSequenceEqual(test_data, client_data)
-
-
-class ExpirationTest(unittest.TestCase):
-
-  @unittest.skip('TODO(nathaniel): Expiration test!')
-  def testExpiration(self):
-    pass
+    del client_call
+    del server_call
 
 
 if __name__ == '__main__':
diff --git a/src/python/src/grpc/_adapter/_server.c b/src/python/src/grpc/_adapter/_server.c
deleted file mode 100644
index a6c20bf..0000000
--- a/src/python/src/grpc/_adapter/_server.c
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- *
- * Copyright 2015, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#include "grpc/_adapter/_server.h"
-
-#include <Python.h>
-#include <grpc/grpc.h>
-
-#include "grpc/_adapter/_call.h"
-#include "grpc/_adapter/_completion_queue.h"
-#include "grpc/_adapter/_error.h"
-#include "grpc/_adapter/_server_credentials.h"
-#include "grpc/_adapter/_tag.h"
-
-static int pygrpc_server_init(Server *self, PyObject *args, PyObject *kwds) {
-  CompletionQueue *completion_queue;
-  static char *kwlist[] = {"completion_queue", NULL};
-
-  if (!PyArg_ParseTupleAndKeywords(args, kwds, "O!:Server", kwlist,
-                                   &pygrpc_CompletionQueueType,
-                                   &completion_queue)) {
-    return -1;
-  }
-  self->c_server = grpc_server_create(NULL);
-  grpc_server_register_completion_queue(self->c_server,
-                                        completion_queue->c_completion_queue);
-  self->completion_queue = completion_queue;
-  Py_INCREF(completion_queue);
-  return 0;
-}
-
-static void pygrpc_server_dealloc(Server *self) {
-  if (self->c_server != NULL) {
-    grpc_server_destroy(self->c_server);
-  }
-  Py_XDECREF(self->completion_queue);
-  self->ob_type->tp_free((PyObject *)self);
-}
-
-static PyObject *pygrpc_server_add_http2_addr(Server *self, PyObject *args) {
-  const char *addr;
-  int port;
-  if (!PyArg_ParseTuple(args, "s:add_http2_addr", &addr)) {
-    return NULL;
-  }
-
-  port = grpc_server_add_http2_port(self->c_server, addr);
-  if (port == 0) {
-    PyErr_SetString(PyExc_RuntimeError, "Couldn't add port to server!");
-    return NULL;
-  }
-
-  return PyInt_FromLong(port);
-}
-
-static PyObject *pygrpc_server_add_secure_http2_addr(Server *self,
-                                                     PyObject *args,
-                                                     PyObject *kwargs) {
-  const char *addr;
-  PyObject *server_credentials;
-  static char *kwlist[] = {"addr", "server_credentials", NULL};
-  int port;
-
-  if (!PyArg_ParseTupleAndKeywords(args, kwargs, "sO!:add_secure_http2_addr",
-                                   kwlist, &addr, &pygrpc_ServerCredentialsType,
-                                   &server_credentials)) {
-    return NULL;
-  }
-  port = grpc_server_add_secure_http2_port(
-      self->c_server, addr,
-      ((ServerCredentials *)server_credentials)->c_server_credentials);
-  if (port == 0) {
-    PyErr_SetString(PyExc_RuntimeError, "Couldn't add port to server!");
-    return NULL;
-  }
-  return PyInt_FromLong(port);
-}
-
-static PyObject *pygrpc_server_start(Server *self) {
-  grpc_server_start(self->c_server);
-
-  Py_RETURN_NONE;
-}
-
-static const PyObject *pygrpc_server_service(Server *self, PyObject *tag) {
-  grpc_call_error call_error;
-  const PyObject *result;
-  pygrpc_tag *c_tag = pygrpc_tag_new_server_rpc_call(tag);
-  c_tag->call->completion_queue = self->completion_queue;
-  c_tag->call->server = self;
-  Py_INCREF(c_tag->call->completion_queue);
-  Py_INCREF(c_tag->call->server);
-  call_error = grpc_server_request_call(
-      self->c_server, &c_tag->call->c_call, &c_tag->call->call_details,
-      &c_tag->call->recv_metadata, self->completion_queue->c_completion_queue,
-      self->completion_queue->c_completion_queue, c_tag);
-
-  result = pygrpc_translate_call_error(call_error);
-  if (result != NULL) {
-    Py_INCREF(tag);
-  }
-  return result;
-}
-
-static PyObject *pygrpc_server_stop(Server *self) {
-  grpc_server_shutdown(self->c_server);
-
-  Py_RETURN_NONE;
-}
-
-static PyMethodDef methods[] = {
-    {"add_http2_addr", (PyCFunction)pygrpc_server_add_http2_addr, METH_VARARGS,
-     "Add an HTTP2 address."},
-    {"add_secure_http2_addr", (PyCFunction)pygrpc_server_add_secure_http2_addr,
-     METH_VARARGS, "Add a secure HTTP2 address."},
-    {"start", (PyCFunction)pygrpc_server_start, METH_NOARGS,
-     "Starts the server."},
-    {"service", (PyCFunction)pygrpc_server_service, METH_O, "Services a call."},
-    {"stop", (PyCFunction)pygrpc_server_stop, METH_NOARGS, "Stops the server."},
-    {NULL}};
-
-static PyTypeObject pygrpc_ServerType = {
-    PyVarObject_HEAD_INIT(NULL, 0)
-    "_gprc.Server",                    /*tp_name*/
-    sizeof(Server),                    /*tp_basicsize*/
-    0,                                 /*tp_itemsize*/
-    (destructor)pygrpc_server_dealloc, /*tp_dealloc*/
-    0,                                 /*tp_print*/
-    0,                                 /*tp_getattr*/
-    0,                                 /*tp_setattr*/
-    0,                                 /*tp_compare*/
-    0,                                 /*tp_repr*/
-    0,                                 /*tp_as_number*/
-    0,                                 /*tp_as_sequence*/
-    0,                                 /*tp_as_mapping*/
-    0,                                 /*tp_hash */
-    0,                                 /*tp_call*/
-    0,                                 /*tp_str*/
-    0,                                 /*tp_getattro*/
-    0,                                 /*tp_setattro*/
-    0,                                 /*tp_as_buffer*/
-    Py_TPFLAGS_DEFAULT,                /*tp_flags*/
-    "Wrapping of grpc_server.",        /* tp_doc */
-    0,                                 /* tp_traverse */
-    0,                                 /* tp_clear */
-    0,                                 /* tp_richcompare */
-    0,                                 /* tp_weaklistoffset */
-    0,                                 /* tp_iter */
-    0,                                 /* tp_iternext */
-    methods,                           /* tp_methods */
-    0,                                 /* tp_members */
-    0,                                 /* tp_getset */
-    0,                                 /* tp_base */
-    0,                                 /* tp_dict */
-    0,                                 /* tp_descr_get */
-    0,                                 /* tp_descr_set */
-    0,                                 /* tp_dictoffset */
-    (initproc)pygrpc_server_init,      /* tp_init */
-    0,                                 /* tp_alloc */
-    PyType_GenericNew,                 /* tp_new */
-};
-
-int pygrpc_add_server(PyObject *module) {
-  if (PyType_Ready(&pygrpc_ServerType) < 0) {
-    return -1;
-  }
-  if (PyModule_AddObject(module, "Server", (PyObject *)&pygrpc_ServerType) ==
-      -1) {
-    return -1;
-  }
-  return 0;
-}
diff --git a/src/python/src/grpc/_adapter/_server.h b/src/python/src/grpc/_adapter/_server.h
deleted file mode 100644
index d31d4e6..0000000
--- a/src/python/src/grpc/_adapter/_server.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- *
- * Copyright 2015, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#ifndef _ADAPTER__SERVER_H_
-#define _ADAPTER__SERVER_H_
-
-#include <Python.h>
-#include <grpc/grpc.h>
-
-#include "grpc/_adapter/_completion_queue.h"
-
-typedef struct {
-  PyObject_HEAD
-
-  CompletionQueue *completion_queue;
-  grpc_server *c_server;
-} Server;
-
-int pygrpc_add_server(PyObject *module);
-
-#endif /* _ADAPTER__SERVER_H_ */
diff --git a/src/python/src/grpc/_adapter/_server_credentials.c b/src/python/src/grpc/_adapter/_server_credentials.c
deleted file mode 100644
index 06e6b94..0000000
--- a/src/python/src/grpc/_adapter/_server_credentials.c
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- *
- * Copyright 2015, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#include "grpc/_adapter/_server_credentials.h"
-
-#include <Python.h>
-#include <grpc/grpc_security.h>
-#include <grpc/support/alloc.h>
-
-static int pygrpc_server_credentials_init(ServerCredentials *self,
-                                          PyObject *args, PyObject *kwds) {
-  char *root_certificates;
-  PyObject *pair_sequence;
-  Py_ssize_t pair_count;
-  grpc_ssl_pem_key_cert_pair *pairs;
-  int error;
-  PyObject *iterator;
-  int i;
-  PyObject *pair;
-  static char *kwlist[] = {"root_credentials", "pair_sequence", NULL};
-
-  if (!PyArg_ParseTupleAndKeywords(args, kwds, "zO:ServerCredentials", kwlist,
-                                   &root_certificates, &pair_sequence)) {
-    return -1;
-  }
-
-  pair_count = PySequence_Length(pair_sequence);
-  if (pair_count == -1) {
-    return -1;
-  }
-
-  iterator = PyObject_GetIter(pair_sequence);
-  if (iterator == NULL) {
-    return -1;
-  }
-  pairs = gpr_malloc(pair_count * sizeof(grpc_ssl_pem_key_cert_pair));
-  error = 0;
-  for (i = 0; i < pair_count; i++) {
-    pair = PyIter_Next(iterator);
-    if (pair == NULL) {
-      error = 1;
-      break;
-    }
-    if (!PyArg_ParseTuple(pair, "ss", &pairs[i].private_key,
-                           &pairs[i].cert_chain)) {
-      error = 1;
-      Py_DECREF(pair);
-      break;
-    }
-    Py_DECREF(pair);
-  }
-  Py_DECREF(iterator);
-
-  if (error) {
-    gpr_free(pairs);
-    return -1;
-  } else {
-    self->c_server_credentials = grpc_ssl_server_credentials_create(
-        root_certificates, pairs, pair_count);
-    gpr_free(pairs);
-    return 0;
-  }
-}
-
-static void pygrpc_server_credentials_dealloc(ServerCredentials *self) {
-  if (self->c_server_credentials != NULL) {
-    grpc_server_credentials_release(self->c_server_credentials);
-  }
-  self->ob_type->tp_free((PyObject *)self);
-}
-
-PyTypeObject pygrpc_ServerCredentialsType = {
-    PyVarObject_HEAD_INIT(NULL, 0)
-    "_grpc.ServerCredencials",                     /*tp_name*/
-    sizeof(ServerCredentials),                     /*tp_basicsize*/
-    0,                                             /*tp_itemsize*/
-    (destructor)pygrpc_server_credentials_dealloc, /*tp_dealloc*/
-    0,                                             /*tp_print*/
-    0,                                             /*tp_getattr*/
-    0,                                             /*tp_setattr*/
-    0,                                             /*tp_compare*/
-    0,                                             /*tp_repr*/
-    0,                                             /*tp_as_number*/
-    0,                                             /*tp_as_sequence*/
-    0,                                             /*tp_as_mapping*/
-    0,                                             /*tp_hash */
-    0,                                             /*tp_call*/
-    0,                                             /*tp_str*/
-    0,                                             /*tp_getattro*/
-    0,                                             /*tp_setattro*/
-    0,                                             /*tp_as_buffer*/
-    Py_TPFLAGS_DEFAULT,                            /*tp_flags*/
-    "Wrapping of grpc_server_credentials.",        /* tp_doc */
-    0,                                             /* tp_traverse */
-    0,                                             /* tp_clear */
-    0,                                             /* tp_richcompare */
-    0,                                             /* tp_weaklistoffset */
-    0,                                             /* tp_iter */
-    0,                                             /* tp_iternext */
-    0,                                             /* tp_methods */
-    0,                                             /* tp_members */
-    0,                                             /* tp_getset */
-    0,                                             /* tp_base */
-    0,                                             /* tp_dict */
-    0,                                             /* tp_descr_get */
-    0,                                             /* tp_descr_set */
-    0,                                             /* tp_dictoffset */
-    (initproc)pygrpc_server_credentials_init,      /* tp_init */
-    0,                                             /* tp_alloc */
-    PyType_GenericNew,                             /* tp_new */
-};
-
-int pygrpc_add_server_credentials(PyObject *module) {
-  if (PyType_Ready(&pygrpc_ServerCredentialsType) < 0) {
-    return -1;
-  }
-  if (PyModule_AddObject(module, "ServerCredentials",
-                         (PyObject *)&pygrpc_ServerCredentialsType) == -1) {
-    return -1;
-  }
-  return 0;
-}
diff --git a/src/python/src/grpc/_adapter/_server_credentials.h b/src/python/src/grpc/_adapter/_server_credentials.h
deleted file mode 100644
index 75af934..0000000
--- a/src/python/src/grpc/_adapter/_server_credentials.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- *
- * Copyright 2015, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#ifndef _ADAPTER__SERVER_CREDENTIALS_H_
-#define _ADAPTER__SERVER_CREDENTIALS_H_
-
-#include <Python.h>
-#include <grpc/grpc_security.h>
-
-typedef struct {
-  PyObject_HEAD
-  grpc_server_credentials *c_server_credentials;
-} ServerCredentials;
-
-extern PyTypeObject pygrpc_ServerCredentialsType;
-
-int pygrpc_add_server_credentials(PyObject *module);
-
-#endif /* _ADAPTER__SERVER_CREDENTIALS_H_ */
diff --git a/src/python/src/grpc/_adapter/_tag.c b/src/python/src/grpc/_adapter/_tag.c
deleted file mode 100644
index 9c6ee19..0000000
--- a/src/python/src/grpc/_adapter/_tag.c
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- *
- * Copyright 2015, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#include "grpc/_adapter/_tag.h"
-
-#include <Python.h>
-#include <grpc/grpc.h>
-#include <grpc/support/alloc.h>
-
-pygrpc_tag *pygrpc_tag_new(pygrpc_tag_type type, PyObject *user_tag,
-                           Call *call) {
-  pygrpc_tag *self = (pygrpc_tag *)gpr_malloc(sizeof(pygrpc_tag));
-  memset(self, 0, sizeof(pygrpc_tag));
-  if (user_tag == NULL) {
-    self->user_tag = Py_None;
-  } else {
-    self->user_tag = user_tag;
-  }
-  Py_INCREF(self->user_tag);
-  self->type = type;
-  self->call = call;
-  Py_INCREF(call);
-  return self;
-}
-
-pygrpc_tag *pygrpc_tag_new_server_rpc_call(PyObject *user_tag) {
-  return pygrpc_tag_new(PYGRPC_SERVER_RPC_NEW, user_tag,
-                        (Call *)pygrpc_CallType.tp_alloc(&pygrpc_CallType, 0));
-}
-
-void pygrpc_tag_destroy(pygrpc_tag *self) {
-  Py_XDECREF(self->user_tag);
-  Py_XDECREF(self->call);
-  gpr_free(self);
-}
diff --git a/src/python/src/grpc/_adapter/_tag.h b/src/python/src/grpc/_adapter/_tag.h
deleted file mode 100644
index 64812aa..0000000
--- a/src/python/src/grpc/_adapter/_tag.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- *
- * Copyright 2015, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#ifndef _ADAPTER__TAG_H_
-#define _ADAPTER__TAG_H_
-
-#include <Python.h>
-#include <grpc/grpc.h>
-
-#include "grpc/_adapter/_call.h"
-#include "grpc/_adapter/_completion_queue.h"
-
-/* grpc_completion_type is becoming meaningless in grpc_event; this is a partial
-   replacement for its descriptive functionality until Python can move its whole
-   C and C adapter stack to more closely resemble the core batching API. */
-typedef enum {
-  PYGRPC_SERVER_RPC_NEW = 0,
-  PYGRPC_INITIAL_METADATA = 1,
-  PYGRPC_READ = 2,
-  PYGRPC_WRITE_ACCEPTED = 3,
-  PYGRPC_FINISH_ACCEPTED = 4,
-  PYGRPC_CLIENT_METADATA_READ = 5,
-  PYGRPC_FINISHED_CLIENT = 6,
-  PYGRPC_FINISHED_SERVER = 7
-} pygrpc_tag_type;
-
-typedef struct {
-  pygrpc_tag_type type;
-  PyObject *user_tag;
-
-  Call *call;
-} pygrpc_tag;
-
-pygrpc_tag *pygrpc_tag_new(pygrpc_tag_type type, PyObject *user_tag,
-                           Call *call);
-pygrpc_tag *pygrpc_tag_new_server_rpc_call(PyObject *user_tag);
-void pygrpc_tag_destroy(pygrpc_tag *self);
-
-#endif /* _ADAPTER__TAG_H_ */
-
diff --git a/src/python/src/grpc/_adapter/_types.py b/src/python/src/grpc/_adapter/_types.py
new file mode 100644
index 0000000..5ddb177
--- /dev/null
+++ b/src/python/src/grpc/_adapter/_types.py
@@ -0,0 +1,368 @@
+# Copyright 2015, Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import abc
+import collections
+import enum
+
+# TODO(atash): decide whether or not to move these enums to the _c module to
+# force build errors with upstream changes.
+
+class GrpcChannelArgumentKeys(enum.Enum):
+  """Mirrors keys used in grpc_channel_args for GRPC-specific arguments."""
+  SSL_TARGET_NAME_OVERRIDE = 'grpc.ssl_target_name_override'
+
+@enum.unique
+class CallError(enum.IntEnum):
+  """Mirrors grpc_call_error in the C core."""
+  OK                        = 0
+  ERROR                     = 1
+  ERROR_NOT_ON_SERVER       = 2
+  ERROR_NOT_ON_CLIENT       = 3
+  ERROR_ALREADY_ACCEPTED    = 4
+  ERROR_ALREADY_INVOKED     = 5
+  ERROR_NOT_INVOKED         = 6
+  ERROR_ALREADY_FINISHED    = 7
+  ERROR_TOO_MANY_OPERATIONS = 8
+  ERROR_INVALID_FLAGS       = 9
+  ERROR_INVALID_METADATA    = 10
+
+@enum.unique
+class StatusCode(enum.IntEnum):
+  """Mirrors grpc_status_code in the C core."""
+  OK                  = 0
+  CANCELLED           = 1
+  UNKNOWN             = 2
+  INVALID_ARGUMENT    = 3
+  DEADLINE_EXCEEDED   = 4
+  NOT_FOUND           = 5
+  ALREADY_EXISTS      = 6
+  PERMISSION_DENIED   = 7
+  RESOURCE_EXHAUSTED  = 8
+  FAILED_PRECONDITION = 9
+  ABORTED             = 10
+  OUT_OF_RANGE        = 11
+  UNIMPLEMENTED       = 12
+  INTERNAL            = 13
+  UNAVAILABLE         = 14
+  DATA_LOSS           = 15
+  UNAUTHENTICATED     = 16
+
+@enum.unique
+class OpType(enum.IntEnum):
+  """Mirrors grpc_op_type in the C core."""
+  SEND_INITIAL_METADATA   = 0
+  SEND_MESSAGE            = 1
+  SEND_CLOSE_FROM_CLIENT  = 2
+  SEND_STATUS_FROM_SERVER = 3
+  RECV_INITIAL_METADATA   = 4
+  RECV_MESSAGE            = 5
+  RECV_STATUS_ON_CLIENT   = 6
+  RECV_CLOSE_ON_SERVER    = 7
+
+@enum.unique
+class EventType(enum.IntEnum):
+  """Mirrors grpc_completion_type in the C core."""
+  QUEUE_SHUTDOWN  = 0
+  QUEUE_TIMEOUT   = 1  # if seen on the Python side, something went horridly wrong
+  OP_COMPLETE     = 2
+
+class Status(collections.namedtuple(
+    'Status', [
+        'code',
+        'details',
+    ])):
+  """The end status of a GRPC call.
+
+  Attributes:
+    code (StatusCode): ...
+    details (str): ...
+  """
+
+class CallDetails(collections.namedtuple(
+    'CallDetails', [
+        'method',
+        'host',
+        'deadline',
+    ])):
+  """Provides information to the server about the client's call.
+
+  Attributes:
+    method (str): ...
+    host (str): ...
+    deadline (float): ...
+  """
+
+class OpArgs(collections.namedtuple(
+    'OpArgs', [
+        'type',
+        'initial_metadata',
+        'trailing_metadata',
+        'message',
+        'status',
+    ])):
+  """Arguments passed into a GRPC operation.
+
+  Attributes:
+    type (OpType): ...
+    initial_metadata (sequence of 2-sequence of str): Only valid if type ==
+      OpType.SEND_INITIAL_METADATA, else is None.
+    trailing_metadata (sequence of 2-sequence of str): Only valid if type ==
+      OpType.SEND_STATUS_FROM_SERVER, else is None.
+    message (bytes): Only valid if type == OpType.SEND_MESSAGE, else is None.
+    status (Status): Only valid if type == OpType.SEND_STATUS_FROM_SERVER, else
+      is None.
+  """
+
+  @staticmethod
+  def send_initial_metadata(initial_metadata):
+    return OpArgs(OpType.SEND_INITIAL_METADATA, initial_metadata, None, None, None)
+
+  @staticmethod
+  def send_message(message):
+    return OpArgs(OpType.SEND_MESSAGE, None, None, message, None)
+
+  @staticmethod
+  def send_close_from_client():
+    return OpArgs(OpType.SEND_CLOSE_FROM_CLIENT, None, None, None, None)
+
+  @staticmethod
+  def send_status_from_server(trailing_metadata, status_code, status_details):
+    return OpArgs(OpType.SEND_STATUS_FROM_SERVER, None, trailing_metadata, None, Status(status_code, status_details))
+
+  @staticmethod
+  def recv_initial_metadata():
+    return OpArgs(OpType.RECV_INITIAL_METADATA, None, None, None, None);
+
+  @staticmethod
+  def recv_message():
+    return OpArgs(OpType.RECV_MESSAGE, None, None, None, None)
+
+  @staticmethod
+  def recv_status_on_client():
+    return OpArgs(OpType.RECV_STATUS_ON_CLIENT, None, None, None, None)
+
+  @staticmethod
+  def recv_close_on_server():
+    return OpArgs(OpType.RECV_CLOSE_ON_SERVER, None, None, None, None)
+
+
+class OpResult(collections.namedtuple(
+    'OpResult', [
+        'type',
+        'initial_metadata',
+        'trailing_metadata',
+        'message',
+        'status',
+        'cancelled',
+    ])):
+  """Results received from a GRPC operation.
+
+  Attributes:
+    type (OpType): ...
+    initial_metadata (sequence of 2-sequence of str): Only valid if type ==
+      OpType.RECV_INITIAL_METADATA, else is None.
+    trailing_metadata (sequence of 2-sequence of str): Only valid if type ==
+      OpType.RECV_STATUS_ON_CLIENT, else is None.
+    message (bytes): Only valid if type == OpType.RECV_MESSAGE, else is None.
+    status (Status): Only valid if type == OpType.RECV_STATUS_ON_CLIENT, else
+      is None.
+    cancelled (bool): Only valid if type == OpType.RECV_CLOSE_ON_SERVER, else
+      is None.
+  """
+
+
+class Event(collections.namedtuple(
+    'Event', [
+        'type',
+        'tag',
+        'call',
+        'call_details',
+        'results',
+        'success',
+    ])):
+  """An event received from a GRPC completion queue.
+
+  Attributes:
+    type (EventType): ...
+    tag (object): ...
+    call (Call): The Call object associated with this event (if there is one,
+      else None).
+    call_details (CallDetails): The call details associated with the
+      server-side call (if there is such information, else None).
+    results (list of OpResult): ...
+    success (bool): ...
+  """
+
+
+class CompletionQueue:
+  __metaclass__ = abc.ABCMeta
+
+  @abc.abstractmethod
+  def __init__(self):
+    pass
+
+  def __iter__(self):
+    """This class may be iterated over.
+
+    This is the equivalent of calling next() repeatedly with an absolute
+    deadline of None (i.e. no deadline).
+    """
+    return self
+
+  @abc.abstractmethod
+  def next(self, deadline=float('+inf')):
+    """Get the next event on this completion queue.
+
+    Args:
+      deadline (float): absolute deadline in seconds from the Python epoch, or
+        None for no deadline.
+
+    Returns:
+      Event: ...
+    """
+    pass
+
+  @abc.abstractmethod
+  def shutdown(self):
+    """Begin the shutdown process of this completion queue.
+
+    Note that this does not immediately destroy the completion queue.
+    Nevertheless, user code should not pass it around after invoking this.
+    """
+    return None
+
+
+class Call:
+  __metaclass__ = abc.ABCMeta
+
+  @abc.abstractmethod
+  def start_batch(self, ops, tag):
+    """Start a batch of operations.
+
+    Args:
+      ops (sequence of OpArgs): ...
+      tag (object): ...
+
+    Returns:
+      CallError: ...
+    """
+    return CallError.ERROR
+
+  @abc.abstractmethod
+  def cancel(self, code=None, details=None):
+    """Cancel the call.
+
+    Args:
+      code (int): Status code to cancel with (on the server side). If
+        specified, so must `details`.
+      details (str): Status details to cancel with (on the server side). If
+        specified, so must `code`.
+
+    Returns:
+      CallError: ...
+    """
+    return CallError.ERROR
+
+
+class Channel:
+  __metaclass__ = abc.ABCMeta
+
+  @abc.abstractmethod
+  def __init__(self, target, args, credentials=None):
+    """Initialize a Channel.
+
+    Args:
+      target (str): ...
+      args (sequence of 2-sequence of str, (str|integer)): ...
+      credentials (ClientCredentials): If None, create an insecure channel,
+        else create a secure channel using the client credentials.
+    """
+
+  @abc.abstractmethod
+  def create_call(self, completion_queue, method, host, deadline=float('+inf')):
+    """Create a call from this channel.
+
+    Args:
+      completion_queue (CompletionQueue): ...
+      method (str): ...
+      host (str): ...
+      deadline (float): absolute deadline in seconds from the Python epoch, or
+        None for no deadline.
+
+    Returns:
+      Call: call object associated with this Channel and passed parameters.
+    """
+    return None
+
+
+class Server:
+  __metaclass__ = abc.ABCMeta
+
+  @abc.abstractmethod
+  def __init__(self, completion_queue, args):
+    """Initialize a server.
+
+    Args:
+      completion_queue (CompletionQueue): ...
+      args (sequence of 2-sequence of str, (str|integer)): ...
+    """
+
+  @abc.abstractmethod
+  def add_http2_port(self, address, credentials=None):
+    """Adds an HTTP/2 address+port to the server.
+
+    Args:
+      address (str): ...
+      credentials (ServerCredentials): If None, create an insecure port, else
+        create a secure port using the server credentials.
+    """
+
+  @abc.abstractmethod
+  def start(self):
+    """Starts the server."""
+
+  @abc.abstractmethod
+  def shutdown(self, tag=None):
+    """Shuts down the server. Does not immediately destroy the server.
+
+    Args:
+      tag (object): if not None, have the server place an event on its
+        completion queue notifying it when this server has completely shut down.
+    """
+
+  @abc.abstractmethod
+  def request_call(self, completion_queue, tag):
+    """Requests a call from the server on the server's completion queue.
+
+    Args:
+      completion_queue (CompletionQueue): Completion queue for the call. May be
+        the same as the server's completion queue.
+      tag (object) ...
+    """
diff --git a/src/python/src/grpc/_adapter/fore.py b/src/python/src/grpc/_adapter/fore.py
index 69e145e..7d88bda 100644
--- a/src/python/src/grpc/_adapter/fore.py
+++ b/src/python/src/grpc/_adapter/fore.py
@@ -35,7 +35,7 @@
 import time
 
 from grpc._adapter import _common
-from grpc._adapter import _low
+from grpc._adapter import _intermediary_low as _low
 from grpc.framework.base import interfaces as base_interfaces
 from grpc.framework.base import null
 from grpc.framework.foundation import activated
@@ -204,7 +204,7 @@
           call, sequence_number,
           base_interfaces.FrontToBackTicket.Kind.CANCELLATION, None, None,
           None, None, None)
-    elif code is _low.Code.EXPIRED:
+    elif code is _low.Code.DEADLINE_EXCEEDED:
       ticket = base_interfaces.FrontToBackTicket(
           call, sequence_number,
           base_interfaces.FrontToBackTicket.Kind.EXPIRATION, None, None, None,
diff --git a/src/python/src/grpc/_adapter/rear.py b/src/python/src/grpc/_adapter/rear.py
index b3b0b4e..fd6f45f 100644
--- a/src/python/src/grpc/_adapter/rear.py
+++ b/src/python/src/grpc/_adapter/rear.py
@@ -35,7 +35,7 @@
 import time
 
 from grpc._adapter import _common
-from grpc._adapter import _low
+from grpc._adapter import _intermediary_low as _low
 from grpc.framework.base import interfaces as base_interfaces
 from grpc.framework.base import null
 from grpc.framework.foundation import activated
@@ -195,7 +195,7 @@
       kind = base_interfaces.BackToFrontTicket.Kind.COMPLETION
     elif event.status.code is _low.Code.CANCELLED:
       kind = base_interfaces.BackToFrontTicket.Kind.CANCELLATION
-    elif event.status.code is _low.Code.EXPIRED:
+    elif event.status.code is _low.Code.DEADLINE_EXCEEDED:
       kind = base_interfaces.BackToFrontTicket.Kind.EXPIRATION
     else:
       kind = base_interfaces.BackToFrontTicket.Kind.TRANSMISSION_FAILURE
diff --git a/src/python/src/setup.py b/src/python/src/setup.py
index d0f4791..dc655a7 100644
--- a/src/python/src/setup.py
+++ b/src/python/src/setup.py
@@ -34,15 +34,15 @@
 import sys
 
 _EXTENSION_SOURCES = (
-    'grpc/_adapter/_c.c',
-    'grpc/_adapter/_call.c',
-    'grpc/_adapter/_channel.c',
-    'grpc/_adapter/_completion_queue.c',
-    'grpc/_adapter/_error.c',
-    'grpc/_adapter/_server.c',
-    'grpc/_adapter/_client_credentials.c',
-    'grpc/_adapter/_server_credentials.c',
-    'grpc/_adapter/_tag.c'
+    'grpc/_adapter/_c/module.c',
+    'grpc/_adapter/_c/types.c',
+    'grpc/_adapter/_c/utility.c',
+    'grpc/_adapter/_c/types/client_credentials.c',
+    'grpc/_adapter/_c/types/server_credentials.c',
+    'grpc/_adapter/_c/types/completion_queue.c',
+    'grpc/_adapter/_c/types/call.c',
+    'grpc/_adapter/_c/types/channel.c',
+    'grpc/_adapter/_c/types/server.c',
 )
 
 _EXTENSION_INCLUDE_DIRECTORIES = (
diff --git a/test/core/security/auth_context_test.c b/test/core/security/auth_context_test.c
index 54548bf..2fb0c01 100644
--- a/test/core/security/auth_context_test.c
+++ b/test/core/security/auth_context_test.c
@@ -43,7 +43,7 @@
   grpc_auth_context *ctx = grpc_auth_context_create(NULL, 0);
   grpc_auth_property_iterator it;
 
-  gpr_log(GPR_INFO, __FUNCTION__);
+  gpr_log(GPR_INFO, "test_empty_context");
   GPR_ASSERT(ctx != NULL);
   GPR_ASSERT(grpc_auth_context_peer_identity_property_name(ctx) == NULL);
   it = grpc_auth_context_peer_identity(ctx);
@@ -60,7 +60,7 @@
   grpc_auth_property_iterator it;
   size_t i;
 
-  gpr_log(GPR_INFO, __FUNCTION__);
+  gpr_log(GPR_INFO, "test_simple_context");
   GPR_ASSERT(ctx != NULL);
   GPR_ASSERT(ctx->property_count == 3);
   ctx->properties[0] = grpc_auth_property_init_from_cstring("name", "chapi");
@@ -95,7 +95,7 @@
   grpc_auth_property_iterator it;
   size_t i;
 
-  gpr_log(GPR_INFO, __FUNCTION__);
+  gpr_log(GPR_INFO, "test_chained_context");
   grpc_auth_context_unref(chained);
   chained->properties[0] =
       grpc_auth_property_init_from_cstring("name", "padapo");
diff --git a/test/core/util/test_config.c b/test/core/util/test_config.c
index be69fcf..20ab67e 100644
--- a/test/core/util/test_config.c
+++ b/test/core/util/test_config.c
@@ -50,8 +50,9 @@
 
 void grpc_test_init(int argc, char **argv) {
   gpr_log(GPR_DEBUG, "test slowdown: machine=%f build=%f total=%f",
-          GRPC_TEST_SLOWDOWN_MACHINE_FACTOR, GRPC_TEST_SLOWDOWN_BUILD_FACTOR,
-          GRPC_TEST_SLOWDOWN_FACTOR);
+          (double)GRPC_TEST_SLOWDOWN_MACHINE_FACTOR,
+          (double)GRPC_TEST_SLOWDOWN_BUILD_FACTOR,
+          (double)GRPC_TEST_SLOWDOWN_FACTOR);
   /* seed rng with pid, so we don't end up with the same random numbers as a
      concurrently running test binary */
   srand(seed());
diff --git a/tools/doxygen/Doxyfile.core b/tools/doxygen/Doxyfile.core
index 7eab680..af372a1 100644
--- a/tools/doxygen/Doxyfile.core
+++ b/tools/doxygen/Doxyfile.core
@@ -760,7 +760,7 @@
 # spaces.
 # Note: If this tag is empty the current directory is searched.
 
-INPUT                  = include/grpc/grpc_security.h include/grpc/byte_buffer.h include/grpc/byte_buffer_reader.h include/grpc/grpc.h include/grpc/status.h include/grpc/support/alloc.h include/grpc/support/atm.h include/grpc/support/atm_gcc_atomic.h include/grpc/support/atm_gcc_sync.h include/grpc/support/atm_win32.h include/grpc/support/cancellable_platform.h include/grpc/support/cmdline.h include/grpc/support/cpu.h include/grpc/support/histogram.h include/grpc/support/host_port.h include/grpc/support/log.h include/grpc/support/log_win32.h include/grpc/support/port_platform.h include/grpc/support/slice.h include/grpc/support/slice_buffer.h include/grpc/support/subprocess.h include/grpc/support/sync.h include/grpc/support/sync_generic.h include/grpc/support/sync_posix.h include/grpc/support/sync_win32.h include/grpc/support/thd.h include/grpc/support/time.h include/grpc/support/tls.h include/grpc/support/tls_gcc.h include/grpc/support/tls_msvc.h include/grpc/support/tls_pthread.h include/grpc/support/useful.h
+INPUT                  = include/grpc/grpc_security.h include/grpc/byte_buffer.h include/grpc/byte_buffer_reader.h include/grpc/grpc.h include/grpc/status.h include/grpc/census.h include/grpc/support/alloc.h include/grpc/support/atm.h include/grpc/support/atm_gcc_atomic.h include/grpc/support/atm_gcc_sync.h include/grpc/support/atm_win32.h include/grpc/support/cancellable_platform.h include/grpc/support/cmdline.h include/grpc/support/cpu.h include/grpc/support/histogram.h include/grpc/support/host_port.h include/grpc/support/log.h include/grpc/support/log_win32.h include/grpc/support/port_platform.h include/grpc/support/slice.h include/grpc/support/slice_buffer.h include/grpc/support/subprocess.h include/grpc/support/sync.h include/grpc/support/sync_generic.h include/grpc/support/sync_posix.h include/grpc/support/sync_win32.h include/grpc/support/thd.h include/grpc/support/time.h include/grpc/support/tls.h include/grpc/support/tls_gcc.h include/grpc/support/tls_msvc.h include/grpc/support/tls_pthread.h include/grpc/support/useful.h
 
 # This tag can be used to specify the character encoding of the source files
 # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal
index 93e922d..c344f2e 100644
--- a/tools/doxygen/Doxyfile.core.internal
+++ b/tools/doxygen/Doxyfile.core.internal
@@ -760,7 +760,7 @@
 # spaces.
 # Note: If this tag is empty the current directory is searched.
 
-INPUT                  = include/grpc/grpc_security.h include/grpc/byte_buffer.h include/grpc/byte_buffer_reader.h include/grpc/grpc.h include/grpc/status.h src/core/httpcli/format_request.h src/core/httpcli/httpcli.h src/core/httpcli/httpcli_security_connector.h src/core/httpcli/parser.h src/core/security/auth_filters.h src/core/security/base64.h src/core/security/credentials.h src/core/security/json_token.h src/core/security/secure_endpoint.h src/core/security/secure_transport_setup.h src/core/security/security_connector.h src/core/security/security_context.h src/core/tsi/fake_transport_security.h src/core/tsi/ssl_transport_security.h src/core/tsi/transport_security.h src/core/tsi/transport_security_interface.h src/core/channel/census_filter.h src/core/channel/channel_args.h src/core/channel/channel_stack.h src/core/channel/child_channel.h src/core/channel/client_channel.h src/core/channel/client_setup.h src/core/channel/connected_channel.h src/core/channel/http_client_filter.h src/core/channel/http_server_filter.h src/core/channel/noop_filter.h src/core/compression/algorithm.h src/core/compression/message_compress.h src/core/debug/trace.h src/core/iomgr/alarm.h src/core/iomgr/alarm_heap.h src/core/iomgr/alarm_internal.h src/core/iomgr/endpoint.h src/core/iomgr/endpoint_pair.h src/core/iomgr/fd_posix.h src/core/iomgr/iocp_windows.h src/core/iomgr/iomgr.h src/core/iomgr/iomgr_internal.h src/core/iomgr/iomgr_posix.h src/core/iomgr/pollset.h src/core/iomgr/pollset_kick.h src/core/iomgr/pollset_kick_posix.h src/core/iomgr/pollset_kick_windows.h src/core/iomgr/pollset_posix.h src/core/iomgr/pollset_windows.h src/core/iomgr/resolve_address.h src/core/iomgr/sockaddr.h src/core/iomgr/sockaddr_posix.h src/core/iomgr/sockaddr_utils.h src/core/iomgr/sockaddr_win32.h src/core/iomgr/socket_utils_posix.h src/core/iomgr/socket_windows.h src/core/iomgr/tcp_client.h src/core/iomgr/tcp_posix.h src/core/iomgr/tcp_server.h src/core/iomgr/tcp_windows.h src/core/iomgr/time_averaged_stats.h src/core/iomgr/wakeup_fd_pipe.h src/core/iomgr/wakeup_fd_posix.h src/core/json/json.h src/core/json/json_common.h src/core/json/json_reader.h src/core/json/json_writer.h src/core/profiling/timers.h src/core/profiling/timers_preciseclock.h 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/byte_buffer_queue.h src/core/surface/call.h src/core/surface/channel.h src/core/surface/client.h src/core/surface/completion_queue.h src/core/surface/event_string.h src/core/surface/init.h src/core/surface/server.h src/core/surface/surface_trace.h src/core/transport/chttp2/alpn.h src/core/transport/chttp2/bin_encoder.h src/core/transport/chttp2/frame.h src/core/transport/chttp2/frame_data.h src/core/transport/chttp2/frame_goaway.h src/core/transport/chttp2/frame_ping.h src/core/transport/chttp2/frame_rst_stream.h src/core/transport/chttp2/frame_settings.h src/core/transport/chttp2/frame_window_update.h src/core/transport/chttp2/hpack_parser.h src/core/transport/chttp2/hpack_table.h src/core/transport/chttp2/http2_errors.h src/core/transport/chttp2/huffsyms.h src/core/transport/chttp2/status_conversion.h src/core/transport/chttp2/stream_encoder.h src/core/transport/chttp2/stream_map.h src/core/transport/chttp2/timeout_encoding.h src/core/transport/chttp2/varint.h src/core/transport/chttp2_transport.h src/core/transport/metadata.h src/core/transport/stream_op.h src/core/transport/transport.h src/core/transport/transport_impl.h src/core/httpcli/format_request.c src/core/httpcli/httpcli.c src/core/httpcli/httpcli_security_connector.c src/core/httpcli/parser.c src/core/security/base64.c src/core/security/client_auth_filter.c src/core/security/credentials.c src/core/security/credentials_metadata.c src/core/security/credentials_posix.c src/core/security/credentials_win32.c src/core/security/google_default_credentials.c src/core/security/json_token.c src/core/security/secure_endpoint.c src/core/security/secure_transport_setup.c src/core/security/security_connector.c src/core/security/security_context.c src/core/security/server_auth_filter.c src/core/security/server_secure_chttp2.c src/core/surface/init_secure.c src/core/surface/secure_channel_create.c src/core/tsi/fake_transport_security.c src/core/tsi/ssl_transport_security.c src/core/tsi/transport_security.c src/core/channel/census_filter.c src/core/channel/channel_args.c src/core/channel/channel_stack.c src/core/channel/child_channel.c src/core/channel/client_channel.c src/core/channel/client_setup.c src/core/channel/connected_channel.c src/core/channel/http_client_filter.c src/core/channel/http_server_filter.c src/core/channel/noop_filter.c src/core/compression/algorithm.c src/core/compression/message_compress.c src/core/debug/trace.c src/core/iomgr/alarm.c src/core/iomgr/alarm_heap.c src/core/iomgr/endpoint.c src/core/iomgr/endpoint_pair_posix.c src/core/iomgr/endpoint_pair_windows.c src/core/iomgr/fd_posix.c src/core/iomgr/iocp_windows.c src/core/iomgr/iomgr.c src/core/iomgr/iomgr_posix.c src/core/iomgr/iomgr_windows.c src/core/iomgr/pollset_kick.c src/core/iomgr/pollset_multipoller_with_epoll.c src/core/iomgr/pollset_multipoller_with_poll_posix.c src/core/iomgr/pollset_posix.c src/core/iomgr/pollset_windows.c src/core/iomgr/resolve_address_posix.c src/core/iomgr/resolve_address_windows.c src/core/iomgr/sockaddr_utils.c src/core/iomgr/socket_utils_common_posix.c src/core/iomgr/socket_utils_linux.c src/core/iomgr/socket_utils_posix.c src/core/iomgr/socket_windows.c src/core/iomgr/tcp_client_posix.c src/core/iomgr/tcp_client_windows.c src/core/iomgr/tcp_posix.c src/core/iomgr/tcp_server_posix.c src/core/iomgr/tcp_server_windows.c src/core/iomgr/tcp_windows.c src/core/iomgr/time_averaged_stats.c src/core/iomgr/wakeup_fd_eventfd.c src/core/iomgr/wakeup_fd_nospecial.c src/core/iomgr/wakeup_fd_pipe.c src/core/iomgr/wakeup_fd_posix.c src/core/json/json.c src/core/json/json_reader.c src/core/json/json_string.c src/core/json/json_writer.c src/core/profiling/basic_timers.c src/core/profiling/stap_timers.c src/core/statistics/census_init.c src/core/statistics/census_log.c src/core/statistics/census_rpc_stats.c src/core/statistics/census_tracing.c src/core/statistics/hash_table.c src/core/statistics/window_stats.c src/core/surface/byte_buffer.c src/core/surface/byte_buffer_queue.c src/core/surface/byte_buffer_reader.c src/core/surface/call.c src/core/surface/call_details.c src/core/surface/call_log_batch.c src/core/surface/channel.c src/core/surface/channel_create.c src/core/surface/client.c src/core/surface/completion_queue.c src/core/surface/event_string.c src/core/surface/init.c src/core/surface/lame_client.c src/core/surface/metadata_array.c src/core/surface/server.c src/core/surface/server_chttp2.c src/core/surface/server_create.c src/core/surface/surface_trace.c src/core/transport/chttp2/alpn.c src/core/transport/chttp2/bin_encoder.c src/core/transport/chttp2/frame_data.c src/core/transport/chttp2/frame_goaway.c src/core/transport/chttp2/frame_ping.c src/core/transport/chttp2/frame_rst_stream.c src/core/transport/chttp2/frame_settings.c src/core/transport/chttp2/frame_window_update.c src/core/transport/chttp2/hpack_parser.c src/core/transport/chttp2/hpack_table.c src/core/transport/chttp2/huffsyms.c src/core/transport/chttp2/status_conversion.c src/core/transport/chttp2/stream_encoder.c src/core/transport/chttp2/stream_map.c src/core/transport/chttp2/timeout_encoding.c src/core/transport/chttp2/varint.c src/core/transport/chttp2_transport.c src/core/transport/metadata.c src/core/transport/stream_op.c src/core/transport/transport.c src/core/transport/transport_op_string.c include/grpc/support/alloc.h include/grpc/support/atm.h include/grpc/support/atm_gcc_atomic.h include/grpc/support/atm_gcc_sync.h include/grpc/support/atm_win32.h include/grpc/support/cancellable_platform.h include/grpc/support/cmdline.h include/grpc/support/cpu.h include/grpc/support/histogram.h include/grpc/support/host_port.h include/grpc/support/log.h include/grpc/support/log_win32.h include/grpc/support/port_platform.h include/grpc/support/slice.h include/grpc/support/slice_buffer.h include/grpc/support/subprocess.h include/grpc/support/sync.h include/grpc/support/sync_generic.h include/grpc/support/sync_posix.h include/grpc/support/sync_win32.h include/grpc/support/thd.h include/grpc/support/time.h include/grpc/support/tls.h include/grpc/support/tls_gcc.h include/grpc/support/tls_msvc.h include/grpc/support/tls_pthread.h include/grpc/support/useful.h src/core/support/env.h src/core/support/file.h src/core/support/murmur_hash.h src/core/support/string.h src/core/support/string_win32.h src/core/support/thd_internal.h src/core/support/alloc.c src/core/support/cancellable.c src/core/support/cmdline.c src/core/support/cpu_iphone.c src/core/support/cpu_linux.c src/core/support/cpu_posix.c src/core/support/cpu_windows.c src/core/support/env_linux.c src/core/support/env_posix.c src/core/support/env_win32.c src/core/support/file.c src/core/support/file_posix.c src/core/support/file_win32.c src/core/support/histogram.c src/core/support/host_port.c src/core/support/log.c src/core/support/log_android.c src/core/support/log_linux.c src/core/support/log_posix.c src/core/support/log_win32.c src/core/support/murmur_hash.c src/core/support/slice.c src/core/support/slice_buffer.c src/core/support/string.c src/core/support/string_posix.c src/core/support/string_win32.c src/core/support/subprocess_posix.c src/core/support/sync.c src/core/support/sync_posix.c src/core/support/sync_win32.c src/core/support/thd.c src/core/support/thd_posix.c src/core/support/thd_win32.c src/core/support/time.c src/core/support/time_posix.c src/core/support/time_win32.c src/core/support/tls_pthread.c
+INPUT                  = include/grpc/grpc_security.h include/grpc/byte_buffer.h include/grpc/byte_buffer_reader.h include/grpc/grpc.h include/grpc/status.h include/grpc/census.h src/core/httpcli/format_request.h src/core/httpcli/httpcli.h src/core/httpcli/httpcli_security_connector.h src/core/httpcli/parser.h src/core/security/auth_filters.h src/core/security/base64.h src/core/security/credentials.h src/core/security/json_token.h src/core/security/secure_endpoint.h src/core/security/secure_transport_setup.h src/core/security/security_connector.h src/core/security/security_context.h src/core/tsi/fake_transport_security.h src/core/tsi/ssl_transport_security.h src/core/tsi/transport_security.h src/core/tsi/transport_security_interface.h src/core/census/grpc_context.h src/core/channel/channel_args.h src/core/channel/channel_stack.h src/core/channel/child_channel.h src/core/channel/client_channel.h src/core/channel/client_setup.h src/core/channel/connected_channel.h src/core/channel/http_client_filter.h src/core/channel/http_server_filter.h src/core/channel/noop_filter.h src/core/compression/algorithm.h src/core/compression/message_compress.h src/core/debug/trace.h src/core/iomgr/alarm.h src/core/iomgr/alarm_heap.h src/core/iomgr/alarm_internal.h src/core/iomgr/endpoint.h src/core/iomgr/endpoint_pair.h src/core/iomgr/fd_posix.h src/core/iomgr/iocp_windows.h src/core/iomgr/iomgr.h src/core/iomgr/iomgr_internal.h src/core/iomgr/iomgr_posix.h src/core/iomgr/pollset.h src/core/iomgr/pollset_kick.h src/core/iomgr/pollset_kick_posix.h src/core/iomgr/pollset_kick_windows.h src/core/iomgr/pollset_posix.h src/core/iomgr/pollset_windows.h src/core/iomgr/resolve_address.h src/core/iomgr/sockaddr.h src/core/iomgr/sockaddr_posix.h src/core/iomgr/sockaddr_utils.h src/core/iomgr/sockaddr_win32.h src/core/iomgr/socket_utils_posix.h src/core/iomgr/socket_windows.h src/core/iomgr/tcp_client.h src/core/iomgr/tcp_posix.h src/core/iomgr/tcp_server.h src/core/iomgr/tcp_windows.h src/core/iomgr/time_averaged_stats.h src/core/iomgr/wakeup_fd_pipe.h src/core/iomgr/wakeup_fd_posix.h src/core/json/json.h src/core/json/json_common.h src/core/json/json_reader.h src/core/json/json_writer.h src/core/profiling/timers.h src/core/profiling/timers_preciseclock.h src/core/surface/byte_buffer_queue.h src/core/surface/call.h src/core/surface/channel.h src/core/surface/client.h src/core/surface/completion_queue.h src/core/surface/event_string.h src/core/surface/init.h src/core/surface/server.h src/core/surface/surface_trace.h src/core/transport/chttp2/alpn.h src/core/transport/chttp2/bin_encoder.h src/core/transport/chttp2/frame.h src/core/transport/chttp2/frame_data.h src/core/transport/chttp2/frame_goaway.h src/core/transport/chttp2/frame_ping.h src/core/transport/chttp2/frame_rst_stream.h src/core/transport/chttp2/frame_settings.h src/core/transport/chttp2/frame_window_update.h src/core/transport/chttp2/hpack_parser.h src/core/transport/chttp2/hpack_table.h src/core/transport/chttp2/http2_errors.h src/core/transport/chttp2/huffsyms.h src/core/transport/chttp2/status_conversion.h src/core/transport/chttp2/stream_encoder.h src/core/transport/chttp2/stream_map.h src/core/transport/chttp2/timeout_encoding.h src/core/transport/chttp2/varint.h src/core/transport/chttp2_transport.h src/core/transport/metadata.h src/core/transport/stream_op.h src/core/transport/transport.h src/core/transport/transport_impl.h src/core/census/context.h src/core/httpcli/format_request.c src/core/httpcli/httpcli.c src/core/httpcli/httpcli_security_connector.c src/core/httpcli/parser.c src/core/security/base64.c src/core/security/client_auth_filter.c src/core/security/credentials.c src/core/security/credentials_metadata.c src/core/security/credentials_posix.c src/core/security/credentials_win32.c src/core/security/google_default_credentials.c src/core/security/json_token.c src/core/security/secure_endpoint.c src/core/security/secure_transport_setup.c src/core/security/security_connector.c src/core/security/security_context.c src/core/security/server_auth_filter.c src/core/security/server_secure_chttp2.c src/core/surface/init_secure.c src/core/surface/secure_channel_create.c src/core/tsi/fake_transport_security.c src/core/tsi/ssl_transport_security.c src/core/tsi/transport_security.c src/core/census/grpc_context.c src/core/channel/channel_args.c src/core/channel/channel_stack.c src/core/channel/child_channel.c src/core/channel/client_channel.c src/core/channel/client_setup.c src/core/channel/connected_channel.c src/core/channel/http_client_filter.c src/core/channel/http_server_filter.c src/core/channel/noop_filter.c src/core/compression/algorithm.c src/core/compression/message_compress.c src/core/debug/trace.c src/core/iomgr/alarm.c src/core/iomgr/alarm_heap.c src/core/iomgr/endpoint.c src/core/iomgr/endpoint_pair_posix.c src/core/iomgr/endpoint_pair_windows.c src/core/iomgr/fd_posix.c src/core/iomgr/iocp_windows.c src/core/iomgr/iomgr.c src/core/iomgr/iomgr_posix.c src/core/iomgr/iomgr_windows.c src/core/iomgr/pollset_kick.c src/core/iomgr/pollset_multipoller_with_epoll.c src/core/iomgr/pollset_multipoller_with_poll_posix.c src/core/iomgr/pollset_posix.c src/core/iomgr/pollset_windows.c src/core/iomgr/resolve_address_posix.c src/core/iomgr/resolve_address_windows.c src/core/iomgr/sockaddr_utils.c src/core/iomgr/socket_utils_common_posix.c src/core/iomgr/socket_utils_linux.c src/core/iomgr/socket_utils_posix.c src/core/iomgr/socket_windows.c src/core/iomgr/tcp_client_posix.c src/core/iomgr/tcp_client_windows.c src/core/iomgr/tcp_posix.c src/core/iomgr/tcp_server_posix.c src/core/iomgr/tcp_server_windows.c src/core/iomgr/tcp_windows.c src/core/iomgr/time_averaged_stats.c src/core/iomgr/wakeup_fd_eventfd.c src/core/iomgr/wakeup_fd_nospecial.c src/core/iomgr/wakeup_fd_pipe.c src/core/iomgr/wakeup_fd_posix.c src/core/json/json.c src/core/json/json_reader.c src/core/json/json_string.c src/core/json/json_writer.c src/core/profiling/basic_timers.c src/core/profiling/stap_timers.c src/core/surface/byte_buffer.c src/core/surface/byte_buffer_queue.c src/core/surface/byte_buffer_reader.c src/core/surface/call.c src/core/surface/call_details.c src/core/surface/call_log_batch.c src/core/surface/channel.c src/core/surface/channel_create.c src/core/surface/client.c src/core/surface/completion_queue.c src/core/surface/event_string.c src/core/surface/init.c src/core/surface/lame_client.c src/core/surface/metadata_array.c src/core/surface/server.c src/core/surface/server_chttp2.c src/core/surface/server_create.c src/core/surface/surface_trace.c src/core/transport/chttp2/alpn.c src/core/transport/chttp2/bin_encoder.c src/core/transport/chttp2/frame_data.c src/core/transport/chttp2/frame_goaway.c src/core/transport/chttp2/frame_ping.c src/core/transport/chttp2/frame_rst_stream.c src/core/transport/chttp2/frame_settings.c src/core/transport/chttp2/frame_window_update.c src/core/transport/chttp2/hpack_parser.c src/core/transport/chttp2/hpack_table.c src/core/transport/chttp2/huffsyms.c src/core/transport/chttp2/status_conversion.c src/core/transport/chttp2/stream_encoder.c src/core/transport/chttp2/stream_map.c src/core/transport/chttp2/timeout_encoding.c src/core/transport/chttp2/varint.c src/core/transport/chttp2_transport.c src/core/transport/metadata.c src/core/transport/stream_op.c src/core/transport/transport.c src/core/transport/transport_op_string.c src/core/census/context.c src/core/census/initialize.c include/grpc/support/alloc.h include/grpc/support/atm.h include/grpc/support/atm_gcc_atomic.h include/grpc/support/atm_gcc_sync.h include/grpc/support/atm_win32.h include/grpc/support/cancellable_platform.h include/grpc/support/cmdline.h include/grpc/support/cpu.h include/grpc/support/histogram.h include/grpc/support/host_port.h include/grpc/support/log.h include/grpc/support/log_win32.h include/grpc/support/port_platform.h include/grpc/support/slice.h include/grpc/support/slice_buffer.h include/grpc/support/subprocess.h include/grpc/support/sync.h include/grpc/support/sync_generic.h include/grpc/support/sync_posix.h include/grpc/support/sync_win32.h include/grpc/support/thd.h include/grpc/support/time.h include/grpc/support/tls.h include/grpc/support/tls_gcc.h include/grpc/support/tls_msvc.h include/grpc/support/tls_pthread.h include/grpc/support/useful.h src/core/support/env.h src/core/support/file.h src/core/support/murmur_hash.h src/core/support/string.h src/core/support/string_win32.h src/core/support/thd_internal.h src/core/support/alloc.c src/core/support/cancellable.c src/core/support/cmdline.c src/core/support/cpu_iphone.c src/core/support/cpu_linux.c src/core/support/cpu_posix.c src/core/support/cpu_windows.c src/core/support/env_linux.c src/core/support/env_posix.c src/core/support/env_win32.c src/core/support/file.c src/core/support/file_posix.c src/core/support/file_win32.c src/core/support/histogram.c src/core/support/host_port.c src/core/support/log.c src/core/support/log_android.c src/core/support/log_linux.c src/core/support/log_posix.c src/core/support/log_win32.c src/core/support/murmur_hash.c src/core/support/slice.c src/core/support/slice_buffer.c src/core/support/string.c src/core/support/string_posix.c src/core/support/string_win32.c src/core/support/subprocess_posix.c src/core/support/sync.c src/core/support/sync_posix.c src/core/support/sync_win32.c src/core/support/thd.c src/core/support/thd_posix.c src/core/support/thd_win32.c src/core/support/time.c src/core/support/time_posix.c src/core/support/time_win32.c src/core/support/tls_pthread.c
 
 # This tag can be used to specify the character encoding of the source files
 # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
diff --git a/tools/gce_setup/cloud_prod_runner.sh b/tools/gce_setup/cloud_prod_runner.sh
index 576c2b2..4206a66 100755
--- a/tools/gce_setup/cloud_prod_runner.sh
+++ b/tools/gce_setup/cloud_prod_runner.sh
@@ -36,13 +36,18 @@
   source grpc_docker.sh
   test_cases=(large_unary empty_unary ping_pong client_streaming server_streaming cancel_after_begin cancel_after_first_response)
   auth_test_cases=(service_account_creds compute_engine_creds jwt_token_creds)
-  clients=(cxx java go ruby node csharp_mono python php)
+  clients=(cxx java go ruby node csharp_mono csharp_dotnet python php)
   for test_case in "${test_cases[@]}"
   do
     for client in "${clients[@]}"
     do
+      client_vm="grpc-docker-testclients"
+      if [ "$client" = "csharp_dotnet" ]
+      then
+        client_vm="grpc-windows-interop1"
+      fi
       log_file_name=cloud_{$test_case}_{$client}.txt 
-      if grpc_cloud_prod_test $test_case grpc-docker-testclients $client > /tmp/$log_file_name 2>&1
+      if grpc_cloud_prod_test $test_case $client_vm $client > /tmp/$log_file_name 2>&1
       then
         echo "          ['$test_case', '$client', 'prod', true, '<a href="$log_link/$log_file_name">log</a>']," >> /tmp/cloud_prod_result.txt
       else
@@ -56,8 +61,13 @@
   do
     for client in "${clients[@]}"
     do
+      client_vm="grpc-docker-testclients"
+      if [ "$client" = "csharp_dotnet" ]
+      then
+        client_vm="grpc-windows-interop1"
+      fi
       log_file_name=cloud_{$test_case}_{$client}.txt 
-      if grpc_cloud_prod_auth_test $test_case grpc-docker-testclients $client > /tmp/$log_file_name 2>&1
+      if grpc_cloud_prod_auth_test $test_case $client_vm $client > /tmp/$log_file_name 2>&1
       then
         echo "          ['$test_case', '$client', 'prod', true, '<a href="$log_link/$log_file_name">log</a>']," >> /tmp/cloud_prod_result.txt
       else
diff --git a/tools/gce_setup/interop_test.sh b/tools/gce_setup/interop_test.sh
index d6e5fce..0b5be6a 100755
--- a/tools/gce_setup/interop_test.sh
+++ b/tools/gce_setup/interop_test.sh
@@ -38,14 +38,24 @@
 
 main() {
   source grpc_docker.sh
-  clients=(cxx java go ruby node csharp_mono python php)
-  servers=(cxx java go ruby node python csharp_mono)
+  clients=(cxx java go ruby node csharp_mono csharp_dotnet python php)
+  servers=(cxx java go ruby node csharp_mono csharp_dotnet python csharp_mono)
   for client in "${clients[@]}"
   do
+    client_vm_test=$client_vm
+    if [ "$client" = "csharp_dotnet" ]
+    then
+      client_vm_test="grpc-windows-interop1"
+    fi
     for server in "${servers[@]}"
     do
       log_file_name=cloud_{$test_case}_{$client}_{$server}.txt 
-      if grpc_interop_test $test_case $client_vm $client $server_vm $server> /tmp/$log_file_name 2>&1
+      server_vm_test=$server_vm
+      if [ "$server" = "csharp_dotnet" ]
+      then
+        server_vm_test="grpc-windows-interop1"
+      fi
+      if grpc_interop_test $test_case $client_vm_test $client $server_vm_test $server> /tmp/$log_file_name 2>&1
       then
         echo "          ['$test_case', '$client', '$server', true, '<a href="$log_link/$log_file_name">log</a>']," >> /tmp/$result.txt
       else
diff --git a/tools/run_tests/jobset.py b/tools/run_tests/jobset.py
index e2b03bd..51d61db 100755
--- a/tools/run_tests/jobset.py
+++ b/tools/run_tests/jobset.py
@@ -66,6 +66,7 @@
   # p as we take elements - this gives us a somewhat random set of values before
   # we've seen all the values, but starts producing values without having to
   # compute ALL of them at once, allowing tests to start a little earlier
+  LARGE_THRESHOLD = 1000
   nextit = []
   p = 1
   for val in it:
@@ -74,6 +75,17 @@
       yield val
     else:
       nextit.append(val)
+      # if the input iterates over a large number of values (potentially
+      # infinite, we'd be in the loop for a while (again, potentially forever).
+      # We need to reset "nextit" every so often to, in the case of an infinite
+      # iterator, avoid growing "nextit" without ever freeing it.
+      if len(nextit) > LARGE_THRESHOLD:
+        random.shuffle(nextit)
+        for val in nextit:
+          yield val
+        nextit = []
+        p = 1
+
   # after taking a random sampling, we shuffle the rest of the elements and
   # yield them
   random.shuffle(nextit)
@@ -339,13 +351,15 @@
         maxjobs=None,
         newline_on_success=False,
         travis=False,
+        infinite_runs=False,
         stop_on_failure=False,
         cache=None):
   js = Jobset(check_cancelled,
               maxjobs if maxjobs is not None else _DEFAULT_MAX_JOBS,
               newline_on_success, travis, stop_on_failure,
               cache if cache is not None else NoCache())
-  if not travis:
+  # We can't sort an infinite sequence of runs.
+  if not travis or infinite_runs:
     cmdlines = shuffle_iteratable(cmdlines)
   else:
     cmdlines = sorted(cmdlines, key=lambda x: x.shortname)
diff --git a/tools/run_tests/python_tests.json b/tools/run_tests/python_tests.json
index dff0537..6c969d7 100755
--- a/tools/run_tests/python_tests.json
+++ b/tools/run_tests/python_tests.json
@@ -1,18 +1,12 @@
 [
   {
-    "file": "test/compiler/python_plugin_test.py"
-  },
-  {
-    "module": "grpc._adapter._blocking_invocation_inline_service_test"
-  },
-  {
     "module": "grpc._adapter._c_test"
   },
   {
-    "module": "grpc._adapter._event_invocation_synchronous_event_service_test"
+    "module": "grpc._adapter._low_test"
   },
   {
-    "module": "grpc._adapter._future_invocation_asynchronous_event_service_test"
+    "module": "grpc._adapter._intermediary_low_test"
   },
   {
     "module": "grpc._adapter._links_test"
@@ -21,7 +15,13 @@
     "module": "grpc._adapter._lonely_rear_link_test"
   },
   {
-    "module": "grpc._adapter._low_test"
+    "module": "grpc._adapter._blocking_invocation_inline_service_test"
+  },
+  {
+    "module": "grpc._adapter._event_invocation_synchronous_event_service_test"
+  },
+  {
+    "module": "grpc._adapter._future_invocation_asynchronous_event_service_test"
   },
   {
     "module": "grpc.early_adopter.implementations_test"
@@ -49,5 +49,8 @@
   },
   {
     "module": "interop._secure_interop_test"
+  },
+  {
+    "file": "test/compiler/python_plugin_test.py"
   }
 ]
diff --git a/tools/run_tests/run_tests.py b/tools/run_tests/run_tests.py
index 602edc7..bd5959c 100755
--- a/tools/run_tests/run_tests.py
+++ b/tools/run_tests/run_tests.py
@@ -149,7 +149,7 @@
                             environ={'GRPC_TRACE': 'surface,batch'})]
 
   def make_targets(self):
-    return ['static_c']
+    return ['static_c', 'shared_c']
 
   def build_steps(self):
     return [['tools/run_tests/build_node.sh']]
@@ -168,7 +168,7 @@
                             environ={'GRPC_TRACE': 'surface,batch'})]
 
   def make_targets(self):
-    return ['static_c']
+    return ['static_c', 'shared_c']
 
   def build_steps(self):
     return [['tools/run_tests/build_php.sh']]
@@ -202,7 +202,7 @@
     return files + modules
 
   def make_targets(self):
-    return ['static_c', 'grpc_python_plugin']
+    return ['static_c', 'grpc_python_plugin', 'shared_c']
 
   def build_steps(self):
     return [['tools/run_tests/build_python.sh']]
@@ -330,7 +330,28 @@
                   choices=['all'] + sorted(_CONFIGS.keys()),
                   nargs='+',
                   default=_DEFAULT)
-argp.add_argument('-n', '--runs_per_test', default=1, type=int)
+
+def runs_per_test_type(arg_str):
+    """Auxilary function to parse the "runs_per_test" flag.
+
+       Returns:
+           A positive integer or 0, the latter indicating an infinite number of
+           runs.
+
+       Raises:
+           argparse.ArgumentTypeError: Upon invalid input.
+    """
+    if arg_str == 'inf':
+        return 0
+    try:
+        n = int(arg_str)
+        if n <= 0: raise ValueError
+    except:
+        msg = "'{}' isn't a positive integer or 'inf'".format(arg_str)
+        raise argparse.ArgumentTypeError(msg)
+argp.add_argument('-n', '--runs_per_test', default=1, type=runs_per_test_type,
+        help='A positive integer or "inf". If "inf", all tests will run in an '
+             'infinite loop. Especially useful in combination with "-f"')
 argp.add_argument('-r', '--regex', default='.*', type=str)
 argp.add_argument('-j', '--jobs', default=2 * multiprocessing.cpu_count(), type=int)
 argp.add_argument('-s', '--slowdown', default=1.0, type=float)
@@ -453,11 +474,14 @@
   antagonists = [subprocess.Popen(['tools/run_tests/antagonist.py']) 
                  for _ in range(0, args.antagonists)]
   try:
+    infinite_runs = runs_per_test == 0
     # run all the tests
-    all_runs = itertools.chain.from_iterable(
-        itertools.repeat(one_run, runs_per_test))
+    runs_sequence = (itertools.repeat(one_run) if infinite_runs
+                     else itertools.repeat(one_run, runs_per_test))
+    all_runs = itertools.chain.from_iterable(runs_sequence)
     if not jobset.run(all_runs, check_cancelled,
                       newline_on_success=newline_on_success, travis=travis,
+                      infinite_runs=infinite_runs,
                       maxjobs=args.jobs,
                       stop_on_failure=args.stop_on_failure,
                       cache=cache):
diff --git a/tools/run_tests/tests.json b/tools/run_tests/tests.json
index 2986d0e..4aafdea 100644
--- a/tools/run_tests/tests.json
+++ b/tools/run_tests/tests.json
@@ -49,78 +49,6 @@
   {
     "flaky": false, 
     "language": "c", 
-    "name": "census_hash_table_test", 
-    "platforms": [
-      "windows", 
-      "posix"
-    ]
-  }, 
-  {
-    "flaky": true, 
-    "language": "c", 
-    "name": "census_statistics_multiple_writers_circular_buffer_test", 
-    "platforms": [
-      "windows", 
-      "posix"
-    ]
-  }, 
-  {
-    "flaky": false, 
-    "language": "c", 
-    "name": "census_statistics_multiple_writers_test", 
-    "platforms": [
-      "windows", 
-      "posix"
-    ]
-  }, 
-  {
-    "flaky": false, 
-    "language": "c", 
-    "name": "census_statistics_performance_test", 
-    "platforms": [
-      "windows", 
-      "posix"
-    ]
-  }, 
-  {
-    "flaky": false, 
-    "language": "c", 
-    "name": "census_statistics_quick_test", 
-    "platforms": [
-      "windows", 
-      "posix"
-    ]
-  }, 
-  {
-    "flaky": false, 
-    "language": "c", 
-    "name": "census_statistics_small_log_test", 
-    "platforms": [
-      "windows", 
-      "posix"
-    ]
-  }, 
-  {
-    "flaky": false, 
-    "language": "c", 
-    "name": "census_stub_test", 
-    "platforms": [
-      "windows", 
-      "posix"
-    ]
-  }, 
-  {
-    "flaky": false, 
-    "language": "c", 
-    "name": "census_window_stats_test", 
-    "platforms": [
-      "windows", 
-      "posix"
-    ]
-  }, 
-  {
-    "flaky": false, 
-    "language": "c", 
     "name": "chttp2_status_conversion_test", 
     "platforms": [
       "windows", 
diff --git a/vsprojects/Grpc.mak b/vsprojects/Grpc.mak
index 357f366..15e1184 100644
--- a/vsprojects/Grpc.mak
+++ b/vsprojects/Grpc.mak
@@ -57,7 +57,7 @@
 build_libs: build_gpr build_gpr_test_util build_grpc build_grpc_test_util build_grpc_test_util_unsecure build_grpc_unsecure Debug\end2end_fixture_chttp2_fake_security.lib Debug\end2end_fixture_chttp2_fullstack.lib Debug\end2end_fixture_chttp2_fullstack_with_poll.lib Debug\end2end_fixture_chttp2_simple_ssl_fullstack.lib Debug\end2end_fixture_chttp2_simple_ssl_fullstack_with_poll.lib Debug\end2end_fixture_chttp2_simple_ssl_with_oauth2_fullstack.lib Debug\end2end_fixture_chttp2_socket_pair.lib Debug\end2end_fixture_chttp2_socket_pair_one_byte_at_a_time.lib Debug\end2end_fixture_chttp2_socket_pair_with_grpc_trace.lib Debug\end2end_test_bad_hostname.lib Debug\end2end_test_cancel_after_accept.lib Debug\end2end_test_cancel_after_accept_and_writes_closed.lib Debug\end2end_test_cancel_after_invoke.lib Debug\end2end_test_cancel_before_invoke.lib Debug\end2end_test_cancel_in_a_vacuum.lib Debug\end2end_test_census_simple_request.lib Debug\end2end_test_disappearing_server.lib Debug\end2end_test_early_server_shutdown_finishes_inflight_calls.lib Debug\end2end_test_early_server_shutdown_finishes_tags.lib Debug\end2end_test_empty_batch.lib Debug\end2end_test_graceful_server_shutdown.lib Debug\end2end_test_invoke_large_request.lib Debug\end2end_test_max_concurrent_streams.lib Debug\end2end_test_max_message_length.lib Debug\end2end_test_no_op.lib Debug\end2end_test_ping_pong_streaming.lib Debug\end2end_test_registered_call.lib Debug\end2end_test_request_response_with_binary_metadata_and_payload.lib Debug\end2end_test_request_response_with_metadata_and_payload.lib Debug\end2end_test_request_response_with_payload.lib Debug\end2end_test_request_response_with_payload_and_call_creds.lib Debug\end2end_test_request_response_with_trailing_metadata_and_payload.lib Debug\end2end_test_request_with_large_metadata.lib Debug\end2end_test_request_with_payload.lib Debug\end2end_test_server_finishes_request.lib Debug\end2end_test_simple_delayed_request.lib Debug\end2end_test_simple_request.lib Debug\end2end_test_simple_request_with_high_initial_sequence_number.lib Debug\end2end_certs.lib Debug\bad_client_test.lib 
 buildtests: buildtests_c buildtests_cxx
 
-buildtests_c: alarm_heap_test.exe alarm_list_test.exe alarm_test.exe alpn_test.exe bin_encoder_test.exe census_hash_table_test.exe census_statistics_multiple_writers_circular_buffer_test.exe census_statistics_multiple_writers_test.exe census_statistics_performance_test.exe census_statistics_quick_test.exe census_statistics_small_log_test.exe census_stub_test.exe census_window_stats_test.exe chttp2_status_conversion_test.exe chttp2_stream_encoder_test.exe chttp2_stream_map_test.exe fling_client.exe fling_server.exe gpr_cancellable_test.exe gpr_cmdline_test.exe gpr_env_test.exe gpr_file_test.exe gpr_histogram_test.exe gpr_host_port_test.exe gpr_log_test.exe gpr_slice_buffer_test.exe gpr_slice_test.exe gpr_string_test.exe gpr_sync_test.exe gpr_thd_test.exe gpr_time_test.exe gpr_tls_test.exe gpr_useful_test.exe grpc_auth_context_test.exe grpc_base64_test.exe grpc_byte_buffer_reader_test.exe grpc_channel_stack_test.exe grpc_completion_queue_test.exe grpc_credentials_test.exe grpc_json_token_test.exe grpc_stream_op_test.exe hpack_parser_test.exe hpack_table_test.exe httpcli_format_request_test.exe httpcli_parser_test.exe httpcli_test.exe json_rewrite.exe json_rewrite_test.exe json_test.exe lame_client_test.exe message_compress_test.exe multi_init_test.exe murmur_hash_test.exe no_server_test.exe resolve_address_test.exe secure_endpoint_test.exe sockaddr_utils_test.exe time_averaged_stats_test.exe time_test.exe timeout_encoding_test.exe timers_test.exe transport_metadata_test.exe transport_security_test.exe chttp2_fake_security_bad_hostname_test.exe chttp2_fake_security_cancel_after_accept_test.exe chttp2_fake_security_cancel_after_accept_and_writes_closed_test.exe chttp2_fake_security_cancel_after_invoke_test.exe chttp2_fake_security_cancel_before_invoke_test.exe chttp2_fake_security_cancel_in_a_vacuum_test.exe chttp2_fake_security_census_simple_request_test.exe chttp2_fake_security_disappearing_server_test.exe chttp2_fake_security_early_server_shutdown_finishes_inflight_calls_test.exe chttp2_fake_security_early_server_shutdown_finishes_tags_test.exe chttp2_fake_security_empty_batch_test.exe chttp2_fake_security_graceful_server_shutdown_test.exe chttp2_fake_security_invoke_large_request_test.exe chttp2_fake_security_max_concurrent_streams_test.exe chttp2_fake_security_max_message_length_test.exe chttp2_fake_security_no_op_test.exe chttp2_fake_security_ping_pong_streaming_test.exe chttp2_fake_security_registered_call_test.exe chttp2_fake_security_request_response_with_binary_metadata_and_payload_test.exe chttp2_fake_security_request_response_with_metadata_and_payload_test.exe chttp2_fake_security_request_response_with_payload_test.exe chttp2_fake_security_request_response_with_payload_and_call_creds_test.exe chttp2_fake_security_request_response_with_trailing_metadata_and_payload_test.exe chttp2_fake_security_request_with_large_metadata_test.exe chttp2_fake_security_request_with_payload_test.exe chttp2_fake_security_server_finishes_request_test.exe chttp2_fake_security_simple_delayed_request_test.exe chttp2_fake_security_simple_request_test.exe chttp2_fake_security_simple_request_with_high_initial_sequence_number_test.exe chttp2_fullstack_bad_hostname_test.exe chttp2_fullstack_cancel_after_accept_test.exe chttp2_fullstack_cancel_after_accept_and_writes_closed_test.exe chttp2_fullstack_cancel_after_invoke_test.exe chttp2_fullstack_cancel_before_invoke_test.exe chttp2_fullstack_cancel_in_a_vacuum_test.exe chttp2_fullstack_census_simple_request_test.exe chttp2_fullstack_disappearing_server_test.exe chttp2_fullstack_early_server_shutdown_finishes_inflight_calls_test.exe chttp2_fullstack_early_server_shutdown_finishes_tags_test.exe chttp2_fullstack_empty_batch_test.exe chttp2_fullstack_graceful_server_shutdown_test.exe chttp2_fullstack_invoke_large_request_test.exe chttp2_fullstack_max_concurrent_streams_test.exe chttp2_fullstack_max_message_length_test.exe chttp2_fullstack_no_op_test.exe chttp2_fullstack_ping_pong_streaming_test.exe chttp2_fullstack_registered_call_test.exe chttp2_fullstack_request_response_with_binary_metadata_and_payload_test.exe chttp2_fullstack_request_response_with_metadata_and_payload_test.exe chttp2_fullstack_request_response_with_payload_test.exe chttp2_fullstack_request_response_with_payload_and_call_creds_test.exe chttp2_fullstack_request_response_with_trailing_metadata_and_payload_test.exe chttp2_fullstack_request_with_large_metadata_test.exe chttp2_fullstack_request_with_payload_test.exe chttp2_fullstack_server_finishes_request_test.exe chttp2_fullstack_simple_delayed_request_test.exe chttp2_fullstack_simple_request_test.exe chttp2_fullstack_simple_request_with_high_initial_sequence_number_test.exe chttp2_simple_ssl_fullstack_bad_hostname_test.exe chttp2_simple_ssl_fullstack_cancel_after_accept_test.exe chttp2_simple_ssl_fullstack_cancel_after_accept_and_writes_closed_test.exe chttp2_simple_ssl_fullstack_cancel_after_invoke_test.exe chttp2_simple_ssl_fullstack_cancel_before_invoke_test.exe chttp2_simple_ssl_fullstack_cancel_in_a_vacuum_test.exe chttp2_simple_ssl_fullstack_census_simple_request_test.exe chttp2_simple_ssl_fullstack_disappearing_server_test.exe chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_inflight_calls_test.exe chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_tags_test.exe chttp2_simple_ssl_fullstack_empty_batch_test.exe chttp2_simple_ssl_fullstack_graceful_server_shutdown_test.exe chttp2_simple_ssl_fullstack_invoke_large_request_test.exe chttp2_simple_ssl_fullstack_max_concurrent_streams_test.exe chttp2_simple_ssl_fullstack_max_message_length_test.exe chttp2_simple_ssl_fullstack_no_op_test.exe chttp2_simple_ssl_fullstack_ping_pong_streaming_test.exe chttp2_simple_ssl_fullstack_registered_call_test.exe chttp2_simple_ssl_fullstack_request_response_with_binary_metadata_and_payload_test.exe chttp2_simple_ssl_fullstack_request_response_with_metadata_and_payload_test.exe chttp2_simple_ssl_fullstack_request_response_with_payload_test.exe chttp2_simple_ssl_fullstack_request_response_with_payload_and_call_creds_test.exe chttp2_simple_ssl_fullstack_request_response_with_trailing_metadata_and_payload_test.exe chttp2_simple_ssl_fullstack_request_with_large_metadata_test.exe chttp2_simple_ssl_fullstack_request_with_payload_test.exe chttp2_simple_ssl_fullstack_server_finishes_request_test.exe chttp2_simple_ssl_fullstack_simple_delayed_request_test.exe chttp2_simple_ssl_fullstack_simple_request_test.exe chttp2_simple_ssl_fullstack_simple_request_with_high_initial_sequence_number_test.exe chttp2_simple_ssl_with_oauth2_fullstack_bad_hostname_test.exe chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_accept_test.exe chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_accept_and_writes_closed_test.exe chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_invoke_test.exe chttp2_simple_ssl_with_oauth2_fullstack_cancel_before_invoke_test.exe chttp2_simple_ssl_with_oauth2_fullstack_cancel_in_a_vacuum_test.exe chttp2_simple_ssl_with_oauth2_fullstack_census_simple_request_test.exe chttp2_simple_ssl_with_oauth2_fullstack_disappearing_server_test.exe chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_inflight_calls_test.exe chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_tags_test.exe chttp2_simple_ssl_with_oauth2_fullstack_empty_batch_test.exe chttp2_simple_ssl_with_oauth2_fullstack_graceful_server_shutdown_test.exe chttp2_simple_ssl_with_oauth2_fullstack_invoke_large_request_test.exe chttp2_simple_ssl_with_oauth2_fullstack_max_concurrent_streams_test.exe chttp2_simple_ssl_with_oauth2_fullstack_max_message_length_test.exe chttp2_simple_ssl_with_oauth2_fullstack_no_op_test.exe chttp2_simple_ssl_with_oauth2_fullstack_ping_pong_streaming_test.exe chttp2_simple_ssl_with_oauth2_fullstack_registered_call_test.exe chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_binary_metadata_and_payload_test.exe chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_metadata_and_payload_test.exe chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_payload_test.exe chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_payload_and_call_creds_test.exe chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_trailing_metadata_and_payload_test.exe chttp2_simple_ssl_with_oauth2_fullstack_request_with_large_metadata_test.exe chttp2_simple_ssl_with_oauth2_fullstack_request_with_payload_test.exe chttp2_simple_ssl_with_oauth2_fullstack_server_finishes_request_test.exe chttp2_simple_ssl_with_oauth2_fullstack_simple_delayed_request_test.exe chttp2_simple_ssl_with_oauth2_fullstack_simple_request_test.exe chttp2_simple_ssl_with_oauth2_fullstack_simple_request_with_high_initial_sequence_number_test.exe chttp2_socket_pair_bad_hostname_test.exe chttp2_socket_pair_cancel_after_accept_test.exe chttp2_socket_pair_cancel_after_accept_and_writes_closed_test.exe chttp2_socket_pair_cancel_after_invoke_test.exe chttp2_socket_pair_cancel_before_invoke_test.exe chttp2_socket_pair_cancel_in_a_vacuum_test.exe chttp2_socket_pair_census_simple_request_test.exe chttp2_socket_pair_disappearing_server_test.exe chttp2_socket_pair_early_server_shutdown_finishes_inflight_calls_test.exe chttp2_socket_pair_early_server_shutdown_finishes_tags_test.exe chttp2_socket_pair_empty_batch_test.exe chttp2_socket_pair_graceful_server_shutdown_test.exe chttp2_socket_pair_invoke_large_request_test.exe chttp2_socket_pair_max_concurrent_streams_test.exe chttp2_socket_pair_max_message_length_test.exe chttp2_socket_pair_no_op_test.exe chttp2_socket_pair_ping_pong_streaming_test.exe chttp2_socket_pair_registered_call_test.exe chttp2_socket_pair_request_response_with_binary_metadata_and_payload_test.exe chttp2_socket_pair_request_response_with_metadata_and_payload_test.exe chttp2_socket_pair_request_response_with_payload_test.exe chttp2_socket_pair_request_response_with_payload_and_call_creds_test.exe chttp2_socket_pair_request_response_with_trailing_metadata_and_payload_test.exe chttp2_socket_pair_request_with_large_metadata_test.exe chttp2_socket_pair_request_with_payload_test.exe chttp2_socket_pair_server_finishes_request_test.exe chttp2_socket_pair_simple_delayed_request_test.exe chttp2_socket_pair_simple_request_test.exe chttp2_socket_pair_simple_request_with_high_initial_sequence_number_test.exe chttp2_socket_pair_one_byte_at_a_time_bad_hostname_test.exe chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_test.exe chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_and_writes_closed_test.exe chttp2_socket_pair_one_byte_at_a_time_cancel_after_invoke_test.exe chttp2_socket_pair_one_byte_at_a_time_cancel_before_invoke_test.exe chttp2_socket_pair_one_byte_at_a_time_cancel_in_a_vacuum_test.exe chttp2_socket_pair_one_byte_at_a_time_census_simple_request_test.exe chttp2_socket_pair_one_byte_at_a_time_disappearing_server_test.exe chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_inflight_calls_test.exe chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_tags_test.exe chttp2_socket_pair_one_byte_at_a_time_empty_batch_test.exe chttp2_socket_pair_one_byte_at_a_time_graceful_server_shutdown_test.exe chttp2_socket_pair_one_byte_at_a_time_invoke_large_request_test.exe chttp2_socket_pair_one_byte_at_a_time_max_concurrent_streams_test.exe chttp2_socket_pair_one_byte_at_a_time_max_message_length_test.exe chttp2_socket_pair_one_byte_at_a_time_no_op_test.exe chttp2_socket_pair_one_byte_at_a_time_ping_pong_streaming_test.exe chttp2_socket_pair_one_byte_at_a_time_registered_call_test.exe chttp2_socket_pair_one_byte_at_a_time_request_response_with_binary_metadata_and_payload_test.exe chttp2_socket_pair_one_byte_at_a_time_request_response_with_metadata_and_payload_test.exe chttp2_socket_pair_one_byte_at_a_time_request_response_with_payload_test.exe chttp2_socket_pair_one_byte_at_a_time_request_response_with_payload_and_call_creds_test.exe chttp2_socket_pair_one_byte_at_a_time_request_response_with_trailing_metadata_and_payload_test.exe chttp2_socket_pair_one_byte_at_a_time_request_with_large_metadata_test.exe chttp2_socket_pair_one_byte_at_a_time_request_with_payload_test.exe chttp2_socket_pair_one_byte_at_a_time_server_finishes_request_test.exe chttp2_socket_pair_one_byte_at_a_time_simple_delayed_request_test.exe chttp2_socket_pair_one_byte_at_a_time_simple_request_test.exe chttp2_socket_pair_one_byte_at_a_time_simple_request_with_high_initial_sequence_number_test.exe chttp2_socket_pair_with_grpc_trace_bad_hostname_test.exe chttp2_socket_pair_with_grpc_trace_cancel_after_accept_test.exe chttp2_socket_pair_with_grpc_trace_cancel_after_accept_and_writes_closed_test.exe chttp2_socket_pair_with_grpc_trace_cancel_after_invoke_test.exe chttp2_socket_pair_with_grpc_trace_cancel_before_invoke_test.exe chttp2_socket_pair_with_grpc_trace_cancel_in_a_vacuum_test.exe chttp2_socket_pair_with_grpc_trace_census_simple_request_test.exe chttp2_socket_pair_with_grpc_trace_disappearing_server_test.exe chttp2_socket_pair_with_grpc_trace_early_server_shutdown_finishes_inflight_calls_test.exe chttp2_socket_pair_with_grpc_trace_early_server_shutdown_finishes_tags_test.exe chttp2_socket_pair_with_grpc_trace_empty_batch_test.exe chttp2_socket_pair_with_grpc_trace_graceful_server_shutdown_test.exe chttp2_socket_pair_with_grpc_trace_invoke_large_request_test.exe chttp2_socket_pair_with_grpc_trace_max_concurrent_streams_test.exe chttp2_socket_pair_with_grpc_trace_max_message_length_test.exe chttp2_socket_pair_with_grpc_trace_no_op_test.exe chttp2_socket_pair_with_grpc_trace_ping_pong_streaming_test.exe chttp2_socket_pair_with_grpc_trace_registered_call_test.exe chttp2_socket_pair_with_grpc_trace_request_response_with_binary_metadata_and_payload_test.exe chttp2_socket_pair_with_grpc_trace_request_response_with_metadata_and_payload_test.exe chttp2_socket_pair_with_grpc_trace_request_response_with_payload_test.exe chttp2_socket_pair_with_grpc_trace_request_response_with_payload_and_call_creds_test.exe chttp2_socket_pair_with_grpc_trace_request_response_with_trailing_metadata_and_payload_test.exe chttp2_socket_pair_with_grpc_trace_request_with_large_metadata_test.exe chttp2_socket_pair_with_grpc_trace_request_with_payload_test.exe chttp2_socket_pair_with_grpc_trace_server_finishes_request_test.exe chttp2_socket_pair_with_grpc_trace_simple_delayed_request_test.exe chttp2_socket_pair_with_grpc_trace_simple_request_test.exe chttp2_socket_pair_with_grpc_trace_simple_request_with_high_initial_sequence_number_test.exe chttp2_fullstack_bad_hostname_unsecure_test.exe chttp2_fullstack_cancel_after_accept_unsecure_test.exe chttp2_fullstack_cancel_after_accept_and_writes_closed_unsecure_test.exe chttp2_fullstack_cancel_after_invoke_unsecure_test.exe chttp2_fullstack_cancel_before_invoke_unsecure_test.exe chttp2_fullstack_cancel_in_a_vacuum_unsecure_test.exe chttp2_fullstack_census_simple_request_unsecure_test.exe chttp2_fullstack_disappearing_server_unsecure_test.exe chttp2_fullstack_early_server_shutdown_finishes_inflight_calls_unsecure_test.exe chttp2_fullstack_early_server_shutdown_finishes_tags_unsecure_test.exe chttp2_fullstack_empty_batch_unsecure_test.exe chttp2_fullstack_graceful_server_shutdown_unsecure_test.exe chttp2_fullstack_invoke_large_request_unsecure_test.exe chttp2_fullstack_max_concurrent_streams_unsecure_test.exe chttp2_fullstack_max_message_length_unsecure_test.exe chttp2_fullstack_no_op_unsecure_test.exe chttp2_fullstack_ping_pong_streaming_unsecure_test.exe chttp2_fullstack_registered_call_unsecure_test.exe chttp2_fullstack_request_response_with_binary_metadata_and_payload_unsecure_test.exe chttp2_fullstack_request_response_with_metadata_and_payload_unsecure_test.exe chttp2_fullstack_request_response_with_payload_unsecure_test.exe chttp2_fullstack_request_response_with_trailing_metadata_and_payload_unsecure_test.exe chttp2_fullstack_request_with_large_metadata_unsecure_test.exe chttp2_fullstack_request_with_payload_unsecure_test.exe chttp2_fullstack_server_finishes_request_unsecure_test.exe chttp2_fullstack_simple_delayed_request_unsecure_test.exe chttp2_fullstack_simple_request_unsecure_test.exe chttp2_fullstack_simple_request_with_high_initial_sequence_number_unsecure_test.exe chttp2_socket_pair_bad_hostname_unsecure_test.exe chttp2_socket_pair_cancel_after_accept_unsecure_test.exe chttp2_socket_pair_cancel_after_accept_and_writes_closed_unsecure_test.exe chttp2_socket_pair_cancel_after_invoke_unsecure_test.exe chttp2_socket_pair_cancel_before_invoke_unsecure_test.exe chttp2_socket_pair_cancel_in_a_vacuum_unsecure_test.exe chttp2_socket_pair_census_simple_request_unsecure_test.exe chttp2_socket_pair_disappearing_server_unsecure_test.exe chttp2_socket_pair_early_server_shutdown_finishes_inflight_calls_unsecure_test.exe chttp2_socket_pair_early_server_shutdown_finishes_tags_unsecure_test.exe chttp2_socket_pair_empty_batch_unsecure_test.exe chttp2_socket_pair_graceful_server_shutdown_unsecure_test.exe chttp2_socket_pair_invoke_large_request_unsecure_test.exe chttp2_socket_pair_max_concurrent_streams_unsecure_test.exe chttp2_socket_pair_max_message_length_unsecure_test.exe chttp2_socket_pair_no_op_unsecure_test.exe chttp2_socket_pair_ping_pong_streaming_unsecure_test.exe chttp2_socket_pair_registered_call_unsecure_test.exe chttp2_socket_pair_request_response_with_binary_metadata_and_payload_unsecure_test.exe chttp2_socket_pair_request_response_with_metadata_and_payload_unsecure_test.exe chttp2_socket_pair_request_response_with_payload_unsecure_test.exe chttp2_socket_pair_request_response_with_trailing_metadata_and_payload_unsecure_test.exe chttp2_socket_pair_request_with_large_metadata_unsecure_test.exe chttp2_socket_pair_request_with_payload_unsecure_test.exe chttp2_socket_pair_server_finishes_request_unsecure_test.exe chttp2_socket_pair_simple_delayed_request_unsecure_test.exe chttp2_socket_pair_simple_request_unsecure_test.exe chttp2_socket_pair_simple_request_with_high_initial_sequence_number_unsecure_test.exe chttp2_socket_pair_one_byte_at_a_time_bad_hostname_unsecure_test.exe chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_unsecure_test.exe chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_and_writes_closed_unsecure_test.exe chttp2_socket_pair_one_byte_at_a_time_cancel_after_invoke_unsecure_test.exe chttp2_socket_pair_one_byte_at_a_time_cancel_before_invoke_unsecure_test.exe chttp2_socket_pair_one_byte_at_a_time_cancel_in_a_vacuum_unsecure_test.exe chttp2_socket_pair_one_byte_at_a_time_census_simple_request_unsecure_test.exe chttp2_socket_pair_one_byte_at_a_time_disappearing_server_unsecure_test.exe chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_inflight_calls_unsecure_test.exe chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_tags_unsecure_test.exe chttp2_socket_pair_one_byte_at_a_time_empty_batch_unsecure_test.exe chttp2_socket_pair_one_byte_at_a_time_graceful_server_shutdown_unsecure_test.exe chttp2_socket_pair_one_byte_at_a_time_invoke_large_request_unsecure_test.exe chttp2_socket_pair_one_byte_at_a_time_max_concurrent_streams_unsecure_test.exe chttp2_socket_pair_one_byte_at_a_time_max_message_length_unsecure_test.exe chttp2_socket_pair_one_byte_at_a_time_no_op_unsecure_test.exe chttp2_socket_pair_one_byte_at_a_time_ping_pong_streaming_unsecure_test.exe chttp2_socket_pair_one_byte_at_a_time_registered_call_unsecure_test.exe chttp2_socket_pair_one_byte_at_a_time_request_response_with_binary_metadata_and_payload_unsecure_test.exe chttp2_socket_pair_one_byte_at_a_time_request_response_with_metadata_and_payload_unsecure_test.exe chttp2_socket_pair_one_byte_at_a_time_request_response_with_payload_unsecure_test.exe chttp2_socket_pair_one_byte_at_a_time_request_response_with_trailing_metadata_and_payload_unsecure_test.exe chttp2_socket_pair_one_byte_at_a_time_request_with_large_metadata_unsecure_test.exe chttp2_socket_pair_one_byte_at_a_time_request_with_payload_unsecure_test.exe chttp2_socket_pair_one_byte_at_a_time_server_finishes_request_unsecure_test.exe chttp2_socket_pair_one_byte_at_a_time_simple_delayed_request_unsecure_test.exe chttp2_socket_pair_one_byte_at_a_time_simple_request_unsecure_test.exe chttp2_socket_pair_one_byte_at_a_time_simple_request_with_high_initial_sequence_number_unsecure_test.exe chttp2_socket_pair_with_grpc_trace_bad_hostname_unsecure_test.exe chttp2_socket_pair_with_grpc_trace_cancel_after_accept_unsecure_test.exe chttp2_socket_pair_with_grpc_trace_cancel_after_accept_and_writes_closed_unsecure_test.exe chttp2_socket_pair_with_grpc_trace_cancel_after_invoke_unsecure_test.exe chttp2_socket_pair_with_grpc_trace_cancel_before_invoke_unsecure_test.exe chttp2_socket_pair_with_grpc_trace_cancel_in_a_vacuum_unsecure_test.exe chttp2_socket_pair_with_grpc_trace_census_simple_request_unsecure_test.exe chttp2_socket_pair_with_grpc_trace_disappearing_server_unsecure_test.exe chttp2_socket_pair_with_grpc_trace_early_server_shutdown_finishes_inflight_calls_unsecure_test.exe chttp2_socket_pair_with_grpc_trace_early_server_shutdown_finishes_tags_unsecure_test.exe chttp2_socket_pair_with_grpc_trace_empty_batch_unsecure_test.exe chttp2_socket_pair_with_grpc_trace_graceful_server_shutdown_unsecure_test.exe chttp2_socket_pair_with_grpc_trace_invoke_large_request_unsecure_test.exe chttp2_socket_pair_with_grpc_trace_max_concurrent_streams_unsecure_test.exe chttp2_socket_pair_with_grpc_trace_max_message_length_unsecure_test.exe chttp2_socket_pair_with_grpc_trace_no_op_unsecure_test.exe chttp2_socket_pair_with_grpc_trace_ping_pong_streaming_unsecure_test.exe chttp2_socket_pair_with_grpc_trace_registered_call_unsecure_test.exe chttp2_socket_pair_with_grpc_trace_request_response_with_binary_metadata_and_payload_unsecure_test.exe chttp2_socket_pair_with_grpc_trace_request_response_with_metadata_and_payload_unsecure_test.exe chttp2_socket_pair_with_grpc_trace_request_response_with_payload_unsecure_test.exe chttp2_socket_pair_with_grpc_trace_request_response_with_trailing_metadata_and_payload_unsecure_test.exe chttp2_socket_pair_with_grpc_trace_request_with_large_metadata_unsecure_test.exe chttp2_socket_pair_with_grpc_trace_request_with_payload_unsecure_test.exe chttp2_socket_pair_with_grpc_trace_server_finishes_request_unsecure_test.exe chttp2_socket_pair_with_grpc_trace_simple_delayed_request_unsecure_test.exe chttp2_socket_pair_with_grpc_trace_simple_request_unsecure_test.exe chttp2_socket_pair_with_grpc_trace_simple_request_with_high_initial_sequence_number_unsecure_test.exe connection_prefix_bad_client_test.exe 
+buildtests_c: alarm_heap_test.exe alarm_list_test.exe alarm_test.exe alpn_test.exe bin_encoder_test.exe chttp2_status_conversion_test.exe chttp2_stream_encoder_test.exe chttp2_stream_map_test.exe fling_client.exe fling_server.exe gpr_cancellable_test.exe gpr_cmdline_test.exe gpr_env_test.exe gpr_file_test.exe gpr_histogram_test.exe gpr_host_port_test.exe gpr_log_test.exe gpr_slice_buffer_test.exe gpr_slice_test.exe gpr_string_test.exe gpr_sync_test.exe gpr_thd_test.exe gpr_time_test.exe gpr_tls_test.exe gpr_useful_test.exe grpc_auth_context_test.exe grpc_base64_test.exe grpc_byte_buffer_reader_test.exe grpc_channel_stack_test.exe grpc_completion_queue_test.exe grpc_credentials_test.exe grpc_json_token_test.exe grpc_stream_op_test.exe hpack_parser_test.exe hpack_table_test.exe httpcli_format_request_test.exe httpcli_parser_test.exe httpcli_test.exe json_rewrite.exe json_rewrite_test.exe json_test.exe lame_client_test.exe message_compress_test.exe multi_init_test.exe murmur_hash_test.exe no_server_test.exe resolve_address_test.exe secure_endpoint_test.exe sockaddr_utils_test.exe time_averaged_stats_test.exe time_test.exe timeout_encoding_test.exe timers_test.exe transport_metadata_test.exe transport_security_test.exe chttp2_fake_security_bad_hostname_test.exe chttp2_fake_security_cancel_after_accept_test.exe chttp2_fake_security_cancel_after_accept_and_writes_closed_test.exe chttp2_fake_security_cancel_after_invoke_test.exe chttp2_fake_security_cancel_before_invoke_test.exe chttp2_fake_security_cancel_in_a_vacuum_test.exe chttp2_fake_security_census_simple_request_test.exe chttp2_fake_security_disappearing_server_test.exe chttp2_fake_security_early_server_shutdown_finishes_inflight_calls_test.exe chttp2_fake_security_early_server_shutdown_finishes_tags_test.exe chttp2_fake_security_empty_batch_test.exe chttp2_fake_security_graceful_server_shutdown_test.exe chttp2_fake_security_invoke_large_request_test.exe chttp2_fake_security_max_concurrent_streams_test.exe chttp2_fake_security_max_message_length_test.exe chttp2_fake_security_no_op_test.exe chttp2_fake_security_ping_pong_streaming_test.exe chttp2_fake_security_registered_call_test.exe chttp2_fake_security_request_response_with_binary_metadata_and_payload_test.exe chttp2_fake_security_request_response_with_metadata_and_payload_test.exe chttp2_fake_security_request_response_with_payload_test.exe chttp2_fake_security_request_response_with_payload_and_call_creds_test.exe chttp2_fake_security_request_response_with_trailing_metadata_and_payload_test.exe chttp2_fake_security_request_with_large_metadata_test.exe chttp2_fake_security_request_with_payload_test.exe chttp2_fake_security_server_finishes_request_test.exe chttp2_fake_security_simple_delayed_request_test.exe chttp2_fake_security_simple_request_test.exe chttp2_fake_security_simple_request_with_high_initial_sequence_number_test.exe chttp2_fullstack_bad_hostname_test.exe chttp2_fullstack_cancel_after_accept_test.exe chttp2_fullstack_cancel_after_accept_and_writes_closed_test.exe chttp2_fullstack_cancel_after_invoke_test.exe chttp2_fullstack_cancel_before_invoke_test.exe chttp2_fullstack_cancel_in_a_vacuum_test.exe chttp2_fullstack_census_simple_request_test.exe chttp2_fullstack_disappearing_server_test.exe chttp2_fullstack_early_server_shutdown_finishes_inflight_calls_test.exe chttp2_fullstack_early_server_shutdown_finishes_tags_test.exe chttp2_fullstack_empty_batch_test.exe chttp2_fullstack_graceful_server_shutdown_test.exe chttp2_fullstack_invoke_large_request_test.exe chttp2_fullstack_max_concurrent_streams_test.exe chttp2_fullstack_max_message_length_test.exe chttp2_fullstack_no_op_test.exe chttp2_fullstack_ping_pong_streaming_test.exe chttp2_fullstack_registered_call_test.exe chttp2_fullstack_request_response_with_binary_metadata_and_payload_test.exe chttp2_fullstack_request_response_with_metadata_and_payload_test.exe chttp2_fullstack_request_response_with_payload_test.exe chttp2_fullstack_request_response_with_payload_and_call_creds_test.exe chttp2_fullstack_request_response_with_trailing_metadata_and_payload_test.exe chttp2_fullstack_request_with_large_metadata_test.exe chttp2_fullstack_request_with_payload_test.exe chttp2_fullstack_server_finishes_request_test.exe chttp2_fullstack_simple_delayed_request_test.exe chttp2_fullstack_simple_request_test.exe chttp2_fullstack_simple_request_with_high_initial_sequence_number_test.exe chttp2_simple_ssl_fullstack_bad_hostname_test.exe chttp2_simple_ssl_fullstack_cancel_after_accept_test.exe chttp2_simple_ssl_fullstack_cancel_after_accept_and_writes_closed_test.exe chttp2_simple_ssl_fullstack_cancel_after_invoke_test.exe chttp2_simple_ssl_fullstack_cancel_before_invoke_test.exe chttp2_simple_ssl_fullstack_cancel_in_a_vacuum_test.exe chttp2_simple_ssl_fullstack_census_simple_request_test.exe chttp2_simple_ssl_fullstack_disappearing_server_test.exe chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_inflight_calls_test.exe chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_tags_test.exe chttp2_simple_ssl_fullstack_empty_batch_test.exe chttp2_simple_ssl_fullstack_graceful_server_shutdown_test.exe chttp2_simple_ssl_fullstack_invoke_large_request_test.exe chttp2_simple_ssl_fullstack_max_concurrent_streams_test.exe chttp2_simple_ssl_fullstack_max_message_length_test.exe chttp2_simple_ssl_fullstack_no_op_test.exe chttp2_simple_ssl_fullstack_ping_pong_streaming_test.exe chttp2_simple_ssl_fullstack_registered_call_test.exe chttp2_simple_ssl_fullstack_request_response_with_binary_metadata_and_payload_test.exe chttp2_simple_ssl_fullstack_request_response_with_metadata_and_payload_test.exe chttp2_simple_ssl_fullstack_request_response_with_payload_test.exe chttp2_simple_ssl_fullstack_request_response_with_payload_and_call_creds_test.exe chttp2_simple_ssl_fullstack_request_response_with_trailing_metadata_and_payload_test.exe chttp2_simple_ssl_fullstack_request_with_large_metadata_test.exe chttp2_simple_ssl_fullstack_request_with_payload_test.exe chttp2_simple_ssl_fullstack_server_finishes_request_test.exe chttp2_simple_ssl_fullstack_simple_delayed_request_test.exe chttp2_simple_ssl_fullstack_simple_request_test.exe chttp2_simple_ssl_fullstack_simple_request_with_high_initial_sequence_number_test.exe chttp2_simple_ssl_with_oauth2_fullstack_bad_hostname_test.exe chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_accept_test.exe chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_accept_and_writes_closed_test.exe chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_invoke_test.exe chttp2_simple_ssl_with_oauth2_fullstack_cancel_before_invoke_test.exe chttp2_simple_ssl_with_oauth2_fullstack_cancel_in_a_vacuum_test.exe chttp2_simple_ssl_with_oauth2_fullstack_census_simple_request_test.exe chttp2_simple_ssl_with_oauth2_fullstack_disappearing_server_test.exe chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_inflight_calls_test.exe chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_tags_test.exe chttp2_simple_ssl_with_oauth2_fullstack_empty_batch_test.exe chttp2_simple_ssl_with_oauth2_fullstack_graceful_server_shutdown_test.exe chttp2_simple_ssl_with_oauth2_fullstack_invoke_large_request_test.exe chttp2_simple_ssl_with_oauth2_fullstack_max_concurrent_streams_test.exe chttp2_simple_ssl_with_oauth2_fullstack_max_message_length_test.exe chttp2_simple_ssl_with_oauth2_fullstack_no_op_test.exe chttp2_simple_ssl_with_oauth2_fullstack_ping_pong_streaming_test.exe chttp2_simple_ssl_with_oauth2_fullstack_registered_call_test.exe chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_binary_metadata_and_payload_test.exe chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_metadata_and_payload_test.exe chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_payload_test.exe chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_payload_and_call_creds_test.exe chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_trailing_metadata_and_payload_test.exe chttp2_simple_ssl_with_oauth2_fullstack_request_with_large_metadata_test.exe chttp2_simple_ssl_with_oauth2_fullstack_request_with_payload_test.exe chttp2_simple_ssl_with_oauth2_fullstack_server_finishes_request_test.exe chttp2_simple_ssl_with_oauth2_fullstack_simple_delayed_request_test.exe chttp2_simple_ssl_with_oauth2_fullstack_simple_request_test.exe chttp2_simple_ssl_with_oauth2_fullstack_simple_request_with_high_initial_sequence_number_test.exe chttp2_socket_pair_bad_hostname_test.exe chttp2_socket_pair_cancel_after_accept_test.exe chttp2_socket_pair_cancel_after_accept_and_writes_closed_test.exe chttp2_socket_pair_cancel_after_invoke_test.exe chttp2_socket_pair_cancel_before_invoke_test.exe chttp2_socket_pair_cancel_in_a_vacuum_test.exe chttp2_socket_pair_census_simple_request_test.exe chttp2_socket_pair_disappearing_server_test.exe chttp2_socket_pair_early_server_shutdown_finishes_inflight_calls_test.exe chttp2_socket_pair_early_server_shutdown_finishes_tags_test.exe chttp2_socket_pair_empty_batch_test.exe chttp2_socket_pair_graceful_server_shutdown_test.exe chttp2_socket_pair_invoke_large_request_test.exe chttp2_socket_pair_max_concurrent_streams_test.exe chttp2_socket_pair_max_message_length_test.exe chttp2_socket_pair_no_op_test.exe chttp2_socket_pair_ping_pong_streaming_test.exe chttp2_socket_pair_registered_call_test.exe chttp2_socket_pair_request_response_with_binary_metadata_and_payload_test.exe chttp2_socket_pair_request_response_with_metadata_and_payload_test.exe chttp2_socket_pair_request_response_with_payload_test.exe chttp2_socket_pair_request_response_with_payload_and_call_creds_test.exe chttp2_socket_pair_request_response_with_trailing_metadata_and_payload_test.exe chttp2_socket_pair_request_with_large_metadata_test.exe chttp2_socket_pair_request_with_payload_test.exe chttp2_socket_pair_server_finishes_request_test.exe chttp2_socket_pair_simple_delayed_request_test.exe chttp2_socket_pair_simple_request_test.exe chttp2_socket_pair_simple_request_with_high_initial_sequence_number_test.exe chttp2_socket_pair_one_byte_at_a_time_bad_hostname_test.exe chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_test.exe chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_and_writes_closed_test.exe chttp2_socket_pair_one_byte_at_a_time_cancel_after_invoke_test.exe chttp2_socket_pair_one_byte_at_a_time_cancel_before_invoke_test.exe chttp2_socket_pair_one_byte_at_a_time_cancel_in_a_vacuum_test.exe chttp2_socket_pair_one_byte_at_a_time_census_simple_request_test.exe chttp2_socket_pair_one_byte_at_a_time_disappearing_server_test.exe chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_inflight_calls_test.exe chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_tags_test.exe chttp2_socket_pair_one_byte_at_a_time_empty_batch_test.exe chttp2_socket_pair_one_byte_at_a_time_graceful_server_shutdown_test.exe chttp2_socket_pair_one_byte_at_a_time_invoke_large_request_test.exe chttp2_socket_pair_one_byte_at_a_time_max_concurrent_streams_test.exe chttp2_socket_pair_one_byte_at_a_time_max_message_length_test.exe chttp2_socket_pair_one_byte_at_a_time_no_op_test.exe chttp2_socket_pair_one_byte_at_a_time_ping_pong_streaming_test.exe chttp2_socket_pair_one_byte_at_a_time_registered_call_test.exe chttp2_socket_pair_one_byte_at_a_time_request_response_with_binary_metadata_and_payload_test.exe chttp2_socket_pair_one_byte_at_a_time_request_response_with_metadata_and_payload_test.exe chttp2_socket_pair_one_byte_at_a_time_request_response_with_payload_test.exe chttp2_socket_pair_one_byte_at_a_time_request_response_with_payload_and_call_creds_test.exe chttp2_socket_pair_one_byte_at_a_time_request_response_with_trailing_metadata_and_payload_test.exe chttp2_socket_pair_one_byte_at_a_time_request_with_large_metadata_test.exe chttp2_socket_pair_one_byte_at_a_time_request_with_payload_test.exe chttp2_socket_pair_one_byte_at_a_time_server_finishes_request_test.exe chttp2_socket_pair_one_byte_at_a_time_simple_delayed_request_test.exe chttp2_socket_pair_one_byte_at_a_time_simple_request_test.exe chttp2_socket_pair_one_byte_at_a_time_simple_request_with_high_initial_sequence_number_test.exe chttp2_socket_pair_with_grpc_trace_bad_hostname_test.exe chttp2_socket_pair_with_grpc_trace_cancel_after_accept_test.exe chttp2_socket_pair_with_grpc_trace_cancel_after_accept_and_writes_closed_test.exe chttp2_socket_pair_with_grpc_trace_cancel_after_invoke_test.exe chttp2_socket_pair_with_grpc_trace_cancel_before_invoke_test.exe chttp2_socket_pair_with_grpc_trace_cancel_in_a_vacuum_test.exe chttp2_socket_pair_with_grpc_trace_census_simple_request_test.exe chttp2_socket_pair_with_grpc_trace_disappearing_server_test.exe chttp2_socket_pair_with_grpc_trace_early_server_shutdown_finishes_inflight_calls_test.exe chttp2_socket_pair_with_grpc_trace_early_server_shutdown_finishes_tags_test.exe chttp2_socket_pair_with_grpc_trace_empty_batch_test.exe chttp2_socket_pair_with_grpc_trace_graceful_server_shutdown_test.exe chttp2_socket_pair_with_grpc_trace_invoke_large_request_test.exe chttp2_socket_pair_with_grpc_trace_max_concurrent_streams_test.exe chttp2_socket_pair_with_grpc_trace_max_message_length_test.exe chttp2_socket_pair_with_grpc_trace_no_op_test.exe chttp2_socket_pair_with_grpc_trace_ping_pong_streaming_test.exe chttp2_socket_pair_with_grpc_trace_registered_call_test.exe chttp2_socket_pair_with_grpc_trace_request_response_with_binary_metadata_and_payload_test.exe chttp2_socket_pair_with_grpc_trace_request_response_with_metadata_and_payload_test.exe chttp2_socket_pair_with_grpc_trace_request_response_with_payload_test.exe chttp2_socket_pair_with_grpc_trace_request_response_with_payload_and_call_creds_test.exe chttp2_socket_pair_with_grpc_trace_request_response_with_trailing_metadata_and_payload_test.exe chttp2_socket_pair_with_grpc_trace_request_with_large_metadata_test.exe chttp2_socket_pair_with_grpc_trace_request_with_payload_test.exe chttp2_socket_pair_with_grpc_trace_server_finishes_request_test.exe chttp2_socket_pair_with_grpc_trace_simple_delayed_request_test.exe chttp2_socket_pair_with_grpc_trace_simple_request_test.exe chttp2_socket_pair_with_grpc_trace_simple_request_with_high_initial_sequence_number_test.exe chttp2_fullstack_bad_hostname_unsecure_test.exe chttp2_fullstack_cancel_after_accept_unsecure_test.exe chttp2_fullstack_cancel_after_accept_and_writes_closed_unsecure_test.exe chttp2_fullstack_cancel_after_invoke_unsecure_test.exe chttp2_fullstack_cancel_before_invoke_unsecure_test.exe chttp2_fullstack_cancel_in_a_vacuum_unsecure_test.exe chttp2_fullstack_census_simple_request_unsecure_test.exe chttp2_fullstack_disappearing_server_unsecure_test.exe chttp2_fullstack_early_server_shutdown_finishes_inflight_calls_unsecure_test.exe chttp2_fullstack_early_server_shutdown_finishes_tags_unsecure_test.exe chttp2_fullstack_empty_batch_unsecure_test.exe chttp2_fullstack_graceful_server_shutdown_unsecure_test.exe chttp2_fullstack_invoke_large_request_unsecure_test.exe chttp2_fullstack_max_concurrent_streams_unsecure_test.exe chttp2_fullstack_max_message_length_unsecure_test.exe chttp2_fullstack_no_op_unsecure_test.exe chttp2_fullstack_ping_pong_streaming_unsecure_test.exe chttp2_fullstack_registered_call_unsecure_test.exe chttp2_fullstack_request_response_with_binary_metadata_and_payload_unsecure_test.exe chttp2_fullstack_request_response_with_metadata_and_payload_unsecure_test.exe chttp2_fullstack_request_response_with_payload_unsecure_test.exe chttp2_fullstack_request_response_with_trailing_metadata_and_payload_unsecure_test.exe chttp2_fullstack_request_with_large_metadata_unsecure_test.exe chttp2_fullstack_request_with_payload_unsecure_test.exe chttp2_fullstack_server_finishes_request_unsecure_test.exe chttp2_fullstack_simple_delayed_request_unsecure_test.exe chttp2_fullstack_simple_request_unsecure_test.exe chttp2_fullstack_simple_request_with_high_initial_sequence_number_unsecure_test.exe chttp2_socket_pair_bad_hostname_unsecure_test.exe chttp2_socket_pair_cancel_after_accept_unsecure_test.exe chttp2_socket_pair_cancel_after_accept_and_writes_closed_unsecure_test.exe chttp2_socket_pair_cancel_after_invoke_unsecure_test.exe chttp2_socket_pair_cancel_before_invoke_unsecure_test.exe chttp2_socket_pair_cancel_in_a_vacuum_unsecure_test.exe chttp2_socket_pair_census_simple_request_unsecure_test.exe chttp2_socket_pair_disappearing_server_unsecure_test.exe chttp2_socket_pair_early_server_shutdown_finishes_inflight_calls_unsecure_test.exe chttp2_socket_pair_early_server_shutdown_finishes_tags_unsecure_test.exe chttp2_socket_pair_empty_batch_unsecure_test.exe chttp2_socket_pair_graceful_server_shutdown_unsecure_test.exe chttp2_socket_pair_invoke_large_request_unsecure_test.exe chttp2_socket_pair_max_concurrent_streams_unsecure_test.exe chttp2_socket_pair_max_message_length_unsecure_test.exe chttp2_socket_pair_no_op_unsecure_test.exe chttp2_socket_pair_ping_pong_streaming_unsecure_test.exe chttp2_socket_pair_registered_call_unsecure_test.exe chttp2_socket_pair_request_response_with_binary_metadata_and_payload_unsecure_test.exe chttp2_socket_pair_request_response_with_metadata_and_payload_unsecure_test.exe chttp2_socket_pair_request_response_with_payload_unsecure_test.exe chttp2_socket_pair_request_response_with_trailing_metadata_and_payload_unsecure_test.exe chttp2_socket_pair_request_with_large_metadata_unsecure_test.exe chttp2_socket_pair_request_with_payload_unsecure_test.exe chttp2_socket_pair_server_finishes_request_unsecure_test.exe chttp2_socket_pair_simple_delayed_request_unsecure_test.exe chttp2_socket_pair_simple_request_unsecure_test.exe chttp2_socket_pair_simple_request_with_high_initial_sequence_number_unsecure_test.exe chttp2_socket_pair_one_byte_at_a_time_bad_hostname_unsecure_test.exe chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_unsecure_test.exe chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_and_writes_closed_unsecure_test.exe chttp2_socket_pair_one_byte_at_a_time_cancel_after_invoke_unsecure_test.exe chttp2_socket_pair_one_byte_at_a_time_cancel_before_invoke_unsecure_test.exe chttp2_socket_pair_one_byte_at_a_time_cancel_in_a_vacuum_unsecure_test.exe chttp2_socket_pair_one_byte_at_a_time_census_simple_request_unsecure_test.exe chttp2_socket_pair_one_byte_at_a_time_disappearing_server_unsecure_test.exe chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_inflight_calls_unsecure_test.exe chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_tags_unsecure_test.exe chttp2_socket_pair_one_byte_at_a_time_empty_batch_unsecure_test.exe chttp2_socket_pair_one_byte_at_a_time_graceful_server_shutdown_unsecure_test.exe chttp2_socket_pair_one_byte_at_a_time_invoke_large_request_unsecure_test.exe chttp2_socket_pair_one_byte_at_a_time_max_concurrent_streams_unsecure_test.exe chttp2_socket_pair_one_byte_at_a_time_max_message_length_unsecure_test.exe chttp2_socket_pair_one_byte_at_a_time_no_op_unsecure_test.exe chttp2_socket_pair_one_byte_at_a_time_ping_pong_streaming_unsecure_test.exe chttp2_socket_pair_one_byte_at_a_time_registered_call_unsecure_test.exe chttp2_socket_pair_one_byte_at_a_time_request_response_with_binary_metadata_and_payload_unsecure_test.exe chttp2_socket_pair_one_byte_at_a_time_request_response_with_metadata_and_payload_unsecure_test.exe chttp2_socket_pair_one_byte_at_a_time_request_response_with_payload_unsecure_test.exe chttp2_socket_pair_one_byte_at_a_time_request_response_with_trailing_metadata_and_payload_unsecure_test.exe chttp2_socket_pair_one_byte_at_a_time_request_with_large_metadata_unsecure_test.exe chttp2_socket_pair_one_byte_at_a_time_request_with_payload_unsecure_test.exe chttp2_socket_pair_one_byte_at_a_time_server_finishes_request_unsecure_test.exe chttp2_socket_pair_one_byte_at_a_time_simple_delayed_request_unsecure_test.exe chttp2_socket_pair_one_byte_at_a_time_simple_request_unsecure_test.exe chttp2_socket_pair_one_byte_at_a_time_simple_request_with_high_initial_sequence_number_unsecure_test.exe chttp2_socket_pair_with_grpc_trace_bad_hostname_unsecure_test.exe chttp2_socket_pair_with_grpc_trace_cancel_after_accept_unsecure_test.exe chttp2_socket_pair_with_grpc_trace_cancel_after_accept_and_writes_closed_unsecure_test.exe chttp2_socket_pair_with_grpc_trace_cancel_after_invoke_unsecure_test.exe chttp2_socket_pair_with_grpc_trace_cancel_before_invoke_unsecure_test.exe chttp2_socket_pair_with_grpc_trace_cancel_in_a_vacuum_unsecure_test.exe chttp2_socket_pair_with_grpc_trace_census_simple_request_unsecure_test.exe chttp2_socket_pair_with_grpc_trace_disappearing_server_unsecure_test.exe chttp2_socket_pair_with_grpc_trace_early_server_shutdown_finishes_inflight_calls_unsecure_test.exe chttp2_socket_pair_with_grpc_trace_early_server_shutdown_finishes_tags_unsecure_test.exe chttp2_socket_pair_with_grpc_trace_empty_batch_unsecure_test.exe chttp2_socket_pair_with_grpc_trace_graceful_server_shutdown_unsecure_test.exe chttp2_socket_pair_with_grpc_trace_invoke_large_request_unsecure_test.exe chttp2_socket_pair_with_grpc_trace_max_concurrent_streams_unsecure_test.exe chttp2_socket_pair_with_grpc_trace_max_message_length_unsecure_test.exe chttp2_socket_pair_with_grpc_trace_no_op_unsecure_test.exe chttp2_socket_pair_with_grpc_trace_ping_pong_streaming_unsecure_test.exe chttp2_socket_pair_with_grpc_trace_registered_call_unsecure_test.exe chttp2_socket_pair_with_grpc_trace_request_response_with_binary_metadata_and_payload_unsecure_test.exe chttp2_socket_pair_with_grpc_trace_request_response_with_metadata_and_payload_unsecure_test.exe chttp2_socket_pair_with_grpc_trace_request_response_with_payload_unsecure_test.exe chttp2_socket_pair_with_grpc_trace_request_response_with_trailing_metadata_and_payload_unsecure_test.exe chttp2_socket_pair_with_grpc_trace_request_with_large_metadata_unsecure_test.exe chttp2_socket_pair_with_grpc_trace_request_with_payload_unsecure_test.exe chttp2_socket_pair_with_grpc_trace_server_finishes_request_unsecure_test.exe chttp2_socket_pair_with_grpc_trace_simple_delayed_request_unsecure_test.exe chttp2_socket_pair_with_grpc_trace_simple_request_unsecure_test.exe chttp2_socket_pair_with_grpc_trace_simple_request_with_high_initial_sequence_number_unsecure_test.exe connection_prefix_bad_client_test.exe 
 	echo All tests built.
 
 buildtests_cxx: interop_client.exe interop_server.exe 
@@ -98,62 +98,6 @@
 bin_encoder_test: bin_encoder_test.exe
 	echo Running bin_encoder_test
 	$(OUT_DIR)\bin_encoder_test.exe
-census_hash_table_test.exe: build_libs $(OUT_DIR)
-	echo Building census_hash_table_test
-	$(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ $(REPO_ROOT)\test\core\statistics\hash_table_test.c 
-	$(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\census_hash_table_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\hash_table_test.obj 
-census_hash_table_test: census_hash_table_test.exe
-	echo Running census_hash_table_test
-	$(OUT_DIR)\census_hash_table_test.exe
-census_statistics_multiple_writers_circular_buffer_test.exe: build_libs $(OUT_DIR)
-	echo Building census_statistics_multiple_writers_circular_buffer_test
-	$(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ $(REPO_ROOT)\test\core\statistics\multiple_writers_circular_buffer_test.c 
-	$(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\census_statistics_multiple_writers_circular_buffer_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\multiple_writers_circular_buffer_test.obj 
-census_statistics_multiple_writers_circular_buffer_test: census_statistics_multiple_writers_circular_buffer_test.exe
-	echo Running census_statistics_multiple_writers_circular_buffer_test
-	$(OUT_DIR)\census_statistics_multiple_writers_circular_buffer_test.exe
-census_statistics_multiple_writers_test.exe: build_libs $(OUT_DIR)
-	echo Building census_statistics_multiple_writers_test
-	$(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ $(REPO_ROOT)\test\core\statistics\multiple_writers_test.c 
-	$(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\census_statistics_multiple_writers_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\multiple_writers_test.obj 
-census_statistics_multiple_writers_test: census_statistics_multiple_writers_test.exe
-	echo Running census_statistics_multiple_writers_test
-	$(OUT_DIR)\census_statistics_multiple_writers_test.exe
-census_statistics_performance_test.exe: build_libs $(OUT_DIR)
-	echo Building census_statistics_performance_test
-	$(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ $(REPO_ROOT)\test\core\statistics\performance_test.c 
-	$(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\census_statistics_performance_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\performance_test.obj 
-census_statistics_performance_test: census_statistics_performance_test.exe
-	echo Running census_statistics_performance_test
-	$(OUT_DIR)\census_statistics_performance_test.exe
-census_statistics_quick_test.exe: build_libs $(OUT_DIR)
-	echo Building census_statistics_quick_test
-	$(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ $(REPO_ROOT)\test\core\statistics\quick_test.c 
-	$(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\census_statistics_quick_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\quick_test.obj 
-census_statistics_quick_test: census_statistics_quick_test.exe
-	echo Running census_statistics_quick_test
-	$(OUT_DIR)\census_statistics_quick_test.exe
-census_statistics_small_log_test.exe: build_libs $(OUT_DIR)
-	echo Building census_statistics_small_log_test
-	$(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ $(REPO_ROOT)\test\core\statistics\small_log_test.c 
-	$(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\census_statistics_small_log_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\small_log_test.obj 
-census_statistics_small_log_test: census_statistics_small_log_test.exe
-	echo Running census_statistics_small_log_test
-	$(OUT_DIR)\census_statistics_small_log_test.exe
-census_stub_test.exe: build_libs $(OUT_DIR)
-	echo Building census_stub_test
-	$(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ $(REPO_ROOT)\test\core\statistics\census_stub_test.c 
-	$(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\census_stub_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\census_stub_test.obj 
-census_stub_test: census_stub_test.exe
-	echo Running census_stub_test
-	$(OUT_DIR)\census_stub_test.exe
-census_window_stats_test.exe: build_libs $(OUT_DIR)
-	echo Building census_window_stats_test
-	$(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ $(REPO_ROOT)\test\core\statistics\window_stats_test.c 
-	$(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\census_window_stats_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\window_stats_test.obj 
-census_window_stats_test: census_window_stats_test.exe
-	echo Running census_window_stats_test
-	$(OUT_DIR)\census_window_stats_test.exe
 chttp2_status_conversion_test.exe: build_libs $(OUT_DIR)
 	echo Building chttp2_status_conversion_test
 	$(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ $(REPO_ROOT)\test\core\transport\chttp2\status_conversion_test.c 
diff --git a/vsprojects/grpc/grpc.vcxproj b/vsprojects/grpc/grpc.vcxproj
index 709a8ee..990962a 100644
--- a/vsprojects/grpc/grpc.vcxproj
+++ b/vsprojects/grpc/grpc.vcxproj
@@ -152,6 +152,7 @@
     <ClInclude Include="..\..\include\grpc\byte_buffer_reader.h" />
     <ClInclude Include="..\..\include\grpc\grpc.h" />
     <ClInclude Include="..\..\include\grpc\status.h" />
+    <ClInclude Include="..\..\include\grpc\census.h" />
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="..\..\src\core\httpcli\format_request.h" />
@@ -170,7 +171,7 @@
     <ClInclude Include="..\..\src\core\tsi\ssl_transport_security.h" />
     <ClInclude Include="..\..\src\core\tsi\transport_security.h" />
     <ClInclude Include="..\..\src\core\tsi\transport_security_interface.h" />
-    <ClInclude Include="..\..\src\core\channel\census_filter.h" />
+    <ClInclude Include="..\..\src\core\census\grpc_context.h" />
     <ClInclude Include="..\..\src\core\channel\channel_args.h" />
     <ClInclude Include="..\..\src\core\channel\channel_stack.h" />
     <ClInclude Include="..\..\src\core\channel\child_channel.h" />
@@ -219,12 +220,6 @@
     <ClInclude Include="..\..\src\core\json\json_writer.h" />
     <ClInclude Include="..\..\src\core\profiling\timers.h" />
     <ClInclude Include="..\..\src\core\profiling\timers_preciseclock.h" />
-    <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\byte_buffer_queue.h" />
     <ClInclude Include="..\..\src\core\surface\call.h" />
     <ClInclude Include="..\..\src\core\surface\channel.h" />
@@ -257,6 +252,7 @@
     <ClInclude Include="..\..\src\core\transport\stream_op.h" />
     <ClInclude Include="..\..\src\core\transport\transport.h" />
     <ClInclude Include="..\..\src\core\transport\transport_impl.h" />
+    <ClInclude Include="..\..\src\core\census\context.h" />
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="..\..\src\core\httpcli\format_request.c">
@@ -305,7 +301,7 @@
     </ClCompile>
     <ClCompile Include="..\..\src\core\tsi\transport_security.c">
     </ClCompile>
-    <ClCompile Include="..\..\src\core\channel\census_filter.c">
+    <ClCompile Include="..\..\src\core\census\grpc_context.c">
     </ClCompile>
     <ClCompile Include="..\..\src\core\channel\channel_args.c">
     </ClCompile>
@@ -409,18 +405,6 @@
     </ClCompile>
     <ClCompile Include="..\..\src\core\profiling\stap_timers.c">
     </ClCompile>
-    <ClCompile Include="..\..\src\core\statistics\census_init.c">
-    </ClCompile>
-    <ClCompile Include="..\..\src\core\statistics\census_log.c">
-    </ClCompile>
-    <ClCompile Include="..\..\src\core\statistics\census_rpc_stats.c">
-    </ClCompile>
-    <ClCompile Include="..\..\src\core\statistics\census_tracing.c">
-    </ClCompile>
-    <ClCompile Include="..\..\src\core\statistics\hash_table.c">
-    </ClCompile>
-    <ClCompile Include="..\..\src\core\statistics\window_stats.c">
-    </ClCompile>
     <ClCompile Include="..\..\src\core\surface\byte_buffer.c">
     </ClCompile>
     <ClCompile Include="..\..\src\core\surface\byte_buffer_queue.c">
@@ -499,6 +483,10 @@
     </ClCompile>
     <ClCompile Include="..\..\src\core\transport\transport_op_string.c">
     </ClCompile>
+    <ClCompile Include="..\..\src\core\census\context.c">
+    </ClCompile>
+    <ClCompile Include="..\..\src\core\census\initialize.c">
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ProjectReference Include="..\gpr\gpr.vcxproj">
diff --git a/vsprojects/grpc/grpc.vcxproj.filters b/vsprojects/grpc/grpc.vcxproj.filters
index 8d4d721..fd9980b 100644
--- a/vsprojects/grpc/grpc.vcxproj.filters
+++ b/vsprojects/grpc/grpc.vcxproj.filters
@@ -70,8 +70,8 @@
     <ClCompile Include="..\..\src\core\tsi\transport_security.c">
       <Filter>src\core\tsi</Filter>
     </ClCompile>
-    <ClCompile Include="..\..\src\core\channel\census_filter.c">
-      <Filter>src\core\channel</Filter>
+    <ClCompile Include="..\..\src\core\census\grpc_context.c">
+      <Filter>src\core\census</Filter>
     </ClCompile>
     <ClCompile Include="..\..\src\core\channel\channel_args.c">
       <Filter>src\core\channel</Filter>
@@ -226,24 +226,6 @@
     <ClCompile Include="..\..\src\core\profiling\stap_timers.c">
       <Filter>src\core\profiling</Filter>
     </ClCompile>
-    <ClCompile Include="..\..\src\core\statistics\census_init.c">
-      <Filter>src\core\statistics</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\src\core\statistics\census_log.c">
-      <Filter>src\core\statistics</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\src\core\statistics\census_rpc_stats.c">
-      <Filter>src\core\statistics</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\src\core\statistics\census_tracing.c">
-      <Filter>src\core\statistics</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\src\core\statistics\hash_table.c">
-      <Filter>src\core\statistics</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\src\core\statistics\window_stats.c">
-      <Filter>src\core\statistics</Filter>
-    </ClCompile>
     <ClCompile Include="..\..\src\core\surface\byte_buffer.c">
       <Filter>src\core\surface</Filter>
     </ClCompile>
@@ -361,6 +343,12 @@
     <ClCompile Include="..\..\src\core\transport\transport_op_string.c">
       <Filter>src\core\transport</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\src\core\census\context.c">
+      <Filter>src\core\census</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\core\census\initialize.c">
+      <Filter>src\core\census</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="..\..\include\grpc\grpc_security.h">
@@ -378,6 +366,9 @@
     <ClInclude Include="..\..\include\grpc\status.h">
       <Filter>include\grpc</Filter>
     </ClInclude>
+    <ClInclude Include="..\..\include\grpc\census.h">
+      <Filter>include\grpc</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="..\..\src\core\httpcli\format_request.h">
@@ -428,8 +419,8 @@
     <ClInclude Include="..\..\src\core\tsi\transport_security_interface.h">
       <Filter>src\core\tsi</Filter>
     </ClInclude>
-    <ClInclude Include="..\..\src\core\channel\census_filter.h">
-      <Filter>src\core\channel</Filter>
+    <ClInclude Include="..\..\src\core\census\grpc_context.h">
+      <Filter>src\core\census</Filter>
     </ClInclude>
     <ClInclude Include="..\..\src\core\channel\channel_args.h">
       <Filter>src\core\channel</Filter>
@@ -575,24 +566,6 @@
     <ClInclude Include="..\..\src\core\profiling\timers_preciseclock.h">
       <Filter>src\core\profiling</Filter>
     </ClInclude>
-    <ClInclude Include="..\..\src\core\statistics\census_interface.h">
-      <Filter>src\core\statistics</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\core\statistics\census_log.h">
-      <Filter>src\core\statistics</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\core\statistics\census_rpc_stats.h">
-      <Filter>src\core\statistics</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\core\statistics\census_tracing.h">
-      <Filter>src\core\statistics</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\core\statistics\hash_table.h">
-      <Filter>src\core\statistics</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\core\statistics\window_stats.h">
-      <Filter>src\core\statistics</Filter>
-    </ClInclude>
     <ClInclude Include="..\..\src\core\surface\byte_buffer_queue.h">
       <Filter>src\core\surface</Filter>
     </ClInclude>
@@ -689,6 +662,9 @@
     <ClInclude Include="..\..\src\core\transport\transport_impl.h">
       <Filter>src\core\transport</Filter>
     </ClInclude>
+    <ClInclude Include="..\..\src\core\census\context.h">
+      <Filter>src\core\census</Filter>
+    </ClInclude>
   </ItemGroup>
 
   <ItemGroup>
@@ -704,6 +680,9 @@
     <Filter Include="src\core">
       <UniqueIdentifier>{ea745680-21ea-9c5e-679b-64dc40562d08}</UniqueIdentifier>
     </Filter>
+    <Filter Include="src\core\census">
+      <UniqueIdentifier>{fb3aefc2-8205-b0bf-525f-ab5e339f7f76}</UniqueIdentifier>
+    </Filter>
     <Filter Include="src\core\channel">
       <UniqueIdentifier>{d897b6c3-c555-234e-a589-b4f008063615}</UniqueIdentifier>
     </Filter>
@@ -728,9 +707,6 @@
     <Filter Include="src\core\security">
       <UniqueIdentifier>{1d850ac6-e639-4eab-5338-4ba40272fcc9}</UniqueIdentifier>
     </Filter>
-    <Filter Include="src\core\statistics">
-      <UniqueIdentifier>{0ef49896-2313-4a3f-1ce2-716fa0e5c6ca}</UniqueIdentifier>
-    </Filter>
     <Filter Include="src\core\surface">
       <UniqueIdentifier>{aeb18e82-5d25-0aad-8b02-a0a3470073ce}</UniqueIdentifier>
     </Filter>
diff --git a/vsprojects/grpc_test_util/grpc_test_util.vcxproj b/vsprojects/grpc_test_util/grpc_test_util.vcxproj
index 4198703..e5288f4 100644
--- a/vsprojects/grpc_test_util/grpc_test_util.vcxproj
+++ b/vsprojects/grpc_test_util/grpc_test_util.vcxproj
@@ -156,8 +156,6 @@
     </ClCompile>
     <ClCompile Include="..\..\test\core\iomgr\endpoint_tests.c">
     </ClCompile>
-    <ClCompile Include="..\..\test\core\statistics\census_log_tests.c">
-    </ClCompile>
     <ClCompile Include="..\..\test\core\util\grpc_profiler.c">
     </ClCompile>
     <ClCompile Include="..\..\test\core\util\parse_hexstring.c">
diff --git a/vsprojects/grpc_unsecure/grpc_unsecure.vcxproj b/vsprojects/grpc_unsecure/grpc_unsecure.vcxproj
index 3dfda32..06ae731 100644
--- a/vsprojects/grpc_unsecure/grpc_unsecure.vcxproj
+++ b/vsprojects/grpc_unsecure/grpc_unsecure.vcxproj
@@ -150,9 +150,10 @@
     <ClInclude Include="..\..\include\grpc\byte_buffer_reader.h" />
     <ClInclude Include="..\..\include\grpc\grpc.h" />
     <ClInclude Include="..\..\include\grpc\status.h" />
+    <ClInclude Include="..\..\include\grpc\census.h" />
   </ItemGroup>
   <ItemGroup>
-    <ClInclude Include="..\..\src\core\channel\census_filter.h" />
+    <ClInclude Include="..\..\src\core\census\grpc_context.h" />
     <ClInclude Include="..\..\src\core\channel\channel_args.h" />
     <ClInclude Include="..\..\src\core\channel\channel_stack.h" />
     <ClInclude Include="..\..\src\core\channel\child_channel.h" />
@@ -201,12 +202,6 @@
     <ClInclude Include="..\..\src\core\json\json_writer.h" />
     <ClInclude Include="..\..\src\core\profiling\timers.h" />
     <ClInclude Include="..\..\src\core\profiling\timers_preciseclock.h" />
-    <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\byte_buffer_queue.h" />
     <ClInclude Include="..\..\src\core\surface\call.h" />
     <ClInclude Include="..\..\src\core\surface\channel.h" />
@@ -239,11 +234,12 @@
     <ClInclude Include="..\..\src\core\transport\stream_op.h" />
     <ClInclude Include="..\..\src\core\transport\transport.h" />
     <ClInclude Include="..\..\src\core\transport\transport_impl.h" />
+    <ClInclude Include="..\..\src\core\census\context.h" />
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="..\..\src\core\surface\init_unsecure.c">
     </ClCompile>
-    <ClCompile Include="..\..\src\core\channel\census_filter.c">
+    <ClCompile Include="..\..\src\core\census\grpc_context.c">
     </ClCompile>
     <ClCompile Include="..\..\src\core\channel\channel_args.c">
     </ClCompile>
@@ -347,18 +343,6 @@
     </ClCompile>
     <ClCompile Include="..\..\src\core\profiling\stap_timers.c">
     </ClCompile>
-    <ClCompile Include="..\..\src\core\statistics\census_init.c">
-    </ClCompile>
-    <ClCompile Include="..\..\src\core\statistics\census_log.c">
-    </ClCompile>
-    <ClCompile Include="..\..\src\core\statistics\census_rpc_stats.c">
-    </ClCompile>
-    <ClCompile Include="..\..\src\core\statistics\census_tracing.c">
-    </ClCompile>
-    <ClCompile Include="..\..\src\core\statistics\hash_table.c">
-    </ClCompile>
-    <ClCompile Include="..\..\src\core\statistics\window_stats.c">
-    </ClCompile>
     <ClCompile Include="..\..\src\core\surface\byte_buffer.c">
     </ClCompile>
     <ClCompile Include="..\..\src\core\surface\byte_buffer_queue.c">
@@ -437,6 +421,10 @@
     </ClCompile>
     <ClCompile Include="..\..\src\core\transport\transport_op_string.c">
     </ClCompile>
+    <ClCompile Include="..\..\src\core\census\context.c">
+    </ClCompile>
+    <ClCompile Include="..\..\src\core\census\initialize.c">
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ProjectReference Include="..\gpr\gpr.vcxproj">
diff --git a/vsprojects/grpc_unsecure/grpc_unsecure.vcxproj.filters b/vsprojects/grpc_unsecure/grpc_unsecure.vcxproj.filters
index 4c9c86e..1603757 100644
--- a/vsprojects/grpc_unsecure/grpc_unsecure.vcxproj.filters
+++ b/vsprojects/grpc_unsecure/grpc_unsecure.vcxproj.filters
@@ -4,8 +4,8 @@
     <ClCompile Include="..\..\src\core\surface\init_unsecure.c">
       <Filter>src\core\surface</Filter>
     </ClCompile>
-    <ClCompile Include="..\..\src\core\channel\census_filter.c">
-      <Filter>src\core\channel</Filter>
+    <ClCompile Include="..\..\src\core\census\grpc_context.c">
+      <Filter>src\core\census</Filter>
     </ClCompile>
     <ClCompile Include="..\..\src\core\channel\channel_args.c">
       <Filter>src\core\channel</Filter>
@@ -160,24 +160,6 @@
     <ClCompile Include="..\..\src\core\profiling\stap_timers.c">
       <Filter>src\core\profiling</Filter>
     </ClCompile>
-    <ClCompile Include="..\..\src\core\statistics\census_init.c">
-      <Filter>src\core\statistics</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\src\core\statistics\census_log.c">
-      <Filter>src\core\statistics</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\src\core\statistics\census_rpc_stats.c">
-      <Filter>src\core\statistics</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\src\core\statistics\census_tracing.c">
-      <Filter>src\core\statistics</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\src\core\statistics\hash_table.c">
-      <Filter>src\core\statistics</Filter>
-    </ClCompile>
-    <ClCompile Include="..\..\src\core\statistics\window_stats.c">
-      <Filter>src\core\statistics</Filter>
-    </ClCompile>
     <ClCompile Include="..\..\src\core\surface\byte_buffer.c">
       <Filter>src\core\surface</Filter>
     </ClCompile>
@@ -295,6 +277,12 @@
     <ClCompile Include="..\..\src\core\transport\transport_op_string.c">
       <Filter>src\core\transport</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\src\core\census\context.c">
+      <Filter>src\core\census</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\src\core\census\initialize.c">
+      <Filter>src\core\census</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="..\..\include\grpc\byte_buffer.h">
@@ -309,10 +297,13 @@
     <ClInclude Include="..\..\include\grpc\status.h">
       <Filter>include\grpc</Filter>
     </ClInclude>
+    <ClInclude Include="..\..\include\grpc\census.h">
+      <Filter>include\grpc</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
-    <ClInclude Include="..\..\src\core\channel\census_filter.h">
-      <Filter>src\core\channel</Filter>
+    <ClInclude Include="..\..\src\core\census\grpc_context.h">
+      <Filter>src\core\census</Filter>
     </ClInclude>
     <ClInclude Include="..\..\src\core\channel\channel_args.h">
       <Filter>src\core\channel</Filter>
@@ -458,24 +449,6 @@
     <ClInclude Include="..\..\src\core\profiling\timers_preciseclock.h">
       <Filter>src\core\profiling</Filter>
     </ClInclude>
-    <ClInclude Include="..\..\src\core\statistics\census_interface.h">
-      <Filter>src\core\statistics</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\core\statistics\census_log.h">
-      <Filter>src\core\statistics</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\core\statistics\census_rpc_stats.h">
-      <Filter>src\core\statistics</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\core\statistics\census_tracing.h">
-      <Filter>src\core\statistics</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\core\statistics\hash_table.h">
-      <Filter>src\core\statistics</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\src\core\statistics\window_stats.h">
-      <Filter>src\core\statistics</Filter>
-    </ClInclude>
     <ClInclude Include="..\..\src\core\surface\byte_buffer_queue.h">
       <Filter>src\core\surface</Filter>
     </ClInclude>
@@ -572,6 +545,9 @@
     <ClInclude Include="..\..\src\core\transport\transport_impl.h">
       <Filter>src\core\transport</Filter>
     </ClInclude>
+    <ClInclude Include="..\..\src\core\census\context.h">
+      <Filter>src\core\census</Filter>
+    </ClInclude>
   </ItemGroup>
 
   <ItemGroup>
@@ -587,6 +563,9 @@
     <Filter Include="src\core">
       <UniqueIdentifier>{88491077-386b-2039-d14c-0c40136b5f7a}</UniqueIdentifier>
     </Filter>
+    <Filter Include="src\core\census">
+      <UniqueIdentifier>{a7596ee2-afee-3a82-7e6e-bd8b8f904e04}</UniqueIdentifier>
+    </Filter>
     <Filter Include="src\core\channel">
       <UniqueIdentifier>{cc102c4b-66ff-cf4c-2288-d76327e1a183}</UniqueIdentifier>
     </Filter>
@@ -605,9 +584,6 @@
     <Filter Include="src\core\profiling">
       <UniqueIdentifier>{7f91d9bf-c9de-835a-d74d-b16f843b89a9}</UniqueIdentifier>
     </Filter>
-    <Filter Include="src\core\statistics">
-      <UniqueIdentifier>{e084164c-a069-00e3-db35-4e0b1cd6f0b7}</UniqueIdentifier>
-    </Filter>
     <Filter Include="src\core\surface">
       <UniqueIdentifier>{6cd0127e-c24b-d43c-38f5-198db8d4322a}</UniqueIdentifier>
     </Filter>