Merge github.com:grpc/grpc into qps_driver
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..b51d2c0
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,22 @@
+language: cpp
+before_install:
+  - sudo add-apt-repository ppa:yjwong/gflags -y
+  - sudo add-apt-repository ppa:h-rayflood/llvm -y
+  - sudo apt-get update -qq
+  - sudo apt-get install -qq libgtest-dev libgflags-dev python-virtualenv clang-3.5
+env:
+  global:
+    - RUBY_VERSION=2.1
+  matrix:
+    - CONFIG=dbg TEST=c
+    - CONFIG=dbg TEST=c++
+    - CONFIG=opt TEST=c
+    - CONFIG=opt TEST=c++
+    - CONFIG=opt TEST=node
+    - CONFIG=opt TEST=ruby
+script:
+  - rvm use $RUBY_VERSION
+  - gem install bundler
+  - ./tools/run_tests/run_tests.py -l $TEST -t -j 16 -c $CONFIG -s 4.0
+notifications:
+  email: false
\ No newline at end of file
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 57d176f..b58c356 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -24,27 +24,27 @@
 If you are planning to work on any of the languages other than C and C++, you
 will also need their appropriate development environments.
 
-If you want to work under Windows, we recommend you to use Visual Studio 2013.
+If you want to work under Windows, we recommend the use of Visual Studio 2013.
 The [Community or Express editions](http://www.visualstudio.com/en-us/downloads/download-visual-studio-vs.aspx)
 are free and suitable for developing with grpc. Note however that our test
 environment and tools are available for Unix environments only at the moment.
 
 ## Testing your changes
 
-We provide a tool to help you run our suite of tests in various environments.
+We provide a tool to help run the suite of tests in various environments.
 In order to run most of the available tests, one would need to run:
 
 `./tools/run_tests/run_tests.py`
 
-If you want to run all the possible tests for all possible languages, do this:
+If you want to run all the possible tests for any of the languages {c, c++, node, php, python}, do this:
 
-`./tools/run_tests/run_tests.py -lall -call`
+`./tools/run_tests/run_tests.py -l <lang> -c all`
 
 ## Adding or removing source code
 
 Each language uses its own build system to work. Currently, the root's Makefile
-and the Visual Studio project files are building the C and C++ source code only
-at the moment. In order to ease the maintenance of these files, we have a
+and the Visual Studio project files are building only the C and C++ source code.
+In order to ease the maintenance of these files, we have a
 template system. Please do not contribute manual changes to any of the generated
 files. Instead, modify the template files, or the build.json file, and
 re-generate the project files using the following command:
diff --git a/INSTALL b/INSTALL
index 2f5f29c..50040d7 100644
--- a/INSTALL
+++ b/INSTALL
@@ -9,15 +9,16 @@
 * If you are in a hurry *
 *************************
 
-A typical unix installation won't require any more steps than running:
-
-  $ make
-  # make install
+ $ git clone https://github.com/grpc/grpc.git
+ $ cd grpc
+ $ git submodule update --init
+ $ make 
+ $ sudo make install
 
 You don't need anything else than GNU Make, gcc and autotools. Under a Debian
 or Ubuntu system, this should boil down to the following packages:
 
-  # apt-get install build-essential autoconf libtool
+  $ apt-get install build-essential autoconf libtool
 
 Building the python wrapper requires the following:
 
diff --git a/Makefile b/Makefile
index 9053dc1..840fb55 100644
--- a/Makefile
+++ b/Makefile
@@ -77,7 +77,7 @@
 CPPFLAGS_valgrind = -O0
 OPENSSL_CFLAGS_valgrind = -DPURIFY
 LDFLAGS_valgrind =
-DEFINES_valgrind = _DEBUG DEBUG
+DEFINES_valgrind = _DEBUG DEBUG GRPC_TEST_SLOWDOWN_BUILD_FACTOR=20
 
 VALID_CONFIG_tsan = 1
 REQUIRE_CUSTOM_LIBRARIES_tsan = 1
@@ -87,7 +87,7 @@
 LDXX_tsan = clang++
 CPPFLAGS_tsan = -O1 -fsanitize=thread -fno-omit-frame-pointer
 LDFLAGS_tsan = -fsanitize=thread
-DEFINES_tsan = NDEBUG
+DEFINES_tsan = NDEBUG GRPC_TEST_SLOWDOWN_BUILD_FACTOR=10
 
 VALID_CONFIG_asan = 1
 REQUIRE_CUSTOM_LIBRARIES_asan = 1
@@ -97,7 +97,7 @@
 LDXX_asan = clang++
 CPPFLAGS_asan = -O1 -fsanitize=address -fno-omit-frame-pointer
 LDFLAGS_asan = -fsanitize=address
-DEFINES_asan = NDEBUG
+DEFINES_asan = NDEBUG GRPC_TEST_SLOWDOWN_BUILD_FACTOR=5
 
 VALID_CONFIG_msan = 1
 REQUIRE_CUSTOM_LIBRARIES_msan = 1
@@ -108,7 +108,7 @@
 CPPFLAGS_msan = -O1 -fsanitize=memory -fsanitize-memory-track-origins -fno-omit-frame-pointer -DGTEST_HAS_TR1_TUPLE=0 -DGTEST_USE_OWN_TR1_TUPLE=1
 OPENSSL_CFLAGS_msan = -DPURIFY
 LDFLAGS_msan = -fsanitize=memory -DGTEST_HAS_TR1_TUPLE=0 -DGTEST_USE_OWN_TR1_TUPLE=1
-DEFINES_msan = NDEBUG
+DEFINES_msan = NDEBUG GRPC_TEST_SLOWDOWN_BUILD_FACTOR=20
 
 VALID_CONFIG_ubsan = 1
 REQUIRE_CUSTOM_LIBRARIES_ubsan = 1
@@ -119,7 +119,7 @@
 CPPFLAGS_ubsan = -O1 -fsanitize=undefined -fno-omit-frame-pointer
 OPENSSL_CFLAGS_ubsan = -DPURIFY
 LDFLAGS_ubsan = -fsanitize=undefined
-DEFINES_ubsan = NDEBUG
+DEFINES_ubsan = NDEBUG GRPC_TEST_SLOWDOWN_BUILD_FACTOR=10
 
 VALID_CONFIG_gcov = 1
 CC_gcov = gcc
@@ -143,7 +143,15 @@
 LD = $(LD_$(CONFIG))
 LDXX = $(LDXX_$(CONFIG))
 AR = ar
+ifeq ($(SYSTEM),Linux)
 STRIP = strip --strip-unneeded
+else
+ifeq ($(SYSTEM),Darwin)
+STRIP = strip -x
+else
+STRIP = strip
+endif
+endif
 INSTALL = install
 RM = rm -f
 
@@ -152,6 +160,10 @@
 endif
 
 
+# Detect if we can use C++11
+CXX11_CHECK_CMD = $(CXX) -std=c++11 -o /dev/null -c test/build/c++11.cc
+HAS_CXX11 = $(shell $(CXX11_CHECK_CMD) 2> /dev/null && echo true || echo false)
+
 # The HOST compiler settings are used to compile the protoc plugins.
 # In most cases, you won't have to change anything, but if you are
 # cross-compiling, you can override these variables from GNU make's
@@ -166,8 +178,17 @@
 DEFINES += $(DEFINES_$(CONFIG)) INSTALL_PREFIX=\"$(prefix)\"
 LDFLAGS += $(LDFLAGS_$(CONFIG))
 
+ifdef EXTRA_DEFINES
+DEFINES += $(EXTRA_DEFINES)
+endif
+
 CFLAGS += -std=c89 -pedantic
+ifeq ($(HAS_CXX11),true)
 CXXFLAGS += -std=c++11
+else
+CXXFLAGS += -std=c++0x
+DEFINES += GRPC_OLD_CXX
+endif
 CPPFLAGS += -g -fPIC -Wall -Wextra -Werror -Wno-long-long -Wno-unused-parameter
 LDFLAGS += -g -fPIC
 
@@ -195,7 +216,7 @@
 Q = @
 endif
 
-VERSION = 0.8.0.0
+VERSION = 0.5.0.0
 
 CPPFLAGS_NO_ARCH += $(addprefix -I, $(INCLUDES)) $(addprefix -D, $(DEFINES))
 CPPFLAGS += $(CPPFLAGS_NO_ARCH) $(ARCH_FLAGS)
@@ -509,6 +530,7 @@
 time_test: $(BINDIR)/$(CONFIG)/time_test
 timeout_encoding_test: $(BINDIR)/$(CONFIG)/timeout_encoding_test
 transport_metadata_test: $(BINDIR)/$(CONFIG)/transport_metadata_test
+transport_security_test: $(BINDIR)/$(CONFIG)/transport_security_test
 async_end2end_test: $(BINDIR)/$(CONFIG)/async_end2end_test
 channel_arguments_test: $(BINDIR)/$(CONFIG)/channel_arguments_test
 credentials_test: $(BINDIR)/$(CONFIG)/credentials_test
@@ -523,8 +545,10 @@
 pubsub_publisher_test: $(BINDIR)/$(CONFIG)/pubsub_publisher_test
 pubsub_subscriber_test: $(BINDIR)/$(CONFIG)/pubsub_subscriber_test
 qps_client: $(BINDIR)/$(CONFIG)/qps_client
+qps_client_async: $(BINDIR)/$(CONFIG)/qps_client_async
 qps_driver: $(BINDIR)/$(CONFIG)/qps_driver
 qps_server: $(BINDIR)/$(CONFIG)/qps_server
+qps_server_async: $(BINDIR)/$(CONFIG)/qps_server_async
 status_test: $(BINDIR)/$(CONFIG)/status_test
 thread_pool_test: $(BINDIR)/$(CONFIG)/thread_pool_test
 chttp2_fake_security_cancel_after_accept_test: $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_after_accept_test
@@ -897,7 +921,11 @@
 
 $(LIBDIR)/$(CONFIG)/protobuf/libprotobuf.a: third_party/protobuf/configure
 	$(E) "[MAKE]    Building protobuf"
+ifeq ($(HAVE_CXX11),true)
 	$(Q)(cd third_party/protobuf ; CC="$(CC)" CXX="$(CXX)" LDFLAGS="$(LDFLAGS_$(CONFIG)) -g" CXXFLAGS="-DLANG_CXX11 -std=c++11" CPPFLAGS="-fPIC $(CPPFLAGS_$(CONFIG)) -g" ./configure --disable-shared --enable-static)
+else
+	$(Q)(cd third_party/protobuf ; CC="$(CC)" CXX="$(CXX)" LDFLAGS="$(LDFLAGS_$(CONFIG)) -g" CXXFLAGS="-std=c++0x" CPPFLAGS="-fPIC $(CPPFLAGS_$(CONFIG)) -g" ./configure --disable-shared --enable-static)
+endif
 	$(Q)$(MAKE) -C third_party/protobuf clean
 	$(Q)$(MAKE) -C third_party/protobuf
 	$(Q)mkdir -p $(LIBDIR)/$(CONFIG)/protobuf
@@ -931,9 +959,9 @@
 
 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)/chttp2_transport_end2end_test $(BINDIR)/$(CONFIG)/dualstack_socket_test $(BINDIR)/$(CONFIG)/echo_client $(BINDIR)/$(CONFIG)/echo_server $(BINDIR)/$(CONFIG)/echo_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_useful_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)/metadata_buffer_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)/transport_metadata_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_no_op_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_ping_pong_streaming_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_with_large_metadata_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_simple_delayed_request_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_thread_stress_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_writes_done_hangs_with_pending_read_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_after_accept_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_after_accept_and_writes_closed_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_after_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_before_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_in_a_vacuum_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_census_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_disappearing_server_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_early_server_shutdown_finishes_inflight_calls_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_early_server_shutdown_finishes_tags_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_graceful_server_shutdown_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_invoke_large_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_max_concurrent_streams_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_no_op_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_ping_pong_streaming_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_response_with_binary_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_response_with_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_response_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_response_with_trailing_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_with_large_metadata_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_simple_delayed_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_thread_stress_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_writes_done_hangs_with_pending_read_legacy_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_no_op_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_ping_pong_streaming_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_with_large_metadata_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_simple_delayed_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_thread_stress_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_writes_done_hangs_with_pending_read_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_after_accept_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_after_accept_and_writes_closed_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_after_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_before_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_in_a_vacuum_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_census_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_disappearing_server_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_early_server_shutdown_finishes_inflight_calls_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_early_server_shutdown_finishes_tags_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_graceful_server_shutdown_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_invoke_large_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_max_concurrent_streams_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_no_op_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_ping_pong_streaming_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_response_with_binary_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_response_with_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_response_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_response_with_trailing_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_with_large_metadata_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_simple_delayed_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_thread_stress_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_writes_done_hangs_with_pending_read_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_after_accept_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_after_accept_and_writes_closed_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_census_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_disappearing_server_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_early_server_shutdown_finishes_inflight_calls_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_early_server_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_empty_batch_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_invoke_large_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_no_op_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_response_with_binary_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_response_with_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_response_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_with_large_metadata_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_simple_delayed_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_thread_stress_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_writes_done_hangs_with_pending_read_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_after_accept_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_after_accept_and_writes_closed_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_after_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_before_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_in_a_vacuum_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_census_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_disappearing_server_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_early_server_shutdown_finishes_inflight_calls_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_early_server_shutdown_finishes_tags_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_graceful_server_shutdown_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_invoke_large_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_max_concurrent_streams_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_no_op_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_ping_pong_streaming_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_response_with_binary_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_response_with_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_response_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_response_with_trailing_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_with_large_metadata_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_simple_delayed_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_thread_stress_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_writes_done_hangs_with_pending_read_legacy_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_no_op_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_ping_pong_streaming_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_with_large_metadata_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_with_payload_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_thread_stress_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_writes_done_hangs_with_pending_read_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_after_accept_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_after_accept_and_writes_closed_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_after_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_before_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_in_a_vacuum_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_census_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_disappearing_server_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_inflight_calls_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_tags_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_graceful_server_shutdown_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_invoke_large_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_max_concurrent_streams_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_no_op_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_ping_pong_streaming_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_response_with_binary_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_response_with_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_response_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_response_with_trailing_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_with_large_metadata_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_simple_delayed_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_thread_stress_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_writes_done_hangs_with_pending_read_legacy_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_no_op_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_ping_pong_streaming_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_with_large_metadata_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_with_payload_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_thread_stress_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_writes_done_hangs_with_pending_read_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_accept_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_accept_and_writes_closed_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_before_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_in_a_vacuum_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_census_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_disappearing_server_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_inflight_calls_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_tags_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_graceful_server_shutdown_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_invoke_large_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_max_concurrent_streams_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_no_op_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_ping_pong_streaming_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_binary_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_trailing_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_with_large_metadata_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_simple_delayed_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_thread_stress_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_writes_done_hangs_with_pending_read_legacy_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_no_op_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_ping_pong_streaming_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_with_large_metadata_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_simple_delayed_request_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_thread_stress_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_writes_done_hangs_with_pending_read_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_after_accept_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_after_accept_and_writes_closed_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_after_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_before_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_in_a_vacuum_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_census_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_disappearing_server_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_early_server_shutdown_finishes_inflight_calls_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_early_server_shutdown_finishes_tags_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_graceful_server_shutdown_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_invoke_large_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_max_concurrent_streams_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_no_op_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_ping_pong_streaming_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_response_with_binary_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_response_with_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_response_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_response_with_trailing_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_with_large_metadata_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_simple_delayed_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_thread_stress_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_writes_done_hangs_with_pending_read_legacy_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_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_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_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_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_thread_stress_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_writes_done_hangs_with_pending_read_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_and_writes_closed_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_after_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_before_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_in_a_vacuum_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_census_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_disappearing_server_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_inflight_calls_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_tags_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_graceful_server_shutdown_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_invoke_large_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_max_concurrent_streams_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_no_op_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_ping_pong_streaming_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_response_with_binary_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_response_with_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_response_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_response_with_trailing_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_with_large_metadata_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_simple_delayed_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_thread_stress_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_writes_done_hangs_with_pending_read_legacy_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)/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)/chttp2_transport_end2end_test $(BINDIR)/$(CONFIG)/dualstack_socket_test $(BINDIR)/$(CONFIG)/echo_client $(BINDIR)/$(CONFIG)/echo_server $(BINDIR)/$(CONFIG)/echo_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_useful_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)/metadata_buffer_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)/transport_metadata_test $(BINDIR)/$(CONFIG)/transport_security_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_no_op_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_ping_pong_streaming_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_with_large_metadata_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_simple_delayed_request_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_thread_stress_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_writes_done_hangs_with_pending_read_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_after_accept_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_after_accept_and_writes_closed_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_after_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_before_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_in_a_vacuum_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_census_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_disappearing_server_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_early_server_shutdown_finishes_inflight_calls_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_early_server_shutdown_finishes_tags_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_graceful_server_shutdown_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_invoke_large_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_max_concurrent_streams_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_no_op_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_ping_pong_streaming_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_response_with_binary_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_response_with_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_response_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_response_with_trailing_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_with_large_metadata_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_simple_delayed_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_thread_stress_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_writes_done_hangs_with_pending_read_legacy_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_no_op_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_ping_pong_streaming_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_with_large_metadata_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_simple_delayed_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_thread_stress_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_writes_done_hangs_with_pending_read_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_after_accept_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_after_accept_and_writes_closed_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_after_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_before_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_in_a_vacuum_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_census_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_disappearing_server_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_early_server_shutdown_finishes_inflight_calls_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_early_server_shutdown_finishes_tags_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_graceful_server_shutdown_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_invoke_large_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_max_concurrent_streams_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_no_op_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_ping_pong_streaming_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_response_with_binary_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_response_with_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_response_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_response_with_trailing_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_with_large_metadata_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_simple_delayed_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_thread_stress_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_writes_done_hangs_with_pending_read_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_after_accept_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_after_accept_and_writes_closed_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_census_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_disappearing_server_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_early_server_shutdown_finishes_inflight_calls_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_early_server_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_empty_batch_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_invoke_large_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_no_op_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_response_with_binary_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_response_with_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_response_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_with_large_metadata_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_simple_delayed_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_thread_stress_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_writes_done_hangs_with_pending_read_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_after_accept_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_after_accept_and_writes_closed_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_after_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_before_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_in_a_vacuum_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_census_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_disappearing_server_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_early_server_shutdown_finishes_inflight_calls_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_early_server_shutdown_finishes_tags_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_graceful_server_shutdown_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_invoke_large_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_max_concurrent_streams_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_no_op_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_ping_pong_streaming_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_response_with_binary_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_response_with_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_response_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_response_with_trailing_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_with_large_metadata_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_simple_delayed_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_thread_stress_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_writes_done_hangs_with_pending_read_legacy_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_no_op_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_ping_pong_streaming_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_with_large_metadata_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_with_payload_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_thread_stress_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_writes_done_hangs_with_pending_read_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_after_accept_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_after_accept_and_writes_closed_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_after_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_before_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_in_a_vacuum_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_census_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_disappearing_server_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_inflight_calls_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_tags_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_graceful_server_shutdown_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_invoke_large_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_max_concurrent_streams_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_no_op_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_ping_pong_streaming_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_response_with_binary_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_response_with_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_response_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_response_with_trailing_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_with_large_metadata_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_simple_delayed_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_thread_stress_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_writes_done_hangs_with_pending_read_legacy_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_no_op_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_ping_pong_streaming_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_with_large_metadata_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_with_payload_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_thread_stress_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_writes_done_hangs_with_pending_read_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_accept_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_accept_and_writes_closed_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_before_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_in_a_vacuum_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_census_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_disappearing_server_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_inflight_calls_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_tags_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_graceful_server_shutdown_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_invoke_large_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_max_concurrent_streams_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_no_op_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_ping_pong_streaming_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_binary_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_trailing_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_with_large_metadata_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_simple_delayed_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_thread_stress_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_writes_done_hangs_with_pending_read_legacy_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_no_op_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_ping_pong_streaming_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_with_large_metadata_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_simple_delayed_request_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_thread_stress_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_writes_done_hangs_with_pending_read_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_after_accept_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_after_accept_and_writes_closed_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_after_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_before_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_in_a_vacuum_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_census_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_disappearing_server_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_early_server_shutdown_finishes_inflight_calls_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_early_server_shutdown_finishes_tags_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_graceful_server_shutdown_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_invoke_large_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_max_concurrent_streams_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_no_op_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_ping_pong_streaming_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_response_with_binary_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_response_with_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_response_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_response_with_trailing_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_with_large_metadata_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_simple_delayed_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_thread_stress_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_writes_done_hangs_with_pending_read_legacy_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_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_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_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_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_thread_stress_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_writes_done_hangs_with_pending_read_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_and_writes_closed_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_after_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_before_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_in_a_vacuum_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_census_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_disappearing_server_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_inflight_calls_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_tags_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_graceful_server_shutdown_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_invoke_large_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_max_concurrent_streams_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_no_op_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_ping_pong_streaming_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_response_with_binary_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_response_with_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_response_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_response_with_trailing_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_with_large_metadata_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_simple_delayed_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_thread_stress_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_writes_done_hangs_with_pending_read_legacy_test
 
-buildtests_cxx: privatelibs_cxx $(BINDIR)/$(CONFIG)/async_end2end_test $(BINDIR)/$(CONFIG)/channel_arguments_test $(BINDIR)/$(CONFIG)/credentials_test $(BINDIR)/$(CONFIG)/end2end_test $(BINDIR)/$(CONFIG)/interop_client $(BINDIR)/$(CONFIG)/interop_server $(BINDIR)/$(CONFIG)/interop_test $(BINDIR)/$(CONFIG)/pubsub_client $(BINDIR)/$(CONFIG)/pubsub_publisher_test $(BINDIR)/$(CONFIG)/pubsub_subscriber_test $(BINDIR)/$(CONFIG)/qps_client $(BINDIR)/$(CONFIG)/qps_driver $(BINDIR)/$(CONFIG)/qps_server $(BINDIR)/$(CONFIG)/status_test $(BINDIR)/$(CONFIG)/thread_pool_test
+buildtests_cxx: privatelibs_cxx $(BINDIR)/$(CONFIG)/async_end2end_test $(BINDIR)/$(CONFIG)/channel_arguments_test $(BINDIR)/$(CONFIG)/credentials_test $(BINDIR)/$(CONFIG)/end2end_test $(BINDIR)/$(CONFIG)/interop_client $(BINDIR)/$(CONFIG)/interop_server $(BINDIR)/$(CONFIG)/interop_test $(BINDIR)/$(CONFIG)/pubsub_client $(BINDIR)/$(CONFIG)/pubsub_publisher_test $(BINDIR)/$(CONFIG)/pubsub_subscriber_test $(BINDIR)/$(CONFIG)/qps_client $(BINDIR)/$(CONFIG)/qps_client_async $(BINDIR)/$(CONFIG)/qps_driver $(BINDIR)/$(CONFIG)/qps_server $(BINDIR)/$(CONFIG)/qps_server_async $(BINDIR)/$(CONFIG)/status_test $(BINDIR)/$(CONFIG)/thread_pool_test
 
 test: test_c test_cxx
 
@@ -1070,6 +1098,8 @@
 	$(Q) $(BINDIR)/$(CONFIG)/timeout_encoding_test || ( echo test timeout_encoding_test failed ; exit 1 )
 	$(E) "[RUN]     Testing transport_metadata_test"
 	$(Q) $(BINDIR)/$(CONFIG)/transport_metadata_test || ( echo test transport_metadata_test failed ; exit 1 )
+	$(E) "[RUN]     Testing transport_security_test"
+	$(Q) $(BINDIR)/$(CONFIG)/transport_security_test || ( echo test transport_security_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_cancel_after_accept_and_writes_closed_test"
@@ -7492,6 +7522,37 @@
 endif
 
 
+TRANSPORT_SECURITY_TEST_SRC = \
+    test/core/tsi/transport_security_test.c \
+
+TRANSPORT_SECURITY_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(TRANSPORT_SECURITY_TEST_SRC))))
+
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure targets if you don't have OpenSSL with ALPN.
+
+$(BINDIR)/$(CONFIG)/transport_security_test: openssl_dep_error
+
+else
+
+$(BINDIR)/$(CONFIG)/transport_security_test: $(TRANSPORT_SECURITY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+	$(E) "[LD]      Linking $@"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(LD) $(LDFLAGS) $(TRANSPORT_SECURITY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/transport_security_test
+
+endif
+
+$(OBJDIR)/$(CONFIG)/test/core/tsi/transport_security_test.o:  $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+deps_transport_security_test: $(TRANSPORT_SECURITY_TEST_OBJS:.o=.dep)
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(TRANSPORT_SECURITY_TEST_OBJS:.o=.dep)
+endif
+endif
+
+
 ASYNC_END2END_TEST_SRC = \
     test/cpp/end2end/async_end2end_test.cc \
 
@@ -7505,13 +7566,24 @@
 
 else
 
-$(BINDIR)/$(CONFIG)/async_end2end_test: $(ASYNC_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+ifeq ($(NO_PROTOBUF),true)
+
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+
+$(BINDIR)/$(CONFIG)/async_end2end_test: protobuf_dep_error
+
+else
+
+$(BINDIR)/$(CONFIG)/async_end2end_test: $(PROTOBUF_DEP) $(ASYNC_END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) $(LDXX) $(LDFLAGS) $(ASYNC_END2END_TEST_OBJS) $(GTEST_LIB) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/async_end2end_test
 
 endif
 
+endif
+
 $(OBJDIR)/$(CONFIG)/test/cpp/end2end/async_end2end_test.o:  $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 
 deps_async_end2end_test: $(ASYNC_END2END_TEST_OBJS:.o=.dep)
@@ -7536,13 +7608,24 @@
 
 else
 
-$(BINDIR)/$(CONFIG)/channel_arguments_test: $(CHANNEL_ARGUMENTS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+ifeq ($(NO_PROTOBUF),true)
+
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+
+$(BINDIR)/$(CONFIG)/channel_arguments_test: protobuf_dep_error
+
+else
+
+$(BINDIR)/$(CONFIG)/channel_arguments_test: $(PROTOBUF_DEP) $(CHANNEL_ARGUMENTS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) $(LDXX) $(LDFLAGS) $(CHANNEL_ARGUMENTS_TEST_OBJS) $(GTEST_LIB) $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/channel_arguments_test
 
 endif
 
+endif
+
 $(OBJDIR)/$(CONFIG)/test/cpp/client/channel_arguments_test.o:  $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
 
 deps_channel_arguments_test: $(CHANNEL_ARGUMENTS_TEST_OBJS:.o=.dep)
@@ -7567,13 +7650,24 @@
 
 else
 
-$(BINDIR)/$(CONFIG)/credentials_test: $(CREDENTIALS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+ifeq ($(NO_PROTOBUF),true)
+
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+
+$(BINDIR)/$(CONFIG)/credentials_test: protobuf_dep_error
+
+else
+
+$(BINDIR)/$(CONFIG)/credentials_test: $(PROTOBUF_DEP) $(CREDENTIALS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) $(LDXX) $(LDFLAGS) $(CREDENTIALS_TEST_OBJS) $(GTEST_LIB) $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/credentials_test
 
 endif
 
+endif
+
 $(OBJDIR)/$(CONFIG)/test/cpp/client/credentials_test.o:  $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
 
 deps_credentials_test: $(CREDENTIALS_TEST_OBJS:.o=.dep)
@@ -7598,13 +7692,24 @@
 
 else
 
-$(BINDIR)/$(CONFIG)/end2end_test: $(END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+ifeq ($(NO_PROTOBUF),true)
+
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+
+$(BINDIR)/$(CONFIG)/end2end_test: protobuf_dep_error
+
+else
+
+$(BINDIR)/$(CONFIG)/end2end_test: $(PROTOBUF_DEP) $(END2END_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) $(LDXX) $(LDFLAGS) $(END2END_TEST_OBJS) $(GTEST_LIB) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/end2end_test
 
 endif
 
+endif
+
 $(OBJDIR)/$(CONFIG)/test/cpp/end2end/end2end_test.o:  $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 
 deps_end2end_test: $(END2END_TEST_OBJS:.o=.dep)
@@ -7625,7 +7730,7 @@
 
 ifeq ($(NO_PROTOBUF),true)
 
-# You can't build the protoc plugins if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
 
 $(BINDIR)/$(CONFIG)/grpc_cpp_plugin: protobuf_dep_error
 
@@ -7657,7 +7762,7 @@
 
 ifeq ($(NO_PROTOBUF),true)
 
-# You can't build the protoc plugins if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
 
 $(BINDIR)/$(CONFIG)/grpc_python_plugin: protobuf_dep_error
 
@@ -7689,7 +7794,7 @@
 
 ifeq ($(NO_PROTOBUF),true)
 
-# You can't build the protoc plugins if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
 
 $(BINDIR)/$(CONFIG)/grpc_ruby_plugin: protobuf_dep_error
 
@@ -7728,13 +7833,24 @@
 
 else
 
-$(BINDIR)/$(CONFIG)/interop_client: $(INTEROP_CLIENT_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+ifeq ($(NO_PROTOBUF),true)
+
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+
+$(BINDIR)/$(CONFIG)/interop_client: protobuf_dep_error
+
+else
+
+$(BINDIR)/$(CONFIG)/interop_client: $(PROTOBUF_DEP) $(INTEROP_CLIENT_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) $(LDXX) $(LDFLAGS) $(INTEROP_CLIENT_OBJS) $(GTEST_LIB) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/interop_client
 
 endif
 
+endif
+
 $(OBJDIR)/$(CONFIG)/test/cpp/interop/empty.o:  $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 $(OBJDIR)/$(CONFIG)/test/cpp/interop/messages.o:  $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 $(OBJDIR)/$(CONFIG)/test/cpp/interop/test.o:  $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
@@ -7765,13 +7881,24 @@
 
 else
 
-$(BINDIR)/$(CONFIG)/interop_server: $(INTEROP_SERVER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+ifeq ($(NO_PROTOBUF),true)
+
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+
+$(BINDIR)/$(CONFIG)/interop_server: protobuf_dep_error
+
+else
+
+$(BINDIR)/$(CONFIG)/interop_server: $(PROTOBUF_DEP) $(INTEROP_SERVER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) $(LDXX) $(LDFLAGS) $(INTEROP_SERVER_OBJS) $(GTEST_LIB) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/interop_server
 
 endif
 
+endif
+
 $(OBJDIR)/$(CONFIG)/test/cpp/interop/empty.o:  $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 $(OBJDIR)/$(CONFIG)/test/cpp/interop/messages.o:  $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 $(OBJDIR)/$(CONFIG)/test/cpp/interop/test.o:  $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
@@ -7799,13 +7926,24 @@
 
 else
 
-$(BINDIR)/$(CONFIG)/interop_test: $(INTEROP_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+ifeq ($(NO_PROTOBUF),true)
+
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+
+$(BINDIR)/$(CONFIG)/interop_test: protobuf_dep_error
+
+else
+
+$(BINDIR)/$(CONFIG)/interop_test: $(PROTOBUF_DEP) $(INTEROP_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) $(LDXX) $(LDFLAGS) $(INTEROP_TEST_OBJS) $(GTEST_LIB) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/interop_test
 
 endif
 
+endif
+
 $(OBJDIR)/$(CONFIG)/test/cpp/interop/interop_test.o:  $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 
 deps_interop_test: $(INTEROP_TEST_OBJS:.o=.dep)
@@ -7830,13 +7968,24 @@
 
 else
 
-$(BINDIR)/$(CONFIG)/pubsub_client: $(PUBSUB_CLIENT_OBJS) $(LIBDIR)/$(CONFIG)/libpubsub_client_lib.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+ifeq ($(NO_PROTOBUF),true)
+
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+
+$(BINDIR)/$(CONFIG)/pubsub_client: protobuf_dep_error
+
+else
+
+$(BINDIR)/$(CONFIG)/pubsub_client: $(PROTOBUF_DEP) $(PUBSUB_CLIENT_OBJS) $(LIBDIR)/$(CONFIG)/libpubsub_client_lib.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) $(LDXX) $(LDFLAGS) $(PUBSUB_CLIENT_OBJS) $(GTEST_LIB) $(LIBDIR)/$(CONFIG)/libpubsub_client_lib.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/pubsub_client
 
 endif
 
+endif
+
 $(OBJDIR)/$(CONFIG)/examples/pubsub/main.o:  $(LIBDIR)/$(CONFIG)/libpubsub_client_lib.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 
 deps_pubsub_client: $(PUBSUB_CLIENT_OBJS:.o=.dep)
@@ -7861,13 +8010,24 @@
 
 else
 
-$(BINDIR)/$(CONFIG)/pubsub_publisher_test: $(PUBSUB_PUBLISHER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libpubsub_client_lib.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+ifeq ($(NO_PROTOBUF),true)
+
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+
+$(BINDIR)/$(CONFIG)/pubsub_publisher_test: protobuf_dep_error
+
+else
+
+$(BINDIR)/$(CONFIG)/pubsub_publisher_test: $(PROTOBUF_DEP) $(PUBSUB_PUBLISHER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libpubsub_client_lib.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) $(LDXX) $(LDFLAGS) $(PUBSUB_PUBLISHER_TEST_OBJS) $(GTEST_LIB) $(LIBDIR)/$(CONFIG)/libpubsub_client_lib.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/pubsub_publisher_test
 
 endif
 
+endif
+
 $(OBJDIR)/$(CONFIG)/examples/pubsub/publisher_test.o:  $(LIBDIR)/$(CONFIG)/libpubsub_client_lib.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 
 deps_pubsub_publisher_test: $(PUBSUB_PUBLISHER_TEST_OBJS:.o=.dep)
@@ -7892,13 +8052,24 @@
 
 else
 
-$(BINDIR)/$(CONFIG)/pubsub_subscriber_test: $(PUBSUB_SUBSCRIBER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libpubsub_client_lib.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+ifeq ($(NO_PROTOBUF),true)
+
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+
+$(BINDIR)/$(CONFIG)/pubsub_subscriber_test: protobuf_dep_error
+
+else
+
+$(BINDIR)/$(CONFIG)/pubsub_subscriber_test: $(PROTOBUF_DEP) $(PUBSUB_SUBSCRIBER_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libpubsub_client_lib.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) $(LDXX) $(LDFLAGS) $(PUBSUB_SUBSCRIBER_TEST_OBJS) $(GTEST_LIB) $(LIBDIR)/$(CONFIG)/libpubsub_client_lib.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/pubsub_subscriber_test
 
 endif
 
+endif
+
 $(OBJDIR)/$(CONFIG)/examples/pubsub/subscriber_test.o:  $(LIBDIR)/$(CONFIG)/libpubsub_client_lib.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 
 deps_pubsub_subscriber_test: $(PUBSUB_SUBSCRIBER_TEST_OBJS:.o=.dep)
@@ -7923,13 +8094,24 @@
 
 else
 
-$(BINDIR)/$(CONFIG)/qps_client: $(QPS_CLIENT_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+ifeq ($(NO_PROTOBUF),true)
+
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+
+$(BINDIR)/$(CONFIG)/qps_client: protobuf_dep_error
+
+else
+
+$(BINDIR)/$(CONFIG)/qps_client: $(PROTOBUF_DEP) $(QPS_CLIENT_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) $(LDXX) $(LDFLAGS) $(QPS_CLIENT_OBJS) $(GTEST_LIB) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/qps_client
 
 endif
 
+endif
+
 $(OBJDIR)/$(CONFIG)/test/cpp/qps/client.o:  $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 
 deps_qps_client: $(QPS_CLIENT_OBJS:.o=.dep)
@@ -7941,6 +8123,50 @@
 endif
 
 
+QPS_CLIENT_ASYNC_SRC = \
+    $(GENDIR)/test/cpp/qps/qpstest.pb.cc \
+    test/cpp/qps/client_async.cc \
+
+QPS_CLIENT_ASYNC_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(QPS_CLIENT_ASYNC_SRC))))
+
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure targets if you don't have OpenSSL with ALPN.
+
+$(BINDIR)/$(CONFIG)/qps_client_async: openssl_dep_error
+
+else
+
+
+ifeq ($(NO_PROTOBUF),true)
+
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+
+$(BINDIR)/$(CONFIG)/qps_client_async: protobuf_dep_error
+
+else
+
+$(BINDIR)/$(CONFIG)/qps_client_async: $(PROTOBUF_DEP) $(QPS_CLIENT_ASYNC_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+	$(E) "[LD]      Linking $@"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(LDXX) $(LDFLAGS) $(QPS_CLIENT_ASYNC_OBJS) $(GTEST_LIB) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/qps_client_async
+
+endif
+
+endif
+
+$(OBJDIR)/$(CONFIG)/test/cpp/qps/qpstest.o:  $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(OBJDIR)/$(CONFIG)/test/cpp/qps/client_async.o:  $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+deps_qps_client_async: $(QPS_CLIENT_ASYNC_OBJS:.o=.dep)
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(QPS_CLIENT_ASYNC_OBJS:.o=.dep)
+endif
+endif
+
+
 QPS_DRIVER_SRC = \
     test/cpp/qps/qps_driver.cc \
 
@@ -7954,13 +8180,24 @@
 
 else
 
-$(BINDIR)/$(CONFIG)/qps_driver: $(QPS_DRIVER_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+ifeq ($(NO_PROTOBUF),true)
+
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+
+$(BINDIR)/$(CONFIG)/qps_driver: protobuf_dep_error
+
+else
+
+$(BINDIR)/$(CONFIG)/qps_driver: $(PROTOBUF_DEP) $(QPS_DRIVER_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) $(LDXX) $(LDFLAGS) $(QPS_DRIVER_OBJS) $(GTEST_LIB) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/qps_driver
 
 endif
 
+endif
+
 $(OBJDIR)/$(CONFIG)/test/cpp/qps/qps_driver.o:  $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 
 deps_qps_driver: $(QPS_DRIVER_OBJS:.o=.dep)
@@ -7985,13 +8222,24 @@
 
 else
 
-$(BINDIR)/$(CONFIG)/qps_server: $(QPS_SERVER_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+ifeq ($(NO_PROTOBUF),true)
+
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+
+$(BINDIR)/$(CONFIG)/qps_server: protobuf_dep_error
+
+else
+
+$(BINDIR)/$(CONFIG)/qps_server: $(PROTOBUF_DEP) $(QPS_SERVER_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) $(LDXX) $(LDFLAGS) $(QPS_SERVER_OBJS) $(GTEST_LIB) $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/qps_server
 
 endif
 
+endif
+
 $(OBJDIR)/$(CONFIG)/test/cpp/qps/server.o:  $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 
 deps_qps_server: $(QPS_SERVER_OBJS:.o=.dep)
@@ -8003,6 +8251,50 @@
 endif
 
 
+QPS_SERVER_ASYNC_SRC = \
+    $(GENDIR)/test/cpp/qps/qpstest.pb.cc \
+    test/cpp/qps/server_async.cc \
+
+QPS_SERVER_ASYNC_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(QPS_SERVER_ASYNC_SRC))))
+
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure targets if you don't have OpenSSL with ALPN.
+
+$(BINDIR)/$(CONFIG)/qps_server_async: openssl_dep_error
+
+else
+
+
+ifeq ($(NO_PROTOBUF),true)
+
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+
+$(BINDIR)/$(CONFIG)/qps_server_async: protobuf_dep_error
+
+else
+
+$(BINDIR)/$(CONFIG)/qps_server_async: $(PROTOBUF_DEP) $(QPS_SERVER_ASYNC_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+	$(E) "[LD]      Linking $@"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(LDXX) $(LDFLAGS) $(QPS_SERVER_ASYNC_OBJS) $(GTEST_LIB) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/qps_server_async
+
+endif
+
+endif
+
+$(OBJDIR)/$(CONFIG)/test/cpp/qps/qpstest.o:  $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(OBJDIR)/$(CONFIG)/test/cpp/qps/server_async.o:  $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+deps_qps_server_async: $(QPS_SERVER_ASYNC_OBJS:.o=.dep)
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(QPS_SERVER_ASYNC_OBJS:.o=.dep)
+endif
+endif
+
+
 STATUS_TEST_SRC = \
     test/cpp/util/status_test.cc \
 
@@ -8016,13 +8308,24 @@
 
 else
 
-$(BINDIR)/$(CONFIG)/status_test: $(STATUS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+ifeq ($(NO_PROTOBUF),true)
+
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+
+$(BINDIR)/$(CONFIG)/status_test: protobuf_dep_error
+
+else
+
+$(BINDIR)/$(CONFIG)/status_test: $(PROTOBUF_DEP) $(STATUS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) $(LDXX) $(LDFLAGS) $(STATUS_TEST_OBJS) $(GTEST_LIB) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/status_test
 
 endif
 
+endif
+
 $(OBJDIR)/$(CONFIG)/test/cpp/util/status_test.o:  $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 
 deps_status_test: $(STATUS_TEST_OBJS:.o=.dep)
@@ -8047,13 +8350,24 @@
 
 else
 
-$(BINDIR)/$(CONFIG)/thread_pool_test: $(THREAD_POOL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+ifeq ($(NO_PROTOBUF),true)
+
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+
+$(BINDIR)/$(CONFIG)/thread_pool_test: protobuf_dep_error
+
+else
+
+$(BINDIR)/$(CONFIG)/thread_pool_test: $(PROTOBUF_DEP) $(THREAD_POOL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
 	$(Q) $(LDXX) $(LDFLAGS) $(THREAD_POOL_TEST_OBJS) $(GTEST_LIB) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/thread_pool_test
 
 endif
 
+endif
+
 $(OBJDIR)/$(CONFIG)/test/cpp/server/thread_pool_test.o:  $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 
 deps_thread_pool_test: $(THREAD_POOL_TEST_OBJS:.o=.dep)
diff --git a/PATENTS b/PATENTS
new file mode 100644
index 0000000..619f9db
--- /dev/null
+++ b/PATENTS
@@ -0,0 +1,22 @@
+Additional IP Rights Grant (Patents)
+
+"This implementation" means the copyrightable works distributed by
+Google as part of the GRPC project.
+
+Google hereby grants to You a perpetual, worldwide, non-exclusive,
+no-charge, royalty-free, irrevocable (except as stated in this section)
+patent license to make, have made, use, offer to sell, sell, import,
+transfer and otherwise run, modify and propagate the contents of this
+implementation of GRPC, where such license applies only to those patent
+claims, both currently owned or controlled by Google and acquired in
+the future, licensable by Google that are necessarily infringed by this
+implementation of GRPC.  This grant does not include claims that would be
+infringed only as a consequence of further modification of this
+implementation.  If you or your agent or exclusive licensee institute or
+order or agree to the institution of patent litigation against any
+entity (including a cross-claim or counterclaim in a lawsuit) alleging
+that this implementation of GRPC or any code incorporated within this
+implementation of GRPC constitutes direct or contributory patent
+infringement, or inducement of patent infringement, then any patent
+rights granted to you under this License for this implementation of GRPC
+shall terminate as of the date such litigation is filed.
diff --git a/README.md b/README.md
index fc35934..8fa9fa4 100644
--- a/README.md
+++ b/README.md
@@ -9,13 +9,13 @@
 
 #Repository Structure
 
-This repository contains source code for gRPC libraries for multiple lanugages written on top
+This repository contains source code for gRPC libraries for multiple languages written on top
 of shared C core library [src/core] (src/core).
 
    * C++ source code: [src/cpp] (src/cpp)
-   * Python source code: [src/python] (src/python)
    * Ruby source code: [src/ruby] (src/ruby)
    * NodeJS source code: [src/node] (src/node)
+   * Python source code: [src/python] (src/python)
    * PHP source code: [src/php] (src/php)
    * C# source code: [src/csharp] (src/csharp)
    * Objective-C source code: [src/objective-c] (src/objective-c)
@@ -33,9 +33,9 @@
 
    * shared C core library [src/core] (src/core) : Early adopter ready - Alpha.
    * C++ Library: [src/cpp] (src/cpp) : Early adopter ready - Alpha.
-   * Python Library: [src/python] (src/python) : Early adopter ready - Alpha.
    * Ruby Library: [src/ruby] (src/ruby) : Early adopter ready - Alpha.
    * NodeJS Library: [src/node] (src/node) : Early adopter ready - Alpha.
+   * Python Library: [src/python] (src/python) : Usable with limitations - Pre-Alpha.
    * PHP Library: [src/php] (src/php) : Pre-Alpha.
    * C# Library: [src/csharp] (src/csharp) : Pre-Alpha.
    * Objective-C Library: [src/objective-c] (src/objective-c): Pre-Alpha.
diff --git a/build.json b/build.json
index 9c35711..f97ff68 100644
--- a/build.json
+++ b/build.json
@@ -3,7 +3,7 @@
     "#": "The public version number of the library.",
     "version": {
       "major": 0,
-      "minor": 8,
+      "minor": 5,
       "micro": 0,
       "build": 0
     }
@@ -596,7 +596,8 @@
         "grpc",
         "gpr_test_util",
         "gpr"
-      ]
+      ],
+      "flaky": true
     },
     {
       "name": "census_statistics_multiple_writers_test",
@@ -652,7 +653,8 @@
         "grpc",
         "gpr_test_util",
         "gpr"
-      ]
+      ],
+      "flaky": true
     },
     {
       "name": "census_stats_store_test",
@@ -880,7 +882,8 @@
         "grpc",
         "gpr_test_util",
         "gpr"
-      ]
+      ],
+      "flaky": true
     },
     {
       "name": "fling_test",
@@ -894,7 +897,8 @@
         "grpc",
         "gpr_test_util",
         "gpr"
-      ]
+      ],
+      "flaky": true
     },
     {
       "name": "gen_hpack_tables",
@@ -1594,6 +1598,20 @@
       ]
     },
     {
+      "name": "transport_security_test",
+      "build": "test",
+      "language": "c",
+      "src": [
+        "test/core/tsi/transport_security_test.c"
+      ],
+      "deps": [
+        "grpc_test_util",
+        "grpc",
+        "gpr_test_util",
+        "gpr"
+      ]
+    },
+    {
       "name": "async_end2end_test",
       "build": "test",
       "language": "c++",
@@ -1834,6 +1852,24 @@
       ]
     },
     {
+      "name": "qps_client_async",
+      "build": "test",
+      "run": false,
+      "language": "c++",
+      "src": [
+        "test/cpp/qps/qpstest.proto",
+        "test/cpp/qps/client_async.cc"
+      ],
+      "deps": [
+        "grpc++_test_util",
+        "grpc_test_util",
+        "grpc++",
+        "grpc",
+        "gpr_test_util",
+        "gpr"
+      ]
+    },
+    {
       "name": "qps_server",
       "build": "test",
       "run": false,
@@ -1852,6 +1888,24 @@
       ]
     },
     {
+      "name": "qps_server_async",
+      "build": "test",
+      "run": false,
+      "language": "c++",
+      "src": [
+        "test/cpp/qps/qpstest.proto",
+        "test/cpp/qps/server_async.cc"
+      ],
+      "deps": [
+        "grpc++_test_util",
+        "grpc_test_util",
+        "grpc++",
+        "grpc",
+        "gpr_test_util",
+        "gpr"
+      ]
+    },
+    {
       "name": "status_test",
       "build": "test",
       "language": "c++",
diff --git a/examples/pubsub/README b/examples/pubsub/README
index b55083a..faeb622 100644
--- a/examples/pubsub/README
+++ b/examples/pubsub/README
@@ -1,3 +1,6 @@
+Experimental example code, likely to change.
+Users should not attempt to run this code till this warning is removed.
+
 C++ Client implementation for Cloud Pub/Sub service
 (https://developers.google.com/apis-explorer/#p/pubsub/v1beta1/).
 
@@ -12,19 +15,7 @@
 gcloud compute instances create instance-name 
     --image debian-7 --scopes https://www.googleapis.com/auth/cloud-platform
 
-Google TLS cert is required to run the client, which can be downloaded from
-Chrome browser.  
-   
-To run the client from GCE:
-make pubsub_client
-GRPC_DEFAULT_SSL_ROOTS_FILE_PATH="Google TLS cert" bins/opt/pubsub_client
-     --project_id="your project id"
-    
-A service account credential is required to run the client from other
-environments, which can be generated as a JSON key file from
-https://console.developers.google.com/project/. To run the client with a service 
-account credential:
 
-GRPC_DEFAULT_SSL_ROOTS_FILE_PATH="Google TLS cert" bins/opt/pubsub_client
-    --project_id="your project id"
-    --service_account_key_file="absolute path to the JSON key file"
+To run the client:
+make pubsub_client
+bins/opt/pubsub_client --project_id="your project id"
diff --git a/examples/pubsub/publisher.h b/examples/pubsub/publisher.h
index 2d64a2a..c90406f 100644
--- a/examples/pubsub/publisher.h
+++ b/examples/pubsub/publisher.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPCPP_EXAMPLES_PUBSUB_PUBLISHER_H_
-#define __GRPCPP_EXAMPLES_PUBSUB_PUBLISHER_H_
+#ifndef GRPC_EXAMPLES_PUBSUB_PUBLISHER_H
+#define GRPC_EXAMPLES_PUBSUB_PUBLISHER_H
 
 #include <grpc++/channel_interface.h>
 #include <grpc++/status.h>
@@ -64,4 +64,4 @@
 }  // namespace examples
 }  // namespace grpc
 
-#endif  // __GRPCPP_EXAMPLES_PUBSUB_PUBLISHER_H_
+#endif  // GRPC_EXAMPLES_PUBSUB_PUBLISHER_H
diff --git a/examples/pubsub/publisher_test.cc b/examples/pubsub/publisher_test.cc
index 4539557..c988b48 100644
--- a/examples/pubsub/publisher_test.cc
+++ b/examples/pubsub/publisher_test.cc
@@ -61,28 +61,28 @@
  public:
   Status CreateTopic(::grpc::ServerContext* context,
                      const ::tech::pubsub::Topic* request,
-                     ::tech::pubsub::Topic* response) override {
+                     ::tech::pubsub::Topic* response) GRPC_OVERRIDE {
     EXPECT_EQ(request->name(), kTopic);
     return Status::OK;
   }
 
   Status Publish(ServerContext* context,
                  const ::tech::pubsub::PublishRequest* request,
-                 ::proto2::Empty* response) override {
+                 ::proto2::Empty* response) GRPC_OVERRIDE {
     EXPECT_EQ(request->message().data(), kMessageData);
     return Status::OK;
   }
 
   Status GetTopic(ServerContext* context,
                   const ::tech::pubsub::GetTopicRequest* request,
-                  ::tech::pubsub::Topic* response) override {
+                  ::tech::pubsub::Topic* response) GRPC_OVERRIDE {
     EXPECT_EQ(request->topic(), kTopic);
     return Status::OK;
   }
 
- Status ListTopics(ServerContext* context,
-                   const ::tech::pubsub::ListTopicsRequest* request,
-                   ::tech::pubsub::ListTopicsResponse* response) override {
+  Status ListTopics(
+      ServerContext* context, const ::tech::pubsub::ListTopicsRequest* request,
+      ::tech::pubsub::ListTopicsResponse* response) GRPC_OVERRIDE {
    std::ostringstream ss;
    ss << "cloud.googleapis.com/project in (/projects/" << kProjectId << ")";
    EXPECT_EQ(request->query(), ss.str());
@@ -92,7 +92,7 @@
 
  Status DeleteTopic(ServerContext* context,
                     const ::tech::pubsub::DeleteTopicRequest* request,
-                    ::proto2::Empty* response) override {
+                    ::proto2::Empty* response) GRPC_OVERRIDE {
     EXPECT_EQ(request->topic(), kTopic);
     return Status::OK;
  }
@@ -102,7 +102,7 @@
 class PublisherTest : public ::testing::Test {
  protected:
   // Setup a server and a client for PublisherService.
-  void SetUp() override {
+  void SetUp() GRPC_OVERRIDE {
     int port = grpc_pick_unused_port_or_die();
     server_address_ << "localhost:" << port;
     ServerBuilder builder;
@@ -116,7 +116,7 @@
     publisher_.reset(new grpc::examples::pubsub::Publisher(channel_));
   }
 
-  void TearDown() override {
+  void TearDown() GRPC_OVERRIDE {
     server_->Shutdown();
     publisher_->Shutdown();
   }
diff --git a/examples/pubsub/subscriber.h b/examples/pubsub/subscriber.h
index a973cd7..c587c01 100644
--- a/examples/pubsub/subscriber.h
+++ b/examples/pubsub/subscriber.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPCPP_EXAMPLES_PUBSUB_SUBSCRIBER_H_
-#define __GRPCPP_EXAMPLES_PUBSUB_SUBSCRIBER_H_
+#ifndef GRPC_EXAMPLES_PUBSUB_SUBSCRIBER_H
+#define GRPC_EXAMPLES_PUBSUB_SUBSCRIBER_H
 
 #include <grpc++/channel_interface.h>
 #include <grpc++/status.h>
@@ -65,4 +65,4 @@
 }  // namespace examples
 }  // namespace grpc
 
-#endif  // __GRPCPP_EXAMPLES_PUBSUB_SUBSCRIBER_H_
+#endif  // GRPC_EXAMPLES_PUBSUB_SUBSCRIBER_H
diff --git a/examples/pubsub/subscriber_test.cc b/examples/pubsub/subscriber_test.cc
index c634aa4..4ff125f 100644
--- a/examples/pubsub/subscriber_test.cc
+++ b/examples/pubsub/subscriber_test.cc
@@ -57,9 +57,9 @@
 
 class SubscriberServiceImpl : public tech::pubsub::SubscriberService::Service {
  public:
-  Status CreateSubscription(ServerContext* context,
-                            const tech::pubsub::Subscription* request,
-                            tech::pubsub::Subscription* response) override {
+  Status CreateSubscription(
+      ServerContext* context, const tech::pubsub::Subscription* request,
+      tech::pubsub::Subscription* response) GRPC_OVERRIDE {
     EXPECT_EQ(request->topic(), kTopic);
     EXPECT_EQ(request->name(), kSubscriptionName);
     return Status::OK;
@@ -67,7 +67,7 @@
 
   Status GetSubscription(ServerContext* context,
                          const tech::pubsub::GetSubscriptionRequest* request,
-                         tech::pubsub::Subscription* response) override {
+                         tech::pubsub::Subscription* response) GRPC_OVERRIDE {
     EXPECT_EQ(request->subscription(), kSubscriptionName);
     response->set_topic(kTopic);
     return Status::OK;
@@ -76,14 +76,13 @@
   Status DeleteSubscription(
       ServerContext* context,
       const tech::pubsub::DeleteSubscriptionRequest* request,
-      proto2::Empty* response) override {
+      proto2::Empty* response) GRPC_OVERRIDE {
     EXPECT_EQ(request->subscription(), kSubscriptionName);
     return Status::OK;
   }
 
-  Status Pull(ServerContext* context,
-              const tech::pubsub::PullRequest* request,
-              tech::pubsub::PullResponse* response) override {
+  Status Pull(ServerContext* context, const tech::pubsub::PullRequest* request,
+              tech::pubsub::PullResponse* response) GRPC_OVERRIDE {
     EXPECT_EQ(request->subscription(), kSubscriptionName);
     response->set_ack_id("1");
     response->mutable_pubsub_event()->mutable_message()->set_data(kData);
@@ -92,7 +91,7 @@
 
   Status Acknowledge(ServerContext* context,
                      const tech::pubsub::AcknowledgeRequest* request,
-                     proto2::Empty* response) override {
+                     proto2::Empty* response) GRPC_OVERRIDE {
     return Status::OK;
   }
 
@@ -101,7 +100,7 @@
 class SubscriberTest : public ::testing::Test {
  protected:
   // Setup a server and a client for SubscriberService.
-  void SetUp() override {
+  void SetUp() GRPC_OVERRIDE {
     int port = grpc_pick_unused_port_or_die();
     server_address_ << "localhost:" << port;
     ServerBuilder builder;
@@ -115,7 +114,7 @@
     subscriber_.reset(new grpc::examples::pubsub::Subscriber(channel_));
   }
 
-  void TearDown() override {
+  void TearDown() GRPC_OVERRIDE {
     server_->Shutdown();
     subscriber_->Shutdown();
   }
diff --git a/include/grpc++/async_unary_call.h b/include/grpc++/async_unary_call.h
index b4a654c..71b7d3f 100644
--- a/include/grpc++/async_unary_call.h
+++ b/include/grpc++/async_unary_call.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPCPP_ASYNC_UNARY_CALL_H__
-#define __GRPCPP_ASYNC_UNARY_CALL_H__
+#ifndef GRPCXX_ASYNC_UNARY_CALL_H
+#define GRPCXX_ASYNC_UNARY_CALL_H
 
 #include <grpc++/channel_interface.h>
 #include <grpc++/client_context.h>
@@ -45,7 +45,7 @@
 
 namespace grpc {
 template <class R>
-class ClientAsyncResponseReader final {
+class ClientAsyncResponseReader GRPC_FINAL {
  public:
   ClientAsyncResponseReader(ChannelInterface* channel, CompletionQueue* cq,
                     const RpcMethod& method, ClientContext* context,
@@ -79,7 +79,7 @@
 
 
  private:
-  ClientContext* context_ = nullptr;
+  ClientContext* context_;
   Call call_;
   CallOpBuffer init_buf_;
   CallOpBuffer meta_buf_;
@@ -87,7 +87,8 @@
 };
 
 template <class W>
-class ServerAsyncResponseWriter final : public ServerAsyncStreamingInterface {
+class ServerAsyncResponseWriter GRPC_FINAL
+    : public ServerAsyncStreamingInterface {
  public:
   explicit ServerAsyncResponseWriter(ServerContext* ctx)
       : call_(nullptr, nullptr, nullptr), ctx_(ctx) {}
@@ -127,7 +128,7 @@
   }
 
  private:
-  void BindCall(Call* call) override { call_ = *call; }
+  void BindCall(Call* call) GRPC_OVERRIDE { call_ = *call; }
 
   Call call_;
   ServerContext* ctx_;
@@ -137,4 +138,4 @@
 
 }  // namespace grpc
 
-#endif  // __GRPCPP_ASYNC_UNARY_CALL_H__
+#endif  // GRPCXX_ASYNC_UNARY_CALL_H
diff --git a/include/grpc++/channel_arguments.h b/include/grpc++/channel_arguments.h
index 75c3cf4..ad96ef1 100644
--- a/include/grpc++/channel_arguments.h
+++ b/include/grpc++/channel_arguments.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPCPP_CHANNEL_ARGUMENTS_H_
-#define __GRPCPP_CHANNEL_ARGUMENTS_H_
+#ifndef GRPCXX_CHANNEL_ARGUMENTS_H
+#define GRPCXX_CHANNEL_ARGUMENTS_H
 
 #include <vector>
 #include <list>
@@ -82,4 +82,4 @@
 
 }  // namespace grpc
 
-#endif  // __GRPCPP_CHANNEL_ARGUMENTS_H_
+#endif  // GRPCXX_CHANNEL_ARGUMENTS_H
diff --git a/include/grpc++/channel_interface.h b/include/grpc++/channel_interface.h
index 890fd04..77d1363 100644
--- a/include/grpc++/channel_interface.h
+++ b/include/grpc++/channel_interface.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPCPP_CHANNEL_INTERFACE_H__
-#define __GRPCPP_CHANNEL_INTERFACE_H__
+#ifndef GRPCXX_CHANNEL_INTERFACE_H
+#define GRPCXX_CHANNEL_INTERFACE_H
 
 #include <grpc++/status.h>
 #include <grpc++/impl/call.h>
@@ -63,4 +63,4 @@
 
 }  // namespace grpc
 
-#endif  // __GRPCPP_CHANNEL_INTERFACE_H__
+#endif  // GRPCXX_CHANNEL_INTERFACE_H
diff --git a/include/grpc++/client_context.h b/include/grpc++/client_context.h
index 1e7e6bf..87e5e9a 100644
--- a/include/grpc++/client_context.h
+++ b/include/grpc++/client_context.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPCPP_CLIENT_CONTEXT_H__
-#define __GRPCPP_CLIENT_CONTEXT_H__
+#ifndef GRPCXX_CLIENT_CONTEXT_H
+#define GRPCXX_CLIENT_CONTEXT_H
 
 #include <chrono>
 #include <map>
@@ -139,7 +139,7 @@
     return authority_;
   }
 
-  bool initial_metadata_received_ = false;
+  bool initial_metadata_received_;
   grpc_call *call_;
   grpc_completion_queue *cq_;
   gpr_timespec absolute_deadline_;
@@ -151,4 +151,4 @@
 
 }  // namespace grpc
 
-#endif  // __GRPCPP_CLIENT_CONTEXT_H__
+#endif  // GRPCXX_CLIENT_CONTEXT_H
diff --git a/include/grpc++/completion_queue.h b/include/grpc++/completion_queue.h
index 0075482..0ca1260 100644
--- a/include/grpc++/completion_queue.h
+++ b/include/grpc++/completion_queue.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPCPP_COMPLETION_QUEUE_H__
-#define __GRPCPP_COMPLETION_QUEUE_H__
+#ifndef GRPCXX_COMPLETION_QUEUE_H
+#define GRPCXX_COMPLETION_QUEUE_H
 
 #include <grpc++/impl/client_unary_call.h>
 
@@ -121,4 +121,4 @@
 
 }  // namespace grpc
 
-#endif  // __GRPCPP_COMPLETION_QUEUE_H__
+#endif  // GRPCXX_COMPLETION_QUEUE_H
diff --git a/include/grpc++/config.h b/include/grpc++/config.h
index 2dced12..cfa8d3b 100644
--- a/include/grpc++/config.h
+++ b/include/grpc++/config.h
@@ -31,15 +31,23 @@
  *
  */
 
-#ifndef __GRPCPP_CONFIG_H__
-#define __GRPCPP_CONFIG_H__
+#ifndef GRPCXX_CONFIG_H
+#define GRPCXX_CONFIG_H
 
 #include <string>
 
+#ifdef GRPC_OLD_CXX
+#define GRPC_FINAL
+#define GRPC_OVERRIDE
+#else
+#define GRPC_FINAL final
+#define GRPC_OVERRIDE override
+#endif
+
 namespace grpc {
 
 typedef std::string string;
 
 }  // namespace grpc
 
-#endif  // __GRPCPP_CONFIG_H__
+#endif  // GRPCXX_CONFIG_H
diff --git a/include/grpc++/create_channel.h b/include/grpc++/create_channel.h
index 80ca0c4..3f13188 100644
--- a/include/grpc++/create_channel.h
+++ b/include/grpc++/create_channel.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPCPP_CREATE_CHANNEL_H__
-#define __GRPCPP_CREATE_CHANNEL_H__
+#ifndef GRPCXX_CREATE_CHANNEL_H
+#define GRPCXX_CREATE_CHANNEL_H
 
 #include <memory>
 
@@ -55,4 +55,4 @@
 
 }  // namespace grpc
 
-#endif  // __GRPCPP_CREATE_CHANNEL_H__
+#endif  // GRPCXX_CREATE_CHANNEL_H
diff --git a/include/grpc++/credentials.h b/include/grpc++/credentials.h
index 5cbcca3..12c1a2f 100644
--- a/include/grpc++/credentials.h
+++ b/include/grpc++/credentials.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPCPP_CREDENTIALS_H_
-#define __GRPCPP_CREDENTIALS_H_
+#ifndef GRPCXX_CREDENTIALS_H
+#define GRPCXX_CREDENTIALS_H
 
 #include <chrono>
 #include <memory>
@@ -47,7 +47,7 @@
 // to creating an instance using CredentialsFactory, and passing it down
 // during channel construction.
 
-class Credentials final {
+class Credentials GRPC_FINAL {
  public:
   ~Credentials();
 
@@ -133,4 +133,4 @@
 
 }  // namespace grpc
 
-#endif  // __GRPCPP_CREDENTIALS_H_
+#endif  // GRPCXX_CREDENTIALS_H
diff --git a/include/grpc++/impl/call.h b/include/grpc++/impl/call.h
index 341710f..3e199e3 100644
--- a/include/grpc++/impl/call.h
+++ b/include/grpc++/impl/call.h
@@ -31,10 +31,11 @@
  *
  */
 
-#ifndef __GRPCPP_CALL_H__
-#define __GRPCPP_CALL_H__
+#ifndef GRPCXX_IMPL_CALL_H
+#define GRPCXX_IMPL_CALL_H
 
 #include <grpc/grpc.h>
+#include <grpc++/config.h>
 #include <grpc++/status.h>
 #include <grpc++/completion_queue.h>
 
@@ -56,7 +57,7 @@
 
 class CallOpBuffer : public CompletionQueueTag {
  public:
-  CallOpBuffer() : return_tag_(this) {}
+  CallOpBuffer();
   ~CallOpBuffer();
 
   void Reset(void *next_return_tag);
@@ -80,40 +81,40 @@
   void FillOps(grpc_op *ops, size_t *nops);
 
   // Called by completion queue just prior to returning from Next() or Pluck()
-  bool FinalizeResult(void **tag, bool *status) override;
+  bool FinalizeResult(void **tag, bool *status) GRPC_OVERRIDE;
 
-  bool got_message = false;
+  bool got_message;
 
  private:
-  void *return_tag_ = nullptr;
+  void *return_tag_;
   // Send initial metadata
-  bool send_initial_metadata_ = false;
-  size_t initial_metadata_count_ = 0;
-  grpc_metadata *initial_metadata_ = nullptr;
+  bool send_initial_metadata_;
+  size_t initial_metadata_count_;
+  grpc_metadata *initial_metadata_;
   // Recv initial metadta
-  std::multimap<grpc::string, grpc::string> *recv_initial_metadata_ = nullptr;
-  grpc_metadata_array recv_initial_metadata_arr_ = {0, 0, nullptr};
+  std::multimap<grpc::string, grpc::string> *recv_initial_metadata_;
+  grpc_metadata_array recv_initial_metadata_arr_;
   // Send message
-  const google::protobuf::Message *send_message_ = nullptr;
-  grpc_byte_buffer *send_message_buf_ = nullptr;
+  const google::protobuf::Message *send_message_;
+  grpc_byte_buffer *send_message_buf_;
   // Recv message
-  google::protobuf::Message *recv_message_ = nullptr;
-  grpc_byte_buffer *recv_message_buf_ = nullptr;
+  google::protobuf::Message *recv_message_;
+  grpc_byte_buffer *recv_message_buf_;
   // Client send close
-  bool client_send_close_ = false;
+  bool client_send_close_;
   // Client recv status
-  std::multimap<grpc::string, grpc::string> *recv_trailing_metadata_ = nullptr;
-  Status *recv_status_ = nullptr;
-  grpc_metadata_array recv_trailing_metadata_arr_ = {0, 0, nullptr};
-  grpc_status_code status_code_ = GRPC_STATUS_OK;
-  char *status_details_ = nullptr;
-  size_t status_details_capacity_ = 0;
+  std::multimap<grpc::string, grpc::string> *recv_trailing_metadata_;
+  Status *recv_status_;
+  grpc_metadata_array recv_trailing_metadata_arr_;
+  grpc_status_code status_code_;
+  char *status_details_;
+  size_t status_details_capacity_;
   // Server send status
-  const Status *send_status_ = nullptr;
-  size_t trailing_metadata_count_ = 0;
-  grpc_metadata *trailing_metadata_ = nullptr;
+  const Status *send_status_;
+  size_t trailing_metadata_count_;
+  grpc_metadata *trailing_metadata_;
   int cancelled_buf_;
-  bool *recv_closed_ = nullptr;
+  bool *recv_closed_;
 };
 
 // Channel and Server implement this to allow them to hook performing ops
@@ -124,7 +125,7 @@
 };
 
 // Straightforward wrapping of the C call object
-class Call final {
+class Call GRPC_FINAL {
  public:
   /* call is owned by the caller */
   Call(grpc_call *call, CallHook *call_hook_, CompletionQueue *cq);
@@ -142,4 +143,4 @@
 
 }  // namespace grpc
 
-#endif  // __GRPCPP_CALL_INTERFACE_H__
+#endif  // GRPCXX_IMPL_CALL_H
diff --git a/include/grpc++/impl/client_unary_call.h b/include/grpc++/impl/client_unary_call.h
index f25ded7..d870326 100644
--- a/include/grpc++/impl/client_unary_call.h
+++ b/include/grpc++/impl/client_unary_call.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPCPP_CLIENT_UNARY_CALL_H__
-#define __GRPCPP_CLIENT_UNARY_CALL_H__
+#ifndef GRPCXX_IMPL_CLIENT_UNARY_CALL_H
+#define GRPCXX_IMPL_CLIENT_UNARY_CALL_H
 
 namespace google {
 namespace protobuf {
@@ -56,4 +56,4 @@
 
 }  // namespace grpc
 
-#endif
+#endif  // GRPCXX_IMPL_CLIENT_UNARY_CALL_H
diff --git a/include/grpc++/impl/internal_stub.h b/include/grpc++/impl/internal_stub.h
index 2529012..2cbf1d9 100644
--- a/include/grpc++/impl/internal_stub.h
+++ b/include/grpc++/impl/internal_stub.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPCPP_IMPL_INTERNAL_STUB_H__
-#define __GRPCPP_IMPL_INTERNAL_STUB_H__
+#ifndef GRPCXX_IMPL_INTERNAL_STUB_H
+#define GRPCXX_IMPL_INTERNAL_STUB_H
 
 #include <memory>
 
@@ -57,4 +57,4 @@
 
 }  // namespace grpc
 
-#endif  // __GRPCPP_IMPL_INTERNAL_STUB_H__
+#endif  // GRPCXX_IMPL_INTERNAL_STUB_H
diff --git a/include/grpc++/impl/rpc_method.h b/include/grpc++/impl/rpc_method.h
index 0236b11..ab407f5 100644
--- a/include/grpc++/impl/rpc_method.h
+++ b/include/grpc++/impl/rpc_method.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPCPP_IMPL_RPC_METHOD_H__
-#define __GRPCPP_IMPL_RPC_METHOD_H__
+#ifndef GRPCXX_IMPL_RPC_METHOD_H
+#define GRPCXX_IMPL_RPC_METHOD_H
 
 namespace google {
 namespace protobuf {
@@ -66,4 +66,4 @@
 
 }  // namespace grpc
 
-#endif  // __GRPCPP_IMPL_RPC_METHOD_H__
+#endif  // GRPCXX_IMPL_RPC_METHOD_H
diff --git a/include/grpc++/impl/rpc_service_method.h b/include/grpc++/impl/rpc_service_method.h
index ffd5c34..ff94c7e 100644
--- a/include/grpc++/impl/rpc_service_method.h
+++ b/include/grpc++/impl/rpc_service_method.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPCPP_IMPL_RPC_SERVICE_METHOD_H__
-#define __GRPCPP_IMPL_RPC_SERVICE_METHOD_H__
+#ifndef GRPCXX_IMPL_RPC_SERVICE_METHOD_H
+#define GRPCXX_IMPL_RPC_SERVICE_METHOD_H
 
 #include <functional>
 #include <map>
@@ -77,7 +77,7 @@
       ServiceType* service)
       : func_(func), service_(service) {}
 
-  Status RunHandler(const HandlerParameter& param) final {
+  Status RunHandler(const HandlerParameter& param) GRPC_FINAL {
     // Invoke application function, cast proto messages to their actual types.
     return func_(service_, param.server_context,
                  dynamic_cast<const RequestType*>(param.request),
@@ -102,7 +102,7 @@
       ServiceType* service)
       : func_(func), service_(service) {}
 
-  Status RunHandler(const HandlerParameter& param) final {
+  Status RunHandler(const HandlerParameter& param) GRPC_FINAL {
     ServerReader<RequestType> reader(param.call, param.server_context);
     return func_(service_, param.server_context, &reader,
                  dynamic_cast<ResponseType*>(param.response));
@@ -124,7 +124,7 @@
       ServiceType* service)
       : func_(func), service_(service) {}
 
-  Status RunHandler(const HandlerParameter& param) final {
+  Status RunHandler(const HandlerParameter& param) GRPC_FINAL {
     ServerWriter<ResponseType> writer(param.call, param.server_context);
     return func_(service_, param.server_context,
                  dynamic_cast<const RequestType*>(param.request), &writer);
@@ -147,7 +147,7 @@
       ServiceType* service)
       : func_(func), service_(service) {}
 
-  Status RunHandler(const HandlerParameter& param) final {
+  Status RunHandler(const HandlerParameter& param) GRPC_FINAL {
     ServerReaderWriter<ResponseType, RequestType> stream(param.call,
                                                          param.server_context);
     return func_(service_, param.server_context, &stream);
@@ -203,4 +203,4 @@
 
 }  // namespace grpc
 
-#endif  // __GRPCPP_IMPL_RPC_SERVICE_METHOD_H__
+#endif  // GRPCXX_IMPL_RPC_SERVICE_METHOD_H
diff --git a/include/grpc++/impl/service_type.h b/include/grpc++/impl/service_type.h
index cafa269..7481d64 100644
--- a/include/grpc++/impl/service_type.h
+++ b/include/grpc++/impl/service_type.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPCPP_IMPL_SERVICE_TYPE_H__
-#define __GRPCPP_IMPL_SERVICE_TYPE_H__
+#ifndef GRPCXX_IMPL_SERVICE_TYPE_H
+#define GRPCXX_IMPL_SERVICE_TYPE_H
 
 namespace google {
 namespace protobuf {
@@ -79,7 +79,11 @@
 
   AsynchronousService(CompletionQueue* cq, const char** method_names,
                       size_t method_count)
-      : cq_(cq), method_names_(method_names), method_count_(method_count) {}
+      : cq_(cq),
+        dispatch_impl_(nullptr),
+        method_names_(method_names),
+        method_count_(method_count),
+        request_args_(nullptr) {}
 
   ~AsynchronousService() { delete[] request_args_; }
 
@@ -116,12 +120,12 @@
  private:
   friend class Server;
   CompletionQueue* const cq_;
-  DispatchImpl* dispatch_impl_ = nullptr;
+  DispatchImpl* dispatch_impl_;
   const char** const method_names_;
   size_t method_count_;
-  void** request_args_ = nullptr;
+  void** request_args_;
 };
 
 }  // namespace grpc
 
-#endif  // __GRPCPP_IMPL_SERVICE_TYPE_H__
+#endif  // GRPCXX_IMPL_SERVICE_TYPE_H
diff --git a/include/grpc++/server.h b/include/grpc++/server.h
index 429c0ff..3282b82 100644
--- a/include/grpc++/server.h
+++ b/include/grpc++/server.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPCPP_SERVER_H__
-#define __GRPCPP_SERVER_H__
+#ifndef GRPCXX_SERVER_H
+#define GRPCXX_SERVER_H
 
 #include <condition_variable>
 #include <list>
@@ -61,8 +61,8 @@
 class ThreadPoolInterface;
 
 // Currently it only supports handling rpcs in a single thread.
-class Server final : private CallHook,
-                     private AsynchronousService::DispatchImpl {
+class Server GRPC_FINAL : private CallHook,
+                          private AsynchronousService::DispatchImpl {
  public:
   ~Server();
 
@@ -97,7 +97,7 @@
   void RunRpc();
   void ScheduleCallback();
 
-  void PerformOpsOnCall(CallOpBuffer* ops, Call* call) override;
+  void PerformOpsOnCall(CallOpBuffer* ops, Call* call) GRPC_OVERRIDE;
 
   // DispatchImpl
   void RequestAsyncCall(void* registered_method, ServerContext* context,
@@ -130,4 +130,4 @@
 
 }  // namespace grpc
 
-#endif  // __GRPCPP_SERVER_H__
+#endif  // GRPCXX_SERVER_H
diff --git a/include/grpc++/server_builder.h b/include/grpc++/server_builder.h
index 4545c41..5566002 100644
--- a/include/grpc++/server_builder.h
+++ b/include/grpc++/server_builder.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPCPP_SERVER_BUILDER_H__
-#define __GRPCPP_SERVER_BUILDER_H__
+#ifndef GRPCXX_SERVER_BUILDER_H
+#define GRPCXX_SERVER_BUILDER_H
 
 #include <memory>
 #include <vector>
@@ -83,9 +83,9 @@
   std::vector<AsynchronousService*> async_services_;
   std::vector<grpc::string> ports_;
   std::shared_ptr<ServerCredentials> creds_;
-  ThreadPoolInterface* thread_pool_ = nullptr;
+  ThreadPoolInterface* thread_pool_;
 };
 
 }  // namespace grpc
 
-#endif  // __GRPCPP_SERVER_BUILDER_H__
+#endif  // GRPCXX_SERVER_BUILDER_H
diff --git a/include/grpc++/server_context.h b/include/grpc++/server_context.h
index d327d8b..9387f4a 100644
--- a/include/grpc++/server_context.h
+++ b/include/grpc++/server_context.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPCPP_SERVER_CONTEXT_H_
-#define __GRPCPP_SERVER_CONTEXT_H_
+#ifndef GRPCXX_SERVER_CONTEXT_H
+#define GRPCXX_SERVER_CONTEXT_H
 
 #include <chrono>
 #include <map>
@@ -66,7 +66,7 @@
 class Server;
 
 // Interface of server side rpc context.
-class ServerContext final {
+class ServerContext GRPC_FINAL {
  public:
   ServerContext();  // for async calls
   ~ServerContext();
@@ -108,12 +108,12 @@
   ServerContext(gpr_timespec deadline, grpc_metadata* metadata,
                 size_t metadata_count);
 
-  CompletionOp* completion_op_ = nullptr;
+  CompletionOp* completion_op_;
 
   std::chrono::system_clock::time_point deadline_;
-  grpc_call* call_ = nullptr;
-  CompletionQueue* cq_ = nullptr;
-  bool sent_initial_metadata_ = false;
+  grpc_call* call_;
+  CompletionQueue* cq_;
+  bool sent_initial_metadata_;
   std::multimap<grpc::string, grpc::string> client_metadata_;
   std::multimap<grpc::string, grpc::string> initial_metadata_;
   std::multimap<grpc::string, grpc::string> trailing_metadata_;
@@ -121,4 +121,4 @@
 
 }  // namespace grpc
 
-#endif  // __GRPCPP_SERVER_CONTEXT_H_
+#endif  // GRPCXX_SERVER_CONTEXT_H
diff --git a/include/grpc++/server_credentials.h b/include/grpc++/server_credentials.h
index 5c6787a..45cd279 100644
--- a/include/grpc++/server_credentials.h
+++ b/include/grpc++/server_credentials.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPCPP_SERVER_CREDENTIALS_H_
-#define __GRPCPP_SERVER_CREDENTIALS_H_
+#ifndef GRPCXX_SERVER_CREDENTIALS_H
+#define GRPCXX_SERVER_CREDENTIALS_H
 
 #include <memory>
 #include <vector>
@@ -44,7 +44,7 @@
 namespace grpc {
 
 // grpc_server_credentials wrapper class.
-class ServerCredentials final {
+class ServerCredentials GRPC_FINAL {
  public:
   ~ServerCredentials();
 
@@ -79,4 +79,4 @@
 
 }  // namespace grpc
 
-#endif  // __GRPCPP_SERVER_CREDENTIALS_H_
+#endif  // GRPCXX_SERVER_CREDENTIALS_H
diff --git a/include/grpc++/status.h b/include/grpc++/status.h
index 1dfb0c9..8073319 100644
--- a/include/grpc++/status.h
+++ b/include/grpc++/status.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPCPP_STATUS_H__
-#define __GRPCPP_STATUS_H__
+#ifndef GRPCXX_STATUS_H
+#define GRPCXX_STATUS_H
 
 #include <grpc++/status_code_enum.h>
 #include <grpc++/config.h>
@@ -62,4 +62,4 @@
 
 }  // namespace grpc
 
-#endif  // __GRPCPP_STATUS_H__
+#endif  // GRPCXX_STATUS_H
diff --git a/include/grpc++/status_code_enum.h b/include/grpc++/status_code_enum.h
index 0ec0a97..2728fb0 100644
--- a/include/grpc++/status_code_enum.h
+++ b/include/grpc++/status_code_enum.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPCPP_STATUS_CODE_ENUM_H__
-#define __GRPCPP_STATUS_CODE_ENUM_H__
+#ifndef GRPCXX_STATUS_CODE_ENUM_H
+#define GRPCXX_STATUS_CODE_ENUM_H
 
 namespace grpc {
 
@@ -195,4 +195,4 @@
 
 }  // namespace grpc
 
-#endif  // __GRPCPP_STATUS_CODE_ENUM_H_
+#endif  // GRPCXX_STATUS_CODE_ENUM_H
diff --git a/include/grpc++/stream.h b/include/grpc++/stream.h
index cd95ff7..d95a379 100644
--- a/include/grpc++/stream.h
+++ b/include/grpc++/stream.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPCPP_STREAM_H__
-#define __GRPCPP_STREAM_H__
+#ifndef GRPCXX_STREAM_H
+#define GRPCXX_STREAM_H
 
 #include <grpc++/channel_interface.h>
 #include <grpc++/client_context.h>
@@ -83,8 +83,8 @@
 };
 
 template <class R>
-class ClientReader final : public ClientStreamingInterface,
-                           public ReaderInterface<R> {
+class ClientReader GRPC_FINAL : public ClientStreamingInterface,
+                                public ReaderInterface<R> {
  public:
   // Blocking create a stream and write the first request out.
   ClientReader(ChannelInterface* channel, const RpcMethod& method,
@@ -111,7 +111,7 @@
     GPR_ASSERT(cq_.Pluck(&buf));
   }
 
-  virtual bool Read(R* msg) override {
+  virtual bool Read(R* msg) GRPC_OVERRIDE {
     CallOpBuffer buf;
     if (!context_->initial_metadata_received_) {
       buf.AddRecvInitialMetadata(context_);
@@ -121,7 +121,7 @@
     return cq_.Pluck(&buf) && buf.got_message;
   }
 
-  virtual Status Finish() override {
+  virtual Status Finish() GRPC_OVERRIDE {
     CallOpBuffer buf;
     Status status;
     buf.AddClientRecvStatus(context_, &status);
@@ -137,8 +137,8 @@
 };
 
 template <class W>
-class ClientWriter final : public ClientStreamingInterface,
-                           public WriterInterface<W> {
+class ClientWriter GRPC_FINAL : public ClientStreamingInterface,
+                                public WriterInterface<W> {
  public:
   // Blocking create a stream.
   ClientWriter(ChannelInterface* channel, const RpcMethod& method,
@@ -152,7 +152,7 @@
     cq_.Pluck(&buf);
   }
 
-  virtual bool Write(const W& msg) override {
+  virtual bool Write(const W& msg) GRPC_OVERRIDE {
     CallOpBuffer buf;
     buf.AddSendMessage(msg);
     call_.PerformOps(&buf);
@@ -167,7 +167,7 @@
   }
 
   // Read the final response and wait for the final status.
-  virtual Status Finish() override {
+  virtual Status Finish() GRPC_OVERRIDE {
     CallOpBuffer buf;
     Status status;
     buf.AddRecvMessage(response_);
@@ -186,9 +186,9 @@
 
 // Client-side interface for bi-directional streaming.
 template <class W, class R>
-class ClientReaderWriter final : public ClientStreamingInterface,
-                                 public WriterInterface<W>,
-                                 public ReaderInterface<R> {
+class ClientReaderWriter GRPC_FINAL : public ClientStreamingInterface,
+                                      public WriterInterface<W>,
+                                      public ReaderInterface<R> {
  public:
   // Blocking create a stream.
   ClientReaderWriter(ChannelInterface* channel, const RpcMethod& method,
@@ -213,7 +213,7 @@
     GPR_ASSERT(cq_.Pluck(&buf));
   }
 
-  virtual bool Read(R* msg) override {
+  virtual bool Read(R* msg) GRPC_OVERRIDE {
     CallOpBuffer buf;
     if (!context_->initial_metadata_received_) {
       buf.AddRecvInitialMetadata(context_);
@@ -223,7 +223,7 @@
     return cq_.Pluck(&buf) && buf.got_message;
   }
 
-  virtual bool Write(const W& msg) override {
+  virtual bool Write(const W& msg) GRPC_OVERRIDE {
     CallOpBuffer buf;
     buf.AddSendMessage(msg);
     call_.PerformOps(&buf);
@@ -237,7 +237,7 @@
     return cq_.Pluck(&buf);
   }
 
-  virtual Status Finish() override {
+  virtual Status Finish() GRPC_OVERRIDE {
     CallOpBuffer buf;
     Status status;
     buf.AddClientRecvStatus(context_, &status);
@@ -253,7 +253,7 @@
 };
 
 template <class R>
-class ServerReader final : public ReaderInterface<R> {
+class ServerReader GRPC_FINAL : public ReaderInterface<R> {
  public:
   ServerReader(Call* call, ServerContext* ctx) : call_(call), ctx_(ctx) {}
 
@@ -267,7 +267,7 @@
     call_->cq()->Pluck(&buf);
   }
 
-  virtual bool Read(R* msg) override {
+  virtual bool Read(R* msg) GRPC_OVERRIDE {
     CallOpBuffer buf;
     buf.AddRecvMessage(msg);
     call_->PerformOps(&buf);
@@ -280,7 +280,7 @@
 };
 
 template <class W>
-class ServerWriter final : public WriterInterface<W> {
+class ServerWriter GRPC_FINAL : public WriterInterface<W> {
  public:
   ServerWriter(Call* call, ServerContext* ctx) : call_(call), ctx_(ctx) {}
 
@@ -294,7 +294,7 @@
     call_->cq()->Pluck(&buf);
   }
 
-  virtual bool Write(const W& msg) override {
+  virtual bool Write(const W& msg) GRPC_OVERRIDE {
     CallOpBuffer buf;
     if (!ctx_->sent_initial_metadata_) {
       buf.AddSendInitialMetadata(&ctx_->initial_metadata_);
@@ -312,8 +312,8 @@
 
 // Server-side interface for bi-directional streaming.
 template <class W, class R>
-class ServerReaderWriter final : public WriterInterface<W>,
-                                 public ReaderInterface<R> {
+class ServerReaderWriter GRPC_FINAL : public WriterInterface<W>,
+                                      public ReaderInterface<R> {
  public:
   ServerReaderWriter(Call* call, ServerContext* ctx) : call_(call), ctx_(ctx) {}
 
@@ -327,14 +327,14 @@
     call_->cq()->Pluck(&buf);
   }
 
-  virtual bool Read(R* msg) override {
+  virtual bool Read(R* msg) GRPC_OVERRIDE {
     CallOpBuffer buf;
     buf.AddRecvMessage(msg);
     call_->PerformOps(&buf);
     return call_->cq()->Pluck(&buf) && buf.got_message;
   }
 
-  virtual bool Write(const W& msg) override {
+  virtual bool Write(const W& msg) GRPC_OVERRIDE {
     CallOpBuffer buf;
     if (!ctx_->sent_initial_metadata_) {
       buf.AddSendInitialMetadata(&ctx_->initial_metadata_);
@@ -380,8 +380,8 @@
 };
 
 template <class R>
-class ClientAsyncReader final : public ClientAsyncStreamingInterface,
-                                public AsyncReaderInterface<R> {
+class ClientAsyncReader GRPC_FINAL : public ClientAsyncStreamingInterface,
+                                     public AsyncReaderInterface<R> {
  public:
   // Create a stream and write the first request out.
   ClientAsyncReader(ChannelInterface* channel, CompletionQueue* cq,
@@ -395,7 +395,7 @@
     call_.PerformOps(&init_buf_);
   }
 
-  void ReadInitialMetadata(void* tag) override {
+  void ReadInitialMetadata(void* tag) GRPC_OVERRIDE {
     GPR_ASSERT(!context_->initial_metadata_received_);
 
     meta_buf_.Reset(tag);
@@ -403,7 +403,7 @@
     call_.PerformOps(&meta_buf_);
   }
 
-  void Read(R* msg, void* tag) override {
+  void Read(R* msg, void* tag) GRPC_OVERRIDE {
     read_buf_.Reset(tag);
     if (!context_->initial_metadata_received_) {
       read_buf_.AddRecvInitialMetadata(context_);
@@ -412,7 +412,7 @@
     call_.PerformOps(&read_buf_);
   }
 
-  void Finish(Status* status, void* tag) override {
+  void Finish(Status* status, void* tag) GRPC_OVERRIDE {
     finish_buf_.Reset(tag);
     if (!context_->initial_metadata_received_) {
       finish_buf_.AddRecvInitialMetadata(context_);
@@ -422,7 +422,7 @@
   }
 
  private:
-  ClientContext* context_ = nullptr;
+  ClientContext* context_;
   Call call_;
   CallOpBuffer init_buf_;
   CallOpBuffer meta_buf_;
@@ -431,8 +431,8 @@
 };
 
 template <class W>
-class ClientAsyncWriter final : public ClientAsyncStreamingInterface,
-                                public AsyncWriterInterface<W> {
+class ClientAsyncWriter GRPC_FINAL : public ClientAsyncStreamingInterface,
+                                     public AsyncWriterInterface<W> {
  public:
   ClientAsyncWriter(ChannelInterface* channel, CompletionQueue* cq,
                     const RpcMethod& method, ClientContext* context,
@@ -445,7 +445,7 @@
     call_.PerformOps(&init_buf_);
   }
 
-  void ReadInitialMetadata(void* tag) override {
+  void ReadInitialMetadata(void* tag) GRPC_OVERRIDE {
     GPR_ASSERT(!context_->initial_metadata_received_);
 
     meta_buf_.Reset(tag);
@@ -453,7 +453,7 @@
     call_.PerformOps(&meta_buf_);
   }
 
-  void Write(const W& msg, void* tag) override {
+  void Write(const W& msg, void* tag) GRPC_OVERRIDE {
     write_buf_.Reset(tag);
     write_buf_.AddSendMessage(msg);
     call_.PerformOps(&write_buf_);
@@ -465,7 +465,7 @@
     call_.PerformOps(&writes_done_buf_);
   }
 
-  void Finish(Status* status, void* tag) override {
+  void Finish(Status* status, void* tag) GRPC_OVERRIDE {
     finish_buf_.Reset(tag);
     if (!context_->initial_metadata_received_) {
       finish_buf_.AddRecvInitialMetadata(context_);
@@ -476,7 +476,7 @@
   }
 
  private:
-  ClientContext* context_ = nullptr;
+  ClientContext* context_;
   google::protobuf::Message* const response_;
   Call call_;
   CallOpBuffer init_buf_;
@@ -488,9 +488,9 @@
 
 // Client-side interface for bi-directional streaming.
 template <class W, class R>
-class ClientAsyncReaderWriter final : public ClientAsyncStreamingInterface,
-                                      public AsyncWriterInterface<W>,
-                                      public AsyncReaderInterface<R> {
+class ClientAsyncReaderWriter GRPC_FINAL : public ClientAsyncStreamingInterface,
+                                           public AsyncWriterInterface<W>,
+                                           public AsyncReaderInterface<R> {
  public:
   ClientAsyncReaderWriter(ChannelInterface* channel, CompletionQueue* cq,
                           const RpcMethod& method, ClientContext* context,
@@ -501,7 +501,7 @@
     call_.PerformOps(&init_buf_);
   }
 
-  void ReadInitialMetadata(void* tag) override {
+  void ReadInitialMetadata(void* tag) GRPC_OVERRIDE {
     GPR_ASSERT(!context_->initial_metadata_received_);
 
     meta_buf_.Reset(tag);
@@ -509,7 +509,7 @@
     call_.PerformOps(&meta_buf_);
   }
 
-  void Read(R* msg, void* tag) override {
+  void Read(R* msg, void* tag) GRPC_OVERRIDE {
     read_buf_.Reset(tag);
     if (!context_->initial_metadata_received_) {
       read_buf_.AddRecvInitialMetadata(context_);
@@ -518,7 +518,7 @@
     call_.PerformOps(&read_buf_);
   }
 
-  void Write(const W& msg, void* tag) override {
+  void Write(const W& msg, void* tag) GRPC_OVERRIDE {
     write_buf_.Reset(tag);
     write_buf_.AddSendMessage(msg);
     call_.PerformOps(&write_buf_);
@@ -530,7 +530,7 @@
     call_.PerformOps(&writes_done_buf_);
   }
 
-  void Finish(Status* status, void* tag) override {
+  void Finish(Status* status, void* tag) GRPC_OVERRIDE {
     finish_buf_.Reset(tag);
     if (!context_->initial_metadata_received_) {
       finish_buf_.AddRecvInitialMetadata(context_);
@@ -540,7 +540,7 @@
   }
 
  private:
-  ClientContext* context_ = nullptr;
+  ClientContext* context_;
   Call call_;
   CallOpBuffer init_buf_;
   CallOpBuffer meta_buf_;
@@ -551,13 +551,13 @@
 };
 
 template <class W, class R>
-class ServerAsyncReader : public ServerAsyncStreamingInterface,
-                          public AsyncReaderInterface<R> {
+class ServerAsyncReader GRPC_FINAL : public ServerAsyncStreamingInterface,
+                                     public AsyncReaderInterface<R> {
  public:
   explicit ServerAsyncReader(ServerContext* ctx)
       : call_(nullptr, nullptr, nullptr), ctx_(ctx) {}
 
-  void SendInitialMetadata(void* tag) override {
+  void SendInitialMetadata(void* tag) GRPC_OVERRIDE {
     GPR_ASSERT(!ctx_->sent_initial_metadata_);
 
     meta_buf_.Reset(tag);
@@ -566,7 +566,7 @@
     call_.PerformOps(&meta_buf_);
   }
 
-  void Read(R* msg, void* tag) override {
+  void Read(R* msg, void* tag) GRPC_OVERRIDE {
     read_buf_.Reset(tag);
     read_buf_.AddRecvMessage(msg);
     call_.PerformOps(&read_buf_);
@@ -598,7 +598,7 @@
   }
 
  private:
-  void BindCall(Call* call) override { call_ = *call; }
+  void BindCall(Call* call) GRPC_OVERRIDE { call_ = *call; }
 
   Call call_;
   ServerContext* ctx_;
@@ -608,13 +608,13 @@
 };
 
 template <class W>
-class ServerAsyncWriter : public ServerAsyncStreamingInterface,
-                          public AsyncWriterInterface<W> {
+class ServerAsyncWriter GRPC_FINAL : public ServerAsyncStreamingInterface,
+                                     public AsyncWriterInterface<W> {
  public:
   explicit ServerAsyncWriter(ServerContext* ctx)
       : call_(nullptr, nullptr, nullptr), ctx_(ctx) {}
 
-  void SendInitialMetadata(void* tag) override {
+  void SendInitialMetadata(void* tag) GRPC_OVERRIDE {
     GPR_ASSERT(!ctx_->sent_initial_metadata_);
 
     meta_buf_.Reset(tag);
@@ -623,7 +623,7 @@
     call_.PerformOps(&meta_buf_);
   }
 
-  void Write(const W& msg, void* tag) override {
+  void Write(const W& msg, void* tag) GRPC_OVERRIDE {
     write_buf_.Reset(tag);
     if (!ctx_->sent_initial_metadata_) {
       write_buf_.AddSendInitialMetadata(&ctx_->initial_metadata_);
@@ -644,7 +644,7 @@
   }
 
  private:
-  void BindCall(Call* call) override { call_ = *call; }
+  void BindCall(Call* call) GRPC_OVERRIDE { call_ = *call; }
 
   Call call_;
   ServerContext* ctx_;
@@ -655,14 +655,14 @@
 
 // Server-side interface for bi-directional streaming.
 template <class W, class R>
-class ServerAsyncReaderWriter : public ServerAsyncStreamingInterface,
-                                public AsyncWriterInterface<W>,
-                                public AsyncReaderInterface<R> {
+class ServerAsyncReaderWriter GRPC_FINAL : public ServerAsyncStreamingInterface,
+                                           public AsyncWriterInterface<W>,
+                                           public AsyncReaderInterface<R> {
  public:
   explicit ServerAsyncReaderWriter(ServerContext* ctx)
       : call_(nullptr, nullptr, nullptr), ctx_(ctx) {}
 
-  void SendInitialMetadata(void* tag) override {
+  void SendInitialMetadata(void* tag) GRPC_OVERRIDE {
     GPR_ASSERT(!ctx_->sent_initial_metadata_);
 
     meta_buf_.Reset(tag);
@@ -671,13 +671,13 @@
     call_.PerformOps(&meta_buf_);
   }
 
-  virtual void Read(R* msg, void* tag) override {
+  virtual void Read(R* msg, void* tag) GRPC_OVERRIDE {
     read_buf_.Reset(tag);
     read_buf_.AddRecvMessage(msg);
     call_.PerformOps(&read_buf_);
   }
 
-  virtual void Write(const W& msg, void* tag) override {
+  virtual void Write(const W& msg, void* tag) GRPC_OVERRIDE {
     write_buf_.Reset(tag);
     if (!ctx_->sent_initial_metadata_) {
       write_buf_.AddSendInitialMetadata(&ctx_->initial_metadata_);
@@ -698,7 +698,7 @@
   }
 
  private:
-  void BindCall(Call* call) override { call_ = *call; }
+  void BindCall(Call* call) GRPC_OVERRIDE { call_ = *call; }
 
   Call call_;
   ServerContext* ctx_;
@@ -710,4 +710,4 @@
 
 }  // namespace grpc
 
-#endif  // __GRPCPP_STREAM_H__
+#endif  // GRPCXX_STREAM_H
diff --git a/include/grpc++/thread_pool_interface.h b/include/grpc++/thread_pool_interface.h
index c839249..ead307f 100644
--- a/include/grpc++/thread_pool_interface.h
+++ b/include/grpc++/thread_pool_interface.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPCPP_THREAD_POOL_INTERFACE_H__
-#define __GRPCPP_THREAD_POOL_INTERFACE_H__
+#ifndef GRPCXX_THREAD_POOL_INTERFACE_H
+#define GRPCXX_THREAD_POOL_INTERFACE_H
 
 #include <functional>
 
@@ -49,4 +49,4 @@
 
 }  // namespace grpc
 
-#endif  // __GRPCPP_THREAD_POOL_INTERFACE_H__
+#endif  // GRPCXX_THREAD_POOL_INTERFACE_H
diff --git a/include/grpc/byte_buffer.h b/include/grpc/byte_buffer.h
index 89d8557e..0ff494c 100644
--- a/include/grpc/byte_buffer.h
+++ b/include/grpc/byte_buffer.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_BYTE_BUFFER_H__
-#define __GRPC_BYTE_BUFFER_H__
+#ifndef GRPC_BYTE_BUFFER_H
+#define GRPC_BYTE_BUFFER_H
 
 #include <grpc/grpc.h>
 #include <grpc/support/slice_buffer.h>
@@ -47,4 +47,4 @@
   } data;
 };
 
-#endif /* __GRPC_BYTE_BUFFER_H__ */
+#endif  /* GRPC_BYTE_BUFFER_H */
diff --git a/include/grpc/byte_buffer_reader.h b/include/grpc/byte_buffer_reader.h
index 4446e0c..cb757cf 100644
--- a/include/grpc/byte_buffer_reader.h
+++ b/include/grpc/byte_buffer_reader.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_BYTE_BUFFER_READER_H__
-#define __GRPC_BYTE_BUFFER_READER_H__
+#ifndef GRPC_BYTE_BUFFER_READER_H
+#define GRPC_BYTE_BUFFER_READER_H
 
 #include <grpc/grpc.h>
 #include <grpc/byte_buffer.h>
@@ -46,4 +46,4 @@
   } current;
 };
 
-#endif /* __GRPC_BYTE_BUFFER_READER_H__ */
+#endif  /* GRPC_BYTE_BUFFER_READER_H */
diff --git a/include/grpc/grpc.h b/include/grpc/grpc.h
index 4a720d1..bb16531 100644
--- a/include/grpc/grpc.h
+++ b/include/grpc/grpc.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_GRPC_H__
-#define __GRPC_GRPC_H__
+#ifndef GRPC_GRPC_H
+#define GRPC_GRPC_H
 
 #include <grpc/status.h>
 
@@ -632,4 +632,4 @@
 }
 #endif
 
-#endif /* __GRPC_GRPC_H__ */
+#endif  /* GRPC_GRPC_H */
diff --git a/include/grpc/grpc_http.h b/include/grpc/grpc_http.h
index 757f53f..c41e874 100644
--- a/include/grpc/grpc_http.h
+++ b/include/grpc/grpc_http.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_GRPC_HTTP_H__
-#define __GRPC_GRPC_HTTP_H__
+#ifndef GRPC_GRPC_HTTP_H
+#define GRPC_GRPC_HTTP_H
 
 #ifdef __cplusplus
 extern "C" {
@@ -64,4 +64,4 @@
 }
 #endif
 
-#endif /* __GRPC_GRPC_HTTP_H__ */
+#endif  /* GRPC_GRPC_HTTP_H */
diff --git a/include/grpc/grpc_security.h b/include/grpc/grpc_security.h
index 4ba4ffc..577f03e 100644
--- a/include/grpc/grpc_security.h
+++ b/include/grpc/grpc_security.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_SECURITY_H_
-#define GRPC_SECURITY_H_
+#ifndef GRPC_GRPC_SECURITY_H
+#define GRPC_GRPC_SECURITY_H
 
 #include "grpc.h"
 #include "status.h"
@@ -185,4 +185,4 @@
 }
 #endif
 
-#endif /* GRPC_SECURITY_H_ */
+#endif  /* GRPC_GRPC_SECURITY_H */
diff --git a/include/grpc/status.h b/include/grpc/status.h
index 76a71ed..a1a4d2f 100644
--- a/include/grpc/status.h
+++ b/include/grpc/status.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_STATUS_H__
-#define __GRPC_STATUS_H__
+#ifndef GRPC_STATUS_H
+#define GRPC_STATUS_H
 
 #ifdef __cplusplus
 extern "C" {
@@ -199,4 +199,4 @@
 }
 #endif
 
-#endif /* __GRPC_STATUS_H__ */
+#endif  /* GRPC_STATUS_H */
diff --git a/include/grpc/support/alloc.h b/include/grpc/support/alloc.h
index 09ea975..509870f 100644
--- a/include/grpc/support/alloc.h
+++ b/include/grpc/support/alloc.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_SUPPORT_ALLOC_H__
-#define __GRPC_SUPPORT_ALLOC_H__
+#ifndef GRPC_SUPPORT_ALLOC_H
+#define GRPC_SUPPORT_ALLOC_H
 
 #include <stddef.h>
 
@@ -55,4 +55,4 @@
 }
 #endif
 
-#endif /* __GRPC_SUPPORT_ALLOC_H__ */
+#endif  /* GRPC_SUPPORT_ALLOC_H */
diff --git a/include/grpc/support/atm.h b/include/grpc/support/atm.h
index f1e30d3..feca6b3 100644
--- a/include/grpc/support/atm.h
+++ b/include/grpc/support/atm.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_SUPPORT_ATM_H__
-#define __GRPC_SUPPORT_ATM_H__
+#ifndef GRPC_SUPPORT_ATM_H
+#define GRPC_SUPPORT_ATM_H
 
 /* This interface provides atomic operations and barriers.
    It is internal to gpr support code and should not be used outside it.
@@ -89,4 +89,4 @@
 #error could not determine platform for atm
 #endif
 
-#endif /* __GRPC_SUPPORT_ATM_H__ */
+#endif  /* GRPC_SUPPORT_ATM_H */
diff --git a/include/grpc/support/atm_gcc_atomic.h b/include/grpc/support/atm_gcc_atomic.h
index 2ae24ae..11d78b4 100644
--- a/include/grpc/support/atm_gcc_atomic.h
+++ b/include/grpc/support/atm_gcc_atomic.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_SUPPORT_ATM_GCC_ATOMIC_H__
-#define __GRPC_SUPPORT_ATM_GCC_ATOMIC_H__
+#ifndef GRPC_SUPPORT_ATM_GCC_ATOMIC_H
+#define GRPC_SUPPORT_ATM_GCC_ATOMIC_H
 
 /* atm_platform.h for gcc and gcc-like compilers with the
    __atomic_* interface.  */
@@ -66,4 +66,4 @@
                                      __ATOMIC_RELAXED);
 }
 
-#endif /* __GRPC_SUPPORT_ATM_GCC_ATOMIC_H__ */
+#endif  /* GRPC_SUPPORT_ATM_GCC_ATOMIC_H */
diff --git a/include/grpc/support/atm_gcc_sync.h b/include/grpc/support/atm_gcc_sync.h
index cec62e1..e863bfd 100644
--- a/include/grpc/support/atm_gcc_sync.h
+++ b/include/grpc/support/atm_gcc_sync.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_SUPPORT_ATM_GCC_SYNC_H__
-#define __GRPC_SUPPORT_ATM_GCC_SYNC_H__
+#ifndef GRPC_SUPPORT_ATM_GCC_SYNC_H
+#define GRPC_SUPPORT_ATM_GCC_SYNC_H
 
 /* variant of atm_platform.h for gcc and gcc-like compiers with __sync_*
    interface */
@@ -70,4 +70,4 @@
 #define gpr_atm_acq_cas(p, o, n) (__sync_bool_compare_and_swap((p), (o), (n)))
 #define gpr_atm_rel_cas(p, o, n) gpr_atm_acq_cas((p), (o), (n))
 
-#endif /* __GRPC_SUPPORT_ATM_GCC_SYNC_H__ */
+#endif  /* GRPC_SUPPORT_ATM_GCC_SYNC_H */
diff --git a/include/grpc/support/atm_win32.h b/include/grpc/support/atm_win32.h
index 9bb1cfe..3b9113c 100644
--- a/include/grpc/support/atm_win32.h
+++ b/include/grpc/support/atm_win32.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_SUPPORT_ATM_WIN32_H__
-#define __GRPC_SUPPORT_ATM_WIN32_H__
+#ifndef GRPC_SUPPORT_ATM_WIN32_H
+#define GRPC_SUPPORT_ATM_WIN32_H
 
 /* Win32 variant of atm_platform.h */
 #include <grpc/support/port_platform.h>
@@ -105,4 +105,4 @@
   return old;
 }
 
-#endif /* __GRPC_SUPPORT_ATM_WIN32_H__ */
+#endif  /* GRPC_SUPPORT_ATM_WIN32_H */
diff --git a/include/grpc/support/cancellable_platform.h b/include/grpc/support/cancellable_platform.h
index e77f9f1..e8e4b84 100644
--- a/include/grpc/support/cancellable_platform.h
+++ b/include/grpc/support/cancellable_platform.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_SUPPORT_CANCELLABLE_PLATFORM_H__
-#define __GRPC_SUPPORT_CANCELLABLE_PLATFORM_H__
+#ifndef GRPC_SUPPORT_CANCELLABLE_PLATFORM_H
+#define GRPC_SUPPORT_CANCELLABLE_PLATFORM_H
 
 #include <grpc/support/atm.h>
 #include <grpc/support/sync.h>
@@ -53,4 +53,4 @@
   struct gpr_cancellable_list_ waiters;
 } gpr_cancellable;
 
-#endif /* __GRPC_SUPPORT_CANCELLABLE_PLATFORM_H__ */
+#endif  /* GRPC_SUPPORT_CANCELLABLE_PLATFORM_H */
diff --git a/include/grpc/support/cmdline.h b/include/grpc/support/cmdline.h
index 20de122..c2350a0 100644
--- a/include/grpc/support/cmdline.h
+++ b/include/grpc/support/cmdline.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_SUPPORT_CMDLINE_H__
-#define __GRPC_SUPPORT_CMDLINE_H__
+#ifndef GRPC_SUPPORT_CMDLINE_H
+#define GRPC_SUPPORT_CMDLINE_H
 
 #ifdef __cplusplus
 extern "C" {
@@ -92,4 +92,4 @@
 }
 #endif
 
-#endif /* __GRPC_SUPPORT_CMDLINE_H__ */
+#endif  /* GRPC_SUPPORT_CMDLINE_H */
diff --git a/include/grpc/support/cpu.h b/include/grpc/support/cpu.h
index 580f12d..005c3c7 100644
--- a/include/grpc/support/cpu.h
+++ b/include/grpc/support/cpu.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_INTERNAL_SUPPORT_CPU_H__
-#define __GRPC_INTERNAL_SUPPORT_CPU_H__
+#ifndef GRPC_SUPPORT_CPU_H
+#define GRPC_SUPPORT_CPU_H
 
 #ifdef __cplusplus
 extern "C" {
@@ -54,4 +54,4 @@
 }  // extern "C"
 #endif
 
-#endif /* __GRPC_INTERNAL_SUPPORT_CPU_H__ */
+#endif  /* GRPC_SUPPORT_CPU_H */
diff --git a/include/grpc/support/histogram.h b/include/grpc/support/histogram.h
index fb9d3d1..31f7fed 100644
--- a/include/grpc/support/histogram.h
+++ b/include/grpc/support/histogram.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_SUPPORT_HISTOGRAM_H__
-#define __GRPC_SUPPORT_HISTOGRAM_H__
+#ifndef GRPC_SUPPORT_HISTOGRAM_H
+#define GRPC_SUPPORT_HISTOGRAM_H
 
 #ifdef __cplusplus
 extern "C" {
@@ -63,4 +63,4 @@
 }
 #endif
 
-#endif /* __GRPC_SUPPORT_HISTOGRAM_H__ */
+#endif  /* GRPC_SUPPORT_HISTOGRAM_H */
diff --git a/include/grpc/support/host_port.h b/include/grpc/support/host_port.h
index 2dac38a..3cc2f49 100644
--- a/include/grpc/support/host_port.h
+++ b/include/grpc/support/host_port.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_SUPPORT_HOST_PORT_H__
-#define __GRPC_SUPPORT_HOST_PORT_H__
+#ifndef GRPC_SUPPORT_HOST_PORT_H
+#define GRPC_SUPPORT_HOST_PORT_H
 
 #ifdef __cplusplus
 extern "C" {
@@ -59,4 +59,4 @@
 }
 #endif
 
-#endif /* __GRPC_SUPPORT_HOST_PORT_H__ */
+#endif  /* GRPC_SUPPORT_HOST_PORT_H */
diff --git a/include/grpc/support/log.h b/include/grpc/support/log.h
index c142949..aad4f23 100644
--- a/include/grpc/support/log.h
+++ b/include/grpc/support/log.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_SUPPORT_LOG_H__
-#define __GRPC_SUPPORT_LOG_H__
+#ifndef GRPC_SUPPORT_LOG_H
+#define GRPC_SUPPORT_LOG_H
 
 #include <stdlib.h> /* for abort() */
 #include <stdarg.h>
@@ -105,4 +105,4 @@
 }
 #endif
 
-#endif /* __GRPC_SUPPORT_LOG_H__ */
+#endif  /* GRPC_SUPPORT_LOG_H */
diff --git a/include/grpc/support/log_win32.h b/include/grpc/support/log_win32.h
index 52d6a70..ad0edcd 100644
--- a/include/grpc/support/log_win32.h
+++ b/include/grpc/support/log_win32.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_SUPPORT_LOG_WIN32_H__
-#define __GRPC_SUPPORT_LOG_WIN32_H__
+#ifndef GRPC_SUPPORT_LOG_WIN32_H
+#define GRPC_SUPPORT_LOG_WIN32_H
 
 #include <windows.h>
 
@@ -50,4 +50,4 @@
 }
 #endif
 
-#endif /* __GRPC_SUPPORT_LOG_H__ */
+#endif  /* GRPC_SUPPORT_LOG_WIN32_H */
diff --git a/include/grpc/support/port_platform.h b/include/grpc/support/port_platform.h
index 0a65175..f04c2e7 100644
--- a/include/grpc/support/port_platform.h
+++ b/include/grpc/support/port_platform.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_SUPPORT_PORT_PLATFORM_H__
-#define __GRPC_SUPPORT_PORT_PLATFORM_H__
+#ifndef GRPC_SUPPORT_PORT_PLATFORM_H
+#define GRPC_SUPPORT_PORT_PLATFORM_H
 
 /* Override this file with one for your platform if you need to redefine
    things.  */
@@ -206,4 +206,4 @@
    power of two */
 #define GPR_MAX_ALIGNMENT 16
 
-#endif /* __GRPC_SUPPORT_PORT_PLATFORM_H__ */
+#endif  /* GRPC_SUPPORT_PORT_PLATFORM_H */
diff --git a/include/grpc/support/slice.h b/include/grpc/support/slice.h
index 8a21290..9026602 100644
--- a/include/grpc/support/slice.h
+++ b/include/grpc/support/slice.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_SUPPORT_SLICE_H__
-#define __GRPC_SUPPORT_SLICE_H__
+#ifndef GRPC_SUPPORT_SLICE_H
+#define GRPC_SUPPORT_SLICE_H
 
 #include <grpc/support/sync.h>
 
@@ -175,4 +175,4 @@
 }
 #endif
 
-#endif /* __GRPC_SUPPORT_SLICE_H__ */
+#endif  /* GRPC_SUPPORT_SLICE_H */
diff --git a/include/grpc/support/slice_buffer.h b/include/grpc/support/slice_buffer.h
index 8b57f9f..56f71ef 100644
--- a/include/grpc/support/slice_buffer.h
+++ b/include/grpc/support/slice_buffer.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_SUPPORT_SLICE_BUFFER_H__
-#define __GRPC_SUPPORT_SLICE_BUFFER_H__
+#ifndef GRPC_SUPPORT_SLICE_BUFFER_H
+#define GRPC_SUPPORT_SLICE_BUFFER_H
 
 #include <grpc/support/slice.h>
 
@@ -81,4 +81,4 @@
 }
 #endif
 
-#endif /* __GRPC_SUPPORT_SLICE_BUFFER_H__ */
+#endif  /* GRPC_SUPPORT_SLICE_BUFFER_H */
diff --git a/include/grpc/support/sync.h b/include/grpc/support/sync.h
index bc99317..35b2d12 100644
--- a/include/grpc/support/sync.h
+++ b/include/grpc/support/sync.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_SUPPORT_SYNC_H__
-#define __GRPC_SUPPORT_SYNC_H__
+#ifndef GRPC_SUPPORT_SYNC_H
+#define GRPC_SUPPORT_SYNC_H
 /* Synchronization primitives for GPR.
 
    The type  gpr_mu              provides a non-reentrant mutex (lock).
@@ -345,4 +345,4 @@
 }
 #endif
 
-#endif /* __GRPC_SUPPORT_SYNC_H__ */
+#endif  /* GRPC_SUPPORT_SYNC_H */
diff --git a/include/grpc/support/sync_generic.h b/include/grpc/support/sync_generic.h
index 3bae222..bbd1b3e 100644
--- a/include/grpc/support/sync_generic.h
+++ b/include/grpc/support/sync_generic.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_SUPPORT_SYNC_GENERIC_H__
-#define __GRPC_SUPPORT_SYNC_GENERIC_H__
+#ifndef GRPC_SUPPORT_SYNC_GENERIC_H
+#define GRPC_SUPPORT_SYNC_GENERIC_H
 /* Generic type defintions for gpr_sync. */
 
 #include <grpc/support/atm.h>
@@ -58,4 +58,4 @@
 #define GPR_STATS_INIT \
   { 0 }
 
-#endif /* __GRPC_SUPPORT_SYNC_GENERIC_H__ */
+#endif  /* GRPC_SUPPORT_SYNC_GENERIC_H */
diff --git a/include/grpc/support/sync_posix.h b/include/grpc/support/sync_posix.h
index 8ba2c5b..762d9eb 100644
--- a/include/grpc/support/sync_posix.h
+++ b/include/grpc/support/sync_posix.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_SUPPORT_SYNC_POSIX_H__
-#define __GRPC_SUPPORT_SYNC_POSIX_H__
+#ifndef GRPC_SUPPORT_SYNC_POSIX_H
+#define GRPC_SUPPORT_SYNC_POSIX_H
 
 #include <grpc/support/sync_generic.h>
 
@@ -44,4 +44,4 @@
 
 #define GPR_ONCE_INIT PTHREAD_ONCE_INIT
 
-#endif /* __GRPC_SUPPORT_SYNC_POSIX_H__ */
+#endif  /* GRPC_SUPPORT_SYNC_POSIX_H */
diff --git a/include/grpc/support/sync_win32.h b/include/grpc/support/sync_win32.h
index 13823b8..cb2a866 100644
--- a/include/grpc/support/sync_win32.h
+++ b/include/grpc/support/sync_win32.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_SUPPORT_SYNC_WIN32_H__
-#define __GRPC_SUPPORT_SYNC_WIN32_H__
+#ifndef GRPC_SUPPORT_SYNC_WIN32_H
+#define GRPC_SUPPORT_SYNC_WIN32_H
 
 #include <grpc/support/sync_generic.h>
 
@@ -48,4 +48,4 @@
 typedef INIT_ONCE gpr_once;
 #define GPR_ONCE_INIT INIT_ONCE_STATIC_INIT
 
-#endif /* __GRPC_SUPPORT_SYNC_WIN32_H__ */
+#endif  /* GRPC_SUPPORT_SYNC_WIN32_H */
diff --git a/include/grpc/support/thd.h b/include/grpc/support/thd.h
index a81e6cd..64d5bed 100644
--- a/include/grpc/support/thd.h
+++ b/include/grpc/support/thd.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_SUPPORT_THD_H__
-#define __GRPC_SUPPORT_THD_H__
+#ifndef GRPC_SUPPORT_THD_H
+#define GRPC_SUPPORT_THD_H
 /* Thread interface for GPR.
 
    Types
@@ -73,4 +73,4 @@
 }
 #endif
 
-#endif /* __GRPC_SUPPORT_THD_H__ */
+#endif  /* GRPC_SUPPORT_THD_H */
diff --git a/include/grpc/support/time.h b/include/grpc/support/time.h
index 150b7ac..1fd3181 100644
--- a/include/grpc/support/time.h
+++ b/include/grpc/support/time.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_SUPPORT_TIME_H__
-#define __GRPC_SUPPORT_TIME_H__
+#ifndef GRPC_SUPPORT_TIME_H
+#define GRPC_SUPPORT_TIME_H
 /* Time support.
    We use gpr_timespec, which is analogous to struct timespec.  On some
    machines, absolute times may be in local time.  */
@@ -100,4 +100,4 @@
 }
 #endif
 
-#endif /* __GRPC_SUPPORT_TIME_H__ */
+#endif  /* GRPC_SUPPORT_TIME_H */
diff --git a/include/grpc/support/useful.h b/include/grpc/support/useful.h
index 8d756c3..979f3d0 100644
--- a/include/grpc/support/useful.h
+++ b/include/grpc/support/useful.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_SUPPORT_USEFUL_H__
-#define __GRPC_SUPPORT_USEFUL_H__
+#ifndef GRPC_SUPPORT_USEFUL_H
+#define GRPC_SUPPORT_USEFUL_H
 
 /* useful macros that don't belong anywhere else */
 
@@ -45,4 +45,4 @@
 
 #define GPR_ARRAY_SIZE(array) (sizeof(array) / sizeof(*(array)))
 
-#endif /* __GRPC_SUPPORT_USEFUL_H__ */
+#endif  /* GRPC_SUPPORT_USEFUL_H */
diff --git a/src/compiler/cpp_generator.cc b/src/compiler/cpp_generator.cc
index 8910323..eade70d 100644
--- a/src/compiler/cpp_generator.cc
+++ b/src/compiler/cpp_generator.cc
@@ -186,7 +186,7 @@
     printer->Print(
         *vars,
         "std::unique_ptr< ::grpc::ClientAsyncResponseReader< $Response$>> "
-        "$Method$(::grpc::ClientContext* context, "
+        "Async$Method$(::grpc::ClientContext* context, "
         "const $Request$& request, "
         "::grpc::CompletionQueue* cq, void* tag);\n");
   } else if (ClientOnlyStreaming(method)) {
@@ -196,7 +196,7 @@
         "::grpc::ClientContext* context, $Response$* response);\n");
     printer->Print(
         *vars,
-        "std::unique_ptr< ::grpc::ClientAsyncWriter< $Request$>> $Method$("
+        "std::unique_ptr< ::grpc::ClientAsyncWriter< $Request$>> Async$Method$("
         "::grpc::ClientContext* context, $Response$* response, "
         "::grpc::CompletionQueue* cq, void* tag);\n");
   } else if (ServerOnlyStreaming(method)) {
@@ -206,7 +206,7 @@
         "::grpc::ClientContext* context, const $Request$& request);\n");
     printer->Print(
         *vars,
-        "std::unique_ptr< ::grpc::ClientAsyncReader< $Response$>> $Method$("
+        "std::unique_ptr< ::grpc::ClientAsyncReader< $Response$>> Async$Method$("
         "::grpc::ClientContext* context, const $Request$& request, "
         "::grpc::CompletionQueue* cq, void* tag);\n");
   } else if (BidiStreaming(method)) {
@@ -217,7 +217,7 @@
     printer->Print(*vars,
                    "std::unique_ptr<  ::grpc::ClientAsyncReaderWriter< "
                    "$Request$, $Response$>> "
-                   "$Method$(::grpc::ClientContext* context, "
+                   "Async$Method$(::grpc::ClientContext* context, "
                    "::grpc::CompletionQueue* cq, void* tag);\n");
   }
 }
@@ -300,13 +300,13 @@
   (*vars)["Service"] = service->name();
 
   printer->Print(*vars,
-                 "class $Service$ final {\n"
+                 "class $Service$ GRPC_FINAL {\n"
                  " public:\n");
   printer->Indent();
 
   // Client side
   printer->Print(
-      "class Stub final : public ::grpc::InternalStub {\n"
+      "class Stub GRPC_FINAL : public ::grpc::InternalStub {\n"
       " public:\n");
   printer->Indent();
   for (int i = 0; i < service->method_count(); ++i) {
@@ -331,7 +331,7 @@
   for (int i = 0; i < service->method_count(); ++i) {
     PrintHeaderServerMethodSync(printer, service->method(i), vars);
   }
-  printer->Print("::grpc::RpcService* service() override final;\n");
+  printer->Print("::grpc::RpcService* service() GRPC_OVERRIDE GRPC_FINAL;\n");
   printer->Outdent();
   printer->Print(
       " private:\n"
@@ -340,7 +340,7 @@
 
   // Server side - Asynchronous
   printer->Print(
-      "class AsyncService final : public ::grpc::AsynchronousService {\n"
+      "class AsyncService GRPC_FINAL : public ::grpc::AsynchronousService {\n"
       " public:\n");
   printer->Indent();
   (*vars)["MethodCount"] = as_string(service->method_count());
@@ -390,7 +390,7 @@
     printer->Print(
         *vars,
         "std::unique_ptr< ::grpc::ClientAsyncResponseReader< $Response$>> "
-        "$Service$::Stub::$Method$(::grpc::ClientContext* context, "
+        "$Service$::Stub::Async$Method$(::grpc::ClientContext* context, "
         "const $Request$& request, "
         "::grpc::CompletionQueue* cq, void* tag) {\n");
     printer->Print(*vars,
@@ -416,7 +416,7 @@
                    "}\n\n");
     printer->Print(*vars,
                    "std::unique_ptr< ::grpc::ClientAsyncWriter< $Request$>> "
-                   "$Service$::Stub::$Method$("
+                   "$Service$::Stub::Async$Method$("
                    "::grpc::ClientContext* context, $Response$* response, "
                    "::grpc::CompletionQueue* cq, void* tag) {\n");
     printer->Print(*vars,
@@ -443,7 +443,7 @@
                    "}\n\n");
     printer->Print(*vars,
                    "std::unique_ptr< ::grpc::ClientAsyncReader< $Response$>> "
-                   "$Service$::Stub::$Method$("
+                   "$Service$::Stub::Async$Method$("
                    "::grpc::ClientContext* context, const $Request$& request, "
                    "::grpc::CompletionQueue* cq, void* tag) {\n");
     printer->Print(*vars,
@@ -471,7 +471,7 @@
     printer->Print(*vars,
                    "std::unique_ptr< ::grpc::ClientAsyncReaderWriter< "
                    "$Request$, $Response$>> "
-                   "$Service$::Stub::$Method$(::grpc::ClientContext* context, "
+                   "$Service$::Stub::Async$Method$(::grpc::ClientContext* context, "
                    "::grpc::CompletionQueue* cq, void* tag) {\n");
     printer->Print(*vars,
                    "  return std::unique_ptr< ::grpc::ClientAsyncReaderWriter< "
@@ -609,7 +609,7 @@
       "  std::unique_ptr< $Service$::Stub> stub(new $Service$::Stub());\n"
       "  stub->set_channel(channel);\n"
       "  return stub;\n"
-      "};\n\n");
+      "}\n\n");
   for (int i = 0; i < service->method_count(); ++i) {
     (*vars)["Idx"] = as_string(i);
     PrintSourceClientMethod(printer, service->method(i), vars);
diff --git a/src/compiler/cpp_generator.h b/src/compiler/cpp_generator.h
index f5b1ad2..1bfe5a8 100644
--- a/src/compiler/cpp_generator.h
+++ b/src/compiler/cpp_generator.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef NET_GRPC_COMPILER_CPP_GENERATOR_H_
-#define NET_GRPC_COMPILER_CPP_GENERATOR_H_
+#ifndef GRPC_INTERNAL_COMPILER_CPP_GENERATOR_H
+#define GRPC_INTERNAL_COMPILER_CPP_GENERATOR_H
 
 #include <string>
 
@@ -58,4 +58,4 @@
 
 }  // namespace grpc_cpp_generator
 
-#endif  // NET_GRPC_COMPILER_CPP_GENERATOR_H_
+#endif  // GRPC_INTERNAL_COMPILER_CPP_GENERATOR_H
diff --git a/src/compiler/cpp_generator_helpers.h b/src/compiler/cpp_generator_helpers.h
index e3c76e0..16abbde 100644
--- a/src/compiler/cpp_generator_helpers.h
+++ b/src/compiler/cpp_generator_helpers.h
@@ -31,57 +31,23 @@
  *
  */
 
-#ifndef NET_GRPC_COMPILER_CPP_GENERATOR_HELPERS_H__
-#define NET_GRPC_COMPILER_CPP_GENERATOR_HELPERS_H__
+#ifndef GRPC_INTERNAL_COMPILER_CPP_GENERATOR_HELPERS_H
+#define GRPC_INTERNAL_COMPILER_CPP_GENERATOR_HELPERS_H
 
 #include <map>
 #include <string>
 #include <google/protobuf/descriptor.h>
 #include <google/protobuf/descriptor.pb.h>
+#include "src/compiler/generator_helpers.h"
 
 namespace grpc_cpp_generator {
 
-inline bool StripSuffix(std::string *filename, const std::string &suffix) {
-  if (filename->length() >= suffix.length()) {
-    size_t suffix_pos = filename->length() - suffix.length();
-    if (filename->compare(suffix_pos, std::string::npos, suffix) == 0) {
-      filename->resize(filename->size() - suffix.size());
-      return true;
-    }
-  }
-
-  return false;
-}
-
-inline std::string StripProto(std::string filename) {
-  if (!StripSuffix(&filename, ".protodevel")) {
-    StripSuffix(&filename, ".proto");
-  }
-  return filename;
-}
-
-inline std::string StringReplace(std::string str, const std::string &from,
-                                 const std::string &to) {
-  size_t pos = 0;
-
-  for (;;) {
-    pos = str.find(from, pos);
-    if (pos == std::string::npos) {
-      break;
-    }
-    str.replace(pos, from.length(), to);
-    pos += to.length();
-  }
-
-  return str;
-}
-
 inline std::string DotsToColons(const std::string &name) {
-  return StringReplace(name, ".", "::");
+  return grpc_generator::StringReplace(name, ".", "::");
 }
 
 inline std::string DotsToUnderscores(const std::string &name) {
-  return StringReplace(name, ".", "_");
+  return grpc_generator::StringReplace(name, ".", "_");
 }
 
 inline std::string ClassName(const google::protobuf::Descriptor *descriptor,
@@ -103,4 +69,4 @@
 
 }  // namespace grpc_cpp_generator
 
-#endif  // NET_GRPC_COMPILER_CPP_GENERATOR_HELPERS_H__
+#endif  // GRPC_INTERNAL_COMPILER_CPP_GENERATOR_HELPERS_H
diff --git a/src/compiler/cpp_plugin.cc b/src/compiler/cpp_plugin.cc
index a421e51..feb158f 100644
--- a/src/compiler/cpp_plugin.cc
+++ b/src/compiler/cpp_plugin.cc
@@ -63,7 +63,7 @@
       return false;
     }
 
-    std::string file_name = grpc_cpp_generator::StripProto(file->name());
+    std::string file_name = grpc_generator::StripProto(file->name());
 
     // Generate .pb.h
     Insert(context, file_name + ".pb.h", "includes",
diff --git a/src/compiler/generator_helpers.h b/src/compiler/generator_helpers.h
new file mode 100644
index 0000000..2035820
--- /dev/null
+++ b/src/compiler/generator_helpers.h
@@ -0,0 +1,79 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef GRPC_INTERNAL_COMPILER_GENERATOR_HELPERS_H
+#define GRPC_INTERNAL_COMPILER_GENERATOR_HELPERS_H
+
+#include <map>
+#include <string>
+
+namespace grpc_generator {
+
+inline bool StripSuffix(std::string *filename, const std::string &suffix) {
+  if (filename->length() >= suffix.length()) {
+    size_t suffix_pos = filename->length() - suffix.length();
+    if (filename->compare(suffix_pos, std::string::npos, suffix) == 0) {
+      filename->resize(filename->size() - suffix.size());
+      return true;
+    }
+  }
+
+  return false;
+}
+
+inline std::string StripProto(std::string filename) {
+  if (!StripSuffix(&filename, ".protodevel")) {
+    StripSuffix(&filename, ".proto");
+  }
+  return filename;
+}
+
+inline std::string StringReplace(std::string str, const std::string &from,
+                                 const std::string &to) {
+  size_t pos = 0;
+
+  for (;;) {
+    pos = str.find(from, pos);
+    if (pos == std::string::npos) {
+      break;
+    }
+    str.replace(pos, from.length(), to);
+    pos += to.length();
+  }
+
+  return str;
+}
+
+}  // namespace grpc_generator
+
+#endif  // GRPC_INTERNAL_COMPILER_GENERATOR_HELPERS_H
diff --git a/src/compiler/python_generator.cc b/src/compiler/python_generator.cc
index cdd3d8a..b8d4aa5 100644
--- a/src/compiler/python_generator.cc
+++ b/src/compiler/python_generator.cc
@@ -31,26 +31,38 @@
  *
  */
 
+#include <algorithm>
 #include <cassert>
 #include <cctype>
+#include <cstring>
 #include <map>
 #include <ostream>
 #include <sstream>
+#include <vector>
 
+#include "src/compiler/generator_helpers.h"
 #include "src/compiler/python_generator.h"
 #include <google/protobuf/io/printer.h>
 #include <google/protobuf/io/zero_copy_stream_impl_lite.h>
 #include <google/protobuf/descriptor.pb.h>
 #include <google/protobuf/descriptor.h>
 
+using grpc_generator::StringReplace;
+using grpc_generator::StripProto;
+using google::protobuf::Descriptor;
 using google::protobuf::FileDescriptor;
-using google::protobuf::ServiceDescriptor;
 using google::protobuf::MethodDescriptor;
+using google::protobuf::ServiceDescriptor;
 using google::protobuf::io::Printer;
 using google::protobuf::io::StringOutputStream;
 using std::initializer_list;
+using std::make_pair;
 using std::map;
+using std::pair;
+using std::replace;
 using std::string;
+using std::strlen;
+using std::vector;
 
 namespace grpc_python_generator {
 namespace {
@@ -99,62 +111,81 @@
 // END FORMATTING BOILERPLATE //
 ////////////////////////////////
 
-void PrintService(const ServiceDescriptor* service,
-                  Printer* out) {
-  string doc = "<fill me in later!>";
-  map<string, string> dict = ListToDict({
-        "Service", service->name(),
-        "Documentation", doc,
-      });
-  out->Print(dict, "class $Service$Service(object):\n");
-  {
-    IndentScope raii_class_indent(out);
-    out->Print(dict, "\"\"\"$Documentation$\"\"\"\n");
-    out->Print("def __init__(self):\n");
-    {
-      IndentScope raii_method_indent(out);
-      out->Print("pass\n");
-    }
-  }
-}
-
-void PrintServicer(const ServiceDescriptor* service,
+bool PrintServicer(const ServiceDescriptor* service,
                    Printer* out) {
   string doc = "<fill me in later!>";
   map<string, string> dict = ListToDict({
         "Service", service->name(),
         "Documentation", doc,
       });
-  out->Print(dict, "class $Service$Servicer(object):\n");
+  out->Print(dict, "class EarlyAdopter$Service$Servicer(object):\n");
   {
     IndentScope raii_class_indent(out);
     out->Print(dict, "\"\"\"$Documentation$\"\"\"\n");
+    out->Print("__metaclass__ = abc.ABCMeta\n");
     for (int i = 0; i < service->method_count(); ++i) {
       auto meth = service->method(i);
-      out->Print("def $Method$(self, arg):\n", "Method", meth->name());
+      string arg_name = meth->client_streaming() ?
+          "request_iterator" : "request";
+      out->Print("@abc.abstractmethod\n");
+      out->Print("def $Method$(self, $ArgName$, context):\n",
+                 "Method", meth->name(), "ArgName", arg_name);
       {
         IndentScope raii_method_indent(out);
         out->Print("raise NotImplementedError()\n");
       }
     }
   }
+  return true;
 }
 
-void PrintStub(const ServiceDescriptor* service,
+bool PrintServer(const ServiceDescriptor* service, Printer* out) {
+  string doc = "<fill me in later!>";
+  map<string, string> dict = ListToDict({
+        "Service", service->name(),
+        "Documentation", doc,
+      });
+  out->Print(dict, "class EarlyAdopter$Service$Server(object):\n");
+  {
+    IndentScope raii_class_indent(out);
+    out->Print(dict, "\"\"\"$Documentation$\"\"\"\n");
+    out->Print("__metaclass__ = abc.ABCMeta\n");
+    out->Print("@abc.abstractmethod\n");
+    out->Print("def start(self):\n");
+    {
+      IndentScope raii_method_indent(out);
+      out->Print("raise NotImplementedError()\n");
+    }
+
+    out->Print("@abc.abstractmethod\n");
+    out->Print("def stop(self):\n");
+    {
+      IndentScope raii_method_indent(out);
+      out->Print("raise NotImplementedError()\n");
+    }
+  }
+  return true;
+}
+
+bool PrintStub(const ServiceDescriptor* service,
                Printer* out) {
   string doc = "<fill me in later!>";
   map<string, string> dict = ListToDict({
         "Service", service->name(),
         "Documentation", doc,
       });
-  out->Print(dict, "class $Service$Stub(object):\n");
+  out->Print(dict, "class EarlyAdopter$Service$Stub(object):\n");
   {
     IndentScope raii_class_indent(out);
     out->Print(dict, "\"\"\"$Documentation$\"\"\"\n");
+    out->Print("__metaclass__ = abc.ABCMeta\n");
     for (int i = 0; i < service->method_count(); ++i) {
       const MethodDescriptor* meth = service->method(i);
-      auto methdict = ListToDict({"Method", meth->name()});
-      out->Print(methdict, "def $Method$(self, arg):\n");
+      string arg_name = meth->client_streaming() ?
+          "request_iterator" : "request";
+      auto methdict = ListToDict({"Method", meth->name(), "ArgName", arg_name});
+      out->Print("@abc.abstractmethod\n");
+      out->Print(methdict, "def $Method$(self, $ArgName$):\n");
       {
         IndentScope raii_method_indent(out);
         out->Print("raise NotImplementedError()\n");
@@ -162,169 +193,195 @@
       out->Print(methdict, "$Method$.async = None\n");
     }
   }
+  return true;
 }
 
-void PrintStubImpl(const ServiceDescriptor* service,
-                   Printer* out) {
-  map<string, string> dict = ListToDict({
-        "Service", service->name(),
-      });
-  out->Print(dict, "class _$Service$Stub($Service$Stub):\n");
-  {
-    IndentScope raii_class_indent(out);
-    out->Print("def __init__(self, face_stub, default_timeout):\n");
-    {
-      IndentScope raii_method_indent(out);
-      out->Print("self._face_stub = face_stub\n"
-                 "self._default_timeout = default_timeout\n"
-                 "stub_self = self\n");
+// TODO(protobuf team): Export `ModuleName` from protobuf's
+// `src/google/protobuf/compiler/python/python_generator.cc` file.
+string ModuleName(const string& filename) {
+  string basename = StripProto(filename);
+  basename = StringReplace(basename, "-", "_");
+  basename = StringReplace(basename, "/", ".");
+  return basename + "_pb2";
+}
 
-      for (int i = 0; i < service->method_count(); ++i) {
-        const MethodDescriptor* meth = service->method(i);
-        bool server_streaming = meth->server_streaming();
-        bool client_streaming = meth->client_streaming();
-        std::string blocking_call, future_call;
-        if (server_streaming) {
-          if (client_streaming) {
-            blocking_call = "stub_self._face_stub.inline_stream_in_stream_out";
-            future_call = blocking_call;
-          } else {
-            blocking_call = "stub_self._face_stub.inline_value_in_stream_out";
-            future_call = blocking_call;
-          }
-        } else {
-          if (client_streaming) {
-            blocking_call = "stub_self._face_stub.blocking_stream_in_value_out";
-            future_call = "stub_self._face_stub.future_stream_in_value_out";
-          } else {
-            blocking_call = "stub_self._face_stub.blocking_value_in_value_out";
-            future_call = "stub_self._face_stub.future_value_in_value_out";
-          }
-        }
-        // TODO(atash): use the solution described at
-        // http://stackoverflow.com/a/2982 to bind 'async' attribute
-        // functions to def'd functions instead of using callable attributes.
-        auto methdict = ListToDict({
-          "Method", meth->name(),
-          "BlockingCall", blocking_call,
-          "FutureCall", future_call
-        });
-        out->Print(methdict, "class $Method$(object):\n");
-        {
-          IndentScope raii_callable_indent(out);
-          out->Print("def __call__(self, arg):\n");
-          {
-            IndentScope raii_callable_call_indent(out);
-            out->Print(methdict,
-                       "return $BlockingCall$(\"$Method$\", arg, "
-                       "stub_self._default_timeout)\n");
-          }
-          out->Print("def async(self, arg):\n");
-          {
-            IndentScope raii_callable_async_indent(out);
-            out->Print(methdict,
-                       "return $FutureCall$(\"$Method$\", arg, "
-                       "stub_self._default_timeout)\n");
-          }
-        }
-        out->Print(methdict, "self.$Method$ = $Method$()\n");
-      }
-    }
+bool GetModuleAndMessagePath(const Descriptor* type,
+                             pair<string, string>* out) {
+  const Descriptor* path_elem_type = type;
+  vector<const Descriptor*> message_path;
+  do {
+    message_path.push_back(path_elem_type);
+    path_elem_type = path_elem_type->containing_type();
+  } while (path_elem_type != nullptr);
+  string file_name = type->file()->name();
+  static const int proto_suffix_length = strlen(".proto");
+  if (!(file_name.size() > static_cast<size_t>(proto_suffix_length) &&
+        file_name.find_last_of(".proto") == file_name.size() - 1)) {
+    return false;
   }
+  string module = ModuleName(file_name);
+  string message_type;
+  for (auto path_iter = message_path.rbegin();
+       path_iter != message_path.rend(); ++path_iter) {
+    message_type += (*path_iter)->name() + ".";
+  }
+  // no pop_back prior to C++11
+  message_type.resize(message_type.size() - 1);
+  *out = make_pair(module, message_type);
+  return true;
 }
 
-void PrintStubGenerators(const ServiceDescriptor* service, Printer* out) {
-  map<string, string> dict = ListToDict({
-        "Service", service->name(),
-      });
-  // Write out a generator of linked pairs of Server/Stub
-  out->Print(dict, "def mock_$Service$(servicer, default_timeout):\n");
+bool PrintServerFactory(const ServiceDescriptor* service, Printer* out) {
+  out->Print("def early_adopter_create_$Service$_server(servicer, port, "
+             "root_certificates, key_chain_pairs):\n",
+             "Service", service->name());
   {
-    IndentScope raii_mock_indent(out);
-    out->Print("value_in_value_out = {}\n"
-               "value_in_stream_out = {}\n"
-               "stream_in_value_out = {}\n"
-               "stream_in_stream_out = {}\n");
+    IndentScope raii_create_server_indent(out);
+    map<string, pair<string, string>> method_to_module_and_message;
+    out->Print("method_implementations = {\n");
     for (int i = 0; i < service->method_count(); ++i) {
+      IndentScope raii_implementations_indent(out);
       const MethodDescriptor* meth = service->method(i);
-      std::string super_interface, meth_dict;
-      bool server_streaming = meth->server_streaming();
-      bool client_streaming = meth->client_streaming();
-      if (server_streaming) {
-        if (client_streaming) {
-          super_interface = "InlineStreamInStreamOutMethod";
-          meth_dict = "stream_in_stream_out";
-        } else {
-          super_interface = "InlineValueInStreamOutMethod";
-          meth_dict = "value_in_stream_out";
-        }
-      } else {
-        if (client_streaming) {
-          super_interface = "InlineStreamInValueOutMethod";
-          meth_dict = "stream_in_value_out";
-        } else {
-          super_interface = "InlineValueInValueOutMethod";
-          meth_dict = "value_in_value_out";
-        }
+      string meth_type =
+          string(meth->client_streaming() ? "stream" : "unary") +
+          string(meth->server_streaming() ? "_stream" : "_unary") + "_inline";
+      out->Print("\"$Method$\": utilities.$Type$(servicer.$Method$),\n",
+                 "Method", meth->name(),
+                 "Type", meth_type);
+      // Maintain information on the input type of the service method for later
+      // use in constructing the service assembly's activated fore link.
+      const Descriptor* input_type = meth->input_type();
+      pair<string, string> module_and_message;
+      if (!GetModuleAndMessagePath(input_type, &module_and_message)) {
+        return false;
       }
-      map<string, string> methdict = ListToDict({
-            "Method", meth->name(),
-            "SuperInterface", super_interface,
-            "MethodDict", meth_dict
-          });
-      out->Print(
-          methdict, "class $Method$(_face_interfaces.$SuperInterface$):\n");
-      {
-        IndentScope raii_inline_class_indent(out);
-        out->Print("def service(self, request, context):\n");
-        {
-          IndentScope raii_inline_class_fn_indent(out);
-          out->Print(methdict, "return servicer.$Method$(request)\n");
-        }
-      }
-      out->Print(methdict, "$MethodDict$['$Method$'] = $Method$()\n");
+      method_to_module_and_message.insert(
+          make_pair(meth->name(), module_and_message));
     }
-    out->Print(
-         "face_linked_pair = _face_testing.server_and_stub(default_timeout,"
-         "inline_value_in_value_out_methods=value_in_value_out,"
-         "inline_value_in_stream_out_methods=value_in_stream_out,"
-         "inline_stream_in_value_out_methods=stream_in_value_out,"
-         "inline_stream_in_stream_out_methods=stream_in_stream_out)\n");
-    out->Print("class LinkedPair(object):\n");
-    {
-      IndentScope raii_linked_pair(out);
-      out->Print("def __init__(self, server, stub):\n");
-      {
-        IndentScope raii_linked_pair_init(out);
-        out->Print("self.server = server\n"
-                   "self.stub = stub\n");
-      }
+    out->Print("}\n");
+    // Ensure that we've imported all of the relevant messages.
+    for (auto& meth_vals : method_to_module_and_message) {
+      out->Print("import $Module$\n",
+                 "Module", meth_vals.second.first);
     }
-    out->Print(
-        dict,
-        "stub = _$Service$Stub(face_linked_pair.stub, default_timeout)\n");
-    out->Print("return LinkedPair(None, stub)\n");
+    out->Print("request_deserializers = {\n");
+    for (auto& meth_vals : method_to_module_and_message) {
+      IndentScope raii_serializers_indent(out);
+      string full_input_type_path = meth_vals.second.first + "." +
+          meth_vals.second.second;
+      out->Print("\"$Method$\": $Type$.FromString,\n",
+                 "Method", meth_vals.first,
+                 "Type", full_input_type_path);
+    }
+    out->Print("}\n");
+    out->Print("response_serializers = {\n");
+    for (auto& meth_vals : method_to_module_and_message) {
+      IndentScope raii_serializers_indent(out);
+      out->Print("\"$Method$\": lambda x: x.SerializeToString(),\n",
+                 "Method", meth_vals.first);
+    }
+    out->Print("}\n");
+    out->Print("link = fore.activated_fore_link(port, request_deserializers, "
+               "response_serializers, root_certificates, key_chain_pairs)\n");
+    out->Print("return implementations.assemble_service("
+               "method_implementations, link)\n");
   }
+  return true;
+}
+
+bool PrintStubFactory(const ServiceDescriptor* service, Printer* out) {
+  map<string, string> dict = ListToDict({
+        "Service", service->name(),
+      });
+  out->Print(dict, "def early_adopter_create_$Service$_stub(host, port):\n");
+  {
+    IndentScope raii_create_server_indent(out);
+    map<string, pair<string, string>> method_to_module_and_message;
+    out->Print("method_implementations = {\n");
+    for (int i = 0; i < service->method_count(); ++i) {
+      IndentScope raii_implementations_indent(out);
+      const MethodDescriptor* meth = service->method(i);
+      string meth_type =
+          string(meth->client_streaming() ? "stream" : "unary") +
+          string(meth->server_streaming() ? "_stream" : "_unary") + "_inline";
+      // TODO(atash): once the expected input to assemble_dynamic_inline_stub is
+      // cleaned up, change this to the expected argument's dictionary values.
+      out->Print("\"$Method$\": utilities.$Type$(None),\n",
+                 "Method", meth->name(),
+                 "Type", meth_type);
+      // Maintain information on the input type of the service method for later
+      // use in constructing the service assembly's activated fore link.
+      const Descriptor* output_type = meth->output_type();
+      pair<string, string> module_and_message;
+      if (!GetModuleAndMessagePath(output_type, &module_and_message)) {
+        return false;
+      }
+      method_to_module_and_message.insert(
+          make_pair(meth->name(), module_and_message));
+    }
+    out->Print("}\n");
+    // Ensure that we've imported all of the relevant messages.
+    for (auto& meth_vals : method_to_module_and_message) {
+      out->Print("import $Module$\n",
+                 "Module", meth_vals.second.first);
+    }
+    out->Print("response_deserializers = {\n");
+    for (auto& meth_vals : method_to_module_and_message) {
+      IndentScope raii_serializers_indent(out);
+      string full_output_type_path = meth_vals.second.first + "." +
+          meth_vals.second.second;
+      out->Print("\"$Method$\": $Type$.FromString,\n",
+                 "Method", meth_vals.first,
+                 "Type", full_output_type_path);
+    }
+    out->Print("}\n");
+    out->Print("request_serializers = {\n");
+    for (auto& meth_vals : method_to_module_and_message) {
+      IndentScope raii_serializers_indent(out);
+      out->Print("\"$Method$\": lambda x: x.SerializeToString(),\n",
+                 "Method", meth_vals.first);
+    }
+    out->Print("}\n");
+    out->Print("link = rear.activated_rear_link("
+               "host, port, request_serializers, response_deserializers)\n");
+    out->Print("return implementations.assemble_dynamic_inline_stub("
+               "method_implementations, link)\n");
+  }
+  return true;
+}
+
+bool PrintPreamble(const FileDescriptor* file, Printer* out) {
+  out->Print("import abc\n");
+  out->Print("from grpc._adapter import fore\n");
+  out->Print("from grpc._adapter import rear\n");
+  out->Print("from grpc.framework.assembly import implementations\n");
+  out->Print("from grpc.framework.assembly import utilities\n");
+  return true;
 }
 
 }  // namespace
 
-string GetServices(const FileDescriptor* file) {
+pair<bool, string> GetServices(const FileDescriptor* file) {
   string output;
-  StringOutputStream output_stream(&output);
-  Printer out(&output_stream, '$');
-  out.Print("from grpc.framework.face import demonstration as _face_testing\n");
-  out.Print("from grpc.framework.face import interfaces as _face_interfaces\n");
-
-  for (int i = 0; i < file->service_count(); ++i) {
-    auto service = file->service(i);
-    PrintService(service, &out);
-    PrintServicer(service, &out);
-    PrintStub(service, &out);
-    PrintStubImpl(service, &out);
-    PrintStubGenerators(service, &out);
+  {
+    // Scope the output stream so it closes and finalizes output to the string.
+    StringOutputStream output_stream(&output);
+    Printer out(&output_stream, '$');
+    if (!PrintPreamble(file, &out)) {
+      return make_pair(false, "");
+    }
+    for (int i = 0; i < file->service_count(); ++i) {
+      auto service = file->service(i);
+      if (!(PrintServicer(service, &out) &&
+            PrintServer(service, &out) &&
+            PrintStub(service, &out) &&
+            PrintServerFactory(service, &out) &&
+            PrintStubFactory(service, &out))) {
+        return make_pair(false, "");
+      }
+    }
   }
-  return output;
+  return make_pair(true, std::move(output));
 }
 
 }  // namespace grpc_python_generator
diff --git a/src/compiler/python_generator.h b/src/compiler/python_generator.h
index 673ef7b..df29ca1 100644
--- a/src/compiler/python_generator.h
+++ b/src/compiler/python_generator.h
@@ -31,10 +31,11 @@
  *
  */
 
-#ifndef __GRPC_COMPILER_PYTHON_GENERATOR_H__
-#define __GRPC_COMPILER_PYTHON_GENERATOR_H__
+#ifndef GRPC_INTERNAL_COMPILER_PYTHON_GENERATOR_H
+#define GRPC_INTERNAL_COMPILER_PYTHON_GENERATOR_H
 
 #include <string>
+#include <utility>
 
 namespace google {
 namespace protobuf {
@@ -44,8 +45,8 @@
 
 namespace grpc_python_generator {
 
-std::string GetServices(const google::protobuf::FileDescriptor* file);
+std::pair<bool, std::string> GetServices(const google::protobuf::FileDescriptor* file);
 
 }  // namespace grpc_python_generator
 
-#endif  // __GRPC_COMPILER_PYTHON_GENERATOR_H__
+#endif  // GRPC_INTERNAL_COMPILER_PYTHON_GENERATOR_H
diff --git a/src/compiler/python_plugin.cc b/src/compiler/python_plugin.cc
index 05c6b09..0dd2c5b 100644
--- a/src/compiler/python_plugin.cc
+++ b/src/compiler/python_plugin.cc
@@ -33,6 +33,7 @@
 
 // Generates a Python gRPC service interface out of Protobuf IDL.
 
+#include <cstring>
 #include <memory>
 #include <string>
 
@@ -50,19 +51,18 @@
 using google::protobuf::io::CodedOutputStream;
 using google::protobuf::io::ZeroCopyOutputStream;
 using std::string;
+using std::strlen;
 
 class PythonGrpcGenerator : public CodeGenerator {
  public:
   PythonGrpcGenerator() {}
-  ~PythonGrpcGenerator() override {}
+  ~PythonGrpcGenerator() {}
 
-  bool Generate(const FileDescriptor* file,
-                const string& parameter,
-                GeneratorContext* context,
-                string* error) const override {
+  bool Generate(const FileDescriptor* file, const string& parameter,
+                GeneratorContext* context, string* error) const {
     // Get output file name.
     string file_name;
-    static const int proto_suffix_length = 6;  // length of ".proto"
+    static const int proto_suffix_length = strlen(".proto");
     if (file->name().size() > static_cast<size_t>(proto_suffix_length) &&
         file->name().find_last_of(".proto") == file->name().size() - 1) {
       file_name = file->name().substr(
@@ -75,9 +75,15 @@
     std::unique_ptr<ZeroCopyOutputStream> output(
         context->OpenForInsert(file_name, "module_scope"));
     CodedOutputStream coded_out(output.get());
-    string code = grpc_python_generator::GetServices(file);
-    coded_out.WriteRaw(code.data(), code.size());
-    return true;
+    bool success = false;
+    string code = "";
+    tie(success, code) = grpc_python_generator::GetServices(file);
+    if (success) {
+      coded_out.WriteRaw(code.data(), code.size());
+      return true;
+    } else {
+      return false;
+    }
   }
 };
 
diff --git a/src/compiler/ruby_generator.h b/src/compiler/ruby_generator.h
index d0c568f..4dd38e0 100644
--- a/src/compiler/ruby_generator.h
+++ b/src/compiler/ruby_generator.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef NET_GRPC_COMPILER_RUBY_GENERATOR_H_
-#define NET_GRPC_COMPILER_RUBY_GENERATOR_H_
+#ifndef GRPC_INTERNAL_COMPILER_RUBY_GENERATOR_H
+#define GRPC_INTERNAL_COMPILER_RUBY_GENERATOR_H
 
 #include <string>
 
@@ -48,4 +48,4 @@
 
 }  // namespace grpc_ruby_generator
 
-#endif  // NET_GRPC_COMPILER_RUBY_GENERATOR_H_
+#endif  // GRPC_INTERNAL_COMPILER_RUBY_GENERATOR_H
diff --git a/src/compiler/ruby_generator_helpers-inl.h b/src/compiler/ruby_generator_helpers-inl.h
index 61d887b..f3a087b 100644
--- a/src/compiler/ruby_generator_helpers-inl.h
+++ b/src/compiler/ruby_generator_helpers-inl.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef NET_GRPC_COMPILER_RUBY_GENERATOR_HELPERS_INL_H_
-#define NET_GRPC_COMPILER_RUBY_GENERATOR_HELPERS_INL_H_
+#ifndef GRPC_INTERNAL_COMPILER_RUBY_GENERATOR_HELPERS_INL_H
+#define GRPC_INTERNAL_COMPILER_RUBY_GENERATOR_HELPERS_INL_H
 
 #include <string>
 
@@ -64,4 +64,4 @@
 
 }  // namespace grpc_ruby_generator
 
-#endif  // NET_GRPC_COMPILER_RUBY_GENERATOR_HELPERS_INL_H_
+#endif  // GRPC_INTERNAL_COMPILER_RUBY_GENERATOR_HELPERS_INL_H
diff --git a/src/compiler/ruby_generator_map-inl.h b/src/compiler/ruby_generator_map-inl.h
index a86342e..f902b6d 100644
--- a/src/compiler/ruby_generator_map-inl.h
+++ b/src/compiler/ruby_generator_map-inl.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef NET_GRPC_COMPILER_RUBY_GENERATOR_MAP_INL_H_
-#define NET_GRPC_COMPILER_RUBY_GENERATOR_MAP_INL_H_
+#ifndef GRPC_INTERNAL_COMPILER_RUBY_GENERATOR_MAP_INL_H
+#define GRPC_INTERNAL_COMPILER_RUBY_GENERATOR_MAP_INL_H
 
 #include <iostream>
 #include <initializer_list>
@@ -69,4 +69,4 @@
 
 }  // namespace grpc_ruby_generator
 
-#endif  // NET_GRPC_COMPILER_RUBY_GENERATOR_MAP_INL_H_
+#endif  // GRPC_INTERNAL_COMPILER_RUBY_GENERATOR_MAP_INL_H
diff --git a/src/compiler/ruby_generator_string-inl.h b/src/compiler/ruby_generator_string-inl.h
index 7c2e4e5..bdd314c 100644
--- a/src/compiler/ruby_generator_string-inl.h
+++ b/src/compiler/ruby_generator_string-inl.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef NET_GRPC_COMPILER_RUBY_GENERATOR_STRING_INL_H_
-#define NET_GRPC_COMPILER_RUBY_GENERATOR_STRING_INL_H_
+#ifndef GRPC_INTERNAL_COMPILER_RUBY_GENERATOR_STRING_INL_H
+#define GRPC_INTERNAL_COMPILER_RUBY_GENERATOR_STRING_INL_H
 
 #include <algorithm>
 #include <string>
@@ -130,4 +130,4 @@
 
 }  // namespace grpc_ruby_generator
 
-#endif  // NET_GRPC_COMPILER_RUBY_GENERATOR_STRING_INL_H_
+#endif  // GRPC_INTERNAL_COMPILER_RUBY_GENERATOR_STRING_INL_H
diff --git a/src/compiler/ruby_plugin.cc b/src/compiler/ruby_plugin.cc
index 6580e5a..4a6e9f7 100644
--- a/src/compiler/ruby_plugin.cc
+++ b/src/compiler/ruby_plugin.cc
@@ -50,12 +50,12 @@
 class RubyGrpcGenerator : public google::protobuf::compiler::CodeGenerator {
  public:
   RubyGrpcGenerator() {}
-  ~RubyGrpcGenerator() override {}
+  ~RubyGrpcGenerator() {}
 
   bool Generate(const google::protobuf::FileDescriptor *file,
                 const std::string &parameter,
                 google::protobuf::compiler::GeneratorContext *context,
-                std::string *error) const override {
+                std::string *error) const {
     std::string code = grpc_ruby_generator::GetServices(file);
     if (code.size() == 0) {
       return true;  // don't generate a file if there are no services
diff --git a/src/core/channel/census_filter.h b/src/core/channel/census_filter.h
index 6acf969..4f9759f 100644
--- a/src/core/channel/census_filter.h
+++ b/src/core/channel/census_filter.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_INTERNAL_CHANNEL_CENSUS_FILTER_H__
-#define __GRPC_INTERNAL_CHANNEL_CENSUS_FILTER_H__
+#ifndef GRPC_INTERNAL_CORE_CHANNEL_CENSUS_FILTER_H
+#define GRPC_INTERNAL_CORE_CHANNEL_CENSUS_FILTER_H
 
 #include "src/core/channel/channel_stack.h"
 
@@ -41,4 +41,4 @@
 extern const grpc_channel_filter grpc_client_census_filter;
 extern const grpc_channel_filter grpc_server_census_filter;
 
-#endif /* __GRPC_INTERNAL_CHANNEL_CENSUS_FILTER_H__ */
+#endif  /* GRPC_INTERNAL_CORE_CHANNEL_CENSUS_FILTER_H */
diff --git a/src/core/channel/channel_args.h b/src/core/channel/channel_args.h
index 640bbd8..eb5bf63 100644
--- a/src/core/channel/channel_args.h
+++ b/src/core/channel/channel_args.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_INTERNAL_CHANNEL_CHANNEL_ARGS_H__
-#define __GRPC_INTERNAL_CHANNEL_CHANNEL_ARGS_H__
+#ifndef GRPC_INTERNAL_CORE_CHANNEL_CHANNEL_ARGS_H
+#define GRPC_INTERNAL_CORE_CHANNEL_CHANNEL_ARGS_H
 
 #include <grpc/grpc.h>
 
@@ -51,4 +51,4 @@
    is specified in channel args, otherwise returns 0. */
 int grpc_channel_args_is_census_enabled(const grpc_channel_args *a);
 
-#endif /* __GRPC_INTERNAL_CHANNEL_CHANNEL_ARGS_H__ */
+#endif  /* GRPC_INTERNAL_CORE_CHANNEL_CHANNEL_ARGS_H */
diff --git a/src/core/channel/channel_stack.h b/src/core/channel/channel_stack.h
index 1ca95e7..c136f5c 100644
--- a/src/core/channel/channel_stack.h
+++ b/src/core/channel/channel_stack.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_INTERNAL_CHANNEL_CHANNEL_STACK_H__
-#define __GRPC_INTERNAL_CHANNEL_CHANNEL_STACK_H__
+#ifndef GRPC_INTERNAL_CORE_CHANNEL_CHANNEL_STACK_H
+#define GRPC_INTERNAL_CORE_CHANNEL_CHANNEL_STACK_H
 
 /* A channel filter defines how operations on a channel are implemented.
    Channel filters are chained together to create full channels, and if those
@@ -301,4 +301,4 @@
 #define GRPC_CALL_LOG_OP(sev, elem, op) \
   if (grpc_trace_bits & GRPC_TRACE_CHANNEL) grpc_call_log_op(sev, elem, op)
 
-#endif /* __GRPC_INTERNAL_CHANNEL_CHANNEL_STACK_H__ */
+#endif  /* GRPC_INTERNAL_CORE_CHANNEL_CHANNEL_STACK_H */
diff --git a/src/core/channel/child_channel.h b/src/core/channel/child_channel.h
index 84a1106..3869540 100644
--- a/src/core/channel/child_channel.h
+++ b/src/core/channel/child_channel.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_INTERNAL_CHANNEL_CHILD_CHANNEL_H_
-#define __GRPC_INTERNAL_CHANNEL_CHILD_CHANNEL_H_
+#ifndef GRPC_INTERNAL_CORE_CHANNEL_CHILD_CHANNEL_H
+#define GRPC_INTERNAL_CORE_CHANNEL_CHILD_CHANNEL_H
 
 #include "src/core/channel/channel_stack.h"
 
@@ -61,4 +61,4 @@
 grpc_call_element *grpc_child_call_get_top_element(grpc_child_call *call);
 void grpc_child_call_destroy(grpc_child_call *call);
 
-#endif /* __GRPC_INTERNAL_CHANNEL_CHILD_CHANNEL_H_ */
+#endif  /* GRPC_INTERNAL_CORE_CHANNEL_CHILD_CHANNEL_H */
diff --git a/src/core/channel/client_channel.h b/src/core/channel/client_channel.h
index 7da4fc9..7a67a9f 100644
--- a/src/core/channel/client_channel.h
+++ b/src/core/channel/client_channel.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_INTERNAL_CHANNEL_CLIENT_CHANNEL_H__
-#define __GRPC_INTERNAL_CHANNEL_CLIENT_CHANNEL_H__
+#ifndef GRPC_INTERNAL_CORE_CHANNEL_CLIENT_CHANNEL_H
+#define GRPC_INTERNAL_CORE_CHANNEL_CLIENT_CHANNEL_H
 
 #include "src/core/channel/channel_stack.h"
 
@@ -59,4 +59,4 @@
     grpc_channel_filter const **channel_filters, size_t num_channel_filters,
     grpc_mdctx *mdctx);
 
-#endif /* __GRPC_INTERNAL_CHANNEL_CLIENT_CHANNEL_H__ */
+#endif  /* GRPC_INTERNAL_CORE_CHANNEL_CLIENT_CHANNEL_H */
diff --git a/src/core/channel/client_setup.h b/src/core/channel/client_setup.h
index f2b6426..70137e1 100644
--- a/src/core/channel/client_setup.h
+++ b/src/core/channel/client_setup.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_INTERNAL_CHANNEL_CLIENT_SETUP_H__
-#define __GRPC_INTERNAL_CHANNEL_CLIENT_SETUP_H__
+#ifndef GRPC_INTERNAL_CORE_CHANNEL_CLIENT_SETUP_H
+#define GRPC_INTERNAL_CORE_CHANNEL_CLIENT_SETUP_H
 
 #include "src/core/channel/client_channel.h"
 #include "src/core/transport/metadata.h"
@@ -70,4 +70,4 @@
 
 grpc_mdctx *grpc_client_setup_get_mdctx(grpc_client_setup_request *r);
 
-#endif /* __GRPC_INTERNAL_CHANNEL_CLIENT_SETUP_H__ */
+#endif  /* GRPC_INTERNAL_CORE_CHANNEL_CLIENT_SETUP_H */
diff --git a/src/core/channel/connected_channel.h b/src/core/channel/connected_channel.h
index e19de62..8b35f69 100644
--- a/src/core/channel/connected_channel.h
+++ b/src/core/channel/connected_channel.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_INTERNAL_CHANNEL_CONNECTED_CHANNEL_H__
-#define __GRPC_INTERNAL_CHANNEL_CONNECTED_CHANNEL_H__
+#ifndef GRPC_INTERNAL_CORE_CHANNEL_CONNECTED_CHANNEL_H
+#define GRPC_INTERNAL_CORE_CHANNEL_CONNECTED_CHANNEL_H
 
 #include "src/core/channel/channel_stack.h"
 
@@ -46,4 +46,4 @@
 grpc_transport_setup_result grpc_connected_channel_bind_transport(
     grpc_channel_stack *channel_stack, grpc_transport *transport);
 
-#endif /* __GRPC_INTERNAL_CHANNEL_CONNECTED_CHANNEL_H__ */
+#endif  /* GRPC_INTERNAL_CORE_CHANNEL_CONNECTED_CHANNEL_H */
diff --git a/src/core/channel/http_client_filter.h b/src/core/channel/http_client_filter.h
index 5882f8f..04eb839 100644
--- a/src/core/channel/http_client_filter.h
+++ b/src/core/channel/http_client_filter.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_INTERNAL_CHANNEL_HTTP_CLIENT_FILTER_H__
-#define __GRPC_INTERNAL_CHANNEL_HTTP_CLIENT_FILTER_H__
+#ifndef GRPC_INTERNAL_CORE_CHANNEL_HTTP_CLIENT_FILTER_H
+#define GRPC_INTERNAL_CORE_CHANNEL_HTTP_CLIENT_FILTER_H
 
 #include "src/core/channel/channel_stack.h"
 
@@ -41,4 +41,4 @@
 
 #define GRPC_ARG_HTTP2_SCHEME "grpc.http2_scheme"
 
-#endif /* __GRPC_INTERNAL_CHANNEL_HTTP_CLIENT_FILTER_H__ */
+#endif  /* GRPC_INTERNAL_CORE_CHANNEL_HTTP_CLIENT_FILTER_H */
diff --git a/src/core/channel/http_filter.h b/src/core/channel/http_filter.h
index b85cd39..1b116ad 100644
--- a/src/core/channel/http_filter.h
+++ b/src/core/channel/http_filter.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_INTERNAL_CHANNEL_HTTP_FILTER_H__
-#define __GRPC_INTERNAL_CHANNEL_HTTP_FILTER_H__
+#ifndef GRPC_INTERNAL_CORE_CHANNEL_HTTP_FILTER_H
+#define GRPC_INTERNAL_CORE_CHANNEL_HTTP_FILTER_H
 
 #include "src/core/channel/channel_stack.h"
 
@@ -40,4 +40,4 @@
    transports. */
 extern const grpc_channel_filter grpc_http_filter;
 
-#endif /* __GRPC_INTERNAL_CHANNEL_HTTP_FILTER_H__ */
+#endif  /* GRPC_INTERNAL_CORE_CHANNEL_HTTP_FILTER_H */
diff --git a/src/core/channel/http_server_filter.h b/src/core/channel/http_server_filter.h
index 0643c7b..42f76ed 100644
--- a/src/core/channel/http_server_filter.h
+++ b/src/core/channel/http_server_filter.h
@@ -31,12 +31,12 @@
  *
  */
 
-#ifndef __GRPC_INTERNAL_CHANNEL_HTTP_SERVER_FILTER_H__
-#define __GRPC_INTERNAL_CHANNEL_HTTP_SERVER_FILTER_H__
+#ifndef GRPC_INTERNAL_CORE_CHANNEL_HTTP_SERVER_FILTER_H
+#define GRPC_INTERNAL_CORE_CHANNEL_HTTP_SERVER_FILTER_H
 
 #include "src/core/channel/channel_stack.h"
 
 /* Processes metadata on the client side for HTTP2 transports */
 extern const grpc_channel_filter grpc_http_server_filter;
 
-#endif /* __GRPC_INTERNAL_CHANNEL_HTTP_SERVER_FILTER_H__ */
+#endif  /* GRPC_INTERNAL_CORE_CHANNEL_HTTP_SERVER_FILTER_H */
diff --git a/src/core/channel/metadata_buffer.h b/src/core/channel/metadata_buffer.h
index 701d69d..b7cc517 100644
--- a/src/core/channel/metadata_buffer.h
+++ b/src/core/channel/metadata_buffer.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_INTERNAL_CHANNEL_METADATA_BUFFER_H__
-#define __GRPC_INTERNAL_CHANNEL_METADATA_BUFFER_H__
+#ifndef GRPC_INTERNAL_CORE_CHANNEL_METADATA_BUFFER_H
+#define GRPC_INTERNAL_CORE_CHANNEL_METADATA_BUFFER_H
 
 #include "src/core/channel/channel_stack.h"
 
@@ -67,4 +67,4 @@
     grpc_metadata_buffer *buffer);
 void grpc_metadata_buffer_cleanup_elements(void *elements, grpc_op_error error);
 
-#endif /* __GRPC_INTERNAL_CHANNEL_METADATA_BUFFER_H__ */
+#endif  /* GRPC_INTERNAL_CORE_CHANNEL_METADATA_BUFFER_H */
diff --git a/src/core/channel/noop_filter.h b/src/core/channel/noop_filter.h
index 93c2bff..96463e5 100644
--- a/src/core/channel/noop_filter.h
+++ b/src/core/channel/noop_filter.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_INTERNAL_CHANNEL_NOOP_FILTER_H__
-#define __GRPC_INTERNAL_CHANNEL_NOOP_FILTER_H__
+#ifndef GRPC_INTERNAL_CORE_CHANNEL_NOOP_FILTER_H
+#define GRPC_INTERNAL_CORE_CHANNEL_NOOP_FILTER_H
 
 #include "src/core/channel/channel_stack.h"
 
@@ -41,4 +41,4 @@
    customize for their own filters */
 extern const grpc_channel_filter grpc_no_op_filter;
 
-#endif /* __GRPC_INTERNAL_CHANNEL_NOOP_FILTER_H__ */
+#endif  /* GRPC_INTERNAL_CORE_CHANNEL_NOOP_FILTER_H */
diff --git a/src/core/compression/algorithm.h b/src/core/compression/algorithm.h
index e398ae3..9dd9f57 100644
--- a/src/core/compression/algorithm.h
+++ b/src/core/compression/algorithm.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_INTERNAL_COMPRESSION_ALGORITHM_H__
-#define __GRPC_INTERNAL_COMPRESSION_ALGORITHM_H__
+#ifndef GRPC_INTERNAL_CORE_COMPRESSION_ALGORITHM_H
+#define GRPC_INTERNAL_CORE_COMPRESSION_ALGORITHM_H
 
 /* The various compression algorithms supported by GRPC */
 typedef enum {
@@ -46,4 +46,4 @@
 const char *grpc_compression_algorithm_name(
     grpc_compression_algorithm algorithm);
 
-#endif /* __GRPC_INTERNAL_COMPRESSION_ALGORITHM_H__ */
+#endif  /* GRPC_INTERNAL_CORE_COMPRESSION_ALGORITHM_H */
diff --git a/src/core/compression/message_compress.h b/src/core/compression/message_compress.h
index 666da2e..e8aef1a 100644
--- a/src/core/compression/message_compress.h
+++ b/src/core/compression/message_compress.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_INTERNAL_COMPRESSION_MESSAGE_COMPRESS_H__
-#define __GRPC_INTERNAL_COMPRESSION_MESSAGE_COMPRESS_H__
+#ifndef GRPC_INTERNAL_CORE_COMPRESSION_MESSAGE_COMPRESS_H
+#define GRPC_INTERNAL_CORE_COMPRESSION_MESSAGE_COMPRESS_H
 
 #include "src/core/compression/algorithm.h"
 #include <grpc/support/slice_buffer.h>
@@ -49,4 +49,4 @@
 int grpc_msg_decompress(grpc_compression_algorithm algorithm,
                         gpr_slice_buffer *input, gpr_slice_buffer *output);
 
-#endif /* __GRPC_INTERNAL_COMPRESSION_MESSAGE_COMPRESS_H__ */
+#endif  /* GRPC_INTERNAL_CORE_COMPRESSION_MESSAGE_COMPRESS_H */
diff --git a/src/core/debug/trace.c b/src/core/debug/trace.c
index 92acbe9..b8eb755 100644
--- a/src/core/debug/trace.c
+++ b/src/core/debug/trace.c
@@ -81,6 +81,8 @@
       grpc_trace_bits |= GRPC_TRACE_TCP;
     } else if (0 == strcmp(s, "secure_endpoint")) {
       grpc_trace_bits |= GRPC_TRACE_SECURE_ENDPOINT;
+    } else if (0 == strcmp(s, "http")) {
+      grpc_trace_bits |= GRPC_TRACE_HTTP;
     } else if (0 == strcmp(s, "all")) {
       grpc_trace_bits = -1;
     } else {
diff --git a/src/core/debug/trace.h b/src/core/debug/trace.h
index 167ef3c..2059599 100644
--- a/src/core/debug/trace.h
+++ b/src/core/debug/trace.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_CORE_DEBUG_TRACE_H
-#define GRPC_CORE_DEBUG_TRACE_H
+#ifndef GRPC_INTERNAL_CORE_DEBUG_TRACE_H
+#define GRPC_INTERNAL_CORE_DEBUG_TRACE_H
 
 #include <grpc/support/port_platform.h>
 
@@ -45,7 +45,8 @@
   GRPC_TRACE_SURFACE = 1 << 0,
   GRPC_TRACE_CHANNEL = 1 << 1,
   GRPC_TRACE_TCP = 1 << 2,
-  GRPC_TRACE_SECURE_ENDPOINT = 1 << 3
+  GRPC_TRACE_SECURE_ENDPOINT = 1 << 3,
+  GRPC_TRACE_HTTP = 1 << 4
 } grpc_trace_bit_value;
 
 #if GRPC_ENABLE_TRACING
@@ -56,5 +57,4 @@
 
 void grpc_init_trace_bits();
 
-#endif
-
+#endif  /* GRPC_INTERNAL_CORE_DEBUG_TRACE_H */
diff --git a/src/core/httpcli/format_request.h b/src/core/httpcli/format_request.h
index e06b632..8bfb20b 100644
--- a/src/core/httpcli/format_request.h
+++ b/src/core/httpcli/format_request.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_INTERNAL_HTTPCLI_FORMAT_REQUEST_H__
-#define __GRPC_INTERNAL_HTTPCLI_FORMAT_REQUEST_H__
+#ifndef GRPC_INTERNAL_CORE_HTTPCLI_FORMAT_REQUEST_H
+#define GRPC_INTERNAL_CORE_HTTPCLI_FORMAT_REQUEST_H
 
 #include "src/core/httpcli/httpcli.h"
 #include <grpc/support/slice.h>
@@ -42,4 +42,4 @@
                                            const char *body_bytes,
                                            size_t body_size);
 
-#endif /* __GRPC_INTERNAL_HTTPCLI_FORMAT_REQUEST_H__ */
+#endif  /* GRPC_INTERNAL_CORE_HTTPCLI_FORMAT_REQUEST_H */
diff --git a/src/core/httpcli/httpcli.h b/src/core/httpcli/httpcli.h
index f620987..255c5ed 100644
--- a/src/core/httpcli/httpcli.h
+++ b/src/core/httpcli/httpcli.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_INTERNAL_HTTPCLI_HTTPCLI_H__
-#define __GRPC_INTERNAL_HTTPCLI_HTTPCLI_H__
+#ifndef GRPC_INTERNAL_CORE_HTTPCLI_HTTPCLI_H
+#define GRPC_INTERNAL_CORE_HTTPCLI_HTTPCLI_H
 
 #include <stddef.h>
 
@@ -115,4 +115,4 @@
 void grpc_httpcli_set_override(grpc_httpcli_get_override get,
                                grpc_httpcli_post_override post);
 
-#endif /* __GRPC_INTERNAL_HTTPCLI_HTTPCLI_H__ */
+#endif  /* GRPC_INTERNAL_CORE_HTTPCLI_HTTPCLI_H */
diff --git a/src/core/httpcli/httpcli_security_context.h b/src/core/httpcli/httpcli_security_context.h
index 5a1311e..a776828 100644
--- a/src/core/httpcli/httpcli_security_context.h
+++ b/src/core/httpcli/httpcli_security_context.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_INTERNAL_HTTPCLI_HTTPCLI_SECURITY_CONTEXT_H__
-#define __GRPC_INTERNAL_HTTPCLI_HTTPCLI_SECURITY_CONTEXT_H__
+#ifndef GRPC_INTERNAL_CORE_HTTPCLI_HTTPCLI_SECURITY_CONTEXT_H
+#define GRPC_INTERNAL_CORE_HTTPCLI_HTTPCLI_SECURITY_CONTEXT_H
 
 #include "src/core/security/security_context.h"
 
@@ -40,4 +40,4 @@
     const unsigned char *pem_root_certs, size_t pem_root_certs_size,
     const char *secure_peer_name, grpc_channel_security_context **ctx);
 
-#endif /* __GRPC_INTERNAL_HTTPCLI_HTTPCLI_SECURITY_CONTEXT_H__ */
+#endif  /* GRPC_INTERNAL_CORE_HTTPCLI_HTTPCLI_SECURITY_CONTEXT_H */
diff --git a/src/core/httpcli/parser.h b/src/core/httpcli/parser.h
index db1fa0a..71280e7 100644
--- a/src/core/httpcli/parser.h
+++ b/src/core/httpcli/parser.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_INTERNAL_HTTPCLI_PARSER_H__
-#define __GRPC_INTERNAL_HTTPCLI_PARSER_H__
+#ifndef GRPC_INTERNAL_CORE_HTTPCLI_PARSER_H
+#define GRPC_INTERNAL_CORE_HTTPCLI_PARSER_H
 
 #include "src/core/httpcli/httpcli.h"
 #include <grpc/support/port_platform.h>
@@ -61,4 +61,4 @@
 int grpc_httpcli_parser_parse(grpc_httpcli_parser *parser, gpr_slice slice);
 int grpc_httpcli_parser_eof(grpc_httpcli_parser *parser);
 
-#endif /* __GRPC_INTERNAL_HTTPCLI_PARSER_H__ */
+#endif  /* GRPC_INTERNAL_CORE_HTTPCLI_PARSER_H */
diff --git a/src/core/iomgr/alarm.h b/src/core/iomgr/alarm.h
index 6dcc63a..e5262e2 100644
--- a/src/core/iomgr/alarm.h
+++ b/src/core/iomgr/alarm.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_INTERNAL_IOMGR_ALARM_H__
-#define __GRPC_INTERNAL_IOMGR_ALARM_H__
+#ifndef GRPC_INTERNAL_CORE_IOMGR_ALARM_H
+#define GRPC_INTERNAL_CORE_IOMGR_ALARM_H
 
 #include "src/core/iomgr/iomgr.h"
 #include <grpc/support/port_platform.h>
@@ -86,4 +86,4 @@
    Requires:  cancel() must happen after add() on a given alarm */
 void grpc_alarm_cancel(grpc_alarm *alarm);
 
-#endif /* __GRPC_INTERNAL_IOMGR_ALARM_H__ */
+#endif  /* GRPC_INTERNAL_CORE_IOMGR_ALARM_H */
diff --git a/src/core/iomgr/alarm_heap.h b/src/core/iomgr/alarm_heap.h
index bb6e5e3..c5adfc6 100644
--- a/src/core/iomgr/alarm_heap.h
+++ b/src/core/iomgr/alarm_heap.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_INTERNAL_IOMGR_ALARM_HEAP_H_
-#define __GRPC_INTERNAL_IOMGR_ALARM_HEAP_H_
+#ifndef GRPC_INTERNAL_CORE_IOMGR_ALARM_HEAP_H
+#define GRPC_INTERNAL_CORE_IOMGR_ALARM_HEAP_H
 
 #include "src/core/iomgr/alarm.h"
 
@@ -54,4 +54,4 @@
 
 int grpc_alarm_heap_is_empty(grpc_alarm_heap *heap);
 
-#endif /* __GRPC_INTERNAL_IOMGR_ALARM_HEAP_H_ */
+#endif  /* GRPC_INTERNAL_CORE_IOMGR_ALARM_HEAP_H */
diff --git a/src/core/iomgr/alarm_internal.h b/src/core/iomgr/alarm_internal.h
index cbd8fa9..0268a01 100644
--- a/src/core/iomgr/alarm_internal.h
+++ b/src/core/iomgr/alarm_internal.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_INTERNAL_IOMGR_ALARM_INTERNAL_H_
-#define __GRPC_INTERNAL_IOMGR_ALARM_INTERNAL_H_
+#ifndef GRPC_INTERNAL_CORE_IOMGR_ALARM_INTERNAL_H
+#define GRPC_INTERNAL_CORE_IOMGR_ALARM_INTERNAL_H
 
 #include <grpc/support/sync.h>
 #include <grpc/support/time.h>
@@ -59,4 +59,4 @@
 
 void grpc_kick_poller(void);
 
-#endif /* __GRPC_INTERNAL_IOMGR_ALARM_INTERNAL_H_ */
+#endif  /* GRPC_INTERNAL_CORE_IOMGR_ALARM_INTERNAL_H */
diff --git a/src/core/iomgr/endpoint.h b/src/core/iomgr/endpoint.h
index e89cf66..881e851 100644
--- a/src/core/iomgr/endpoint.h
+++ b/src/core/iomgr/endpoint.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_INTERNAL_IOMGR_ENDPOINT_H__
-#define __GRPC_INTERNAL_IOMGR_ENDPOINT_H__
+#ifndef GRPC_INTERNAL_CORE_IOMGR_ENDPOINT_H
+#define GRPC_INTERNAL_CORE_IOMGR_ENDPOINT_H
 
 #include "src/core/iomgr/pollset.h"
 #include <grpc/support/slice.h>
@@ -103,4 +103,4 @@
   const grpc_endpoint_vtable *vtable;
 };
 
-#endif /* __GRPC_INTERNAL_IOMGR_ENDPOINT_H__ */
+#endif  /* GRPC_INTERNAL_CORE_IOMGR_ENDPOINT_H */
diff --git a/src/core/iomgr/endpoint_pair.h b/src/core/iomgr/endpoint_pair.h
index 2e46aab..dffbd36 100644
--- a/src/core/iomgr/endpoint_pair.h
+++ b/src/core/iomgr/endpoint_pair.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_INTERNAL_IOMGR_ENDPOINT_PAIR_H_
-#define __GRPC_INTERNAL_IOMGR_ENDPOINT_PAIR_H_
+#ifndef GRPC_INTERNAL_CORE_IOMGR_ENDPOINT_PAIR_H
+#define GRPC_INTERNAL_CORE_IOMGR_ENDPOINT_PAIR_H
 
 #include "src/core/iomgr/endpoint.h"
 
@@ -43,4 +43,4 @@
 
 grpc_endpoint_pair grpc_iomgr_create_endpoint_pair(size_t read_slice_size);
 
-#endif /* __GRPC_INTERNAL_IOMGR_ENDPOINT_PAIR_H_ */
+#endif  /* GRPC_INTERNAL_CORE_IOMGR_ENDPOINT_PAIR_H */
diff --git a/src/core/iomgr/fd_posix.c b/src/core/iomgr/fd_posix.c
index 41fd24e..abdd49b 100644
--- a/src/core/iomgr/fd_posix.c
+++ b/src/core/iomgr/fd_posix.c
@@ -38,6 +38,7 @@
 #include "src/core/iomgr/fd_posix.h"
 
 #include <assert.h>
+#include <sys/socket.h>
 #include <unistd.h>
 
 #include "src/core/iomgr/iomgr_internal.h"
@@ -113,6 +114,7 @@
 static void unref_by(grpc_fd *fd, int n) {
   gpr_atm old = gpr_atm_full_fetch_add(&fd->refst, -n);
   if (old == n) {
+    close(fd->fd);
     grpc_iomgr_add_callback(fd->on_done, fd->on_done_user_data);
     freelist_fd(fd);
     grpc_iomgr_unref();
@@ -158,9 +160,9 @@
 void grpc_fd_orphan(grpc_fd *fd, grpc_iomgr_cb_func on_done, void *user_data) {
   fd->on_done = on_done ? on_done : do_nothing;
   fd->on_done_user_data = user_data;
+  shutdown(fd->fd, SHUT_RDWR);
   ref_by(fd, 1); /* remove active status, but keep referenced */
   wake_watchers(fd);
-  close(fd->fd);
   unref_by(fd, 2); /* drop the reference */
 }
 
diff --git a/src/core/iomgr/fd_posix.h b/src/core/iomgr/fd_posix.h
index 2a308c8..be21f2b 100644
--- a/src/core/iomgr/fd_posix.h
+++ b/src/core/iomgr/fd_posix.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_INTERNAL_IOMGR_FD_POSIX_H_
-#define __GRPC_INTERNAL_IOMGR_FD_POSIX_H_
+#ifndef GRPC_INTERNAL_CORE_IOMGR_FD_POSIX_H
+#define GRPC_INTERNAL_CORE_IOMGR_FD_POSIX_H
 
 #include "src/core/iomgr/iomgr.h"
 #include "src/core/iomgr/pollset.h"
@@ -143,4 +143,4 @@
 void grpc_fd_global_init(void);
 void grpc_fd_global_shutdown(void);
 
-#endif /* __GRPC_INTERNAL_IOMGR_FD_POSIX_H_ */
+#endif  /* GRPC_INTERNAL_CORE_IOMGR_FD_POSIX_H */
diff --git a/src/core/iomgr/iocp_windows.h b/src/core/iomgr/iocp_windows.h
index d023170..3313319 100644
--- a/src/core/iomgr/iocp_windows.h
+++ b/src/core/iomgr/iocp_windows.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_INTERNAL_IOMGR_IOCP_WINDOWS_H_
-#define __GRPC_INTERNAL_IOMGR_IOCP_WINDOWS_H_
+#ifndef GRPC_INTERNAL_CORE_IOMGR_IOCP_WINDOWS_H
+#define GRPC_INTERNAL_CORE_IOMGR_IOCP_WINDOWS_H
 
 #include <windows.h>
 #include <grpc/support/sync.h>
@@ -49,4 +49,4 @@
 void grpc_socket_notify_on_read(grpc_winsocket *, void(*cb)(void *, int success),
                                 void *opaque);
 
-#endif /* __GRPC_INTERNAL_IOMGR_IOCP_WINDOWS_H_ */
+#endif  /* GRPC_INTERNAL_CORE_IOMGR_IOCP_WINDOWS_H */
diff --git a/src/core/iomgr/iomgr.h b/src/core/iomgr/iomgr.h
index 18a7d15..1f5d23f 100644
--- a/src/core/iomgr/iomgr.h
+++ b/src/core/iomgr/iomgr.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_INTERNAL_IOMGR_IOMGR_H__
-#define __GRPC_INTERNAL_IOMGR_IOMGR_H__
+#ifndef GRPC_INTERNAL_CORE_IOMGR_IOMGR_H
+#define GRPC_INTERNAL_CORE_IOMGR_IOMGR_H
 
 /* gRPC Callback definition */
 typedef void (*grpc_iomgr_cb_func)(void *arg, int success);
@@ -44,4 +44,4 @@
    and causes the invocation of a callback at some point in the future */
 void grpc_iomgr_add_callback(grpc_iomgr_cb_func cb, void *cb_arg);
 
-#endif /* __GRPC_INTERNAL_IOMGR_IOMGR_H__ */
+#endif  /* GRPC_INTERNAL_CORE_IOMGR_IOMGR_H */
diff --git a/src/core/iomgr/iomgr_internal.h b/src/core/iomgr/iomgr_internal.h
index 7f29f44..0792325 100644
--- a/src/core/iomgr/iomgr_internal.h
+++ b/src/core/iomgr/iomgr_internal.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_INTERNAL_IOMGR_IOMGR_INTERNAL_H_
-#define __GRPC_INTERNAL_IOMGR_IOMGR_INTERNAL_H_
+#ifndef GRPC_INTERNAL_CORE_IOMGR_IOMGR_INTERNAL_H
+#define GRPC_INTERNAL_CORE_IOMGR_IOMGR_INTERNAL_H
 
 #include "src/core/iomgr/iomgr.h"
 #include "src/core/iomgr/iomgr_internal.h"
@@ -48,4 +48,4 @@
 void grpc_iomgr_platform_init(void);
 void grpc_iomgr_platform_shutdown(void);
 
-#endif /* __GRPC_INTERNAL_IOMGR_IOMGR_INTERNAL_H_ */
+#endif  /* GRPC_INTERNAL_CORE_IOMGR_IOMGR_INTERNAL_H */
diff --git a/src/core/iomgr/iomgr_posix.h b/src/core/iomgr/iomgr_posix.h
index f9e9b3d..a404f64 100644
--- a/src/core/iomgr/iomgr_posix.h
+++ b/src/core/iomgr/iomgr_posix.h
@@ -31,12 +31,12 @@
  *
  */
 
-#ifndef __GRPC_INTERNAL_IOMGR_IOMGR_POSIX_H_
-#define __GRPC_INTERNAL_IOMGR_IOMGR_POSIX_H_
+#ifndef GRPC_INTERNAL_CORE_IOMGR_IOMGR_POSIX_H
+#define GRPC_INTERNAL_CORE_IOMGR_IOMGR_POSIX_H
 
 #include "src/core/iomgr/iomgr_internal.h"
 
 void grpc_pollset_global_init(void);
 void grpc_pollset_global_shutdown(void);
 
-#endif /* __GRPC_INTERNAL_IOMGR_IOMGR_POSIX_H_ */
+#endif  /* GRPC_INTERNAL_CORE_IOMGR_IOMGR_POSIX_H */
diff --git a/src/core/iomgr/pollset.h b/src/core/iomgr/pollset.h
index 9d04b01..067af87 100644
--- a/src/core/iomgr/pollset.h
+++ b/src/core/iomgr/pollset.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_INTERNAL_IOMGR_POLLSET_H_
-#define __GRPC_INTERNAL_IOMGR_POLLSET_H_
+#ifndef GRPC_INTERNAL_CORE_IOMGR_POLLSET_H
+#define GRPC_INTERNAL_CORE_IOMGR_POLLSET_H
 
 #include <grpc/support/port_platform.h>
 #include <grpc/support/time.h>
@@ -52,9 +52,14 @@
 #include "src/core/iomgr/pollset_windows.h"
 #endif
 
+
 void grpc_pollset_init(grpc_pollset *pollset);
+void grpc_pollset_shutdown(grpc_pollset *pollset,
+                           void (*shutdown_done)(void *arg),
+                           void *shutdown_done_arg);
 void grpc_pollset_destroy(grpc_pollset *pollset);
 
+
 /* Do some work on a pollset.
    May involve invoking asynchronous callbacks, or actually polling file
    descriptors.
@@ -66,4 +71,4 @@
    Requires GRPC_POLLSET_MU(pollset) locked. */
 void grpc_pollset_kick(grpc_pollset *pollset);
 
-#endif /* __GRPC_INTERNAL_IOMGR_POLLSET_H_ */
+#endif  /* GRPC_INTERNAL_CORE_IOMGR_POLLSET_H */
diff --git a/src/core/iomgr/pollset_kick.h b/src/core/iomgr/pollset_kick.h
index b224177..cc9357d 100644
--- a/src/core/iomgr/pollset_kick.h
+++ b/src/core/iomgr/pollset_kick.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_INTERNAL_IOMGR_POLLSET_KICK_H_
-#define __GRPC_INTERNAL_IOMGR_POLLSET_KICK_H_
+#ifndef GRPC_INTERNAL_CORE_IOMGR_POLLSET_KICK_H
+#define GRPC_INTERNAL_CORE_IOMGR_POLLSET_KICK_H
 
 #include <grpc/support/port_platform.h>
 
@@ -71,4 +71,4 @@
 
 void grpc_pollset_kick_kick(grpc_pollset_kick_state *kick_state);
 
-#endif /* __GRPC_INTERNAL_IOMGR_POLLSET_KICK_H_ */
+#endif  /* GRPC_INTERNAL_CORE_IOMGR_POLLSET_KICK_H */
diff --git a/src/core/iomgr/pollset_kick_posix.h b/src/core/iomgr/pollset_kick_posix.h
index 162ae5b..4276991 100644
--- a/src/core/iomgr/pollset_kick_posix.h
+++ b/src/core/iomgr/pollset_kick_posix.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_INTERNAL_IOMGR_POLLSET_KICK_POSIX_H_
-#define __GRPC_INTERNAL_IOMGR_POLLSET_KICK_POSIX_H_
+#ifndef GRPC_INTERNAL_CORE_IOMGR_POLLSET_KICK_POSIX_H
+#define GRPC_INTERNAL_CORE_IOMGR_POLLSET_KICK_POSIX_H
 
 #include "src/core/iomgr/wakeup_fd_posix.h"
 #include <grpc/support/sync.h>
@@ -48,4 +48,4 @@
   struct grpc_kick_fd_info *fd_info;
 } grpc_pollset_kick_state;
 
-#endif  /* __GRPC_INTERNALIOMGR_POLLSET_KICK_POSIX_H_ */
+#endif  /* GRPC_INTERNAL_CORE_IOMGR_POLLSET_KICK_POSIX_H */
diff --git a/src/core/iomgr/pollset_kick_windows.h b/src/core/iomgr/pollset_kick_windows.h
index 1053230..3836aa0 100644
--- a/src/core/iomgr/pollset_kick_windows.h
+++ b/src/core/iomgr/pollset_kick_windows.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_INTERNAL_IOMGR_POLLSET_KICK_WINDOWS_H_
-#define __GRPC_INTERNAL_IOMGR_POLLSET_KICK_WINDOWS_H_
+#ifndef GRPC_INTERNAL_CORE_IOMGR_POLLSET_KICK_WINDOWS_H
+#define GRPC_INTERNAL_CORE_IOMGR_POLLSET_KICK_WINDOWS_H
 
 #include <grpc/support/sync.h>
 
@@ -42,4 +42,4 @@
   int unused;
 } grpc_pollset_kick_state;
 
-#endif  /* __GRPC_INTERNALIOMGR_POLLSET_KICK_WINDOWS_H_ */
+#endif  /* GRPC_INTERNAL_CORE_IOMGR_POLLSET_KICK_WINDOWS_H */
diff --git a/src/core/iomgr/pollset_posix.c b/src/core/iomgr/pollset_posix.c
index 87e7aa8..f0a8453 100644
--- a/src/core/iomgr/pollset_posix.c
+++ b/src/core/iomgr/pollset_posix.c
@@ -55,6 +55,7 @@
 static grpc_pollset g_backup_pollset;
 static int g_shutdown_backup_poller;
 static gpr_event g_backup_poller_done;
+static gpr_event g_backup_pollset_shutdown_done;
 
 static void backup_poller(void *p) {
   gpr_timespec delta = gpr_time_from_millis(100);
@@ -104,9 +105,14 @@
   /* start the backup poller thread */
   g_shutdown_backup_poller = 0;
   gpr_event_init(&g_backup_poller_done);
+  gpr_event_init(&g_backup_pollset_shutdown_done);
   gpr_thd_new(&id, backup_poller, NULL, NULL);
 }
 
+static void on_backup_pollset_shutdown_done(void *arg) {
+  gpr_event_set(&g_backup_pollset_shutdown_done, (void *)1);
+}
+
 void grpc_pollset_global_shutdown(void) {
   /* terminate the backup poller thread */
   gpr_mu_lock(&g_backup_pollset.mu);
@@ -114,6 +120,10 @@
   gpr_mu_unlock(&g_backup_pollset.mu);
   gpr_event_wait(&g_backup_poller_done, gpr_inf_future);
 
+  grpc_pollset_shutdown(&g_backup_pollset, on_backup_pollset_shutdown_done,
+                        NULL);
+  gpr_event_wait(&g_backup_pollset_shutdown_done, gpr_inf_future);
+
   /* destroy the backup pollset */
   grpc_pollset_destroy(&g_backup_pollset);
 
@@ -130,6 +140,8 @@
   gpr_mu_init(&pollset->mu);
   gpr_cv_init(&pollset->cv);
   grpc_pollset_kick_init(&pollset->kick_state);
+  pollset->in_flight_cbs = 0;
+  pollset->shutting_down = 0;
   become_empty_pollset(pollset);
 }
 
@@ -163,7 +175,24 @@
   return pollset->vtable->maybe_work(pollset, deadline, now, 1);
 }
 
+void grpc_pollset_shutdown(grpc_pollset *pollset,
+                           void (*shutdown_done)(void *arg),
+                           void *shutdown_done_arg) {
+  int in_flight_cbs;
+  gpr_mu_lock(&pollset->mu);
+  pollset->shutting_down = 1;
+  in_flight_cbs = pollset->in_flight_cbs;
+  pollset->shutdown_done_cb = shutdown_done;
+  pollset->shutdown_done_arg = shutdown_done_arg;
+  gpr_mu_unlock(&pollset->mu);
+  if (in_flight_cbs == 0) {
+    shutdown_done(shutdown_done_arg);
+  }
+}
+
 void grpc_pollset_destroy(grpc_pollset *pollset) {
+  GPR_ASSERT(pollset->shutting_down);
+  GPR_ASSERT(pollset->in_flight_cbs == 0);
   pollset->vtable->destroy(pollset);
   grpc_pollset_kick_destroy(&pollset->kick_state);
   gpr_mu_destroy(&pollset->mu);
@@ -201,21 +230,119 @@
  *                      via poll()
  */
 
-static void unary_poll_pollset_add_fd(grpc_pollset *pollset, grpc_fd *fd) {
-  grpc_fd *fds[2];
-  if (fd == pollset->data.ptr) return;
-  fds[0] = pollset->data.ptr;
-  fds[1] = fd;
-  if (!grpc_fd_is_orphaned(fds[0])) {
-    grpc_platform_become_multipoller(pollset, fds, GPR_ARRAY_SIZE(fds));
-    grpc_fd_unref(fds[0]);
-  } else {
-    /* old fd is orphaned and we haven't cleaned it up until now, so remain a
-     * unary poller */
-    grpc_fd_unref(fds[0]);
-    pollset->data.ptr = fd;
-    grpc_fd_ref(fd);
+
+typedef struct grpc_unary_promote_args {
+  const grpc_pollset_vtable *original_vtable;
+  grpc_pollset *pollset;
+  grpc_fd *fd;
+} grpc_unary_promote_args;
+
+static void unary_poll_do_promote(void *args, int success) {
+  grpc_unary_promote_args *up_args = args;
+  const grpc_pollset_vtable *original_vtable = up_args->original_vtable;
+  grpc_pollset *pollset = up_args->pollset;
+  grpc_fd *fd = up_args->fd;
+  int do_shutdown_cb = 0;
+  gpr_free(up_args);
+
+  /*
+   * This is quite tricky. There are a number of cases to keep in mind here:
+   * 1. fd may have been orphaned
+   * 2. The pollset may no longer be a unary poller (and we can't let case #1
+   * leak to other pollset types!)
+   * 3. pollset's fd (which may have changed) may have been orphaned
+   * 4. The pollset may be shutting down.
+   */
+
+  gpr_mu_lock(&pollset->mu);
+  /* First we need to ensure that nobody is polling concurrently */
+  while (pollset->counter != 0) {
+    grpc_pollset_kick(pollset);
+    gpr_cv_wait(&pollset->cv, &pollset->mu, gpr_inf_future);
   }
+  /* At this point the pollset may no longer be a unary poller. In that case
+   * we should just call the right add function and be done. */
+  /* TODO(klempner): If we're not careful this could cause infinite recursion.
+   * That's not a problem for now because empty_pollset has a trivial poller
+   * and we don't have any mechanism to unbecome multipoller. */
+  pollset->in_flight_cbs--;
+  if (pollset->shutting_down) {
+    gpr_log(GPR_INFO, "Shutting down");
+    /* We don't care about this pollset anymore. */
+    if (pollset->in_flight_cbs == 0) {
+      do_shutdown_cb = 1;
+    }
+  } else if (grpc_fd_is_orphaned(fd)) {
+    /* Don't try to add it to anything, we'll drop our ref on it below */
+  } else if (pollset->vtable != original_vtable) {
+    gpr_log(GPR_INFO, "Not original vtable");
+    pollset->vtable->add_fd(pollset, fd);
+  } else if (fd != pollset->data.ptr) {
+    grpc_fd *fds[2];
+    fds[0] = pollset->data.ptr;
+    fds[1] = fd;
+
+    if (!grpc_fd_is_orphaned(fds[0])) {
+      grpc_platform_become_multipoller(pollset, fds, GPR_ARRAY_SIZE(fds));
+      grpc_fd_unref(fds[0]);
+    } else {
+      /* old fd is orphaned and we haven't cleaned it up until now, so remain a
+       * unary poller */
+      /* Note that it is possible that fds[1] is also orphaned at this point.
+       * That's okay, we'll correct it at the next add or poll. */
+      grpc_fd_unref(fds[0]);
+      pollset->data.ptr = fd;
+      grpc_fd_ref(fd);
+    }
+  }
+
+  gpr_cv_broadcast(&pollset->cv);
+  gpr_mu_unlock(&pollset->mu);
+
+  if (do_shutdown_cb) {
+    pollset->shutdown_done_cb(pollset->shutdown_done_arg);
+  }
+
+  /* Matching ref in unary_poll_pollset_add_fd */
+  grpc_fd_unref(fd);
+}
+
+static void unary_poll_pollset_add_fd(grpc_pollset *pollset, grpc_fd *fd) {
+  grpc_unary_promote_args *up_args;
+  if (fd == pollset->data.ptr) return;
+
+  if (!pollset->counter) {
+    /* Fast path -- no in flight cbs */
+    /* TODO(klempner): Comment this out and fix any test failures or establish
+     * they are due to timing issues */
+    grpc_fd *fds[2];
+    fds[0] = pollset->data.ptr;
+    fds[1] = fd;
+
+    if (!grpc_fd_is_orphaned(fds[0])) {
+      grpc_platform_become_multipoller(pollset, fds, GPR_ARRAY_SIZE(fds));
+      grpc_fd_unref(fds[0]);
+    } else {
+      /* old fd is orphaned and we haven't cleaned it up until now, so remain a
+       * unary poller */
+      grpc_fd_unref(fds[0]);
+      pollset->data.ptr = fd;
+      grpc_fd_ref(fd);
+    }
+    return;
+  }
+
+  /* Now we need to promote. This needs to happen when we're not polling. Since
+   * this may be called from poll, the wait needs to happen asynchronously. */
+  grpc_fd_ref(fd);
+  pollset->in_flight_cbs++;
+  up_args = gpr_malloc(sizeof(*up_args));
+  up_args->pollset = pollset;
+  up_args->fd = fd;
+  up_args->original_vtable = pollset->vtable;
+  grpc_iomgr_add_callback(unary_poll_do_promote, up_args);
+
+  grpc_pollset_kick(pollset);
 }
 
 static void unary_poll_pollset_del_fd(grpc_pollset *pollset, grpc_fd *fd) {
@@ -238,6 +365,10 @@
   if (pollset->counter) {
     return 0;
   }
+  if (pollset->in_flight_cbs) {
+    /* Give do_promote priority so we don't starve it out */
+    return 0;
+  }
   fd = pollset->data.ptr;
   if (grpc_fd_is_orphaned(fd)) {
     grpc_fd_unref(fd);
diff --git a/src/core/iomgr/pollset_posix.h b/src/core/iomgr/pollset_posix.h
index 03b4c77..da843f7 100644
--- a/src/core/iomgr/pollset_posix.h
+++ b/src/core/iomgr/pollset_posix.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_INTERNAL_IOMGR_POLLSET_POSIX_H_
-#define __GRPC_INTERNAL_IOMGR_POLLSET_POSIX_H_
+#ifndef GRPC_INTERNAL_CORE_IOMGR_POLLSET_POSIX_H
+#define GRPC_INTERNAL_CORE_IOMGR_POLLSET_POSIX_H
 
 #include <grpc/support/sync.h>
 
@@ -55,6 +55,10 @@
   gpr_cv cv;
   grpc_pollset_kick_state kick_state;
   int counter;
+  int in_flight_cbs;
+  int shutting_down;
+  void (*shutdown_done_cb)(void *arg);
+  void *shutdown_done_arg;
   union {
     int fd;
     void *ptr;
@@ -100,4 +104,4 @@
 void grpc_platform_become_multipoller(grpc_pollset *pollset,
                                       struct grpc_fd **fds, size_t fd_count);
 
-#endif /* __GRPC_INTERNAL_IOMGR_POLLSET_POSIX_H_ */
+#endif  /* GRPC_INTERNAL_CORE_IOMGR_POLLSET_POSIX_H */
diff --git a/src/core/iomgr/pollset_windows.c b/src/core/iomgr/pollset_windows.c
index d21072b..bea6711 100644
--- a/src/core/iomgr/pollset_windows.c
+++ b/src/core/iomgr/pollset_windows.c
@@ -46,6 +46,12 @@
   gpr_cv_init(&pollset->cv);
 }
 
+void grpc_pollset_shutdown(grpc_pollset *pollset,
+                           void (*shutdown_done)(void *arg),
+                           void *shutdown_done_arg) {
+  shutdown_done(shutdown_done_arg);
+}
+
 void grpc_pollset_destroy(grpc_pollset *pollset) {
   gpr_mu_destroy(&pollset->mu);
   gpr_cv_destroy(&pollset->cv);
diff --git a/src/core/iomgr/pollset_windows.h b/src/core/iomgr/pollset_windows.h
index 41c193f..266175a 100644
--- a/src/core/iomgr/pollset_windows.h
+++ b/src/core/iomgr/pollset_windows.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_INTERNAL_IOMGR_POLLSET_WINDOWS_H_
-#define __GRPC_INTERNAL_IOMGR_POLLSET_WINDOWS_H_
+#ifndef GRPC_INTERNAL_CORE_IOMGR_POLLSET_WINDOWS_H
+#define GRPC_INTERNAL_CORE_IOMGR_POLLSET_WINDOWS_H
 
 #include <windows.h>
 #include <grpc/support/sync.h>
@@ -53,4 +53,4 @@
 #define GRPC_POLLSET_MU(pollset) (&(pollset)->mu)
 #define GRPC_POLLSET_CV(pollset) (&(pollset)->cv)
 
-#endif /* __GRPC_INTERNAL_IOMGR_POLLSET_WINDOWS_H_ */
+#endif  /* GRPC_INTERNAL_CORE_IOMGR_POLLSET_WINDOWS_H */
diff --git a/src/core/iomgr/resolve_address.h b/src/core/iomgr/resolve_address.h
index 65432ec..8f1d7a2 100644
--- a/src/core/iomgr/resolve_address.h
+++ b/src/core/iomgr/resolve_address.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_INTERNAL_IOMGR_RESOLVE_ADDRESS_H__
-#define __GRPC_INTERNAL_IOMGR_RESOLVE_ADDRESS_H__
+#ifndef GRPC_INTERNAL_CORE_IOMGR_RESOLVE_ADDRESS_H
+#define GRPC_INTERNAL_CORE_IOMGR_RESOLVE_ADDRESS_H
 
 #include <stddef.h>
 
@@ -66,4 +66,4 @@
 grpc_resolved_addresses *grpc_blocking_resolve_address(
     const char *addr, const char *default_port);
 
-#endif /* __GRPC_INTERNAL_IOMGR_RESOLVE_ADDRESS_H__ */
+#endif  /* GRPC_INTERNAL_CORE_IOMGR_RESOLVE_ADDRESS_H */
diff --git a/src/core/iomgr/resolve_address_posix.c b/src/core/iomgr/resolve_address_posix.c
index edf40b5..989b968 100644
--- a/src/core/iomgr/resolve_address_posix.c
+++ b/src/core/iomgr/resolve_address_posix.c
@@ -66,7 +66,6 @@
   int s;
   size_t i;
   grpc_resolved_addresses *addrs = NULL;
-  const gpr_timespec start_time = gpr_now();
   struct sockaddr_un *un;
 
   if (name[0] == 'u' && name[1] == 'n' && name[2] == 'i' && name[3] == 'x' &&
@@ -121,22 +120,6 @@
     i++;
   }
 
-  /* Temporary logging, to help identify flakiness in dualstack_socket_test. */
-  {
-    const gpr_timespec delay = gpr_time_sub(gpr_now(), start_time);
-    const int delay_ms =
-        delay.tv_sec * GPR_MS_PER_SEC + delay.tv_nsec / GPR_NS_PER_MS;
-    gpr_log(GPR_INFO, "logspam: getaddrinfo(%s, %s) resolved %d addrs in %dms:",
-            host, port, addrs->naddrs, delay_ms);
-    for (i = 0; i < addrs->naddrs; i++) {
-      char *buf;
-      grpc_sockaddr_to_string(&buf, (struct sockaddr *)&addrs->addrs[i].addr,
-                              0);
-      gpr_log(GPR_INFO, "logspam:   [%d] %s", i, buf);
-      gpr_free(buf);
-    }
-  }
-
 done:
   gpr_free(host);
   gpr_free(port);
diff --git a/src/core/iomgr/sockaddr.h b/src/core/iomgr/sockaddr.h
index a5f7c54..7528db7 100644
--- a/src/core/iomgr/sockaddr.h
+++ b/src/core/iomgr/sockaddr.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_INTERNAL_IOMGR_SOCKADDR_H_
-#define __GRPC_INTERNAL_IOMGR_SOCKADDR_H_
+#ifndef GRPC_INTERNAL_CORE_IOMGR_SOCKADDR_H
+#define GRPC_INTERNAL_CORE_IOMGR_SOCKADDR_H
 
 #include <grpc/support/port_platform.h>
 
@@ -44,4 +44,4 @@
 #include "src/core/iomgr/sockaddr_posix.h"
 #endif
 
-#endif /* __GRPC_INTERNAL_IOMGR_SOCKADDR_H_ */
+#endif  /* GRPC_INTERNAL_CORE_IOMGR_SOCKADDR_H */
diff --git a/src/core/iomgr/sockaddr_posix.h b/src/core/iomgr/sockaddr_posix.h
index 00115e2..2a3d932 100644
--- a/src/core/iomgr/sockaddr_posix.h
+++ b/src/core/iomgr/sockaddr_posix.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_INTERNAL_IOMGR_SOCKADDR_POSIX_H_
-#define __GRPC_INTERNAL_IOMGR_SOCKADDR_POSIX_H_
+#ifndef GRPC_INTERNAL_CORE_IOMGR_SOCKADDR_POSIX_H
+#define GRPC_INTERNAL_CORE_IOMGR_SOCKADDR_POSIX_H
 
 #include <arpa/inet.h>
 #include <sys/socket.h>
@@ -41,4 +41,4 @@
 #include <netdb.h>
 #include <unistd.h>
 
-#endif /* __GRPC_INTERNAL_IOMGR_SOCKADDR_POSIX_H_ */
+#endif  /* GRPC_INTERNAL_CORE_IOMGR_SOCKADDR_POSIX_H */
diff --git a/src/core/iomgr/sockaddr_utils.h b/src/core/iomgr/sockaddr_utils.h
index d3a25ad..bdfb834 100644
--- a/src/core/iomgr/sockaddr_utils.h
+++ b/src/core/iomgr/sockaddr_utils.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_INTERNAL_IOMGR_SOCKADDR_UTILS_H__
-#define __GRPC_INTERNAL_IOMGR_SOCKADDR_UTILS_H__
+#ifndef GRPC_INTERNAL_CORE_IOMGR_SOCKADDR_UTILS_H
+#define GRPC_INTERNAL_CORE_IOMGR_SOCKADDR_UTILS_H
 
 #include "src/core/iomgr/sockaddr.h"
 
@@ -84,4 +84,4 @@
 int grpc_sockaddr_to_string(char **out, const struct sockaddr *addr,
                             int normalize);
 
-#endif /* __GRPC_INTERNAL_IOMGR_SOCKADDR_UTILS_H__ */
+#endif  /* GRPC_INTERNAL_CORE_IOMGR_SOCKADDR_UTILS_H */
diff --git a/src/core/iomgr/sockaddr_win32.h b/src/core/iomgr/sockaddr_win32.h
index 6ed164c..3a5f27b 100644
--- a/src/core/iomgr/sockaddr_win32.h
+++ b/src/core/iomgr/sockaddr_win32.h
@@ -31,11 +31,11 @@
  *
  */
 
-#ifndef __GRPC_INTERNAL_IOMGR_SOCKADDR_WIN32_H_
-#define __GRPC_INTERNAL_IOMGR_SOCKADDR_WIN32_H_
+#ifndef GRPC_INTERNAL_CORE_IOMGR_SOCKADDR_WIN32_H
+#define GRPC_INTERNAL_CORE_IOMGR_SOCKADDR_WIN32_H
 
 #include <ws2tcpip.h>
 #include <winsock2.h>
 #include <mswsock.h>
 
-#endif  /* __GRPC_INTERNAL_IOMGR_SOCKADDR_WIN32_H_ */
+#endif  /* GRPC_INTERNAL_CORE_IOMGR_SOCKADDR_WIN32_H */
diff --git a/src/core/iomgr/socket_utils_posix.h b/src/core/iomgr/socket_utils_posix.h
index b35fe78..c161082 100644
--- a/src/core/iomgr/socket_utils_posix.h
+++ b/src/core/iomgr/socket_utils_posix.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_INTERNAL_IOMGR_SOCKET_UTILS_POSIX_H__
-#define __GRPC_INTERNAL_IOMGR_SOCKET_UTILS_POSIX_H__
+#ifndef GRPC_INTERNAL_CORE_IOMGR_SOCKET_UTILS_POSIX_H
+#define GRPC_INTERNAL_CORE_IOMGR_SOCKET_UTILS_POSIX_H
 
 #include <unistd.h>
 #include <sys/socket.h>
@@ -105,4 +105,4 @@
 int grpc_create_dualstack_socket(const struct sockaddr *addr, int type,
                                  int protocol, grpc_dualstack_mode *dsmode);
 
-#endif /* __GRPC_INTERNAL_IOMGR_SOCKET_UTILS_POSIX_H__ */
+#endif  /* GRPC_INTERNAL_CORE_IOMGR_SOCKET_UTILS_POSIX_H */
diff --git a/src/core/iomgr/socket_windows.h b/src/core/iomgr/socket_windows.h
index de80e97..d4776ab 100644
--- a/src/core/iomgr/socket_windows.h
+++ b/src/core/iomgr/socket_windows.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_INTERNAL_IOMGR_HANDLE_WINDOWS_H__
-#define __GRPC_INTERNAL_IOMGR_HANDLE_WINDOWS_H__
+#ifndef GRPC_INTERNAL_CORE_IOMGR_SOCKET_WINDOWS_H
+#define GRPC_INTERNAL_CORE_IOMGR_SOCKET_WINDOWS_H
 
 #include <windows.h>
 
@@ -72,4 +72,4 @@
 void grpc_winsocket_shutdown(grpc_winsocket *socket);
 void grpc_winsocket_orphan(grpc_winsocket *socket);
 
-#endif /* __GRPC_INTERNAL_IOMGR_HANDLE_WINDOWS_H__ */
+#endif  /* GRPC_INTERNAL_CORE_IOMGR_SOCKET_WINDOWS_H */
diff --git a/src/core/iomgr/tcp_client.h b/src/core/iomgr/tcp_client.h
index c919c02..2e91497 100644
--- a/src/core/iomgr/tcp_client.h
+++ b/src/core/iomgr/tcp_client.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_INTERNAL_IOMGR_TCP_CLIENT_H__
-#define __GRPC_INTERNAL_IOMGR_TCP_CLIENT_H__
+#ifndef GRPC_INTERNAL_CORE_IOMGR_TCP_CLIENT_H
+#define GRPC_INTERNAL_CORE_IOMGR_TCP_CLIENT_H
 
 #include "src/core/iomgr/endpoint.h"
 #include "src/core/iomgr/sockaddr.h"
@@ -45,4 +45,4 @@
                              void *arg, const struct sockaddr *addr,
                              int addr_len, gpr_timespec deadline);
 
-#endif /* __GRPC_INTERNAL_IOMGR_TCP_CLIENT_H__ */
+#endif  /* GRPC_INTERNAL_CORE_IOMGR_TCP_CLIENT_H */
diff --git a/src/core/iomgr/tcp_posix.h b/src/core/iomgr/tcp_posix.h
index 6ff8770..7e8064b 100644
--- a/src/core/iomgr/tcp_posix.h
+++ b/src/core/iomgr/tcp_posix.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_INTERNAL_IOMGR_TCP_POSIX_H__
-#define __GRPC_INTERNAL_IOMGR_TCP_POSIX_H__
+#ifndef GRPC_INTERNAL_CORE_IOMGR_TCP_POSIX_H
+#define GRPC_INTERNAL_CORE_IOMGR_TCP_POSIX_H
 /*
    Low level TCP "bottom half" implementation, for use by transports built on
    top of a TCP connection.
@@ -53,4 +53,4 @@
    Takes ownership of fd. */
 grpc_endpoint *grpc_tcp_create(grpc_fd *fd, size_t read_slice_size);
 
-#endif /* __GRPC_INTERNAL_IOMGR_TCP_POSIX_H__ */
+#endif  /* GRPC_INTERNAL_CORE_IOMGR_TCP_POSIX_H */
diff --git a/src/core/iomgr/tcp_server.h b/src/core/iomgr/tcp_server.h
index c1e5f45..68ee85c 100644
--- a/src/core/iomgr/tcp_server.h
+++ b/src/core/iomgr/tcp_server.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_INTERNAL_IOMGR_TCP_SERVER_H__
-#define __GRPC_INTERNAL_IOMGR_TCP_SERVER_H__
+#ifndef GRPC_INTERNAL_CORE_IOMGR_TCP_SERVER_H
+#define GRPC_INTERNAL_CORE_IOMGR_TCP_SERVER_H
 
 #include "src/core/iomgr/endpoint.h"
 
@@ -73,4 +73,4 @@
 
 void grpc_tcp_server_destroy(grpc_tcp_server *server);
 
-#endif /* __GRPC_INTERNAL_IOMGR_TCP_SERVER_H__ */
+#endif  /* GRPC_INTERNAL_CORE_IOMGR_TCP_SERVER_H */
diff --git a/src/core/iomgr/tcp_windows.h b/src/core/iomgr/tcp_windows.h
index 565d42e..4cbc12c 100644
--- a/src/core/iomgr/tcp_windows.h
+++ b/src/core/iomgr/tcp_windows.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_INTERNAL_IOMGR_TCP_WINDOWS_H__
-#define __GRPC_INTERNAL_IOMGR_TCP_WINDOWS_H__
+#ifndef GRPC_INTERNAL_CORE_IOMGR_TCP_WINDOWS_H
+#define GRPC_INTERNAL_CORE_IOMGR_TCP_WINDOWS_H
 /*
    Low level TCP "bottom half" implementation, for use by transports built on
    top of a TCP connection.
@@ -54,4 +54,4 @@
 
 int grpc_tcp_prepare_socket(SOCKET sock);
 
-#endif /* __GRPC_INTERNAL_IOMGR_TCP_WINDOWS_H__ */
+#endif  /* GRPC_INTERNAL_CORE_IOMGR_TCP_WINDOWS_H */
diff --git a/src/core/iomgr/time_averaged_stats.h b/src/core/iomgr/time_averaged_stats.h
index e901f3c..13894b2 100644
--- a/src/core/iomgr/time_averaged_stats.h
+++ b/src/core/iomgr/time_averaged_stats.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_INTERNAL_IOMGR_TIME_AVERAGED_STATS_H_
-#define __GRPC_INTERNAL_IOMGR_TIME_AVERAGED_STATS_H_
+#ifndef GRPC_INTERNAL_CORE_IOMGR_TIME_AVERAGED_STATS_H
+#define GRPC_INTERNAL_CORE_IOMGR_TIME_AVERAGED_STATS_H
 
 /* This tracks a time-decaying weighted average.  It works by collecting
    batches of samples and then mixing their average into a time-decaying
@@ -85,4 +85,4 @@
    value. */
 double grpc_time_averaged_stats_update_average(grpc_time_averaged_stats *stats);
 
-#endif /* __GRPC_INTERNAL_IOMGR_TIME_AVERAGED_STATS_H_ */
+#endif  /* GRPC_INTERNAL_CORE_IOMGR_TIME_AVERAGED_STATS_H */
diff --git a/src/core/iomgr/wakeup_fd_pipe.h b/src/core/iomgr/wakeup_fd_pipe.h
index a2fcde5..aa8f977 100644
--- a/src/core/iomgr/wakeup_fd_pipe.h
+++ b/src/core/iomgr/wakeup_fd_pipe.h
@@ -31,11 +31,11 @@
  *
  */
 
-#ifndef __GRPC_INTERNAL_IOMGR_WAKEUP_FD_PIPE_H_
-#define __GRPC_INTERNAL_IOMGR_WAKEUP_FD_PIPE_H_
+#ifndef GRPC_INTERNAL_CORE_IOMGR_WAKEUP_FD_PIPE_H
+#define GRPC_INTERNAL_CORE_IOMGR_WAKEUP_FD_PIPE_H
 
 #include "src/core/iomgr/wakeup_fd_posix.h"
 
 extern grpc_wakeup_fd_vtable grpc_pipe_wakeup_fd_vtable;
 
-#endif  /* __GRPC_INTERNAL_IOMGR_WAKEUP_FD_PIPE_H_ */
+#endif  /* GRPC_INTERNAL_CORE_IOMGR_WAKEUP_FD_PIPE_H */
diff --git a/src/core/iomgr/wakeup_fd_posix.h b/src/core/iomgr/wakeup_fd_posix.h
index 75bb9fc..1b0ff70 100644
--- a/src/core/iomgr/wakeup_fd_posix.h
+++ b/src/core/iomgr/wakeup_fd_posix.h
@@ -59,8 +59,8 @@
  * 2. If the polling thread was awakened by a wakeup_fd event, call
  *    grpc_wakeup_fd_consume_wakeup() on it.
  */
-#ifndef __GRPC_INTERNAL_IOMGR_WAKEUP_FD_POSIX_H_
-#define __GRPC_INTERNAL_IOMGR_WAKEUP_FD_POSIX_H_
+#ifndef GRPC_INTERNAL_CORE_IOMGR_WAKEUP_FD_POSIX_H
+#define GRPC_INTERNAL_CORE_IOMGR_WAKEUP_FD_POSIX_H
 
 void grpc_wakeup_fd_global_init(void);
 void grpc_wakeup_fd_global_destroy(void);
@@ -96,4 +96,4 @@
  * wakeup_fd_nospecial.c if no such implementation exists. */
 extern const grpc_wakeup_fd_vtable grpc_specialized_wakeup_fd_vtable;
 
-#endif /* __GRPC_INTERNAL_IOMGR_WAKEUP_FD_POSIX_H_ */
+#endif  /* GRPC_INTERNAL_CORE_IOMGR_WAKEUP_FD_POSIX_H */
diff --git a/src/core/json/json.h b/src/core/json/json.h
index dc519e9..69cbac1 100644
--- a/src/core/json/json.h
+++ b/src/core/json/json.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_SRC_CORE_JSON_JSON_H__
-#define __GRPC_SRC_CORE_JSON_JSON_H__
+#ifndef GRPC_INTERNAL_CORE_JSON_JSON_H
+#define GRPC_INTERNAL_CORE_JSON_JSON_H
 
 #include <stdlib.h>
 
@@ -85,4 +85,4 @@
 grpc_json* grpc_json_create(grpc_json_type type);
 void grpc_json_destroy(grpc_json* json);
 
-#endif /* __GRPC_SRC_CORE_JSON_JSON_H__ */
+#endif  /* GRPC_INTERNAL_CORE_JSON_JSON_H */
diff --git a/src/core/json/json_common.h b/src/core/json/json_common.h
index 60763cc..84bf375 100644
--- a/src/core/json/json_common.h
+++ b/src/core/json/json_common.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_SRC_CORE_JSON_JSON_COMMON_H__
-#define __GRPC_SRC_CORE_JSON_JSON_COMMON_H__
+#ifndef GRPC_INTERNAL_CORE_JSON_JSON_COMMON_H
+#define GRPC_INTERNAL_CORE_JSON_JSON_COMMON_H
 
 /* The various json types. */
 typedef enum {
@@ -46,4 +46,4 @@
   GRPC_JSON_TOP_LEVEL
 } grpc_json_type;
 
-#endif /* __GRPC_SRC_CORE_JSON_JSON_COMMON_H__ */
+#endif  /* GRPC_INTERNAL_CORE_JSON_JSON_COMMON_H */
diff --git a/src/core/json/json_reader.h b/src/core/json/json_reader.h
index f7f5912..b1a5ace 100644
--- a/src/core/json/json_reader.h
+++ b/src/core/json/json_reader.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_SRC_CORE_JSON_JSON_READER_H__
-#define __GRPC_SRC_CORE_JSON_JSON_READER_H__
+#ifndef GRPC_INTERNAL_CORE_JSON_JSON_READER_H
+#define GRPC_INTERNAL_CORE_JSON_JSON_READER_H
 
 #include <grpc/support/port_platform.h>
 #include "src/core/json/json_common.h"
@@ -157,4 +157,4 @@
  */
 int grpc_json_reader_is_complete(grpc_json_reader* reader);
 
-#endif /* __GRPC_SRC_CORE_JSON_JSON_READER_H__ */
+#endif  /* GRPC_INTERNAL_CORE_JSON_JSON_READER_H */
diff --git a/src/core/json/json_writer.h b/src/core/json/json_writer.h
index 5d5d089..dfa61a5 100644
--- a/src/core/json/json_writer.h
+++ b/src/core/json/json_writer.h
@@ -43,8 +43,8 @@
  * a valid UTF-8 string overall.
  */
 
-#ifndef __GRPC_SRC_CORE_JSON_JSON_WRITER_H__
-#define __GRPC_SRC_CORE_JSON_JSON_WRITER_H__
+#ifndef GRPC_INTERNAL_CORE_JSON_JSON_WRITER_H
+#define GRPC_INTERNAL_CORE_JSON_JSON_WRITER_H
 
 #include <stdlib.h>
 
@@ -90,4 +90,4 @@
 /* Sets a string value. It'll be escaped, and utf-8 validated. */
 void grpc_json_writer_value_string(grpc_json_writer* writer, const char* string);
 
-#endif /* __GRPC_SRC_CORE_JSON_JSON_WRITER_H__ */
+#endif  /* GRPC_INTERNAL_CORE_JSON_JSON_WRITER_H */
diff --git a/src/core/security/auth.h b/src/core/security/auth.h
index fee75c4..08dc415 100644
--- a/src/core/security/auth.h
+++ b/src/core/security/auth.h
@@ -31,11 +31,11 @@
  *
  */
 
-#ifndef __GRPC_INTERNAL_SECURITY_AUTH_H__
-#define __GRPC_INTERNAL_SECURITY_AUTH_H__
+#ifndef GRPC_INTERNAL_CORE_SECURITY_AUTH_H
+#define GRPC_INTERNAL_CORE_SECURITY_AUTH_H
 
 #include "src/core/channel/channel_stack.h"
 
 extern const grpc_channel_filter grpc_client_auth_filter;
 
-#endif /* __GRPC_INTERNAL_SECURITY_AUTH_H__ */
+#endif  /* GRPC_INTERNAL_CORE_SECURITY_AUTH_H */
diff --git a/src/core/security/base64.h b/src/core/security/base64.h
index 0eb69d0..6a7cd8e 100644
--- a/src/core/security/base64.h
+++ b/src/core/security/base64.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_INTERNAL_SECURITY_BASE64_H_
-#define __GRPC_INTERNAL_SECURITY_BASE64_H_
+#ifndef GRPC_INTERNAL_CORE_SECURITY_BASE64_H
+#define GRPC_INTERNAL_CORE_SECURITY_BASE64_H
 
 #include <grpc/support/slice.h>
 
@@ -45,4 +45,4 @@
    slice in case of failure. */
 gpr_slice grpc_base64_decode(const char *b64, int url_safe);
 
-#endif /* __GRPC_INTERNAL_SECURITY_BASE64_H_ */
+#endif  /* GRPC_INTERNAL_CORE_SECURITY_BASE64_H */
diff --git a/src/core/security/credentials.h b/src/core/security/credentials.h
index 0a0074c..454e668 100644
--- a/src/core/security/credentials.h
+++ b/src/core/security/credentials.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_INTERNAL_SECURITY_CREDENTIALS_H__
-#define __GRPC_INTERNAL_SECURITY_CREDENTIALS_H__
+#ifndef GRPC_INTERNAL_CORE_SECURITY_CREDENTIALS_H
+#define GRPC_INTERNAL_CORE_SECURITY_CREDENTIALS_H
 
 #include "src/core/transport/stream_op.h"
 #include <grpc/grpc.h>
@@ -160,4 +160,4 @@
 const grpc_ssl_server_config *grpc_ssl_server_credentials_get_config(
     const grpc_server_credentials *ssl_creds);
 
-#endif /* __GRPC_INTERNAL_SECURITY_CREDENTIALS_H__ */
+#endif  /* GRPC_INTERNAL_CORE_SECURITY_CREDENTIALS_H */
diff --git a/src/core/security/json_token.h b/src/core/security/json_token.h
index 1ef9682..029ede3 100644
--- a/src/core/security/json_token.h
+++ b/src/core/security/json_token.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_INTERNAL_SECURITY_JSON_TOKEN_H_
-#define __GRPC_INTERNAL_SECURITY_JSON_TOKEN_H_
+#ifndef GRPC_INTERNAL_CORE_SECURITY_JSON_TOKEN_H
+#define GRPC_INTERNAL_CORE_SECURITY_JSON_TOKEN_H
 
 #include <grpc/support/slice.h>
 #include <openssl/rsa.h>
@@ -79,4 +79,4 @@
 void grpc_jwt_encode_and_sign_set_override(
     grpc_jwt_encode_and_sign_override func);
 
-#endif /* __GRPC_INTERNAL_SECURITY_JSON_TOKEN_H_ */
+#endif  /* GRPC_INTERNAL_CORE_SECURITY_JSON_TOKEN_H */
diff --git a/src/core/security/secure_endpoint.h b/src/core/security/secure_endpoint.h
index 82ba408..808889b 100644
--- a/src/core/security/secure_endpoint.h
+++ b/src/core/security/secure_endpoint.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_INTERNAL_ENDPOINT_SECURE_ENDPOINT_H__
-#define __GRPC_INTERNAL_ENDPOINT_SECURE_ENDPOINT_H__
+#ifndef GRPC_INTERNAL_CORE_SECURITY_SECURE_ENDPOINT_H
+#define GRPC_INTERNAL_CORE_SECURITY_SECURE_ENDPOINT_H
 
 #include "src/core/iomgr/endpoint.h"
 #include <grpc/support/slice.h>
@@ -44,4 +44,4 @@
     struct tsi_frame_protector *protector, grpc_endpoint *to_wrap,
     gpr_slice *leftover_slices, size_t leftover_nslices);
 
-#endif /* __GRPC_INTERNAL_ENDPOINT_SECURE_ENDPOINT_H__ */
+#endif  /* GRPC_INTERNAL_CORE_SECURITY_SECURE_ENDPOINT_H */
diff --git a/src/core/security/secure_transport_setup.h b/src/core/security/secure_transport_setup.h
index 21f41fd..e1f8ed7 100644
--- a/src/core/security/secure_transport_setup.h
+++ b/src/core/security/secure_transport_setup.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_INTERNAL_SECURITY_SECURE_TRANSPORT_SETUP_H__
-#define __GRPC_INTERNAL_SECURITY_SECURE_TRANSPORT_SETUP_H__
+#ifndef GRPC_INTERNAL_CORE_SECURITY_SECURE_TRANSPORT_SETUP_H
+#define GRPC_INTERNAL_CORE_SECURITY_SECURE_TRANSPORT_SETUP_H
 
 #include "src/core/iomgr/endpoint.h"
 #include "src/core/security/security_context.h"
@@ -50,4 +50,4 @@
                                  grpc_secure_transport_setup_done_cb cb,
                                  void *user_data);
 
-#endif /* __GRPC_INTERNAL_SECURITY_SECURE_TRANSPORT_SETUP_H__ */
+#endif  /* GRPC_INTERNAL_CORE_SECURITY_SECURE_TRANSPORT_SETUP_H */
diff --git a/src/core/security/security_context.c b/src/core/security/security_context.c
index 9dce5af..0dc37fa 100644
--- a/src/core/security/security_context.c
+++ b/src/core/security/security_context.c
@@ -44,7 +44,9 @@
 #include "src/core/support/string.h"
 #include "src/core/surface/lame_client.h"
 #include "src/core/transport/chttp2/alpn.h"
+
 #include <grpc/support/alloc.h>
+#include <grpc/support/host_port.h>
 #include <grpc/support/log.h>
 #include <grpc/support/slice_buffer.h>
 #include "src/core/tsi/fake_transport_security.h"
@@ -52,20 +54,33 @@
 
 /* -- Constants. -- */
 
-/* Defines the cipher suites that we accept. All these cipher suites are
-   compliant with TLS 1.2 and use an RSA public key. We prefer GCM over CBC
-   and ECDHE-RSA over just RSA. */
-#define GRPC_SSL_CIPHER_SUITES                                                 \
-  "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:AES128-GCM-SHA256:" \
-  "AES256-GCM-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384:AES128-"  \
-  "SHA256:AES256-SHA256"
-
 #ifndef INSTALL_PREFIX
 static const char *installed_roots_path = "/usr/share/grpc/roots.pem";
 #else
 static const char *installed_roots_path = INSTALL_PREFIX "/share/grpc/roots.pem";
 #endif
 
+/* -- Cipher suites. -- */
+
+/* Defines the cipher suites that we accept by default. All these cipher suites
+   are compliant with HTTP2. */
+#define GRPC_SSL_CIPHER_SUITES                                            \
+  "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-" \
+  "SHA384:ECDHE-RSA-AES256-GCM-SHA384"
+
+static gpr_once cipher_suites_once = GPR_ONCE_INIT;
+static const char *cipher_suites = NULL;
+
+static void init_cipher_suites(void) {
+  char *overridden = gpr_getenv("GRPC_SSL_CIPHER_SUITES");
+  cipher_suites = overridden != NULL ? overridden : GRPC_SSL_CIPHER_SUITES;
+}
+
+static const char *ssl_cipher_suites(void) {
+  gpr_once_init(&cipher_suites_once, init_cipher_suites);
+  return cipher_suites;
+}
+
 /* -- Common methods. -- */
 
 grpc_security_status grpc_security_context_create_handshaker(
@@ -323,6 +338,24 @@
   return ssl_create_handshaker(c->handshaker_factory, 0, NULL, handshaker);
 }
 
+static int ssl_host_matches_name(const tsi_peer *peer,
+                                 const char *peer_name) {
+  char *allocated_name = NULL;
+  int r;
+
+  if (strchr(peer_name, ':') != NULL) {
+    char *ignored_port;
+    gpr_split_host_port(peer_name, &allocated_name, &ignored_port);
+    gpr_free(ignored_port);
+    peer_name = allocated_name;
+    if (!peer_name) return 0;
+  }
+  
+  r = tsi_ssl_peer_matches_name(peer, peer_name);
+  gpr_free(allocated_name);
+  return r;
+}
+
 static grpc_security_status ssl_check_peer(const char *peer_name,
                                            const tsi_peer *peer) {
   /* Check the ALPN. */
@@ -344,10 +377,11 @@
 
   /* Check the peer name if specified. */
   if (peer_name != NULL &&
-      !tsi_ssl_peer_matches_name(peer, peer_name)) {
+      !ssl_host_matches_name(peer, peer_name)) {
     gpr_log(GPR_ERROR, "Peer name %s is not in peer certificate", peer_name);
     return GRPC_SECURITY_ERROR;
   }
+
   return GRPC_SECURITY_OK;
 }
 
@@ -383,7 +417,7 @@
   grpc_ssl_channel_security_context *c =
       (grpc_ssl_channel_security_context *)ctx;
 
-  if (tsi_ssl_peer_matches_name(&c->peer, host)) return GRPC_SECURITY_OK;
+  if (ssl_host_matches_name(&c->peer, host)) return GRPC_SECURITY_OK;
 
   /* If the target name was overridden, then the original target_name was
      'checked' transitively during the previous peer check at the end of the
@@ -443,6 +477,7 @@
   size_t i;
   const unsigned char *pem_root_certs;
   size_t pem_root_certs_size;
+  char *port;
 
   for (i = 0; i < num_alpn_protocols; i++) {
     alpn_protocol_strings[i] =
@@ -468,9 +503,8 @@
   c->base.base.url_scheme = GRPC_SSL_URL_SCHEME;
   c->base.request_metadata_creds = grpc_credentials_ref(request_metadata_creds);
   c->base.check_call_host = ssl_channel_check_call_host;
-  if (target_name != NULL) {
-    c->target_name = gpr_strdup(target_name);
-  }
+  gpr_split_host_port(target_name, &c->target_name, &port);
+  gpr_free(port);
   if (overridden_target_name != NULL) {
     c->overridden_target_name = gpr_strdup(overridden_target_name);
   }
@@ -487,7 +521,7 @@
   result = tsi_create_ssl_client_handshaker_factory(
       config->pem_private_key, config->pem_private_key_size,
       config->pem_cert_chain, config->pem_cert_chain_size, pem_root_certs,
-      pem_root_certs_size, GRPC_SSL_CIPHER_SUITES, alpn_protocol_strings,
+      pem_root_certs_size, ssl_cipher_suites(), alpn_protocol_strings,
       alpn_protocol_string_lengths, num_alpn_protocols, &c->handshaker_factory);
   if (result != TSI_OK) {
     gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.",
@@ -541,7 +575,7 @@
       (const unsigned char **)config->pem_cert_chains,
       config->pem_cert_chains_sizes, config->num_key_cert_pairs,
       config->pem_root_certs, config->pem_root_certs_size,
-      GRPC_SSL_CIPHER_SUITES, alpn_protocol_strings,
+      ssl_cipher_suites(), alpn_protocol_strings,
       alpn_protocol_string_lengths, num_alpn_protocols, &c->handshaker_factory);
   if (result != TSI_OK) {
     gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.",
diff --git a/src/core/security/security_context.h b/src/core/security/security_context.h
index 40e2dac..0b5821c 100644
--- a/src/core/security/security_context.h
+++ b/src/core/security/security_context.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_INTERNAL_SECURITY_SECURITY_CONTEXT_H__
-#define __GRPC_INTERNAL_SECURITY_SECURITY_CONTEXT_H__
+#ifndef GRPC_INTERNAL_CORE_SECURITY_SECURITY_CONTEXT_H
+#define GRPC_INTERNAL_CORE_SECURITY_SECURITY_CONTEXT_H
 
 #include <grpc/grpc_security.h>
 #include "src/core/iomgr/endpoint.h"
@@ -212,4 +212,4 @@
                                                 const grpc_channel_args *args,
                                                 grpc_security_context *ctx);
 
-#endif /* __GRPC_INTERNAL_SECURITY_SECURITY_CONTEXT_H__ */
+#endif  /* GRPC_INTERNAL_CORE_SECURITY_SECURITY_CONTEXT_H */
diff --git a/src/core/statistics/census_init.c b/src/core/statistics/census_init.c
index 820d75f..e6306f5 100644
--- a/src/core/statistics/census_init.c
+++ b/src/core/statistics/census_init.c
@@ -38,13 +38,11 @@
 #include "src/core/statistics/census_tracing.h"
 
 void census_init(void) {
-  gpr_log(GPR_INFO, "Initialize census library.");
   census_tracing_init();
   census_stats_store_init();
 }
 
 void census_shutdown(void) {
-  gpr_log(GPR_INFO, "Shutdown census library.");
   census_stats_store_shutdown();
   census_tracing_shutdown();
 }
diff --git a/src/core/statistics/census_interface.h b/src/core/statistics/census_interface.h
index 0bb0a9f..eb4349c 100644
--- a/src/core/statistics/census_interface.h
+++ b/src/core/statistics/census_interface.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_INTERNAL_STATISTICS_CENSUS_INTERFACE_H__
-#define __GRPC_INTERNAL_STATISTICS_CENSUS_INTERFACE_H__
+#ifndef GRPC_INTERNAL_CORE_STATISTICS_CENSUS_INTERFACE_H
+#define GRPC_INTERNAL_CORE_STATISTICS_CENSUS_INTERFACE_H
 
 #include <grpc/support/port_platform.h>
 
@@ -73,4 +73,4 @@
 /* Ends tracing. Calling this function will invalidate the input op_id. */
 void census_tracing_end_op(census_op_id op_id);
 
-#endif /* __GRPC_INTERNAL_STATISTICS_CENSUS_INTERFACE_H__ */
+#endif  /* GRPC_INTERNAL_CORE_STATISTICS_CENSUS_INTERFACE_H */
diff --git a/src/core/statistics/census_log.h b/src/core/statistics/census_log.h
index 01fd63a..06869b7 100644
--- a/src/core/statistics/census_log.h
+++ b/src/core/statistics/census_log.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_INTERNAL_STATISTICS_LOG_H__
-#define __GRPC_INTERNAL_STATISTICS_LOG_H__
+#ifndef GRPC_INTERNAL_CORE_STATISTICS_CENSUS_LOG_H
+#define GRPC_INTERNAL_CORE_STATISTICS_CENSUS_LOG_H
 
 #include <stddef.h>
 
@@ -88,4 +88,4 @@
    out-of-space. */
 int census_log_out_of_space_count(void);
 
-#endif /* __GRPC_INTERNAL_STATISTICS_LOG_H__ */
+#endif  /* GRPC_INTERNAL_CORE_STATISTICS_CENSUS_LOG_H */
diff --git a/src/core/statistics/census_rpc_stats.c b/src/core/statistics/census_rpc_stats.c
index 388ce4f..0491c91 100644
--- a/src/core/statistics/census_rpc_stats.c
+++ b/src/core/statistics/census_rpc_stats.c
@@ -222,7 +222,6 @@
 }
 
 void census_stats_store_init(void) {
-  gpr_log(GPR_INFO, "Initialize census stats store.");
   init_mutex_once();
   gpr_mu_lock(&g_mu);
   if (g_client_stats_store == NULL && g_server_stats_store == NULL) {
@@ -235,7 +234,6 @@
 }
 
 void census_stats_store_shutdown(void) {
-  gpr_log(GPR_INFO, "Shutdown census stats store.");
   init_mutex_once();
   gpr_mu_lock(&g_mu);
   if (g_client_stats_store != NULL) {
diff --git a/src/core/statistics/census_rpc_stats.h b/src/core/statistics/census_rpc_stats.h
index 942de81..9336dce 100644
--- a/src/core/statistics/census_rpc_stats.h
+++ b/src/core/statistics/census_rpc_stats.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_INTERNAL_STATISTICS_CENSUS_RPC_STATS_H__
-#define __GRPC_INTERNAL_STATISTICS_CENSUS_RPC_STATS_H__
+#ifndef GRPC_INTERNAL_CORE_STATISTICS_CENSUS_RPC_STATS_H
+#define GRPC_INTERNAL_CORE_STATISTICS_CENSUS_RPC_STATS_H
 
 #include "src/core/statistics/census_interface.h"
 #include <grpc/support/port_platform.h>
@@ -98,4 +98,4 @@
 }
 #endif
 
-#endif /* __GRPC_INTERNAL_STATISTICS_CENSUS_RPC_STATS_H__ */
+#endif  /* GRPC_INTERNAL_CORE_STATISTICS_CENSUS_RPC_STATS_H */
diff --git a/src/core/statistics/census_tracing.c b/src/core/statistics/census_tracing.c
index adfcbec..05e72b9 100644
--- a/src/core/statistics/census_tracing.c
+++ b/src/core/statistics/census_tracing.c
@@ -154,7 +154,6 @@
 }
 
 void census_tracing_init(void) {
-  gpr_log(GPR_INFO, "Initialize census trace store.");
   init_mutex_once();
   gpr_mu_lock(&g_mu);
   if (g_trace_store == NULL) {
@@ -167,7 +166,6 @@
 }
 
 void census_tracing_shutdown(void) {
-  gpr_log(GPR_INFO, "Shutdown census trace store.");
   gpr_mu_lock(&g_mu);
   if (g_trace_store != NULL) {
     census_ht_destroy(g_trace_store);
diff --git a/src/core/statistics/census_tracing.h b/src/core/statistics/census_tracing.h
index 51aa578..a4494b5 100644
--- a/src/core/statistics/census_tracing.h
+++ b/src/core/statistics/census_tracing.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_INTERNAL_STATISTICS_CENSUS_TRACING_H_
-#define __GRPC_INTERNAL_STATISTICS_CENSUS_TRACING_H_
+#ifndef GRPC_INTERNAL_CORE_STATISTICS_CENSUS_TRACING_H
+#define GRPC_INTERNAL_CORE_STATISTICS_CENSUS_TRACING_H
 
 #include <grpc/support/time.h>
 #include "src/core/statistics/census_rpc_stats.h"
@@ -93,4 +93,4 @@
 }
 #endif
 
-#endif /* __GRPC_INTERNAL_STATISTICS_CENSUS_TRACING_H_ */
+#endif  /* GRPC_INTERNAL_CORE_STATISTICS_CENSUS_TRACING_H */
diff --git a/src/core/statistics/hash_table.h b/src/core/statistics/hash_table.h
index 2c2386d..7bcb4bc 100644
--- a/src/core/statistics/hash_table.h
+++ b/src/core/statistics/hash_table.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_INTERNAL_STATISTICS_HASH_TABLE_H_
-#define __GRPC_INTERNAL_STATISTICS_HASH_TABLE_H_
+#ifndef GRPC_INTERNAL_CORE_STATISTICS_HASH_TABLE_H
+#define GRPC_INTERNAL_CORE_STATISTICS_HASH_TABLE_H
 
 #include <stddef.h>
 
@@ -128,4 +128,4 @@
    should not invalidate data entries. */
 gpr_uint64 census_ht_for_all(const census_ht* ht, census_ht_itr_cb);
 
-#endif /* __GRPC_INTERNAL_STATISTICS_HASH_TABLE_H_ */
+#endif  /* GRPC_INTERNAL_CORE_STATISTICS_HASH_TABLE_H */
diff --git a/src/core/statistics/window_stats.h b/src/core/statistics/window_stats.h
index 98f8dac..d733d8d 100644
--- a/src/core/statistics/window_stats.h
+++ b/src/core/statistics/window_stats.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_INTERNAL_STATISTICS_WINDOW_STATS_H_
-#define __GRPC_INTERNAL_STATISTICS_WINDOW_STATS_H_
+#ifndef GRPC_INTERNAL_CORE_STATISTICS_WINDOW_STATS_H
+#define GRPC_INTERNAL_CORE_STATISTICS_WINDOW_STATS_H
 
 #include <grpc/support/time.h>
 
@@ -170,4 +170,4 @@
    assertion failure). This function is thread-compatible. */
 void census_window_stats_destroy(struct census_window_stats* wstats);
 
-#endif /* __GRPC_INTERNAL_STATISTICS_WINDOW_STATS_H_ */
+#endif  /* GRPC_INTERNAL_CORE_STATISTICS_WINDOW_STATS_H */
diff --git a/src/core/support/cpu_posix.c b/src/core/support/cpu_posix.c
index 33c7b90..5f45fb0 100644
--- a/src/core/support/cpu_posix.c
+++ b/src/core/support/cpu_posix.c
@@ -40,6 +40,7 @@
 #include <string.h>
 
 #include <grpc/support/log.h>
+#include <grpc/support/sync.h>
 
 static __thread char magic_thread_local;
 
@@ -55,7 +56,7 @@
 
 unsigned gpr_cpu_num_cores(void) {
   static gpr_once once = GPR_ONCE_INIT;
-  gpr_once_init(&once, init_num_cpus);
+  gpr_once_init(&once, init_ncpus);
   return ncpus;
 }
 
diff --git a/src/core/support/env.h b/src/core/support/env.h
index 0c6091b..4f2e394 100644
--- a/src/core/support/env.h
+++ b/src/core/support/env.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_SUPPORT_ENV_H__
-#define __GRPC_SUPPORT_ENV_H__
+#ifndef GRPC_INTERNAL_CORE_SUPPORT_ENV_H
+#define GRPC_INTERNAL_CORE_SUPPORT_ENV_H
 
 #include <stdio.h>
 
@@ -57,4 +57,4 @@
 }
 #endif
 
-#endif /* __GRPC_SUPPORT_ENV_H__ */
+#endif  /* GRPC_INTERNAL_CORE_SUPPORT_ENV_H */
diff --git a/src/core/support/file.h b/src/core/support/file.h
index 600850e..ee6ca7b 100644
--- a/src/core/support/file.h
+++ b/src/core/support/file.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_SUPPORT_FILE_H__
-#define __GRPC_SUPPORT_FILE_H__
+#ifndef GRPC_INTERNAL_CORE_SUPPORT_FILE_H
+#define GRPC_INTERNAL_CORE_SUPPORT_FILE_H
 
 #include <stdio.h>
 
@@ -58,4 +58,4 @@
 }
 #endif
 
-#endif /* __GRPC_SUPPORT_FILE_H__ */
+#endif  /* GRPC_INTERNAL_CORE_SUPPORT_FILE_H */
diff --git a/src/core/support/log_posix.c b/src/core/support/log_posix.c
index 8f85791..afca792 100644
--- a/src/core/support/log_posix.c
+++ b/src/core/support/log_posix.c
@@ -64,7 +64,7 @@
   } else {
     message = allocated = gpr_malloc(ret + 1);
     va_start(args, format);
-    vsnprintf(message, ret, format, args);
+    vsnprintf(message, ret + 1, format, args);
     va_end(args);
   }
   gpr_log_message(file, line, severity, message);
diff --git a/src/core/support/murmur_hash.h b/src/core/support/murmur_hash.h
index 06c0c56..85ab2fe 100644
--- a/src/core/support/murmur_hash.h
+++ b/src/core/support/murmur_hash.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_INTERNAL_SUPPORT_MURMUR_HASH_H__
-#define __GRPC_INTERNAL_SUPPORT_MURMUR_HASH_H__
+#ifndef GRPC_INTERNAL_CORE_SUPPORT_MURMUR_HASH_H
+#define GRPC_INTERNAL_CORE_SUPPORT_MURMUR_HASH_H
 
 #include <grpc/support/port_platform.h>
 
@@ -41,4 +41,4 @@
 /* compute the hash of key (length len) */
 gpr_uint32 gpr_murmur_hash3(const void *key, size_t len, gpr_uint32 seed);
 
-#endif /* __GRPC_INTERNAL_SUPPORT_MURMUR_HASH_H__ */
+#endif  /* GRPC_INTERNAL_CORE_SUPPORT_MURMUR_HASH_H */
diff --git a/src/core/support/string.h b/src/core/support/string.h
index eaa1826..faf3342 100644
--- a/src/core/support/string.h
+++ b/src/core/support/string.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_SUPPORT_STRING_H__
-#define __GRPC_SUPPORT_STRING_H__
+#ifndef GRPC_INTERNAL_CORE_SUPPORT_STRING_H
+#define GRPC_INTERNAL_CORE_SUPPORT_STRING_H
 
 #include <stddef.h>
 
@@ -106,4 +106,4 @@
 }
 #endif
 
-#endif /* __GRPC_SUPPORT_STRING_H__ */
+#endif  /* GRPC_INTERNAL_CORE_SUPPORT_STRING_H */
diff --git a/src/core/support/string_win32.h b/src/core/support/string_win32.h
index 5dbb40d..0bc3247 100644
--- a/src/core/support/string_win32.h
+++ b/src/core/support/string_win32.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_SUPPORT_STRING_WIN32_H__
-#define __GRPC_SUPPORT_STRING_WIN32_H__
+#ifndef GRPC_INTERNAL_CORE_SUPPORT_STRING_WIN32_H
+#define GRPC_INTERNAL_CORE_SUPPORT_STRING_WIN32_H
 
 #include <grpc/support/port_platform.h>
 
@@ -46,4 +46,4 @@
 
 #endif  /* GPR_WIN32 */
 
-#endif /* __GRPC_SUPPORT_STRING_WIN32_H__ */
+#endif  /* GRPC_INTERNAL_CORE_SUPPORT_STRING_WIN32_H */
diff --git a/src/core/support/thd_internal.h b/src/core/support/thd_internal.h
index 0fb1447..4683c37 100644
--- a/src/core/support/thd_internal.h
+++ b/src/core/support/thd_internal.h
@@ -31,9 +31,9 @@
  *
  */
 
-#ifndef __GRPC_INTERNAL_SUPPORT_THD_INTERNAL_H__
-#define __GRPC_INTERNAL_SUPPORT_THD_INTERNAL_H__
+#ifndef GRPC_INTERNAL_CORE_SUPPORT_THD_INTERNAL_H
+#define GRPC_INTERNAL_CORE_SUPPORT_THD_INTERNAL_H
 
 /* Internal interfaces between modules within the gpr support library.  */
 
-#endif /* __GRPC_INTERNAL_SUPPORT_THD_INTERNAL_H__ */
+#endif  /* GRPC_INTERNAL_CORE_SUPPORT_THD_INTERNAL_H */
diff --git a/src/core/surface/byte_buffer_queue.h b/src/core/surface/byte_buffer_queue.h
index 9d3b525..32c57f8 100644
--- a/src/core/surface/byte_buffer_queue.h
+++ b/src/core/surface/byte_buffer_queue.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_INTERNAL_SURFACE_BYTE_BUFFER_QUEUE_H__
-#define __GRPC_INTERNAL_SURFACE_BYTE_BUFFER_QUEUE_H__
+#ifndef GRPC_INTERNAL_CORE_SURFACE_BYTE_BUFFER_QUEUE_H
+#define GRPC_INTERNAL_CORE_SURFACE_BYTE_BUFFER_QUEUE_H
 
 #include <grpc/byte_buffer.h>
 
@@ -57,4 +57,4 @@
 int grpc_bbq_empty(grpc_byte_buffer_queue *q);
 void grpc_bbq_push(grpc_byte_buffer_queue *q, grpc_byte_buffer *bb);
 
-#endif  /* __GRPC_INTERNAL_SURFACE_BYTE_BUFFER_QUEUE_H__ */
+#endif  /* GRPC_INTERNAL_CORE_SURFACE_BYTE_BUFFER_QUEUE_H */
diff --git a/src/core/surface/call.h b/src/core/surface/call.h
index dd3ad12..cb81cb5 100644
--- a/src/core/surface/call.h
+++ b/src/core/surface/call.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_INTERNAL_SURFACE_CALL_H__
-#define __GRPC_INTERNAL_SURFACE_CALL_H__
+#ifndef GRPC_INTERNAL_CORE_SURFACE_CALL_H
+#define GRPC_INTERNAL_CORE_SURFACE_CALL_H
 
 #include "src/core/channel/channel_stack.h"
 #include "src/core/channel/metadata_buffer.h"
@@ -119,4 +119,4 @@
 /* Given the top call_element, get the call object. */
 grpc_call *grpc_call_from_top_element(grpc_call_element *surface_element);
 
-#endif /* __GRPC_INTERNAL_SURFACE_CALL_H__ */
+#endif  /* GRPC_INTERNAL_CORE_SURFACE_CALL_H */
diff --git a/src/core/surface/channel.h b/src/core/surface/channel.h
index 6bdfd47..d3e5118 100644
--- a/src/core/surface/channel.h
+++ b/src/core/surface/channel.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_INTERNAL_SURFACE_CHANNEL_H__
-#define __GRPC_INTERNAL_SURFACE_CHANNEL_H__
+#ifndef GRPC_INTERNAL_CORE_SURFACE_CHANNEL_H
+#define GRPC_INTERNAL_CORE_SURFACE_CHANNEL_H
 
 #include "src/core/channel/channel_stack.h"
 
@@ -50,4 +50,4 @@
 void grpc_channel_internal_ref(grpc_channel *channel);
 void grpc_channel_internal_unref(grpc_channel *channel);
 
-#endif /* __GRPC_INTERNAL_SURFACE_CHANNEL_H__ */
+#endif  /* GRPC_INTERNAL_CORE_SURFACE_CHANNEL_H */
diff --git a/src/core/surface/client.h b/src/core/surface/client.h
index 06ce8f6..9db2ccf 100644
--- a/src/core/surface/client.h
+++ b/src/core/surface/client.h
@@ -31,11 +31,11 @@
  *
  */
 
-#ifndef __GRPC_INTERNAL_SURFACE_CLIENT_H__
-#define __GRPC_INTERNAL_SURFACE_CLIENT_H__
+#ifndef GRPC_INTERNAL_CORE_SURFACE_CLIENT_H
+#define GRPC_INTERNAL_CORE_SURFACE_CLIENT_H
 
 #include "src/core/channel/channel_stack.h"
 
 extern const grpc_channel_filter grpc_client_surface_filter;
 
-#endif /* __GRPC_INTERNAL_SURFACE_CLIENT_H__ */
+#endif  /* GRPC_INTERNAL_CORE_SURFACE_CLIENT_H */
diff --git a/src/core/surface/completion_queue.c b/src/core/surface/completion_queue.c
index 2efc084..c4b8d60 100644
--- a/src/core/surface/completion_queue.c
+++ b/src/core/surface/completion_queue.c
@@ -389,12 +389,17 @@
   }
 }
 
-void grpc_completion_queue_destroy(grpc_completion_queue *cc) {
-  GPR_ASSERT(cc->queue == NULL);
+static void on_pollset_destroy_done(void *arg) {
+  grpc_completion_queue *cc = arg;
   grpc_pollset_destroy(&cc->pollset);
   gpr_free(cc);
 }
 
+void grpc_completion_queue_destroy(grpc_completion_queue *cc) {
+  GPR_ASSERT(cc->queue == NULL);
+  grpc_pollset_shutdown(&cc->pollset, on_pollset_destroy_done, cc);
+}
+
 void grpc_event_finish(grpc_event *base) {
   event *ev = (event *)base;
   ev->on_finish(ev->on_finish_user_data, GRPC_OP_OK);
diff --git a/src/core/surface/completion_queue.h b/src/core/surface/completion_queue.h
index a7688b8..3054264 100644
--- a/src/core/surface/completion_queue.h
+++ b/src/core/surface/completion_queue.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_INTERNAL_SURFACE_COMPLETION_QUEUE_H__
-#define __GRPC_INTERNAL_SURFACE_COMPLETION_QUEUE_H__
+#ifndef GRPC_INTERNAL_CORE_SURFACE_COMPLETION_QUEUE_H
+#define GRPC_INTERNAL_CORE_SURFACE_COMPLETION_QUEUE_H
 
 /* Internal API for completion channels */
 
@@ -114,4 +114,4 @@
 
 grpc_pollset *grpc_cq_pollset(grpc_completion_queue *cc);
 
-#endif /* __GRPC_INTERNAL_SURFACE_COMPLETION_QUEUE_H__ */
+#endif  /* GRPC_INTERNAL_CORE_SURFACE_COMPLETION_QUEUE_H */
diff --git a/src/core/surface/event_string.h b/src/core/surface/event_string.h
index d9b1e4e..e8a8f93 100644
--- a/src/core/surface/event_string.h
+++ b/src/core/surface/event_string.h
@@ -31,12 +31,12 @@
  *
  */
 
-#ifndef __GRPC_INTERNAL_SURFACE_EVENT_STRING_H__
-#define __GRPC_INTERNAL_SURFACE_EVENT_STRING_H__
+#ifndef GRPC_INTERNAL_CORE_SURFACE_EVENT_STRING_H
+#define GRPC_INTERNAL_CORE_SURFACE_EVENT_STRING_H
 
 #include <grpc/grpc.h>
 
 /* Returns a string describing an event. Must be later freed with gpr_free() */
 char *grpc_event_string(grpc_event *ev);
 
-#endif /* __GRPC_INTERNAL_SURFACE_EVENT_STRING_H__ */
+#endif  /* GRPC_INTERNAL_CORE_SURFACE_EVENT_STRING_H */
diff --git a/src/core/surface/lame_client.h b/src/core/surface/lame_client.h
index 2bd97b9..b13e8cb 100644
--- a/src/core/surface/lame_client.h
+++ b/src/core/surface/lame_client.h
@@ -31,12 +31,12 @@
  *
  */
 
-#ifndef __GRPC_INTERNAL_SURFACE_LAME_CLIENT_H_
-#define __GRPC_INTERNAL_SURFACE_LAME_CLIENT_H_
+#ifndef GRPC_INTERNAL_CORE_SURFACE_LAME_CLIENT_H
+#define GRPC_INTERNAL_CORE_SURFACE_LAME_CLIENT_H
 
 #include <grpc/grpc.h>
 
 /* Create a lame client: this client fails every operation attempted on it. */
 grpc_channel *grpc_lame_client_channel_create(void);
 
-#endif /* __GRPC_INTERNAL_SURFACE_LAME_CLIENT_H_ */
+#endif  /* GRPC_INTERNAL_CORE_SURFACE_LAME_CLIENT_H */
diff --git a/src/core/surface/server.h b/src/core/surface/server.h
index 5ae59b2..e33f69b 100644
--- a/src/core/surface/server.h
+++ b/src/core/surface/server.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_INTERNAL_SURFACE_SERVER_H__
-#define __GRPC_INTERNAL_SURFACE_SERVER_H__
+#ifndef GRPC_INTERNAL_CORE_SURFACE_SERVER_H
+#define GRPC_INTERNAL_CORE_SURFACE_SERVER_H
 
 #include "src/core/channel/channel_stack.h"
 #include <grpc/grpc.h>
@@ -60,4 +60,4 @@
 
 const grpc_channel_args *grpc_server_get_channel_args(grpc_server *server);
 
-#endif /* __GRPC_INTERNAL_SURFACE_SERVER_H__ */
+#endif  /* GRPC_INTERNAL_CORE_SURFACE_SERVER_H */
diff --git a/src/core/surface/surface_trace.h b/src/core/surface/surface_trace.h
index 4d478d6..50071ee 100644
--- a/src/core/surface/surface_trace.h
+++ b/src/core/surface/surface_trace.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_INTERNAL_SURFACE_SURFACE_TRACE_H__
-#define __GRPC_INTERNAL_SURFACE_SURFACE_TRACE_H__
+#ifndef GRPC_INTERNAL_CORE_SURFACE_SURFACE_TRACE_H
+#define GRPC_INTERNAL_CORE_SURFACE_SURFACE_TRACE_H
 
 #include "src/core/debug/trace.h"
 #include <grpc/support/log.h>
@@ -44,4 +44,4 @@
     gpr_free(_ev);                                      \
   }
 
-#endif /* __GRPC_INTERNAL_SURFACE_SURFACE_TRACE_H__ */
+#endif  /* GRPC_INTERNAL_CORE_SURFACE_SURFACE_TRACE_H */
diff --git a/src/core/transport/chttp2/alpn.h b/src/core/transport/chttp2/alpn.h
index 796f514..fcbefc0 100644
--- a/src/core/transport/chttp2/alpn.h
+++ b/src/core/transport/chttp2/alpn.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_INTERNAL_TRANSPORT_CHTTP2_ALPN_H_
-#define __GRPC_INTERNAL_TRANSPORT_CHTTP2_ALPN_H_
+#ifndef GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_ALPN_H
+#define GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_ALPN_H
 
 #include <string.h>
 
@@ -46,4 +46,4 @@
  * grpc_chttp2_num_alpn_versions()) */
 const char *grpc_chttp2_get_alpn_version_index(size_t i);
 
-#endif /* __GRPC_INTERNAL_TRANSPORT_CHTTP2_ALPN_H_ */
+#endif  /* GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_ALPN_H */
diff --git a/src/core/transport/chttp2/bin_encoder.h b/src/core/transport/chttp2/bin_encoder.h
index 2368fdd..9c88ac9 100644
--- a/src/core/transport/chttp2/bin_encoder.h
+++ b/src/core/transport/chttp2/bin_encoder.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_INTERNAL_TRANSPORT_CHTTP2_BIN_ENCODER_H_
-#define __GRPC_INTERNAL_TRANSPORT_CHTTP2_BIN_ENCODER_H_
+#ifndef GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_BIN_ENCODER_H
+#define GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_BIN_ENCODER_H
 
 #include <grpc/support/slice.h>
 
@@ -53,4 +53,4 @@
 
 int grpc_is_binary_header(const char *key, size_t length);
 
-#endif /* __GRPC_INTERNAL_TRANSPORT_CHTTP2_BIN_ENCODER_H_ */
+#endif  /* GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_BIN_ENCODER_H */
diff --git a/src/core/transport/chttp2/frame.h b/src/core/transport/chttp2/frame.h
index 733dd5e..fbb9419 100644
--- a/src/core/transport/chttp2/frame.h
+++ b/src/core/transport/chttp2/frame.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_INTERNAL_TRANSPORT_CHTTP2_FRAME_H__
-#define __GRPC_INTERNAL_TRANSPORT_CHTTP2_FRAME_H__
+#ifndef GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_FRAME_H
+#define GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_FRAME_H
 
 #include <grpc/support/port_platform.h>
 #include <grpc/support/slice.h>
@@ -77,4 +77,4 @@
 #define GRPC_CHTTP2_DATA_FLAG_PADDED 8
 #define GRPC_CHTTP2_FLAG_HAS_PRIORITY 0x20
 
-#endif /* __GRPC_INTERNAL_TRANSPORT_CHTTP2_FRAME_H__ */
+#endif  /* GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_FRAME_H */
diff --git a/src/core/transport/chttp2/frame_data.h b/src/core/transport/chttp2/frame_data.h
index 4d05a5f..24e557a 100644
--- a/src/core/transport/chttp2/frame_data.h
+++ b/src/core/transport/chttp2/frame_data.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_INTERNAL_TRANSPORT_CHTTP2_FRAME_DATA_H__
-#define __GRPC_INTERNAL_TRANSPORT_CHTTP2_FRAME_DATA_H__
+#ifndef GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_FRAME_DATA_H
+#define GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_FRAME_DATA_H
 
 /* Parser for GRPC streams embedded in DATA frames */
 
@@ -77,4 +77,4 @@
 /* create a slice with an empty data frame and is_last set */
 gpr_slice grpc_chttp2_data_frame_create_empty_close(gpr_uint32 id);
 
-#endif /* __GRPC_INTERNAL_TRANSPORT_CHTTP2_FRAME_DATA_H__ */
+#endif  /* GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_FRAME_DATA_H */
diff --git a/src/core/transport/chttp2/frame_goaway.h b/src/core/transport/chttp2/frame_goaway.h
index 9ccef27..7638891 100644
--- a/src/core/transport/chttp2/frame_goaway.h
+++ b/src/core/transport/chttp2/frame_goaway.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_INTERNAL_TRANSPORT_CHTTP2_FRAME_GOAWAY_H_
-#define __GRPC_INTERNAL_TRANSPORT_CHTTP2_FRAME_GOAWAY_H_
+#ifndef GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_FRAME_GOAWAY_H
+#define GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_FRAME_GOAWAY_H
 
 #include "src/core/transport/chttp2/frame.h"
 #include <grpc/support/port_platform.h>
@@ -71,4 +71,4 @@
                                gpr_slice debug_data,
                                gpr_slice_buffer *slice_buffer);
 
-#endif /* __GRPC_INTERNAL_TRANSPORT_CHTTP2_FRAME_GOAWAY_H_ */
+#endif  /* GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_FRAME_GOAWAY_H */
diff --git a/src/core/transport/chttp2/frame_ping.h b/src/core/transport/chttp2/frame_ping.h
index d9d6f7e..11d38b8 100644
--- a/src/core/transport/chttp2/frame_ping.h
+++ b/src/core/transport/chttp2/frame_ping.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_INTERNAL_TRANSPORT_CHTTP2_FRAME_PING_H__
-#define __GRPC_INTERNAL_TRANSPORT_CHTTP2_FRAME_PING_H__
+#ifndef GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_FRAME_PING_H
+#define GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_FRAME_PING_H
 
 #include <grpc/support/slice.h>
 #include "src/core/transport/chttp2/frame.h"
@@ -50,4 +50,4 @@
 grpc_chttp2_parse_error grpc_chttp2_ping_parser_parse(
     void *parser, grpc_chttp2_parse_state *state, gpr_slice slice, int is_last);
 
-#endif /* __GRPC_INTERNAL_TRANSPORT_CHTTP2_FRAME_PING_H__ */
+#endif  /* GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_FRAME_PING_H */
diff --git a/src/core/transport/chttp2/frame_rst_stream.h b/src/core/transport/chttp2/frame_rst_stream.h
index 83fc380..2d3ee18 100644
--- a/src/core/transport/chttp2/frame_rst_stream.h
+++ b/src/core/transport/chttp2/frame_rst_stream.h
@@ -31,11 +31,11 @@
  *
  */
 
-#ifndef __GRPC_INTERNAL_TRANSPORT_CHTTP2_FRAME_RST_STREAM_H__
-#define __GRPC_INTERNAL_TRANSPORT_CHTTP2_FRAME_RST_STREAM_H__
+#ifndef GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_FRAME_RST_STREAM_H
+#define GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_FRAME_RST_STREAM_H
 
 #include <grpc/support/slice.h>
 
 gpr_slice grpc_chttp2_rst_stream_create(gpr_uint32 stream_id, gpr_uint32 code);
 
-#endif /* __GRPC_INTERNAL_TRANSPORT_CHTTP2_FRAME_RST_STREAM_H__ */
+#endif  /* GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_FRAME_RST_STREAM_H */
diff --git a/src/core/transport/chttp2/frame_settings.c b/src/core/transport/chttp2/frame_settings.c
index 06429e2..e6c4b7e 100644
--- a/src/core/transport/chttp2/frame_settings.c
+++ b/src/core/transport/chttp2/frame_settings.c
@@ -35,6 +35,7 @@
 
 #include <string.h>
 
+#include "src/core/debug/trace.h"
 #include "src/core/transport/chttp2/frame.h"
 #include <grpc/support/log.h>
 #include <grpc/support/useful.h>
@@ -53,7 +54,8 @@
         {"MAX_FRAME_SIZE", 16384, 16384, 16777215,
          GRPC_CHTTP2_DISCONNECT_ON_INVALID_VALUE},
         {"MAX_HEADER_LIST_SIZE", 0xffffffffu, 0, 0xffffffffu,
-         GRPC_CHTTP2_CLAMP_INVALID_VALUE}, };
+         GRPC_CHTTP2_CLAMP_INVALID_VALUE},
+};
 
 static gpr_uint8 *fill_header(gpr_uint8 *out, gpr_uint32 length,
                               gpr_uint8 flags) {
@@ -155,7 +157,7 @@
           }
           return GRPC_CHTTP2_PARSE_OK;
         }
-        parser->id = ((gpr_uint16) * cur) << 8;
+        parser->id = ((gpr_uint16)*cur) << 8;
         cur++;
       /* fallthrough */
       case GRPC_CHTTP2_SPS_ID1:
@@ -171,7 +173,7 @@
           parser->state = GRPC_CHTTP2_SPS_VAL0;
           return GRPC_CHTTP2_PARSE_OK;
         }
-        parser->value = ((gpr_uint32) * cur) << 24;
+        parser->value = ((gpr_uint32)*cur) << 24;
         cur++;
       /* fallthrough */
       case GRPC_CHTTP2_SPS_VAL1:
@@ -179,7 +181,7 @@
           parser->state = GRPC_CHTTP2_SPS_VAL1;
           return GRPC_CHTTP2_PARSE_OK;
         }
-        parser->value |= ((gpr_uint32) * cur) << 16;
+        parser->value |= ((gpr_uint32)*cur) << 16;
         cur++;
       /* fallthrough */
       case GRPC_CHTTP2_SPS_VAL2:
@@ -187,7 +189,7 @@
           parser->state = GRPC_CHTTP2_SPS_VAL2;
           return GRPC_CHTTP2_PARSE_OK;
         }
-        parser->value |= ((gpr_uint32) * cur) << 8;
+        parser->value |= ((gpr_uint32)*cur) << 8;
         cur++;
       /* fallthrough */
       case GRPC_CHTTP2_SPS_VAL3:
@@ -216,8 +218,10 @@
             }
           }
           parser->incoming_settings[parser->id] = parser->value;
-          gpr_log(GPR_DEBUG, "CHTTP2: got setting %d = %d", parser->id,
-                  parser->value);
+          if (grpc_trace_bits & GRPC_TRACE_HTTP) {
+            gpr_log(GPR_DEBUG, "CHTTP2: got setting %d = %d", parser->id,
+                    parser->value);
+          }
         } else {
           gpr_log(GPR_ERROR, "CHTTP2: Ignoring unknown setting %d (value %d)",
                   parser->id, parser->value);
diff --git a/src/core/transport/chttp2/frame_settings.h b/src/core/transport/chttp2/frame_settings.h
index 6cde2c6..1876563 100644
--- a/src/core/transport/chttp2/frame_settings.h
+++ b/src/core/transport/chttp2/frame_settings.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_INTERNAL_TRANSPORT_CHTTP2_FRAME_SETTINGS_H__
-#define __GRPC_INTERNAL_TRANSPORT_CHTTP2_FRAME_SETTINGS_H__
+#ifndef GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_FRAME_SETTINGS_H
+#define GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_FRAME_SETTINGS_H
 
 #include <grpc/support/port_platform.h>
 #include <grpc/support/slice.h>
@@ -96,4 +96,4 @@
 grpc_chttp2_parse_error grpc_chttp2_settings_parser_parse(
     void *parser, grpc_chttp2_parse_state *state, gpr_slice slice, int is_last);
 
-#endif /* __GRPC_INTERNAL_TRANSPORT_CHTTP2_FRAME_SETTINGS_H__ */
+#endif  /* GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_FRAME_SETTINGS_H */
diff --git a/src/core/transport/chttp2/frame_window_update.h b/src/core/transport/chttp2/frame_window_update.h
index 093263d..85475a8 100644
--- a/src/core/transport/chttp2/frame_window_update.h
+++ b/src/core/transport/chttp2/frame_window_update.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_INTERNAL_TRANSPORT_CHTTP2_FRAME_WINDOW_UPDATE_H__
-#define __GRPC_INTERNAL_TRANSPORT_CHTTP2_FRAME_WINDOW_UPDATE_H__
+#ifndef GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_FRAME_WINDOW_UPDATE_H
+#define GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_FRAME_WINDOW_UPDATE_H
 
 #include <grpc/support/slice.h>
 #include "src/core/transport/chttp2/frame.h"
@@ -52,4 +52,4 @@
 grpc_chttp2_parse_error grpc_chttp2_window_update_parser_parse(
     void *parser, grpc_chttp2_parse_state *state, gpr_slice slice, int is_last);
 
-#endif /* __GRPC_INTERNAL_TRANSPORT_CHTTP2_FRAME_WINDOW_UPDATE_H__ */
+#endif  /* GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_FRAME_WINDOW_UPDATE_H */
diff --git a/src/core/transport/chttp2/hpack_parser.h b/src/core/transport/chttp2/hpack_parser.h
index 94acc88..bb4c1a1 100644
--- a/src/core/transport/chttp2/hpack_parser.h
+++ b/src/core/transport/chttp2/hpack_parser.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_INTERNAL_TRANSPORT_CHTTP2_HPACK_PARSER_H__
-#define __GRPC_INTERNAL_TRANSPORT_CHTTP2_HPACK_PARSER_H__
+#ifndef GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_HPACK_PARSER_H
+#define GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_HPACK_PARSER_H
 
 #include <stddef.h>
 
@@ -108,4 +108,4 @@
     void *hpack_parser, grpc_chttp2_parse_state *state, gpr_slice slice,
     int is_last);
 
-#endif /* __GRPC_INTERNAL_TRANSPORT_CHTTP2_HPACK_PARSER_H__ */
+#endif  /* GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_HPACK_PARSER_H */
diff --git a/src/core/transport/chttp2/hpack_table.h b/src/core/transport/chttp2/hpack_table.h
index ea0fc1d..d3bf41b 100644
--- a/src/core/transport/chttp2/hpack_table.h
+++ b/src/core/transport/chttp2/hpack_table.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_INTERNAL_TRANSPORT_CHTTP2_HPACK_TABLE_H__
-#define __GRPC_INTERNAL_TRANSPORT_CHTTP2_HPACK_TABLE_H__
+#ifndef GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_HPACK_TABLE_H
+#define GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_HPACK_TABLE_H
 
 #include "src/core/transport/metadata.h"
 #include <grpc/support/port_platform.h>
@@ -94,4 +94,4 @@
 grpc_chttp2_hptbl_find_result grpc_chttp2_hptbl_find(
     const grpc_chttp2_hptbl *tbl, grpc_mdelem *md);
 
-#endif /* __GRPC_INTERNAL_TRANSPORT_CHTTP2_HPACK_TABLE_H__ */
+#endif  /* GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_HPACK_TABLE_H */
diff --git a/src/core/transport/chttp2/http2_errors.h b/src/core/transport/chttp2/http2_errors.h
index 1eecd17..4ab2ec0 100644
--- a/src/core/transport/chttp2/http2_errors.h
+++ b/src/core/transport/chttp2/http2_errors.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_INTERNAL_TRANSPORT_CHTTP2_HTTP2_ERRORS_H__
-#define __GRPC_INTERNAL_TRANSPORT_CHTTP2_HTTP2_ERRORS_H__
+#ifndef GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_HTTP2_ERRORS_H
+#define GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_HTTP2_ERRORS_H
 
 /* error codes for RST_STREAM from http2 draft 14 section 7 */
 typedef enum {
@@ -53,4 +53,4 @@
   GRPC_CHTTP2__ERROR_DO_NOT_USE = -1
 } grpc_chttp2_error_code;
 
-#endif /* __GRPC_INTERNAL_TRANSPORT_CHTTP2_HTTP2_ERRORS_H__ */
+#endif  /* GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_HTTP2_ERRORS_H */
diff --git a/src/core/transport/chttp2/huffsyms.h b/src/core/transport/chttp2/huffsyms.h
index 131c4ac..f9c1447 100644
--- a/src/core/transport/chttp2/huffsyms.h
+++ b/src/core/transport/chttp2/huffsyms.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_INTERNAL_TRANSPORT_CHTTP2_HUFFSYMS_H_
-#define __GRPC_INTERNAL_TRANSPORT_CHTTP2_HUFFSYMS_H_
+#ifndef GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_HUFFSYMS_H
+#define GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_HUFFSYMS_H
 
 /* HPACK static huffman table */
 
@@ -45,4 +45,4 @@
 
 extern const grpc_chttp2_huffsym grpc_chttp2_huffsyms[GRPC_CHTTP2_NUM_HUFFSYMS];
 
-#endif /* __GRPC_INTERNAL_TRANSPORT_CHTTP2_HUFFSYMS_H_ */
+#endif  /* GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_HUFFSYMS_H */
diff --git a/src/core/transport/chttp2/status_conversion.h b/src/core/transport/chttp2/status_conversion.h
index 8e26720..cf06c35 100644
--- a/src/core/transport/chttp2/status_conversion.h
+++ b/src/core/transport/chttp2/status_conversion.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_INTERNAL_TRANSPORT_CHTTP2_STATUS_CONVERSION_H__
-#define __GRPC_INTERNAL_TRANSPORT_CHTTP2_STATUS_CONVERSION_H__
+#ifndef GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_STATUS_CONVERSION_H
+#define GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_STATUS_CONVERSION_H
 
 #include <grpc/grpc.h>
 #include "src/core/transport/chttp2/http2_errors.h"
@@ -47,4 +47,4 @@
 grpc_status_code grpc_chttp2_http2_status_to_grpc_status(int status);
 int grpc_chttp2_grpc_status_to_http2_status(grpc_status_code status);
 
-#endif /* __GRPC_INTERNAL_TRANSPORT_CHTTP2_STATUS_CONVERSION_H__ */
+#endif  /* GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_STATUS_CONVERSION_H */
diff --git a/src/core/transport/chttp2/stream_encoder.h b/src/core/transport/chttp2/stream_encoder.h
index a99d61a..50c58ad 100644
--- a/src/core/transport/chttp2/stream_encoder.h
+++ b/src/core/transport/chttp2/stream_encoder.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_INTERNAL_TRANSPORT_CHTTP2_STREAM_ENCODER_H__
-#define __GRPC_INTERNAL_TRANSPORT_CHTTP2_STREAM_ENCODER_H__
+#ifndef GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_STREAM_ENCODER_H
+#define GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_STREAM_ENCODER_H
 
 #include "src/core/transport/chttp2/frame.h"
 #include "src/core/transport/metadata.h"
@@ -90,4 +90,4 @@
                         grpc_chttp2_hpack_compressor *compressor,
                         gpr_slice_buffer *output);
 
-#endif /* __GRPC_INTERNAL_TRANSPORT_CHTTP2_STREAM_ENCODER_H__ */
+#endif  /* GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_STREAM_ENCODER_H */
diff --git a/src/core/transport/chttp2/stream_map.h b/src/core/transport/chttp2/stream_map.h
index 3fb91fc..d338d2f 100644
--- a/src/core/transport/chttp2/stream_map.h
+++ b/src/core/transport/chttp2/stream_map.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_INTERNAL_TRANSPORT_CHTTP2_STREAM_MAP_H__
-#define __GRPC_INTERNAL_TRANSPORT_CHTTP2_STREAM_MAP_H__
+#ifndef GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_STREAM_MAP_H
+#define GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_STREAM_MAP_H
 
 #include <grpc/support/port_platform.h>
 
@@ -78,4 +78,4 @@
                                                void *value),
                                      void *user_data);
 
-#endif /* __GRPC_INTERNAL_TRANSPORT_CHTTP2_STREAM_MAP_H__ */
+#endif  /* GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_STREAM_MAP_H */
diff --git a/src/core/transport/chttp2/timeout_encoding.h b/src/core/transport/chttp2/timeout_encoding.h
index 2bef8ba..e6664c6 100644
--- a/src/core/transport/chttp2/timeout_encoding.h
+++ b/src/core/transport/chttp2/timeout_encoding.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_INTERNAL_TRANSPORT_CHTTP2_TIMEOUT_ENCODING_H_
-#define __GRPC_INTERNAL_TRANSPORT_CHTTP2_TIMEOUT_ENCODING_H_
+#ifndef GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_TIMEOUT_ENCODING_H
+#define GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_TIMEOUT_ENCODING_H
 
 #include "src/core/support/string.h"
 #include <grpc/support/time.h>
@@ -44,4 +44,4 @@
 void grpc_chttp2_encode_timeout(gpr_timespec timeout, char *buffer);
 int grpc_chttp2_decode_timeout(const char *buffer, gpr_timespec *timeout);
 
-#endif /* __GRPC_INTERNAL_TRANSPORT_CHTTP2_TIMEOUT_ENCODING_H_ */
+#endif  /* GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_TIMEOUT_ENCODING_H */
diff --git a/src/core/transport/chttp2/varint.h b/src/core/transport/chttp2/varint.h
index 8c353c6..ee04ed7 100644
--- a/src/core/transport/chttp2/varint.h
+++ b/src/core/transport/chttp2/varint.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_INTERNAL_TRANSPORT_CHTTP2_VARINT_H__
-#define __GRPC_INTERNAL_TRANSPORT_CHTTP2_VARINT_H__
+#ifndef GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_VARINT_H
+#define GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_VARINT_H
 
 #include <grpc/support/port_platform.h>
 
@@ -71,4 +71,4 @@
     }                                                                       \
   } while (0)
 
-#endif /* __GRPC_INTERNAL_TRANSPORT_CHTTP2_VARINT_H__ */
+#endif  /* GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_VARINT_H */
diff --git a/src/core/transport/chttp2_transport.c b/src/core/transport/chttp2_transport.c
index ccd8d0c..476cc4b 100644
--- a/src/core/transport/chttp2_transport.c
+++ b/src/core/transport/chttp2_transport.c
@@ -37,6 +37,7 @@
 #include <stdio.h>
 #include <string.h>
 
+#include "src/core/debug/trace.h"
 #include "src/core/support/string.h"
 #include "src/core/transport/chttp2/frame_data.h"
 #include "src/core/transport/chttp2/frame_goaway.h"
@@ -66,6 +67,12 @@
 typedef struct transport transport;
 typedef struct stream stream;
 
+#define IF_TRACING(stmt)                    \
+  if (!(grpc_trace_bits & GRPC_TRACE_HTTP)) \
+    ;                                       \
+  else                                      \
+  stmt
+
 /* streams are kept in various linked lists depending on what things need to
    happen to them... this enum labels each list */
 typedef enum {
@@ -301,7 +308,7 @@
                          gpr_uint32 value);
 
 static int prepare_callbacks(transport *t);
-static void run_callbacks(transport *t);
+static void run_callbacks(transport *t, const grpc_transport_callbacks *cb);
 
 static int prepare_write(transport *t);
 static void perform_write(transport *t, grpc_endpoint *ep);
@@ -552,7 +559,7 @@
     lock(t);
     s->id = 0;
   } else {
-    s->id = (gpr_uint32)(gpr_uintptr)server_data;
+    s->id = (gpr_uint32)(gpr_uintptr) server_data;
     t->incoming_stream = s;
     grpc_chttp2_stream_map_add(&t->stream_map, s->id, s);
   }
@@ -706,6 +713,7 @@
   pending_goaway *goaways = NULL;
   grpc_endpoint *ep = t->ep;
   grpc_stream_op_buffer nuke_now;
+  const grpc_transport_callbacks *cb = t->cb;
 
   grpc_sopb_init(&nuke_now);
   if (t->nuke_later_sopb.nops) {
@@ -725,7 +733,7 @@
   }
 
   /* gather any callbacks that need to be made */
-  if (!t->calling_back && t->cb) {
+  if (!t->calling_back && cb) {
     perform_callbacks = prepare_callbacks(t);
     if (perform_callbacks) {
       t->calling_back = 1;
@@ -733,6 +741,7 @@
     if (t->error_state == ERROR_STATE_SEEN) {
       call_closed = 1;
       t->calling_back = 1;
+      t->cb = NULL;  /* no more callbacks */
       t->error_state = ERROR_STATE_NOTIFIED;
     }
     if (t->num_pending_goaways) {
@@ -754,16 +763,16 @@
 
   /* perform some callbacks if necessary */
   for (i = 0; i < num_goaways; i++) {
-    t->cb->goaway(t->cb_user_data, &t->base, goaways[i].status,
-                  goaways[i].debug);
+    cb->goaway(t->cb_user_data, &t->base, goaways[i].status,
+               goaways[i].debug);
   }
 
   if (perform_callbacks) {
-    run_callbacks(t);
+    run_callbacks(t, cb);
   }
 
   if (call_closed) {
-    t->cb->closed(t->cb_user_data, &t->base);
+    cb->closed(t->cb_user_data, &t->base);
   }
 
   /* write some bytes if necessary */
@@ -1206,6 +1215,11 @@
   stream *s = t->incoming_stream;
 
   GPR_ASSERT(s);
+
+  IF_TRACING(gpr_log(GPR_INFO, "HTTP:%d:HDR: %s: %s", s->id,
+                     grpc_mdstr_as_c_string(md->key),
+                     grpc_mdstr_as_c_string(md->value)));
+
   stream_list_join(t, s, PENDING_CALLBACKS);
   if (md->key == t->str_grpc_timeout) {
     gpr_timespec *cached_timeout = grpc_mdelem_get_user_data(md, free_timeout);
@@ -1269,7 +1283,7 @@
     t->incoming_stream = NULL;
     /* if stream is accepted, we set incoming_stream in init_stream */
     t->cb->accept_stream(t->cb_user_data, &t->base,
-                         (void *)(gpr_uintptr)t->incoming_stream_id);
+                         (void *)(gpr_uintptr) t->incoming_stream_id);
     s = t->incoming_stream;
     if (!s) {
       gpr_log(GPR_ERROR, "stream not accepted");
@@ -1534,8 +1548,8 @@
                   "Connect string mismatch: expected '%c' (%d) got '%c' (%d) "
                   "at byte %d",
                   CLIENT_CONNECT_STRING[t->deframe_state],
-                  (int)(gpr_uint8)CLIENT_CONNECT_STRING[t->deframe_state], *cur,
-                  (int)*cur, t->deframe_state);
+                  (int)(gpr_uint8) CLIENT_CONNECT_STRING[t->deframe_state],
+                  *cur, (int)*cur, t->deframe_state);
           drop_connection(t);
           return 0;
         }
@@ -1741,13 +1755,13 @@
   return n;
 }
 
-static void run_callbacks(transport *t) {
+static void run_callbacks(transport *t, const grpc_transport_callbacks *cb) {
   stream *s;
   while ((s = stream_list_remove_head(t, EXECUTING_CALLBACKS))) {
     size_t nops = s->callback_sopb.nops;
     s->callback_sopb.nops = 0;
-    t->cb->recv_batch(t->cb_user_data, &t->base, (grpc_stream *)s,
-                      s->callback_sopb.ops, nops, s->callback_state);
+    cb->recv_batch(t->cb_user_data, &t->base, (grpc_stream *)s,
+                   s->callback_sopb.ops, nops, s->callback_state);
   }
 }
 
@@ -1765,9 +1779,9 @@
  */
 
 static const grpc_transport_vtable vtable = {
-    sizeof(stream), init_stream, send_batch, set_allow_window_updates,
-    add_to_pollset, destroy_stream, abort_stream, goaway, close_transport,
-    send_ping, destroy_transport};
+    sizeof(stream),  init_stream,    send_batch,       set_allow_window_updates,
+    add_to_pollset,  destroy_stream, abort_stream,     goaway,
+    close_transport, send_ping,      destroy_transport};
 
 void grpc_create_chttp2_transport(grpc_transport_setup_callback setup,
                                   void *arg,
diff --git a/src/core/transport/chttp2_transport.h b/src/core/transport/chttp2_transport.h
index 6fbc596..c5b65bd 100644
--- a/src/core/transport/chttp2_transport.h
+++ b/src/core/transport/chttp2_transport.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_INTERNAL_TRANSPORT_CHTTP2_TRANSPORT_H__
-#define __GRPC_INTERNAL_TRANSPORT_CHTTP2_TRANSPORT_H__
+#ifndef GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_TRANSPORT_H
+#define GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_TRANSPORT_H
 
 #include "src/core/iomgr/endpoint.h"
 #include "src/core/transport/transport.h"
@@ -44,4 +44,4 @@
                                   size_t nslices, grpc_mdctx *metadata_context,
                                   int is_client);
 
-#endif /* __GRPC_INTERNAL_TRANSPORT_CHTTP2_TRANSPORT_H__ */
+#endif  /* GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_TRANSPORT_H */
diff --git a/src/core/transport/metadata.h b/src/core/transport/metadata.h
index 7a56e34..b8afbeb 100644
--- a/src/core/transport/metadata.h
+++ b/src/core/transport/metadata.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_INTERNAL_TRANSPORT_METADATA_H__
-#define __GRPC_INTERNAL_TRANSPORT_METADATA_H__
+#ifndef GRPC_INTERNAL_CORE_TRANSPORT_METADATA_H
+#define GRPC_INTERNAL_CORE_TRANSPORT_METADATA_H
 
 #include <grpc/support/slice.h>
 #include <grpc/support/useful.h>
@@ -137,4 +137,4 @@
 
 #define GRPC_MDSTR_KV_HASH(k_hash, v_hash) (GPR_ROTL((k_hash), 2) ^ (v_hash))
 
-#endif /* __GRPC_INTERNAL_TRANSPORT_METADATA_H__ */
+#endif  /* GRPC_INTERNAL_CORE_TRANSPORT_METADATA_H */
diff --git a/src/core/transport/stream_op.h b/src/core/transport/stream_op.h
index 828a7f7..2ffbcce 100644
--- a/src/core/transport/stream_op.h
+++ b/src/core/transport/stream_op.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_INTERNAL_TRANSPORT_STREAM_OP_H__
-#define __GRPC_INTERNAL_TRANSPORT_STREAM_OP_H__
+#ifndef GRPC_INTERNAL_CORE_TRANSPORT_STREAM_OP_H
+#define GRPC_INTERNAL_CORE_TRANSPORT_STREAM_OP_H
 
 #include <grpc/grpc.h>
 #include <grpc/support/port_platform.h>
@@ -131,4 +131,4 @@
 void grpc_sopb_append(grpc_stream_op_buffer *sopb, grpc_stream_op *ops,
                       size_t nops);
 
-#endif /* __GRPC_INTERNAL_TRANSPORT_STREAM_OP_H__ */
+#endif  /* GRPC_INTERNAL_CORE_TRANSPORT_STREAM_OP_H */
diff --git a/src/core/transport/transport.h b/src/core/transport/transport.h
index 60193b1..ce8c17c 100644
--- a/src/core/transport/transport.h
+++ b/src/core/transport/transport.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_INTERNAL_TRANSPORT_TRANSPORT_H__
-#define __GRPC_INTERNAL_TRANSPORT_TRANSPORT_H__
+#ifndef GRPC_INTERNAL_CORE_TRANSPORT_TRANSPORT_H
+#define GRPC_INTERNAL_CORE_TRANSPORT_TRANSPORT_H
 
 #include <stddef.h>
 
@@ -254,4 +254,4 @@
    used as a destruction call by setup). */
 void grpc_transport_setup_cancel(grpc_transport_setup *setup);
 
-#endif /* __GRPC_INTERNAL_TRANSPORT_TRANSPORT_H__ */
+#endif  /* GRPC_INTERNAL_CORE_TRANSPORT_TRANSPORT_H */
diff --git a/src/core/transport/transport_impl.h b/src/core/transport/transport_impl.h
index d1e0b19..ac275c7 100644
--- a/src/core/transport/transport_impl.h
+++ b/src/core/transport/transport_impl.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_INTERNAL_TRANSPORT_TRANSPORT_IMPL_H__
-#define __GRPC_INTERNAL_TRANSPORT_TRANSPORT_IMPL_H__
+#ifndef GRPC_INTERNAL_CORE_TRANSPORT_TRANSPORT_IMPL_H
+#define GRPC_INTERNAL_CORE_TRANSPORT_TRANSPORT_IMPL_H
 
 #include "src/core/transport/transport.h"
 
@@ -84,4 +84,4 @@
   const grpc_transport_vtable *vtable;
 };
 
-#endif /* __GRPC_INTERNAL_TRANSPORT_TRANSPORT_IMPL_H__ */
+#endif  /* GRPC_INTERNAL_CORE_TRANSPORT_TRANSPORT_IMPL_H */
diff --git a/src/core/tsi/fake_transport_security.c b/src/core/tsi/fake_transport_security.c
index e8af200..f58f04e 100644
--- a/src/core/tsi/fake_transport_security.c
+++ b/src/core/tsi/fake_transport_security.c
@@ -392,8 +392,10 @@
     if (next_message_to_send > TSI_FAKE_HANDSHAKE_MESSAGE_MAX) {
       next_message_to_send = TSI_FAKE_HANDSHAKE_MESSAGE_MAX;
     }
-    gpr_log(GPR_INFO, "%s prepared %s.", impl->is_client ? "Client" : "Server",
-            tsi_fake_handshake_message_to_string(impl->next_message_to_send));
+    if (tsi_tracing_enabled) {
+      gpr_log(GPR_INFO, "%s prepared %s.", impl->is_client ? "Client" : "Server",
+              tsi_fake_handshake_message_to_string(impl->next_message_to_send));
+    }
     impl->next_message_to_send = next_message_to_send;
   }
   result = drain_frame_to_bytes(bytes, bytes_size, &impl->outgoing);
@@ -401,7 +403,9 @@
   if (!impl->is_client &&
       impl->next_message_to_send == TSI_FAKE_HANDSHAKE_MESSAGE_MAX) {
     /* We're done. */
-    gpr_log(GPR_INFO, "Server is done.");
+    if (tsi_tracing_enabled) {
+      gpr_log(GPR_INFO, "Server is done.");
+    }
     impl->result = TSI_OK;
   } else {
     impl->needs_incoming_message = 1;
@@ -436,13 +440,17 @@
             tsi_fake_handshake_message_to_string(received_msg),
             tsi_fake_handshake_message_to_string(expected_msg));
   }
-  gpr_log(GPR_INFO, "%s received %s.", impl->is_client ? "Client" : "Server",
-          tsi_fake_handshake_message_to_string(received_msg));
+  if (tsi_tracing_enabled) {
+    gpr_log(GPR_INFO, "%s received %s.", impl->is_client ? "Client" : "Server",
+            tsi_fake_handshake_message_to_string(received_msg));
+  }
   tsi_fake_frame_reset(&impl->incoming, 0 /* needs_draining */);
   impl->needs_incoming_message = 0;
   if (impl->next_message_to_send == TSI_FAKE_HANDSHAKE_MESSAGE_MAX) {
     /* We're done. */
-    gpr_log(GPR_INFO, "%s is done.", impl->is_client ? "Client" : "Server");
+    if (tsi_tracing_enabled) {
+      gpr_log(GPR_INFO, "%s is done.", impl->is_client ? "Client" : "Server");
+    }
     impl->result = TSI_OK;
   }
   return TSI_OK;
diff --git a/src/core/tsi/fake_transport_security.h b/src/core/tsi/fake_transport_security.h
index 36e62bc..af9730b 100644
--- a/src/core/tsi/fake_transport_security.h
+++ b/src/core/tsi/fake_transport_security.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __FAKE_TRANSPORT_SECURITY_H_
-#define __FAKE_TRANSPORT_SECURITY_H_
+#ifndef GRPC_INTERNAL_CORE_TSI_FAKE_TRANSPORT_SECURITY_H
+#define GRPC_INTERNAL_CORE_TSI_FAKE_TRANSPORT_SECURITY_H
 
 #include "src/core/tsi/transport_security_interface.h"
 
@@ -58,4 +58,4 @@
 }
 #endif
 
-#endif /* __FAKE_TRANSPORT_SECURITY_H_ */
+#endif  /* GRPC_INTERNAL_CORE_TSI_FAKE_TRANSPORT_SECURITY_H */
diff --git a/src/core/tsi/ssl_transport_security.c b/src/core/tsi/ssl_transport_security.c
index 85b0922..dc43f7e 100644
--- a/src/core/tsi/ssl_transport_security.c
+++ b/src/core/tsi/ssl_transport_security.c
@@ -162,7 +162,7 @@
 /* TODO(jboeuf): Remove when we are past the debugging phase with this code. */
 static void ssl_log_where_info(const SSL* ssl, int where, int flag,
                                const char* msg) {
-  if (where & flag) {
+  if ((where & flag) && tsi_tracing_enabled) {
     gpr_log(GPR_INFO, "%20.20s - %30.30s  - %5.10s", msg,
             SSL_state_string_long(ssl), SSL_state_string(ssl));
   }
@@ -180,6 +180,30 @@
   ssl_log_where_info(ssl, where, SSL_CB_HANDSHAKE_DONE, "HANDSHAKE DONE");
 }
 
+/* Returns 1 if name looks like an IP address, 0 otherwise.
+   This is a very rough heuristic as it does not handle IPV6 or things like:
+   0300.0250.00.01, 0xC0.0Xa8.0x0.0x1, 000030052000001, 0xc0.052000001 */
+static int looks_like_ip_address(const char *name) {
+  size_t i;
+  size_t dot_count = 0;
+  size_t num_size = 0;
+  for (i = 0; i < strlen(name); i++) {
+    if (name[i] >= '0' && name[i] <= '9') {
+      if (num_size > 3) return 0;
+      num_size++;
+    } else if (name[i] == '.') {
+      if (dot_count > 3 || num_size == 0) return 0;
+      dot_count++;
+      num_size = 0;
+    } else {
+      return 0;
+    }
+  }
+  if (dot_count < 3 || num_size == 0) return 0;
+  return 1;
+}
+
+
 /* Gets the subject CN from an X509 cert. */
 static tsi_result ssl_get_x509_common_name(X509* cert, unsigned char** utf8,
                                            size_t* utf8_size) {
@@ -226,10 +250,18 @@
   size_t common_name_size;
   tsi_result result =
       ssl_get_x509_common_name(cert, &common_name, &common_name_size);
-  if (result != TSI_OK) return result;
+  if (result != TSI_OK) {
+    if (result == TSI_NOT_FOUND) {
+      common_name = NULL;
+      common_name_size = 0;
+    } else {
+      return result;
+    }
+  }
   result = tsi_construct_string_peer_property(
-      TSI_X509_SUBJECT_COMMON_NAME_PEER_PROPERTY, (const char*)common_name,
-      common_name_size, property);
+      TSI_X509_SUBJECT_COMMON_NAME_PEER_PROPERTY,
+      common_name == NULL ? "" : (const char*)common_name, common_name_size,
+      property);
   OPENSSL_free(common_name);
   return result;
 }
@@ -1036,9 +1068,22 @@
 
 static int does_entry_match_name(const char* entry, size_t entry_length,
                                  const char* name) {
+  const char *dot;
   const char* name_subdomain = NULL;
+  size_t name_length = strlen(name);
+  size_t name_subdomain_length;
   if (entry_length == 0) return 0;
-  if (!strncmp(name, entry, entry_length) && (strlen(name) == entry_length)) {
+
+  /* Take care of '.' terminations. */
+  if (name[name_length - 1] == '.') {
+    name_length--;
+  }
+  if (entry[entry_length - 1] == '.') {
+    entry_length--;
+    if (entry_length == 0) return 0;
+  }
+
+  if ((name_length == entry_length) && !strncmp(name, entry, entry_length)) {
     return 1; /* Perfect match. */
   }
   if (entry[0] != '*') return 0;
@@ -1049,18 +1094,29 @@
     return 0;
   }
   name_subdomain = strchr(name, '.');
-  if (name_subdomain == NULL || strlen(name_subdomain) < 2) return 0;
+  if (name_subdomain == NULL) return 0;
+  name_subdomain_length = strlen(name_subdomain);
+  if (name_subdomain_length < 2) return 0;
   name_subdomain++; /* Starts after the dot. */
+  name_subdomain_length--;
   entry += 2;       /* Remove *. */
   entry_length -= 2;
-  return (!strncmp(entry, name_subdomain, entry_length) &&
-          (strlen(name_subdomain) == entry_length));
+  dot = strchr(name_subdomain, '.');
+  if ((dot == NULL) || (dot == &name_subdomain[name_subdomain_length - 1])) {
+    gpr_log(GPR_ERROR, "Invalid toplevel subdomain: %s", name_subdomain);
+    return 0;
+  }
+  if (name_subdomain[name_subdomain_length - 1] == '.') {
+    name_subdomain_length--;
+  }
+  return ((entry_length > 0) && (name_subdomain_length == entry_length) &&
+          !strncmp(entry, name_subdomain, entry_length));
 }
 
 static int ssl_server_handshaker_factory_servername_callback(SSL* ssl, int* ap,
                                                              void* arg) {
   tsi_ssl_server_handshaker_factory* impl =
-      (tsi_ssl_server_handshaker_factory*)arg;
+     (tsi_ssl_server_handshaker_factory*)arg;
   size_t i = 0;
   const char* servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
   if (servername == NULL || strlen(servername) == 0) {
@@ -1283,17 +1339,13 @@
 
 int tsi_ssl_peer_matches_name(const tsi_peer* peer, const char* name) {
   size_t i = 0;
-  const tsi_peer_property* property = tsi_peer_get_property_by_name(
-      peer, TSI_X509_SUBJECT_COMMON_NAME_PEER_PROPERTY);
-  if (property == NULL || property->type != TSI_PEER_PROPERTY_TYPE_STRING) {
-    gpr_log(GPR_ERROR, "Invalid x509 subject common name property.");
-    return 0;
-  }
-  if (does_entry_match_name(property->value.string.data,
-                            property->value.string.length, name)) {
-    return 1;
-  }
+  size_t san_count = 0;
+  const tsi_peer_property* property = NULL;
 
+  /* For now reject what looks like an IP address. */
+  if (looks_like_ip_address(name)) return 0;
+
+  /* Check the SAN first. */
   property = tsi_peer_get_property_by_name(
       peer, TSI_X509_SUBJECT_ALTERNATIVE_NAMES_PEER_PROPERTY);
   if (property == NULL || property->type != TSI_PEER_PROPERTY_TYPE_LIST) {
@@ -1301,7 +1353,8 @@
     return 0;
   }
 
-  for (i = 0; i < property->value.list.child_count; i++) {
+  san_count = property->value.list.child_count;
+  for (i = 0; i < san_count; i++) {
     const tsi_peer_property* alt_name_property =
         &property->value.list.children[i];
     if (alt_name_property->type != TSI_PEER_PROPERTY_TYPE_STRING) {
@@ -1313,5 +1366,20 @@
       return 1;
     }
   }
+
+  /* If there's no SAN, try the CN. */
+  if (san_count == 0) {
+    property = tsi_peer_get_property_by_name(
+        peer, TSI_X509_SUBJECT_COMMON_NAME_PEER_PROPERTY);
+    if (property == NULL || property->type != TSI_PEER_PROPERTY_TYPE_STRING) {
+      gpr_log(GPR_ERROR, "Invalid x509 subject common name property.");
+      return 0;
+    }
+    if (does_entry_match_name(property->value.string.data,
+                              property->value.string.length, name)) {
+      return 1;
+    }
+  }
+
   return 0; /* Not found. */
 }
diff --git a/src/core/tsi/ssl_transport_security.h b/src/core/tsi/ssl_transport_security.h
index 3c1c4c0..192f7ac 100644
--- a/src/core/tsi/ssl_transport_security.h
+++ b/src/core/tsi/ssl_transport_security.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __SSL_TRANSPORT_SECURITY_H_
-#define __SSL_TRANSPORT_SECURITY_H_
+#ifndef GRPC_INTERNAL_CORE_TSI_SSL_TRANSPORT_SECURITY_H
+#define GRPC_INTERNAL_CORE_TSI_SSL_TRANSPORT_SECURITY_H
 
 #include "src/core/tsi/transport_security_interface.h"
 
@@ -158,11 +158,16 @@
    while handshakers created with this factory are still in use.  */
 void tsi_ssl_handshaker_factory_destroy(tsi_ssl_handshaker_factory* self);
 
-/* Util that checks that an ssl peer matches a specific name. */
+/* Util that checks that an ssl peer matches a specific name.
+   Still TODO(jboeuf):
+   - handle mixed case.
+   - handle %encoded chars.
+   - handle public suffix wildchar more strictly (e.g. *.co.uk)
+   - handle IP addresses in SAN. */
 int tsi_ssl_peer_matches_name(const tsi_peer* peer, const char* name);
 
 #ifdef __cplusplus
 }
 #endif
 
-#endif /* __SSL_TRANSPORT_SECURITY_H_ */
+#endif  /* GRPC_INTERNAL_CORE_TSI_SSL_TRANSPORT_SECURITY_H */
diff --git a/src/core/tsi/transport_security.c b/src/core/tsi/transport_security.c
index aeb9b3f..04b3000 100644
--- a/src/core/tsi/transport_security.c
+++ b/src/core/tsi/transport_security.c
@@ -36,6 +36,14 @@
 #include <stdlib.h>
 #include <string.h>
 
+/* --- Tracing. --- */
+
+int tsi_tracing_enabled = 0;
+
+void tsi_enable_tracing() {
+  tsi_tracing_enabled = 1;
+}
+
 /* --- Utils. --- */
 
 char* tsi_strdup(const char* src) {
diff --git a/src/core/tsi/transport_security.h b/src/core/tsi/transport_security.h
index 432da07..59e5dcf 100644
--- a/src/core/tsi/transport_security.h
+++ b/src/core/tsi/transport_security.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __TRANSPORT_SECURITY_H_
-#define __TRANSPORT_SECURITY_H_
+#ifndef GRPC_INTERNAL_CORE_TSI_TRANSPORT_SECURITY_H
+#define GRPC_INTERNAL_CORE_TSI_TRANSPORT_SECURITY_H
 
 #include "src/core/tsi/transport_security_interface.h"
 
@@ -40,6 +40,8 @@
 extern "C" {
 #endif
 
+extern int tsi_tracing_enabled;
+
 /* Base for tsi_frame_protector implementations.
    See transport_security_interface.h for documentation. */
 typedef struct {
@@ -115,4 +117,4 @@
 }
 #endif
 
-#endif /* __TRANSPORT_SECURITY_H_ */
+#endif  /* GRPC_INTERNAL_CORE_TSI_TRANSPORT_SECURITY_H */
diff --git a/src/core/tsi/transport_security_interface.h b/src/core/tsi/transport_security_interface.h
index 90e119c..33a19be 100644
--- a/src/core/tsi/transport_security_interface.h
+++ b/src/core/tsi/transport_security_interface.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __TRANSPORT_SECURITY_INTERFACE_H_
-#define __TRANSPORT_SECURITY_INTERFACE_H_
+#ifndef GRPC_INTERNAL_CORE_TSI_TRANSPORT_SECURITY_INTERFACE_H
+#define GRPC_INTERNAL_CORE_TSI_TRANSPORT_SECURITY_INTERFACE_H
 
 #include <stdint.h>
 #include <stdlib.h>
@@ -61,6 +61,11 @@
 
 const char* tsi_result_to_string(tsi_result result);
 
+/* --- tsi tracing --- */
+
+/* Call this function before any other tsi function to avoid races. */
+void tsi_enable_tracing(void);
+
 /* --- tsi_frame_protector object ---
 
   This object protects and unprotects buffers once the handshake is done.
@@ -361,4 +366,4 @@
 }
 #endif
 
-#endif /* __TRANSPORT_SECURITY_INTERFACE_H_ */
+#endif  /* GRPC_INTERNAL_CORE_TSI_TRANSPORT_SECURITY_INTERFACE_H */
diff --git a/src/cpp/client/channel.h b/src/cpp/client/channel.h
index 06f5a8f..63c6e2b 100644
--- a/src/cpp/client/channel.h
+++ b/src/cpp/client/channel.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPCPP_INTERNAL_CLIENT_CHANNEL_H__
-#define __GRPCPP_INTERNAL_CLIENT_CHANNEL_H__
+#ifndef GRPC_INTERNAL_CPP_CLIENT_CHANNEL_H
+#define GRPC_INTERNAL_CPP_CLIENT_CHANNEL_H
 
 #include <memory>
 
@@ -49,17 +49,17 @@
 class Credentials;
 class StreamContextInterface;
 
-class Channel final : public ChannelInterface {
+class Channel GRPC_FINAL : public ChannelInterface {
  public:
   Channel(const grpc::string &target, const ChannelArguments &args);
   Channel(const grpc::string &target, const std::unique_ptr<Credentials> &creds,
           const ChannelArguments &args);
 
-  ~Channel() override;
+  ~Channel() GRPC_OVERRIDE;
 
   virtual Call CreateCall(const RpcMethod &method, ClientContext *context,
-                          CompletionQueue *cq) override;
-  virtual void PerformOpsOnCall(CallOpBuffer *ops, Call *call) override;
+                          CompletionQueue *cq) GRPC_OVERRIDE;
+  virtual void PerformOpsOnCall(CallOpBuffer *ops, Call *call) GRPC_OVERRIDE;
 
  private:
   const grpc::string target_;
@@ -68,4 +68,4 @@
 
 }  // namespace grpc
 
-#endif  // __GRPCPP_INTERNAL_CLIENT_CHANNEL_H__
+#endif  // GRPC_INTERNAL_CPP_CLIENT_CHANNEL_H
diff --git a/src/cpp/client/client_context.cc b/src/cpp/client/client_context.cc
index 80cbdd9..9f99f7b 100644
--- a/src/cpp/client/client_context.cc
+++ b/src/cpp/client/client_context.cc
@@ -41,7 +41,10 @@
 namespace grpc {
 
 ClientContext::ClientContext()
-    : call_(nullptr), cq_(nullptr), absolute_deadline_(gpr_inf_future) {}
+    : initial_metadata_received_(false),
+      call_(nullptr),
+      cq_(nullptr),
+      absolute_deadline_(gpr_inf_future) {}
 
 ClientContext::~ClientContext() {
   if (call_) {
diff --git a/src/cpp/common/call.cc b/src/cpp/common/call.cc
index e6a20a2..f3a6911 100644
--- a/src/cpp/common/call.cc
+++ b/src/cpp/common/call.cc
@@ -41,6 +41,30 @@
 
 namespace grpc {
 
+CallOpBuffer::CallOpBuffer()
+    : return_tag_(this),
+      send_initial_metadata_(false),
+      initial_metadata_count_(0),
+      initial_metadata_(nullptr),
+      recv_initial_metadata_(nullptr),
+      recv_initial_metadata_arr_{0, 0, nullptr},
+      send_message_(nullptr),
+      send_message_buf_(nullptr),
+      recv_message_(nullptr),
+      recv_message_buf_(nullptr),
+      client_send_close_(false),
+      recv_trailing_metadata_(nullptr),
+      recv_status_(nullptr),
+      recv_trailing_metadata_arr_{0, 0, nullptr},
+      status_code_(GRPC_STATUS_OK),
+      status_details_(nullptr),
+      status_details_capacity_(0),
+      send_status_(nullptr),
+      trailing_metadata_count_(0),
+      trailing_metadata_(nullptr),
+      cancelled_buf_(0),
+      recv_closed_(nullptr) {}
+
 void CallOpBuffer::Reset(void* next_return_tag) {
   return_tag_ = next_return_tag;
 
diff --git a/src/cpp/proto/proto_utils.h b/src/cpp/proto/proto_utils.h
index 834884d..a0af4d6 100644
--- a/src/cpp/proto/proto_utils.h
+++ b/src/cpp/proto/proto_utils.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPCPP_INTERNAL_PROTO_PROTO_UTILS_H__
-#define __GRPCPP_INTERNAL_PROTO_PROTO_UTILS_H__
+#ifndef GRPC_INTERNAL_CPP_PROTO_PROTO_UTILS_H
+#define GRPC_INTERNAL_CPP_PROTO_PROTO_UTILS_H
 
 struct grpc_byte_buffer;
 namespace google {
@@ -54,4 +54,4 @@
 
 }  // namespace grpc
 
-#endif  // __GRPCPP_INTERNAL_PROTO_PROTO_UTILS_H__
+#endif  // GRPC_INTERNAL_CPP_PROTO_PROTO_UTILS_H
diff --git a/src/cpp/server/server.cc b/src/cpp/server/server.cc
index 178fa1a..97bf0f1 100644
--- a/src/cpp/server/server.cc
+++ b/src/cpp/server/server.cc
@@ -49,11 +49,12 @@
 
 namespace grpc {
 
-class Server::SyncRequest final : public CompletionQueueTag {
+class Server::SyncRequest GRPC_FINAL : public CompletionQueueTag {
  public:
   SyncRequest(RpcServiceMethod* method, void* tag)
       : method_(method),
         tag_(tag),
+        in_flight_(false),
         has_request_payload_(method->method_type() == RpcMethod::NORMAL_RPC ||
                              method->method_type() ==
                                  RpcMethod::SERVER_STREAMING),
@@ -85,14 +86,14 @@
                    this));
   }
 
-  bool FinalizeResult(void** tag, bool* status) override {
+  bool FinalizeResult(void** tag, bool* status) GRPC_OVERRIDE {
     if (!*status) {
       grpc_completion_queue_destroy(cq_);
     }
     return true;
   }
 
-  class CallData final {
+  class CallData GRPC_FINAL {
    public:
     explicit CallData(Server* server, SyncRequest* mrd)
         : cq_(mrd->cq_),
@@ -159,7 +160,7 @@
  private:
   RpcServiceMethod* const method_;
   void* const tag_;
-  bool in_flight_ = false;
+  bool in_flight_;
   const bool has_request_payload_;
   const bool has_response_payload_;
   grpc_call* call_;
@@ -294,7 +295,7 @@
              grpc_call_start_batch(call->call(), ops, nops, buf));
 }
 
-class Server::AsyncRequest final : public CompletionQueueTag {
+class Server::AsyncRequest GRPC_FINAL : public CompletionQueueTag {
  public:
   AsyncRequest(Server* server, void* registered_method, ServerContext* ctx,
                ::google::protobuf::Message* request,
@@ -305,7 +306,9 @@
         stream_(stream),
         cq_(cq),
         ctx_(ctx),
-        server_(server) {
+        server_(server),
+        call_(nullptr),
+        payload_(nullptr) {
     memset(&array_, 0, sizeof(array_));
     grpc_server_request_registered_call(
         server->server_, registered_method, &call_, &deadline_, &array_,
@@ -319,7 +322,7 @@
     grpc_metadata_array_destroy(&array_);
   }
 
-  bool FinalizeResult(void** tag, bool* status) override {
+  bool FinalizeResult(void** tag, bool* status) GRPC_OVERRIDE {
     *tag = tag_;
     if (*status && request_) {
       if (payload_) {
@@ -354,10 +357,10 @@
   CompletionQueue* const cq_;
   ServerContext* const ctx_;
   Server* const server_;
-  grpc_call* call_ = nullptr;
+  grpc_call* call_;
   gpr_timespec deadline_;
   grpc_metadata_array array_;
-  grpc_byte_buffer* payload_ = nullptr;
+  grpc_byte_buffer* payload_;
 };
 
 void Server::RequestAsyncCall(void* registered_method, ServerContext* context,
diff --git a/src/cpp/server/server_builder.cc b/src/cpp/server/server_builder.cc
index 3c2093c..ae60f3d 100644
--- a/src/cpp/server/server_builder.cc
+++ b/src/cpp/server/server_builder.cc
@@ -41,7 +41,7 @@
 
 namespace grpc {
 
-ServerBuilder::ServerBuilder() {}
+ServerBuilder::ServerBuilder() : thread_pool_(nullptr) {}
 
 void ServerBuilder::RegisterService(SynchronousService* service) {
   services_.push_back(service->service());
diff --git a/src/cpp/server/server_context.cc b/src/cpp/server/server_context.cc
index 1aa18bc..bb3c2d1 100644
--- a/src/cpp/server/server_context.cc
+++ b/src/cpp/server/server_context.cc
@@ -44,10 +44,13 @@
 
 // CompletionOp
 
-class ServerContext::CompletionOp final : public CallOpBuffer {
+class ServerContext::CompletionOp GRPC_FINAL : public CallOpBuffer {
  public:
-  CompletionOp();
-  bool FinalizeResult(void** tag, bool* status) override;
+  // initial refs: one in the server context, one in the cq
+  CompletionOp() : refs_(2), finalized_(false), cancelled_(false) {
+    AddServerRecvClose(&cancelled_);
+  }
+  bool FinalizeResult(void** tag, bool* status) GRPC_OVERRIDE;
 
   bool CheckCancelled(CompletionQueue* cq);
 
@@ -55,13 +58,11 @@
 
  private:
   std::mutex mu_;
-  int refs_ = 2;  // initial refs: one in the server context, one in the cq
-  bool finalized_ = false;
-  bool cancelled_ = false;
+  int refs_;
+  bool finalized_;
+  bool cancelled_;
 };
 
-ServerContext::CompletionOp::CompletionOp() { AddServerRecvClose(&cancelled_); }
-
 void ServerContext::CompletionOp::Unref() {
   std::unique_lock<std::mutex> lock(mu_);
   if (--refs_ == 0) {
@@ -90,11 +91,19 @@
 
 // ServerContext body
 
-ServerContext::ServerContext() {}
+ServerContext::ServerContext()
+    : completion_op_(nullptr),
+      call_(nullptr),
+      cq_(nullptr),
+      sent_initial_metadata_(false) {}
 
 ServerContext::ServerContext(gpr_timespec deadline, grpc_metadata* metadata,
                              size_t metadata_count)
-    : deadline_(Timespec2Timepoint(deadline)) {
+    : completion_op_(nullptr),
+      deadline_(Timespec2Timepoint(deadline)),
+      call_(nullptr),
+      cq_(nullptr),
+      sent_initial_metadata_(false) {
   for (size_t i = 0; i < metadata_count; i++) {
     client_metadata_.insert(std::make_pair(
         grpc::string(metadata[i].key),
diff --git a/src/cpp/server/thread_pool.cc b/src/cpp/server/thread_pool.cc
index fa11ddd..5dc9bcf 100644
--- a/src/cpp/server/thread_pool.cc
+++ b/src/cpp/server/thread_pool.cc
@@ -35,7 +35,7 @@
 
 namespace grpc {
 
-ThreadPool::ThreadPool(int num_threads) {
+ThreadPool::ThreadPool(int num_threads) : shutdown_(false) {
   for (int i = 0; i < num_threads; i++) {
     threads_.push_back(std::thread([this]() {
       for (;;) {
diff --git a/src/cpp/server/thread_pool.h b/src/cpp/server/thread_pool.h
index 283618f..6157e40 100644
--- a/src/cpp/server/thread_pool.h
+++ b/src/cpp/server/thread_pool.h
@@ -31,9 +31,10 @@
  *
  */
 
-#ifndef __GRPCPP_INTERNAL_SERVER_THREAD_POOL_H__
-#define __GRPCPP_INTERNAL_SERVER_THREAD_POOL_H__
+#ifndef GRPC_INTERNAL_CPP_SERVER_THREAD_POOL_H
+#define GRPC_INTERNAL_CPP_SERVER_THREAD_POOL_H
 
+#include <grpc++/config.h>
 #include <grpc++/thread_pool_interface.h>
 
 #include <condition_variable>
@@ -44,21 +45,21 @@
 
 namespace grpc {
 
-class ThreadPool final : public ThreadPoolInterface {
+class ThreadPool GRPC_FINAL : public ThreadPoolInterface {
  public:
   explicit ThreadPool(int num_threads);
   ~ThreadPool();
 
-  void ScheduleCallback(const std::function<void()> &callback) override;
+  void ScheduleCallback(const std::function<void()> &callback) GRPC_OVERRIDE;
 
  private:
   std::mutex mu_;
   std::condition_variable cv_;
-  bool shutdown_ = false;
+  bool shutdown_;
   std::queue<std::function<void()>> callbacks_;
   std::vector<std::thread> threads_;
 };
 
 }  // namespace grpc
 
-#endif  // __GRPCPP_INTERNAL_SERVER_THREAD_POOL_H__
+#endif  // GRPC_INTERNAL_CPP_SERVER_THREAD_POOL_H
diff --git a/src/cpp/util/time.h b/src/cpp/util/time.h
index 9f9e582..1994848 100644
--- a/src/cpp/util/time.h
+++ b/src/cpp/util/time.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPCPP_INTERNAL_UTIL_TIME_H__
-#define __GRPCPP_INTERNAL_UTIL_TIME_H__
+#ifndef GRPC_INTERNAL_CPP_UTIL_TIME_H
+#define GRPC_INTERNAL_CPP_UTIL_TIME_H
 
 #include <chrono>
 
@@ -48,4 +48,4 @@
 
 }  // namespace grpc
 
-#endif  // __GRPCPP_INTERNAL_UTIL_TIME_H__
+#endif  // GRPC_INTERNAL_CPP_UTIL_TIME_H
diff --git a/src/csharp/Grpc.Core.Tests/ClientServerTest.cs b/src/csharp/Grpc.Core.Tests/ClientServerTest.cs
index 7e564a2..39be35c 100644
--- a/src/csharp/Grpc.Core.Tests/ClientServerTest.cs
+++ b/src/csharp/Grpc.Core.Tests/ClientServerTest.cs
@@ -101,15 +101,8 @@
             using (Channel channel = new Channel(host + ":" + port))
             {
                 var call = new Call<string, string>(unaryEchoStringMethod, channel);
-
-                var stopwatch = new Stopwatch();
-                stopwatch.Start();
-                for (int i = 0; i < 1000; i++)
-                {
-                    Calls.BlockingUnaryCall(call, "ABC", default(CancellationToken));
-                }
-                stopwatch.Stop();
-                Console.WriteLine("Elapsed time: " + stopwatch.ElapsedMilliseconds + "ms");
+                BenchmarkUtil.RunBenchmark(100, 1000,
+                                           () => { Calls.BlockingUnaryCall(call, "ABC", default(CancellationToken)); });
             }
 
             server.ShutdownAsync().Wait();
diff --git a/src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj b/src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj
index 687be3c..a365320 100644
--- a/src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj
+++ b/src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj
@@ -41,6 +41,7 @@
     <Compile Include="ServerTest.cs" />
     <Compile Include="GrpcEnvironmentTest.cs" />
     <Compile Include="TimespecTest.cs" />
+    <Compile Include="PInvokeTest.cs" />
   </ItemGroup>
   <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
   <ItemGroup>
diff --git a/src/csharp/Grpc.Core.Tests/GrpcEnvironmentTest.cs b/src/csharp/Grpc.Core.Tests/GrpcEnvironmentTest.cs
index 8d3aef9..596918c 100644
--- a/src/csharp/Grpc.Core.Tests/GrpcEnvironmentTest.cs
+++ b/src/csharp/Grpc.Core.Tests/GrpcEnvironmentTest.cs
@@ -41,14 +41,16 @@
     public class GrpcEnvironmentTest
     {
         [Test]
-        public void InitializeAndShutdownGrpcEnvironment() {
+        public void InitializeAndShutdownGrpcEnvironment()
+        {
             GrpcEnvironment.Initialize();
             Assert.IsNotNull(GrpcEnvironment.ThreadPool.CompletionQueue);
             GrpcEnvironment.Shutdown();
         }
 
         [Test]
-        public void SubsequentInvocations() {
+        public void SubsequentInvocations()
+        {
             GrpcEnvironment.Initialize();
             GrpcEnvironment.Initialize();
             GrpcEnvironment.Shutdown();
@@ -56,7 +58,8 @@
         }
 
         [Test]
-        public void InitializeAfterShutdown() {
+        public void InitializeAfterShutdown()
+        {
             GrpcEnvironment.Initialize();
             var tp1 = GrpcEnvironment.ThreadPool;
             GrpcEnvironment.Shutdown();
diff --git a/src/csharp/Grpc.Core.Tests/PInvokeTest.cs b/src/csharp/Grpc.Core.Tests/PInvokeTest.cs
new file mode 100644
index 0000000..282d521
--- /dev/null
+++ b/src/csharp/Grpc.Core.Tests/PInvokeTest.cs
@@ -0,0 +1,145 @@
+#region Copyright notice and license
+
+// Copyright 2015, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#endregion
+
+using System;
+using System.Diagnostics;
+using System.Threading;
+using System.Threading.Tasks;
+using Grpc.Core;
+using Grpc.Core.Internal;
+using Grpc.Core.Utils;
+using NUnit.Framework;
+using System.Runtime.InteropServices;
+
+namespace Grpc.Core.Tests
+{
+    public class PInvokeTest
+    {
+        int counter;
+
+        [DllImport("grpc_csharp_ext.dll")]
+        static extern GRPCCallError grpcsharp_test_callback([MarshalAs(UnmanagedType.FunctionPtr)] CompletionCallbackDelegate callback);
+
+        [DllImport("grpc_csharp_ext.dll")]
+        static extern IntPtr grpcsharp_test_nop(IntPtr ptr);
+
+        [TestFixtureSetUp]
+        public void Init()
+        {
+            GrpcEnvironment.Initialize();
+        }
+
+        [TestFixtureTearDown]
+        public void Cleanup()
+        {
+            GrpcEnvironment.Shutdown();
+        }
+
+        /// <summary>
+        /// (~1.26us .NET Windows)
+        /// </summary>
+        [Test]
+        public void CompletionQueueCreateDestroyBenchmark()
+        {
+            BenchmarkUtil.RunBenchmark(
+                100000, 1000000,
+                () => {
+                    CompletionQueueSafeHandle cq = CompletionQueueSafeHandle.Create();
+                    cq.Dispose();
+                }
+            );
+        }
+
+
+        /// <summary>
+        /// Approximate results:
+        /// (~80ns Mono Linux)
+        /// (~110ns .NET Windows)
+        /// </summary>
+        [Test]
+        public void NativeCallbackBenchmark()
+        {
+            CompletionCallbackDelegate handler = Handler;
+
+            counter = 0;
+            BenchmarkUtil.RunBenchmark(
+                1000000, 10000000,
+                () => {
+                    grpcsharp_test_callback(handler);
+                }
+            );
+            Assert.AreNotEqual(0, counter);
+        }
+
+        /// <summary>
+        /// Creating a new native-to-managed callback has significant overhead
+        /// compared to using an existing one. We need to be aware of this.
+        /// (~50us on Mono Linux!!!)
+        /// (~1.1us on .NET Windows)
+        /// </summary>
+        [Test]
+        public void NewNativeCallbackBenchmark()
+        {
+            counter = 0;
+            BenchmarkUtil.RunBenchmark(
+                10000, 10000,
+                () => {
+                grpcsharp_test_callback(new CompletionCallbackDelegate(Handler));
+            }
+            );
+            Assert.AreNotEqual(0, counter);
+        }
+
+        /// <summary>
+        /// Tests overhead of a simple PInvoke call.
+        /// (~46ns .NET Windows)
+        /// </summary>
+        [Test]
+        public void NopPInvokeBenchmark()
+        {
+            CompletionCallbackDelegate handler = Handler;
+
+            BenchmarkUtil.RunBenchmark(
+                1000000, 100000000,
+                () => {
+                    grpcsharp_test_nop(IntPtr.Zero);
+                }
+            );
+        }
+
+        private void Handler(GRPCOpError op, IntPtr ptr) {
+            counter ++;
+        }
+    }
+}
+
diff --git a/src/csharp/Grpc.Core/Calls.cs b/src/csharp/Grpc.Core/Calls.cs
index b673326..ee2208e 100644
--- a/src/csharp/Grpc.Core/Calls.cs
+++ b/src/csharp/Grpc.Core/Calls.cs
@@ -47,19 +47,8 @@
     {
         public static TResponse BlockingUnaryCall<TRequest, TResponse>(Call<TRequest, TResponse> call, TRequest req, CancellationToken token)
         {
-            //TODO: implement this in real synchronous style.
-            try {
-                return AsyncUnaryCall(call, req, token).Result;
-            } catch(AggregateException ae) {
-                foreach (var e in ae.InnerExceptions)
-                {
-                    if (e is RpcException)
-                    {
-                        throw e;
-                    }
-                }
-                throw;
-            }
+            var asyncCall = new AsyncCall<TRequest, TResponse>(call.RequestSerializer, call.ResponseDeserializer);
+            return asyncCall.UnaryCall(call.Channel, call.MethodName, req);
         }
 
         public static async Task<TResponse> AsyncUnaryCall<TRequest, TResponse>(Call<TRequest, TResponse> call, TRequest req, CancellationToken token)
diff --git a/src/csharp/Grpc.Core/Grpc.Core.csproj b/src/csharp/Grpc.Core/Grpc.Core.csproj
index 4ad32e1..05d40d4 100644
--- a/src/csharp/Grpc.Core/Grpc.Core.csproj
+++ b/src/csharp/Grpc.Core/Grpc.Core.csproj
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
 <Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <PropertyGroup>
     <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@@ -33,6 +33,7 @@
     <Reference Include="System" />
   </ItemGroup>
   <ItemGroup>
+    <Compile Include="Internal\GrpcLog.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
     <Compile Include="RpcException.cs" />
     <Compile Include="Calls.cs" />
@@ -62,10 +63,20 @@
     <Compile Include="Internal\ClientStreamingInputObserver.cs" />
     <Compile Include="Internal\ServerStreamingOutputObserver.cs" />
     <Compile Include="Internal\BatchContextSafeHandleNotOwned.cs" />
+    <Compile Include="Utils\BenchmarkUtil.cs" />
+    <Compile Include="Utils\ExceptionHelper.cs" />
   </ItemGroup>
+  <Choose>
+    <!-- Under older versions of Monodevelop, Choose is not supported and is just
+         ignored, which gives us the desired effect. -->
+    <When Condition=" '$(OS)' != 'Unix' ">
+      <ItemGroup>
+        <Content Include="..\..\..\vsprojects\vs2013\Debug\grpc_csharp_ext.dll">
+          <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+        </Content>
+      </ItemGroup>
+    </When>
+    <Otherwise />
+  </Choose>
   <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
-  <ItemGroup>
-    <Folder Include="Internal\" />
-    <Folder Include="Utils\" />
-  </ItemGroup>
 </Project>
\ No newline at end of file
diff --git a/src/csharp/Grpc.Core/GrpcEnvironment.cs b/src/csharp/Grpc.Core/GrpcEnvironment.cs
index 0e3a0a5..d3a8da4 100644
--- a/src/csharp/Grpc.Core/GrpcEnvironment.cs
+++ b/src/csharp/Grpc.Core/GrpcEnvironment.cs
@@ -107,6 +107,7 @@
         /// </summary>
         private GrpcEnvironment()
         {
+            GrpcLog.RedirectNativeLogs(Console.Error);
             grpcsharp_init();
             threadPool = new GrpcThreadPool(THREAD_POOL_SIZE);
             threadPool.Start();
diff --git a/src/csharp/Grpc.Core/Internal/AsyncCall.cs b/src/csharp/Grpc.Core/Internal/AsyncCall.cs
index 5e96092..6f37b05 100644
--- a/src/csharp/Grpc.Core/Internal/AsyncCall.cs
+++ b/src/csharp/Grpc.Core/Internal/AsyncCall.cs
@@ -38,6 +38,7 @@
 using System.Threading;
 using System.Threading.Tasks;
 using Grpc.Core.Internal;
+using Grpc.Core.Utils;
 
 namespace Grpc.Core.Internal
 {
@@ -112,6 +113,36 @@
             InitializeInternal(call, true);
         }
 
+        public TRead UnaryCall(Channel channel, String methodName, TWrite msg)
+        {
+            using(CompletionQueueSafeHandle cq = CompletionQueueSafeHandle.Create())
+            {
+                // TODO: handle serialization error...
+                byte[] payload = serializer(msg);
+
+                unaryResponseTcs = new TaskCompletionSource<TRead>();
+
+                lock (myLock)
+                {
+                    Initialize(channel, cq, methodName);
+                    started = true;
+                    halfcloseRequested = true;
+                    readingDone = true;
+                }
+                call.BlockingUnary(cq, payload, unaryResponseHandler);
+
+                try
+                {
+                    // Once the blocking call returns, the result should be available synchronously.
+                    return unaryResponseTcs.Task.Result;
+                }
+                catch (AggregateException ae)
+                {
+                    throw ExceptionHelper.UnwrapRpcException(ae);
+                }
+            }
+        }
+
         public Task<TRead> UnaryCallAsync(TWrite msg)
         {
             lock (myLock)
@@ -150,6 +181,7 @@
             {
                 started = true;
                 halfcloseRequested = true;
+                halfclosed = true;  // halfclose not confirmed yet, but it will be once finishedHandler is called.
         
                 this.readObserver = readObserver;
 
@@ -513,6 +545,8 @@
                     }
                     observer = readObserver;
                     status = finishedStatus;
+
+                    ReleaseResourcesIfPossible();
                 }
 
                 // TODO: wrap deserialization...
diff --git a/src/csharp/Grpc.Core/Internal/CallSafeHandle.cs b/src/csharp/Grpc.Core/Internal/CallSafeHandle.cs
index 659a383..1c0bc98 100644
--- a/src/csharp/Grpc.Core/Internal/CallSafeHandle.cs
+++ b/src/csharp/Grpc.Core/Internal/CallSafeHandle.cs
@@ -63,6 +63,11 @@
                                                                         byte[] send_buffer, UIntPtr send_buffer_len);
 
         [DllImport("grpc_csharp_ext.dll")]
+        static extern void grpcsharp_call_blocking_unary(CallSafeHandle call, CompletionQueueSafeHandle dedicatedCq,
+                                                               [MarshalAs(UnmanagedType.FunctionPtr)] CompletionCallbackDelegate callback,
+                                                               byte[] send_buffer, UIntPtr send_buffer_len);
+
+        [DllImport("grpc_csharp_ext.dll")]
         static extern GRPCCallError grpcsharp_call_start_client_streaming(CallSafeHandle call,
                                                                       [MarshalAs(UnmanagedType.FunctionPtr)] CompletionCallbackDelegate callback);
 
@@ -113,6 +118,11 @@
             AssertCallOk(grpcsharp_call_start_unary(this, callback, payload, new UIntPtr((ulong) payload.Length)));
         }
 
+        public void BlockingUnary(CompletionQueueSafeHandle dedicatedCq, byte[] payload, CompletionCallbackDelegate callback)
+        {
+            grpcsharp_call_blocking_unary(this, dedicatedCq, callback, payload, new UIntPtr((ulong) payload.Length));
+        }
+
         public void StartClientStreaming(CompletionCallbackDelegate callback)
         {
             AssertCallOk(grpcsharp_call_start_client_streaming(this, callback));
diff --git a/src/csharp/Grpc.Core/Internal/GrpcLog.cs b/src/csharp/Grpc.Core/Internal/GrpcLog.cs
new file mode 100644
index 0000000..98768d0
--- /dev/null
+++ b/src/csharp/Grpc.Core/Internal/GrpcLog.cs
@@ -0,0 +1,94 @@
+#region Copyright notice and license
+
+// Copyright 2015, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#endregion
+
+using System;
+using System.Collections.Concurrent;
+using System.Diagnostics;
+using System.IO;
+using System.Runtime.InteropServices;
+using System.Threading;
+
+namespace Grpc.Core.Internal
+{
+    internal delegate void GprLogDelegate(IntPtr fileStringPtr, Int32 line, UInt64 threadId, IntPtr severityStringPtr, IntPtr msgPtr);
+
+    /// <summary>
+    /// Logs from gRPC C core library can get lost if your application is not a console app.
+    /// This class allows redirection of logs to arbitrary destination.
+    /// </summary>
+    internal static class GrpcLog
+    {
+        static object staticLock = new object();
+        static GprLogDelegate writeCallback;
+        static TextWriter dest;
+
+        [DllImport("grpc_csharp_ext.dll")]
+        static extern void grpcsharp_redirect_log(GprLogDelegate callback);
+
+        /// <summary>
+        /// Sets text writer as destination for logs from native gRPC C core library.
+        /// Only first invocation has effect.
+        /// </summary>
+        /// <param name="textWriter"></param>
+        public static void RedirectNativeLogs(TextWriter textWriter)
+        {
+            lock (staticLock)
+            {
+                if (writeCallback == null)
+                {
+                    writeCallback = new GprLogDelegate(HandleWrite);
+                    dest = textWriter;
+                    grpcsharp_redirect_log(writeCallback);    
+                }
+            }
+        }
+
+        private static void HandleWrite(IntPtr fileStringPtr, Int32 line, UInt64 threadId, IntPtr severityStringPtr, IntPtr msgPtr)
+        {
+            try
+            {
+                // TODO: DateTime format used here is different than in C core.
+                dest.WriteLine(string.Format("{0}{1} {2} {3}:{4}: {5}", 
+                    Marshal.PtrToStringAnsi(severityStringPtr), DateTime.Now,  
+                    threadId,
+                    Marshal.PtrToStringAnsi(fileStringPtr), 
+                    line, 
+                    Marshal.PtrToStringAnsi(msgPtr)));
+            }
+            catch (Exception e)
+            {
+                Console.WriteLine("Caught exception in native callback " + e);
+            }
+        }
+    }
+}
diff --git a/src/csharp/Grpc.Core/RpcException.cs b/src/csharp/Grpc.Core/RpcException.cs
index 5a9d003..e1cf64c 100644
--- a/src/csharp/Grpc.Core/RpcException.cs
+++ b/src/csharp/Grpc.Core/RpcException.cs
@@ -49,7 +49,8 @@
             this.status = status;
         }
 
-        public Status Status {
+        public Status Status
+        {
             get
             {
                 return status;
diff --git a/src/csharp/Grpc.Core/Server.cs b/src/csharp/Grpc.Core/Server.cs
index 002592a..152cc21 100644
--- a/src/csharp/Grpc.Core/Server.cs
+++ b/src/csharp/Grpc.Core/Server.cs
@@ -124,6 +124,17 @@
             handle.Dispose();
         }
 
+        /// <summary>
+        /// To allow awaiting termination of the server.
+        /// </summary>
+        public Task ShutdownTask
+        {
+            get
+            {
+                return shutdownTcs.Task;
+            }
+        }
+
         public void Kill() {
             handle.Dispose();
         }
diff --git a/src/csharp/Grpc.Core/ServerCallHandler.cs b/src/csharp/Grpc.Core/ServerCallHandler.cs
index 1296947..289f97a 100644
--- a/src/csharp/Grpc.Core/ServerCallHandler.cs
+++ b/src/csharp/Grpc.Core/ServerCallHandler.cs
@@ -111,6 +111,8 @@
 
             var finishedTask = asyncCall.ServerSideStreamingRequestCallAsync(new NullObserver<byte[]>());
 
+            // TODO: this makes the call finish before all reads can be done which causes trouble
+            // in AsyncCall.HandleReadFinished callback. Revisit this.
             asyncCall.SendStatusFromServerAsync(new Status(StatusCode.Unimplemented, "No such method.")).Wait();
 
             finishedTask.Wait();
diff --git a/src/csharp/Grpc.Core/Utils/BenchmarkUtil.cs b/src/csharp/Grpc.Core/Utils/BenchmarkUtil.cs
new file mode 100644
index 0000000..3f0dae8
--- /dev/null
+++ b/src/csharp/Grpc.Core/Utils/BenchmarkUtil.cs
@@ -0,0 +1,68 @@
+#region Copyright notice and license
+
+// Copyright 2015, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#endregion
+
+using System;
+using System.Threading.Tasks;
+using System.Collections.Generic;
+using System.Collections.Concurrent;
+using System.Diagnostics;
+
+namespace Grpc.Core.Utils
+{
+    public static class BenchmarkUtil
+    {
+        /// <summary>
+        /// Runs a simple benchmark preceded by warmup phase.
+        /// </summary>
+        public static void RunBenchmark(int warmupIterations, int benchmarkIterations, Action action)
+        {
+            Console.WriteLine("Warmup iterations: " + warmupIterations);
+            for (int i = 0; i < warmupIterations; i++)
+            {
+                action();
+            }
+
+            Console.WriteLine("Benchmark iterations: " + benchmarkIterations);
+            var stopwatch = new Stopwatch();
+            stopwatch.Start();
+            for (int i = 0; i < benchmarkIterations; i++)
+            {
+                action();
+            }
+            stopwatch.Stop();
+            Console.WriteLine("Elapsed time: " + stopwatch.ElapsedMilliseconds + "ms");
+            Console.WriteLine("Ops per second: " + (int) ((double) benchmarkIterations  * 1000 / stopwatch.ElapsedMilliseconds));
+        }
+    }
+}
+
diff --git a/src/csharp/Grpc.Core/Utils/ExceptionHelper.cs b/src/csharp/Grpc.Core/Utils/ExceptionHelper.cs
new file mode 100644
index 0000000..18702e1
--- /dev/null
+++ b/src/csharp/Grpc.Core/Utils/ExceptionHelper.cs
@@ -0,0 +1,57 @@
+#region Copyright notice and license
+
+// Copyright 2015, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#endregion
+
+using System;
+
+namespace Grpc.Core.Utils
+{
+    public static class ExceptionHelper
+    {
+        /// <summary>
+        /// If inner exceptions contain RpcException, rethrows it.
+        /// Otherwise, rethrows the original aggregate exception.
+        /// Always throws, the exception return type is here only to make the.
+        /// </summary>
+        public static Exception UnwrapRpcException(AggregateException ae) {
+            foreach (var e in ae.InnerExceptions)
+            {
+                if (e is RpcException)
+                {
+                    throw e;
+                }
+            }
+            throw ae;
+        }
+    }
+}
+
diff --git a/src/csharp/Grpc.Examples/MathServiceImpl.cs b/src/csharp/Grpc.Examples/MathServiceImpl.cs
index 462fab4..76a08ce 100644
--- a/src/csharp/Grpc.Examples/MathServiceImpl.cs
+++ b/src/csharp/Grpc.Examples/MathServiceImpl.cs
@@ -127,8 +127,7 @@
 
             public void OnCompleted()
             {
-                Task.Factory.StartNew(() =>
-                    responseObserver.OnCompleted());
+                responseObserver.OnCompleted();
             }
 
             public void OnError(Exception error)
@@ -138,13 +137,7 @@
 
             public void OnNext(DivArgs value)
             {
-                // TODO: currently we need this indirection because
-                // responseObserver waits for write to finish, this
-                // callback is called from grpc threadpool which
-                // currently only has one thread.
-                // Same story for OnCompleted().
-                Task.Factory.StartNew(() =>
-                responseObserver.OnNext(DivInternal(value)));
+                responseObserver.OnNext(DivInternal(value));
             }
         }
     }
diff --git a/src/csharp/Grpc.IntegrationTesting.Client/.gitignore b/src/csharp/Grpc.IntegrationTesting.Client/.gitignore
new file mode 100644
index 0000000..a382af2
--- /dev/null
+++ b/src/csharp/Grpc.IntegrationTesting.Client/.gitignore
@@ -0,0 +1,3 @@
+bin
+obj
+
diff --git a/src/csharp/Grpc.IntegrationTesting.Client/Grpc.IntegrationTesting.Client.csproj b/src/csharp/Grpc.IntegrationTesting.Client/Grpc.IntegrationTesting.Client.csproj
new file mode 100644
index 0000000..b1a4a81
--- /dev/null
+++ b/src/csharp/Grpc.IntegrationTesting.Client/Grpc.IntegrationTesting.Client.csproj
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">x86</Platform>
+    <ProductVersion>10.0.0</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{3D166931-BA2D-416E-95A3-D36E8F6E90B9}</ProjectGuid>
+    <OutputType>Exe</OutputType>
+    <RootNamespace>Grpc.IntegrationTesting.Client</RootNamespace>
+    <AssemblyName>Grpc.IntegrationTesting.Client</AssemblyName>
+    <StartupObject>Grpc.IntegrationTesting.Client.Program</StartupObject>
+    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug</OutputPath>
+    <DefineConstants>DEBUG;</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <Externalconsole>true</Externalconsole>
+    <PlatformTarget>x86</PlatformTarget>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
+    <DebugType>full</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release</OutputPath>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <Externalconsole>true</Externalconsole>
+    <PlatformTarget>x86</PlatformTarget>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Program.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+  </ItemGroup>
+  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+  <ItemGroup>
+    <ProjectReference Include="..\Grpc.IntegrationTesting\Grpc.IntegrationTesting.csproj">
+      <Project>{C61154BA-DD4A-4838-8420-0162A28925E0}</Project>
+      <Name>Grpc.IntegrationTesting</Name>
+    </ProjectReference>
+  </ItemGroup>
+</Project>
\ No newline at end of file
diff --git a/src/csharp/Grpc.IntegrationTesting.Client/Program.cs b/src/csharp/Grpc.IntegrationTesting.Client/Program.cs
new file mode 100644
index 0000000..2e1c9aa
--- /dev/null
+++ b/src/csharp/Grpc.IntegrationTesting.Client/Program.cs
@@ -0,0 +1,46 @@
+#region Copyright notice and license
+
+// Copyright 2015, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#endregion
+
+using System;
+using Grpc.IntegrationTesting;
+
+namespace Grpc.IntegrationTesting.Client
+{
+    class Program
+    {
+        public static void Main(string[] args)
+        {
+            InteropClient.Run(args);
+        }
+    }
+}
diff --git a/src/csharp/Grpc.IntegrationTesting.Client/Properties/AssemblyInfo.cs b/src/csharp/Grpc.IntegrationTesting.Client/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..d1f9e85
--- /dev/null
+++ b/src/csharp/Grpc.IntegrationTesting.Client/Properties/AssemblyInfo.cs
@@ -0,0 +1,22 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+
+// Information about this assembly is defined by the following attributes. 
+// Change them to the values specific to your project.
+[assembly: AssemblyTitle("Grpc.IntegrationTesting.Client")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("")]
+[assembly: AssemblyCopyright("Google Inc.  All rights reserved.")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
+// The form "{Major}.{Minor}.*" will automatically update the build and revision,
+// and "{Major}.{Minor}.{Build}.*" will update just the revision.
+[assembly: AssemblyVersion("0.1.*")]
+// The following attributes are used to specify the signing key for the assembly, 
+// if desired. See the Mono documentation for more information about signing.
+//[assembly: AssemblyDelaySign(false)]
+//[assembly: AssemblyKeyFile("")]
+
diff --git a/src/csharp/Grpc.IntegrationTesting.Server/.gitignore b/src/csharp/Grpc.IntegrationTesting.Server/.gitignore
new file mode 100644
index 0000000..a382af2
--- /dev/null
+++ b/src/csharp/Grpc.IntegrationTesting.Server/.gitignore
@@ -0,0 +1,3 @@
+bin
+obj
+
diff --git a/src/csharp/Grpc.IntegrationTesting.Server/Grpc.IntegrationTesting.Server.csproj b/src/csharp/Grpc.IntegrationTesting.Server/Grpc.IntegrationTesting.Server.csproj
new file mode 100644
index 0000000..73c9f2d
--- /dev/null
+++ b/src/csharp/Grpc.IntegrationTesting.Server/Grpc.IntegrationTesting.Server.csproj
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">x86</Platform>
+    <ProductVersion>10.0.0</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{A654F3B8-E859-4E6A-B30D-227527DBEF0D}</ProjectGuid>
+    <OutputType>Exe</OutputType>
+    <RootNamespace>Grpc.IntegrationTesting.Server</RootNamespace>
+    <AssemblyName>Grpc.IntegrationTesting.Server</AssemblyName>
+    <StartupObject>Grpc.IntegrationTesting.Server.Program</StartupObject>
+    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug</OutputPath>
+    <DefineConstants>DEBUG;</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <Externalconsole>true</Externalconsole>
+    <PlatformTarget>x86</PlatformTarget>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
+    <DebugType>full</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release</OutputPath>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <Externalconsole>true</Externalconsole>
+    <PlatformTarget>x86</PlatformTarget>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Program.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+  </ItemGroup>
+  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+  <ItemGroup>
+    <ProjectReference Include="..\Grpc.IntegrationTesting\Grpc.IntegrationTesting.csproj">
+      <Project>{C61154BA-DD4A-4838-8420-0162A28925E0}</Project>
+      <Name>Grpc.IntegrationTesting</Name>
+    </ProjectReference>
+  </ItemGroup>
+</Project>
\ No newline at end of file
diff --git a/src/csharp/Grpc.IntegrationTesting.Server/Program.cs b/src/csharp/Grpc.IntegrationTesting.Server/Program.cs
new file mode 100644
index 0000000..01bcc6e
--- /dev/null
+++ b/src/csharp/Grpc.IntegrationTesting.Server/Program.cs
@@ -0,0 +1,45 @@
+#region Copyright notice and license
+
+// Copyright 2015, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#endregion
+
+using System;
+
+namespace Grpc.IntegrationTesting.Server
+{
+    class Program
+    {
+        public static void Main(string[] args)
+        {
+            InteropServer.Run(args);
+        }
+    }
+}
diff --git a/src/csharp/Grpc.IntegrationTesting.Server/Properties/AssemblyInfo.cs b/src/csharp/Grpc.IntegrationTesting.Server/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..4ef93f3
--- /dev/null
+++ b/src/csharp/Grpc.IntegrationTesting.Server/Properties/AssemblyInfo.cs
@@ -0,0 +1,22 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+
+// Information about this assembly is defined by the following attributes. 
+// Change them to the values specific to your project.
+[assembly: AssemblyTitle("Grpc.IntegrationTesting.Server")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("")]
+[assembly: AssemblyCopyright("Google Inc.  All rights reserved.")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
+// The form "{Major}.{Minor}.*" will automatically update the build and revision,
+// and "{Major}.{Minor}.{Build}.*" will update just the revision.
+[assembly: AssemblyVersion("0.1.*")]
+// The following attributes are used to specify the signing key for the assembly, 
+// if desired. See the Mono documentation for more information about signing.
+//[assembly: AssemblyDelaySign(false)]
+//[assembly: AssemblyKeyFile("")]
+
diff --git a/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj b/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj
index 9b46a64..6d6aaf5 100644
--- a/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj
+++ b/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj
@@ -6,10 +6,9 @@
     <ProductVersion>10.0.0</ProductVersion>
     <SchemaVersion>2.0</SchemaVersion>
     <ProjectGuid>{C61154BA-DD4A-4838-8420-0162A28925E0}</ProjectGuid>
-    <OutputType>Exe</OutputType>
+    <OutputType>Library</OutputType>
     <RootNamespace>Grpc.IntegrationTesting</RootNamespace>
     <AssemblyName>Grpc.IntegrationTesting</AssemblyName>
-    <StartupObject>Grpc.IntegrationTesting.Client</StartupObject>
     <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
@@ -43,10 +42,13 @@
   </ItemGroup>
   <ItemGroup>
     <Compile Include="Properties\AssemblyInfo.cs" />
-    <Compile Include="Client.cs" />
     <Compile Include="TestServiceGrpc.cs" />
     <Compile Include="Empty.cs" />
     <Compile Include="Messages.cs" />
+    <Compile Include="InteropClientServerTest.cs" />
+    <Compile Include="TestServiceImpl.cs" />
+    <Compile Include="InteropServer.cs" />
+    <Compile Include="InteropClient.cs" />
   </ItemGroup>
   <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
   <ItemGroup>
diff --git a/src/csharp/Grpc.IntegrationTesting/Client.cs b/src/csharp/Grpc.IntegrationTesting/InteropClient.cs
similarity index 89%
rename from src/csharp/Grpc.IntegrationTesting/Client.cs
rename to src/csharp/Grpc.IntegrationTesting/InteropClient.cs
index bb650a1..a7a3c63 100644
--- a/src/csharp/Grpc.IntegrationTesting/Client.cs
+++ b/src/csharp/Grpc.IntegrationTesting/InteropClient.cs
@@ -33,7 +33,9 @@
 
 using System;
 using System.Collections.Generic;
+using System.Diagnostics;
 using System.Text.RegularExpressions;
+using System.Threading.Tasks;
 using Google.ProtocolBuffers;
 using Grpc.Core;
 using Grpc.Core.Utils;
@@ -42,7 +44,7 @@
 
 namespace Grpc.IntegrationTesting
 {
-    class Client
+    public class InteropClient
     {
         private class ClientOptions
         {
@@ -57,12 +59,12 @@
 
         ClientOptions options;
 
-        private Client(ClientOptions options)
+        private InteropClient(ClientOptions options)
         {
             this.options = options;
         }
 
-        public static void Main(string[] args)
+        public static void Run(string[] args)
         {
             Console.WriteLine("gRPC C# interop testing client");
             ClientOptions options = ParseArguments(args);
@@ -87,7 +89,7 @@
                 Environment.Exit(1);
             }
 
-            var interopClient = new Client(options);
+            var interopClient = new InteropClient(options);
             interopClient.Run();
         }
 
@@ -128,12 +130,15 @@
                 case "empty_stream":
                     RunEmptyStream(client);
                     break;
+                case "benchmark_empty_unary":
+                    RunBenchmarkEmptyUnary(client);
+                    break;
                 default:
                     throw new ArgumentException("Unknown test case " + testCase);
             }
         }
 
-        private void RunEmptyUnary(TestServiceGrpc.ITestServiceClient client)
+        public static void RunEmptyUnary(TestServiceGrpc.ITestServiceClient client)
         {
             Console.WriteLine("running empty_unary");
             var response = client.EmptyCall(Empty.DefaultInstance);
@@ -141,7 +146,7 @@
             Console.WriteLine("Passed!");
         }
 
-        private void RunLargeUnary(TestServiceGrpc.ITestServiceClient client)
+        public static void RunLargeUnary(TestServiceGrpc.ITestServiceClient client)
         {
             Console.WriteLine("running large_unary");
             var request = SimpleRequest.CreateBuilder()
@@ -157,7 +162,7 @@
             Console.WriteLine("Passed!");
         }
 
-        private void RunClientStreaming(TestServiceGrpc.ITestServiceClient client)
+        public static void RunClientStreaming(TestServiceGrpc.ITestServiceClient client)
         {
             Console.WriteLine("running client_streaming");
 
@@ -176,7 +181,7 @@
             Console.WriteLine("Passed!");
         }
 
-        private void RunServerStreaming(TestServiceGrpc.ITestServiceClient client)
+        public static void RunServerStreaming(TestServiceGrpc.ITestServiceClient client)
         {
             Console.WriteLine("running server_streaming");
 
@@ -201,7 +206,7 @@
             Console.WriteLine("Passed!");
         }
 
-        private void RunPingPong(TestServiceGrpc.ITestServiceClient client)
+        public static void RunPingPong(TestServiceGrpc.ITestServiceClient client)
         {
             Console.WriteLine("running ping_pong");
 
@@ -230,7 +235,7 @@
 
             inputs.OnNext(StreamingOutputCallRequest.CreateBuilder()
                           .SetResponseType(PayloadType.COMPRESSABLE)
-                          .AddResponseParameters(ResponseParameters.CreateBuilder().SetSize(2635))
+                          .AddResponseParameters(ResponseParameters.CreateBuilder().SetSize(2653))
                           .SetPayload(CreateZerosPayload(1828)).Build());
 
             response = recorder.Queue.Take();
@@ -247,13 +252,15 @@
             Assert.AreEqual(PayloadType.COMPRESSABLE, response.Payload.Type);
             Assert.AreEqual(58979, response.Payload.Body.Length);
 
+            inputs.OnCompleted();
+
             recorder.Finished.Wait();
             Assert.AreEqual(0, recorder.Queue.Count);
 
             Console.WriteLine("Passed!");
         }
 
-        private void RunEmptyStream(TestServiceGrpc.ITestServiceClient client)
+        public static void RunEmptyStream(TestServiceGrpc.ITestServiceClient client)
         {
             Console.WriteLine("running empty_stream");
 
@@ -267,8 +274,14 @@
             Console.WriteLine("Passed!");
         }
 
+        // This is not an official interop test, but it's useful.
+        public static void RunBenchmarkEmptyUnary(TestServiceGrpc.ITestServiceClient client)
+        {
+            BenchmarkUtil.RunBenchmark(10000, 10000,
+                                       () => { client.EmptyCall(Empty.DefaultInstance);});
+        }
 
-        private Payload CreateZerosPayload(int size) {
+        private static Payload CreateZerosPayload(int size) {
             return Payload.CreateBuilder().SetBody(ByteString.CopyFrom(new byte[size])).Build();
         }
 
diff --git a/src/csharp/Grpc.IntegrationTesting/InteropClientServerTest.cs b/src/csharp/Grpc.IntegrationTesting/InteropClientServerTest.cs
new file mode 100644
index 0000000..4bb0b9e
--- /dev/null
+++ b/src/csharp/Grpc.IntegrationTesting/InteropClientServerTest.cs
@@ -0,0 +1,119 @@
+#region Copyright notice and license
+
+// Copyright 2015, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Threading;
+using System.Threading.Tasks;
+using Grpc.Core;
+using Grpc.Core.Utils;
+using NUnit.Framework;
+using grpc.testing;
+
+namespace Grpc.IntegrationTesting
+{
+    /// <summary>
+    /// Runs interop tests in-process.
+    /// </summary>
+    public class InteropClientServerTest
+    {
+        string host = "localhost";
+        Server server;
+        Channel channel;
+        TestServiceGrpc.ITestServiceClient client;
+
+        [TestFixtureSetUp]
+        public void Init()
+        {
+            GrpcEnvironment.Initialize();
+
+            server = new Server();
+            server.AddServiceDefinition(TestServiceGrpc.BindService(new TestServiceImpl()));
+            int port = server.AddPort(host + ":0");
+            server.Start();
+            channel = new Channel(host + ":" + port);
+            client = TestServiceGrpc.NewStub(channel);
+        }
+
+        [TestFixtureTearDown]
+        public void Cleanup()
+        {
+            channel.Dispose();
+
+            server.ShutdownAsync().Wait();
+            GrpcEnvironment.Shutdown();
+        }
+
+        [Test]
+        public void EmptyUnary()
+        {
+            InteropClient.RunEmptyUnary(client);
+        }
+
+        [Test]
+        public void LargeUnary()
+        {
+            InteropClient.RunEmptyUnary(client);
+        }
+
+        [Test]
+        public void ClientStreaming()
+        {
+            InteropClient.RunClientStreaming(client);
+        }
+
+        [Test]
+        public void ServerStreaming()
+        {
+            InteropClient.RunServerStreaming(client);
+        }
+
+        [Test]
+        public void PingPong()
+        {
+            InteropClient.RunPingPong(client);
+        }
+
+        [Test]
+        public void EmptyStream()
+        {
+            InteropClient.RunEmptyStream(client);
+        }
+
+        // TODO: add cancel_after_begin
+
+        // TODO: add cancel_after_first_response
+
+    }
+}
+
diff --git a/src/csharp/Grpc.IntegrationTesting/InteropServer.cs b/src/csharp/Grpc.IntegrationTesting/InteropServer.cs
new file mode 100644
index 0000000..a25d3b3
--- /dev/null
+++ b/src/csharp/Grpc.IntegrationTesting/InteropServer.cs
@@ -0,0 +1,140 @@
+#region Copyright notice and license
+
+// Copyright 2015, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Text.RegularExpressions;
+using System.Threading.Tasks;
+using Google.ProtocolBuffers;
+using Grpc.Core;
+using Grpc.Core.Utils;
+using NUnit.Framework;
+using grpc.testing;
+
+namespace Grpc.IntegrationTesting
+{
+    public class InteropServer
+    {
+        private class ServerOptions
+        {
+            public bool help;
+            public int? port;
+            public bool useTls;
+        }
+
+        ServerOptions options;
+
+        private InteropServer(ServerOptions options)
+        {
+            this.options = options;
+        }
+
+        public static void Run(string[] args)
+        {
+            Console.WriteLine("gRPC C# interop testing server");
+            ServerOptions options = ParseArguments(args);
+
+            if (!options.port.HasValue)
+            {
+                Console.WriteLine("Missing required argument.");
+                Console.WriteLine();
+                options.help = true;
+            }
+
+            if (options.help)
+            {
+                Console.WriteLine("Usage:");
+                Console.WriteLine("  --port=PORT");
+                Console.WriteLine("  --use_tls=BOOLEAN");
+                Console.WriteLine();
+                Environment.Exit(1);
+            }
+
+            var interopServer = new InteropServer(options);
+            interopServer.Run();
+        }
+
+        private void Run()
+        {
+            GrpcEnvironment.Initialize();
+
+            var server = new Server();
+            server.AddServiceDefinition(TestServiceGrpc.BindService(new TestServiceImpl()));
+
+            string addr = "0.0.0.0:" + options.port;
+            server.AddPort(addr);
+            Console.WriteLine("Running server on " + addr);
+            server.Start();
+
+            server.ShutdownTask.Wait();
+
+            GrpcEnvironment.Shutdown();
+        }
+
+        private static ServerOptions ParseArguments(string[] args)
+        {
+            var options = new ServerOptions();
+            foreach(string arg in args)
+            {
+                ParseArgument(arg, options);
+                if (options.help)
+                {
+                    break;
+                }
+            }
+            return options;
+        }
+
+        private static void ParseArgument(string arg, ServerOptions options)
+        {
+            Match match;
+            match = Regex.Match(arg, "--port=(.*)");
+            if (match.Success)
+            {
+                options.port = int.Parse(match.Groups[1].Value.Trim());
+                return;
+            }
+
+            match = Regex.Match(arg, "--use_tls=(.*)");
+            if (match.Success)
+            {
+                options.useTls = bool.Parse(match.Groups[1].Value.Trim());
+                return;
+            }
+
+            Console.WriteLine(string.Format("Unrecognized argument \"{0}\"", arg));
+            options.help = true;
+        }
+    }
+}
diff --git a/src/csharp/Grpc.IntegrationTesting/TestServiceImpl.cs b/src/csharp/Grpc.IntegrationTesting/TestServiceImpl.cs
new file mode 100644
index 0000000..176843b
--- /dev/null
+++ b/src/csharp/Grpc.IntegrationTesting/TestServiceImpl.cs
@@ -0,0 +1,140 @@
+#region Copyright notice and license
+
+// Copyright 2015, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Threading;
+using System.Threading.Tasks;
+using Google.ProtocolBuffers;
+using Grpc.Core.Utils;
+
+namespace grpc.testing
+{
+    /// <summary>
+    /// Implementation of TestService server
+    /// </summary>
+    public class TestServiceImpl : TestServiceGrpc.ITestService
+    {
+        public void EmptyCall(Empty request, IObserver<Empty> responseObserver)
+        {
+            responseObserver.OnNext(Empty.DefaultInstance);
+            responseObserver.OnCompleted();
+        }
+
+        public void UnaryCall(SimpleRequest request, IObserver<SimpleResponse> responseObserver)
+        {
+            var response = SimpleResponse.CreateBuilder()
+                .SetPayload(CreateZerosPayload(request.ResponseSize)).Build();
+            //TODO: check we support ReponseType
+            responseObserver.OnNext(response);
+            responseObserver.OnCompleted();
+        }
+
+        public void StreamingOutputCall(StreamingOutputCallRequest request, IObserver<StreamingOutputCallResponse> responseObserver)
+        {
+            foreach(var responseParam in request.ResponseParametersList)
+            {
+                var response = StreamingOutputCallResponse.CreateBuilder()
+                    .SetPayload(CreateZerosPayload(responseParam.Size)).Build();
+                responseObserver.OnNext(response);
+            }
+            responseObserver.OnCompleted();
+        }
+
+        public IObserver<StreamingInputCallRequest> StreamingInputCall(IObserver<StreamingInputCallResponse> responseObserver)
+        {
+            var recorder = new RecordingObserver<StreamingInputCallRequest>();
+            Task.Run(() => {
+                int sum = 0;
+                foreach(var req in recorder.ToList().Result)
+                {
+                    sum += req.Payload.Body.Length;
+                }
+                var response = StreamingInputCallResponse.CreateBuilder()
+                    .SetAggregatedPayloadSize(sum).Build();
+                responseObserver.OnNext(response);
+                responseObserver.OnCompleted();
+            });
+            return recorder;
+        }
+
+        public IObserver<StreamingOutputCallRequest> FullDuplexCall(IObserver<StreamingOutputCallResponse> responseObserver)
+        {
+            return new FullDuplexObserver(responseObserver);
+        }
+
+        public IObserver<StreamingOutputCallRequest> HalfDuplexCall(IObserver<StreamingOutputCallResponse> responseObserver)
+        {
+            throw new NotImplementedException();
+        }
+
+        private class FullDuplexObserver : IObserver<StreamingOutputCallRequest> {
+
+            readonly IObserver<StreamingOutputCallResponse> responseObserver;
+
+            public FullDuplexObserver(IObserver<StreamingOutputCallResponse> responseObserver)
+            {
+                this.responseObserver = responseObserver;
+            }
+
+            public void OnCompleted()
+            {
+                responseObserver.OnCompleted();
+            }
+
+            public void OnError(Exception error)
+            {
+                throw new NotImplementedException();
+            }
+
+            public void OnNext(StreamingOutputCallRequest value)
+            {
+                // TODO: this is not in order!!!
+                //Task.Factory.StartNew(() => {
+
+                    foreach(var responseParam in value.ResponseParametersList)
+                    {
+                        var response = StreamingOutputCallResponse.CreateBuilder()
+                            .SetPayload(CreateZerosPayload(responseParam.Size)).Build();
+                        responseObserver.OnNext(response);
+                    }
+                //});
+            }
+        }
+
+        private static Payload CreateZerosPayload(int size) {
+            return Payload.CreateBuilder().SetBody(ByteString.CopyFrom(new byte[size])).Build();
+        }
+    }
+}
+
diff --git a/src/csharp/Grpc.sln b/src/csharp/Grpc.sln
index a544eb1..2e6d288 100644
--- a/src/csharp/Grpc.sln
+++ b/src/csharp/Grpc.sln
@@ -13,6 +13,10 @@
 EndProject

 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Grpc.IntegrationTesting", "Grpc.IntegrationTesting\Grpc.IntegrationTesting.csproj", "{C61154BA-DD4A-4838-8420-0162A28925E0}"

 EndProject

+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Grpc.IntegrationTesting.Client", "Grpc.IntegrationTesting.Client\Grpc.IntegrationTesting.Client.csproj", "{3D166931-BA2D-416E-95A3-D36E8F6E90B9}"

+EndProject

+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Grpc.IntegrationTesting.Server", "Grpc.IntegrationTesting.Server\Grpc.IntegrationTesting.Server.csproj", "{A654F3B8-E859-4E6A-B30D-227527DBEF0D}"

+EndProject

 Global

 	GlobalSection(SolutionConfigurationPlatforms) = preSolution

 		Debug|x86 = Debug|x86

@@ -23,6 +27,10 @@
 		{143B1C29-C442-4BE0-BF3F-A8F92288AC9F}.Debug|x86.Build.0 = Debug|Any CPU

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

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

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

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

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

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

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

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

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

@@ -35,6 +43,10 @@
 		{86EC5CB4-4EA2-40A2-8057-86542A0353BB}.Debug|x86.Build.0 = Debug|Any CPU

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

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

+		{A654F3B8-E859-4E6A-B30D-227527DBEF0D}.Debug|x86.ActiveCfg = Debug|x86

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

+		{A654F3B8-E859-4E6A-B30D-227527DBEF0D}.Release|x86.ActiveCfg = Release|x86

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

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

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

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

diff --git a/src/csharp/README.md b/src/csharp/README.md
index 55739a1..21aab52 100755
--- a/src/csharp/README.md
+++ b/src/csharp/README.md
@@ -9,7 +9,7 @@
 **This gRPC C# implementation is work-in-progress and is not expected to work yet.**
 
 - The implementation is a wrapper around gRPC C core library
-- Code only runs under mono currently, building gGRPC C core library under Windows
+- Code only runs under mono currently, building gRPC C core library under Windows
   is in progress.
 - It is very possible that some parts of the code will be heavily refactored or
   completely rewritten.
diff --git a/src/csharp/ext/grpc_csharp_ext.c b/src/csharp/ext/grpc_csharp_ext.c
index 5f9f22c..8f5a414 100644
--- a/src/csharp/ext/grpc_csharp_ext.c
+++ b/src/csharp/ext/grpc_csharp_ext.c
@@ -35,9 +35,10 @@
 
 #include <grpc/support/port_platform.h>
 #include <grpc/support/alloc.h>
-#include <grpc/grpc.h>
 #include <grpc/support/log.h>
 #include <grpc/support/slice.h>
+#include <grpc/support/thd.h>
+#include <grpc/grpc.h>
 
 #include <string.h>
 
@@ -343,6 +344,23 @@
   return grpc_call_start_batch(call, ops, sizeof(ops) / sizeof(ops[0]), ctx);
 }
 
+/* Synchronous unary call */
+GPR_EXPORT void GPR_CALLTYPE
+grpcsharp_call_blocking_unary(grpc_call *call,
+                              grpc_completion_queue *dedicated_cq,
+                              callback_funcptr callback,
+                              const char *send_buffer, size_t send_buffer_len) {
+  GPR_ASSERT(grpcsharp_call_start_unary(call, callback, send_buffer,
+                                        send_buffer_len) == GRPC_CALL_OK);
+
+  /* TODO: we would like to use pluck, but we don't know the tag */
+  GPR_ASSERT(grpcsharp_completion_queue_next_with_callback(dedicated_cq) ==
+             GRPC_OP_COMPLETE);
+  grpc_completion_queue_shutdown(dedicated_cq);
+  GPR_ASSERT(grpcsharp_completion_queue_next_with_callback(dedicated_cq) ==
+             GRPC_QUEUE_SHUTDOWN);
+}
+
 GPR_EXPORT grpc_call_error GPR_CALLTYPE
 grpcsharp_call_start_client_streaming(grpc_call *call,
                                       callback_funcptr callback) {
@@ -566,3 +584,32 @@
       server, &(ctx->server_rpc_new.call), &(ctx->server_rpc_new.call_details),
       &(ctx->server_rpc_new.request_metadata), cq, ctx);
 }
+
+/* Logging */
+
+typedef void(GPR_CALLTYPE *grpcsharp_log_func)(const char *file, gpr_int32 line,
+                                               gpr_uint64 thd_id,
+                                               const char *severity_string,
+                                               const char *msg);
+static grpcsharp_log_func log_func = NULL;
+
+/* Redirects gpr_log to log_func callback */
+static void grpcsharp_log_handler(gpr_log_func_args *args) {
+  log_func(args->file, args->line, gpr_thd_currentid(),
+           gpr_log_severity_string(args->severity), args->message);
+}
+
+GPR_EXPORT void GPR_CALLTYPE grpcsharp_redirect_log(grpcsharp_log_func func) {
+  GPR_ASSERT(func);
+  log_func = func;
+  gpr_set_log_function(grpcsharp_log_handler);
+}
+
+/* For testing */
+GPR_EXPORT void GPR_CALLTYPE
+grpcsharp_test_callback(callback_funcptr callback) {
+  callback(GRPC_OP_OK, NULL);
+}
+
+/* For testing */
+GPR_EXPORT void *GPR_CALLTYPE grpcsharp_test_nop(void *ptr) { return ptr; }
diff --git a/src/node/LICENSE b/src/node/LICENSE
new file mode 100644
index 0000000..0209b57
--- /dev/null
+++ b/src/node/LICENSE
@@ -0,0 +1,28 @@
+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.
diff --git a/src/node/README.md b/src/node/README.md
index 8880213..5b3de6b 100644
--- a/src/node/README.md
+++ b/src/node/README.md
@@ -4,6 +4,10 @@
 
 Alpha : Ready for early adopters
 
+## Prerequisites
+
+This requires `node` to be installed. If you instead have the `nodejs` executable on Debian, you should install the [`nodejs-legacy`](https://packages.debian.org/sid/nodejs-legacy) package.
+
 ## Installation
 
 First, clone this repository (NPM package coming soon). Then follow the instructions in the `INSTALL` file in the root of the repository to install the C core library that this package depends on.
diff --git a/src/node/binding.gyp b/src/node/binding.gyp
index fb4c779..10afaf6 100644
--- a/src/node/binding.gyp
+++ b/src/node/binding.gyp
@@ -7,10 +7,10 @@
   "targets" : [
     {
       'include_dirs': [
-        "<!(nodejs -e \"require('nan')\")"
+        "<!(node -e \"require('nan')\")"
       ],
       'cflags': [
-        '-std=c++11',
+        '-std=c++0x',
         '-Wall',
         '-pthread',
         '-pedantic',
diff --git a/src/node/examples/pubsub/pubsub_demo.js b/src/node/examples/pubsub/pubsub_demo.js
index 4f7a9a9..2630151 100644
--- a/src/node/examples/pubsub/pubsub_demo.js
+++ b/src/node/examples/pubsub/pubsub_demo.js
@@ -35,7 +35,7 @@
 
 var async = require('async');
 var fs = require('fs');
-var GoogleAuth = require('googleauth');
+var GoogleAuth = require('google-auth-library');
 var parseArgs = require('minimist');
 var strftime = require('strftime');
 var _ = require('underscore');
diff --git a/src/node/ext/channel.cc b/src/node/ext/channel.cc
index 6c7a89e..bc9461d 100644
--- a/src/node/ext/channel.cc
+++ b/src/node/ext/channel.cc
@@ -103,11 +103,15 @@
     grpc_channel *wrapped_channel;
     // Owned by the Channel object
     NanUtf8String *host = new NanUtf8String(args[0]);
+    NanUtf8String *host_override = NULL;
     if (args[1]->IsUndefined()) {
       wrapped_channel = grpc_channel_create(**host, NULL);
     } else if (args[1]->IsObject()) {
       grpc_credentials *creds = NULL;
       Handle<Object> args_hash(args[1]->ToObject()->Clone());
+      if (args_hash->HasOwnProperty(NanNew(GRPC_SSL_TARGET_NAME_OVERRIDE_ARG))) {
+        host_override = new NanUtf8String(args_hash->Get(NanNew(GRPC_SSL_TARGET_NAME_OVERRIDE_ARG)));
+      }
       if (args_hash->HasOwnProperty(NanNew("credentials"))) {
         Handle<Value> creds_value = args_hash->Get(NanNew("credentials"));
         if (!Credentials::HasInstance(creds_value)) {
@@ -155,7 +159,12 @@
     } else {
       return NanThrowTypeError("Channel expects a string and an object");
     }
-    Channel *channel = new Channel(wrapped_channel, host);
+    Channel *channel;
+    if (host_override == NULL) {
+      channel = new Channel(wrapped_channel, host);
+    } else {
+      channel = new Channel(wrapped_channel, host_override);
+    }
     channel->Wrap(args.This());
     NanReturnValue(args.This());
   } else {
diff --git a/src/node/index.js b/src/node/index.js
index 4b5302e..ad3dd96 100644
--- a/src/node/index.js
+++ b/src/node/index.js
@@ -78,7 +78,7 @@
 /**
  * Get a function that a client can use to update metadata with authentication
  * information from a Google Auth credential object, which comes from the
- * googleauth library.
+ * google-auth-library.
  * @param {Object} credential The credential object to use
  * @return {function(Object, callback)} Metadata updater function
  */
diff --git a/src/node/interop/interop_client.js b/src/node/interop/interop_client.js
index eaf254b..8060baf 100644
--- a/src/node/interop/interop_client.js
+++ b/src/node/interop/interop_client.js
@@ -37,7 +37,7 @@
 var path = require('path');
 var grpc = require('..');
 var testProto = grpc.load(__dirname + '/test.proto').grpc.testing;
-var GoogleAuth = require('googleauth');
+var GoogleAuth = require('google-auth-library');
 
 var assert = require('assert');
 
diff --git a/src/node/package.json b/src/node/package.json
index e6ac550..0ef1c99 100644
--- a/src/node/package.json
+++ b/src/node/package.json
@@ -1,10 +1,27 @@
 {
   "name": "grpc",
-  "version": "0.2.0",
+  "version": "0.5.1",
+  "author": "Google Inc.",
   "description": "gRPC Library for Node",
+  "homepage": "http://www.grpc.io/",
+  "repository": {
+    "type": "git",
+    "url": "https://github.com/grpc/grpc.git"
+  },
+  "bugs": "https://github.com/grpc/grpc/issues",
+  "contributors": [
+    {
+      "name": "Michael Lumish",
+      "email": "mlumish@google.com"
+    }
+  ],
+  "directories": {
+    "lib": "src",
+    "example": "examples"
+  },
   "scripts": {
-    "lint": "nodejs ./node_modules/jshint/bin/jshint src test examples interop index.js",
-    "test": "nodejs ./node_modules/mocha/bin/mocha && npm run-script lint"
+    "lint": "node ./node_modules/jshint/bin/jshint src test examples interop index.js",
+    "test": "node ./node_modules/mocha/bin/mocha && npm run-script lint"
   },
   "dependencies": {
     "bindings": "^1.2.1",
@@ -16,12 +33,13 @@
   },
   "devDependencies": {
     "async": "^0.9.0",
-    "googleauth": "google/google-auth-library-nodejs",
+    "google-auth-library": "^0.9.2",
     "minimist": "^1.1.0",
     "mocha": "~1.21.0",
     "strftime": "^0.8.2"
   },
   "files": [
+    "LICENSE",
     "README.md",
     "index.js",
     "binding.gyp",
@@ -31,5 +49,6 @@
     "src",
     "test"
   ],
-  "main": "index.js"
+  "main": "index.js",
+  "license": "BSD-3-Clause"
 }
diff --git a/src/node/test/interop_sanity_test.js b/src/node/test/interop_sanity_test.js
index 8dc933e..6b3aa3d 100644
--- a/src/node/test/interop_sanity_test.js
+++ b/src/node/test/interop_sanity_test.js
@@ -40,7 +40,7 @@
 
 var port;
 
-var name_override = 'foo.test.google.com';
+var name_override = 'foo.test.google.fr';
 
 describe('Interop tests', function() {
   before(function(done) {
diff --git a/src/php/ext/grpc/credentials.c b/src/php/ext/grpc/credentials.c
index f25e042..6d8f59f 100644
--- a/src/php/ext/grpc/credentials.c
+++ b/src/php/ext/grpc/credentials.c
@@ -94,7 +94,7 @@
  * @return Credentials The new default credentials object
  */
 PHP_METHOD(Credentials, createDefault) {
-  grpc_credentials *creds = grpc_default_credentials_create();
+  grpc_credentials *creds = grpc_google_default_credentials_create();
   zval *creds_object = grpc_php_wrap_credentials(creds);
   RETURN_DESTROY_ZVAL(creds_object);
 }
diff --git a/src/php/ext/grpc/event.c b/src/php/ext/grpc/event.c
index 8d39845..452c4b8 100644
--- a/src/php/ext/grpc/event.c
+++ b/src/php/ext/grpc/event.c
@@ -90,10 +90,6 @@
         add_property_stringl(event_object, "data", read_string, read_len, true);
       }
       break;
-    case GRPC_INVOKE_ACCEPTED:
-      add_property_long(event_object, "data",
-                        (long)event->data.invoke_accepted);
-      break;
     case GRPC_WRITE_ACCEPTED:
       add_property_long(event_object, "data", (long)event->data.write_accepted);
       break;
diff --git a/src/php/tests/interop/interop_client.php b/src/php/tests/interop/interop_client.php
index 5a09fc7..82ca438 100755
--- a/src/php/tests/interop/interop_client.php
+++ b/src/php/tests/interop/interop_client.php
@@ -215,7 +215,7 @@
     new Grpc\BaseStub(
         $server_address,
         [
-            'grpc.ssl_target_name_override' => 'foo.test.google.com',
+            'grpc.ssl_target_name_override' => 'foo.test.google.fr',
             'credentials' => $credentials
          ]));
 
diff --git a/src/php/tests/unit_tests/SecureEndToEndTest.php b/src/php/tests/unit_tests/SecureEndToEndTest.php
index b19ac80..c23dd79 100755
--- a/src/php/tests/unit_tests/SecureEndToEndTest.php
+++ b/src/php/tests/unit_tests/SecureEndToEndTest.php
@@ -47,7 +47,7 @@
     $this->channel = new Grpc\Channel(
         'localhost:' . $port,
         [
-            'grpc.ssl_target_name_override' => 'foo.test.google.com',
+            'grpc.ssl_target_name_override' => 'foo.test.google.fr',
             'credentials' => $credentials
          ]);
   }
diff --git a/src/python/README.md b/src/python/README.md
index be2f2be..490a229 100755
--- a/src/python/README.md
+++ b/src/python/README.md
@@ -1,9 +1,14 @@
-GRPC Python
+gRPC Python
 =========
 
-The Python facility of GRPC.
+The Python facility of gRPC.
 
 
+Status
+-------
+
+Usable with limitations, Pre-Alpha
+
 Prerequisites
 -----------------------
 
@@ -13,8 +18,8 @@
 Building from source
 ----------------------
 
-- Build the GRPC core
-E.g, from the root of the grpc [git repo](https://github.com/google/grpc)
+- Build the gRPC core from the root of the
+  [gRPC git repo](https://github.com/grpc/grpc)
 ```
 $ make shared_c static_c
 ```
@@ -28,7 +33,23 @@
 Testing
 -----------------------
 
-- Use run_python.sh to run GRPC as it was installed into the virtual environment
+- Use run_python.sh to run gRPC as it was installed into the virtual environment
 ```
 $ tools/run_tests/run_python.sh
 ```
+
+
+Installing
+-----------------------
+
+- [Install the gRPC core](https://github.com/grpc/grpc/blob/master/INSTALL)
+
+- Install gRPC Python's dependencies
+```
+$ pip install -r requirements.txt
+```
+
+- Install gRPC Python
+```
+$ pip install src/python/src
+```
diff --git a/src/python/interop/interop/client.py b/src/python/interop/interop/client.py
new file mode 100644
index 0000000..f4a449e
--- /dev/null
+++ b/src/python/interop/interop/client.py
@@ -0,0 +1,86 @@
+# 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.
+
+"""The Python implementation of the GRPC interoperability test client."""
+
+import argparse
+
+from grpc.early_adopter import implementations
+
+from interop import methods
+from interop import resources
+
+_ONE_DAY_IN_SECONDS = 60 * 60 * 24
+
+
+def _args():
+  parser = argparse.ArgumentParser()
+  parser.add_argument(
+      '--server_host', help='the host to which to connect', type=str)
+  parser.add_argument(
+      '--server_host_override',
+      help='the server host to which to claim to connect', type=str)
+  parser.add_argument(
+      '--server_port', help='the port to which to connect', type=int)
+  parser.add_argument(
+      '--test_case', help='the test case to execute', type=str)
+  parser.add_argument(
+      '--use_tls', help='require a secure connection', dest='use_tls',
+      action='store_true')
+  parser.add_argument(
+      '--use_test_ca', help='replace platform root CAs with ca.pem',
+      action='store_true')
+  return parser.parse_args()
+
+
+def _stub(args):
+  if args.use_tls:
+    if args.use_test_ca:
+      root_certificates = resources.test_root_certificates()
+    else:
+      root_certificates = resources.prod_root_certificates()
+    # TODO(nathaniel): server host override.
+
+    stub = implementations.secure_stub(
+        methods.CLIENT_METHODS, args.server_host, args.server_port,
+        root_certificates, None, None)
+  else:
+    stub = implementations.insecure_stub(
+        methods.CLIENT_METHODS, args.server_host, args.server_port)
+  return stub
+
+
+def _test_interoperability():
+  args = _args()
+  stub = _stub(args)
+  methods.test_interoperability(args.test_case, stub)
+
+
+if __name__ == '__main__':
+  _test_interoperability()
diff --git a/src/python/interop/interop/credentials/ca.pem b/src/python/interop/interop/credentials/ca.pem
new file mode 100755
index 0000000..6c8511a
--- /dev/null
+++ b/src/python/interop/interop/credentials/ca.pem
@@ -0,0 +1,15 @@
+-----BEGIN CERTIFICATE-----
+MIICSjCCAbOgAwIBAgIJAJHGGR4dGioHMA0GCSqGSIb3DQEBCwUAMFYxCzAJBgNV
+BAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBX
+aWRnaXRzIFB0eSBMdGQxDzANBgNVBAMTBnRlc3RjYTAeFw0xNDExMTEyMjMxMjla
+Fw0yNDExMDgyMjMxMjlaMFYxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0
+YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQxDzANBgNVBAMT
+BnRlc3RjYTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAwEDfBV5MYdlHVHJ7
++L4nxrZy7mBfAVXpOc5vMYztssUI7mL2/iYujiIXM+weZYNTEpLdjyJdu7R5gGUu
+g1jSVK/EPHfc74O7AyZU34PNIP4Sh33N+/A5YexrNgJlPY+E3GdVYi4ldWJjgkAd
+Qah2PH5ACLrIIC6tRka9hcaBlIECAwEAAaMgMB4wDAYDVR0TBAUwAwEB/zAOBgNV
+HQ8BAf8EBAMCAgQwDQYJKoZIhvcNAQELBQADgYEAHzC7jdYlzAVmddi/gdAeKPau
+sPBG/C2HCWqHzpCUHcKuvMzDVkY/MP2o6JIW2DBbY64bO/FceExhjcykgaYtCH/m
+oIU63+CFOTtR7otyQAWHqXa7q4SbCDlG7DyRFxqG0txPtGvy12lgldA2+RgcigQG
+Dfcog5wrJytaQ6UA0wE=
+-----END CERTIFICATE-----
diff --git a/src/python/interop/interop/methods.py b/src/python/interop/interop/methods.py
index 26c1869..4da28ee 100644
--- a/src/python/interop/interop/methods.py
+++ b/src/python/interop/interop/methods.py
@@ -29,52 +29,57 @@
 
 """Implementations of interoperability test methods."""
 
+import threading
+
 from grpc.early_adopter import utilities
 
 from interop import empty_pb2
 from interop import messages_pb2
 
-def _empty_call(request):
+_TIMEOUT = 7
+
+
+def _empty_call(request, unused_context):
   return empty_pb2.Empty()
 
-_CLIENT_EMPTY_CALL = utilities.unary_unary_client_rpc_method(
+_CLIENT_EMPTY_CALL = utilities.unary_unary_invocation_description(
     empty_pb2.Empty.SerializeToString, empty_pb2.Empty.FromString)
-_SERVER_EMPTY_CALL = utilities.unary_unary_server_rpc_method(
+_SERVER_EMPTY_CALL = utilities.unary_unary_service_description(
     _empty_call, empty_pb2.Empty.FromString,
     empty_pb2.Empty.SerializeToString)
 
 
-def _unary_call(request):
+def _unary_call(request, unused_context):
   return messages_pb2.SimpleResponse(
       payload=messages_pb2.Payload(
           type=messages_pb2.COMPRESSABLE,
           body=b'\x00' * request.response_size))
 
-_CLIENT_UNARY_CALL = utilities.unary_unary_client_rpc_method(
+_CLIENT_UNARY_CALL = utilities.unary_unary_invocation_description(
     messages_pb2.SimpleRequest.SerializeToString,
     messages_pb2.SimpleResponse.FromString)
-_SERVER_UNARY_CALL = utilities.unary_unary_server_rpc_method(
+_SERVER_UNARY_CALL = utilities.unary_unary_service_description(
     _unary_call, messages_pb2.SimpleRequest.FromString,
     messages_pb2.SimpleResponse.SerializeToString)
 
 
-def _streaming_output_call(request):
+def _streaming_output_call(request, unused_context):
   for response_parameters in request.response_parameters:
     yield messages_pb2.StreamingOutputCallResponse(
         payload=messages_pb2.Payload(
             type=request.response_type,
             body=b'\x00' * response_parameters.size))
 
-_CLIENT_STREAMING_OUTPUT_CALL = utilities.unary_stream_client_rpc_method(
+_CLIENT_STREAMING_OUTPUT_CALL = utilities.unary_stream_invocation_description(
     messages_pb2.StreamingOutputCallRequest.SerializeToString,
     messages_pb2.StreamingOutputCallResponse.FromString)
-_SERVER_STREAMING_OUTPUT_CALL = utilities.unary_stream_server_rpc_method(
+_SERVER_STREAMING_OUTPUT_CALL = utilities.unary_stream_service_description(
     _streaming_output_call,
     messages_pb2.StreamingOutputCallRequest.FromString,
     messages_pb2.StreamingOutputCallResponse.SerializeToString)
 
 
-def _streaming_input_call(request_iterator):
+def _streaming_input_call(request_iterator, unused_context):
   aggregate_size = 0
   for request in request_iterator:
     if request.payload and request.payload.body:
@@ -82,35 +87,35 @@
   return messages_pb2.StreamingInputCallResponse(
       aggregated_payload_size=aggregate_size)
 
-_CLIENT_STREAMING_INPUT_CALL = utilities.stream_unary_client_rpc_method(
+_CLIENT_STREAMING_INPUT_CALL = utilities.stream_unary_invocation_description(
     messages_pb2.StreamingInputCallRequest.SerializeToString,
     messages_pb2.StreamingInputCallResponse.FromString)
-_SERVER_STREAMING_INPUT_CALL = utilities.stream_unary_server_rpc_method(
+_SERVER_STREAMING_INPUT_CALL = utilities.stream_unary_service_description(
     _streaming_input_call,
     messages_pb2.StreamingInputCallRequest.FromString,
     messages_pb2.StreamingInputCallResponse.SerializeToString)
 
 
-def _full_duplex_call(request_iterator):
+def _full_duplex_call(request_iterator, unused_context):
   for request in request_iterator:
     yield messages_pb2.StreamingOutputCallResponse(
         payload=messages_pb2.Payload(
             type=request.payload.type,
             body=b'\x00' * request.response_parameters[0].size))
 
-_CLIENT_FULL_DUPLEX_CALL = utilities.stream_stream_client_rpc_method(
+_CLIENT_FULL_DUPLEX_CALL = utilities.stream_stream_invocation_description(
     messages_pb2.StreamingOutputCallRequest.SerializeToString,
     messages_pb2.StreamingOutputCallResponse.FromString)
-_SERVER_FULL_DUPLEX_CALL = utilities.stream_stream_server_rpc_method(
+_SERVER_FULL_DUPLEX_CALL = utilities.stream_stream_service_description(
     _full_duplex_call,
     messages_pb2.StreamingOutputCallRequest.FromString,
     messages_pb2.StreamingOutputCallResponse.SerializeToString)
 
 # NOTE(nathaniel): Apparently this is the same as the full-duplex call?
-_CLIENT_HALF_DUPLEX_CALL = utilities.stream_stream_client_rpc_method(
+_CLIENT_HALF_DUPLEX_CALL = utilities.stream_stream_invocation_description(
     messages_pb2.StreamingOutputCallRequest.SerializeToString,
     messages_pb2.StreamingOutputCallResponse.FromString)
-_SERVER_HALF_DUPLEX_CALL = utilities.stream_stream_server_rpc_method(
+_SERVER_HALF_DUPLEX_CALL = utilities.stream_stream_service_description(
     _full_duplex_call,
     messages_pb2.StreamingOutputCallRequest.FromString,
     messages_pb2.StreamingOutputCallResponse.SerializeToString)
@@ -142,3 +147,134 @@
     FULL_DUPLEX_CALL_METHOD_NAME: _SERVER_FULL_DUPLEX_CALL,
     HALF_DUPLEX_CALL_METHOD_NAME: _SERVER_HALF_DUPLEX_CALL,
 }
+
+
+def _empty_unary(stub):
+  with stub:
+    response = stub.EmptyCall(empty_pb2.Empty(), _TIMEOUT)
+    if not isinstance(response, empty_pb2.Empty):
+      raise TypeError(
+          'response is of type "%s", not empty_pb2.Empty!', type(response))
+
+
+def _large_unary(stub):
+  with stub:
+    request = messages_pb2.SimpleRequest(
+        response_type=messages_pb2.COMPRESSABLE, response_size=314159,
+        payload=messages_pb2.Payload(body=b'\x00' * 271828))
+    response_future = stub.UnaryCall.async(request, _TIMEOUT)
+    response = response_future.result()
+    if response.payload.type is not messages_pb2.COMPRESSABLE:
+      raise ValueError(
+          'response payload type is "%s"!' % type(response.payload.type))
+    if len(response.payload.body) != 314159:
+      raise ValueError(
+          'response body of incorrect size %d!' % len(response.payload.body))
+
+
+def _client_streaming(stub):
+  with stub:
+    payload_body_sizes = (27182, 8, 1828, 45904)
+    payloads = (
+        messages_pb2.Payload(body=b'\x00' * size)
+        for size in payload_body_sizes)
+    requests = (
+        messages_pb2.StreamingInputCallRequest(payload=payload)
+        for payload in payloads)
+    response = stub.StreamingInputCall(requests, _TIMEOUT)
+    if response.aggregated_payload_size != 74922:
+      raise ValueError(
+          'incorrect size %d!' % response.aggregated_payload_size)
+
+
+def _server_streaming(stub):
+  sizes = (31415, 9, 2653, 58979)
+
+  with stub:
+    request = messages_pb2.StreamingOutputCallRequest(
+        response_type=messages_pb2.COMPRESSABLE,
+        response_parameters=(
+            messages_pb2.ResponseParameters(size=sizes[0]),
+            messages_pb2.ResponseParameters(size=sizes[1]),
+            messages_pb2.ResponseParameters(size=sizes[2]),
+            messages_pb2.ResponseParameters(size=sizes[3]),
+        ))
+    response_iterator = stub.StreamingOutputCall(request, _TIMEOUT)
+    for index, response in enumerate(response_iterator):
+      if response.payload.type != messages_pb2.COMPRESSABLE:
+        raise ValueError(
+            'response body of invalid type %s!' % response.payload.type)
+      if len(response.payload.body) != sizes[index]:
+        raise ValueError(
+            'response body of invalid size %d!' % len(response.payload.body))
+
+
+class _Pipe(object):
+
+  def __init__(self):
+    self._condition = threading.Condition()
+    self._values = []
+    self._open = True
+
+  def __iter__(self):
+    return self
+
+  def next(self):
+    with self._condition:
+      while not self._values and self._open:
+        self._condition.wait()
+      if self._values:
+        return self._values.pop(0)
+      else:
+        raise StopIteration()
+
+  def add(self, value):
+    with self._condition:
+      self._values.append(value)
+      self._condition.notify()
+
+  def close(self):
+    with self._condition:
+      self._open = False
+      self._condition.notify()
+
+
+def _ping_pong(stub):
+  request_response_sizes = (31415, 9, 2653, 58979)
+  request_payload_sizes = (27182, 8, 1828, 45904)
+
+  with stub:
+    pipe = _Pipe()
+    response_iterator = stub.FullDuplexCall(pipe, _TIMEOUT)
+    print 'Starting ping-pong with response iterator %s' % response_iterator
+    for response_size, payload_size in zip(
+        request_response_sizes, request_payload_sizes):
+      request = messages_pb2.StreamingOutputCallRequest(
+          response_type=messages_pb2.COMPRESSABLE,
+          response_parameters=(messages_pb2.ResponseParameters(
+              size=response_size),),
+          payload=messages_pb2.Payload(body=b'\x00' * payload_size))
+      pipe.add(request)
+      response = next(response_iterator)
+      if response.payload.type != messages_pb2.COMPRESSABLE:
+        raise ValueError(
+            'response body of invalid type %s!' % response.payload.type)
+      if len(response.payload.body) != response_size:
+        raise ValueError(
+            'response body of invalid size %d!' % len(response.payload.body))
+    pipe.close()
+
+
+def test_interoperability(test_case, stub):
+  if test_case == 'empty_unary':
+    _empty_unary(stub)
+  elif test_case == 'large_unary':
+    _large_unary(stub)
+  elif test_case == 'server_streaming':
+    _server_streaming(stub)
+  elif test_case == 'client_streaming':
+    _client_streaming(stub)
+  elif test_case == 'ping_pong':
+    _ping_pong(stub)
+  else:
+    raise NotImplementedError('Test case "%s" not implemented!')
diff --git a/src/python/interop/interop/resources.py b/src/python/interop/interop/resources.py
new file mode 100644
index 0000000..2c30453
--- /dev/null
+++ b/src/python/interop/interop/resources.py
@@ -0,0 +1,56 @@
+# 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.
+
+"""Constants and functions for data used in interoperability testing."""
+
+import os
+
+import pkg_resources
+
+_ROOT_CERTIFICATES_RESOURCE_PATH = 'credentials/ca.pem'
+_PRIVATE_KEY_RESOURCE_PATH = 'credentials/server1.key'
+_CERTIFICATE_CHAIN_RESOURCE_PATH = 'credentials/server1.pem'
+
+
+def test_root_certificates():
+  return pkg_resources.resource_string(
+      __name__, _ROOT_CERTIFICATES_RESOURCE_PATH)
+
+
+def prod_root_certificates():
+  return open(os.environ['SSL_CERT_FILE'], mode='rb').read()
+
+
+def private_key():
+  return pkg_resources.resource_string(__name__, _PRIVATE_KEY_RESOURCE_PATH)
+
+
+def certificate_chain():
+  return pkg_resources.resource_string(
+      __name__, _CERTIFICATE_CHAIN_RESOURCE_PATH)
diff --git a/src/python/interop/interop/server.py b/src/python/interop/interop/server.py
index 785d482..4e4b127 100644
--- a/src/python/interop/interop/server.py
+++ b/src/python/interop/interop/server.py
@@ -31,18 +31,15 @@
 
 import argparse
 import logging
-import pkg_resources
 import time
 
 from grpc.early_adopter import implementations
 
 from interop import methods
+from interop import resources
 
 _ONE_DAY_IN_SECONDS = 60 * 60 * 24
 
-_PRIVATE_KEY_RESOURCE_PATH = 'credentials/server1.key'
-_CERTIFICATE_CHAIN_RESOURCE_PATH = 'credentials/server1.pem'
-
 
 def serve():
   parser = argparse.ArgumentParser()
@@ -54,10 +51,8 @@
   args = parser.parse_args()
 
   if args.use_tls:
-    private_key = pkg_resources.resource_string(
-        __name__, _PRIVATE_KEY_RESOURCE_PATH)
-    certificate_chain = pkg_resources.resource_string(
-        __name__, _CERTIFICATE_CHAIN_RESOURCE_PATH)
+    private_key = resources.private_key()
+    certificate_chain = resources.certificate_chain()
     server = implementations.secure_server(
         methods.SERVER_METHODS, args.port, private_key, certificate_chain)
   else:
diff --git a/src/python/interop/setup.py b/src/python/interop/setup.py
index 4b7709f..6db5435 100644
--- a/src/python/interop/setup.py
+++ b/src/python/interop/setup.py
@@ -40,7 +40,9 @@
 }
 
 _PACKAGE_DATA = {
-    'interop': ['credentials/server1.key', 'credentials/server1.pem',]
+    'interop': [
+        'credentials/ca.pem', 'credentials/server1.key',
+        'credentials/server1.pem',]
 }
 
 _INSTALL_REQUIRES = ['grpc-2015>=0.0.1']
diff --git a/src/python/requirements.txt b/src/python/requirements.txt
new file mode 100644
index 0000000..06a42e1
--- /dev/null
+++ b/src/python/requirements.txt
@@ -0,0 +1,3 @@
+enum34==1.0.4
+futures==2.2.0
+protobuf==3.0.0-alpha-1
diff --git a/src/python/src/grpc/_adapter/_c.c b/src/python/src/grpc/_adapter/_c.c
index 55b9d05..f096a55 100644
--- a/src/python/src/grpc/_adapter/_c.c
+++ b/src/python/src/grpc/_adapter/_c.c
@@ -38,6 +38,7 @@
 #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) {
@@ -76,6 +77,9 @@
   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/_c_test.py b/src/python/src/grpc/_adapter/_c_test.py
index d421692..d81c63e 100644
--- a/src/python/src/grpc/_adapter/_c_test.py
+++ b/src/python/src/grpc/_adapter/_c_test.py
@@ -70,7 +70,7 @@
   def testChannel(self):
     _c.init()
 
-    channel = _c.Channel('test host:12345')
+    channel = _c.Channel('test host:12345', None)
     del channel
 
     _c.shut_down()
@@ -81,7 +81,7 @@
 
     _c.init()
 
-    channel = _c.Channel('%s:%d' % (host, 12345))
+    channel = _c.Channel('%s:%d' % (host, 12345), None)
     call = _c.Call(channel, method, host, time.time() + _TIMEOUT)
     del call
     del channel
@@ -136,6 +136,29 @@
 
     _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.'
diff --git a/src/python/src/grpc/_adapter/_call.c b/src/python/src/grpc/_adapter/_call.c
index 325d3d5..dca2e49 100644
--- a/src/python/src/grpc/_adapter/_call.c
+++ b/src/python/src/grpc/_adapter/_call.c
@@ -161,7 +161,7 @@
 }
 
 static const PyObject *pygrpc_call_premetadata(Call *self) {
-  /* TODO(b/18702680): Actually support metadata. */
+  /* TODO(nathaniel): Metadata support. */
   return pygrpc_translate_call_error(
       grpc_call_server_end_initial_metadata_old(self->c_call, 0));
 }
diff --git a/src/python/src/grpc/_adapter/_channel.c b/src/python/src/grpc/_adapter/_channel.c
index 3ba943e..9cf580b 100644
--- a/src/python/src/grpc/_adapter/_channel.c
+++ b/src/python/src/grpc/_adapter/_channel.c
@@ -35,18 +35,28 @@
 
 #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;
-  static char *kwlist[] = {"hostport", NULL};
+  PyObject *client_credentials;
+  static char *kwlist[] = {"hostport", "client_credentials", NULL};
 
-  if (!(PyArg_ParseTupleAndKeywords(args, kwds, "s:Channel", kwlist,
-                                    &hostport))) {
+  if (!(PyArg_ParseTupleAndKeywords(args, kwds, "sO:Channel", kwlist,
+                                    &hostport, &client_credentials))) {
     return -1;
   }
-
-  self->c_channel = grpc_channel_create(hostport, NULL);
-  return 0;
+  if (client_credentials == Py_None) {
+    self->c_channel = grpc_channel_create(hostport, NULL);
+    return 0;
+  } else {
+    self->c_channel = grpc_secure_channel_create(
+        ((ClientCredentials *)client_credentials)->c_client_credentials,
+        hostport, NULL);
+    return 0;
+  }
 }
 
 static void pygrpc_channel_dealloc(Channel *self) {
diff --git a/src/python/src/grpc/_adapter/_client_credentials.c b/src/python/src/grpc/_adapter/_client_credentials.c
new file mode 100644
index 0000000..e8ccff8
--- /dev/null
+++ b/src/python/src/grpc/_adapter/_client_credentials.c
@@ -0,0 +1,121 @@
+/*
+ *
+ * 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
new file mode 100644
index 0000000..664dc80
--- /dev/null
+++ b/src/python/src/grpc/_adapter/_client_credentials.h
@@ -0,0 +1,48 @@
+/*
+ *
+ * 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;
+
+PyTypeObject pygrpc_ClientCredentialsType;
+
+int pygrpc_add_client_credentials(PyObject *module);
+
+#endif /* _ADAPTER__CLIENT_CREDENTIALS_H_ */
diff --git a/src/python/src/grpc/_adapter/_face_test_case.py b/src/python/src/grpc/_adapter/_face_test_case.py
index 8cce322..475d780 100644
--- a/src/python/src/grpc/_adapter/_face_test_case.py
+++ b/src/python/src/grpc/_adapter/_face_test_case.py
@@ -85,7 +85,8 @@
     port = fore_link.port()
     rear_link = rear.RearLink(
         'localhost', port, pool,
-        serialization.request_serializers, serialization.response_deserializers)
+        serialization.request_serializers,
+        serialization.response_deserializers, False, None, None, None)
     rear_link.start()
     front = tickets_implementations.front(pool, pool, pool)
     back = tickets_implementations.back(
diff --git a/src/python/src/grpc/_adapter/_links_test.py b/src/python/src/grpc/_adapter/_links_test.py
index 6b3bcee..5d7e677 100644
--- a/src/python/src/grpc/_adapter/_links_test.py
+++ b/src/python/src/grpc/_adapter/_links_test.py
@@ -75,7 +75,7 @@
 
     rear_link = rear.RearLink(
         'localhost', port, self.rear_link_pool, {test_method: None},
-        {test_method: None})
+        {test_method: None}, False, None, None, None)
     rear_link.join_fore_link(test_fore_link)
     test_fore_link.join_rear_link(rear_link)
     rear_link.start()
@@ -129,7 +129,7 @@
 
     rear_link = rear.RearLink(
         'localhost', port, self.rear_link_pool, {test_method: _IDENTITY},
-        {test_method: _IDENTITY})
+        {test_method: _IDENTITY}, False, None, None, None)
     rear_link.join_fore_link(test_fore_link)
     test_fore_link.join_rear_link(rear_link)
     rear_link.start()
@@ -193,7 +193,7 @@
     rear_link = rear.RearLink(
         'localhost', port, self.rear_link_pool,
         {test_method: scenario.serialize_request},
-        {test_method: scenario.deserialize_response})
+        {test_method: scenario.deserialize_response}, False, None, None, None)
     rear_link.join_fore_link(test_fore_link)
     test_fore_link.join_rear_link(rear_link)
     rear_link.start()
diff --git a/src/python/src/grpc/_adapter/_lonely_rear_link_test.py b/src/python/src/grpc/_adapter/_lonely_rear_link_test.py
index 9a13309..77821ba 100644
--- a/src/python/src/grpc/_adapter/_lonely_rear_link_test.py
+++ b/src/python/src/grpc/_adapter/_lonely_rear_link_test.py
@@ -50,7 +50,8 @@
     self.pool.shutdown(wait=True)
 
   def testUpAndDown(self):
-    rear_link = rear.RearLink('nonexistent', 54321, self.pool, {}, {})
+    rear_link = rear.RearLink(
+        'nonexistent', 54321, self.pool, {}, {}, False, None, None, None)
 
     rear_link.start()
     rear_link.stop()
@@ -63,7 +64,7 @@
 
     rear_link = rear.RearLink(
         'nonexistent', 54321, self.pool, {test_method: None},
-        {test_method: None})
+        {test_method: None}, False, None, None, None)
     rear_link.join_fore_link(fore_link)
     rear_link.start()
 
diff --git a/src/python/src/grpc/_adapter/_low.py b/src/python/src/grpc/_adapter/_low.py
index 2ef2eb8..a24baae 100644
--- a/src/python/src/grpc/_adapter/_low.py
+++ b/src/python/src/grpc/_adapter/_low.py
@@ -52,5 +52,6 @@
 Channel = _c.Channel
 CompletionQueue = _c.CompletionQueue
 Server = _c.Server
+ClientCredentials = _c.ClientCredentials
 ServerCredentials = _c.ServerCredentials
 # pylint: enable=invalid-name
diff --git a/src/python/src/grpc/_adapter/_low_test.py b/src/python/src/grpc/_adapter/_low_test.py
index 898c62c..03e3f47 100644
--- a/src/python/src/grpc/_adapter/_low_test.py
+++ b/src/python/src/grpc/_adapter/_low_test.py
@@ -56,7 +56,7 @@
     finish_tag = object()
 
     completion_queue = _low.CompletionQueue()
-    channel = _low.Channel('%s:%d' % (host, port))
+    channel = _low.Channel('%s:%d' % (host, port), None)
     client_call = _low.Call(channel, method, host, deadline)
 
     client_call.invoke(completion_queue, metadata_tag, finish_tag)
@@ -87,7 +87,7 @@
     self.server.start()
 
     self.client_completion_queue = _low.CompletionQueue()
-    self.channel = _low.Channel('%s:%d' % (self.host, port))
+    self.channel = _low.Channel('%s:%d' % (self.host, port), None)
 
   def tearDown(self):
     self.server.stop()
@@ -265,7 +265,7 @@
     self.server.start()
 
     self.client_completion_queue = _low.CompletionQueue()
-    self.channel = _low.Channel('%s:%d' % (self.host, port))
+    self.channel = _low.Channel('%s:%d' % (self.host, port), None)
 
   def tearDown(self):
     self.server.stop()
diff --git a/src/python/src/grpc/_adapter/rear.py b/src/python/src/grpc/_adapter/rear.py
index 94ff66f..bfde5f5 100644
--- a/src/python/src/grpc/_adapter/rear.py
+++ b/src/python/src/grpc/_adapter/rear.py
@@ -92,7 +92,8 @@
   """An invocation-side bridge between RPC Framework and the C-ish _low code."""
 
   def __init__(
-      self, host, port, pool, request_serializers, response_deserializers):
+      self, host, port, pool, request_serializers, response_deserializers,
+      secure, root_certificates, private_key, certificate_chain):
     """Constructor.
 
     Args:
@@ -103,6 +104,13 @@
         serializer behaviors.
       response_deserializers: A dict from RPC method names to response object
         deserializer behaviors.
+      secure: A boolean indicating whether or not to use a secure connection.
+      root_certificates: The PEM-encoded root certificates or None to ask for
+        them to be retrieved from a default location.
+      private_key: The PEM-encoded private key to use or None if no private
+        key should be used.
+      certificate_chain: The PEM-encoded certificate chain to use or None if
+        no certificate chain should be used.
     """
     self._condition = threading.Condition()
     self._host = host
@@ -116,6 +124,14 @@
     self._channel = None
     self._rpc_states = {}
     self._spinning = False
+    if secure:
+      self._client_credentials = _low.ClientCredentials(
+          root_certificates, private_key, certificate_chain)
+    else:
+      self._client_credentials = None
+    self._root_certificates = root_certificates
+    self._private_key = private_key
+    self._certificate_chain = certificate_chain
 
   def _on_write_event(self, operation_id, event, rpc_state):
     if event.write_accepted:
@@ -310,7 +326,8 @@
     """
     with self._condition:
       self._completion_queue = _low.CompletionQueue()
-      self._channel = _low.Channel('%s:%d' % (self._host, self._port))
+      self._channel = _low.Channel(
+          '%s:%d' % (self._host, self._port), self._client_credentials)
     return self
 
   def _stop(self):
@@ -369,11 +386,17 @@
 
 class _ActivatedRearLink(ticket_interfaces.RearLink, activated.Activated):
 
-  def __init__(self, host, port, request_serializers, response_deserializers):
+  def __init__(
+      self, host, port, request_serializers, response_deserializers, secure,
+      root_certificates, private_key, certificate_chain):
     self._host = host
     self._port = port
     self._request_serializers = request_serializers
     self._response_deserializers = response_deserializers
+    self._secure = secure
+    self._root_certificates = root_certificates
+    self._private_key = private_key
+    self._certificate_chain = certificate_chain
 
     self._lock = threading.Lock()
     self._pool = None
@@ -391,7 +414,8 @@
       self._pool = logging_pool.pool(_THREAD_POOL_SIZE)
       self._rear_link = RearLink(
           self._host, self._port, self._pool, self._request_serializers,
-          self._response_deserializers)
+          self._response_deserializers, self._secure, self._root_certificates,
+          self._private_key, self._certificate_chain)
       self._rear_link.join_fore_link(self._fore_link)
       self._rear_link.start()
     return self
@@ -422,6 +446,7 @@
         self._rear_link.accept_front_to_back_ticket(ticket)
 
 
+# TODO(issue 726): reconcile these two creation functions.
 def activated_rear_link(
     host, port, request_serializers, response_deserializers):
   """Creates a RearLink that is also an activated.Activated.
@@ -436,6 +461,42 @@
       serializer behavior.
     response_deserializers: A dictionary from RPC method name to response
       object deserializer behavior.
+    secure: A boolean indicating whether or not to use a secure connection.
+    root_certificates: The PEM-encoded root certificates or None to ask for
+      them to be retrieved from a default location.
+    private_key: The PEM-encoded private key to use or None if no private key
+      should be used.
+    certificate_chain: The PEM-encoded certificate chain to use or None if no
+      certificate chain should be used.
   """
   return _ActivatedRearLink(
-      host, port, request_serializers, response_deserializers)
+      host, port, request_serializers, response_deserializers, False, None,
+      None, None)
+
+
+
+def secure_activated_rear_link(
+    host, port, request_serializers, response_deserializers, root_certificates,
+    private_key, certificate_chain):
+  """Creates a RearLink that is also an activated.Activated.
+
+  The returned object is only valid for use between calls to its start and stop
+  methods (or in context when used as a context manager).
+
+  Args:
+    host: The host to which to connect for RPC service.
+    port: The port to which to connect for RPC service.
+    request_serializers: A dictionary from RPC method name to request object
+      serializer behavior.
+    response_deserializers: A dictionary from RPC method name to response
+      object deserializer behavior.
+    root_certificates: The PEM-encoded root certificates or None to ask for
+      them to be retrieved from a default location.
+    private_key: The PEM-encoded private key to use or None if no private key
+      should be used.
+    certificate_chain: The PEM-encoded certificate chain to use or None if no
+      certificate chain should be used.
+  """
+  return _ActivatedRearLink(
+      host, port, request_serializers, response_deserializers, True,
+      root_certificates, private_key, certificate_chain)
diff --git a/src/python/src/grpc/early_adopter/_assembly_utilities.py b/src/python/src/grpc/early_adopter/_assembly_utilities.py
new file mode 100644
index 0000000..facfc2b
--- /dev/null
+++ b/src/python/src/grpc/early_adopter/_assembly_utilities.py
@@ -0,0 +1,168 @@
+# 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
+
+# assembly_interfaces is referenced from specification in this module.
+from grpc.framework.assembly import interfaces as assembly_interfaces  # pylint: disable=unused-import
+from grpc.framework.assembly import utilities as assembly_utilities
+from grpc.early_adopter import _reexport
+from grpc.early_adopter import interfaces
+
+
+# TODO(issue 726): Kill the "implementations" attribute of this in favor
+# of the same-information-less-bogusly-represented "cardinalities".
+class InvocationBreakdown(object):
+  """An intermediate representation of invocation-side views of RPC methods.
+
+  Attributes:
+    cardinalities: A dictionary from RPC method name to interfaces.Cardinality
+      value.
+    implementations: A dictionary from RPC method name to
+      assembly_interfaces.MethodImplementation describing the method.
+    request_serializers: A dictionary from RPC method name to callable
+      behavior to be used serializing request values for the RPC.
+    response_deserializers: A dictionary from RPC method name to callable
+      behavior to be used deserializing response values for the RPC.
+  """
+  __metaclass__ = abc.ABCMeta
+
+
+class _EasyInvocationBreakdown(
+    InvocationBreakdown,
+    collections.namedtuple(
+        '_EasyInvocationBreakdown',
+        ('cardinalities', 'implementations', 'request_serializers',
+         'response_deserializers'))):
+  pass
+
+
+class ServiceBreakdown(object):
+  """An intermediate representation of service-side views of RPC methods.
+
+  Attributes:
+    implementations: A dictionary from RPC method name
+      assembly_interfaces.MethodImplementation implementing the RPC method.
+    request_deserializers: A dictionary from RPC method name to callable
+      behavior to be used deserializing request values for the RPC.
+    response_serializers: A dictionary from RPC method name to callable
+      behavior to be used serializing response values for the RPC.
+  """
+  __metaclass__ = abc.ABCMeta
+
+
+class _EasyServiceBreakdown(
+    ServiceBreakdown,
+    collections.namedtuple(
+        '_EasyServiceBreakdown',
+        ('implementations', 'request_deserializers', 'response_serializers'))):
+  pass
+
+
+def break_down_invocation(method_descriptions):
+  """Derives an InvocationBreakdown from several RPC method descriptions.
+
+  Args:
+    method_descriptions: A dictionary from RPC method name to
+      interfaces.RpcMethodInvocationDescription describing the RPCs.
+
+  Returns:
+    An InvocationBreakdown corresponding to the given method descriptions.
+  """
+  cardinalities = {}
+  implementations = {}
+  request_serializers = {}
+  response_deserializers = {}
+  for name, method_description in method_descriptions.iteritems():
+    cardinality = method_description.cardinality()
+    cardinalities[name] = cardinality
+    if cardinality is interfaces.Cardinality.UNARY_UNARY:
+      implementations[name] = assembly_utilities.unary_unary_inline(None)
+    elif cardinality is interfaces.Cardinality.UNARY_STREAM:
+      implementations[name] = assembly_utilities.unary_stream_inline(None)
+    elif cardinality is interfaces.Cardinality.STREAM_UNARY:
+      implementations[name] = assembly_utilities.stream_unary_inline(None)
+    elif cardinality is interfaces.Cardinality.STREAM_STREAM:
+      implementations[name] = assembly_utilities.stream_stream_inline(None)
+    request_serializers[name] = method_description.serialize_request
+    response_deserializers[name] = method_description.deserialize_response
+  return _EasyInvocationBreakdown(
+      cardinalities, implementations, request_serializers,
+      response_deserializers)
+
+
+def break_down_service(method_descriptions):
+  """Derives a ServiceBreakdown from several RPC method descriptions.
+
+  Args:
+    method_descriptions: A dictionary from RPC method name to
+      interfaces.RpcMethodServiceDescription describing the RPCs.
+
+  Returns:
+    A ServiceBreakdown corresponding to the given method descriptions.
+  """
+  implementations = {}
+  request_deserializers = {}
+  response_serializers = {}
+  for name, method_description in method_descriptions.iteritems():
+    cardinality = method_description.cardinality()
+    if cardinality is interfaces.Cardinality.UNARY_UNARY:
+      def service(
+          request, face_rpc_context,
+          service_behavior=method_description.service_unary_unary):
+        return service_behavior(
+            request, _reexport.rpc_context(face_rpc_context))
+      implementations[name] = assembly_utilities.unary_unary_inline(service)
+    elif cardinality is interfaces.Cardinality.UNARY_STREAM:
+      def service(
+          request, face_rpc_context,
+          service_behavior=method_description.service_unary_stream):
+        return service_behavior(
+            request, _reexport.rpc_context(face_rpc_context))
+      implementations[name] = assembly_utilities.unary_stream_inline(service)
+    elif cardinality is interfaces.Cardinality.STREAM_UNARY:
+      def service(
+          request_iterator, face_rpc_context,
+          service_behavior=method_description.service_stream_unary):
+        return service_behavior(
+            request_iterator, _reexport.rpc_context(face_rpc_context))
+      implementations[name] = assembly_utilities.stream_unary_inline(service)
+    elif cardinality is interfaces.Cardinality.STREAM_STREAM:
+      def service(
+          request_iterator, face_rpc_context,
+          service_behavior=method_description.service_stream_stream):
+        return service_behavior(
+            request_iterator, _reexport.rpc_context(face_rpc_context))
+      implementations[name] = assembly_utilities.stream_stream_inline(service)
+    request_deserializers[name] = method_description.deserialize_request
+    response_serializers[name] = method_description.serialize_response
+
+  return _EasyServiceBreakdown(
+      implementations, request_deserializers, response_serializers)
diff --git a/src/python/src/grpc/early_adopter/_face_utilities.py b/src/python/src/grpc/early_adopter/_face_utilities.py
deleted file mode 100644
index 3e37b08..0000000
--- a/src/python/src/grpc/early_adopter/_face_utilities.py
+++ /dev/null
@@ -1,178 +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.
-
-import abc
-import collections
-
-from grpc.framework.face import interfaces as face_interfaces
-
-from grpc.early_adopter import interfaces
-
-
-class _InlineUnaryUnaryMethod(face_interfaces.InlineValueInValueOutMethod):
-
-  def __init__(self, unary_unary_server_rpc_method):
-    self._method = unary_unary_server_rpc_method
-
-  def service(self, request, context):
-    """See face_interfaces.InlineValueInValueOutMethod.service for spec."""
-    return self._method.service_unary_unary(request)
-
-
-class _InlineUnaryStreamMethod(face_interfaces.InlineValueInStreamOutMethod):
-
-  def __init__(self, unary_stream_server_rpc_method):
-    self._method = unary_stream_server_rpc_method
-
-  def service(self, request, context):
-    """See face_interfaces.InlineValueInStreamOutMethod.service for spec."""
-    return self._method.service_unary_stream(request)
-
-
-class _InlineStreamUnaryMethod(face_interfaces.InlineStreamInValueOutMethod):
-
-  def __init__(self, stream_unary_server_rpc_method):
-    self._method = stream_unary_server_rpc_method
-
-  def service(self, request_iterator, context):
-    """See face_interfaces.InlineStreamInValueOutMethod.service for spec."""
-    return self._method.service_stream_unary(request_iterator)
-
-
-class _InlineStreamStreamMethod(face_interfaces.InlineStreamInStreamOutMethod):
-
-  def __init__(self, stream_stream_server_rpc_method):
-    self._method = stream_stream_server_rpc_method
-
-  def service(self, request_iterator, context):
-    """See face_interfaces.InlineStreamInStreamOutMethod.service for spec."""
-    return self._method.service_stream_stream(request_iterator)
-
-
-class ClientBreakdown(object):
-  """An intermediate representation of invocation-side views of RPC methods.
-
-  Attributes:
-    request_serializers: A dictionary from RPC method name to callable
-      behavior to be used serializing request values for the RPC.
-    response_deserializers: A dictionary from RPC method name to callable
-      behavior to be used deserializing response values for the RPC.
-  """
-  __metaclass__ = abc.ABCMeta
-
-
-class _EasyClientBreakdown(
-    ClientBreakdown,
-    collections.namedtuple(
-        '_EasyClientBreakdown',
-        ('request_serializers', 'response_deserializers'))):
-  pass
-
-
-class ServerBreakdown(object):
-  """An intermediate representation of implementations of RPC methods.
-
-  Attributes:
-    unary_unary_methods: A dictionary from RPC method name to callable
-      behavior implementing the RPC method for unary-unary RPC methods.
-    unary_stream_methods: A dictionary from RPC method name to callable
-      behavior implementing the RPC method for unary-stream RPC methods.
-    stream_unary_methods: A dictionary from RPC method name to callable
-      behavior implementing the RPC method for stream-unary RPC methods.
-    stream_stream_methods: A dictionary from RPC method name to callable
-      behavior implementing the RPC method for stream-stream RPC methods.
-    request_deserializers: A dictionary from RPC method name to callable
-      behavior to be used deserializing request values for the RPC.
-    response_serializers: A dictionary from RPC method name to callable
-      behavior to be used serializing response values for the RPC.
-  """
-  __metaclass__ = abc.ABCMeta
-
-
-
-class _EasyServerBreakdown(
-    ServerBreakdown,
-    collections.namedtuple(
-        '_EasyServerBreakdown',
-        ('unary_unary_methods', 'unary_stream_methods', 'stream_unary_methods',
-         'stream_stream_methods', 'request_deserializers',
-         'response_serializers'))):
-  pass
-
-
-def client_break_down(methods):
-  """Derives a ClientBreakdown from several interfaces.ClientRpcMethods.
-
-  Args:
-    methods: A dictionary from RPC mthod name to
-      interfaces.ClientRpcMethod object describing the RPCs.
-
-  Returns:
-    A ClientBreakdown corresponding to the given methods.
-  """
-  request_serializers = {}
-  response_deserializers = {}
-  for name, method in methods.iteritems():
-    request_serializers[name] = method.serialize_request
-    response_deserializers[name] = method.deserialize_response
-  return _EasyClientBreakdown(request_serializers, response_deserializers)
-
-
-def server_break_down(methods):
-  """Derives a ServerBreakdown from several interfaces.ServerRpcMethods.
-
-  Args:
-    methods: A dictionary from RPC mthod name to
-      interfaces.ServerRpcMethod object describing the RPCs.
-
-  Returns:
-    A ServerBreakdown corresponding to the given methods.
-  """
-  unary_unary = {}
-  unary_stream = {}
-  stream_unary = {}
-  stream_stream = {}
-  request_deserializers = {}
-  response_serializers = {}
-  for name, method in methods.iteritems():
-    cardinality = method.cardinality()
-    if cardinality is interfaces.Cardinality.UNARY_UNARY:
-      unary_unary[name] = _InlineUnaryUnaryMethod(method)
-    elif cardinality is interfaces.Cardinality.UNARY_STREAM:
-      unary_stream[name] = _InlineUnaryStreamMethod(method)
-    elif cardinality is interfaces.Cardinality.STREAM_UNARY:
-      stream_unary[name] = _InlineStreamUnaryMethod(method)
-    elif cardinality is interfaces.Cardinality.STREAM_STREAM:
-      stream_stream[name] = _InlineStreamStreamMethod(method)
-    request_deserializers[name] = method.deserialize_request
-    response_serializers[name] = method.serialize_response
-
-  return _EasyServerBreakdown(
-      unary_unary, unary_stream, stream_unary, stream_stream,
-      request_deserializers, response_serializers)
diff --git a/src/python/src/grpc/early_adopter/_reexport.py b/src/python/src/grpc/early_adopter/_reexport.py
new file mode 100644
index 0000000..35f4e85
--- /dev/null
+++ b/src/python/src/grpc/early_adopter/_reexport.py
@@ -0,0 +1,212 @@
+# Copyright 2015, Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+from grpc.framework.face import exceptions as face_exceptions
+from grpc.framework.face import interfaces as face_interfaces
+from grpc.framework.foundation import future
+from grpc.early_adopter import exceptions
+from grpc.early_adopter import interfaces
+
+_ABORTION_REEXPORT = {
+    face_interfaces.Abortion.CANCELLED: interfaces.Abortion.CANCELLED,
+    face_interfaces.Abortion.EXPIRED: interfaces.Abortion.EXPIRED,
+    face_interfaces.Abortion.NETWORK_FAILURE:
+        interfaces.Abortion.NETWORK_FAILURE,
+    face_interfaces.Abortion.SERVICED_FAILURE:
+        interfaces.Abortion.SERVICED_FAILURE,
+    face_interfaces.Abortion.SERVICER_FAILURE:
+        interfaces.Abortion.SERVICER_FAILURE,
+}
+
+
+class _RpcError(exceptions.RpcError):
+  pass
+
+
+def _reexport_error(face_rpc_error):
+  if isinstance(face_rpc_error, face_exceptions.CancellationError):
+    return exceptions.CancellationError()
+  elif isinstance(face_rpc_error, face_exceptions.ExpirationError):
+    return exceptions.ExpirationError()
+  else:
+    return _RpcError()
+
+
+def _as_face_abortion_callback(abortion_callback):
+  def face_abortion_callback(face_abortion):
+    abortion_callback(_ABORTION_REEXPORT[face_abortion])
+  return face_abortion_callback
+
+
+class _ReexportedFuture(future.Future):
+
+  def __init__(self, face_future):
+    self._face_future = face_future
+
+  def cancel(self):
+    return self._face_future.cancel()
+
+  def cancelled(self):
+    return self._face_future.cancelled()
+
+  def running(self):
+    return self._face_future.running()
+
+  def done(self):
+    return self._face_future.done()
+
+  def result(self, timeout=None):
+    try:
+      return self._face_future.result(timeout=timeout)
+    except face_exceptions.RpcError as e:
+      raise _reexport_error(e)
+
+  def exception(self, timeout=None):
+    face_error = self._face_future.exception(timeout=timeout)
+    return None if face_error is None else _reexport_error(face_error)
+
+  def traceback(self, timeout=None):
+    return self._face_future.traceback(timeout=timeout)
+
+  def add_done_callback(self, fn):
+    self._face_future.add_done_callback(lambda unused_face_future: fn(self))
+
+
+def _call_reexporting_errors(behavior, *args, **kwargs):
+  try:
+    return behavior(*args, **kwargs)
+  except face_exceptions.RpcError as e:
+    raise _reexport_error(e)
+
+
+def _reexported_future(face_future):
+  return _ReexportedFuture(face_future)
+
+
+class _CancellableIterator(interfaces.CancellableIterator):
+
+  def __init__(self, face_cancellable_iterator):
+    self._face_cancellable_iterator = face_cancellable_iterator
+
+  def __iter__(self):
+    return self
+
+  def next(self):
+    return _call_reexporting_errors(self._face_cancellable_iterator.next)
+
+  def cancel(self):
+    self._face_cancellable_iterator.cancel()
+
+
+class _RpcContext(interfaces.RpcContext):
+
+  def __init__(self, face_rpc_context):
+    self._face_rpc_context = face_rpc_context
+
+  def is_active(self):
+    return self._face_rpc_context.is_active()
+
+  def time_remaining(self):
+    return self._face_rpc_context.time_remaining()
+
+  def add_abortion_callback(self, abortion_callback):
+    self._face_rpc_context.add_abortion_callback(
+        _as_face_abortion_callback(abortion_callback))
+
+
+class _UnaryUnarySyncAsync(interfaces.UnaryUnarySyncAsync):
+
+  def __init__(self, face_unary_unary_sync_async):
+    self._underlying = face_unary_unary_sync_async
+
+  def __call__(self, request, timeout):
+    return _call_reexporting_errors(
+        self._underlying, request, timeout)
+
+  def async(self, request, timeout):
+    return _ReexportedFuture(self._underlying.async(request, timeout))
+
+
+class _StreamUnarySyncAsync(interfaces.StreamUnarySyncAsync):
+
+  def __init__(self, face_stream_unary_sync_async):
+    self._underlying = face_stream_unary_sync_async
+
+  def __call__(self, request_iterator, timeout):
+    return _call_reexporting_errors(
+        self._underlying, request_iterator, timeout)
+
+  def async(self, request_iterator, timeout):
+    return _ReexportedFuture(self._underlying.async(request_iterator, timeout))
+
+
+class _Stub(interfaces.Stub):
+
+  def __init__(self, assembly_stub, cardinalities):
+    self._assembly_stub = assembly_stub
+    self._cardinalities = cardinalities
+
+  def __enter__(self):
+    self._assembly_stub.__enter__()
+    return self
+
+  def __exit__(self, exc_type, exc_val, exc_tb):
+    self._assembly_stub.__exit__(exc_type, exc_val, exc_tb)
+    return False
+
+  def __getattr__(self, attr):
+    underlying_attr = self._assembly_stub.__getattr__(attr)
+    cardinality = self._cardinalities.get(attr)
+    # TODO(nathaniel): unify this trick with its other occurrence in the code.
+    if cardinality is None:
+      for name, cardinality in self._cardinalities.iteritems():
+        last_slash_index = name.rfind('/')
+        if 0 <= last_slash_index and name[last_slash_index + 1:] == attr:
+          break
+      else:
+        raise AttributeError(attr)
+    if cardinality is interfaces.Cardinality.UNARY_UNARY:
+      return _UnaryUnarySyncAsync(underlying_attr)
+    elif cardinality is interfaces.Cardinality.UNARY_STREAM:
+      return lambda request, timeout: _CancellableIterator(
+          underlying_attr(request, timeout))
+    elif cardinality is interfaces.Cardinality.STREAM_UNARY:
+      return _StreamUnarySyncAsync(underlying_attr)
+    elif cardinality is interfaces.Cardinality.STREAM_STREAM:
+      return lambda request_iterator, timeout: _CancellableIterator(
+          underlying_attr(request_iterator, timeout))
+    else:
+      raise AttributeError(attr)
+
+def rpc_context(face_rpc_context):
+  return _RpcContext(face_rpc_context)
+
+
+def stub(assembly_stub, cardinalities):
+  return _Stub(assembly_stub, cardinalities)
diff --git a/src/python/src/grpc/early_adopter/exceptions.py b/src/python/src/grpc/early_adopter/exceptions.py
new file mode 100644
index 0000000..5234d3b
--- /dev/null
+++ b/src/python/src/grpc/early_adopter/exceptions.py
@@ -0,0 +1,48 @@
+# 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.
+
+"""Exceptions raised by GRPC.
+
+Only GRPC should instantiate and raise these exceptions.
+"""
+
+import abc
+
+
+class RpcError(Exception):
+  """Common super type for all exceptions raised by GRPC."""
+  __metaclass__ = abc.ABCMeta
+
+
+class CancellationError(RpcError):
+  """Indicates that an RPC has been cancelled."""
+
+
+class ExpirationError(RpcError):
+  """Indicates that an RPC has expired ("timed out")."""
diff --git a/src/python/src/grpc/early_adopter/implementations.py b/src/python/src/grpc/early_adopter/implementations.py
index 1d76d0f..6195958 100644
--- a/src/python/src/grpc/early_adopter/implementations.py
+++ b/src/python/src/grpc/early_adopter/implementations.py
@@ -31,15 +31,12 @@
 
 import threading
 
-from grpc._adapter import fore
-from grpc.framework.base.packets import implementations as _tickets_implementations
-from grpc.framework.face import implementations as _face_implementations
-from grpc.framework.foundation import logging_pool
-from grpc.early_adopter import _face_utilities
+from grpc._adapter import fore as _fore
+from grpc._adapter import rear as _rear
+from grpc.early_adopter import _assembly_utilities
+from grpc.early_adopter import _reexport
 from grpc.early_adopter import interfaces
-
-_MEGA_TIMEOUT = 60 * 60 * 24
-_THREAD_POOL_SIZE = 80
+from grpc.framework.assembly import implementations as _assembly_implementations
 
 
 class _Server(interfaces.Server):
@@ -48,63 +45,122 @@
     self._lock = threading.Lock()
     self._breakdown = breakdown
     self._port = port
-    self._private_key = private_key
-    self._certificate_chain = certificate_chain
+    if private_key is None or certificate_chain is None:
+      self._key_chain_pairs = ()
+    else:
+      self._key_chain_pairs = ((private_key, certificate_chain),)
 
-    self._pool = None
     self._fore_link = None
-    self._back = None
+    self._server = None
 
-  def start(self):
-    """See interfaces.Server.start for specification."""
+  def _start(self):
     with self._lock:
-      if self._pool is None:
-        self._pool = logging_pool.pool(_THREAD_POOL_SIZE)
-        servicer = _face_implementations.servicer(
-            self._pool,
-            inline_value_in_value_out_methods=self._breakdown.unary_unary_methods,
-            inline_value_in_stream_out_methods=self._breakdown.unary_stream_methods,
-            inline_stream_in_value_out_methods=self._breakdown.stream_unary_methods,
-            inline_stream_in_stream_out_methods=self._breakdown.stream_stream_methods)
-        self._fore_link = fore.ForeLink(
-            self._pool, self._breakdown.request_deserializers,
-            self._breakdown.response_serializers, None,
-            ((self._private_key, self._certificate_chain),), port=self._port)
-        self._fore_link.start()
-        port = self._fore_link.port()
-        self._back = _tickets_implementations.back(
-            servicer, self._pool, self._pool, self._pool, _MEGA_TIMEOUT,
-            _MEGA_TIMEOUT)
-        self._fore_link.join_rear_link(self._back)
-        self._back.join_fore_link(self._fore_link)
-        return port
+      if self._server is None:
+        self._fore_link = _fore.activated_fore_link(
+            self._port, self._breakdown.request_deserializers,
+            self._breakdown.response_serializers, None, self._key_chain_pairs)
+
+        self._server = _assembly_implementations.assemble_service(
+            self._breakdown.implementations, self._fore_link)
+        self._server.start()
       else:
         raise ValueError('Server currently running!')
 
-  def stop(self):
-    """See interfaces.Server.stop for specification."""
+  def _stop(self):
     with self._lock:
-      if self._pool is None:
+      if self._server is None:
         raise ValueError('Server not running!')
       else:
-        self._fore_link.stop()
-        self._pool.shutdown(wait=True)
-        self._pool = None
+        self._server.stop()
+        self._server = None
+        self._fore_link = None
+
+  def __enter__(self):
+    self._start()
+    return self
+
+  def __exit__(self, exc_type, exc_val, exc_tb):
+    self._stop()
+    return False
+
+  def start(self):
+    self._start()
+
+  def stop(self):
+    self._stop()
+
+  def port(self):
+    with self._lock:
+      return self._fore_link.port()
+
+def _build_stub(breakdown, activated_rear_link):
+  assembly_stub = _assembly_implementations.assemble_dynamic_inline_stub(
+      breakdown.implementations, activated_rear_link)
+  return _reexport.stub(assembly_stub, breakdown.cardinalities)
 
 
 def _build_server(methods, port, private_key, certificate_chain):
-  breakdown = _face_utilities.server_break_down(methods)
+  breakdown = _assembly_utilities.break_down_service(methods)
   return _Server(breakdown, port, private_key, certificate_chain)
 
 
+def insecure_stub(methods, host, port):
+  """Constructs an insecure interfaces.Stub.
+
+  Args:
+    methods: A dictionary from RPC method name to
+      interfaces.RpcMethodInvocationDescription describing the RPCs to be
+      supported by the created stub.
+    host: The host to which to connect for RPC service.
+    port: The port to which to connect for RPC service.
+
+  Returns:
+    An interfaces.Stub affording RPC invocation.
+  """
+  breakdown = _assembly_utilities.break_down_invocation(methods)
+  activated_rear_link = _rear.activated_rear_link(
+      host, port, breakdown.request_serializers,
+      breakdown.response_deserializers)
+  return _build_stub(breakdown, activated_rear_link)
+
+
+def secure_stub(
+    methods, host, port, root_certificates, private_key, certificate_chain):
+  """Constructs an insecure interfaces.Stub.
+
+  Args:
+    methods: A dictionary from RPC method name to
+      interfaces.RpcMethodInvocationDescription describing the RPCs to be
+      supported by the created stub.
+    host: The host to which to connect for RPC service.
+    port: The port to which to connect for RPC service.
+    root_certificates: The PEM-encoded root certificates or None to ask for
+      them to be retrieved from a default location.
+    private_key: The PEM-encoded private key to use or None if no private key
+      should be used.
+    certificate_chain: The PEM-encoded certificate chain to use or None if no
+      certificate chain should be used.
+
+  Returns:
+    An interfaces.Stub affording RPC invocation.
+  """
+  breakdown = _assembly_utilities.break_down_invocation(methods)
+  activated_rear_link = _rear.secure_activated_rear_link(
+      host, port, breakdown.request_serializers,
+      breakdown.response_deserializers, root_certificates, private_key,
+      certificate_chain)
+  return _build_stub(breakdown, activated_rear_link)
+
+
 def insecure_server(methods, port):
   """Constructs an insecure interfaces.Server.
 
   Args:
     methods: A dictionary from RPC method name to
-      interfaces.ServerRpcMethod object describing the RPCs to
+      interfaces.RpcMethodServiceDescription describing the RPCs to
       be serviced by the created server.
-    port: The port on which to serve.
+    port: The desired port on which to serve or zero to ask for a port to
+      be automatically selected.
 
   Returns:
     An interfaces.Server that will run with no security and
@@ -118,9 +174,10 @@
 
   Args:
     methods: A dictionary from RPC method name to
-      interfaces.ServerRpcMethod object describing the RPCs to
+      interfaces.RpcMethodServiceDescription describing the RPCs to
       be serviced by the created server.
-    port: The port on which to serve.
+    port: The port on which to serve or zero to ask for a port to be
+      automatically selected.
     private_key: A pem-encoded private key.
     certificate_chain: A pem-encoded certificate chain.
 
diff --git a/src/python/src/grpc/early_adopter/implementations_test.py b/src/python/src/grpc/early_adopter/implementations_test.py
new file mode 100644
index 0000000..9ef06c3
--- /dev/null
+++ b/src/python/src/grpc/early_adopter/implementations_test.py
@@ -0,0 +1,176 @@
+# 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.
+
+# TODO(nathaniel): Expand this test coverage.
+
+"""Test of the GRPC-backed ForeLink and RearLink."""
+
+import unittest
+
+from grpc.early_adopter import implementations
+from grpc.early_adopter import utilities
+from grpc._junkdrawer import math_pb2
+
+DIV = 'Div'
+DIV_MANY = 'DivMany'
+FIB = 'Fib'
+SUM = 'Sum'
+
+def _fibbonacci(limit):
+  left, right = 0, 1
+  for _ in xrange(limit):
+    yield left
+    left, right = right, left + right
+
+
+def _div(request, unused_context):
+  return math_pb2.DivReply(
+      quotient=request.dividend / request.divisor,
+      remainder=request.dividend % request.divisor)
+
+
+def _div_many(request_iterator, unused_context):
+  for request in request_iterator:
+    yield math_pb2.DivReply(
+        quotient=request.dividend / request.divisor,
+        remainder=request.dividend % request.divisor)
+
+
+def _fib(request, unused_context):
+  for number in _fibbonacci(request.limit):
+    yield math_pb2.Num(num=number)
+
+
+def _sum(request_iterator, unused_context):
+  accumulation = 0
+  for request in request_iterator:
+    accumulation += request.num
+  return math_pb2.Num(num=accumulation)
+
+
+_INVOCATION_DESCRIPTIONS = {
+    DIV: utilities.unary_unary_invocation_description(
+        math_pb2.DivArgs.SerializeToString, math_pb2.DivReply.FromString),
+    DIV_MANY: utilities.stream_stream_invocation_description(
+        math_pb2.DivArgs.SerializeToString, math_pb2.DivReply.FromString),
+    FIB: utilities.unary_stream_invocation_description(
+        math_pb2.FibArgs.SerializeToString, math_pb2.Num.FromString),
+    SUM: utilities.stream_unary_invocation_description(
+        math_pb2.Num.SerializeToString, math_pb2.Num.FromString),
+}
+
+_SERVICE_DESCRIPTIONS = {
+    DIV: utilities.unary_unary_service_description(
+        _div, math_pb2.DivArgs.FromString,
+        math_pb2.DivReply.SerializeToString),
+    DIV_MANY: utilities.stream_stream_service_description(
+        _div_many, math_pb2.DivArgs.FromString,
+        math_pb2.DivReply.SerializeToString),
+    FIB: utilities.unary_stream_service_description(
+        _fib, math_pb2.FibArgs.FromString, math_pb2.Num.SerializeToString),
+    SUM: utilities.stream_unary_service_description(
+        _sum, math_pb2.Num.FromString, math_pb2.Num.SerializeToString),
+}
+
+_TIMEOUT = 3
+
+
+class EarlyAdopterImplementationsTest(unittest.TestCase):
+
+  def setUp(self):
+    self.server = implementations.insecure_server(_SERVICE_DESCRIPTIONS, 0)
+    self.server.start()
+    port = self.server.port()
+    self.stub = implementations.insecure_stub(_INVOCATION_DESCRIPTIONS, 'localhost', port)
+
+  def tearDown(self):
+    self.server.stop()
+
+  def testUpAndDown(self):
+    with self.stub:
+      pass
+
+  def testUnaryUnary(self):
+    divisor = 59
+    dividend = 973
+    expected_quotient = dividend / divisor
+    expected_remainder = dividend % divisor
+
+    with self.stub:
+      response = self.stub.Div(
+          math_pb2.DivArgs(divisor=divisor, dividend=dividend), _TIMEOUT)
+      self.assertEqual(expected_quotient, response.quotient)
+      self.assertEqual(expected_remainder, response.remainder)
+
+  def testUnaryStream(self):
+    stream_length = 43
+
+    with self.stub:
+      response_iterator = self.stub.Fib(
+          math_pb2.FibArgs(limit=stream_length), _TIMEOUT)
+      numbers = tuple(response.num for response in response_iterator)
+      for early, middle, later in zip(numbers, numbers[:1], numbers[:2]):
+        self.assertEqual(early + middle, later)
+      self.assertEqual(stream_length, len(numbers))
+
+  def testStreamUnary(self):
+    stream_length = 127
+
+    with self.stub:
+      response_future = self.stub.Sum.async(
+          (math_pb2.Num(num=index) for index in range(stream_length)),
+          _TIMEOUT)
+      self.assertEqual(
+          (stream_length * (stream_length - 1)) / 2,
+          response_future.result().num)
+
+  def testStreamStream(self):
+    stream_length = 179
+    divisor_offset = 71
+    dividend_offset = 1763
+
+    with self.stub:
+      response_iterator = self.stub.DivMany(
+          (math_pb2.DivArgs(
+               divisor=divisor_offset + index,
+               dividend=dividend_offset + index)
+           for index in range(stream_length)),
+          _TIMEOUT)
+      for index, response in enumerate(response_iterator):
+        self.assertEqual(
+            (dividend_offset + index) / (divisor_offset + index),
+            response.quotient)
+        self.assertEqual(
+            (dividend_offset + index) % (divisor_offset + index),
+            response.remainder)
+      self.assertEqual(stream_length, index + 1)
+
+
+if __name__ == '__main__':
+  unittest.main()
diff --git a/src/python/src/grpc/early_adopter/interfaces.py b/src/python/src/grpc/early_adopter/interfaces.py
index 0ec371f..b733873 100644
--- a/src/python/src/grpc/early_adopter/interfaces.py
+++ b/src/python/src/grpc/early_adopter/interfaces.py
@@ -32,6 +32,11 @@
 import abc
 import enum
 
+# exceptions is referenced from specification in this module.
+from grpc.early_adopter import exceptions  # pylint: disable=unused-import
+from grpc.framework.foundation import activated
+from grpc.framework.foundation import future
+
 
 @enum.unique
 class Cardinality(enum.Enum):
@@ -43,24 +48,166 @@
   STREAM_STREAM = 'request-streaming/response-streaming'
 
 
-class RpcMethod(object):
-  """A type for the common aspects of RPC method specifications."""
+@enum.unique
+class Abortion(enum.Enum):
+  """Categories of RPC abortion."""
+
+  CANCELLED = 'cancelled'
+  EXPIRED = 'expired'
+  NETWORK_FAILURE = 'network failure'
+  SERVICED_FAILURE = 'serviced failure'
+  SERVICER_FAILURE = 'servicer failure'
+
+
+class CancellableIterator(object):
+  """Implements the Iterator protocol and affords a cancel method."""
   __metaclass__ = abc.ABCMeta
 
   @abc.abstractmethod
-  def cardinality(self):
-    """Identifies the cardinality of this RpcMethod.
+  def __iter__(self):
+    """Returns the self object in accordance with the Iterator protocol."""
+    raise NotImplementedError()
 
+  @abc.abstractmethod
+  def next(self):
+    """Returns a value or raises StopIteration per the Iterator protocol."""
+    raise NotImplementedError()
+
+  @abc.abstractmethod
+  def cancel(self):
+    """Requests cancellation of whatever computation underlies this iterator."""
+    raise NotImplementedError()
+
+
+class RpcContext(object):
+  """Provides RPC-related information and action."""
+  __metaclass__ = abc.ABCMeta
+
+  @abc.abstractmethod
+  def is_active(self):
+    """Describes whether the RPC is active or has terminated."""
+    raise NotImplementedError()
+
+  @abc.abstractmethod
+  def time_remaining(self):
+    """Describes the length of allowed time remaining for the RPC.
     Returns:
-      A Cardinality value identifying whether or not this
-        RpcMethod is request-unary or request-streaming and
-        whether or not it is response-unary or
-        response-streaming.
+      A nonnegative float indicating the length of allowed time in seconds
+      remaining for the RPC to complete before it is considered to have timed
+      out.
+    """
+    raise NotImplementedError()
+
+  @abc.abstractmethod
+  def add_abortion_callback(self, abortion_callback):
+    """Registers a callback to be called if the RPC is aborted.
+    Args:
+      abortion_callback: A callable to be called and passed an Abortion value
+        in the event of RPC abortion.
     """
     raise NotImplementedError()
 
 
-class ClientRpcMethod(RpcMethod):
+class UnaryUnarySyncAsync(object):
+  """Affords invoking a unary-unary RPC synchronously or asynchronously.
+  Values implementing this interface are directly callable and present an
+  "async" method. Both calls take a request value and a numeric timeout.
+  Direct invocation of a value of this type invokes its associated RPC and
+  blocks until the RPC's response is available. Calling the "async" method
+  of a value of this type invokes its associated RPC and immediately returns a
+  future.Future bound to the asynchronous execution of the RPC.
+  """
+  __metaclass__ = abc.ABCMeta
+
+  @abc.abstractmethod
+  def __call__(self, request, timeout):
+    """Synchronously invokes the underlying RPC.
+    Args:
+      request: The request value for the RPC.
+      timeout: A duration of time in seconds to allow for the RPC.
+    Returns:
+      The response value for the RPC.
+    Raises:
+      exceptions.RpcError: Indicating that the RPC was aborted.
+    """
+    raise NotImplementedError()
+
+  @abc.abstractmethod
+  def async(self, request, timeout):
+    """Asynchronously invokes the underlying RPC.
+    Args:
+      request: The request value for the RPC.
+      timeout: A duration of time in seconds to allow for the RPC.
+    Returns:
+      A future.Future representing the RPC. In the event of RPC completion, the
+        returned Future's result value will be the response value of the RPC.
+        In the event of RPC abortion, the returned Future's exception value
+        will be an exceptions.RpcError.
+    """
+    raise NotImplementedError()
+
+
+class StreamUnarySyncAsync(object):
+  """Affords invoking a stream-unary RPC synchronously or asynchronously.
+  Values implementing this interface are directly callable and present an
+  "async" method. Both calls take an iterator of request values and a numeric
+  timeout. Direct invocation of a value of this type invokes its associated RPC
+  and blocks until the RPC's response is available. Calling the "async" method
+  of a value of this type invokes its associated RPC and immediately returns a
+  future.Future bound to the asynchronous execution of the RPC.
+  """
+  __metaclass__ = abc.ABCMeta
+
+  @abc.abstractmethod
+  def __call__(self, request_iterator, timeout):
+    """Synchronously invokes the underlying RPC.
+
+    Args:
+      request_iterator: An iterator that yields request values for the RPC.
+      timeout: A duration of time in seconds to allow for the RPC.
+
+    Returns:
+      The response value for the RPC.
+
+    Raises:
+      exceptions.RpcError: Indicating that the RPC was aborted.
+    """
+    raise NotImplementedError()
+
+  @abc.abstractmethod
+  def async(self, request_iterator, timeout):
+    """Asynchronously invokes the underlying RPC.
+
+    Args:
+      request_iterator: An iterator that yields request values for the RPC.
+      timeout: A duration of time in seconds to allow for the RPC.
+
+    Returns:
+      A future.Future representing the RPC. In the event of RPC completion, the
+        returned Future's result value will be the response value of the RPC.
+        In the event of RPC abortion, the returned Future's exception value
+        will be an exceptions.RpcError.
+    """
+    raise NotImplementedError()
+
+
+class RpcMethodDescription(object):
+  """A type for the common aspects of RPC method descriptions."""
+  __metaclass__ = abc.ABCMeta
+
+  @abc.abstractmethod
+  def cardinality(self):
+    """Identifies the cardinality of this RpcMethodDescription.
+
+    Returns:
+      A Cardinality value identifying whether or not this
+        RpcMethodDescription is request-unary or request-streaming and
+        whether or not it is response-unary or response-streaming.
+    """
+    raise NotImplementedError()
+
+
+class RpcMethodInvocationDescription(RpcMethodDescription):
   """Invocation-side description of an RPC method."""
   __metaclass__ = abc.ABCMeta
 
@@ -69,7 +216,8 @@
     """Serializes a request value.
 
     Args:
-      request: A request value appropriate for this RpcMethod.
+      request: A request value appropriate for the RPC method described by this
+        RpcMethodInvocationDescription.
 
     Returns:
       The serialization of the given request value as a
@@ -82,9 +230,9 @@
     """Deserializes a response value.
 
     Args:
-      serialized_response: A bytestring that is the
-        serialization of a response value appropriate for this
-        RpcMethod.
+      serialized_response: A bytestring that is the serialization of a response
+        value appropriate for the RPC method described by this
+        RpcMethodInvocationDescription.
 
     Returns:
       A response value corresponding to the given bytestring.
@@ -92,7 +240,7 @@
     raise NotImplementedError()
 
 
-class ServerRpcMethod(RpcMethod):
+class RpcMethodServiceDescription(RpcMethodDescription):
   """Service-side description of an RPC method."""
   __metaclass__ = abc.ABCMeta
 
@@ -101,9 +249,9 @@
     """Deserializes a request value.
 
     Args:
-      serialized_request: A bytestring that is the
-        serialization of a request value appropriate for this
-        RpcMethod.
+      serialized_request: A bytestring that is the serialization of a request
+        value appropriate for the RPC method described by this
+        RpcMethodServiceDescription.
 
     Returns:
       A request value corresponding to the given bytestring.
@@ -115,7 +263,8 @@
     """Serializes a response value.
 
     Args:
-      response: A response value appropriate for this RpcMethod.
+      response: A response value appropriate for the RPC method described by
+        this RpcMethodServiceDescription.
 
     Returns:
       The serialization of the given response value as a
@@ -124,80 +273,116 @@
     raise NotImplementedError()
 
   @abc.abstractmethod
-  def service_unary_unary(self, request):
+  def service_unary_unary(self, request, context):
     """Carries out this RPC.
 
     This method may only be called if the cardinality of this
-    RpcMethod is Cardinality.UNARY_UNARY.
+    RpcMethodServiceDescription is Cardinality.UNARY_UNARY.
 
     Args:
-      request: A request value appropriate for this RpcMethod.
+      request: A request value appropriate for the RPC method described by this
+        RpcMethodServiceDescription.
+      context: An RpcContext object for the RPC.
 
     Returns:
-      A response value appropriate for this RpcMethod.
+      A response value appropriate for the RPC method described by this
+        RpcMethodServiceDescription.
     """
     raise NotImplementedError()
 
   @abc.abstractmethod
-  def service_unary_stream(self, request):
+  def service_unary_stream(self, request, context):
     """Carries out this RPC.
 
     This method may only be called if the cardinality of this
-    RpcMethod is Cardinality.UNARY_STREAM.
+    RpcMethodServiceDescription is Cardinality.UNARY_STREAM.
 
     Args:
-      request: A request value appropriate for this RpcMethod.
+      request: A request value appropriate for the RPC method described by this
+        RpcMethodServiceDescription.
+      context: An RpcContext object for the RPC.
 
     Yields:
-      Zero or more response values appropriate for this
-        RpcMethod.
+      Zero or more response values appropriate for the RPC method described by
+        this RpcMethodServiceDescription.
     """
     raise NotImplementedError()
 
   @abc.abstractmethod
-  def service_stream_unary(self, request_iterator):
+  def service_stream_unary(self, request_iterator, context):
     """Carries out this RPC.
 
     This method may only be called if the cardinality of this
-    RpcMethod is Cardinality.STREAM_UNARY.
+    RpcMethodServiceDescription is Cardinality.STREAM_UNARY.
 
     Args:
-      request_iterator: An iterator of request values
-        appropriate for this RpcMethod.
+      request_iterator: An iterator of request values appropriate for the RPC
+        method described by this RpcMethodServiceDescription.
+      context: An RpcContext object for the RPC.
 
     Returns:
-      A response value appropriate for this RpcMethod.
+      A response value appropriate for the RPC method described by this
+        RpcMethodServiceDescription.
     """
     raise NotImplementedError()
 
   @abc.abstractmethod
-  def service_stream_stream(self, request_iterator):
+  def service_stream_stream(self, request_iterator, context):
     """Carries out this RPC.
 
     This method may only be called if the cardinality of this
-    RpcMethod is Cardinality.STREAM_STREAM.
+    RpcMethodServiceDescription is Cardinality.STREAM_STREAM.
 
     Args:
-      request_iterator: An iterator of request values
-        appropriate for this RpcMethod.
+      request_iterator: An iterator of request values appropriate for the RPC
+        method described by this RpcMethodServiceDescription.
+      context: An RpcContext object for the RPC.
 
     Yields:
-      Zero or more response values appropraite for this
-        RpcMethod.
+      Zero or more response values appropriate for the RPC method described by
+        this RpcMethodServiceDescription.
     """
     raise NotImplementedError()
 
 
-class Server(object):
+class Stub(object):
+  """A stub with callable RPC method names for attributes.
+
+  Instances of this type are context managers and only afford RPC invocation
+  when used in context.
+
+  Instances of this type, when used in context, respond to attribute access
+  as follows: if the requested attribute is the name of a unary-unary RPC
+  method, the value of the attribute will be a UnaryUnarySyncAsync with which
+  to invoke the RPC method. If the requested attribute is the name of a
+  unary-stream RPC method, the value of the attribute will be a callable taking
+  a request object and a timeout parameter and returning a CancellableIterator
+  that yields the response values of the RPC. If the requested attribute is the
+  name of a stream-unary RPC method, the value of the attribute will be a
+  StreamUnarySyncAsync with which to invoke the RPC method. If the requested
+  attribute is the name of a stream-stream RPC method, the value of the
+  attribute will be a callable taking an iterator of request objects and a
+  timeout and returning a CancellableIterator that yields the response values
+  of the RPC.
+
+  In all cases indication of abortion is indicated by raising of
+  exceptions.RpcError, exceptions.CancellationError,
+  and exceptions.ExpirationError.
+  """
+  __metaclass__ = abc.ABCMeta
+
+
+class Server(activated.Activated):
   """A GRPC Server."""
   __metaclass__ = abc.ABCMeta
 
   @abc.abstractmethod
-  def start(self):
-    """Instructs this server to commence service of RPCs."""
-    raise NotImplementedError()
+  def port(self):
+    """Reports the port on which the server is serving.
 
-  @abc.abstractmethod
-  def stop(self):
-    """Instructs this server to halt service of RPCs."""
+    This method may only be called while the server is activated.
+
+    Returns:
+      The port on which the server is serving.
+    """
     raise NotImplementedError()
diff --git a/src/python/src/grpc/early_adopter/utilities.py b/src/python/src/grpc/early_adopter/utilities.py
index 9277d3f..da8ef82 100644
--- a/src/python/src/grpc/early_adopter/utilities.py
+++ b/src/python/src/grpc/early_adopter/utilities.py
@@ -32,7 +32,9 @@
 from grpc.early_adopter import interfaces
 
 
-class _RpcMethod(interfaces.ClientRpcMethod, interfaces.ServerRpcMethod):
+class _RpcMethodDescription(
+    interfaces.RpcMethodInvocationDescription,
+    interfaces.RpcMethodServiceDescription):
 
   def __init__(
       self, cardinality, unary_unary, unary_stream, stream_unary,
@@ -49,44 +51,45 @@
     self._response_deserializer = response_deserializer
 
   def cardinality(self):
-    """See interfaces.RpcMethod.cardinality for specification."""
+    """See interfaces.RpcMethodDescription.cardinality for specification."""
     return self._cardinality
 
   def serialize_request(self, request):
-    """See interfaces.RpcMethod.serialize_request for specification."""
+    """See interfaces.RpcMethodInvocationDescription.serialize_request."""
     return self._request_serializer(request)
 
   def deserialize_request(self, serialized_request):
-    """See interfaces.RpcMethod.deserialize_request for specification."""
+    """See interfaces.RpcMethodServiceDescription.deserialize_request."""
     return self._request_deserializer(serialized_request)
 
   def serialize_response(self, response):
-    """See interfaces.RpcMethod.serialize_response for specification."""
+    """See interfaces.RpcMethodServiceDescription.serialize_response."""
     return self._response_serializer(response)
 
   def deserialize_response(self, serialized_response):
-    """See interfaces.RpcMethod.deserialize_response for specification."""
+    """See interfaces.RpcMethodInvocationDescription.deserialize_response."""
     return self._response_deserializer(serialized_response)
 
-  def service_unary_unary(self, request):
-    """See interfaces.RpcMethod.service_unary_unary for specification."""
-    return self._unary_unary(request)
+  def service_unary_unary(self, request, context):
+    """See interfaces.RpcMethodServiceDescription.service_unary_unary."""
+    return self._unary_unary(request, context)
 
-  def service_unary_stream(self, request):
-    """See interfaces.RpcMethod.service_unary_stream for specification."""
-    return self._unary_stream(request)
+  def service_unary_stream(self, request, context):
+    """See interfaces.RpcMethodServiceDescription.service_unary_stream."""
+    return self._unary_stream(request, context)
 
-  def service_stream_unary(self, request_iterator):
-    """See interfaces.RpcMethod.service_stream_unary for specification."""
-    return self._stream_unary(request_iterator)
+  def service_stream_unary(self, request_iterator, context):
+    """See interfaces.RpcMethodServiceDescription.service_stream_unary."""
+    return self._stream_unary(request_iterator, context)
 
-  def service_stream_stream(self, request_iterator):
-    """See interfaces.RpcMethod.service_stream_stream for specification."""
-    return self._stream_stream(request_iterator)
+  def service_stream_stream(self, request_iterator, context):
+    """See interfaces.RpcMethodServiceDescription.service_stream_stream."""
+    return self._stream_stream(request_iterator, context)
 
 
-def unary_unary_client_rpc_method(request_serializer, response_deserializer):
-  """Constructs an interfaces.ClientRpcMethod for a unary-unary RPC method.
+def unary_unary_invocation_description(
+    request_serializer, response_deserializer):
+  """Creates an interfaces.RpcMethodInvocationDescription for an RPC method.
 
   Args:
     request_serializer: A callable that when called on a request
@@ -96,17 +99,17 @@
       that bytestring.
 
   Returns:
-    An interfaces.ClientRpcMethod constructed from the given
-      arguments representing a unary-request/unary-response RPC
-      method.
+    An interfaces.RpcMethodInvocationDescription constructed from the given
+      arguments representing a unary-request/unary-response RPC method.
   """
-  return _RpcMethod(
+  return _RpcMethodDescription(
       interfaces.Cardinality.UNARY_UNARY, None, None, None, None,
       request_serializer, None, None, response_deserializer)
 
 
-def unary_stream_client_rpc_method(request_serializer, response_deserializer):
-  """Constructs an interfaces.ClientRpcMethod for a unary-stream RPC method.
+def unary_stream_invocation_description(
+    request_serializer, response_deserializer):
+  """Creates an interfaces.RpcMethodInvocationDescription for an RPC method.
 
   Args:
     request_serializer: A callable that when called on a request
@@ -116,17 +119,17 @@
       that bytestring.
 
   Returns:
-    An interfaces.ClientRpcMethod constructed from the given
-      arguments representing a unary-request/streaming-response
-      RPC method.
+    An interfaces.RpcMethodInvocationDescription constructed from the given
+      arguments representing a unary-request/streaming-response RPC method.
   """
-  return _RpcMethod(
+  return _RpcMethodDescription(
       interfaces.Cardinality.UNARY_STREAM, None, None, None, None,
       request_serializer, None, None, response_deserializer)
 
 
-def stream_unary_client_rpc_method(request_serializer, response_deserializer):
-  """Constructs an interfaces.ClientRpcMethod for a stream-unary RPC method.
+def stream_unary_invocation_description(
+    request_serializer, response_deserializer):
+  """Creates an interfaces.RpcMethodInvocationDescription for an RPC method.
 
   Args:
     request_serializer: A callable that when called on a request
@@ -136,17 +139,17 @@
       that bytestring.
 
   Returns:
-    An interfaces.ClientRpcMethod constructed from the given
-      arguments representing a streaming-request/unary-response
-      RPC method.
+    An interfaces.RpcMethodInvocationDescription constructed from the given
+      arguments representing a streaming-request/unary-response RPC method.
   """
-  return _RpcMethod(
+  return _RpcMethodDescription(
       interfaces.Cardinality.STREAM_UNARY, None, None, None, None,
       request_serializer, None, None, response_deserializer)
 
 
-def stream_stream_client_rpc_method(request_serializer, response_deserializer):
-  """Constructs an interfaces.ClientRpcMethod for a stream-stream RPC method.
+def stream_stream_invocation_description(
+    request_serializer, response_deserializer):
+  """Creates an interfaces.RpcMethodInvocationDescription for an RPC method.
 
   Args:
     request_serializer: A callable that when called on a request
@@ -156,23 +159,23 @@
       that bytestring.
 
   Returns:
-    An interfaces.ClientRpcMethod constructed from the given
-      arguments representing a
-      streaming-request/streaming-response RPC method.
+    An interfaces.RpcMethodInvocationDescription constructed from the given
+      arguments representing a  streaming-request/streaming-response RPC
+      method.
   """
-  return _RpcMethod(
+  return _RpcMethodDescription(
       interfaces.Cardinality.STREAM_STREAM, None, None, None, None,
       request_serializer, None, None, response_deserializer)
 
 
-def unary_unary_server_rpc_method(
+def unary_unary_service_description(
     behavior, request_deserializer, response_serializer):
-  """Constructs an interfaces.ServerRpcMethod for the given behavior.
+  """Creates an interfaces.RpcMethodServiceDescription for the given behavior.
 
   Args:
     behavior: A callable that implements a unary-unary RPC
-      method that accepts a single request and returns a single
-      response.
+      method that accepts a single request and an interfaces.RpcContext and
+      returns a single response.
     request_deserializer: A callable that when called on a
       bytestring returns the request value corresponding to that
       bytestring.
@@ -181,72 +184,22 @@
       that value.
 
   Returns:
-    An interfaces.ServerRpcMethod constructed from the given
+    An interfaces.RpcMethodServiceDescription constructed from the given
       arguments representing a unary-request/unary-response RPC
       method.
   """
-  return _RpcMethod(
+  return _RpcMethodDescription(
       interfaces.Cardinality.UNARY_UNARY, behavior, None, None, None,
       None, request_deserializer, response_serializer, None)
 
 
-def unary_stream_server_rpc_method(
+def unary_stream_service_description(
     behavior, request_deserializer, response_serializer):
-  """Constructs an interfaces.ServerRpcMethod for the given behavior.
+  """Creates an interfaces.RpcMethodServiceDescription for the given behavior.
 
   Args:
     behavior: A callable that implements a unary-stream RPC
-      method that accepts a single request and returns an
-      iterator of zero or more responses.
-    request_deserializer: A callable that when called on a
-      bytestring returns the request value corresponding to that
-      bytestring.
-    response_serializer: A callable that when called on a
-      response value returns the bytestring corresponding to
-      that value.
-
-  Returns:
-    An interfaces.ServerRpcMethod constructed from the given
-      arguments representing a unary-request/streaming-response
-      RPC method.
-  """
-  return _RpcMethod(
-      interfaces.Cardinality.UNARY_STREAM, None, behavior, None, None,
-      None, request_deserializer, response_serializer, None)
-
-
-def stream_unary_server_rpc_method(
-    behavior, request_deserializer, response_serializer):
-  """Constructs an interfaces.ServerRpcMethod for the given behavior.
-
-  Args:
-    behavior: A callable that implements a stream-unary RPC
-      method that accepts an iterator of zero or more requests
-      and returns a single response.
-    request_deserializer: A callable that when called on a
-      bytestring returns the request value corresponding to that
-      bytestring.
-    response_serializer: A callable that when called on a
-      response value returns the bytestring corresponding to
-      that value.
-
-  Returns:
-    An interfaces.ServerRpcMethod constructed from the given
-      arguments representing a streaming-request/unary-response
-      RPC method.
-  """
-  return _RpcMethod(
-      interfaces.Cardinality.STREAM_UNARY, None, None, behavior, None,
-      None, request_deserializer, response_serializer, None)
-
-
-def stream_stream_server_rpc_method(
-    behavior, request_deserializer, response_serializer):
-  """Constructs an interfaces.ServerRpcMethod for the given behavior.
-
-  Args:
-    behavior: A callable that implements a stream-stream RPC
-      method that accepts an iterator of zero or more requests
+      method that accepts a single request and an interfaces.RpcContext
       and returns an iterator of zero or more responses.
     request_deserializer: A callable that when called on a
       bytestring returns the request value corresponding to that
@@ -256,10 +209,61 @@
       that value.
 
   Returns:
-    An interfaces.ServerRpcMethod constructed from the given
+    An interfaces.RpcMethodServiceDescription constructed from the given
+      arguments representing a unary-request/streaming-response
+      RPC method.
+  """
+  return _RpcMethodDescription(
+      interfaces.Cardinality.UNARY_STREAM, None, behavior, None, None,
+      None, request_deserializer, response_serializer, None)
+
+
+def stream_unary_service_description(
+    behavior, request_deserializer, response_serializer):
+  """Creates an interfaces.RpcMethodServiceDescription for the given behavior.
+
+  Args:
+    behavior: A callable that implements a stream-unary RPC
+      method that accepts an iterator of zero or more requests
+      and an interfaces.RpcContext and returns a single response.
+    request_deserializer: A callable that when called on a
+      bytestring returns the request value corresponding to that
+      bytestring.
+    response_serializer: A callable that when called on a
+      response value returns the bytestring corresponding to
+      that value.
+
+  Returns:
+    An interfaces.RpcMethodServiceDescription constructed from the given
+      arguments representing a streaming-request/unary-response
+      RPC method.
+  """
+  return _RpcMethodDescription(
+      interfaces.Cardinality.STREAM_UNARY, None, None, behavior, None,
+      None, request_deserializer, response_serializer, None)
+
+
+def stream_stream_service_description(
+    behavior, request_deserializer, response_serializer):
+  """Creates an interfaces.RpcMethodServiceDescription for the given behavior.
+
+  Args:
+    behavior: A callable that implements a stream-stream RPC
+      method that accepts an iterator of zero or more requests
+      and an interfaces.RpcContext and returns an iterator of
+      zero or more responses.
+    request_deserializer: A callable that when called on a
+      bytestring returns the request value corresponding to that
+      bytestring.
+    response_serializer: A callable that when called on a
+      response value returns the bytestring corresponding to
+      that value.
+
+  Returns:
+    An interfaces.RpcMethodServiceDescription constructed from the given
       arguments representing a
       streaming-request/streaming-response RPC method.
   """
-  return _RpcMethod(
+  return _RpcMethodDescription(
       interfaces.Cardinality.STREAM_STREAM, None, None, None, behavior,
       None, request_deserializer, response_serializer, None)
diff --git a/src/python/src/grpc/framework/assembly/implementations.py b/src/python/src/grpc/framework/assembly/implementations.py
index b9d3148..f7166ed 100644
--- a/src/python/src/grpc/framework/assembly/implementations.py
+++ b/src/python/src/grpc/framework/assembly/implementations.py
@@ -31,16 +31,18 @@
 
 import threading
 
+# tickets_interfaces, face_interfaces, and activated are referenced from
+# specification in this module.
 from grpc.framework.assembly import interfaces
 from grpc.framework.base import util as base_utilities
 from grpc.framework.base.packets import implementations as tickets_implementations
-from grpc.framework.base.packets import interfaces as tickets_interfaces
+from grpc.framework.base.packets import interfaces as tickets_interfaces  # pylint: disable=unused-import
 from grpc.framework.common import cardinality
 from grpc.framework.common import style
 from grpc.framework.face import implementations as face_implementations
-from grpc.framework.face import interfaces as face_interfaces
+from grpc.framework.face import interfaces as face_interfaces  # pylint: disable=unused-import
 from grpc.framework.face import utilities as face_utilities
-from grpc.framework.foundation import activated
+from grpc.framework.foundation import activated  # pylint: disable=unused-import
 from grpc.framework.foundation import logging_pool
 
 _ONE_DAY_IN_SECONDS = 60 * 60 * 24
@@ -138,7 +140,13 @@
     with self._lock:
       behavior = self._behaviors.get(attr)
       if behavior is None:
-        raise AttributeError(attr)
+        for name, behavior in self._behaviors.iteritems():
+          last_slash_index = name.rfind('/')
+          if 0 <= last_slash_index and name[last_slash_index + 1:] == attr:
+            return behavior
+        else:
+          raise AttributeError(
+              '_DynamicInlineStub instance has no attribute "%s"!' % attr)
       else:
         return behavior
 
diff --git a/src/python/src/setup.py b/src/python/src/setup.py
index e3f13fa..26121dc 100644
--- a/src/python/src/setup.py
+++ b/src/python/src/setup.py
@@ -38,6 +38,7 @@
     'grpc/_adapter/_completion_queue.c',
     'grpc/_adapter/_error.c',
     'grpc/_adapter/_server.c',
+    'grpc/_adapter/_client_credentials.c',
     'grpc/_adapter/_server_credentials.c',
 )
 
@@ -80,6 +81,6 @@
 }
 
 _core.setup(
-    name='grpc-2015', version='0.0.1',
+    name='grpc-2015', version='0.4.0',
     ext_modules=[_EXTENSION_MODULE], packages=_PACKAGES,
     package_dir=_PACKAGE_DIRECTORIES)
diff --git a/src/ruby/bin/apis/pubsub_demo.rb b/src/ruby/bin/apis/pubsub_demo.rb
index 6656a56..9bb324f 100755
--- a/src/ruby/bin/apis/pubsub_demo.rb
+++ b/src/ruby/bin/apis/pubsub_demo.rb
@@ -31,10 +31,9 @@
 
 # pubsub_demo demos accesses the Google PubSub API via its gRPC interface
 #
-# TODO: update the Usage once the usable auth gem is available
-# $ SSL_CERT_FILE=<path/to/ssl/certs> \
+# $ GOOGLE_APPLICATION_CREDENTIALS=<path_to_service_account_key_file> \
+#   SSL_CERT_FILE=<path/to/ssl/certs> \
 #   path/to/pubsub_demo.rb \
-#   --service_account_key_file=<path_to_service_account> \
 #   [--action=<chosen_demo_action> ]
 #
 # There are options related to the chosen action, see #parse_args below.
@@ -49,6 +48,7 @@
 require 'optparse'
 
 require 'grpc'
+require 'googleauth'
 require 'google/protobuf'
 
 require 'google/protobuf/empty'
@@ -59,7 +59,9 @@
 def load_prod_cert
   fail 'could not find a production cert' if ENV['SSL_CERT_FILE'].nil?
   p "loading prod certs from #{ENV['SSL_CERT_FILE']}"
-  File.open(ENV['SSL_CERT_FILE']).read
+  File.open(ENV['SSL_CERT_FILE']) do |f|
+    return f.read
+  end
 end
 
 # creates a SSL Credentials from the production certificates.
@@ -68,14 +70,9 @@
 end
 
 # Builds the metadata authentication update proc.
-#
-# TODO: replace this once the ruby usable auth repo is available.
 def auth_proc(opts)
-  if GRPC::Auth::GCECredentials.on_gce?
-    return GRPC::Auth::GCECredentials.new.updater_proc
-  end
-  fd = StringIO.new(File.read(opts.oauth_key_file))
-  GRPC::Auth::ServiceAccountCredentials.new(opts.oauth_scope, fd).updater_proc
+  auth_creds = Google::Auth.get_application_default(opts.oauth_scope)
+  return auth_creds.updater_proc
 end
 
 # Creates a stub for accessing the publisher service.
@@ -216,14 +213,14 @@
 end
 
 # Args is used to hold the command line info.
-Args = Struct.new(:host, :oauth_scope, :oauth_key_file, :port, :action,
-                  :project_id, :topic_name, :sub_name)
+Args = Struct.new(:host, :oauth_scope, :port, :action, :project_id, :topic_name,
+                  :sub_name)
 
 # validates the the command line options, returning them as an Arg.
 def parse_args
   args = Args.new('pubsub-staging.googleapis.com',
                   'https://www.googleapis.com/auth/pubsub',
-                  nil, 443, 'list_some_topics', 'stoked-keyword-656')
+                   443, 'list_some_topics', 'stoked-keyword-656')
   OptionParser.new do |opts|
     opts.on('--oauth_scope scope',
             'Scope for OAuth tokens') { |v| args['oauth_scope'] = v }
@@ -233,10 +230,6 @@
     opts.on('--server_port SERVER_PORT', 'server port') do |v|
       args.port = v
     end
-    opts.on('--service_account_key_file PATH',
-            'Path to the service account json key file') do |v|
-      args.oauth_key_file = v
-    end
 
     # instance_methods(false) gives only the methods defined in that class.
     scenes = NamedActions.instance_methods(false).map { |t| t.to_s }
@@ -257,15 +250,11 @@
 end
 
 def _check_args(args)
-  %w(host port action).each do |a|
+  %w(host port action oauth_scope).each do |a|
     if args[a].nil?
       raise OptionParser::MissingArgument.new("please specify --#{a}")
     end
   end
-  if args['oauth_key_file'].nil? || args['oauth_scope'].nil?
-    fail(OptionParser::MissingArgument,
-         'please specify both of --service_account_key_file and --oauth_scope')
-  end
   args
 end
 
diff --git a/src/ruby/bin/interop/interop_client.rb b/src/ruby/bin/interop/interop_client.rb
index 76402b7..b0b24b9 100755
--- a/src/ruby/bin/interop/interop_client.rb
+++ b/src/ruby/bin/interop/interop_client.rb
@@ -48,6 +48,7 @@
 require 'minitest/assertions'
 
 require 'grpc'
+require 'googleauth'
 require 'google/protobuf'
 
 require 'test/cpp/interop/test_services'
@@ -56,7 +57,7 @@
 
 require 'signet/ssl_config'
 
-include GRPC::Auth
+AUTH_ENV = Google::Auth::ServiceAccountCredentials::ENV_VAR
 
 # loads the certificates used to access the test server securely.
 def load_test_certs
@@ -101,22 +102,14 @@
     }
 
     # Add service account creds if specified
-    if %w(all service_account_creds).include?(opts.test_case)
+    wants_creds = %w(all compute_engine_creds service_account_creds)
+    if wants_creds.include?(opts.test_case)
       unless opts.oauth_scope.nil?
-        fd = StringIO.new(File.read(opts.oauth_key_file))
-        logger.info("loading oauth certs from #{opts.oauth_key_file}")
-        auth_creds = ServiceAccountCredentials.new(opts.oauth_scope, fd)
+        auth_creds = Google::Auth.get_application_default(opts.oauth_scope)
         stub_opts[:update_metadata] = auth_creds.updater_proc
       end
     end
 
-    # Add compute engine creds if specified
-    if %w(all compute_engine_creds).include?(opts.test_case)
-      unless opts.oauth_scope.nil?
-        stub_opts[:update_metadata] = GCECredentials.new.update_proc
-      end
-    end
-
     logger.info("... connecting securely to #{address}")
     Grpc::Testing::TestService::Stub.new(address, **stub_opts)
   else
@@ -193,11 +186,11 @@
 
   def service_account_creds
     # ignore this test if the oauth options are not set
-    if @args.oauth_scope.nil? || @args.oauth_key_file.nil?
+    if @args.oauth_scope.nil?
       p 'NOT RUN: service_account_creds; no service_account settings'
       return
     end
-    json_key = File.read(@args.oauth_key_file)
+    json_key = File.read(ENV[AUTH_ENV])
     wanted_email = MultiJson.load(json_key)['client_email']
     resp = perform_large_unary(fill_username: true,
                                fill_oauth_scope: true)
@@ -285,13 +278,13 @@
 
 # Args is used to hold the command line info.
 Args = Struct.new(:default_service_account, :host, :host_override,
-                  :oauth_scope, :oauth_key_file, :port, :secure, :test_case,
+                  :oauth_scope, :port, :secure, :test_case,
                   :use_test_ca)
 
 # validates the the command line options, returning them as a Hash.
 def parse_args
   args = Args.new
-  args.host_override = 'foo.test.google.com'
+  args.host_override = 'foo.test.google.fr'
   OptionParser.new do |opts|
     opts.on('--oauth_scope scope',
             'Scope for OAuth tokens') { |v| args['oauth_scope'] = v }
@@ -302,10 +295,6 @@
             'email address of the default service account') do |v|
       args['default_service_account'] = v
     end
-    opts.on('--service_account_key_file PATH',
-            'Path to the service account json key file') do |v|
-      args['oauth_key_file'] = v
-    end
     opts.on('--server_host_override HOST_OVERRIDE',
             'override host via a HTTP header') do |v|
       args['host_override'] = v
@@ -333,10 +322,6 @@
       fail(OptionParser::MissingArgument, "please specify --#{arg}")
     end
   end
-  if args['oauth_key_file'].nil? ^ args['oauth_scope'].nil?
-    fail(OptionParser::MissingArgument,
-         'please specify both of --service_account_key_file and --oauth_scope')
-  end
   args
 end
 
diff --git a/src/ruby/bin/math_client.rb b/src/ruby/bin/math_client.rb
index cb085d4..db254ef 100755
--- a/src/ruby/bin/math_client.rb
+++ b/src/ruby/bin/math_client.rb
@@ -127,7 +127,7 @@
   if options['secure']
     stub_opts = {
       :creds => test_creds,
-      GRPC::Core::Channel::SSL_TARGET => 'foo.test.google.com'
+      GRPC::Core::Channel::SSL_TARGET => 'foo.test.google.fr'
     }
     p stub_opts
     p options['host']
diff --git a/src/ruby/bin/noproto_client.rb b/src/ruby/bin/noproto_client.rb
index 4471052..f3fd110 100755
--- a/src/ruby/bin/noproto_client.rb
+++ b/src/ruby/bin/noproto_client.rb
@@ -89,7 +89,7 @@
   if options['secure']
     stub_opts = {
       :creds => test_creds,
-      GRPC::Core::Channel::SSL_TARGET => 'foo.test.google.com'
+      GRPC::Core::Channel::SSL_TARGET => 'foo.test.google.fr'
     }
     p stub_opts
     p options['host']
diff --git a/src/ruby/ext/grpc/extconf.rb b/src/ruby/ext/grpc/extconf.rb
index 96c92e2..483a31f 100644
--- a/src/ruby/ext/grpc/extconf.rb
+++ b/src/ruby/ext/grpc/extconf.rb
@@ -32,6 +32,17 @@
 LIBDIR = RbConfig::CONFIG['libdir']
 INCLUDEDIR = RbConfig::CONFIG['includedir']
 
+if ENV.key? 'GRPC_ROOT'
+  GRPC_ROOT = ENV['GRPC_ROOT']
+  if ENV.key? 'GRPC_LIB_DIR'
+    GRPC_LIB_DIR = ENV['GRPC_LIB_DIR']
+  else
+    GRPC_LIB_DIR = 'libs/opt'
+  end
+else
+  GRPC_ROOT = nil
+end
+
 HEADER_DIRS = [
   # Search /opt/local (Mac source install)
   '/opt/local/include',
@@ -54,6 +65,11 @@
   LIBDIR
 ]
 
+unless GRPC_ROOT.nil?
+  HEADER_DIRS.unshift File.join(GRPC_ROOT, 'include')
+  LIB_DIRS.unshift File.join(GRPC_ROOT, GRPC_LIB_DIR)
+end
+
 def crash(msg)
   print(" extconf failure: #{msg}\n")
   exit 1
diff --git a/src/ruby/grpc.gemspec b/src/ruby/grpc.gemspec
index bc59c23..ed26fef 100755
--- a/src/ruby/grpc.gemspec
+++ b/src/ruby/grpc.gemspec
@@ -11,6 +11,7 @@
   s.homepage      = 'https://github.com/google/grpc/tree/master/src/ruby'
   s.summary       = 'GRPC system in Ruby'
   s.description   = 'Send RPCs from Ruby using GRPC'
+  s.license       = 'BSD-3-Clause'
 
   s.files         = `git ls-files`.split("\n")
   s.test_files    = `git ls-files -- spec/*`.split("\n")
@@ -22,6 +23,7 @@
 
   s.add_dependency 'faraday', '~> 0.9'
   s.add_dependency 'google-protobuf', '~> 3.0.0alpha.1.1'
+  s.add_dependency 'googleauth', '~> 0.1'
   s.add_dependency 'logging', '~> 1.8'
   s.add_dependency 'jwt', '~> 1.2.1'
   s.add_dependency 'minitest', '~> 5.4'  # reqd for interop tests
diff --git a/src/ruby/lib/grpc.rb b/src/ruby/lib/grpc.rb
index a2a609f..dd02ef7 100644
--- a/src/ruby/lib/grpc.rb
+++ b/src/ruby/lib/grpc.rb
@@ -27,8 +27,6 @@
 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-require 'grpc/auth/compute_engine.rb'
-require 'grpc/auth/service_account.rb'
 require 'grpc/errors'
 require 'grpc/grpc'
 require 'grpc/logconfig'
diff --git a/src/ruby/lib/grpc/auth/compute_engine.rb b/src/ruby/lib/grpc/auth/compute_engine.rb
deleted file mode 100644
index 5cb1e1a..0000000
--- a/src/ruby/lib/grpc/auth/compute_engine.rb
+++ /dev/null
@@ -1,67 +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.
-
-require 'faraday'
-require 'grpc/auth/signet'
-
-module GRPC
-  # Module Auth provides classes that provide Google-specific authentication
-  # used to access Google gRPC services.
-  module Auth
-    # Extends Signet::OAuth2::Client so that the auth token is obtained from
-    # the GCE metadata server.
-    class GCECredentials < Signet::OAuth2::Client
-      COMPUTE_AUTH_TOKEN_URI = 'http://metadata/computeMetadata/v1/'\
-                               'instance/service-accounts/default/token'
-      COMPUTE_CHECK_URI = 'http://metadata.google.internal'
-
-      # Detect if this appear to be a GCE instance, by checking if metadata
-      # is available
-      def self.on_gce?(options = {})
-        c = options[:connection] || Faraday.default_connection
-        resp = c.get(COMPUTE_CHECK_URI)
-        return false unless resp.status == 200
-        return false unless resp.headers.key?('Metadata-Flavor')
-        return resp.headers['Metadata-Flavor'] == 'Google'
-      rescue Faraday::ConnectionFailed
-        return false
-      end
-
-      # Overrides the super class method to change how access tokens are
-      # fetched.
-      def fetch_access_token(options = {})
-        c = options[:connection] || Faraday.default_connection
-        c.headers = { 'Metadata-Flavor' => 'Google' }
-        resp = c.get(COMPUTE_AUTH_TOKEN_URI)
-        Signet::OAuth2.parse_credentials(resp.body,
-                                         resp.headers['content-type'])
-      end
-    end
-  end
-end
diff --git a/src/ruby/lib/grpc/auth/service_account.rb b/src/ruby/lib/grpc/auth/service_account.rb
deleted file mode 100644
index 14b81a9..0000000
--- a/src/ruby/lib/grpc/auth/service_account.rb
+++ /dev/null
@@ -1,66 +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.
-
-require 'grpc/auth/signet'
-require 'multi_json'
-require 'openssl'
-
-# Reads the private key and client email fields from service account JSON key.
-def read_json_key(json_key_io)
-  json_key = MultiJson.load(json_key_io.read)
-  fail 'missing client_email' unless json_key.key?('client_email')
-  fail 'missing private_key' unless json_key.key?('private_key')
-  [json_key['private_key'], json_key['client_email']]
-end
-
-module GRPC
-  # Module Auth provides classes that provide Google-specific authentication
-  # used to access Google gRPC services.
-  module Auth
-    # Authenticates requests using Google's Service Account credentials.
-    # (cf https://developers.google.com/accounts/docs/OAuth2ServiceAccount)
-    class ServiceAccountCredentials < Signet::OAuth2::Client
-      TOKEN_CRED_URI = 'https://www.googleapis.com/oauth2/v3/token'
-      AUDIENCE = TOKEN_CRED_URI
-
-      # Initializes a ServiceAccountCredentials.
-      #
-      # @param scope [string|array] the scope(s) to access
-      # @param json_key_io [IO] an IO from which the JSON key can be read
-      def initialize(scope, json_key_io)
-        private_key, client_email = read_json_key(json_key_io)
-        super(token_credential_uri: TOKEN_CRED_URI,
-              audience: AUDIENCE,
-              scope: scope,
-              issuer: client_email,
-              signing_key: OpenSSL::PKey::RSA.new(private_key))
-      end
-    end
-  end
-end
diff --git a/src/ruby/lib/grpc/auth/signet.rb b/src/ruby/lib/grpc/auth/signet.rb
deleted file mode 100644
index a8bce12..0000000
--- a/src/ruby/lib/grpc/auth/signet.rb
+++ /dev/null
@@ -1,67 +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.
-
-require 'signet/oauth_2/client'
-
-module Signet
-  # Signet::OAuth2 supports OAuth2 authentication.
-  module OAuth2
-    AUTH_METADATA_KEY = :Authorization
-    # Signet::OAuth2::Client creates an OAuth2 client
-    #
-    # Here client is re-opened to add the #apply and #apply! methods which
-    # update a hash map with the fetched authentication token
-    #
-    # Eventually, this change may be merged into signet itself, or some other
-    # package that provides Google-specific auth via signet, and this extension
-    # will be unnecessary.
-    class Client
-      # Updates a_hash updated with the authentication token
-      def apply!(a_hash, opts = {})
-        # fetch the access token there is currently not one, or if the client
-        # has expired
-        fetch_access_token!(opts) if access_token.nil? || expired?
-        a_hash[AUTH_METADATA_KEY] = "Bearer #{access_token}"
-      end
-
-      # Returns a clone of a_hash updated with the authentication token
-      def apply(a_hash, opts = {})
-        a_copy = a_hash.clone
-        apply!(a_copy, opts)
-        a_copy
-      end
-
-      # Returns a reference to the #apply method, suitable for passing as
-      # a closure
-      def updater_proc
-        lambda(&method(:apply))
-      end
-    end
-  end
-end
diff --git a/src/ruby/lib/grpc/generic/client_stub.rb b/src/ruby/lib/grpc/generic/client_stub.rb
index 7fc0d83..f234984 100644
--- a/src/ruby/lib/grpc/generic/client_stub.rb
+++ b/src/ruby/lib/grpc/generic/client_stub.rb
@@ -400,7 +400,12 @@
     # @param deadline [TimeConst]
     def new_active_call(ch, marshal, unmarshal, deadline = nil)
       absolute_deadline = Core::TimeConsts.from_relative_time(deadline)
-      call = @ch.create_call(ch, @host, absolute_deadline)
+      # It should be OK to to pass the hostname:port to create_call, but at
+      # the moment this fails a security check.  This will be corrected.
+      #
+      # TODO: # remove this after create_call is updated
+      host = @host.split(':')[0]
+      call = @ch.create_call(ch, host, absolute_deadline)
       ActiveCall.new(call, @queue, marshal, unmarshal, absolute_deadline,
                      started: false)
     end
diff --git a/src/ruby/lib/grpc/generic/service.rb b/src/ruby/lib/grpc/generic/service.rb
index 61d1871..6ea0831 100644
--- a/src/ruby/lib/grpc/generic/service.rb
+++ b/src/ruby/lib/grpc/generic/service.rb
@@ -217,8 +217,8 @@
 
     def self.included(o)
       o.extend(Dsl)
-      # Update to the use the service name including module. Proivde a default
-      # that can be nil e,g. when modules are declared dynamically.
+      # Update to the use the service name including module. Provide a default
+      # that can be nil e.g. when modules are declared dynamically.
       return unless o.service_name.nil?
       if o.name.nil?
         o.service_name = 'GenericService'
diff --git a/src/ruby/lib/grpc/version.rb b/src/ruby/lib/grpc/version.rb
index d4eb0ed..513a537 100644
--- a/src/ruby/lib/grpc/version.rb
+++ b/src/ruby/lib/grpc/version.rb
@@ -29,5 +29,5 @@
 
 # GRPC contains the General RPC module.
 module GRPC
-  VERSION = '0.0.1'
+  VERSION = '0.5.0'
 end
diff --git a/src/ruby/spec/auth/apply_auth_examples.rb b/src/ruby/spec/auth/apply_auth_examples.rb
deleted file mode 100644
index 09b3930..0000000
--- a/src/ruby/spec/auth/apply_auth_examples.rb
+++ /dev/null
@@ -1,163 +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.
-
-spec_dir = File.expand_path(File.join(File.dirname(__FILE__)))
-$LOAD_PATH.unshift(spec_dir)
-$LOAD_PATH.uniq!
-
-require 'faraday'
-require 'spec_helper'
-
-def build_json_response(payload)
-  [200,
-   { 'Content-Type' => 'application/json; charset=utf-8' },
-   MultiJson.dump(payload)]
-end
-
-WANTED_AUTH_KEY = :Authorization
-
-shared_examples 'apply/apply! are OK' do
-  # tests that use these examples need to define
-  #
-  # @client which should be an auth client
-  #
-  # @make_auth_stubs, which should stub out the expected http behaviour of the
-  # auth client
-  describe '#fetch_access_token' do
-    it 'should set access_token to the fetched value' do
-      token = '1/abcdef1234567890'
-      stubs = make_auth_stubs with_access_token: token
-      c = Faraday.new do |b|
-        b.adapter(:test, stubs)
-      end
-
-      @client.fetch_access_token!(connection: c)
-      expect(@client.access_token).to eq(token)
-      stubs.verify_stubbed_calls
-    end
-  end
-
-  describe '#apply!' do
-    it 'should update the target hash with fetched access token' do
-      token = '1/abcdef1234567890'
-      stubs = make_auth_stubs with_access_token: token
-      c = Faraday.new do |b|
-        b.adapter(:test, stubs)
-      end
-
-      md = { foo: 'bar' }
-      @client.apply!(md, connection: c)
-      want = { :foo => 'bar', WANTED_AUTH_KEY => "Bearer #{token}" }
-      expect(md).to eq(want)
-      stubs.verify_stubbed_calls
-    end
-  end
-
-  describe 'updater_proc' do
-    it 'should provide a proc that updates a hash with the access token' do
-      token = '1/abcdef1234567890'
-      stubs = make_auth_stubs with_access_token: token
-      c = Faraday.new do |b|
-        b.adapter(:test, stubs)
-      end
-
-      md = { foo: 'bar' }
-      the_proc = @client.updater_proc
-      got = the_proc.call(md, connection: c)
-      want = { :foo => 'bar', WANTED_AUTH_KEY => "Bearer #{token}" }
-      expect(got).to eq(want)
-      stubs.verify_stubbed_calls
-    end
-  end
-
-  describe '#apply' do
-    it 'should not update the original hash with the access token' do
-      token = '1/abcdef1234567890'
-      stubs = make_auth_stubs with_access_token: token
-      c = Faraday.new do |b|
-        b.adapter(:test, stubs)
-      end
-
-      md = { foo: 'bar' }
-      @client.apply(md, connection: c)
-      want = { foo: 'bar' }
-      expect(md).to eq(want)
-      stubs.verify_stubbed_calls
-    end
-
-    it 'should add the token to the returned hash' do
-      token = '1/abcdef1234567890'
-      stubs = make_auth_stubs with_access_token: token
-      c = Faraday.new do |b|
-        b.adapter(:test, stubs)
-      end
-
-      md = { foo: 'bar' }
-      got = @client.apply(md, connection: c)
-      want = { :foo => 'bar', WANTED_AUTH_KEY => "Bearer #{token}" }
-      expect(got).to eq(want)
-      stubs.verify_stubbed_calls
-    end
-
-    it 'should not fetch a new token if the current is not expired' do
-      token = '1/abcdef1234567890'
-      stubs = make_auth_stubs with_access_token: token
-      c = Faraday.new do |b|
-        b.adapter(:test, stubs)
-      end
-
-      n = 5 # arbitrary
-      n.times do |_t|
-        md = { foo: 'bar' }
-        got = @client.apply(md, connection: c)
-        want = { :foo => 'bar', WANTED_AUTH_KEY => "Bearer #{token}" }
-        expect(got).to eq(want)
-      end
-      stubs.verify_stubbed_calls
-    end
-
-    it 'should fetch a new token if the current one is expired' do
-      token_1 = '1/abcdef1234567890'
-      token_2 = '2/abcdef1234567890'
-
-      [token_1, token_2].each do |t|
-        stubs = make_auth_stubs with_access_token: t
-        c = Faraday.new do |b|
-          b.adapter(:test, stubs)
-        end
-        md = { foo: 'bar' }
-        got = @client.apply(md, connection: c)
-        want = { :foo => 'bar', WANTED_AUTH_KEY => "Bearer #{t}" }
-        expect(got).to eq(want)
-        stubs.verify_stubbed_calls
-        @client.expires_at -= 3601 # default is to expire in 1hr
-      end
-    end
-  end
-end
diff --git a/src/ruby/spec/auth/compute_engine_spec.rb b/src/ruby/spec/auth/compute_engine_spec.rb
deleted file mode 100644
index c43214d..0000000
--- a/src/ruby/spec/auth/compute_engine_spec.rb
+++ /dev/null
@@ -1,108 +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.
-
-spec_dir = File.expand_path(File.join(File.dirname(__FILE__)))
-$LOAD_PATH.unshift(spec_dir)
-$LOAD_PATH.uniq!
-
-require 'apply_auth_examples'
-require 'faraday'
-require 'grpc/auth/compute_engine'
-require 'spec_helper'
-
-describe GRPC::Auth::GCECredentials do
-  MD_URI = '/computeMetadata/v1/instance/service-accounts/default/token'
-  GCECredentials = GRPC::Auth::GCECredentials
-
-  before(:example) do
-    @client = GCECredentials.new
-  end
-
-  def make_auth_stubs(with_access_token: '')
-    Faraday::Adapter::Test::Stubs.new do |stub|
-      stub.get(MD_URI) do |env|
-        headers = env[:request_headers]
-        expect(headers['Metadata-Flavor']).to eq('Google')
-        build_json_response(
-            'access_token' => with_access_token,
-            'token_type' => 'Bearer',
-            'expires_in' => 3600)
-      end
-    end
-  end
-
-  it_behaves_like 'apply/apply! are OK'
-
-  describe '#on_gce?' do
-    it 'should be true when Metadata-Flavor is Google' do
-      stubs = Faraday::Adapter::Test::Stubs.new do |stub|
-        stub.get('/') do |_env|
-          [200,
-           { 'Metadata-Flavor' => 'Google' },
-           '']
-        end
-      end
-      c = Faraday.new do |b|
-        b.adapter(:test, stubs)
-      end
-      expect(GCECredentials.on_gce?(connection: c)).to eq(true)
-      stubs.verify_stubbed_calls
-    end
-
-    it 'should be false when Metadata-Flavor is not Google' do
-      stubs = Faraday::Adapter::Test::Stubs.new do |stub|
-        stub.get('/') do |_env|
-          [200,
-           { 'Metadata-Flavor' => 'NotGoogle' },
-           '']
-        end
-      end
-      c = Faraday.new do |b|
-        b.adapter(:test, stubs)
-      end
-      expect(GCECredentials.on_gce?(connection: c)).to eq(false)
-      stubs.verify_stubbed_calls
-    end
-
-    it 'should be false if the response is not 200' do
-      stubs = Faraday::Adapter::Test::Stubs.new do |stub|
-        stub.get('/') do |_env|
-          [404,
-           { 'Metadata-Flavor' => 'Google' },
-           '']
-        end
-      end
-      c = Faraday.new do |b|
-        b.adapter(:test, stubs)
-      end
-      expect(GCECredentials.on_gce?(connection: c)).to eq(false)
-      stubs.verify_stubbed_calls
-    end
-  end
-end
diff --git a/src/ruby/spec/auth/service_account_spec.rb b/src/ruby/spec/auth/service_account_spec.rb
deleted file mode 100644
index 2f14a1a..0000000
--- a/src/ruby/spec/auth/service_account_spec.rb
+++ /dev/null
@@ -1,75 +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.
-
-spec_dir = File.expand_path(File.join(File.dirname(__FILE__)))
-$LOAD_PATH.unshift(spec_dir)
-$LOAD_PATH.uniq!
-
-require 'apply_auth_examples'
-require 'grpc/auth/service_account'
-require 'jwt'
-require 'multi_json'
-require 'openssl'
-require 'spec_helper'
-
-describe GRPC::Auth::ServiceAccountCredentials do
-  before(:example) do
-    @key = OpenSSL::PKey::RSA.new(2048)
-    cred_json = {
-      private_key_id: 'a_private_key_id',
-      private_key: @key.to_pem,
-      client_email: 'app@developer.gserviceaccount.com',
-      client_id: 'app.apps.googleusercontent.com',
-      type: 'service_account'
-    }
-    cred_json_text = MultiJson.dump(cred_json)
-    @client = GRPC::Auth::ServiceAccountCredentials.new(
-        'https://www.googleapis.com/auth/userinfo.profile',
-        StringIO.new(cred_json_text))
-  end
-
-  def make_auth_stubs(with_access_token: '')
-    Faraday::Adapter::Test::Stubs.new do |stub|
-      stub.post('/oauth2/v3/token') do |env|
-        params = Addressable::URI.form_unencode(env[:body])
-        _claim, _header = JWT.decode(params.assoc('assertion').last,
-                                     @key.public_key)
-        want = ['grant_type', 'urn:ietf:params:oauth:grant-type:jwt-bearer']
-        expect(params.assoc('grant_type')).to eq(want)
-        build_json_response(
-          'access_token' => with_access_token,
-          'token_type' => 'Bearer',
-          'expires_in' => 3600
-        )
-      end
-    end
-  end
-
-  it_behaves_like 'apply/apply! are OK'
-end
diff --git a/src/ruby/spec/auth/signet_spec.rb b/src/ruby/spec/auth/signet_spec.rb
deleted file mode 100644
index 1712edf..0000000
--- a/src/ruby/spec/auth/signet_spec.rb
+++ /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.
-
-spec_dir = File.expand_path(File.join(File.dirname(__FILE__)))
-$LOAD_PATH.unshift(spec_dir)
-$LOAD_PATH.uniq!
-
-require 'apply_auth_examples'
-require 'grpc/auth/signet'
-require 'jwt'
-require 'openssl'
-require 'spec_helper'
-
-describe Signet::OAuth2::Client do
-  before(:example) do
-    @key = OpenSSL::PKey::RSA.new(2048)
-    @client = Signet::OAuth2::Client.new(
-        token_credential_uri: 'https://accounts.google.com/o/oauth2/token',
-        scope: 'https://www.googleapis.com/auth/userinfo.profile',
-        issuer: 'app@example.com',
-        audience: 'https://accounts.google.com/o/oauth2/token',
-        signing_key: @key
-      )
-  end
-
-  def make_auth_stubs(with_access_token: '')
-    Faraday::Adapter::Test::Stubs.new do |stub|
-      stub.post('/o/oauth2/token') do |env|
-        params = Addressable::URI.form_unencode(env[:body])
-        _claim, _header = JWT.decode(params.assoc('assertion').last,
-                                     @key.public_key)
-        want = ['grant_type', 'urn:ietf:params:oauth:grant-type:jwt-bearer']
-        expect(params.assoc('grant_type')).to eq(want)
-        build_json_response(
-          'access_token' => with_access_token,
-          'token_type' => 'Bearer',
-          'expires_in' => 3600
-        )
-      end
-    end
-  end
-
-  it_behaves_like 'apply/apply! are OK'
-end
diff --git a/src/ruby/spec/client_server_spec.rb b/src/ruby/spec/client_server_spec.rb
index 52c9857..030ff32 100644
--- a/src/ruby/spec/client_server_spec.rb
+++ b/src/ruby/spec/client_server_spec.rb
@@ -353,7 +353,7 @@
     @server = GRPC::Core::Server.new(@server_queue, nil, server_creds)
     server_port = @server.add_http2_port(server_host, true)
     @server.start
-    args = { Channel::SSL_TARGET => 'foo.test.google.com' }
+    args = { Channel::SSL_TARGET => 'foo.test.google.fr' }
     @ch = Channel.new("0.0.0.0:#{server_port}", args,
                       GRPC::Core::Credentials.new(certs[0], nil, nil))
   end
diff --git a/src/ruby/spec/credentials_spec.rb b/src/ruby/spec/credentials_spec.rb
index 001fecd..fc97d11 100644
--- a/src/ruby/spec/credentials_spec.rb
+++ b/src/ruby/spec/credentials_spec.rb
@@ -68,10 +68,4 @@
       expect { cred1.compose(cred2) }.to_not raise_error
     end
   end
-
-  describe 'Credentials#default' do
-    it 'is not implemented yet' do
-      expect { Credentials.default }.to raise_error RuntimeError
-    end
-  end
 end
diff --git a/src/ruby/spec/generic/client_stub_spec.rb b/src/ruby/spec/generic/client_stub_spec.rb
index 297a133..adf354f 100644
--- a/src/ruby/spec/generic/client_stub_spec.rb
+++ b/src/ruby/spec/generic/client_stub_spec.rb
@@ -116,7 +116,7 @@
       host = FAKE_HOST
       blk = proc do
         opts = {
-          GRPC::Core::Channel::SSL_TARGET => 'foo.test.google.com',
+          GRPC::Core::Channel::SSL_TARGET => 'foo.test.google.fr',
           a_channel_arg: 'an_arg',
           creds: GRPC::Core::Credentials.new(certs[0], nil, nil)
         }
diff --git a/templates/Makefile.template b/templates/Makefile.template
index 8240996..2e50e5d 100644
--- a/templates/Makefile.template
+++ b/templates/Makefile.template
@@ -94,7 +94,7 @@
 CPPFLAGS_valgrind = -O0
 OPENSSL_CFLAGS_valgrind = -DPURIFY
 LDFLAGS_valgrind =
-DEFINES_valgrind = _DEBUG DEBUG
+DEFINES_valgrind = _DEBUG DEBUG GRPC_TEST_SLOWDOWN_BUILD_FACTOR=20
 
 VALID_CONFIG_tsan = 1
 REQUIRE_CUSTOM_LIBRARIES_tsan = 1
@@ -104,7 +104,7 @@
 LDXX_tsan = clang++
 CPPFLAGS_tsan = -O1 -fsanitize=thread -fno-omit-frame-pointer
 LDFLAGS_tsan = -fsanitize=thread
-DEFINES_tsan = NDEBUG
+DEFINES_tsan = NDEBUG GRPC_TEST_SLOWDOWN_BUILD_FACTOR=10
 
 VALID_CONFIG_asan = 1
 REQUIRE_CUSTOM_LIBRARIES_asan = 1
@@ -114,7 +114,7 @@
 LDXX_asan = clang++
 CPPFLAGS_asan = -O1 -fsanitize=address -fno-omit-frame-pointer
 LDFLAGS_asan = -fsanitize=address
-DEFINES_asan = NDEBUG
+DEFINES_asan = NDEBUG GRPC_TEST_SLOWDOWN_BUILD_FACTOR=5
 
 VALID_CONFIG_msan = 1
 REQUIRE_CUSTOM_LIBRARIES_msan = 1
@@ -125,7 +125,7 @@
 CPPFLAGS_msan = -O1 -fsanitize=memory -fsanitize-memory-track-origins -fno-omit-frame-pointer -DGTEST_HAS_TR1_TUPLE=0 -DGTEST_USE_OWN_TR1_TUPLE=1
 OPENSSL_CFLAGS_msan = -DPURIFY
 LDFLAGS_msan = -fsanitize=memory -DGTEST_HAS_TR1_TUPLE=0 -DGTEST_USE_OWN_TR1_TUPLE=1
-DEFINES_msan = NDEBUG
+DEFINES_msan = NDEBUG GRPC_TEST_SLOWDOWN_BUILD_FACTOR=20
 
 VALID_CONFIG_ubsan = 1
 REQUIRE_CUSTOM_LIBRARIES_ubsan = 1
@@ -136,7 +136,7 @@
 CPPFLAGS_ubsan = -O1 -fsanitize=undefined -fno-omit-frame-pointer
 OPENSSL_CFLAGS_ubsan = -DPURIFY
 LDFLAGS_ubsan = -fsanitize=undefined
-DEFINES_ubsan = NDEBUG
+DEFINES_ubsan = NDEBUG GRPC_TEST_SLOWDOWN_BUILD_FACTOR=10
 
 VALID_CONFIG_gcov = 1
 CC_gcov = gcc
@@ -160,7 +160,15 @@
 LD = $(LD_$(CONFIG))
 LDXX = $(LDXX_$(CONFIG))
 AR = ar
+ifeq ($(SYSTEM),Linux)
 STRIP = strip --strip-unneeded
+else
+ifeq ($(SYSTEM),Darwin)
+STRIP = strip -x
+else
+STRIP = strip
+endif
+endif
 INSTALL = install
 RM = rm -f
 
@@ -169,6 +177,10 @@
 endif
 
 
+# Detect if we can use C++11
+CXX11_CHECK_CMD = $(CXX) -std=c++11 -o /dev/null -c test/build/c++11.cc
+HAS_CXX11 = $(shell $(CXX11_CHECK_CMD) 2> /dev/null && echo true || echo false)
+
 # The HOST compiler settings are used to compile the protoc plugins.
 # In most cases, you won't have to change anything, but if you are
 # cross-compiling, you can override these variables from GNU make's
@@ -183,8 +195,17 @@
 DEFINES += $(DEFINES_$(CONFIG)) INSTALL_PREFIX=\"$(prefix)\"
 LDFLAGS += $(LDFLAGS_$(CONFIG))
 
+ifdef EXTRA_DEFINES
+DEFINES += $(EXTRA_DEFINES)
+endif
+
 CFLAGS += -std=c89 -pedantic
+ifeq ($(HAS_CXX11),true)
 CXXFLAGS += -std=c++11
+else
+CXXFLAGS += -std=c++0x
+DEFINES += GRPC_OLD_CXX
+endif
 CPPFLAGS += -g -fPIC -Wall -Wextra -Werror -Wno-long-long -Wno-unused-parameter
 LDFLAGS += -g -fPIC
 
@@ -495,7 +516,11 @@
 
 $(LIBDIR)/$(CONFIG)/protobuf/libprotobuf.a: third_party/protobuf/configure
 	$(E) "[MAKE]    Building protobuf"
+ifeq ($(HAVE_CXX11),true)
 	$(Q)(cd third_party/protobuf ; CC="$(CC)" CXX="$(CXX)" LDFLAGS="$(LDFLAGS_$(CONFIG)) -g" CXXFLAGS="-DLANG_CXX11 -std=c++11" CPPFLAGS="-fPIC $(CPPFLAGS_$(CONFIG)) -g" ./configure --disable-shared --enable-static)
+else
+	$(Q)(cd third_party/protobuf ; CC="$(CC)" CXX="$(CXX)" LDFLAGS="$(LDFLAGS_$(CONFIG)) -g" CXXFLAGS="-std=c++0x" CPPFLAGS="-fPIC $(CPPFLAGS_$(CONFIG)) -g" ./configure --disable-shared --enable-static)
+endif
 	$(Q)$(MAKE) -C third_party/protobuf clean
 	$(Q)$(MAKE) -C third_party/protobuf
 	$(Q)mkdir -p $(LIBDIR)/$(CONFIG)/protobuf
@@ -1095,11 +1120,11 @@
 ## That simplifies the codegen a bit, but prevents a fully defined Makefile.
 ## I can live with that.
 ##
-% if tgt.build == 'protoc':
+% if tgt.build == 'protoc' or tgt.language == 'c++':
 
 ifeq ($(NO_PROTOBUF),true)
 
-# You can't build the protoc plugins if you don't have protobuf 3.0.0+.
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
 
 $(BINDIR)/$(CONFIG)/${tgt.name}: protobuf_dep_error
 
@@ -1154,7 +1179,7 @@
  $(LDLIBS_SECURE)\
 % endif
  -o $(BINDIR)/$(CONFIG)/${tgt.name}
-% if tgt.build == 'protoc':
+% if tgt.build == 'protoc' or tgt.language == 'c++':
 
 endif
 % endif
diff --git a/templates/tools/run_tests/tests.json.template b/templates/tools/run_tests/tests.json.template
index bb54489..6d7520b 100644
--- a/templates/tools/run_tests/tests.json.template
+++ b/templates/tools/run_tests/tests.json.template
@@ -2,7 +2,9 @@
 import json
 %>
 
-${json.dumps([{"name": tgt.name, "language": tgt.language}
+${json.dumps([{"name": tgt.name,
+               "language": tgt.language,
+               "flaky": tgt.get("flaky", False)}
               for tgt in targets
               if tgt.get('run', True) and tgt.build == 'test'],
              sort_keys=True, indent=2)}
diff --git a/test/build/c++11.cc b/test/build/c++11.cc
new file mode 100644
index 0000000..4822a20
--- /dev/null
+++ b/test/build/c++11.cc
@@ -0,0 +1,52 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/* This is just a compilation test, to see if we have C++11. */
+
+#include <stdlib.h>
+#include <zlib.h>
+
+class Base {
+ public:
+  virtual void foo() = 0;
+};
+
+class Foo final : public Base {
+ public:
+  void foo() override {}
+};
+
+int main() {
+  Foo().foo();
+  return 0;
+}
diff --git a/test/compiler/python_plugin_test.py b/test/compiler/python_plugin_test.py
index b0c9ec6..1981f49 100644
--- a/test/compiler/python_plugin_test.py
+++ b/test/compiler/python_plugin_test.py
@@ -40,6 +40,21 @@
 from grpc.framework.face import exceptions
 from grpc.framework.foundation import future
 
+# Identifiers of entities we expect to find in the generated module.
+SERVICER_IDENTIFIER = 'EarlyAdopterTestServiceServicer'
+SERVER_IDENTIFIER = 'EarlyAdopterTestServiceServer'
+STUB_IDENTIFIER = 'EarlyAdopterTestServiceStub'
+SERVER_FACTORY_IDENTIFIER = 'early_adopter_create_TestService_server'
+STUB_FACTORY_IDENTIFIER = 'early_adopter_create_TestService_stub'
+
+# Timeouts and delays.
+SHORT_TIMEOUT = 0.1
+NORMAL_TIMEOUT = 1
+LONG_TIMEOUT = 2
+DOES_NOT_MATTER_DELAY = 0
+NO_DELAY = 0
+LONG_DELAY = 1
+
 # Assigned in __main__.
 _build_mode = None
 
@@ -71,14 +86,14 @@
     while self._paused:
       time.sleep(0)
 
-  def UnaryCall(self, request):
+  def UnaryCall(self, request, unused_context):
     response = self.test_pb2.SimpleResponse()
     response.payload.payload_type = self.test_pb2.COMPRESSABLE
     response.payload.payload_compressable = 'a' * request.response_size
     self._control()
     return response
 
-  def StreamingOutputCall(self, request):
+  def StreamingOutputCall(self, request, unused_context):
     for parameter in request.response_parameters:
       response = self.test_pb2.StreamingOutputCallResponse()
       response.payload.payload_type = self.test_pb2.COMPRESSABLE
@@ -86,7 +101,7 @@
       self._control()
       yield response
 
-  def StreamingInputCall(self, request_iter):
+  def StreamingInputCall(self, request_iter, unused_context):
     response = self.test_pb2.StreamingInputCallResponse()
     aggregated_payload_size = 0
     for request in request_iter:
@@ -95,7 +110,7 @@
     self._control()
     return response
 
-  def FullDuplexCall(self, request_iter):
+  def FullDuplexCall(self, request_iter, unused_context):
     for request in request_iter:
       for parameter in request.response_parameters:
         response = self.test_pb2.StreamingOutputCallResponse()
@@ -104,7 +119,7 @@
         self._control()
         yield response
 
-  def HalfDuplexCall(self, request_iter):
+  def HalfDuplexCall(self, request_iter, unused_context):
     responses = []
     for request in request_iter:
       for parameter in request.response_parameters:
@@ -117,7 +132,8 @@
       yield response
 
 
-def CreateService(test_pb2, delay=0, timeout=1):
+@contextlib.contextmanager
+def _CreateService(test_pb2, delay):
   """Provides a servicer backend and a stub.
 
   The servicer is just the implementation
@@ -132,32 +148,39 @@
     test_pb2: the test_pb2 module generated by this test
     delay: delay in seconds per response from the servicer
     timeout: how long the stub will wait for the servicer by default.
-  Returns:
-    A two-tuple (servicer, stub), where the servicer is the back-end of the
-      service bound to the stub.
+
+  Yields:
+    A three-tuple (servicer_methods, servicer, stub), where the servicer is
+      the back-end of the service bound to the stub and the server and stub
+      are both activated and ready for use.
   """
-  class Servicer(test_pb2.TestServiceServicer):
-
-    def UnaryCall(self, request):
-      return servicer_methods.UnaryCall(request)
-
-    def StreamingOutputCall(self, request):
-      return servicer_methods.StreamingOutputCall(request)
-
-    def StreamingInputCall(self, request_iter):
-      return servicer_methods.StreamingInputCall(request_iter)
-
-    def FullDuplexCall(self, request_iter):
-      return servicer_methods.FullDuplexCall(request_iter)
-
-    def HalfDuplexCall(self, request_iter):
-      return servicer_methods.HalfDuplexCall(request_iter)
-
   servicer_methods = _ServicerMethods(test_pb2, delay)
+
+  class Servicer(getattr(test_pb2, SERVICER_IDENTIFIER)):
+
+    def UnaryCall(self, request, context):
+      return servicer_methods.UnaryCall(request, context)
+
+    def StreamingOutputCall(self, request, context):
+      return servicer_methods.StreamingOutputCall(request, context)
+
+    def StreamingInputCall(self, request_iter, context):
+      return servicer_methods.StreamingInputCall(request_iter, context)
+
+    def FullDuplexCall(self, request_iter, context):
+      return servicer_methods.FullDuplexCall(request_iter, context)
+
+    def HalfDuplexCall(self, request_iter, context):
+      return servicer_methods.HalfDuplexCall(request_iter, context)
+
   servicer = Servicer()
-  linked_pair = test_pb2.mock_TestService(servicer, timeout)
-  stub = linked_pair.stub
-  return servicer_methods, stub
+  server = getattr(
+      test_pb2, SERVER_FACTORY_IDENTIFIER)(servicer, 0, None, None)
+  with server:
+    port = server.port()
+    stub = getattr(test_pb2, STUB_FACTORY_IDENTIFIER)('localhost', port)
+    with stub:
+      yield servicer_methods, stub, server
 
 
 def StreamingInputRequest(test_pb2):
@@ -198,19 +221,20 @@
   def setUp(self):
     protoc_command = '../../bins/%s/protobuf/protoc' % _build_mode
     protoc_plugin_filename = '../../bins/%s/grpc_python_plugin' % _build_mode
-    test_proto_filename = '../cpp/interop/test.proto'
+    test_proto_filename = './test.proto'
     if not os.path.isfile(protoc_command):
       # Assume that if we haven't built protoc that it's on the system.
       protoc_command = 'protoc'
 
-    # ensure that the output directory exists
-    outdir = '../../gens/test/compiler/python/'
+    # Ensure that the output directory exists.
+    outdir = '../../gens/test/compiler/python'
     try:
       os.makedirs(outdir)
     except OSError as exception:
       if exception.errno != errno.EEXIST:
         raise
 
+    # Invoke protoc with the plugin.
     cmd = [
         protoc_command,
         '--plugin=protoc-gen-python-grpc=%s' % protoc_plugin_filename,
@@ -222,232 +246,239 @@
     subprocess.call(' '.join(cmd), shell=True)
     sys.path.append(outdir)
 
-    self.delay = 1  # seconds
-    self.timeout = 2  # seconds
+  # TODO(atash): Figure out which of theses tests is hanging flakily with small
+  # probability.
 
   def testImportAttributes(self):
-    # check that we can access the members
+    # check that we can access the generated module and its members.
     import test_pb2  # pylint: disable=g-import-not-at-top
-    self.assertIsNotNone(getattr(test_pb2, 'TestServiceServicer', None))
-    self.assertIsNotNone(getattr(test_pb2, 'TestServiceService', None))
-    self.assertIsNotNone(getattr(test_pb2, 'TestServiceStub', None))
+    self.assertIsNotNone(getattr(test_pb2, SERVICER_IDENTIFIER, None))
+    self.assertIsNotNone(getattr(test_pb2, SERVER_IDENTIFIER, None))
+    self.assertIsNotNone(getattr(test_pb2, STUB_IDENTIFIER, None))
+    self.assertIsNotNone(getattr(test_pb2, SERVER_FACTORY_IDENTIFIER, None))
+    self.assertIsNotNone(getattr(test_pb2, STUB_FACTORY_IDENTIFIER, None))
+
+  def testUpDown(self):
+    import test_pb2
+    with _CreateService(
+        test_pb2, DOES_NOT_MATTER_DELAY) as (servicer, stub, unused_server):
+      request = test_pb2.SimpleRequest(response_size=13)
 
   def testUnaryCall(self):
     import test_pb2  # pylint: disable=g-import-not-at-top
-    servicer, stub = CreateService(test_pb2)
-    request = test_pb2.SimpleRequest(response_size=13)
-    response = stub.UnaryCall(request)
-    expected_response = servicer.UnaryCall(request)
+    with _CreateService(test_pb2, NO_DELAY) as (servicer, stub, unused_server):
+      request = test_pb2.SimpleRequest(response_size=13)
+      response = stub.UnaryCall(request, NORMAL_TIMEOUT)
+    expected_response = servicer.UnaryCall(request, None)
     self.assertEqual(expected_response, response)
 
   def testUnaryCallAsync(self):
     import test_pb2  # pylint: disable=g-import-not-at-top
-    servicer, stub = CreateService(
-        test_pb2, delay=self.delay, timeout=self.timeout)
     request = test_pb2.SimpleRequest(response_size=13)
-    # TODO(atash): consider using the 'profile' module? Does it even work here?
-    start_time = time.clock()
-    response_future = stub.UnaryCall.async(request)
-    self.assertGreater(self.delay, time.clock() - start_time)
-    response = response_future.result()
-    expected_response = servicer.UnaryCall(request)
+    with _CreateService(test_pb2, LONG_DELAY) as (
+        servicer, stub, unused_server):
+      start_time = time.clock()
+      response_future = stub.UnaryCall.async(request, LONG_TIMEOUT)
+      # Check that we didn't block on the asynchronous call.
+      self.assertGreater(LONG_DELAY, time.clock() - start_time)
+      response = response_future.result()
+    expected_response = servicer.UnaryCall(request, None)
     self.assertEqual(expected_response, response)
 
   def testUnaryCallAsyncExpired(self):
     import test_pb2  # pylint: disable=g-import-not-at-top
     # set the timeout super low...
-    servicer, stub = CreateService(test_pb2, delay=1, timeout=0.1)
-    request = test_pb2.SimpleRequest(response_size=13)
-    with servicer.pause():
-      response_future = stub.UnaryCall.async(request)
-      with self.assertRaises(exceptions.ExpirationError):
-        response_future.result()
+    with _CreateService(test_pb2, DOES_NOT_MATTER_DELAY) as (
+        servicer, stub, unused_server):
+      request = test_pb2.SimpleRequest(response_size=13)
+      with servicer.pause():
+        response_future = stub.UnaryCall.async(request, SHORT_TIMEOUT)
+        with self.assertRaises(exceptions.ExpirationError):
+          response_future.result()
 
   def testUnaryCallAsyncCancelled(self):
     import test_pb2  # pylint: disable=g-import-not-at-top
-    servicer, stub = CreateService(test_pb2)
     request = test_pb2.SimpleRequest(response_size=13)
-    with servicer.pause():
-      response_future = stub.UnaryCall.async(request)
-      response_future.cancel()
-      self.assertTrue(response_future.cancelled())
+    with _CreateService(test_pb2, DOES_NOT_MATTER_DELAY) as (
+        servicer, stub, unused_server):
+      with servicer.pause():
+        response_future = stub.UnaryCall.async(request, 1)
+        response_future.cancel()
+        self.assertTrue(response_future.cancelled())
 
   def testUnaryCallAsyncFailed(self):
     import test_pb2  # pylint: disable=g-import-not-at-top
-    servicer, stub = CreateService(test_pb2)
     request = test_pb2.SimpleRequest(response_size=13)
-    with servicer.fail():
-      response_future = stub.UnaryCall.async(request)
-      self.assertIsNotNone(response_future.exception())
+    with _CreateService(test_pb2, DOES_NOT_MATTER_DELAY) as (
+        servicer, stub, unused_server):
+      with servicer.fail():
+        response_future = stub.UnaryCall.async(request, NORMAL_TIMEOUT)
+        self.assertIsNotNone(response_future.exception())
 
   def testStreamingOutputCall(self):
     import test_pb2  # pylint: disable=g-import-not-at-top
-    servicer, stub = CreateService(test_pb2)
     request = StreamingOutputRequest(test_pb2)
-    responses = stub.StreamingOutputCall(request)
-    expected_responses = servicer.StreamingOutputCall(request)
-    for check in itertools.izip_longest(expected_responses, responses):
-      expected_response, response = check
-      self.assertEqual(expected_response, response)
+    with _CreateService(test_pb2, NO_DELAY) as (servicer, stub, unused_server):
+      responses = stub.StreamingOutputCall(request, NORMAL_TIMEOUT)
+      expected_responses = servicer.StreamingOutputCall(request, None)
+      for check in itertools.izip_longest(expected_responses, responses):
+        expected_response, response = check
+        self.assertEqual(expected_response, response)
 
-  def testStreamingOutputCallAsync(self):
+  def testStreamingOutputCallExpired(self):
     import test_pb2  # pylint: disable=g-import-not-at-top
-    servicer, stub = CreateService(test_pb2, timeout=self.timeout)
     request = StreamingOutputRequest(test_pb2)
-    responses = stub.StreamingOutputCall.async(request)
-    expected_responses = servicer.StreamingOutputCall(request)
-    for check in itertools.izip_longest(expected_responses, responses):
-      expected_response, response = check
-      self.assertEqual(expected_response, response)
+    with _CreateService(test_pb2, DOES_NOT_MATTER_DELAY) as (
+        servicer, stub, unused_server):
+      with servicer.pause():
+        responses = stub.StreamingOutputCall(request, SHORT_TIMEOUT)
+        with self.assertRaises(exceptions.ExpirationError):
+          list(responses)
 
-  def testStreamingOutputCallAsyncExpired(self):
+  def testStreamingOutputCallCancelled(self):
     import test_pb2  # pylint: disable=g-import-not-at-top
-    servicer, stub = CreateService(test_pb2, timeout=0.1)
     request = StreamingOutputRequest(test_pb2)
-    with servicer.pause():
-      responses = stub.StreamingOutputCall.async(request)
-      with self.assertRaises(exceptions.ExpirationError):
-        list(responses)
-
-  def testStreamingOutputCallAsyncCancelled(self):
-    import test_pb2  # pylint: disable=g-import-not-at-top
-    _, stub = CreateService(test_pb2, timeout=0.1)
-    request = StreamingOutputRequest(test_pb2)
-    responses = stub.StreamingOutputCall.async(request)
-    next(responses)
-    responses.cancel()
-    with self.assertRaises(future.CancelledError):
+    with _CreateService(test_pb2, DOES_NOT_MATTER_DELAY) as (
+        unused_servicer, stub, unused_server):
+      responses = stub.StreamingOutputCall(request, SHORT_TIMEOUT)
       next(responses)
-
-  def testStreamingOutputCallAsyncFailed(self):
-    import test_pb2  # pylint: disable=g-import-not-at-top
-    servicer, stub = CreateService(test_pb2, timeout=0.1)
-    request = StreamingOutputRequest(test_pb2)
-    with servicer.fail():
-      responses = stub.StreamingOutputCall.async(request)
-      self.assertIsNotNone(responses)
-      with self.assertRaises(exceptions.ServicerError):
+      responses.cancel()
+      with self.assertRaises(future.CancelledError):
         next(responses)
 
+  @unittest.skip('TODO(atash,nathaniel): figure out why this times out '
+                 'instead of raising the proper error.')
+  def testStreamingOutputCallFailed(self):
+    import test_pb2  # pylint: disable=g-import-not-at-top
+    request = StreamingOutputRequest(test_pb2)
+    with _CreateService(test_pb2, DOES_NOT_MATTER_DELAY) as (
+        servicer, stub, unused_server):
+      with servicer.fail():
+        responses = stub.StreamingOutputCall(request, 1)
+        self.assertIsNotNone(responses)
+        with self.assertRaises(exceptions.ServicerError):
+          next(responses)
+
   def testStreamingInputCall(self):
     import test_pb2  # pylint: disable=g-import-not-at-top
-    servicer, stub = CreateService(test_pb2)
-    response = stub.StreamingInputCall(StreamingInputRequest(test_pb2))
+    with _CreateService(test_pb2, NO_DELAY) as (servicer, stub, unused_server):
+      response = stub.StreamingInputCall(StreamingInputRequest(test_pb2),
+                                         NORMAL_TIMEOUT)
     expected_response = servicer.StreamingInputCall(
-        StreamingInputRequest(test_pb2))
+        StreamingInputRequest(test_pb2), None)
     self.assertEqual(expected_response, response)
 
   def testStreamingInputCallAsync(self):
     import test_pb2  # pylint: disable=g-import-not-at-top
-    servicer, stub = CreateService(
-        test_pb2, delay=self.delay, timeout=self.timeout)
-    start_time = time.clock()
-    response_future = stub.StreamingInputCall.async(
-        StreamingInputRequest(test_pb2))
-    self.assertGreater(self.delay, time.clock() - start_time)
-    response = response_future.result()
+    with _CreateService(test_pb2, LONG_DELAY) as (
+        servicer, stub, unused_server):
+      start_time = time.clock()
+      response_future = stub.StreamingInputCall.async(
+          StreamingInputRequest(test_pb2), LONG_TIMEOUT)
+      self.assertGreater(LONG_DELAY, time.clock() - start_time)
+      response = response_future.result()
     expected_response = servicer.StreamingInputCall(
-        StreamingInputRequest(test_pb2))
+        StreamingInputRequest(test_pb2), None)
     self.assertEqual(expected_response, response)
 
   def testStreamingInputCallAsyncExpired(self):
     import test_pb2  # pylint: disable=g-import-not-at-top
     # set the timeout super low...
-    servicer, stub = CreateService(test_pb2, delay=1, timeout=0.1)
-    with servicer.pause():
-      response_future = stub.StreamingInputCall.async(
-          StreamingInputRequest(test_pb2))
-      with self.assertRaises(exceptions.ExpirationError):
-        response_future.result()
-      self.assertIsInstance(
-          response_future.exception(), exceptions.ExpirationError)
+    with _CreateService(test_pb2, DOES_NOT_MATTER_DELAY) as (
+        servicer, stub, unused_server):
+      with servicer.pause():
+        response_future = stub.StreamingInputCall.async(
+            StreamingInputRequest(test_pb2), SHORT_TIMEOUT)
+        with self.assertRaises(exceptions.ExpirationError):
+          response_future.result()
+        self.assertIsInstance(
+            response_future.exception(), exceptions.ExpirationError)
 
   def testStreamingInputCallAsyncCancelled(self):
     import test_pb2  # pylint: disable=g-import-not-at-top
-    servicer, stub = CreateService(test_pb2)
-    with servicer.pause():
-      response_future = stub.StreamingInputCall.async(
-          StreamingInputRequest(test_pb2))
-      response_future.cancel()
-      self.assertTrue(response_future.cancelled())
-    with self.assertRaises(future.CancelledError):
-      response_future.result()
+    with _CreateService(test_pb2, DOES_NOT_MATTER_DELAY) as (
+        servicer, stub, unused_server):
+      with servicer.pause():
+        response_future = stub.StreamingInputCall.async(
+            StreamingInputRequest(test_pb2), NORMAL_TIMEOUT)
+        response_future.cancel()
+        self.assertTrue(response_future.cancelled())
+      with self.assertRaises(future.CancelledError):
+        response_future.result()
 
   def testStreamingInputCallAsyncFailed(self):
     import test_pb2  # pylint: disable=g-import-not-at-top
-    servicer, stub = CreateService(test_pb2)
-    with servicer.fail():
-      response_future = stub.StreamingInputCall.async(
-          StreamingInputRequest(test_pb2))
-      self.assertIsNotNone(response_future.exception())
+    with _CreateService(test_pb2, DOES_NOT_MATTER_DELAY) as (
+        servicer, stub, unused_server):
+      with servicer.fail():
+        response_future = stub.StreamingInputCall.async(
+            StreamingInputRequest(test_pb2), SHORT_TIMEOUT)
+        self.assertIsNotNone(response_future.exception())
 
   def testFullDuplexCall(self):
     import test_pb2  # pylint: disable=g-import-not-at-top
-    servicer, stub = CreateService(test_pb2)
-    responses = stub.FullDuplexCall(FullDuplexRequest(test_pb2))
-    expected_responses = servicer.FullDuplexCall(FullDuplexRequest(test_pb2))
-    for check in itertools.izip_longest(expected_responses, responses):
-      expected_response, response = check
-      self.assertEqual(expected_response, response)
+    with _CreateService(test_pb2, NO_DELAY) as (servicer, stub, unused_server):
+      responses = stub.FullDuplexCall(FullDuplexRequest(test_pb2),
+                                      NORMAL_TIMEOUT)
+      expected_responses = servicer.FullDuplexCall(FullDuplexRequest(test_pb2),
+                                                   None)
+      for check in itertools.izip_longest(expected_responses, responses):
+        expected_response, response = check
+        self.assertEqual(expected_response, response)
 
-  def testFullDuplexCallAsync(self):
+  def testFullDuplexCallExpired(self):
     import test_pb2  # pylint: disable=g-import-not-at-top
-    servicer, stub = CreateService(test_pb2, timeout=self.timeout)
-    responses = stub.FullDuplexCall.async(FullDuplexRequest(test_pb2))
-    expected_responses = servicer.FullDuplexCall(FullDuplexRequest(test_pb2))
-    for check in itertools.izip_longest(expected_responses, responses):
-      expected_response, response = check
-      self.assertEqual(expected_response, response)
-
-  def testFullDuplexCallAsyncExpired(self):
-    import test_pb2  # pylint: disable=g-import-not-at-top
-    servicer, stub = CreateService(test_pb2, timeout=0.1)
     request = FullDuplexRequest(test_pb2)
-    with servicer.pause():
-      responses = stub.FullDuplexCall.async(request)
-      with self.assertRaises(exceptions.ExpirationError):
-        list(responses)
+    with _CreateService(test_pb2, DOES_NOT_MATTER_DELAY) as (
+        servicer, stub, unused_server):
+      with servicer.pause():
+        responses = stub.FullDuplexCall(request, SHORT_TIMEOUT)
+        with self.assertRaises(exceptions.ExpirationError):
+          list(responses)
 
-  def testFullDuplexCallAsyncCancelled(self):
+  def testFullDuplexCallCancelled(self):
     import test_pb2  # pylint: disable=g-import-not-at-top
-    _, stub = CreateService(test_pb2, timeout=0.1)
-    request = FullDuplexRequest(test_pb2)
-    responses = stub.FullDuplexCall.async(request)
-    next(responses)
-    responses.cancel()
-    with self.assertRaises(future.CancelledError):
+    with _CreateService(test_pb2, NO_DELAY) as (servicer, stub, unused_server):
+      request = FullDuplexRequest(test_pb2)
+      responses = stub.FullDuplexCall(request, NORMAL_TIMEOUT)
       next(responses)
-
-  def testFullDuplexCallAsyncFailed(self):
-    import test_pb2  # pylint: disable=g-import-not-at-top
-    servicer, stub = CreateService(test_pb2, timeout=0.1)
-    request = FullDuplexRequest(test_pb2)
-    with servicer.fail():
-      responses = stub.FullDuplexCall.async(request)
-      self.assertIsNotNone(responses)
-      with self.assertRaises(exceptions.ServicerError):
+      responses.cancel()
+      with self.assertRaises(future.CancelledError):
         next(responses)
 
+  @unittest.skip('TODO(atash,nathaniel): figure out why this hangs forever '
+                 'and fix.')
+  def testFullDuplexCallFailed(self):
+    import test_pb2  # pylint: disable=g-import-not-at-top
+    request = FullDuplexRequest(test_pb2)
+    with _CreateService(test_pb2, DOES_NOT_MATTER_DELAY) as (
+        servicer, stub, unused_server):
+      with servicer.fail():
+        responses = stub.FullDuplexCall(request, NORMAL_TIMEOUT)
+        self.assertIsNotNone(responses)
+        with self.assertRaises(exceptions.ServicerError):
+          next(responses)
+
   def testHalfDuplexCall(self):
     import test_pb2  # pylint: disable=g-import-not-at-top
-    servicer, stub = CreateService(test_pb2)
-    def HalfDuplexRequest():
-      request = test_pb2.StreamingOutputCallRequest()
-      request.response_parameters.add(size=1, interval_us=0)
-      yield request
-      request = test_pb2.StreamingOutputCallRequest()
-      request.response_parameters.add(size=2, interval_us=0)
-      request.response_parameters.add(size=3, interval_us=0)
-      yield request
-    responses = stub.HalfDuplexCall(HalfDuplexRequest())
-    expected_responses = servicer.HalfDuplexCall(HalfDuplexRequest())
-    for check in itertools.izip_longest(expected_responses, responses):
-      expected_response, response = check
-      self.assertEqual(expected_response, response)
+    with _CreateService(test_pb2, DOES_NOT_MATTER_DELAY) as (
+        servicer, stub, unused_server):
+      def HalfDuplexRequest():
+        request = test_pb2.StreamingOutputCallRequest()
+        request.response_parameters.add(size=1, interval_us=0)
+        yield request
+        request = test_pb2.StreamingOutputCallRequest()
+        request.response_parameters.add(size=2, interval_us=0)
+        request.response_parameters.add(size=3, interval_us=0)
+        yield request
+      responses = stub.HalfDuplexCall(HalfDuplexRequest(), NORMAL_TIMEOUT)
+      expected_responses = servicer.HalfDuplexCall(HalfDuplexRequest(), None)
+      for check in itertools.izip_longest(expected_responses, responses):
+        expected_response, response = check
+        self.assertEqual(expected_response, response)
 
-  def testHalfDuplexCallAsyncWedged(self):
+  def testHalfDuplexCallWedged(self):
     import test_pb2  # pylint: disable=g-import-not-at-top
-    _, stub = CreateService(test_pb2, timeout=1)
     wait_flag = [False]
     @contextlib.contextmanager
     def wait():  # pylint: disable=invalid-name
@@ -461,19 +492,23 @@
       yield request
       while wait_flag[0]:
         time.sleep(0.1)
-    with wait():
-      responses = stub.HalfDuplexCall.async(HalfDuplexRequest())
-      # half-duplex waits for the client to send all info
-      with self.assertRaises(exceptions.ExpirationError):
-        next(responses)
+    with _CreateService(test_pb2, NO_DELAY) as (servicer, stub, unused_server):
+      with wait():
+        responses = stub.HalfDuplexCall(HalfDuplexRequest(), NORMAL_TIMEOUT)
+        # half-duplex waits for the client to send all info
+        with self.assertRaises(exceptions.ExpirationError):
+          next(responses)
 
 
 if __name__ == '__main__':
   os.chdir(os.path.dirname(sys.argv[0]))
-  parser = argparse.ArgumentParser(description='Run Python compiler plugin test.')
-  parser.add_argument('--build_mode', dest='build_mode', type=str, default='dbg',
-                      help='The build mode of the targets to test, e.g. '
-                      '"dbg", "opt", "asan", etc.')
+  parser = argparse.ArgumentParser(
+      description='Run Python compiler plugin test.')
+  parser.add_argument(
+      '--build_mode', dest='build_mode', type=str, default='dbg',
+      help='The build mode of the targets to test, e.g. "dbg", "opt", "asan", '
+      'etc.')
+  parser.add_argument('--port', dest='port', type=int, default=0)
   args, remainder = parser.parse_known_args()
   _build_mode = args.build_mode
   sys.argv[1:] = remainder
diff --git a/test/core/channel/channel_stack_test.c b/test/core/channel/channel_stack_test.c
index 59a4564..e92db59 100644
--- a/test/core/channel/channel_stack_test.c
+++ b/test/core/channel/channel_stack_test.c
@@ -77,10 +77,10 @@
 }
 
 static void test_create_channel_stack(void) {
-  const grpc_channel_filter
-      filter = {call_func,         channel_func,         sizeof(int),
-                call_init_func,    call_destroy_func,    sizeof(int),
-                channel_init_func, channel_destroy_func, "some_test_filter" };
+  const grpc_channel_filter filter = {
+      call_func,         channel_func,         sizeof(int),
+      call_init_func,    call_destroy_func,    sizeof(int),
+      channel_init_func, channel_destroy_func, "some_test_filter"};
   const grpc_channel_filter *filters = &filter;
   grpc_channel_stack *channel_stack;
   grpc_call_stack *call_stack;
diff --git a/test/core/channel/metadata_buffer_test.c b/test/core/channel/metadata_buffer_test.c
index ba8100b..4fc434f 100644
--- a/test/core/channel/metadata_buffer_test.c
+++ b/test/core/channel/metadata_buffer_test.c
@@ -110,14 +110,14 @@
 static void destroy_channel_elem(grpc_channel_element *elem) {}
 
 static const grpc_channel_filter top_filter = {
-    fail_call_op,      fail_channel_op,     sizeof(size_t),
-    init_call_elem,    destroy_call_elem,   sizeof(channel_data),
-    init_channel_elem, destroy_channel_elem, "top_filter" };
+    fail_call_op,      fail_channel_op,      sizeof(size_t),
+    init_call_elem,    destroy_call_elem,    sizeof(channel_data),
+    init_channel_elem, destroy_channel_elem, "top_filter"};
 
 static const grpc_channel_filter bottom_filter = {
-    expect_call_op,    fail_channel_op,     sizeof(size_t),
-    init_call_elem,    destroy_call_elem,   sizeof(channel_data),
-    init_channel_elem, destroy_channel_elem, "bottom_filter" };
+    expect_call_op,    fail_channel_op,      sizeof(size_t),
+    init_call_elem,    destroy_call_elem,    sizeof(channel_data),
+    init_channel_elem, destroy_channel_elem, "bottom_filter"};
 
 static const grpc_channel_filter *filters[2] = {&top_filter, &bottom_filter};
 
@@ -149,7 +149,7 @@
     op.flags = i;
     op.data.metadata = grpc_mdelem_from_slices(mdctx, key, value);
     op.done_cb = do_nothing;
-    op.user_data = (void *)(gpr_uintptr)i;
+    op.user_data = (void *)(gpr_uintptr) i;
 
     grpc_metadata_buffer_queue(&buffer, &op);
   }
diff --git a/test/core/echo/client.c b/test/core/echo/client.c
index fb1e366..f2b69ec 100644
--- a/test/core/echo/client.c
+++ b/test/core/echo/client.c
@@ -78,9 +78,8 @@
 
   GPR_ASSERT(argc == 2);
   channel = grpc_channel_create(argv[1], NULL);
-  call = grpc_channel_create_call_old(
-      channel, "/foo", "localhost",
-      gpr_time_add(gpr_time_from_seconds(5), gpr_now()));
+  call = grpc_channel_create_call_old(channel, "/foo", "localhost",
+                                      GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5));
   GPR_ASSERT(grpc_call_invoke_old(call, cq, (void *)1, (void *)1, 0) ==
              GRPC_CALL_OK);
 
diff --git a/test/core/echo/server.c b/test/core/echo/server.c
index 83da8b6..bc84645 100644
--- a/test/core/echo/server.c
+++ b/test/core/echo/server.c
@@ -166,7 +166,7 @@
       shutdown_started = 1;
     }
     ev = grpc_completion_queue_next(
-        cq, gpr_time_add(gpr_now(), gpr_time_from_micros(1000000)));
+        cq, gpr_time_add(gpr_now(), gpr_time_from_seconds(1)));
     if (!ev) continue;
     s = ev->tag;
     switch (ev->type) {
diff --git a/test/core/end2end/cq_verifier.c b/test/core/end2end/cq_verifier.c
index 9ed98a4..9369dfd 100644
--- a/test/core/end2end/cq_verifier.c
+++ b/test/core/end2end/cq_verifier.c
@@ -116,7 +116,8 @@
   return 0;
 }
 
-int contains_metadata(grpc_metadata_array *array, const char *key, const char *value) {
+int contains_metadata(grpc_metadata_array *array, const char *key,
+                      const char *value) {
   return has_metadata(array->metadata, array->count, key, value);
 }
 
@@ -327,8 +328,7 @@
 }
 
 void cq_verify(cq_verifier *v) {
-  gpr_timespec deadline =
-      gpr_time_add(gpr_now(), gpr_time_from_micros(10 * GPR_US_PER_SEC));
+  gpr_timespec deadline = GRPC_TIMEOUT_SECONDS_TO_DEADLINE(10);
   grpc_event *ev;
   expectation *e;
   char *s;
@@ -371,8 +371,7 @@
 }
 
 void cq_verify_empty(cq_verifier *v) {
-  gpr_timespec deadline =
-      gpr_time_add(gpr_now(), gpr_time_from_micros(3000000));
+  gpr_timespec deadline = gpr_time_add(gpr_now(), gpr_time_from_seconds(1));
   grpc_event *ev;
 
   GPR_ASSERT(v->expect.next == &v->expect && "expectation queue must be empty");
diff --git a/test/core/end2end/cq_verifier.h b/test/core/end2end/cq_verifier.h
index ad64811..c1e25d8 100644
--- a/test/core/end2end/cq_verifier.h
+++ b/test/core/end2end/cq_verifier.h
@@ -31,10 +31,11 @@
  *
  */
 
-#ifndef __GRPC_TEST_END2END_CQ_VERIFIER_H__
-#define __GRPC_TEST_END2END_CQ_VERIFIER_H__
+#ifndef GRPC_TEST_CORE_END2END_CQ_VERIFIER_H
+#define GRPC_TEST_CORE_END2END_CQ_VERIFIER_H
 
 #include <grpc/grpc.h>
+#include "test/core/util/test_config.h"
 
 /* A cq_verifier can verify that expected events arrive in a timely fashion
    on a single completion queue */
@@ -75,4 +76,4 @@
 int byte_buffer_eq_string(grpc_byte_buffer *byte_buffer, const char *string);
 int contains_metadata(grpc_metadata_array *array, const char *key, const char *value);
 
-#endif /* __GRPC_TEST_END2END_CQ_VERIFIER_H__ */
+#endif  /* GRPC_TEST_CORE_END2END_CQ_VERIFIER_H */
diff --git a/test/core/end2end/data/ssl_test_data.h b/test/core/end2end/data/ssl_test_data.h
index 4124867..4f4b30e 100644
--- a/test/core/end2end/data/ssl_test_data.h
+++ b/test/core/end2end/data/ssl_test_data.h
@@ -31,11 +31,11 @@
  *
  */
 
-#ifndef __GRPC_TEST_END2END_DATA_SSL_TEST_DATA_H__
-#define __GRPC_TEST_END2END_DATA_SSL_TEST_DATA_H__
+#ifndef GRPC_TEST_CORE_END2END_DATA_SSL_TEST_DATA_H
+#define GRPC_TEST_CORE_END2END_DATA_SSL_TEST_DATA_H
 
 extern const char test_root_cert[];
 extern const char test_server1_cert[];
 extern const char test_server1_key[];
 
-#endif /* __GRPC_TEST_END2END_DATA_SSL_TEST_DATA_H__ */
+#endif  /* GRPC_TEST_CORE_END2END_DATA_SSL_TEST_DATA_H */
diff --git a/test/core/end2end/dualstack_socket_test.c b/test/core/end2end/dualstack_socket_test.c
index 2c4c3b7..66b76dc 100644
--- a/test/core/end2end/dualstack_socket_test.c
+++ b/test/core/end2end/dualstack_socket_test.c
@@ -45,7 +45,7 @@
 static void *tag(gpr_intptr i) { return (void *)i; }
 
 static gpr_timespec ms_from_now(int ms) {
-  return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_MS * ms));
+  return GRPC_TIMEOUT_MILLIS_TO_DEADLINE(ms);
 }
 
 static void drain_cq(grpc_completion_queue *cq) {
@@ -75,6 +75,10 @@
   gpr_timespec deadline;
   int got_port;
 
+  if (port == 0) {
+    port = grpc_pick_unused_port_or_die();
+  }
+
   gpr_join_host_port(&server_hostport, server_host, port);
 
   /* Create server. */
@@ -112,7 +116,7 @@
   }
 
   /* Send a trivial request. */
-  c = grpc_channel_create_call_old(client, "/foo", "foo.test.google.com",
+  c = grpc_channel_create_call_old(client, "/foo", "foo.test.google.fr",
                                    deadline);
   GPR_ASSERT(c);
 
@@ -126,7 +130,7 @@
 
     GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call_old(server, tag(100)));
     cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo",
-                             "foo.test.google.com", deadline, NULL);
+                             "foo.test.google.fr", deadline, NULL);
     cq_verify(v_server);
 
     GPR_ASSERT(GRPC_CALL_OK ==
@@ -179,7 +183,6 @@
 
 int main(int argc, char **argv) {
   int do_ipv6 = 1;
-  int fixed_port;
 
   grpc_test_init(argc, argv);
   grpc_init();
@@ -189,32 +192,28 @@
     do_ipv6 = 0;
   }
 
-  for (fixed_port = 0; fixed_port <= 1; fixed_port++) {
-    int port = fixed_port ? grpc_pick_unused_port_or_die() : 0;
-
     /* For coverage, test with and without dualstack sockets. */
-    for (grpc_forbid_dualstack_sockets_for_testing = 0;
-         grpc_forbid_dualstack_sockets_for_testing <= 1;
-         grpc_forbid_dualstack_sockets_for_testing++) {
-      /* :: and 0.0.0.0 are handled identically. */
-      test_connect("::", "127.0.0.1", port, 1);
-      test_connect("::", "::ffff:127.0.0.1", port, 1);
-      test_connect("::", "localhost", port, 1);
-      test_connect("0.0.0.0", "127.0.0.1", port, 1);
-      test_connect("0.0.0.0", "::ffff:127.0.0.1", port, 1);
-      test_connect("0.0.0.0", "localhost", port, 1);
-      if (do_ipv6) {
-        test_connect("::", "::1", port, 1);
-        test_connect("0.0.0.0", "::1", port, 1);
-      }
+  for (grpc_forbid_dualstack_sockets_for_testing = 0;
+       grpc_forbid_dualstack_sockets_for_testing <= 1;
+       grpc_forbid_dualstack_sockets_for_testing++) {
+    /* :: and 0.0.0.0 are handled identically. */
+    test_connect("::", "127.0.0.1", 0, 1);
+    test_connect("::", "::ffff:127.0.0.1", 0, 1);
+    test_connect("::", "localhost", 0, 1);
+    test_connect("0.0.0.0", "127.0.0.1", 0, 1);
+    test_connect("0.0.0.0", "::ffff:127.0.0.1", 0, 1);
+    test_connect("0.0.0.0", "localhost", 0, 1);
+    if (do_ipv6) {
+      test_connect("::", "::1", 0, 1);
+      test_connect("0.0.0.0", "::1", 0, 1);
+    }
 
-      /* These only work when the families agree. */
-      test_connect("127.0.0.1", "127.0.0.1", port, 1);
-      if (do_ipv6) {
-        test_connect("::1", "::1", port, 1);
-        test_connect("::1", "127.0.0.1", port, 0);
-        test_connect("127.0.0.1", "::1", port, 0);
-      }
+    /* These only work when the families agree. */
+    test_connect("127.0.0.1", "127.0.0.1", 0, 1);
+    if (do_ipv6) {
+      test_connect("::1", "::1", 0, 1);
+      test_connect("::1", "127.0.0.1", 0, 0);
+      test_connect("127.0.0.1", "::1", 0, 0);
     }
   }
 
diff --git a/test/core/end2end/end2end_tests.h b/test/core/end2end/end2end_tests.h
index 8f2cd0f..b6d9325 100644
--- a/test/core/end2end/end2end_tests.h
+++ b/test/core/end2end/end2end_tests.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_TEST_END2END_END2END_TESTS_H__
-#define __GRPC_TEST_END2END_END2END_TESTS_H__
+#ifndef GRPC_TEST_CORE_END2END_END2END_TESTS_H
+#define GRPC_TEST_CORE_END2END_END2END_TESTS_H
 
 #include <grpc/grpc.h>
 
@@ -63,4 +63,4 @@
 
 void grpc_end2end_tests(grpc_end2end_test_config config);
 
-#endif /* __GRPC_TEST_END2END_END2END_TESTS_H__ */
+#endif  /* GRPC_TEST_CORE_END2END_END2END_TESTS_H */
diff --git a/test/core/end2end/fixtures/chttp2_fake_security.c b/test/core/end2end/fixtures/chttp2_fake_security.c
index 039909f..247d1fd 100644
--- a/test/core/end2end/fixtures/chttp2_fake_security.c
+++ b/test/core/end2end/fixtures/chttp2_fake_security.c
@@ -117,7 +117,8 @@
      chttp2_create_fixture_secure_fullstack,
      chttp2_init_client_fake_secure_fullstack,
      chttp2_init_server_fake_secure_fullstack,
-     chttp2_tear_down_secure_fullstack}, };
+     chttp2_tear_down_secure_fullstack},
+};
 
 int main(int argc, char **argv) {
   size_t i;
diff --git a/test/core/end2end/fixtures/chttp2_fullstack.c b/test/core/end2end/fixtures/chttp2_fullstack.c
index ea367f4..ab7c7f4 100644
--- a/test/core/end2end/fixtures/chttp2_fullstack.c
+++ b/test/core/end2end/fixtures/chttp2_fullstack.c
@@ -99,7 +99,8 @@
 static grpc_end2end_test_config configs[] = {
     {"chttp2/fullstack", FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION,
      chttp2_create_fixture_fullstack, chttp2_init_client_fullstack,
-     chttp2_init_server_fullstack, chttp2_tear_down_fullstack}, };
+     chttp2_init_server_fullstack, chttp2_tear_down_fullstack},
+};
 
 int main(int argc, char **argv) {
   size_t i;
diff --git a/test/core/end2end/fixtures/chttp2_simple_ssl_fullstack.c b/test/core/end2end/fixtures/chttp2_simple_ssl_fullstack.c
index 1db9e72..16946d5 100644
--- a/test/core/end2end/fixtures/chttp2_simple_ssl_fullstack.c
+++ b/test/core/end2end/fixtures/chttp2_simple_ssl_fullstack.c
@@ -101,11 +101,10 @@
 
 static void chttp2_init_client_simple_ssl_secure_fullstack(
     grpc_end2end_test_fixture *f, grpc_channel_args *client_args) {
-  grpc_credentials *ssl_creds =
-      grpc_ssl_credentials_create(NULL, NULL);
+  grpc_credentials *ssl_creds = grpc_ssl_credentials_create(NULL, NULL);
   grpc_arg ssl_name_override = {GRPC_ARG_STRING,
                                 GRPC_SSL_TARGET_NAME_OVERRIDE_ARG,
-                                {"foo.test.google.com"}};
+                                {"foo.test.google.fr"}};
   grpc_channel_args *new_client_args =
       grpc_channel_args_copy_and_add(client_args, &ssl_name_override);
   chttp2_init_client_secure_fullstack(f, new_client_args, ssl_creds);
@@ -128,7 +127,8 @@
      chttp2_create_fixture_secure_fullstack,
      chttp2_init_client_simple_ssl_secure_fullstack,
      chttp2_init_server_simple_ssl_secure_fullstack,
-     chttp2_tear_down_secure_fullstack}, };
+     chttp2_tear_down_secure_fullstack},
+};
 
 int main(int argc, char **argv) {
   size_t i;
diff --git a/test/core/end2end/fixtures/chttp2_simple_ssl_with_oauth2_fullstack.c b/test/core/end2end/fixtures/chttp2_simple_ssl_with_oauth2_fullstack.c
index 35e022c..c451e01 100644
--- a/test/core/end2end/fixtures/chttp2_simple_ssl_with_oauth2_fullstack.c
+++ b/test/core/end2end/fixtures/chttp2_simple_ssl_with_oauth2_fullstack.c
@@ -107,7 +107,7 @@
       grpc_composite_credentials_create(ssl_creds, oauth2_creds);
   grpc_arg ssl_name_override = {GRPC_ARG_STRING,
                                 GRPC_SSL_TARGET_NAME_OVERRIDE_ARG,
-                                {"foo.test.google.com"}};
+                                {"foo.test.google.fr"}};
   grpc_channel_args *new_client_args =
       grpc_channel_args_copy_and_add(client_args, &ssl_name_override);
   chttp2_init_client_secure_fullstack(f, new_client_args, ssl_oauth2_creds);
@@ -133,7 +133,8 @@
      chttp2_create_fixture_secure_fullstack,
      chttp2_init_client_simple_ssl_with_oauth2_secure_fullstack,
      chttp2_init_server_simple_ssl_secure_fullstack,
-     chttp2_tear_down_secure_fullstack}, };
+     chttp2_tear_down_secure_fullstack},
+};
 
 int main(int argc, char **argv) {
   size_t i;
diff --git a/test/core/end2end/fixtures/chttp2_socket_pair.c b/test/core/end2end/fixtures/chttp2_socket_pair.c
index 759c6b4..1225f7d 100644
--- a/test/core/end2end/fixtures/chttp2_socket_pair.c
+++ b/test/core/end2end/fixtures/chttp2_socket_pair.c
@@ -133,7 +133,8 @@
 static grpc_end2end_test_config configs[] = {
     {"chttp2/socketpair", 0, chttp2_create_fixture_socketpair,
      chttp2_init_client_socketpair, chttp2_init_server_socketpair,
-     chttp2_tear_down_socketpair}, };
+     chttp2_tear_down_socketpair},
+};
 
 int main(int argc, char **argv) {
   size_t i;
diff --git a/test/core/end2end/fixtures/chttp2_socket_pair_one_byte_at_a_time.c b/test/core/end2end/fixtures/chttp2_socket_pair_one_byte_at_a_time.c
index c814527..9f6ad98 100644
--- a/test/core/end2end/fixtures/chttp2_socket_pair_one_byte_at_a_time.c
+++ b/test/core/end2end/fixtures/chttp2_socket_pair_one_byte_at_a_time.c
@@ -133,7 +133,8 @@
 static grpc_end2end_test_config configs[] = {
     {"chttp2/socketpair_one_byte_at_a_time", 0,
      chttp2_create_fixture_socketpair, chttp2_init_client_socketpair,
-     chttp2_init_server_socketpair, chttp2_tear_down_socketpair}, };
+     chttp2_init_server_socketpair, chttp2_tear_down_socketpair},
+};
 
 int main(int argc, char **argv) {
   size_t i;
diff --git a/test/core/end2end/no_server_test.c b/test/core/end2end/no_server_test.c
index 92e8e5a..d953552 100644
--- a/test/core/end2end/no_server_test.c
+++ b/test/core/end2end/no_server_test.c
@@ -41,8 +41,7 @@
 int main(int argc, char **argv) {
   grpc_channel *chan;
   grpc_call *call;
-  gpr_timespec timeout = gpr_time_from_seconds(4);
-  gpr_timespec deadline = gpr_time_add(gpr_now(), timeout);
+  gpr_timespec deadline = GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5);
   grpc_completion_queue *cq;
   cq_verifier *cqv;
   grpc_event *ev;
diff --git a/test/core/end2end/tests/cancel_after_accept.c b/test/core/end2end/tests/cancel_after_accept.c
index faaa147..9a19abf 100644
--- a/test/core/end2end/tests/cancel_after_accept.c
+++ b/test/core/end2end/tests/cancel_after_accept.c
@@ -62,7 +62,7 @@
 }
 
 static gpr_timespec n_seconds_time(int n) {
-  return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n));
+  return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n);
 }
 
 static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); }
@@ -132,7 +132,7 @@
   int was_cancelled = 2;
 
   c = grpc_channel_create_call(f.client, f.client_cq, "/foo",
-                               "foo.test.google.com", deadline);
+                               "foo.test.google.fr", deadline);
   GPR_ASSERT(c);
 
   grpc_metadata_array_init(&initial_metadata_recv);
@@ -163,11 +163,9 @@
   op++;
   GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_batch(c, ops, op - ops, tag(1)));
 
-  GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call(f.server, &s,
-                                                      &call_details,
-                                                      &request_metadata_recv,
-                                                      f.server_cq,
-                                                      tag(2)));
+  GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call(
+                                 f.server, &s, &call_details,
+                                 &request_metadata_recv, f.server_cq, tag(2)));
   cq_expect_completion(v_server, tag(2), GRPC_OP_OK);
   cq_verify(v_server);
 
diff --git a/test/core/end2end/tests/cancel_after_accept_and_writes_closed.c b/test/core/end2end/tests/cancel_after_accept_and_writes_closed.c
index c6fb8b3..f360fa3 100644
--- a/test/core/end2end/tests/cancel_after_accept_and_writes_closed.c
+++ b/test/core/end2end/tests/cancel_after_accept_and_writes_closed.c
@@ -62,7 +62,7 @@
 }
 
 static gpr_timespec n_seconds_time(int n) {
-  return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n));
+  return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n);
 }
 
 static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); }
@@ -113,7 +113,7 @@
   cq_verifier *v_client = cq_verifier_create(f.client_cq);
   cq_verifier *v_server = cq_verifier_create(f.server_cq);
 
-  c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.com",
+  c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.fr",
                                    deadline);
   GPR_ASSERT(c);
 
@@ -121,8 +121,8 @@
              grpc_call_invoke_old(c, f.client_cq, tag(2), tag(3), 0));
 
   GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call_old(f.server, tag(100)));
-  cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo",
-                           "foo.test.google.com", deadline, NULL);
+  cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "foo.test.google.fr",
+                           deadline, NULL);
   cq_verify(v_server);
 
   GPR_ASSERT(GRPC_CALL_OK ==
diff --git a/test/core/end2end/tests/cancel_after_accept_and_writes_closed_legacy.c b/test/core/end2end/tests/cancel_after_accept_and_writes_closed_legacy.c
index 85b7599..f360fa3 100644
--- a/test/core/end2end/tests/cancel_after_accept_and_writes_closed_legacy.c
+++ b/test/core/end2end/tests/cancel_after_accept_and_writes_closed_legacy.c
@@ -62,7 +62,7 @@
 }
 
 static gpr_timespec n_seconds_time(int n) {
-  return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n));
+  return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n);
 }
 
 static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); }
@@ -113,7 +113,7 @@
   cq_verifier *v_client = cq_verifier_create(f.client_cq);
   cq_verifier *v_server = cq_verifier_create(f.server_cq);
 
-  c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.com",
+  c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.fr",
                                    deadline);
   GPR_ASSERT(c);
 
@@ -121,7 +121,7 @@
              grpc_call_invoke_old(c, f.client_cq, tag(2), tag(3), 0));
 
   GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call_old(f.server, tag(100)));
-  cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "foo.test.google.com",
+  cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "foo.test.google.fr",
                            deadline, NULL);
   cq_verify(v_server);
 
diff --git a/test/core/end2end/tests/cancel_after_accept_legacy.c b/test/core/end2end/tests/cancel_after_accept_legacy.c
index 345c31d..904a06f 100644
--- a/test/core/end2end/tests/cancel_after_accept_legacy.c
+++ b/test/core/end2end/tests/cancel_after_accept_legacy.c
@@ -62,7 +62,7 @@
 }
 
 static gpr_timespec n_seconds_time(int n) {
-  return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n));
+  return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n);
 }
 
 static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); }
@@ -113,7 +113,7 @@
   cq_verifier *v_client = cq_verifier_create(f.client_cq);
   cq_verifier *v_server = cq_verifier_create(f.server_cq);
 
-  c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.com",
+  c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.fr",
                                    deadline);
   GPR_ASSERT(c);
 
@@ -121,7 +121,7 @@
              grpc_call_invoke_old(c, f.client_cq, tag(2), tag(3), 0));
 
   GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call_old(f.server, tag(100)));
-  cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "foo.test.google.com",
+  cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "foo.test.google.fr",
                            deadline, NULL);
   cq_verify(v_server);
 
diff --git a/test/core/end2end/tests/cancel_after_invoke.c b/test/core/end2end/tests/cancel_after_invoke.c
index 3c75024..e15fa7f 100644
--- a/test/core/end2end/tests/cancel_after_invoke.c
+++ b/test/core/end2end/tests/cancel_after_invoke.c
@@ -62,7 +62,7 @@
 }
 
 static gpr_timespec n_seconds_time(int n) {
-  return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n));
+  return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n);
 }
 
 static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); }
@@ -125,7 +125,7 @@
       grpc_byte_buffer_create(&request_payload_slice, 1);
 
   c = grpc_channel_create_call(f.client, f.client_cq, "/foo",
-                               "foo.test.google.com", deadline);
+                               "foo.test.google.fr", deadline);
   GPR_ASSERT(c);
 
   grpc_metadata_array_init(&initial_metadata_recv);
diff --git a/test/core/end2end/tests/cancel_after_invoke_legacy.c b/test/core/end2end/tests/cancel_after_invoke_legacy.c
index 64af7cd..6ad471d 100644
--- a/test/core/end2end/tests/cancel_after_invoke_legacy.c
+++ b/test/core/end2end/tests/cancel_after_invoke_legacy.c
@@ -62,7 +62,7 @@
 }
 
 static gpr_timespec n_seconds_time(int n) {
-  return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n));
+  return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n);
 }
 
 static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); }
@@ -111,7 +111,7 @@
   gpr_timespec deadline = five_seconds_time();
   cq_verifier *v_client = cq_verifier_create(f.client_cq);
 
-  c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.com",
+  c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.fr",
                                    deadline);
   GPR_ASSERT(c);
 
diff --git a/test/core/end2end/tests/cancel_before_invoke.c b/test/core/end2end/tests/cancel_before_invoke.c
index bee6dd2..6e100db 100644
--- a/test/core/end2end/tests/cancel_before_invoke.c
+++ b/test/core/end2end/tests/cancel_before_invoke.c
@@ -61,7 +61,7 @@
 }
 
 static gpr_timespec n_seconds_time(int n) {
-  return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n));
+  return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n);
 }
 
 static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); }
@@ -103,7 +103,8 @@
 }
 
 /* Cancel before invoke */
-static void test_cancel_before_invoke(grpc_end2end_test_config config, int test_ops) {
+static void test_cancel_before_invoke(grpc_end2end_test_config config,
+                                      int test_ops) {
   grpc_op ops[6];
   grpc_op *op;
   grpc_call *c;
@@ -123,7 +124,7 @@
       grpc_byte_buffer_create(&request_payload_slice, 1);
 
   c = grpc_channel_create_call(f.client, f.client_cq, "/foo",
-                               "foo.test.google.com", deadline);
+                               "foo.test.google.fr", deadline);
   GPR_ASSERT(c);
 
   GPR_ASSERT(GRPC_CALL_OK == grpc_call_cancel(c));
diff --git a/test/core/end2end/tests/cancel_before_invoke_legacy.c b/test/core/end2end/tests/cancel_before_invoke_legacy.c
index 23e82cf..c8db3d2 100644
--- a/test/core/end2end/tests/cancel_before_invoke_legacy.c
+++ b/test/core/end2end/tests/cancel_before_invoke_legacy.c
@@ -61,7 +61,7 @@
 }
 
 static gpr_timespec n_seconds_time(int n) {
-  return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n));
+  return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n);
 }
 
 static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); }
@@ -109,7 +109,7 @@
   gpr_timespec deadline = five_seconds_time();
   cq_verifier *v_client = cq_verifier_create(f.client_cq);
 
-  c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.com",
+  c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.fr",
                                    deadline);
   GPR_ASSERT(c);
 
diff --git a/test/core/end2end/tests/cancel_in_a_vacuum.c b/test/core/end2end/tests/cancel_in_a_vacuum.c
index 8228353..a88ca0b 100644
--- a/test/core/end2end/tests/cancel_in_a_vacuum.c
+++ b/test/core/end2end/tests/cancel_in_a_vacuum.c
@@ -60,7 +60,7 @@
 }
 
 static gpr_timespec n_seconds_time(int n) {
-  return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n));
+  return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n);
 }
 
 static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); }
@@ -110,7 +110,7 @@
   cq_verifier *v_client = cq_verifier_create(f.client_cq);
 
   c = grpc_channel_create_call(f.client, f.client_cq, "/foo",
-                               "foo.test.google.com", deadline);
+                               "foo.test.google.fr", deadline);
   GPR_ASSERT(c);
 
   GPR_ASSERT(GRPC_CALL_OK == mode.initiate_cancel(c));
diff --git a/test/core/end2end/tests/cancel_in_a_vacuum_legacy.c b/test/core/end2end/tests/cancel_in_a_vacuum_legacy.c
index 869f091..a827eed 100644
--- a/test/core/end2end/tests/cancel_in_a_vacuum_legacy.c
+++ b/test/core/end2end/tests/cancel_in_a_vacuum_legacy.c
@@ -60,7 +60,7 @@
 }
 
 static gpr_timespec n_seconds_time(int n) {
-  return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n));
+  return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n);
 }
 
 static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); }
@@ -109,7 +109,7 @@
   gpr_timespec deadline = five_seconds_time();
   cq_verifier *v_client = cq_verifier_create(f.client_cq);
 
-  c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.com",
+  c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.fr",
                                    deadline);
   GPR_ASSERT(c);
 
diff --git a/test/core/end2end/tests/cancel_test_helpers.h b/test/core/end2end/tests/cancel_test_helpers.h
index 3dd7437..f2581dc 100644
--- a/test/core/end2end/tests/cancel_test_helpers.h
+++ b/test/core/end2end/tests/cancel_test_helpers.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_TEST_END2END_TESTS_CANCEL_TEST_HELPERS_H__
-#define __GRPC_TEST_END2END_TESTS_CANCEL_TEST_HELPERS_H__
+#ifndef GRPC_TEST_CORE_END2END_TESTS_CANCEL_TEST_HELPERS_H
+#define GRPC_TEST_CORE_END2END_TESTS_CANCEL_TEST_HELPERS_H
 
 typedef struct {
   grpc_call_error (*initiate_cancel)(grpc_call *call);
@@ -48,4 +48,4 @@
     {grpc_call_cancel, GRPC_STATUS_CANCELLED, ""},
     {wait_for_deadline, GRPC_STATUS_DEADLINE_EXCEEDED, "Deadline Exceeded"}, };
 
-#endif
+#endif  /* GRPC_TEST_CORE_END2END_TESTS_CANCEL_TEST_HELPERS_H */
diff --git a/test/core/end2end/tests/census_simple_request.c b/test/core/end2end/tests/census_simple_request.c
index 003a8be..dabdc56 100644
--- a/test/core/end2end/tests/census_simple_request.c
+++ b/test/core/end2end/tests/census_simple_request.c
@@ -46,7 +46,7 @@
 #include "test/core/end2end/cq_verifier.h"
 
 static gpr_timespec n_seconds_time(int n) {
-  return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n));
+  return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n);
 }
 
 static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
@@ -106,7 +106,7 @@
   cq_verifier *v_client = cq_verifier_create(f.client_cq);
   cq_verifier *v_server = cq_verifier_create(f.server_cq);
 
-  c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.com",
+  c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.fr",
                                    deadline);
   GPR_ASSERT(c);
   tag(1);
@@ -118,7 +118,7 @@
   cq_verify(v_client);
 
   GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call_old(f.server, tag(100)));
-  cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "foo.test.google.com",
+  cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "foo.test.google.fr",
                            deadline, NULL);
   cq_verify(v_server);
 
diff --git a/test/core/end2end/tests/census_simple_request_legacy.c b/test/core/end2end/tests/census_simple_request_legacy.c
index 003a8be..dabdc56 100644
--- a/test/core/end2end/tests/census_simple_request_legacy.c
+++ b/test/core/end2end/tests/census_simple_request_legacy.c
@@ -46,7 +46,7 @@
 #include "test/core/end2end/cq_verifier.h"
 
 static gpr_timespec n_seconds_time(int n) {
-  return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n));
+  return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n);
 }
 
 static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
@@ -106,7 +106,7 @@
   cq_verifier *v_client = cq_verifier_create(f.client_cq);
   cq_verifier *v_server = cq_verifier_create(f.server_cq);
 
-  c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.com",
+  c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.fr",
                                    deadline);
   GPR_ASSERT(c);
   tag(1);
@@ -118,7 +118,7 @@
   cq_verify(v_client);
 
   GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call_old(f.server, tag(100)));
-  cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "foo.test.google.com",
+  cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "foo.test.google.fr",
                            deadline, NULL);
   cq_verify(v_server);
 
diff --git a/test/core/end2end/tests/disappearing_server.c b/test/core/end2end/tests/disappearing_server.c
index 6115896..a65a9f3 100644
--- a/test/core/end2end/tests/disappearing_server.c
+++ b/test/core/end2end/tests/disappearing_server.c
@@ -49,7 +49,7 @@
 static void *tag(gpr_intptr t) { return (void *)t; }
 
 static gpr_timespec n_seconds_time(int n) {
-  return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n));
+  return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n);
 }
 
 static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); }
@@ -97,7 +97,7 @@
   grpc_call *s;
   gpr_timespec deadline = five_seconds_time();
 
-  c = grpc_channel_create_call_old(f->client, "/foo", "foo.test.google.com",
+  c = grpc_channel_create_call_old(f->client, "/foo", "foo.test.google.fr",
                                    deadline);
   GPR_ASSERT(c);
 
@@ -109,8 +109,8 @@
   cq_verify(v_client);
 
   GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call_old(f->server, tag(100)));
-  cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo",
-                           "foo.test.google.com", deadline, NULL);
+  cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "foo.test.google.fr",
+                           deadline, NULL);
   cq_verify(v_server);
 
   GPR_ASSERT(GRPC_CALL_OK ==
diff --git a/test/core/end2end/tests/disappearing_server_legacy.c b/test/core/end2end/tests/disappearing_server_legacy.c
index ff8832a..a65a9f3 100644
--- a/test/core/end2end/tests/disappearing_server_legacy.c
+++ b/test/core/end2end/tests/disappearing_server_legacy.c
@@ -49,7 +49,7 @@
 static void *tag(gpr_intptr t) { return (void *)t; }
 
 static gpr_timespec n_seconds_time(int n) {
-  return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n));
+  return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n);
 }
 
 static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); }
@@ -97,7 +97,7 @@
   grpc_call *s;
   gpr_timespec deadline = five_seconds_time();
 
-  c = grpc_channel_create_call_old(f->client, "/foo", "foo.test.google.com",
+  c = grpc_channel_create_call_old(f->client, "/foo", "foo.test.google.fr",
                                    deadline);
   GPR_ASSERT(c);
 
@@ -109,7 +109,7 @@
   cq_verify(v_client);
 
   GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call_old(f->server, tag(100)));
-  cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "foo.test.google.com",
+  cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "foo.test.google.fr",
                            deadline, NULL);
   cq_verify(v_server);
 
diff --git a/test/core/end2end/tests/early_server_shutdown_finishes_inflight_calls.c b/test/core/end2end/tests/early_server_shutdown_finishes_inflight_calls.c
index 49ec471..16ed627 100644
--- a/test/core/end2end/tests/early_server_shutdown_finishes_inflight_calls.c
+++ b/test/core/end2end/tests/early_server_shutdown_finishes_inflight_calls.c
@@ -61,7 +61,7 @@
 }
 
 static gpr_timespec n_seconds_time(int n) {
-  return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n));
+  return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n);
 }
 
 static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); }
@@ -111,7 +111,7 @@
   cq_verifier *v_client = cq_verifier_create(f.client_cq);
   cq_verifier *v_server = cq_verifier_create(f.server_cq);
 
-  c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.com",
+  c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.fr",
                                    deadline);
   GPR_ASSERT(c);
 
@@ -123,8 +123,8 @@
   cq_verify(v_client);
 
   GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call_old(f.server, tag(100)));
-  cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo",
-                           "foo.test.google.com", deadline, NULL);
+  cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "foo.test.google.fr",
+                           deadline, NULL);
   cq_verify(v_server);
 
   GPR_ASSERT(GRPC_CALL_OK ==
diff --git a/test/core/end2end/tests/early_server_shutdown_finishes_inflight_calls_legacy.c b/test/core/end2end/tests/early_server_shutdown_finishes_inflight_calls_legacy.c
index 2e3a05e..16ed627 100644
--- a/test/core/end2end/tests/early_server_shutdown_finishes_inflight_calls_legacy.c
+++ b/test/core/end2end/tests/early_server_shutdown_finishes_inflight_calls_legacy.c
@@ -61,7 +61,7 @@
 }
 
 static gpr_timespec n_seconds_time(int n) {
-  return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n));
+  return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n);
 }
 
 static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); }
@@ -111,7 +111,7 @@
   cq_verifier *v_client = cq_verifier_create(f.client_cq);
   cq_verifier *v_server = cq_verifier_create(f.server_cq);
 
-  c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.com",
+  c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.fr",
                                    deadline);
   GPR_ASSERT(c);
 
@@ -123,7 +123,7 @@
   cq_verify(v_client);
 
   GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call_old(f.server, tag(100)));
-  cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "foo.test.google.com",
+  cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "foo.test.google.fr",
                            deadline, NULL);
   cq_verify(v_server);
 
diff --git a/test/core/end2end/tests/early_server_shutdown_finishes_tags.c b/test/core/end2end/tests/early_server_shutdown_finishes_tags.c
index 49dddc7..061a2d3 100644
--- a/test/core/end2end/tests/early_server_shutdown_finishes_tags.c
+++ b/test/core/end2end/tests/early_server_shutdown_finishes_tags.c
@@ -61,7 +61,7 @@
 }
 
 static gpr_timespec n_seconds_time(int n) {
-  return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n));
+  return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n);
 }
 
 static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); }
diff --git a/test/core/end2end/tests/early_server_shutdown_finishes_tags_legacy.c b/test/core/end2end/tests/early_server_shutdown_finishes_tags_legacy.c
index ed8f839..bb0ef92 100644
--- a/test/core/end2end/tests/early_server_shutdown_finishes_tags_legacy.c
+++ b/test/core/end2end/tests/early_server_shutdown_finishes_tags_legacy.c
@@ -61,7 +61,7 @@
 }
 
 static gpr_timespec n_seconds_time(int n) {
-  return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n));
+  return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n);
 }
 
 static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); }
diff --git a/test/core/end2end/tests/empty_batch.c b/test/core/end2end/tests/empty_batch.c
index 7faeeaa..6237e29 100644
--- a/test/core/end2end/tests/empty_batch.c
+++ b/test/core/end2end/tests/empty_batch.c
@@ -63,7 +63,7 @@
 }
 
 static gpr_timespec n_seconds_time(int n) {
-  return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n));
+  return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n);
 }
 
 static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); }
@@ -111,7 +111,7 @@
   grpc_op *op = NULL;
 
   c = grpc_channel_create_call(f.client, f.client_cq, "/foo",
-                               "foo.test.google.com", deadline);
+                               "foo.test.google.fr", deadline);
   GPR_ASSERT(c);
 
   GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_batch(c, op, 0, tag(1)));
diff --git a/test/core/end2end/tests/graceful_server_shutdown.c b/test/core/end2end/tests/graceful_server_shutdown.c
index ab9792e..39830b0 100644
--- a/test/core/end2end/tests/graceful_server_shutdown.c
+++ b/test/core/end2end/tests/graceful_server_shutdown.c
@@ -61,7 +61,7 @@
 }
 
 static gpr_timespec n_seconds_time(int n) {
-  return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n));
+  return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n);
 }
 
 static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); }
@@ -110,7 +110,7 @@
   cq_verifier *v_client = cq_verifier_create(f.client_cq);
   cq_verifier *v_server = cq_verifier_create(f.server_cq);
 
-  c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.com",
+  c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.fr",
                                    deadline);
   GPR_ASSERT(c);
 
@@ -122,8 +122,8 @@
   cq_verify(v_client);
 
   GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call_old(f.server, tag(100)));
-  cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo",
-                           "foo.test.google.com", deadline, NULL);
+  cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "foo.test.google.fr",
+                           deadline, NULL);
   cq_verify(v_server);
 
   GPR_ASSERT(GRPC_CALL_OK ==
diff --git a/test/core/end2end/tests/graceful_server_shutdown_legacy.c b/test/core/end2end/tests/graceful_server_shutdown_legacy.c
index 852a153..39830b0 100644
--- a/test/core/end2end/tests/graceful_server_shutdown_legacy.c
+++ b/test/core/end2end/tests/graceful_server_shutdown_legacy.c
@@ -61,7 +61,7 @@
 }
 
 static gpr_timespec n_seconds_time(int n) {
-  return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n));
+  return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n);
 }
 
 static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); }
@@ -110,7 +110,7 @@
   cq_verifier *v_client = cq_verifier_create(f.client_cq);
   cq_verifier *v_server = cq_verifier_create(f.server_cq);
 
-  c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.com",
+  c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.fr",
                                    deadline);
   GPR_ASSERT(c);
 
@@ -122,7 +122,7 @@
   cq_verify(v_client);
 
   GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call_old(f.server, tag(100)));
-  cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "foo.test.google.com",
+  cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "foo.test.google.fr",
                            deadline, NULL);
   cq_verify(v_server);
 
diff --git a/test/core/end2end/tests/invoke_large_request.c b/test/core/end2end/tests/invoke_large_request.c
index 2a302e2..55606ca 100644
--- a/test/core/end2end/tests/invoke_large_request.c
+++ b/test/core/end2end/tests/invoke_large_request.c
@@ -61,7 +61,7 @@
 }
 
 static gpr_timespec n_seconds_time(int n) {
-  return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n));
+  return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n);
 }
 
 static void drain_cq(grpc_completion_queue *cq) {
@@ -122,7 +122,7 @@
 
   GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call_old(f.server, tag(100)));
 
-  c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.com",
+  c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.fr",
                                    deadline);
   GPR_ASSERT(c);
 
@@ -138,8 +138,8 @@
      request (as this request is very large) */
   cq_verify_empty(v_client);
 
-  cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo",
-                           "foo.test.google.com", deadline, NULL);
+  cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "foo.test.google.fr",
+                           deadline, NULL);
   cq_verify(v_server);
 
   GPR_ASSERT(GRPC_CALL_OK ==
diff --git a/test/core/end2end/tests/invoke_large_request_legacy.c b/test/core/end2end/tests/invoke_large_request_legacy.c
index 875458e..55606ca 100644
--- a/test/core/end2end/tests/invoke_large_request_legacy.c
+++ b/test/core/end2end/tests/invoke_large_request_legacy.c
@@ -61,7 +61,7 @@
 }
 
 static gpr_timespec n_seconds_time(int n) {
-  return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n));
+  return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n);
 }
 
 static void drain_cq(grpc_completion_queue *cq) {
@@ -122,7 +122,7 @@
 
   GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call_old(f.server, tag(100)));
 
-  c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.com",
+  c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.fr",
                                    deadline);
   GPR_ASSERT(c);
 
@@ -138,7 +138,7 @@
      request (as this request is very large) */
   cq_verify_empty(v_client);
 
-  cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "foo.test.google.com",
+  cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "foo.test.google.fr",
                            deadline, NULL);
   cq_verify(v_server);
 
diff --git a/test/core/end2end/tests/max_concurrent_streams.c b/test/core/end2end/tests/max_concurrent_streams.c
index 85369b5..af29e17 100644
--- a/test/core/end2end/tests/max_concurrent_streams.c
+++ b/test/core/end2end/tests/max_concurrent_streams.c
@@ -61,7 +61,7 @@
 }
 
 static gpr_timespec n_seconds_time(int n) {
-  return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n));
+  return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n);
 }
 
 static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); }
@@ -109,7 +109,7 @@
   cq_verifier *v_client = cq_verifier_create(f.client_cq);
   cq_verifier *v_server = cq_verifier_create(f.server_cq);
 
-  c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.com",
+  c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.fr",
                                    deadline);
   GPR_ASSERT(c);
 
@@ -121,8 +121,8 @@
   cq_verify(v_client);
 
   GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call_old(f.server, tag(100)));
-  cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo",
-                           "foo.test.google.com", deadline, NULL);
+  cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "foo.test.google.fr",
+                           deadline, NULL);
   cq_verify(v_server);
 
   GPR_ASSERT(GRPC_CALL_OK ==
@@ -182,10 +182,10 @@
   /* start two requests - ensuring that the second is not accepted until
      the first completes */
   deadline = five_seconds_time();
-  c1 = grpc_channel_create_call_old(f.client, "/alpha", "foo.test.google.com",
+  c1 = grpc_channel_create_call_old(f.client, "/alpha", "foo.test.google.fr",
                                     deadline);
   GPR_ASSERT(c1);
-  c2 = grpc_channel_create_call_old(f.client, "/beta", "foo.test.google.com",
+  c2 = grpc_channel_create_call_old(f.client, "/beta", "foo.test.google.fr",
                                     deadline);
   GPR_ASSERT(c1);
 
@@ -196,7 +196,7 @@
   GPR_ASSERT(GRPC_CALL_OK ==
              grpc_call_invoke_old(c2, f.client_cq, tag(401), tag(402), 0));
   GPR_ASSERT(GRPC_CALL_OK == grpc_call_writes_done_old(c1, tag(303)));
-  GPR_ASSERT(GRPC_CALL_OK == grpc_call_writes_done_old(c2, tag(303)));
+  GPR_ASSERT(GRPC_CALL_OK == grpc_call_writes_done_old(c2, tag(403)));
 
   ev = grpc_completion_queue_next(
       f.client_cq, gpr_time_add(gpr_now(), gpr_time_from_seconds(10)));
@@ -211,7 +211,7 @@
 
   cq_expect_server_rpc_new(v_server, &s1, tag(100),
                            live_call == 300 ? "/alpha" : "/beta",
-                           "foo.test.google.com", deadline, NULL);
+                           "foo.test.google.fr", deadline, NULL);
   cq_verify(v_server);
 
   GPR_ASSERT(GRPC_CALL_OK ==
@@ -230,14 +230,14 @@
   /* first request is finished, we should be able to start the second */
   cq_expect_finished_with_status(v_client, tag(live_call + 2),
                                  GRPC_STATUS_UNIMPLEMENTED, "xyz", NULL);
-  cq_expect_finish_accepted(v_client, tag(live_call + 3), GRPC_OP_OK);
   live_call = (live_call == 300) ? 400 : 300;
+  cq_expect_finish_accepted(v_client, tag(live_call + 3), GRPC_OP_OK);
   cq_verify(v_client);
 
   GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call_old(f.server, tag(200)));
   cq_expect_server_rpc_new(v_server, &s2, tag(200),
                            live_call == 300 ? "/alpha" : "/beta",
-                           "foo.test.google.com", deadline, NULL);
+                           "foo.test.google.fr", deadline, NULL);
   cq_verify(v_server);
 
   GPR_ASSERT(GRPC_CALL_OK ==
diff --git a/test/core/end2end/tests/max_concurrent_streams_legacy.c b/test/core/end2end/tests/max_concurrent_streams_legacy.c
index 0cb118d..af29e17 100644
--- a/test/core/end2end/tests/max_concurrent_streams_legacy.c
+++ b/test/core/end2end/tests/max_concurrent_streams_legacy.c
@@ -61,7 +61,7 @@
 }
 
 static gpr_timespec n_seconds_time(int n) {
-  return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n));
+  return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n);
 }
 
 static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); }
@@ -109,7 +109,7 @@
   cq_verifier *v_client = cq_verifier_create(f.client_cq);
   cq_verifier *v_server = cq_verifier_create(f.server_cq);
 
-  c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.com",
+  c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.fr",
                                    deadline);
   GPR_ASSERT(c);
 
@@ -121,7 +121,7 @@
   cq_verify(v_client);
 
   GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call_old(f.server, tag(100)));
-  cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "foo.test.google.com",
+  cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "foo.test.google.fr",
                            deadline, NULL);
   cq_verify(v_server);
 
@@ -182,10 +182,10 @@
   /* start two requests - ensuring that the second is not accepted until
      the first completes */
   deadline = five_seconds_time();
-  c1 = grpc_channel_create_call_old(f.client, "/alpha", "foo.test.google.com",
+  c1 = grpc_channel_create_call_old(f.client, "/alpha", "foo.test.google.fr",
                                     deadline);
   GPR_ASSERT(c1);
-  c2 = grpc_channel_create_call_old(f.client, "/beta", "foo.test.google.com",
+  c2 = grpc_channel_create_call_old(f.client, "/beta", "foo.test.google.fr",
                                     deadline);
   GPR_ASSERT(c1);
 
@@ -196,7 +196,7 @@
   GPR_ASSERT(GRPC_CALL_OK ==
              grpc_call_invoke_old(c2, f.client_cq, tag(401), tag(402), 0));
   GPR_ASSERT(GRPC_CALL_OK == grpc_call_writes_done_old(c1, tag(303)));
-  GPR_ASSERT(GRPC_CALL_OK == grpc_call_writes_done_old(c2, tag(303)));
+  GPR_ASSERT(GRPC_CALL_OK == grpc_call_writes_done_old(c2, tag(403)));
 
   ev = grpc_completion_queue_next(
       f.client_cq, gpr_time_add(gpr_now(), gpr_time_from_seconds(10)));
@@ -211,7 +211,7 @@
 
   cq_expect_server_rpc_new(v_server, &s1, tag(100),
                            live_call == 300 ? "/alpha" : "/beta",
-                           "foo.test.google.com", deadline, NULL);
+                           "foo.test.google.fr", deadline, NULL);
   cq_verify(v_server);
 
   GPR_ASSERT(GRPC_CALL_OK ==
@@ -230,14 +230,14 @@
   /* first request is finished, we should be able to start the second */
   cq_expect_finished_with_status(v_client, tag(live_call + 2),
                                  GRPC_STATUS_UNIMPLEMENTED, "xyz", NULL);
-  cq_expect_finish_accepted(v_client, tag(live_call + 3), GRPC_OP_OK);
   live_call = (live_call == 300) ? 400 : 300;
+  cq_expect_finish_accepted(v_client, tag(live_call + 3), GRPC_OP_OK);
   cq_verify(v_client);
 
   GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call_old(f.server, tag(200)));
   cq_expect_server_rpc_new(v_server, &s2, tag(200),
                            live_call == 300 ? "/alpha" : "/beta",
-                           "foo.test.google.com", deadline, NULL);
+                           "foo.test.google.fr", deadline, NULL);
   cq_verify(v_server);
 
   GPR_ASSERT(GRPC_CALL_OK ==
diff --git a/test/core/end2end/tests/no_op.c b/test/core/end2end/tests/no_op.c
index 00d940d..497bdcc 100644
--- a/test/core/end2end/tests/no_op.c
+++ b/test/core/end2end/tests/no_op.c
@@ -59,7 +59,7 @@
 }
 
 static gpr_timespec n_seconds_time(int n) {
-  return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n));
+  return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n);
 }
 
 static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); }
diff --git a/test/core/end2end/tests/no_op_legacy.c b/test/core/end2end/tests/no_op_legacy.c
index 00d940d..497bdcc 100644
--- a/test/core/end2end/tests/no_op_legacy.c
+++ b/test/core/end2end/tests/no_op_legacy.c
@@ -59,7 +59,7 @@
 }
 
 static gpr_timespec n_seconds_time(int n) {
-  return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n));
+  return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n);
 }
 
 static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); }
diff --git a/test/core/end2end/tests/ping_pong_streaming.c b/test/core/end2end/tests/ping_pong_streaming.c
index 2930ba6..23721e9 100644
--- a/test/core/end2end/tests/ping_pong_streaming.c
+++ b/test/core/end2end/tests/ping_pong_streaming.c
@@ -61,7 +61,7 @@
 }
 
 static gpr_timespec n_seconds_time(int n) {
-  return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n));
+  return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n);
 }
 
 static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); }
@@ -118,7 +118,7 @@
   cq_verifier *v_server = cq_verifier_create(f.server_cq);
 
   gpr_log(GPR_INFO, "testing with %d message pairs.", messages);
-  c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.com",
+  c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.fr",
                                    deadline);
   GPR_ASSERT(c);
 
@@ -127,8 +127,8 @@
 
   GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call_old(f.server, tag(100)));
 
-  cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo",
-                           "foo.test.google.com", deadline, NULL);
+  cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "foo.test.google.fr",
+                           deadline, NULL);
   cq_verify(v_server);
   GPR_ASSERT(GRPC_CALL_OK ==
              grpc_call_server_accept_old(s, f.server_cq, tag(102)));
diff --git a/test/core/end2end/tests/ping_pong_streaming_legacy.c b/test/core/end2end/tests/ping_pong_streaming_legacy.c
index b2764e9..23721e9 100644
--- a/test/core/end2end/tests/ping_pong_streaming_legacy.c
+++ b/test/core/end2end/tests/ping_pong_streaming_legacy.c
@@ -61,7 +61,7 @@
 }
 
 static gpr_timespec n_seconds_time(int n) {
-  return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n));
+  return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n);
 }
 
 static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); }
@@ -118,7 +118,7 @@
   cq_verifier *v_server = cq_verifier_create(f.server_cq);
 
   gpr_log(GPR_INFO, "testing with %d message pairs.", messages);
-  c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.com",
+  c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.fr",
                                    deadline);
   GPR_ASSERT(c);
 
@@ -127,7 +127,7 @@
 
   GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call_old(f.server, tag(100)));
 
-  cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "foo.test.google.com",
+  cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "foo.test.google.fr",
                            deadline, NULL);
   cq_verify(v_server);
   GPR_ASSERT(GRPC_CALL_OK ==
diff --git a/test/core/end2end/tests/request_response_with_binary_metadata_and_payload.c b/test/core/end2end/tests/request_response_with_binary_metadata_and_payload.c
index 843e9db..a120f27 100644
--- a/test/core/end2end/tests/request_response_with_binary_metadata_and_payload.c
+++ b/test/core/end2end/tests/request_response_with_binary_metadata_and_payload.c
@@ -61,7 +61,7 @@
 }
 
 static gpr_timespec n_seconds_time(int n) {
-  return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n));
+  return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n);
 }
 
 static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); }
@@ -140,7 +140,7 @@
   int was_cancelled = 2;
 
   c = grpc_channel_create_call(f.client, f.client_cq, "/foo",
-                               "foo.test.google.com", deadline);
+                               "foo.test.google.fr", deadline);
   GPR_ASSERT(c);
 
   grpc_metadata_array_init(&initial_metadata_recv);
@@ -175,8 +175,7 @@
   GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call(f.server, &s,
                                                       &call_details,
                                                       &request_metadata_recv,
-                                                      f.server_cq,
-                                                      tag(101)));
+                                                      f.server_cq, tag(101)));
   cq_expect_completion(v_server, tag(101), GRPC_OP_OK);
   cq_verify(v_server);
 
@@ -210,7 +209,7 @@
   GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED);
   GPR_ASSERT(0 == strcmp(details, "xyz"));
   GPR_ASSERT(0 == strcmp(call_details.method, "/foo"));
-  GPR_ASSERT(0 == strcmp(call_details.host, "foo.test.google.com"));
+  GPR_ASSERT(0 == strcmp(call_details.host, "foo.test.google.fr"));
   GPR_ASSERT(was_cancelled == 0);
   GPR_ASSERT(byte_buffer_eq_string(request_payload_recv, "hello world"));
   GPR_ASSERT(byte_buffer_eq_string(response_payload_recv, "hello you"));
diff --git a/test/core/end2end/tests/request_response_with_binary_metadata_and_payload_legacy.c b/test/core/end2end/tests/request_response_with_binary_metadata_and_payload_legacy.c
index 9c09e51..75fddea 100644
--- a/test/core/end2end/tests/request_response_with_binary_metadata_and_payload_legacy.c
+++ b/test/core/end2end/tests/request_response_with_binary_metadata_and_payload_legacy.c
@@ -61,7 +61,7 @@
 }
 
 static gpr_timespec n_seconds_time(int n) {
-  return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n));
+  return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n);
 }
 
 static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); }
@@ -137,7 +137,7 @@
   gpr_slice_unref(request_payload_slice);
   gpr_slice_unref(response_payload_slice);
 
-  c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.com",
+  c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.fr",
                                    deadline);
   GPR_ASSERT(c);
 
@@ -157,9 +157,10 @@
   cq_verify(v_client);
 
   cq_expect_server_rpc_new(
-      v_server, &s, tag(100), "/foo", "foo.test.google.com", deadline, "key1-bin",
-      "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc", "key2-bin",
-      "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d", NULL);
+      v_server, &s, tag(100), "/foo", "foo.test.google.fr", deadline,
+      "key1-bin", "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc",
+      "key2-bin", "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d",
+      NULL);
   cq_verify(v_server);
 
   grpc_call_server_accept_old(s, f.server_cq, tag(102));
diff --git a/test/core/end2end/tests/request_response_with_metadata_and_payload.c b/test/core/end2end/tests/request_response_with_metadata_and_payload.c
index 7f7b594..d5f58d3 100644
--- a/test/core/end2end/tests/request_response_with_metadata_and_payload.c
+++ b/test/core/end2end/tests/request_response_with_metadata_and_payload.c
@@ -61,7 +61,7 @@
 }
 
 static gpr_timespec n_seconds_time(int n) {
-  return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n));
+  return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n);
 }
 
 static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); }
@@ -133,7 +133,7 @@
   int was_cancelled = 2;
 
   c = grpc_channel_create_call(f.client, f.client_cq, "/foo",
-                               "foo.test.google.com", deadline);
+                               "foo.test.google.fr", deadline);
   GPR_ASSERT(c);
 
   grpc_metadata_array_init(&initial_metadata_recv);
@@ -168,8 +168,7 @@
   GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call(f.server, &s,
                                                       &call_details,
                                                       &request_metadata_recv,
-                                                      f.server_cq,
-                                                      tag(101)));
+                                                      f.server_cq, tag(101)));
   cq_expect_completion(v_server, tag(101), GRPC_OP_OK);
   cq_verify(v_server);
 
@@ -203,7 +202,7 @@
   GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED);
   GPR_ASSERT(0 == strcmp(details, "xyz"));
   GPR_ASSERT(0 == strcmp(call_details.method, "/foo"));
-  GPR_ASSERT(0 == strcmp(call_details.host, "foo.test.google.com"));
+  GPR_ASSERT(0 == strcmp(call_details.host, "foo.test.google.fr"));
   GPR_ASSERT(was_cancelled == 0);
   GPR_ASSERT(byte_buffer_eq_string(request_payload_recv, "hello world"));
   GPR_ASSERT(byte_buffer_eq_string(response_payload_recv, "hello you"));
diff --git a/test/core/end2end/tests/request_response_with_metadata_and_payload_legacy.c b/test/core/end2end/tests/request_response_with_metadata_and_payload_legacy.c
index ba330d5..91a0442 100644
--- a/test/core/end2end/tests/request_response_with_metadata_and_payload_legacy.c
+++ b/test/core/end2end/tests/request_response_with_metadata_and_payload_legacy.c
@@ -61,7 +61,7 @@
 }
 
 static gpr_timespec n_seconds_time(int n) {
-  return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n));
+  return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n);
 }
 
 static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); }
@@ -128,7 +128,7 @@
   gpr_slice_unref(request_payload_slice);
   gpr_slice_unref(response_payload_slice);
 
-  c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.com",
+  c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.fr",
                                    deadline);
   GPR_ASSERT(c);
 
@@ -147,7 +147,7 @@
   cq_expect_write_accepted(v_client, tag(4), GRPC_OP_OK);
   cq_verify(v_client);
 
-  cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "foo.test.google.com",
+  cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "foo.test.google.fr",
                            deadline, "key1", "val1", "key2", "val2", NULL);
   cq_verify(v_server);
 
diff --git a/test/core/end2end/tests/request_response_with_payload.c b/test/core/end2end/tests/request_response_with_payload.c
index a0dc033..9203659 100644
--- a/test/core/end2end/tests/request_response_with_payload.c
+++ b/test/core/end2end/tests/request_response_with_payload.c
@@ -61,7 +61,7 @@
 }
 
 static gpr_timespec n_seconds_time(int n) {
-  return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n));
+  return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n);
 }
 
 static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); }
@@ -128,7 +128,7 @@
   int was_cancelled = 2;
 
   c = grpc_channel_create_call(f.client, f.client_cq, "/foo",
-                               "foo.test.google.com", deadline);
+                               "foo.test.google.fr", deadline);
   GPR_ASSERT(c);
 
   grpc_metadata_array_init(&initial_metadata_recv);
@@ -162,8 +162,7 @@
   GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call(f.server, &s,
                                                       &call_details,
                                                       &request_metadata_recv,
-                                                      f.server_cq,
-                                                      tag(101)));
+                                                      f.server_cq, tag(101)));
   cq_expect_completion(v_server, tag(101), GRPC_OP_OK);
   cq_verify(v_server);
 
@@ -196,7 +195,7 @@
   GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED);
   GPR_ASSERT(0 == strcmp(details, "xyz"));
   GPR_ASSERT(0 == strcmp(call_details.method, "/foo"));
-  GPR_ASSERT(0 == strcmp(call_details.host, "foo.test.google.com"));
+  GPR_ASSERT(0 == strcmp(call_details.host, "foo.test.google.fr"));
   GPR_ASSERT(was_cancelled == 0);
   GPR_ASSERT(byte_buffer_eq_string(request_payload_recv, "hello world"));
   GPR_ASSERT(byte_buffer_eq_string(response_payload_recv, "hello you"));
diff --git a/test/core/end2end/tests/request_response_with_payload_legacy.c b/test/core/end2end/tests/request_response_with_payload_legacy.c
index be56274..bc9e0ae 100644
--- a/test/core/end2end/tests/request_response_with_payload_legacy.c
+++ b/test/core/end2end/tests/request_response_with_payload_legacy.c
@@ -61,7 +61,7 @@
 }
 
 static gpr_timespec n_seconds_time(int n) {
-  return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n));
+  return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n);
 }
 
 static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); }
@@ -121,7 +121,7 @@
 
   GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call_old(f.server, tag(100)));
 
-  c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.com",
+  c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.fr",
                                    deadline);
   GPR_ASSERT(c);
 
@@ -136,7 +136,7 @@
   cq_expect_write_accepted(v_client, tag(4), GRPC_OP_OK);
   cq_verify(v_client);
 
-  cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "foo.test.google.com",
+  cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "foo.test.google.fr",
                            deadline, NULL);
   cq_verify(v_server);
 
diff --git a/test/core/end2end/tests/request_response_with_trailing_metadata_and_payload.c b/test/core/end2end/tests/request_response_with_trailing_metadata_and_payload.c
index bf3b19b..b7834a1 100644
--- a/test/core/end2end/tests/request_response_with_trailing_metadata_and_payload.c
+++ b/test/core/end2end/tests/request_response_with_trailing_metadata_and_payload.c
@@ -61,7 +61,7 @@
 }
 
 static gpr_timespec n_seconds_time(int n) {
-  return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n));
+  return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n);
 }
 
 static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); }
@@ -134,7 +134,7 @@
   int was_cancelled = 2;
 
   c = grpc_channel_create_call(f.client, f.client_cq, "/foo",
-                               "foo.test.google.com", deadline);
+                               "foo.test.google.fr", deadline);
   GPR_ASSERT(c);
 
   grpc_metadata_array_init(&initial_metadata_recv);
@@ -169,8 +169,7 @@
   GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call(f.server, &s,
                                                       &call_details,
                                                       &request_metadata_recv,
-                                                      f.server_cq,
-                                                      tag(101)));
+                                                      f.server_cq, tag(101)));
   cq_expect_completion(v_server, tag(101), GRPC_OP_OK);
   cq_verify(v_server);
 
@@ -205,7 +204,7 @@
   GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED);
   GPR_ASSERT(0 == strcmp(details, "xyz"));
   GPR_ASSERT(0 == strcmp(call_details.method, "/foo"));
-  GPR_ASSERT(0 == strcmp(call_details.host, "foo.test.google.com"));
+  GPR_ASSERT(0 == strcmp(call_details.host, "foo.test.google.fr"));
   GPR_ASSERT(was_cancelled == 1);
   GPR_ASSERT(byte_buffer_eq_string(request_payload_recv, "hello world"));
   GPR_ASSERT(byte_buffer_eq_string(response_payload_recv, "hello you"));
diff --git a/test/core/end2end/tests/request_response_with_trailing_metadata_and_payload_legacy.c b/test/core/end2end/tests/request_response_with_trailing_metadata_and_payload_legacy.c
index 0ed0f98..6431ec5 100644
--- a/test/core/end2end/tests/request_response_with_trailing_metadata_and_payload_legacy.c
+++ b/test/core/end2end/tests/request_response_with_trailing_metadata_and_payload_legacy.c
@@ -61,7 +61,7 @@
 }
 
 static gpr_timespec n_seconds_time(int n) {
-  return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n));
+  return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n);
 }
 
 static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); }
@@ -130,7 +130,7 @@
   gpr_slice_unref(request_payload_slice);
   gpr_slice_unref(response_payload_slice);
 
-  c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.com",
+  c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.fr",
                                    deadline);
   GPR_ASSERT(c);
 
@@ -149,7 +149,7 @@
   cq_expect_write_accepted(v_client, tag(4), GRPC_OP_OK);
   cq_verify(v_client);
 
-  cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "foo.test.google.com",
+  cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "foo.test.google.fr",
                            deadline, "key1", "val1", "key2", "val2", NULL);
   cq_verify(v_server);
 
diff --git a/test/core/end2end/tests/request_with_large_metadata.c b/test/core/end2end/tests/request_with_large_metadata.c
index 7534104..c5b4e0c 100644
--- a/test/core/end2end/tests/request_with_large_metadata.c
+++ b/test/core/end2end/tests/request_with_large_metadata.c
@@ -61,7 +61,7 @@
 }
 
 static gpr_timespec n_seconds_time(int n) {
-  return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n));
+  return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n);
 }
 
 static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); }
@@ -128,13 +128,13 @@
   const int large_size = 64 * 1024;
 
   c = grpc_channel_create_call(f.client, f.client_cq, "/foo",
-                               "foo.test.google.com", deadline);
+                               "foo.test.google.fr", deadline);
   GPR_ASSERT(c);
 
   meta.key = "key";
   meta.value = gpr_malloc(large_size + 1);
   memset((char *)meta.value, 'a', large_size);
-  ((char*)meta.value)[large_size] = 0;
+  ((char *)meta.value)[large_size] = 0;
   meta.value_length = large_size;
 
   grpc_metadata_array_init(&initial_metadata_recv);
@@ -166,8 +166,7 @@
   GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call(f.server, &s,
                                                       &call_details,
                                                       &request_metadata_recv,
-                                                      f.server_cq,
-                                                      tag(101)));
+                                                      f.server_cq, tag(101)));
   cq_expect_completion(v_server, tag(101), GRPC_OP_OK);
   cq_verify(v_server);
 
@@ -197,7 +196,7 @@
   GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED);
   GPR_ASSERT(0 == strcmp(details, "xyz"));
   GPR_ASSERT(0 == strcmp(call_details.method, "/foo"));
-  GPR_ASSERT(0 == strcmp(call_details.host, "foo.test.google.com"));
+  GPR_ASSERT(0 == strcmp(call_details.host, "foo.test.google.fr"));
   GPR_ASSERT(was_cancelled == 0);
   GPR_ASSERT(byte_buffer_eq_string(request_payload_recv, "hello world"));
   GPR_ASSERT(contains_metadata(&request_metadata_recv, "key", meta.value));
diff --git a/test/core/end2end/tests/request_with_large_metadata_legacy.c b/test/core/end2end/tests/request_with_large_metadata_legacy.c
index bc3b380..082b5ad 100644
--- a/test/core/end2end/tests/request_with_large_metadata_legacy.c
+++ b/test/core/end2end/tests/request_with_large_metadata_legacy.c
@@ -61,7 +61,7 @@
 }
 
 static gpr_timespec n_seconds_time(int n) {
-  return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n));
+  return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n);
 }
 
 static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); }
@@ -118,10 +118,10 @@
   meta.key = "key";
   meta.value = gpr_malloc(large_size + 1);
   memset((char *)meta.value, 'a', large_size);
-  ((char*)meta.value)[large_size] = 0;
+  ((char *)meta.value)[large_size] = 0;
   meta.value_length = large_size;
 
-  c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.com",
+  c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.fr",
                                    deadline);
   GPR_ASSERT(c);
 
@@ -131,7 +131,7 @@
   GPR_ASSERT(GRPC_CALL_OK ==
              grpc_call_invoke_old(c, f.client_cq, tag(2), tag(3), 0));
 
-  cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "foo.test.google.com",
+  cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "foo.test.google.fr",
                            deadline, "key", meta.value, NULL);
   cq_verify(v_server);
 
diff --git a/test/core/end2end/tests/request_with_payload.c b/test/core/end2end/tests/request_with_payload.c
index bb13512..63b7c5e 100644
--- a/test/core/end2end/tests/request_with_payload.c
+++ b/test/core/end2end/tests/request_with_payload.c
@@ -61,7 +61,7 @@
 }
 
 static gpr_timespec n_seconds_time(int n) {
-  return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n));
+  return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n);
 }
 
 static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); }
@@ -126,7 +126,7 @@
   int was_cancelled = 2;
 
   c = grpc_channel_create_call(f.client, f.client_cq, "/foo",
-                               "foo.test.google.com", deadline);
+                               "foo.test.google.fr", deadline);
   GPR_ASSERT(c);
 
   grpc_metadata_array_init(&initial_metadata_recv);
@@ -157,8 +157,7 @@
   GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call(f.server, &s,
                                                       &call_details,
                                                       &request_metadata_recv,
-                                                      f.server_cq,
-                                                      tag(101)));
+                                                      f.server_cq, tag(101)));
   cq_expect_completion(v_server, tag(101), GRPC_OP_OK);
   cq_verify(v_server);
 
@@ -188,7 +187,7 @@
   GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED);
   GPR_ASSERT(0 == strcmp(details, "xyz"));
   GPR_ASSERT(0 == strcmp(call_details.method, "/foo"));
-  GPR_ASSERT(0 == strcmp(call_details.host, "foo.test.google.com"));
+  GPR_ASSERT(0 == strcmp(call_details.host, "foo.test.google.fr"));
   GPR_ASSERT(was_cancelled == 0);
   GPR_ASSERT(byte_buffer_eq_string(request_payload_recv, "hello world"));
 
diff --git a/test/core/end2end/tests/request_with_payload_legacy.c b/test/core/end2end/tests/request_with_payload_legacy.c
index b56e08c..266f9bd 100644
--- a/test/core/end2end/tests/request_with_payload_legacy.c
+++ b/test/core/end2end/tests/request_with_payload_legacy.c
@@ -61,7 +61,7 @@
 }
 
 static gpr_timespec n_seconds_time(int n) {
-  return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n));
+  return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n);
 }
 
 static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); }
@@ -116,7 +116,7 @@
   /* byte buffer holds the slice, we can unref it already */
   gpr_slice_unref(payload_slice);
 
-  c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.com",
+  c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.fr",
                                    deadline);
   GPR_ASSERT(c);
 
@@ -132,7 +132,7 @@
   cq_expect_write_accepted(v_client, tag(4), GRPC_OP_OK);
   cq_verify(v_client);
 
-  cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "foo.test.google.com",
+  cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "foo.test.google.fr",
                            deadline, NULL);
   cq_verify(v_server);
 
diff --git a/test/core/end2end/tests/simple_delayed_request.c b/test/core/end2end/tests/simple_delayed_request.c
index 0a3eb7c..0dbb35d 100644
--- a/test/core/end2end/tests/simple_delayed_request.c
+++ b/test/core/end2end/tests/simple_delayed_request.c
@@ -49,7 +49,7 @@
 static void *tag(gpr_intptr t) { return (void *)t; }
 
 static gpr_timespec n_seconds_time(int n) {
-  return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n));
+  return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n);
 }
 
 static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); }
@@ -114,7 +114,7 @@
   config.init_client(f, client_args);
 
   c = grpc_channel_create_call(f->client, f->client_cq, "/foo",
-                               "foo.test.google.com", deadline);
+                               "foo.test.google.fr", deadline);
   GPR_ASSERT(c);
 
   grpc_metadata_array_init(&initial_metadata_recv);
@@ -144,8 +144,7 @@
   GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call(f->server, &s,
                                                       &call_details,
                                                       &request_metadata_recv,
-                                                      f->server_cq,
-                                                      tag(101)));
+                                                      f->server_cq, tag(101)));
   cq_expect_completion(v_server, tag(101), GRPC_OP_OK);
   cq_verify(v_server);
 
@@ -172,7 +171,7 @@
   GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED);
   GPR_ASSERT(0 == strcmp(details, "xyz"));
   GPR_ASSERT(0 == strcmp(call_details.method, "/foo"));
-  GPR_ASSERT(0 == strcmp(call_details.host, "foo.test.google.com"));
+  GPR_ASSERT(0 == strcmp(call_details.host, "foo.test.google.fr"));
   GPR_ASSERT(was_cancelled == 0);
 
   gpr_free(details);
diff --git a/test/core/end2end/tests/simple_delayed_request_legacy.c b/test/core/end2end/tests/simple_delayed_request_legacy.c
index 3c94de5..7ab97ee 100644
--- a/test/core/end2end/tests/simple_delayed_request_legacy.c
+++ b/test/core/end2end/tests/simple_delayed_request_legacy.c
@@ -49,7 +49,7 @@
 static void *tag(gpr_intptr t) { return (void *)t; }
 
 static gpr_timespec n_seconds_time(int n) {
-  return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n));
+  return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n);
 }
 
 static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); }
@@ -103,7 +103,7 @@
 
   config.init_client(f, client_args);
 
-  c = grpc_channel_create_call_old(f->client, "/foo", "foo.test.google.com",
+  c = grpc_channel_create_call_old(f->client, "/foo", "foo.test.google.fr",
                                    deadline);
   GPR_ASSERT(c);
 
@@ -119,7 +119,7 @@
   cq_verify(v_client);
 
   GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call_old(f->server, tag(100)));
-  cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "foo.test.google.com",
+  cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "foo.test.google.fr",
                            deadline, NULL);
   cq_verify(v_server);
 
diff --git a/test/core/end2end/tests/simple_request.c b/test/core/end2end/tests/simple_request.c
index 591bc52..4d4d48a 100644
--- a/test/core/end2end/tests/simple_request.c
+++ b/test/core/end2end/tests/simple_request.c
@@ -63,7 +63,7 @@
 }
 
 static gpr_timespec n_seconds_time(int n) {
-  return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n));
+  return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n);
 }
 
 static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); }
@@ -122,7 +122,7 @@
   int was_cancelled = 2;
 
   c = grpc_channel_create_call(f.client, f.client_cq, "/foo",
-                               "foo.test.google.com", deadline);
+                               "foo.test.google.fr:1234", deadline);
   GPR_ASSERT(c);
 
   grpc_metadata_array_init(&initial_metadata_recv);
@@ -150,8 +150,7 @@
   GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call(f.server, &s,
                                                       &call_details,
                                                       &request_metadata_recv,
-                                                      f.server_cq,
-                                                      tag(101)));
+                                                      f.server_cq, tag(101)));
   cq_expect_completion(v_server, tag(101), GRPC_OP_OK);
   cq_verify(v_server);
 
@@ -178,7 +177,7 @@
   GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED);
   GPR_ASSERT(0 == strcmp(details, "xyz"));
   GPR_ASSERT(0 == strcmp(call_details.method, "/foo"));
-  GPR_ASSERT(0 == strcmp(call_details.host, "foo.test.google.com"));
+  GPR_ASSERT(0 == strcmp(call_details.host, "foo.test.google.fr:1234"));
   GPR_ASSERT(was_cancelled == 0);
 
   gpr_free(details);
diff --git a/test/core/end2end/tests/simple_request_legacy.c b/test/core/end2end/tests/simple_request_legacy.c
index 2e30d10..3e1b3f6 100644
--- a/test/core/end2end/tests/simple_request_legacy.c
+++ b/test/core/end2end/tests/simple_request_legacy.c
@@ -62,7 +62,7 @@
 }
 
 static gpr_timespec n_seconds_time(int n) {
-  return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n));
+  return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n);
 }
 
 static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); }
@@ -110,7 +110,7 @@
   cq_verifier *v_client = cq_verifier_create(f.client_cq);
   cq_verifier *v_server = cq_verifier_create(f.server_cq);
 
-  c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.com",
+  c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.fr",
                                    deadline);
   GPR_ASSERT(c);
 
@@ -122,7 +122,7 @@
   cq_verify(v_client);
 
   GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call_old(f.server, tag(100)));
-  cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "foo.test.google.com",
+  cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "foo.test.google.fr",
                            deadline, NULL);
   cq_verify(v_server);
 
@@ -157,7 +157,7 @@
   cq_verifier *v_client = cq_verifier_create(f.client_cq);
   cq_verifier *v_server = cq_verifier_create(f.server_cq);
 
-  c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.com",
+  c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.fr",
                                    deadline);
   GPR_ASSERT(c);
 
@@ -169,7 +169,7 @@
   cq_verify(v_client);
 
   GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call_old(f.server, tag(100)));
-  cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "foo.test.google.com",
+  cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "foo.test.google.fr",
                            deadline, NULL);
   cq_verify(v_server);
 
diff --git a/test/core/end2end/tests/thread_stress.c b/test/core/end2end/tests/thread_stress.c
index c10b373..a42956f 100644
--- a/test/core/end2end/tests/thread_stress.c
+++ b/test/core/end2end/tests/thread_stress.c
@@ -41,6 +41,7 @@
 #include <grpc/support/log.h>
 #include <grpc/support/time.h>
 #include <grpc/support/thd.h>
+#include "test/core/util/test_config.h"
 
 #define SERVER_THREADS 16
 #define CLIENT_THREADS 16
@@ -53,7 +54,7 @@
 static int g_active_requests;
 
 static gpr_timespec n_seconds_time(int n) {
-  return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n));
+  return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n);
 }
 
 static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); }
@@ -109,7 +110,7 @@
   gpr_slice slice = gpr_slice_malloc(100);
   grpc_byte_buffer *buf;
   grpc_call *call = grpc_channel_create_call_old(
-      g_fixture.client, "/Foo", "foo.test.google.com", g_test_end_time);
+      g_fixture.client, "/Foo", "foo.test.google.fr", g_test_end_time);
 
   memset(GPR_SLICE_START_PTR(slice), 1, GPR_SLICE_LENGTH(slice));
   buf = grpc_byte_buffer_create(&slice, 1);
@@ -280,11 +281,11 @@
   /* kick off threads */
   for (i = 0; i < CLIENT_THREADS; i++) {
     gpr_event_init(&g_client_done[i]);
-    gpr_thd_new(&thd_id, client_thread, (void *)(gpr_intptr)i, NULL);
+    gpr_thd_new(&thd_id, client_thread, (void *)(gpr_intptr) i, NULL);
   }
   for (i = 0; i < SERVER_THREADS; i++) {
     gpr_event_init(&g_server_done[i]);
-    gpr_thd_new(&thd_id, server_thread, (void *)(gpr_intptr)i, NULL);
+    gpr_thd_new(&thd_id, server_thread, (void *)(gpr_intptr) i, NULL);
   }
 
   /* start requests */
diff --git a/test/core/end2end/tests/thread_stress_legacy.c b/test/core/end2end/tests/thread_stress_legacy.c
index c10b373..a42956f 100644
--- a/test/core/end2end/tests/thread_stress_legacy.c
+++ b/test/core/end2end/tests/thread_stress_legacy.c
@@ -41,6 +41,7 @@
 #include <grpc/support/log.h>
 #include <grpc/support/time.h>
 #include <grpc/support/thd.h>
+#include "test/core/util/test_config.h"
 
 #define SERVER_THREADS 16
 #define CLIENT_THREADS 16
@@ -53,7 +54,7 @@
 static int g_active_requests;
 
 static gpr_timespec n_seconds_time(int n) {
-  return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n));
+  return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n);
 }
 
 static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); }
@@ -109,7 +110,7 @@
   gpr_slice slice = gpr_slice_malloc(100);
   grpc_byte_buffer *buf;
   grpc_call *call = grpc_channel_create_call_old(
-      g_fixture.client, "/Foo", "foo.test.google.com", g_test_end_time);
+      g_fixture.client, "/Foo", "foo.test.google.fr", g_test_end_time);
 
   memset(GPR_SLICE_START_PTR(slice), 1, GPR_SLICE_LENGTH(slice));
   buf = grpc_byte_buffer_create(&slice, 1);
@@ -280,11 +281,11 @@
   /* kick off threads */
   for (i = 0; i < CLIENT_THREADS; i++) {
     gpr_event_init(&g_client_done[i]);
-    gpr_thd_new(&thd_id, client_thread, (void *)(gpr_intptr)i, NULL);
+    gpr_thd_new(&thd_id, client_thread, (void *)(gpr_intptr) i, NULL);
   }
   for (i = 0; i < SERVER_THREADS; i++) {
     gpr_event_init(&g_server_done[i]);
-    gpr_thd_new(&thd_id, server_thread, (void *)(gpr_intptr)i, NULL);
+    gpr_thd_new(&thd_id, server_thread, (void *)(gpr_intptr) i, NULL);
   }
 
   /* start requests */
diff --git a/test/core/end2end/tests/writes_done_hangs_with_pending_read.c b/test/core/end2end/tests/writes_done_hangs_with_pending_read.c
index 5f8b997..75b4bfb 100644
--- a/test/core/end2end/tests/writes_done_hangs_with_pending_read.c
+++ b/test/core/end2end/tests/writes_done_hangs_with_pending_read.c
@@ -61,7 +61,7 @@
 }
 
 static gpr_timespec n_seconds_time(int n) {
-  return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n));
+  return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n);
 }
 
 static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); }
@@ -124,7 +124,7 @@
   gpr_slice_unref(request_payload_slice);
   gpr_slice_unref(response_payload_slice);
 
-  c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.com",
+  c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.fr",
                                    deadline);
   GPR_ASSERT(c);
 
@@ -140,8 +140,8 @@
   cq_verify(v_client);
 
   GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call_old(f.server, tag(100)));
-  cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo",
-                           "foo.test.google.com", deadline, NULL);
+  cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "foo.test.google.fr",
+                           deadline, NULL);
   cq_verify(v_server);
 
   GPR_ASSERT(GRPC_CALL_OK ==
diff --git a/test/core/end2end/tests/writes_done_hangs_with_pending_read_legacy.c b/test/core/end2end/tests/writes_done_hangs_with_pending_read_legacy.c
index 5f8b997..75b4bfb 100644
--- a/test/core/end2end/tests/writes_done_hangs_with_pending_read_legacy.c
+++ b/test/core/end2end/tests/writes_done_hangs_with_pending_read_legacy.c
@@ -61,7 +61,7 @@
 }
 
 static gpr_timespec n_seconds_time(int n) {
-  return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n));
+  return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n);
 }
 
 static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); }
@@ -124,7 +124,7 @@
   gpr_slice_unref(request_payload_slice);
   gpr_slice_unref(response_payload_slice);
 
-  c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.com",
+  c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.fr",
                                    deadline);
   GPR_ASSERT(c);
 
@@ -140,8 +140,8 @@
   cq_verify(v_client);
 
   GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call_old(f.server, tag(100)));
-  cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo",
-                           "foo.test.google.com", deadline, NULL);
+  cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "foo.test.google.fr",
+                           deadline, NULL);
   cq_verify(v_server);
 
   GPR_ASSERT(GRPC_CALL_OK ==
diff --git a/test/core/httpcli/httpcli_test.c b/test/core/httpcli/httpcli_test.c
index 599b3ad..17a2996 100644
--- a/test/core/httpcli/httpcli_test.c
+++ b/test/core/httpcli/httpcli_test.c
@@ -43,7 +43,7 @@
 static gpr_event g_done;
 
 static gpr_timespec n_seconds_time(int seconds) {
-  return gpr_time_add(gpr_now(), gpr_time_from_micros(seconds * 1000000));
+  return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(seconds);
 }
 
 static void on_finish(void *arg, const grpc_httpcli_response *response) {
diff --git a/test/core/iomgr/alarm_list_test.c b/test/core/iomgr/alarm_list_test.c
index f2ccd1f..684e3f5 100644
--- a/test/core/iomgr/alarm_list_test.c
+++ b/test/core/iomgr/alarm_list_test.c
@@ -61,13 +61,13 @@
   /* 10 ms alarms.  will expire in the current epoch */
   for (i = 0; i < 10; i++) {
     grpc_alarm_init(&alarms[i], gpr_time_add(start, gpr_time_from_millis(10)),
-                    cb, (void *)(gpr_intptr)i, start);
+                    cb, (void *)(gpr_intptr) i, start);
   }
 
   /* 1010 ms alarms.  will expire in the next epoch */
   for (i = 10; i < 20; i++) {
     grpc_alarm_init(&alarms[i], gpr_time_add(start, gpr_time_from_millis(1010)),
-                    cb, (void *)(gpr_intptr)i, start);
+                    cb, (void *)(gpr_intptr) i, start);
   }
 
   /* collect alarms.  Only the first batch should be ready. */
@@ -115,15 +115,15 @@
   memset(cb_called, 0, sizeof(cb_called));
 
   grpc_alarm_init(&alarms[0], gpr_time_from_millis(100), cb,
-                  (void *)(gpr_intptr)0, gpr_time_0);
+                  (void *)(gpr_intptr) 0, gpr_time_0);
   grpc_alarm_init(&alarms[1], gpr_time_from_millis(3), cb,
-                  (void *)(gpr_intptr)1, gpr_time_0);
+                  (void *)(gpr_intptr) 1, gpr_time_0);
   grpc_alarm_init(&alarms[2], gpr_time_from_millis(100), cb,
-                  (void *)(gpr_intptr)2, gpr_time_0);
+                  (void *)(gpr_intptr) 2, gpr_time_0);
   grpc_alarm_init(&alarms[3], gpr_time_from_millis(3), cb,
-                  (void *)(gpr_intptr)3, gpr_time_0);
+                  (void *)(gpr_intptr) 3, gpr_time_0);
   grpc_alarm_init(&alarms[4], gpr_time_from_millis(1), cb,
-                  (void *)(gpr_intptr)4, gpr_time_0);
+                  (void *)(gpr_intptr) 4, gpr_time_0);
   GPR_ASSERT(1 == grpc_alarm_check(NULL, gpr_time_from_millis(2), NULL));
   GPR_ASSERT(1 == cb_called[4][1]);
   grpc_alarm_cancel(&alarms[0]);
diff --git a/test/core/iomgr/alarm_test.c b/test/core/iomgr/alarm_test.c
index 18f5772..8d49332 100644
--- a/test/core/iomgr/alarm_test.c
+++ b/test/core/iomgr/alarm_test.c
@@ -113,10 +113,10 @@
   gpr_cv_init(&arg.cv);
   gpr_event_init(&arg.fcb_arg);
 
-  grpc_alarm_init(&alarm, gpr_time_add(gpr_time_from_millis(100), gpr_now()),
-                  alarm_cb, &arg, gpr_now());
+  grpc_alarm_init(&alarm, GRPC_TIMEOUT_MILLIS_TO_DEADLINE(100), alarm_cb, &arg,
+                  gpr_now());
 
-  alarm_deadline = gpr_time_add(gpr_now(), gpr_time_from_seconds(1));
+  alarm_deadline = GRPC_TIMEOUT_SECONDS_TO_DEADLINE(1);
   gpr_mu_lock(&arg.mu);
   while (arg.done == 0) {
     if (gpr_cv_wait(&arg.cv, &arg.mu, alarm_deadline)) {
@@ -126,7 +126,7 @@
   }
   gpr_mu_unlock(&arg.mu);
 
-  followup_deadline = gpr_time_add(gpr_now(), gpr_time_from_seconds(5));
+  followup_deadline = GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5);
   fdone = gpr_event_wait(&arg.fcb_arg, followup_deadline);
 
   if (arg.counter != 1) {
@@ -162,12 +162,11 @@
   gpr_cv_init(&arg2.cv);
   gpr_event_init(&arg2.fcb_arg);
 
-  grpc_alarm_init(&alarm_to_cancel,
-                  gpr_time_add(gpr_time_from_millis(100), gpr_now()), alarm_cb,
-                  &arg2, gpr_now());
+  grpc_alarm_init(&alarm_to_cancel, GRPC_TIMEOUT_MILLIS_TO_DEADLINE(100),
+                  alarm_cb, &arg2, gpr_now());
   grpc_alarm_cancel(&alarm_to_cancel);
 
-  alarm_deadline = gpr_time_add(gpr_now(), gpr_time_from_seconds(1));
+  alarm_deadline = GRPC_TIMEOUT_SECONDS_TO_DEADLINE(1);
   gpr_mu_lock(&arg2.mu);
   while (arg2.done == 0) {
     gpr_cv_wait(&arg2.cv, &arg2.mu, alarm_deadline);
@@ -176,7 +175,7 @@
 
   gpr_log(GPR_INFO, "alarm done = %d", arg2.done);
 
-  followup_deadline = gpr_time_add(gpr_now(), gpr_time_from_seconds(5));
+  followup_deadline = GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5);
   fdone = gpr_event_wait(&arg2.fcb_arg, followup_deadline);
 
   if (arg2.counter != arg2.done_success_ctr) {
diff --git a/test/core/iomgr/endpoint_tests.c b/test/core/iomgr/endpoint_tests.c
index c08ee7d..e63048e 100644
--- a/test/core/iomgr/endpoint_tests.c
+++ b/test/core/iomgr/endpoint_tests.c
@@ -39,6 +39,7 @@
 #include <grpc/support/slice.h>
 #include <grpc/support/log.h>
 #include <grpc/support/time.h>
+#include "test/core/util/test_config.h"
 
 /*
    General test notes:
@@ -211,7 +212,7 @@
                                 size_t num_bytes, size_t write_size,
                                 size_t slice_size, int shutdown) {
   struct read_and_write_test_state state;
-  gpr_timespec deadline = gpr_time_add(gpr_now(), gpr_time_from_seconds(20));
+  gpr_timespec deadline = GRPC_TIMEOUT_SECONDS_TO_DEADLINE(20);
   grpc_endpoint_test_fixture f = begin_test(config, __FUNCTION__, slice_size);
 
   if (shutdown) {
@@ -290,7 +291,7 @@
 
   if (error != GRPC_ENDPOINT_CB_OK) {
     grpc_endpoint_destroy(st->ep);
-    gpr_event_set(&st->ev, (void *)(gpr_intptr)error);
+    gpr_event_set(&st->ev, (void *)(gpr_intptr) error);
   } else {
     grpc_endpoint_notify_on_read(
         st->ep, shutdown_during_write_test_read_handler, user_data);
@@ -309,7 +310,7 @@
     gpr_log(GPR_ERROR,
             "shutdown_during_write_test_write_handler completed unexpectedly");
   }
-  gpr_event_set(&st->ev, (void *)(gpr_intptr)1);
+  gpr_event_set(&st->ev, (void *)(gpr_intptr) 1);
 }
 
 static void shutdown_during_write_test(grpc_endpoint_test_config config,
@@ -345,8 +346,7 @@
         abort();
       case GRPC_ENDPOINT_WRITE_PENDING:
         grpc_endpoint_shutdown(write_st.ep);
-        deadline =
-            gpr_time_add(gpr_now(), gpr_time_from_micros(10 * GPR_US_PER_SEC));
+        deadline = GRPC_TIMEOUT_SECONDS_TO_DEADLINE(10);
         GPR_ASSERT(gpr_event_wait(&write_st.ev, deadline));
         grpc_endpoint_destroy(write_st.ep);
         GPR_ASSERT(gpr_event_wait(&read_st.ev, deadline));
diff --git a/test/core/iomgr/endpoint_tests.h b/test/core/iomgr/endpoint_tests.h
index 3be377c..1679d7b 100644
--- a/test/core/iomgr/endpoint_tests.h
+++ b/test/core/iomgr/endpoint_tests.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_TEST_IOMGR_ENDPOINT_TESTS_H__
-#define __GRPC_TEST_IOMGR_ENDPOINT_TESTS_H__
+#ifndef GRPC_TEST_CORE_IOMGR_ENDPOINT_TESTS_H
+#define GRPC_TEST_CORE_IOMGR_ENDPOINT_TESTS_H
 
 #include <sys/types.h>
 
@@ -54,4 +54,4 @@
 
 void grpc_endpoint_tests(grpc_endpoint_test_config config);
 
-#endif /* __GRPC_TEST_IOMGR_ENDPOINT_TESTS_H__ */
+#endif  /* GRPC_TEST_CORE_IOMGR_ENDPOINT_TESTS_H */
diff --git a/test/core/iomgr/resolve_address_test.c b/test/core/iomgr/resolve_address_test.c
index 0961a36..668c539 100644
--- a/test/core/iomgr/resolve_address_test.c
+++ b/test/core/iomgr/resolve_address_test.c
@@ -39,7 +39,7 @@
 #include "test/core/util/test_config.h"
 
 static gpr_timespec test_deadline(void) {
-  return gpr_time_add(gpr_now(), gpr_time_from_micros(100000000));
+  return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(100);
 }
 
 static void must_succeed(void* evp, grpc_resolved_addresses* p) {
@@ -83,8 +83,9 @@
 }
 
 static void test_ipv6_without_port(void) {
-  const char* const kCases[] = {"2001:db8::1", "2001:db8::1.2.3.4",
-                                "[2001:db8::1]", };
+  const char* const kCases[] = {
+      "2001:db8::1", "2001:db8::1.2.3.4", "[2001:db8::1]",
+  };
   unsigned i;
   for (i = 0; i < sizeof(kCases) / sizeof(*kCases); i++) {
     gpr_event ev;
@@ -95,7 +96,9 @@
 }
 
 static void test_invalid_ip_addresses(void) {
-  const char* const kCases[] = {"293.283.1238.3:1", "[2001:db8::11111]:1", };
+  const char* const kCases[] = {
+      "293.283.1238.3:1", "[2001:db8::11111]:1",
+  };
   unsigned i;
   for (i = 0; i < sizeof(kCases) / sizeof(*kCases); i++) {
     gpr_event ev;
@@ -106,8 +109,9 @@
 }
 
 static void test_unparseable_hostports(void) {
-  const char* const kCases[] = {"[",         "[::1",        "[::1]bad",
-                                "[1.2.3.4]", "[localhost]", "[localhost]:1", };
+  const char* const kCases[] = {
+      "[", "[::1", "[::1]bad", "[1.2.3.4]", "[localhost]", "[localhost]:1",
+  };
   unsigned i;
   for (i = 0; i < sizeof(kCases) / sizeof(*kCases); i++) {
     gpr_event ev;
diff --git a/test/core/iomgr/tcp_client_posix_test.c b/test/core/iomgr/tcp_client_posix_test.c
index ad5a317..3c4d8fe 100644
--- a/test/core/iomgr/tcp_client_posix_test.c
+++ b/test/core/iomgr/tcp_client_posix_test.c
@@ -43,9 +43,10 @@
 #include "src/core/iomgr/socket_utils_posix.h"
 #include <grpc/support/log.h>
 #include <grpc/support/time.h>
+#include "test/core/util/test_config.h"
 
 static gpr_timespec test_deadline(void) {
-  return gpr_time_add(gpr_now(), gpr_time_from_seconds(10));
+  return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(10);
 }
 
 static void must_succeed(void *arg, grpc_endpoint *tcp) {
@@ -150,13 +151,12 @@
 
   /* connect to dummy server address */
 
-  connect_deadline = gpr_time_add(gpr_now(), gpr_time_from_micros(1000000));
+  connect_deadline = GRPC_TIMEOUT_SECONDS_TO_DEADLINE(1);
 
   grpc_tcp_client_connect(must_fail, &ev, (struct sockaddr *)&addr, addr_len,
                           connect_deadline);
   /* Make sure the event doesn't trigger early */
-  GPR_ASSERT(!gpr_event_wait(
-                 &ev, gpr_time_add(gpr_now(), gpr_time_from_micros(500000))));
+  GPR_ASSERT(!gpr_event_wait(&ev, GRPC_TIMEOUT_MILLIS_TO_DEADLINE(500)));
   /* Now wait until it should have triggered */
   sleep(1);
 
@@ -168,7 +168,8 @@
   }
 }
 
-int main(void) {
+int main(int argc, char **argv) {
+  grpc_test_init(argc, argv);
   grpc_iomgr_init();
   test_succeeds();
   gpr_log(GPR_ERROR, "End of first test");
diff --git a/test/core/iomgr/tcp_posix_test.c b/test/core/iomgr/tcp_posix_test.c
index 0f81ba7..59e525a 100644
--- a/test/core/iomgr/tcp_posix_test.c
+++ b/test/core/iomgr/tcp_posix_test.c
@@ -163,8 +163,7 @@
   grpc_endpoint *ep;
   struct read_socket_state state;
   ssize_t written_bytes;
-  gpr_timespec rel_deadline = {20, 0};
-  gpr_timespec deadline = gpr_time_add(gpr_now(), rel_deadline);
+  gpr_timespec deadline = GRPC_TIMEOUT_SECONDS_TO_DEADLINE(20);
 
   gpr_log(GPR_INFO, "Read test of size %d, slice size %d", num_bytes,
           slice_size);
@@ -206,8 +205,7 @@
   grpc_endpoint *ep;
   struct read_socket_state state;
   ssize_t written_bytes;
-  gpr_timespec rel_deadline = {20, 0};
-  gpr_timespec deadline = gpr_time_add(gpr_now(), rel_deadline);
+  gpr_timespec deadline = GRPC_TIMEOUT_SECONDS_TO_DEADLINE(20);
 
   gpr_log(GPR_INFO, "Start large read test, slice size %d", slice_size);
 
@@ -343,8 +341,7 @@
   size_t num_blocks;
   gpr_slice *slices;
   int current_data = 0;
-  gpr_timespec rel_deadline = {20, 0};
-  gpr_timespec deadline = gpr_time_add(gpr_now(), rel_deadline);
+  gpr_timespec deadline = GRPC_TIMEOUT_SECONDS_TO_DEADLINE(20);
 
   gpr_log(GPR_INFO, "Start write test with %d bytes, slice size %d", num_bytes,
           slice_size);
@@ -400,8 +397,7 @@
   size_t num_blocks;
   gpr_slice *slices;
   int current_data = 0;
-  gpr_timespec rel_deadline = {20, 0};
-  gpr_timespec deadline = gpr_time_add(gpr_now(), rel_deadline);
+  gpr_timespec deadline = GRPC_TIMEOUT_SECONDS_TO_DEADLINE(20);
 
   gpr_log(GPR_INFO, "Start write error test with %d bytes, slice size %d",
           num_bytes, slice_size);
@@ -482,7 +478,8 @@
 }
 
 static grpc_endpoint_test_config configs[] = {
-    {"tcp/tcp_socketpair", create_fixture_tcp_socketpair, clean_up}, };
+    {"tcp/tcp_socketpair", create_fixture_tcp_socketpair, clean_up},
+};
 
 int main(int argc, char **argv) {
   grpc_test_init(argc, argv);
diff --git a/test/core/iomgr/tcp_server_posix_test.c b/test/core/iomgr/tcp_server_posix_test.c
index b26115b..2689c3f 100644
--- a/test/core/iomgr/tcp_server_posix_test.c
+++ b/test/core/iomgr/tcp_server_posix_test.c
@@ -123,7 +123,7 @@
   grpc_tcp_server_start(s, NULL, 0, on_connect, NULL);
 
   for (i = 0; i < n; i++) {
-    deadline = gpr_time_add(gpr_now(), gpr_time_from_micros(10000000));
+    deadline = GRPC_TIMEOUT_SECONDS_TO_DEADLINE(1);
 
     nconnects_before = nconnects;
     clifd = socket(addr.ss_family, SOCK_STREAM, 0);
diff --git a/test/core/json/json_rewrite.c b/test/core/json/json_rewrite.c
index 203e75c..02f60a3 100644
--- a/test/core/json/json_rewrite.c
+++ b/test/core/json/json_rewrite.c
@@ -40,9 +40,7 @@
 #include "src/core/json/json_reader.h"
 #include "src/core/json/json_writer.h"
 
-typedef struct json_writer_userdata {
-  FILE* out;
-} json_writer_userdata;
+typedef struct json_writer_userdata { FILE* out; } json_writer_userdata;
 
 typedef struct stacked_container {
   grpc_json_type type;
@@ -76,11 +74,9 @@
   fwrite(str, len, 1, state->out);
 }
 
-grpc_json_writer_vtable writer_vtable = {
-  json_writer_output_char,
-  json_writer_output_string,
-  json_writer_output_string_with_len
-};
+grpc_json_writer_vtable writer_vtable = {json_writer_output_char,
+                                         json_writer_output_string,
+                                         json_writer_output_string_with_len};
 
 static void check_string(json_reader_userdata* state, size_t needed) {
   if (state->free_space >= needed) return;
@@ -202,19 +198,12 @@
 }
 
 static grpc_json_reader_vtable reader_vtable = {
-  json_reader_string_clear,
-  json_reader_string_add_char,
-  json_reader_string_add_utf32,
-  json_reader_read_char,
-  json_reader_container_begins,
-  json_reader_container_ends,
-  json_reader_set_key,
-  json_reader_set_string,
-  json_reader_set_number,
-  json_reader_set_true,
-  json_reader_set_false,
-  json_reader_set_null
-};
+    json_reader_string_clear,     json_reader_string_add_char,
+    json_reader_string_add_utf32, json_reader_read_char,
+    json_reader_container_begins, json_reader_container_ends,
+    json_reader_set_key,          json_reader_set_string,
+    json_reader_set_number,       json_reader_set_true,
+    json_reader_set_false,        json_reader_set_null};
 
 int rewrite(FILE* in, FILE* out, int indent) {
   grpc_json_writer writer;
diff --git a/test/core/json/json_rewrite_test.c b/test/core/json/json_rewrite_test.c
index 78dff92..ec6deeb 100644
--- a/test/core/json/json_rewrite_test.c
+++ b/test/core/json/json_rewrite_test.c
@@ -42,9 +42,7 @@
 #include "src/core/json/json_reader.h"
 #include "src/core/json/json_writer.h"
 
-typedef struct json_writer_userdata {
-  FILE* cmp;
-} json_writer_userdata;
+typedef struct json_writer_userdata { FILE* cmp; } json_writer_userdata;
 
 typedef struct stacked_container {
   grpc_json_type type;
@@ -83,11 +81,9 @@
   }
 }
 
-grpc_json_writer_vtable writer_vtable = {
-  json_writer_output_char,
-  json_writer_output_string,
-  json_writer_output_string_with_len
-};
+grpc_json_writer_vtable writer_vtable = {json_writer_output_char,
+                                         json_writer_output_string,
+                                         json_writer_output_string_with_len};
 
 static void check_string(json_reader_userdata* state, size_t needed) {
   if (state->free_space >= needed) return;
@@ -216,19 +212,12 @@
 }
 
 static grpc_json_reader_vtable reader_vtable = {
-  json_reader_string_clear,
-  json_reader_string_add_char,
-  json_reader_string_add_utf32,
-  json_reader_read_char,
-  json_reader_container_begins,
-  json_reader_container_ends,
-  json_reader_set_key,
-  json_reader_set_string,
-  json_reader_set_number,
-  json_reader_set_true,
-  json_reader_set_false,
-  json_reader_set_null
-};
+    json_reader_string_clear,     json_reader_string_add_char,
+    json_reader_string_add_utf32, json_reader_read_char,
+    json_reader_container_begins, json_reader_container_ends,
+    json_reader_set_key,          json_reader_set_string,
+    json_reader_set_number,       json_reader_set_true,
+    json_reader_set_false,        json_reader_set_null};
 
 int rewrite_and_compare(FILE* in, FILE* cmp, int indent) {
   grpc_json_writer writer;
@@ -275,26 +264,14 @@
 } test_file;
 
 static test_file test_files[] = {
-  {
-    "test/core/json/rewrite_test_input.json",
-    "test/core/json/rewrite_test_output_condensed.json",
-    0
-  },
-  {
-    "test/core/json/rewrite_test_input.json",
-    "test/core/json/rewrite_test_output_indented.json",
-    2
-  },
-  {
-    "test/core/json/rewrite_test_output_indented.json",
-    "test/core/json/rewrite_test_output_condensed.json",
-    0
-  },
-  {
-    "test/core/json/rewrite_test_output_condensed.json",
-    "test/core/json/rewrite_test_output_indented.json",
-    2
-  },
+    {"test/core/json/rewrite_test_input.json",
+     "test/core/json/rewrite_test_output_condensed.json", 0},
+    {"test/core/json/rewrite_test_input.json",
+     "test/core/json/rewrite_test_output_indented.json", 2},
+    {"test/core/json/rewrite_test_output_indented.json",
+     "test/core/json/rewrite_test_output_condensed.json", 0},
+    {"test/core/json/rewrite_test_output_condensed.json",
+     "test/core/json/rewrite_test_output_indented.json", 2},
 };
 
 void test_rewrites() {
@@ -305,8 +282,8 @@
     FILE* input = fopen(test->input, "rb");
     FILE* cmp = fopen(test->cmp, "rb");
     int status;
-    gpr_log(GPR_INFO, "Testing file %s against %s using indent=%i",
-            test->input, test->cmp, test->indent);
+    gpr_log(GPR_INFO, "Testing file %s against %s using indent=%i", test->input,
+            test->cmp, test->indent);
     status = rewrite_and_compare(input, cmp, test->indent);
     GPR_ASSERT(status);
     fclose(input);
diff --git a/test/core/json/json_test.c b/test/core/json/json_test.c
index bc3c7a3..9a50a69 100644
--- a/test/core/json/json_test.c
+++ b/test/core/json/json_test.c
@@ -47,80 +47,83 @@
 } testing_pair;
 
 static testing_pair testing_pairs[] = {
-  /* Testing valid parsing. */
+    /* Testing valid parsing. */
 
-  /* Testing trivial parses, with de-indentation. */
-  { " 0 ", "0" },
-  { " 1 ", "1" },
-  { " \"a\" ", "\"a\"" },
-  { " true ", "true" },
-  /* Testing the parser's ability to decode trivial UTF-16. */
-  { "\"\\u0020\\\\\\u0010\\u000a\\u000D\"", "\" \\\\\\u0010\\n\\r\"" },
-  /* Testing various UTF-8 sequences. */
-  { "\"ßâñć௵⇒\"", "\"\\u00df\\u00e2\\u00f1\\u0107\\u0bf5\\u21d2\"" },
-  { "\"\\u00df\\u00e2\\u00f1\\u0107\\u0bf5\\u21d2\"", "\"\\u00df\\u00e2\\u00f1\\u0107\\u0bf5\\u21d2\"" },
-  /* Testing UTF-8 character "𝄞", U+11D1E. */
-  { "\"\xf0\x9d\x84\x9e\"", "\"\\ud834\\udd1e\"" },
-  { "\"\\ud834\\udd1e\"", "\"\\ud834\\udd1e\"" },
-  /* Testing nested empty containers. */
-  { " [ [ ] , { } , [ ] ] ", "[[],{},[]]", },
-  /* Testing escapes and control chars in key strings. */
-  { " { \"\x7f\\n\\\\a , b\": 1, \"\": 0 } ", "{\"\\u007f\\n\\\\a , b\":1,\"\":0}" },
-  /* Testing the writer's ability to cut off invalid UTF-8 sequences. */
-  { "\"abc\xf0\x9d\x24\"", "\"abc\"" },
-  { "\"\xff\"", "\"\"" },
-  /* Testing valid number parsing. */
-  { "[0, 42 , 0.0123, 123.456]", "[0,42,0.0123,123.456]"},
-  { "[1e4,-53.235e-31, 0.3e+3]", "[1e4,-53.235e-31,0.3e+3]" },
-  /* Testing keywords parsing. */
-  { "[true, false, null]", "[true,false,null]" },
+    /* Testing trivial parses, with de-indentation. */
+    {" 0 ", "0"},
+    {" 1 ", "1"},
+    {" \"a\" ", "\"a\""},
+    {" true ", "true"},
+    /* Testing the parser's ability to decode trivial UTF-16. */
+    {"\"\\u0020\\\\\\u0010\\u000a\\u000D\"", "\" \\\\\\u0010\\n\\r\""},
+    /* Testing various UTF-8 sequences. */
+    {"\"ßâñć௵⇒\"", "\"\\u00df\\u00e2\\u00f1\\u0107\\u0bf5\\u21d2\""},
+    {"\"\\u00df\\u00e2\\u00f1\\u0107\\u0bf5\\u21d2\"",
+     "\"\\u00df\\u00e2\\u00f1\\u0107\\u0bf5\\u21d2\""},
+    /* Testing UTF-8 character "𝄞", U+11D1E. */
+    {"\"\xf0\x9d\x84\x9e\"", "\"\\ud834\\udd1e\""},
+    {"\"\\ud834\\udd1e\"", "\"\\ud834\\udd1e\""},
+    /* Testing nested empty containers. */
+    {
+     " [ [ ] , { } , [ ] ] ", "[[],{},[]]",
+    },
+    /* Testing escapes and control chars in key strings. */
+    {" { \"\x7f\\n\\\\a , b\": 1, \"\": 0 } ",
+     "{\"\\u007f\\n\\\\a , b\":1,\"\":0}"},
+    /* Testing the writer's ability to cut off invalid UTF-8 sequences. */
+    {"\"abc\xf0\x9d\x24\"", "\"abc\""},
+    {"\"\xff\"", "\"\""},
+    /* Testing valid number parsing. */
+    {"[0, 42 , 0.0123, 123.456]", "[0,42,0.0123,123.456]"},
+    {"[1e4,-53.235e-31, 0.3e+3]", "[1e4,-53.235e-31,0.3e+3]"},
+    /* Testing keywords parsing. */
+    {"[true, false, null]", "[true,false,null]"},
 
+    /* Testing invalid parsing. */
 
-  /* Testing invalid parsing. */
-
-  /* Testing plain invalid things, exercising the state machine. */
-  { "\\", NULL },
-  { "nu ll", NULL },
-  { "fals", NULL },
-  /* Testing unterminated string. */
-  { "\"\\x", NULL },
-  /* Testing invalid UTF-16 number. */
-  { "\"\\u123x", NULL },
-  /* Testing imbalanced surrogate pairs. */
-  { "\"\\ud834f", NULL },
-  { "\"\\ud834\\n", NULL },
-  { "\"\\udd1ef", NULL },
-  { "\"\\ud834\\ud834\"", NULL },
-  { "\"\\ud834\\u1234\"", NULL },
-  /* Testing embedded invalid whitechars. */
-  { "\"\n\"", NULL },
-  { "\"\t\"", NULL },
-  /* Testing empty json data. */
-  { "", NULL },
-  /* Testing extra characters after end of parsing. */
-  { "{},", NULL },
-  /* Testing imbalanced containers. */
-  { "{}}", NULL },
-  { "[]]", NULL },
-  { "{{}", NULL },
-  { "[[]", NULL },
-  { "[}", NULL },
-  { "{]", NULL },
-  /*Testing trailing comma. */
-  { "{,}", NULL },
-  { "[1,2,3,4,]", NULL },
-  /* Testing having a key syntax in an array. */
-  { "[\"x\":0]", NULL },
-  /* Testing invalid numbers. */
-  { "1.", NULL },
-  { "1e", NULL },
-  { ".12", NULL },
-  { "1.x", NULL },
-  { "1.12x", NULL },
-  { "1ex", NULL },
-  { "1e12x", NULL },
-  { ".12x", NULL },
-  { "000", NULL },
+    /* Testing plain invalid things, exercising the state machine. */
+    {"\\", NULL},
+    {"nu ll", NULL},
+    {"fals", NULL},
+    /* Testing unterminated string. */
+    {"\"\\x", NULL},
+    /* Testing invalid UTF-16 number. */
+    {"\"\\u123x", NULL},
+    /* Testing imbalanced surrogate pairs. */
+    {"\"\\ud834f", NULL},
+    {"\"\\ud834\\n", NULL},
+    {"\"\\udd1ef", NULL},
+    {"\"\\ud834\\ud834\"", NULL},
+    {"\"\\ud834\\u1234\"", NULL},
+    /* Testing embedded invalid whitechars. */
+    {"\"\n\"", NULL},
+    {"\"\t\"", NULL},
+    /* Testing empty json data. */
+    {"", NULL},
+    /* Testing extra characters after end of parsing. */
+    {"{},", NULL},
+    /* Testing imbalanced containers. */
+    {"{}}", NULL},
+    {"[]]", NULL},
+    {"{{}", NULL},
+    {"[[]", NULL},
+    {"[}", NULL},
+    {"{]", NULL},
+    /*Testing trailing comma. */
+    {"{,}", NULL},
+    {"[1,2,3,4,]", NULL},
+    /* Testing having a key syntax in an array. */
+    {"[\"x\":0]", NULL},
+    /* Testing invalid numbers. */
+    {"1.", NULL},
+    {"1e", NULL},
+    {".12", NULL},
+    {"1.x", NULL},
+    {"1.12x", NULL},
+    {"1ex", NULL},
+    {"1e12x", NULL},
+    {".12x", NULL},
+    {"000", NULL},
 };
 
 static void test_pairs() {
@@ -169,7 +172,7 @@
   gpr_free(scratchpad);
 }
 
-int main(int argc, char **argv) {
+int main(int argc, char** argv) {
   grpc_test_init(argc, argv);
   test_pairs();
   test_atypical();
diff --git a/test/core/security/credentials_test.c b/test/core/security/credentials_test.c
index 91229c9..50ef2d7 100644
--- a/test/core/security/credentials_test.c
+++ b/test/core/security/credentials_test.c
@@ -55,7 +55,8 @@
    Maximum size for a string literal is 509 chars in C89, yay!  */
 static const char test_json_key_str_part1[] =
     "{ \"private_key\": \"-----BEGIN PRIVATE KEY-----"
-    "\\nMIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBAOEvJsnoHnyHkXcp\\n7mJEqg"
+    "\\nMIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBAOEvJsnoHnyHkXcp\\n7mJE"
+    "qg"
     "WGjiw71NfXByguekSKho65FxaGbsnSM9SMQAqVk7Q2rG+I0OpsT0LrWQtZ\\nyjSeg/"
     "rWBQvS4hle4LfijkP3J5BG+"
     "IXDMP8RfziNRQsenAXDNPkY4kJCvKux2xdD\\nOnVF6N7dL3nTYZg+"
@@ -66,11 +67,14 @@
 static const char test_json_key_str_part2[] =
     "53XxNVnxBHsYb+AYEfklR96yVi8HywjVHP34+OQZ\\nCslxoHQM8s+"
     "dBnjfScLu22JqkPv04xyxmt0QAKm9+vTdAkEA4ib7YvEAn2jXzcCI\\nEkoy2L/"
-    "XydR1GCHoacdfdAwiL2npOdnbvi4ZmdYRPY1LSTO058tQHKVXV7NLeCa3\\nAARh2QJBAMKeDAG"
-    "W303SQv2cZTdbeaLKJbB5drz3eo3j7dDKjrTD9JupixFbzcGw\\n8FZi5c8idxiwC36kbAL6HzA"
+    "XydR1GCHoacdfdAwiL2npOdnbvi4ZmdYRPY1LSTO058tQHKVXV7NLeCa3\\nAARh2QJBAMKeDA"
+    "G"
+    "W303SQv2cZTdbeaLKJbB5drz3eo3j7dDKjrTD9JupixFbzcGw\\n8FZi5c8idxiwC36kbAL6Hz"
+    "A"
     "ZoX+ofI0CQE6KCzPJTtYNqyShgKAZdJ8hwOcvCZtf\\n6z8RJm0+"
     "6YBd38lfh5j8mZd7aHFf6I17j5AQY7oPEc47TjJj/"
-    "5nZ68ECQQDvYuI3\\nLyK5fS8g0SYbmPOL9TlcHDOqwG0mrX9qpg5DC2fniXNSrrZ64GTDKdzZY"
+    "5nZ68ECQQDvYuI3\\nLyK5fS8g0SYbmPOL9TlcHDOqwG0mrX9qpg5DC2fniXNSrrZ64GTDKdzZ"
+    "Y"
     "Ap6LI9W\\nIqv4vr6y38N79TTC\\n-----END PRIVATE KEY-----\\n\", ";
 static const char test_json_key_str_part3[] =
     "\"private_key_id\": \"e6b5137873db8d2ef81e06a47289e6434ec8a165\", "
@@ -614,9 +618,10 @@
   grpc_jwt_encode_and_sign_set_override(NULL);
 }
 
-static void on_jwt_creds_get_metadata_success(
-    void *user_data, grpc_mdelem **md_elems, size_t num_md,
-    grpc_credentials_status status) {
+static void on_jwt_creds_get_metadata_success(void *user_data,
+                                              grpc_mdelem **md_elems,
+                                              size_t num_md,
+                                              grpc_credentials_status status) {
   char *expected_md_value;
   gpr_asprintf(&expected_md_value, "Bearer %s", test_signed_jwt);
   GPR_ASSERT(status == GRPC_CREDENTIALS_OK);
@@ -630,9 +635,10 @@
   gpr_free(expected_md_value);
 }
 
-static void on_jwt_creds_get_metadata_failure(
-    void *user_data, grpc_mdelem **md_elems, size_t num_md,
-    grpc_credentials_status status) {
+static void on_jwt_creds_get_metadata_failure(void *user_data,
+                                              grpc_mdelem **md_elems,
+                                              size_t num_md,
+                                              grpc_credentials_status status) {
   GPR_ASSERT(status == GRPC_CREDENTIALS_ERROR);
   GPR_ASSERT(num_md == 0);
   GPR_ASSERT(user_data != NULL);
diff --git a/test/core/security/json_token_test.c b/test/core/security/json_token_test.c
index eed0fdf..fae9117 100644
--- a/test/core/security/json_token_test.c
+++ b/test/core/security/json_token_test.c
@@ -49,7 +49,8 @@
    Maximum size for a string literal is 509 chars in C89, yay!  */
 static const char test_json_key_str_part1[] =
     "{ \"private_key\": \"-----BEGIN PRIVATE KEY-----"
-    "\\nMIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBAOEvJsnoHnyHkXcp\\n7mJEqg"
+    "\\nMIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBAOEvJsnoHnyHkXcp\\n7mJE"
+    "qg"
     "WGjiw71NfXByguekSKho65FxaGbsnSM9SMQAqVk7Q2rG+I0OpsT0LrWQtZ\\nyjSeg/"
     "rWBQvS4hle4LfijkP3J5BG+"
     "IXDMP8RfziNRQsenAXDNPkY4kJCvKux2xdD\\nOnVF6N7dL3nTYZg+"
@@ -60,11 +61,14 @@
 static const char test_json_key_str_part2[] =
     "53XxNVnxBHsYb+AYEfklR96yVi8HywjVHP34+OQZ\\nCslxoHQM8s+"
     "dBnjfScLu22JqkPv04xyxmt0QAKm9+vTdAkEA4ib7YvEAn2jXzcCI\\nEkoy2L/"
-    "XydR1GCHoacdfdAwiL2npOdnbvi4ZmdYRPY1LSTO058tQHKVXV7NLeCa3\\nAARh2QJBAMKeDAG"
-    "W303SQv2cZTdbeaLKJbB5drz3eo3j7dDKjrTD9JupixFbzcGw\\n8FZi5c8idxiwC36kbAL6HzA"
+    "XydR1GCHoacdfdAwiL2npOdnbvi4ZmdYRPY1LSTO058tQHKVXV7NLeCa3\\nAARh2QJBAMKeDA"
+    "G"
+    "W303SQv2cZTdbeaLKJbB5drz3eo3j7dDKjrTD9JupixFbzcGw\\n8FZi5c8idxiwC36kbAL6Hz"
+    "A"
     "ZoX+ofI0CQE6KCzPJTtYNqyShgKAZdJ8hwOcvCZtf\\n6z8RJm0+"
     "6YBd38lfh5j8mZd7aHFf6I17j5AQY7oPEc47TjJj/"
-    "5nZ68ECQQDvYuI3\\nLyK5fS8g0SYbmPOL9TlcHDOqwG0mrX9qpg5DC2fniXNSrrZ64GTDKdzZY"
+    "5nZ68ECQQDvYuI3\\nLyK5fS8g0SYbmPOL9TlcHDOqwG0mrX9qpg5DC2fniXNSrrZ64GTDKdzZ"
+    "Y"
     "Ap6LI9W\\nIqv4vr6y38N79TTC\\n-----END PRIVATE KEY-----\\n\", ";
 static const char test_json_key_str_part3[] =
     "\"private_key_id\": \"e6b5137873db8d2ef81e06a47289e6434ec8a165\", "
diff --git a/test/core/security/print_google_default_creds_token.c b/test/core/security/print_google_default_creds_token.c
index cfd62cf..76e69ef 100644
--- a/test/core/security/print_google_default_creds_token.c
+++ b/test/core/security/print_google_default_creds_token.c
@@ -73,8 +73,7 @@
   char *service_url = "https://test.foo.google.com/Foo";
   gpr_cmdline *cl = gpr_cmdline_create("print_google_default_creds_token");
   gpr_cmdline_add_string(cl, "service_url",
-                         "Service URL for the token request.",
-                         &service_url);
+                         "Service URL for the token request.", &service_url);
   gpr_cmdline_parse(cl, argc, argv);
 
   grpc_init();
diff --git a/test/core/security/secure_endpoint_test.c b/test/core/security/secure_endpoint_test.c
index 03a4d3a..f7bd3cb 100644
--- a/test/core/security/secure_endpoint_test.c
+++ b/test/core/security/secure_endpoint_test.c
@@ -130,7 +130,8 @@
     {"secure_ep/tcp_socketpair",
      secure_endpoint_create_fixture_tcp_socketpair_noleftover, clean_up},
     {"secure_ep/tcp_socketpair_leftover",
-     secure_endpoint_create_fixture_tcp_socketpair_leftover, clean_up}, };
+     secure_endpoint_create_fixture_tcp_socketpair_leftover, clean_up},
+};
 
 static void verify_leftover(void *user_data, gpr_slice *slices, size_t nslices,
                             grpc_endpoint_cb_status error) {
diff --git a/test/core/statistics/census_log_tests.c b/test/core/statistics/census_log_tests.c
index fbc96bb..241ec1c 100644
--- a/test/core/statistics/census_log_tests.c
+++ b/test/core/statistics/census_log_tests.c
@@ -42,6 +42,7 @@
 #include <grpc/support/thd.h>
 #include <grpc/support/time.h>
 #include <grpc/support/useful.h>
+#include "test/core/util/test_config.h"
 
 /* Fills in 'record' of size 'size'. Each byte in record is filled in with the
    same value. The value is extracted from 'record' pointer. */
@@ -123,8 +124,8 @@
 /* Given log size and record size, computes the minimum usable space. */
 static gpr_int32 min_usable_space(size_t log_size, size_t record_size) {
   gpr_int32 usable_space;
-  gpr_int32 num_blocks = GPR_MAX(log_size / CENSUS_LOG_MAX_RECORD_SIZE,
-                                 gpr_cpu_num_cores());
+  gpr_int32 num_blocks =
+      GPR_MAX(log_size / CENSUS_LOG_MAX_RECORD_SIZE, gpr_cpu_num_cores());
   gpr_int32 waste_per_block = CENSUS_LOG_MAX_RECORD_SIZE % record_size;
   /* In the worst case, all except one core-local block is full. */
   gpr_int32 num_full_blocks = num_blocks - 1;
@@ -198,7 +199,7 @@
          This should never happen for circular logs. */
       printf("   Writer stalled due to out-of-space: %d out of %d written\n",
              records_written, args->num_records);
-      gpr_sleep_until(gpr_time_add(gpr_now(), gpr_time_from_micros(10000)));
+      gpr_sleep_until(GRPC_TIMEOUT_MILLIS_TO_DEADLINE(10));
     }
   }
   /* Done. Decrement count and signal. */
diff --git a/test/core/statistics/census_log_tests.h b/test/core/statistics/census_log_tests.h
index f829ab3..28bde08 100644
--- a/test/core/statistics/census_log_tests.h
+++ b/test/core/statistics/census_log_tests.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_TEST_STATISTICS_LOG_TESTS_H__
-#define __GRPC_TEST_STATISTICS_LOG_TESTS_H__
+#ifndef GRPC_TEST_CORE_STATISTICS_CENSUS_LOG_TESTS_H
+#define GRPC_TEST_CORE_STATISTICS_CENSUS_LOG_TESTS_H
 
 void test_invalid_record_size();
 void test_end_write_with_different_size();
@@ -48,4 +48,4 @@
 void test_performance();
 void test_small_log();
 
-#endif /* __GRPC_TEST_STATISTICS_LOG_TESTS_H__ */
+#endif  /* GRPC_TEST_CORE_STATISTICS_CENSUS_LOG_TESTS_H */
diff --git a/test/core/statistics/hash_table_test.c b/test/core/statistics/hash_table_test.c
index 2752d6d..1e9e1c8 100644
--- a/test/core/statistics/hash_table_test.c
+++ b/test/core/statistics/hash_table_test.c
@@ -97,7 +97,7 @@
   for (i = 0; i < 20; ++i) {
     census_ht_key key;
     key.val = i;
-    census_ht_insert(ht, key, (void*)(gpr_intptr)i);
+    census_ht_insert(ht, key, (void*)(gpr_intptr) i);
     GPR_ASSERT(census_ht_get_size(ht) == i + 1);
   }
   for (i = 0; i < 20; i++) {
@@ -105,7 +105,7 @@
     census_ht_key key;
     key.val = i;
     val = census_ht_find(ht, key);
-    GPR_ASSERT(val == (void*)(gpr_intptr)i);
+    GPR_ASSERT(val == (void*)(gpr_intptr) i);
   }
   elements = census_ht_get_all_elements(ht, &num_elements);
   GPR_ASSERT(elements != NULL);
diff --git a/test/core/statistics/trace_test.c b/test/core/statistics/trace_test.c
index 65b70e1..b13fd03 100644
--- a/test/core/statistics/trace_test.c
+++ b/test/core/statistics/trace_test.c
@@ -111,7 +111,7 @@
     id = census_tracing_start_op();
     census_add_method_tag(id, method_name);
     /* pretend doing 1us work. */
-    gpr_sleep_until(gpr_time_add(gpr_now(), gpr_time_from_micros(1)));
+    gpr_sleep_until(GRPC_TIMEOUT_MICROS_TO_DEADLINE(1));
     census_tracing_end_op(id);
   }
   gpr_log(GPR_INFO, "End trace op sequence thread.");
diff --git a/test/core/support/file_test.c b/test/core/support/file_test.c
index c0c14ff..dd8caf7 100644
--- a/test/core/support/file_test.c
+++ b/test/core/support/file_test.c
@@ -148,7 +148,6 @@
   gpr_slice_unref(slice);
 }
 
-
 int main(int argc, char **argv) {
   grpc_test_init(argc, argv);
   test_load_empty_file();
diff --git a/test/core/support/sync_test.c b/test/core/support/sync_test.c
index 43d05c6..44bc6ba 100644
--- a/test/core/support/sync_test.c
+++ b/test/core/support/sync_test.c
@@ -56,9 +56,9 @@
                  (That is, except during initialization or
                  destruction, the fields below should be accessed
                  only by a thread that holds mu.) */
-  int head;    /* Index of head of queue 0..N-1. */
-  int length;  /* Number of valid elements in queue 0..N. */
-  int elem[N]; /* elem[head .. head+length-1] are queue elements. */
+  int head;         /* Index of head of queue 0..N-1. */
+  int length;       /* Number of valid elements in queue 0..N. */
+  int elem[N];      /* elem[head .. head+length-1] are queue elements. */
 } queue;
 
 /* Initialize *q. */
diff --git a/test/core/surface/completion_queue_benchmark.c b/test/core/surface/completion_queue_benchmark.c
index 9116fd0..81ebe15 100644
--- a/test/core/surface/completion_queue_benchmark.c
+++ b/test/core/surface/completion_queue_benchmark.c
@@ -53,23 +53,23 @@
   test_thread_options *opt = arg;
   int i;
 
-  gpr_event_set(&opt->on_started, (void *)(gpr_intptr)1);
+  gpr_event_set(&opt->on_started, (void *)(gpr_intptr) 1);
   GPR_ASSERT(gpr_event_wait(opt->start, gpr_inf_future));
 
   for (i = 0; i < opt->iterations; i++) {
     grpc_cq_begin_op(opt->cc, NULL, GRPC_WRITE_ACCEPTED);
-    grpc_cq_end_write_accepted(opt->cc, (void *)(gpr_intptr)1, NULL, NULL, NULL,
-                               GRPC_OP_OK);
+    grpc_cq_end_write_accepted(opt->cc, (void *)(gpr_intptr) 1, NULL, NULL,
+                               NULL, GRPC_OP_OK);
   }
 
-  gpr_event_set(&opt->on_finished, (void *)(gpr_intptr)1);
+  gpr_event_set(&opt->on_finished, (void *)(gpr_intptr) 1);
 }
 
 static void consumer_thread(void *arg) {
   test_thread_options *opt = arg;
   grpc_event *ev;
 
-  gpr_event_set(&opt->on_started, (void *)(gpr_intptr)1);
+  gpr_event_set(&opt->on_started, (void *)(gpr_intptr) 1);
   GPR_ASSERT(gpr_event_wait(opt->start, gpr_inf_future));
 
   for (;;) {
@@ -78,7 +78,7 @@
       case GRPC_WRITE_ACCEPTED:
         break;
       case GRPC_QUEUE_SHUTDOWN:
-        gpr_event_set(&opt->on_finished, (void *)(gpr_intptr)1);
+        gpr_event_set(&opt->on_finished, (void *)(gpr_intptr) 1);
         return;
       default:
         gpr_log(GPR_ERROR, "Invalid event received: %d", ev->type);
@@ -112,7 +112,7 @@
 
   /* start the benchmark */
   t_start = gpr_now();
-  gpr_event_set(&start, (void *)(gpr_intptr)1);
+  gpr_event_set(&start, (void *)(gpr_intptr) 1);
 
   /* wait for producers to finish */
   for (i = 0; i < producers; i++) {
diff --git a/test/core/surface/completion_queue_test.c b/test/core/surface/completion_queue_test.c
index 35f150c..414ca2e 100644
--- a/test/core/surface/completion_queue_test.c
+++ b/test/core/surface/completion_queue_test.c
@@ -248,7 +248,7 @@
 } test_thread_options;
 
 gpr_timespec ten_seconds_time(void) {
-  return gpr_time_add(gpr_now(), gpr_time_from_micros(10 * 1000000));
+  return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(1);
 }
 
 static void producer_thread(void *arg) {
@@ -256,7 +256,7 @@
   int i;
 
   gpr_log(GPR_INFO, "producer %d started", opt->id);
-  gpr_event_set(&opt->on_started, (void *)(gpr_intptr)1);
+  gpr_event_set(&opt->on_started, (void *)(gpr_intptr) 1);
   GPR_ASSERT(gpr_event_wait(opt->phase1, ten_seconds_time()));
 
   gpr_log(GPR_INFO, "producer %d phase 1", opt->id);
@@ -265,18 +265,18 @@
   }
 
   gpr_log(GPR_INFO, "producer %d phase 1 done", opt->id);
-  gpr_event_set(&opt->on_phase1_done, (void *)(gpr_intptr)1);
+  gpr_event_set(&opt->on_phase1_done, (void *)(gpr_intptr) 1);
   GPR_ASSERT(gpr_event_wait(opt->phase2, ten_seconds_time()));
 
   gpr_log(GPR_INFO, "producer %d phase 2", opt->id);
   for (i = 0; i < TEST_THREAD_EVENTS; i++) {
-    grpc_cq_end_write_accepted(opt->cc, (void *)(gpr_intptr)1, NULL, NULL, NULL,
-                               GRPC_OP_OK);
+    grpc_cq_end_write_accepted(opt->cc, (void *)(gpr_intptr) 1, NULL, NULL,
+                               NULL, GRPC_OP_OK);
     opt->events_triggered++;
   }
 
   gpr_log(GPR_INFO, "producer %d phase 2 done", opt->id);
-  gpr_event_set(&opt->on_finished, (void *)(gpr_intptr)1);
+  gpr_event_set(&opt->on_finished, (void *)(gpr_intptr) 1);
 }
 
 static void consumer_thread(void *arg) {
@@ -284,13 +284,13 @@
   grpc_event *ev;
 
   gpr_log(GPR_INFO, "consumer %d started", opt->id);
-  gpr_event_set(&opt->on_started, (void *)(gpr_intptr)1);
+  gpr_event_set(&opt->on_started, (void *)(gpr_intptr) 1);
   GPR_ASSERT(gpr_event_wait(opt->phase1, ten_seconds_time()));
 
   gpr_log(GPR_INFO, "consumer %d phase 1", opt->id);
 
   gpr_log(GPR_INFO, "consumer %d phase 1 done", opt->id);
-  gpr_event_set(&opt->on_phase1_done, (void *)(gpr_intptr)1);
+  gpr_event_set(&opt->on_phase1_done, (void *)(gpr_intptr) 1);
   GPR_ASSERT(gpr_event_wait(opt->phase2, ten_seconds_time()));
 
   gpr_log(GPR_INFO, "consumer %d phase 2", opt->id);
@@ -305,7 +305,7 @@
         break;
       case GRPC_QUEUE_SHUTDOWN:
         gpr_log(GPR_INFO, "consumer %d phase 2 done", opt->id);
-        gpr_event_set(&opt->on_finished, (void *)(gpr_intptr)1);
+        gpr_event_set(&opt->on_finished, (void *)(gpr_intptr) 1);
         grpc_event_finish(ev);
         return;
       default:
@@ -350,7 +350,7 @@
   /* start phase1: producers will pre-declare all operations they will
      complete */
   gpr_log(GPR_INFO, "start phase 1");
-  gpr_event_set(&phase1, (void *)(gpr_intptr)1);
+  gpr_event_set(&phase1, (void *)(gpr_intptr) 1);
 
   gpr_log(GPR_INFO, "wait phase 1");
   for (i = 0; i < producers + consumers; i++) {
@@ -360,7 +360,7 @@
 
   /* start phase2: operations will complete, and consumers will consume them */
   gpr_log(GPR_INFO, "start phase 2");
-  gpr_event_set(&phase2, (void *)(gpr_intptr)1);
+  gpr_event_set(&phase2, (void *)(gpr_intptr) 1);
 
   /* in parallel, we shutdown the completion channel - all events should still
      be consumed */
diff --git a/test/core/surface/lame_client_test.c b/test/core/surface/lame_client_test.c
index 0142768..3653c5a 100644
--- a/test/core/surface/lame_client_test.c
+++ b/test/core/surface/lame_client_test.c
@@ -51,9 +51,8 @@
 
   chan = grpc_lame_client_channel_create();
   GPR_ASSERT(chan);
-  call = grpc_channel_create_call_old(
-      chan, "/Foo", "anywhere",
-      gpr_time_add(gpr_now(), gpr_time_from_seconds(100)));
+  call = grpc_channel_create_call_old(chan, "/Foo", "anywhere",
+                                      GRPC_TIMEOUT_SECONDS_TO_DEADLINE(100));
   GPR_ASSERT(call);
   cq = grpc_completion_queue_create();
   cqv = cq_verifier_create(cq);
diff --git a/test/core/transport/chttp2/hpack_parser_test.c b/test/core/transport/chttp2/hpack_parser_test.c
index 86c6bb1..1d6ad2a 100644
--- a/test/core/transport/chttp2/hpack_parser_test.c
+++ b/test/core/transport/chttp2/hpack_parser_test.c
@@ -42,9 +42,7 @@
 #include "test/core/util/slice_splitter.h"
 #include "test/core/util/test_config.h"
 
-typedef struct {
-  va_list args;
-} test_checker;
+typedef struct { va_list args; } test_checker;
 
 static void onhdr(void *ud, grpc_mdelem *md) {
   const char *ekey, *evalue;
diff --git a/test/core/transport/chttp2/stream_map_test.c b/test/core/transport/chttp2/stream_map_test.c
index 49d5811..d678e0a 100644
--- a/test/core/transport/chttp2/stream_map_test.c
+++ b/test/core/transport/chttp2/stream_map_test.c
@@ -93,7 +93,7 @@
   grpc_chttp2_stream_map_init(&map, 8);
   GPR_ASSERT(0 == grpc_chttp2_stream_map_size(&map));
   for (i = 1; i <= n; i++) {
-    grpc_chttp2_stream_map_add(&map, i, (void *)(gpr_uintptr)i);
+    grpc_chttp2_stream_map_add(&map, i, (void *)(gpr_uintptr) i);
   }
   GPR_ASSERT(n == grpc_chttp2_stream_map_size(&map));
   GPR_ASSERT(NULL == grpc_chttp2_stream_map_find(&map, 0));
@@ -148,7 +148,7 @@
 
   grpc_chttp2_stream_map_init(&map, 8);
   for (i = 1; i <= n; i++) {
-    grpc_chttp2_stream_map_add(&map, i, (void *)(gpr_uintptr)i);
+    grpc_chttp2_stream_map_add(&map, i, (void *)(gpr_uintptr) i);
   }
   for (i = 1; i <= n; i++) {
     if ((i & 1) == 0) {
@@ -170,7 +170,7 @@
 
   grpc_chttp2_stream_map_init(&map, 8);
   for (i = 1; i <= n; i++) {
-    grpc_chttp2_stream_map_add(&map, i, (void *)(gpr_uintptr)i);
+    grpc_chttp2_stream_map_add(&map, i, (void *)(gpr_uintptr) i);
     if ((i & 1) == 0) {
       grpc_chttp2_stream_map_delete(&map, i);
     }
@@ -213,7 +213,7 @@
   test_empty_find();
   test_double_deletion();
 
-  while (n < 10000000) {
+  while (n < 100000) {
     test_basic_add_find(n);
     test_delete_evens_sweep(n);
     test_delete_evens_incremental(n);
diff --git a/test/core/transport/chttp2_transport_end2end_test.c b/test/core/transport/chttp2_transport_end2end_test.c
index a3c9f97..b90fe22 100644
--- a/test/core/transport/chttp2_transport_end2end_test.c
+++ b/test/core/transport/chttp2_transport_end2end_test.c
@@ -100,7 +100,8 @@
     {"chttp2_on_socketpair/medium",
      create_http2_transport_for_test_medium_slices},
     {"chttp2_on_socketpair/large",
-     create_http2_transport_for_test_large_slices}, };
+     create_http2_transport_for_test_large_slices},
+};
 
 /* Driver function: run the test suite for each test configuration */
 int main(int argc, char **argv) {
diff --git a/test/core/transport/transport_end2end_tests.c b/test/core/transport/transport_end2end_tests.c
index 6d13bf1..437a1c3 100644
--- a/test/core/transport/transport_end2end_tests.c
+++ b/test/core/transport/transport_end2end_tests.c
@@ -43,8 +43,7 @@
 #include <grpc/support/log.h>
 #include <grpc/support/thd.h>
 #include <grpc/support/useful.h>
-
-enum { REQUEST_DEADLINE = 200000 }; /* valgrind need a large value */
+#include "test/core/util/test_config.h"
 
 static grpc_mdctx *g_metadata_context;
 
@@ -63,9 +62,7 @@
 typedef struct test_fixture test_fixture;
 
 /* User data passed to the transport and handed to each callback */
-typedef struct test_user_data {
-  test_fixture *fixture;
-} test_user_data;
+typedef struct test_user_data { test_fixture *fixture; } test_user_data;
 
 /* A message we expect to receive (forms a singly linked list with next) */
 typedef struct expected_message {
@@ -131,8 +128,7 @@
 /* Convert some number of seconds into a gpr_timespec that many seconds in the
    future */
 static gpr_timespec deadline_from_seconds(double deadline_seconds) {
-  return gpr_time_add(gpr_now(),
-                      gpr_time_from_micros((long)(deadline_seconds * 1e6)));
+  return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(deadline_seconds);
 }
 
 /* Init a test_user_data instance */
@@ -576,7 +572,7 @@
      name   - the name of this test */
 static void begin_test(test_fixture *f, grpc_transport_test_config *config,
                        const char *name) {
-  gpr_timespec timeout = gpr_time_add(gpr_now(), gpr_time_from_seconds(100));
+  gpr_timespec timeout = GRPC_TIMEOUT_SECONDS_TO_DEADLINE(100);
 
   gpr_log(GPR_INFO, "BEGIN: %s/%s", name, config->name);
 
@@ -591,9 +587,10 @@
   f->client_transport = NULL;
   f->server_transport = NULL;
 
-  GPR_ASSERT(0 == config->create_transport(setup_client_transport, f,
-                                           setup_server_transport, f,
-                                           g_metadata_context));
+  GPR_ASSERT(0 ==
+             config->create_transport(setup_client_transport, f,
+                                      setup_server_transport, f,
+                                      g_metadata_context));
 
   gpr_mu_lock(&f->mu);
   while (!f->client_transport || !f->server_transport) {
@@ -909,8 +906,9 @@
  * Test driver
  */
 
-static const size_t interesting_message_lengths[] = {1,      100,     10000,
-                                                     100000, 1000000, };
+static const size_t interesting_message_lengths[] = {
+    1, 100, 10000, 100000, 1000000,
+};
 
 void grpc_transport_end2end_tests(grpc_transport_test_config *config) {
   unsigned i;
diff --git a/test/core/transport/transport_end2end_tests.h b/test/core/transport/transport_end2end_tests.h
index 3dc2b9b..1edffe9 100644
--- a/test/core/transport/transport_end2end_tests.h
+++ b/test/core/transport/transport_end2end_tests.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_TEST_TRANSPORT_TRANSPORT_END2END_TESTS_H__
-#define __GRPC_TEST_TRANSPORT_TRANSPORT_END2END_TESTS_H__
+#ifndef GRPC_TEST_CORE_TRANSPORT_TRANSPORT_END2END_TESTS_H
+#define GRPC_TEST_CORE_TRANSPORT_TRANSPORT_END2END_TESTS_H
 
 #include "src/core/transport/transport.h"
 
@@ -65,4 +65,4 @@
 /* Run the test suite on one configuration */
 void grpc_transport_end2end_tests(grpc_transport_test_config *config);
 
-#endif /* __GRPC_TEST_TRANSPORT_TRANSPORT_END2END_TESTS_H__ */
+#endif  /* GRPC_TEST_CORE_TRANSPORT_TRANSPORT_END2END_TESTS_H */
diff --git a/test/core/tsi/transport_security_test.c b/test/core/tsi/transport_security_test.c
new file mode 100644
index 0000000..c5882af
--- /dev/null
+++ b/test/core/tsi/transport_security_test.c
@@ -0,0 +1,303 @@
+/*
+ *
+ * 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 "src/core/tsi/transport_security.h"
+
+#include <string.h>
+
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/useful.h>
+
+#include "src/core/support/string.h"
+#include "src/core/tsi/ssl_transport_security.h"
+#include "test/core/util/test_config.h"
+
+typedef struct {
+  /* 1 if success, 0 if failure. */
+  int expected;
+
+  /* Host name to match. */
+  const char *host_name;
+
+  /* Common name (CN). */
+  const char *common_name;
+
+  /* Comma separated list of certificate names to match against. Any occurrence
+     of '#' will be replaced with a null character before processing. */
+  const char *dns_names;
+
+} cert_name_test_entry;
+
+/* Largely inspired from:
+   chromium/src/net/cert/x509_certificate_unittest.cc.
+   TODO(jboeuf) uncomment test cases as we fix tsi_ssl_peer_matches_name. */
+const cert_name_test_entry cert_name_test_entries[] = {
+    {1, "foo.com", "foo.com", NULL},
+    {1, "f", "f", NULL},
+    {0, "h", "i", NULL},
+    {1, "bar.foo.com", "*.foo.com", NULL},
+    {1, "www.test.fr", "common.name",
+     "*.test.com,*.test.co.uk,*.test.de,*.test.fr"},
+    /*
+    {1, "wwW.tESt.fr", "common.name", ",*.*,*.test.de,*.test.FR,www"},
+    */
+    {0, "f.uk", ".uk", NULL},
+    {0, "w.bar.foo.com", "?.bar.foo.com", NULL},
+    {0, "www.foo.com", "(www|ftp).foo.com", NULL},
+    {0, "www.foo.com", "www.foo.com#", NULL}, /* # = null char. */
+    {0, "www.foo.com", "", "www.foo.com#*.foo.com,#,#"},
+    {0, "www.house.example", "ww.house.example", NULL},
+    {0, "test.org", "", "www.test.org,*.test.org,*.org"},
+    {0, "w.bar.foo.com", "w*.bar.foo.com", NULL},
+    {0, "www.bar.foo.com", "ww*ww.bar.foo.com", NULL},
+    {0, "wwww.bar.foo.com", "ww*ww.bar.foo.com", NULL},
+    {0, "wwww.bar.foo.com", "w*w.bar.foo.com", NULL},
+    {0, "wwww.bar.foo.com", "w*w.bar.foo.c0m", NULL},
+    {0, "WALLY.bar.foo.com", "wa*.bar.foo.com", NULL},
+    {0, "wally.bar.foo.com", "*Ly.bar.foo.com", NULL},
+    /*
+    {1, "ww%57.foo.com", "", "www.foo.com"},
+    {1, "www&.foo.com", "www%26.foo.com", NULL},
+    */
+
+    /* Common name must not be used if subject alternative name was provided. */
+    {0, "www.test.co.jp", "www.test.co.jp",
+     "*.test.de,*.jp,www.test.co.uk,www.*.co.jp"},
+    {0, "www.bar.foo.com", "www.bar.foo.com",
+     "*.foo.com,*.*.foo.com,*.*.bar.foo.com,*..bar.foo.com,"},
+
+    /* IDN tests */
+    {1, "xn--poema-9qae5a.com.br", "xn--poema-9qae5a.com.br", NULL},
+    {1, "www.xn--poema-9qae5a.com.br", "*.xn--poema-9qae5a.com.br", NULL},
+    {0, "xn--poema-9qae5a.com.br", "",
+     "*.xn--poema-9qae5a.com.br,"
+     "xn--poema-*.com.br,"
+     "xn--*-9qae5a.com.br,"
+     "*--poema-9qae5a.com.br"},
+
+    /* The following are adapted from the  examples quoted from
+       http://tools.ietf.org/html/rfc6125#section-6.4.3
+        (e.g., *.example.com would match foo.example.com but
+         not bar.foo.example.com or example.com). */
+    {1, "foo.example.com", "*.example.com", NULL},
+    {0, "bar.foo.example.com", "*.example.com", NULL},
+    {0, "example.com", "*.example.com", NULL},
+
+    /* Partial wildcards are disallowed, though RFC 2818 rules allow them.
+       That is, forms such as baz*.example.net, *baz.example.net, and
+       b*z.example.net should NOT match domains. Instead, the wildcard must
+       always be the left-most label, and only a single label. */
+    {0, "baz1.example.net", "baz*.example.net", NULL},
+    {0, "foobaz.example.net", "*baz.example.net", NULL},
+    {0, "buzz.example.net", "b*z.example.net", NULL},
+    {0, "www.test.example.net", "www.*.example.net", NULL},
+
+    /* Wildcards should not be valid for public registry controlled domains,
+       and unknown/unrecognized domains, at least three domain components must
+       be present. */
+    {1, "www.test.example", "*.test.example", NULL},
+    {1, "test.example.co.uk", "*.example.co.uk", NULL},
+    {0, "test.example", "*.example", NULL},
+    /*
+    {0, "example.co.uk", "*.co.uk", NULL},
+    */
+    {0, "foo.com", "*.com", NULL},
+    {0, "foo.us", "*.us", NULL},
+    {0, "foo", "*", NULL},
+
+    /* IDN variants of wildcards and registry controlled domains. */
+    {1, "www.xn--poema-9qae5a.com.br", "*.xn--poema-9qae5a.com.br", NULL},
+    {1, "test.example.xn--mgbaam7a8h", "*.example.xn--mgbaam7a8h", NULL},
+    /*
+    {0, "xn--poema-9qae5a.com.br", "*.com.br", NULL},
+    */
+    {0, "example.xn--mgbaam7a8h", "*.xn--mgbaam7a8h", NULL},
+
+    /* Wildcards should be permissible for 'private' registry controlled
+       domains. */
+    {1, "www.appspot.com", "*.appspot.com", NULL},
+    {1, "foo.s3.amazonaws.com", "*.s3.amazonaws.com", NULL},
+
+    /* Multiple wildcards are not valid. */
+    {0, "foo.example.com", "*.*.com", NULL},
+    {0, "foo.bar.example.com", "*.bar.*.com", NULL},
+
+    /* Absolute vs relative DNS name tests. Although not explicitly specified
+       in RFC 6125, absolute reference names (those ending in a .) should
+       match either absolute or relative presented names. */
+    {1, "foo.com", "foo.com.", NULL},
+    {1, "foo.com.", "foo.com", NULL},
+    {1, "foo.com.", "foo.com.", NULL},
+    {1, "f", "f.", NULL},
+    {1, "f.", "f", NULL},
+    {1, "f.", "f.", NULL},
+    {1, "www-3.bar.foo.com", "*.bar.foo.com.", NULL},
+    {1, "www-3.bar.foo.com.", "*.bar.foo.com", NULL},
+    {1, "www-3.bar.foo.com.", "*.bar.foo.com.", NULL},
+    {0, ".", ".", NULL},
+    {0, "example.com", "*.com.", NULL},
+    {0, "example.com.", "*.com", NULL},
+    {0, "example.com.", "*.com.", NULL},
+    {0, "foo.", "*.", NULL},
+    {0, "foo", "*.", NULL},
+    /*
+    {0, "foo.co.uk", "*.co.uk.", NULL},
+    {0, "foo.co.uk.", "*.co.uk.", NULL},
+    */
+
+    /* An empty CN is OK. */
+    {1, "test.foo.com", "", "test.foo.com"},
+
+    /* An IP should not be used for the CN. */
+    {0, "173.194.195.139", "173.194.195.139", NULL},
+};
+
+typedef struct name_list {
+  const char *name;
+  struct name_list *next;
+} name_list;
+
+typedef struct {
+  size_t name_count;
+  char *buffer;
+  name_list *names;
+} parsed_dns_names;
+
+name_list *name_list_add(const char *n) {
+  name_list *result = gpr_malloc(sizeof(name_list));
+  result->name = n;
+  result->next = NULL;
+  return result;
+}
+
+static parsed_dns_names parse_dns_names(const char *dns_names_str) {
+  parsed_dns_names result;
+  name_list *current_nl;
+  size_t i;
+  memset(&result, 0, sizeof(parsed_dns_names));
+  if (dns_names_str == 0) return result;
+  result.name_count = 1;
+  result.buffer = gpr_strdup(dns_names_str);
+  result.names = name_list_add(result.buffer);
+  current_nl = result.names;
+  for (i = 0; i < strlen(dns_names_str); i++) {
+    if (dns_names_str[i] == ',') {
+      result.buffer[i] = '\0';
+      result.name_count++;
+      i++;
+      current_nl->next = name_list_add(result.buffer + i);
+      current_nl = current_nl->next;
+    }
+  }
+  return result;
+}
+
+static void destruct_parsed_dns_names(parsed_dns_names *pdn) {
+  name_list *nl = pdn->names;
+  if (pdn->buffer != NULL) gpr_free(pdn->buffer);
+  while (nl != NULL) {
+    name_list *to_be_free = nl;
+    nl = nl->next;
+    gpr_free(to_be_free);
+  }
+}
+
+static char *processed_dns_name(const char *dns_name) {
+  char *result = gpr_strdup(dns_name);
+  size_t i;
+  for (i = 0; i < strlen(result); i++) {
+    if (result[i] == '#') {
+      result[i] = '\0';
+    }
+  }
+  return result;
+}
+
+static tsi_peer peer_from_cert_name_test_entry(
+    const cert_name_test_entry *entry) {
+  size_t i;
+  tsi_peer peer;
+  name_list *nl;
+  parsed_dns_names dns_entries = parse_dns_names(entry->dns_names);
+  nl = dns_entries.names;
+  GPR_ASSERT(tsi_construct_peer(2, &peer) == TSI_OK);
+  GPR_ASSERT(tsi_construct_string_peer_property_from_cstring(
+                 TSI_X509_SUBJECT_COMMON_NAME_PEER_PROPERTY, entry->common_name,
+                 &peer.properties[0]) == TSI_OK);
+  GPR_ASSERT(tsi_construct_list_peer_property(
+                 TSI_X509_SUBJECT_ALTERNATIVE_NAMES_PEER_PROPERTY,
+                 dns_entries.name_count, &peer.properties[1]) == TSI_OK);
+  i = 0;
+  while (nl != NULL) {
+    char *processed = processed_dns_name(nl->name);
+    GPR_ASSERT(tsi_construct_string_peer_property(
+                   NULL, processed, strlen(nl->name),
+                   &peer.properties[1].value.list.children[i++]) == TSI_OK);
+    nl = nl->next;
+    gpr_free(processed);
+  }
+  destruct_parsed_dns_names(&dns_entries);
+  return peer;
+}
+
+char *cert_name_test_entry_to_string(const cert_name_test_entry *entry) {
+  char *s;
+  gpr_asprintf(
+      &s, "{ success = %s, host_name = %s, common_name = %s, dns_names = %s}",
+      entry->expected ? "true" : "false", entry->host_name, entry->common_name,
+      entry->dns_names != NULL ? entry->dns_names : "");
+  return s;
+}
+
+static void test_peer_matches_name(void) {
+  size_t i = 0;
+  for (i = 0; i < GPR_ARRAY_SIZE(cert_name_test_entries); i++) {
+    const cert_name_test_entry *entry = &cert_name_test_entries[i];
+    tsi_peer peer = peer_from_cert_name_test_entry(entry);
+    int result = tsi_ssl_peer_matches_name(&peer, entry->host_name);
+    if (result != entry->expected) {
+      char *entry_str = cert_name_test_entry_to_string(entry);
+      gpr_log(GPR_ERROR, "%s", entry_str);
+      gpr_free(entry_str);
+      GPR_ASSERT(0); /* Unexpected result. */
+    }
+    tsi_peer_destruct(&peer);
+  }
+}
+
+int main(int argc, char **argv) {
+  grpc_test_init(argc, argv);
+  test_peer_matches_name();
+  return 0;
+}
diff --git a/test/core/util/grpc_profiler.h b/test/core/util/grpc_profiler.h
index a31fcc1..347a1d3 100644
--- a/test/core/util/grpc_profiler.h
+++ b/test/core/util/grpc_profiler.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_TEST_UTIL_GRPC_PROFILER_H__
-#define __GRPC_TEST_UTIL_GRPC_PROFILER_H__
+#ifndef GRPC_TEST_CORE_UTIL_GRPC_PROFILER_H
+#define GRPC_TEST_CORE_UTIL_GRPC_PROFILER_H
 
 #ifdef __cplusplus
 extern "C" {
@@ -45,4 +45,4 @@
 }
 #endif /*  __cplusplus */
 
-#endif /* __GRPC_TEST_UTIL_GRPC_PROFILER_H__ */
+#endif  /* GRPC_TEST_CORE_UTIL_GRPC_PROFILER_H */
diff --git a/test/core/util/parse_hexstring.h b/test/core/util/parse_hexstring.h
index 3fce0c9..22bbd17 100644
--- a/test/core/util/parse_hexstring.h
+++ b/test/core/util/parse_hexstring.h
@@ -31,11 +31,11 @@
  *
  */
 
-#ifndef __GRPC_TEST_UTIL_PARSE_HEXSTRING_H_
-#define __GRPC_TEST_UTIL_PARSE_HEXSTRING_H_
+#ifndef GRPC_TEST_CORE_UTIL_PARSE_HEXSTRING_H
+#define GRPC_TEST_CORE_UTIL_PARSE_HEXSTRING_H
 
 #include <grpc/support/slice.h>
 
 gpr_slice parse_hexstring(const char *hexstring);
 
-#endif /* __GRPC_TEST_UTIL_PARSE_HEXSTRING_H_ */
+#endif  /* GRPC_TEST_CORE_UTIL_PARSE_HEXSTRING_H */
diff --git a/test/core/util/port.h b/test/core/util/port.h
index 2a12ab9..b516ec5 100644
--- a/test/core/util/port.h
+++ b/test/core/util/port.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_TEST_UTIL_PORT_H__
-#define __GRPC_TEST_UTIL_PORT_H__
+#ifndef GRPC_TEST_CORE_UTIL_PORT_H
+#define GRPC_TEST_CORE_UTIL_PORT_H
 
 #ifdef __cplusplus
 extern "C" {
@@ -49,4 +49,4 @@
 }
 #endif
 
-#endif /* __GRPC_TEST_UTIL_PORT_H__ */
+#endif  /* GRPC_TEST_CORE_UTIL_PORT_H */
diff --git a/test/core/util/port_posix.c b/test/core/util/port_posix.c
index f0fe1a0..36f13e1 100644
--- a/test/core/util/port_posix.c
+++ b/test/core/util/port_posix.c
@@ -116,11 +116,20 @@
   int try = 0;
 
   for (;;) {
-    int port =
-        try < NUM_RANDOM_PORTS_TO_PICK ? rand() % (65536 - 30000) + 30000 : 0;
+    int port;
+    try++;
+    if (try == 1) {
+      port = getpid() % (65536 - 30000) + 30000;
+    } else if (try <= NUM_RANDOM_PORTS_TO_PICK) {
+      port = rand() % (65536 - 30000) + 30000;
+    } else {
+      port = 0;
+    }
+    
     if (!is_port_available(&port, is_tcp)) {
       continue;
     }
+
     GPR_ASSERT(port > 0);
     /* Check that the port # is free for the other type of socket also */
     if (!is_port_available(&port, !is_tcp)) {
diff --git a/test/core/util/slice_splitter.h b/test/core/util/slice_splitter.h
index b67fe73..1ce1c09 100644
--- a/test/core/util/slice_splitter.h
+++ b/test/core/util/slice_splitter.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPC_TEST_UTIL_SLICE_SPLITTER_H__
-#define __GRPC_TEST_UTIL_SLICE_SPLITTER_H__
+#ifndef GRPC_TEST_CORE_UTIL_SLICE_SPLITTER_H
+#define GRPC_TEST_CORE_UTIL_SLICE_SPLITTER_H
 
 /* utility function to split/merge slices together to help create test
    cases */
@@ -65,4 +65,4 @@
 
 const char *grpc_slice_split_mode_name(grpc_slice_split_mode mode);
 
-#endif /* __GRPC_TEST_UTIL_SLICE_SPLITTER_H__ */
+#endif  /* GRPC_TEST_CORE_UTIL_SLICE_SPLITTER_H */
diff --git a/test/core/util/test_config.c b/test/core/util/test_config.c
index 1c46407..1f0f017 100644
--- a/test/core/util/test_config.c
+++ b/test/core/util/test_config.c
@@ -34,6 +34,7 @@
 #include "test/core/util/test_config.h"
 
 #include <grpc/support/port_platform.h>
+#include <grpc/support/log.h>
 #include <stdlib.h>
 #include <signal.h>
 
@@ -52,6 +53,9 @@
   /* disable SIGPIPE */
   signal(SIGPIPE, SIG_IGN);
 #endif
+  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);
   /* 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/test/core/util/test_config.h b/test/core/util/test_config.h
index b97fbfa..668a069 100644
--- a/test/core/util/test_config.h
+++ b/test/core/util/test_config.h
@@ -31,17 +31,38 @@
  *
  */
 
-#ifndef __GRPC_TEST_UTIL_TEST_CONFIG_H__
-#define __GRPC_TEST_UTIL_TEST_CONFIG_H__
+#ifndef GRPC_TEST_CORE_UTIL_TEST_CONFIG_H
+#define GRPC_TEST_CORE_UTIL_TEST_CONFIG_H
+
+#include <grpc/support/time.h>
 
 #ifdef __cplusplus
 extern "C" {
 #endif /*  __cplusplus */
 
+#ifndef GRPC_TEST_SLOWDOWN_BUILD_FACTOR
+#define GRPC_TEST_SLOWDOWN_BUILD_FACTOR 1.0
+#endif
+
+#ifndef GRPC_TEST_SLOWDOWN_MACHINE_FACTOR
+#define GRPC_TEST_SLOWDOWN_MACHINE_FACTOR 1.0
+#endif
+
+#define GRPC_TEST_SLOWDOWN_FACTOR \
+  (GRPC_TEST_SLOWDOWN_BUILD_FACTOR * GRPC_TEST_SLOWDOWN_MACHINE_FACTOR)
+
+#define GRPC_TIMEOUT_SECONDS_TO_DEADLINE(x) \
+  gpr_time_add(gpr_now(),                   \
+               gpr_time_from_micros(GRPC_TEST_SLOWDOWN_FACTOR * 1e6 * (x)))
+
+#define GRPC_TIMEOUT_MILLIS_TO_DEADLINE(x) \
+  gpr_time_add(gpr_now(),                  \
+               gpr_time_from_micros(GRPC_TEST_SLOWDOWN_FACTOR * 1e3 * (x)))
+
 void grpc_test_init(int argc, char **argv);
 
 #ifdef __cplusplus
 }
 #endif /*  __cplusplus */
 
-#endif /* __GRPC_TEST_UTIL_TEST_CONFIG_H__ */
+#endif  /* GRPC_TEST_CORE_UTIL_TEST_CONFIG_H */
diff --git a/test/cpp/end2end/async_end2end_test.cc b/test/cpp/end2end/async_end2end_test.cc
index 9e25a53..331a5ef 100644
--- a/test/cpp/end2end/async_end2end_test.cc
+++ b/test/cpp/end2end/async_end2end_test.cc
@@ -65,9 +65,7 @@
 
 namespace {
 
-void* tag(int i) {
-  return (void*)(gpr_intptr)i;
-}
+void* tag(int i) { return (void*)(gpr_intptr)i; }
 
 void verify_ok(CompletionQueue* cq, int i, bool expect_ok) {
   bool ok;
@@ -81,7 +79,7 @@
  protected:
   AsyncEnd2endTest() : service_(&srv_cq_) {}
 
-  void SetUp() override {
+  void SetUp() GRPC_OVERRIDE {
     int port = grpc_pick_unused_port_or_die();
     server_address_ << "localhost:" << port;
     // Setup server
@@ -91,7 +89,7 @@
     server_ = builder.BuildAndStart();
   }
 
-  void TearDown() override {
+  void TearDown() GRPC_OVERRIDE {
     server_->Shutdown();
     void* ignored_tag;
     bool ignored_ok;
@@ -109,18 +107,10 @@
     stub_ = std::move(grpc::cpp::test::util::TestService::NewStub(channel));
   }
 
-  void server_ok(int i) {
-    verify_ok(&srv_cq_, i, true);
-  }
-  void client_ok(int i) {
-    verify_ok(&cli_cq_, i , true);
-  }
-  void server_fail(int i) {
-    verify_ok(&srv_cq_, i, false);
-  }
-  void client_fail(int i) {
-    verify_ok(&cli_cq_, i, false);
-  }
+  void server_ok(int i) { verify_ok(&srv_cq_, i, true); }
+  void client_ok(int i) { verify_ok(&cli_cq_, i, true); }
+  void server_fail(int i) { verify_ok(&srv_cq_, i, false); }
+  void client_fail(int i) { verify_ok(&cli_cq_, i, false); }
 
   void SendRpc(int num_rpcs) {
     for (int i = 0; i < num_rpcs; i++) {
@@ -135,12 +125,11 @@
       grpc::ServerAsyncResponseWriter<EchoResponse> response_writer(&srv_ctx);
 
       send_request.set_message("Hello");
-      std::unique_ptr<ClientAsyncResponseReader<EchoResponse> >
-          response_reader(stub_->Echo(
-              &cli_ctx, send_request, &cli_cq_, tag(1)));
+      std::unique_ptr<ClientAsyncResponseReader<EchoResponse> > response_reader(
+          stub_->AsyncEcho(&cli_ctx, send_request, &cli_cq_, tag(1)));
 
-      service_.RequestEcho(
-          &srv_ctx, &recv_request, &response_writer, &srv_cq_, tag(2));
+      service_.RequestEcho(&srv_ctx, &recv_request, &response_writer, &srv_cq_,
+                           tag(2));
 
       server_ok(2);
       EXPECT_EQ(send_request.message(), recv_request.message());
@@ -191,10 +180,9 @@
 
   send_request.set_message("Hello");
   std::unique_ptr<ClientAsyncWriter<EchoRequest> > cli_stream(
-      stub_->RequestStream(&cli_ctx, &recv_response, &cli_cq_, tag(1)));
+      stub_->AsyncRequestStream(&cli_ctx, &recv_response, &cli_cq_, tag(1)));
 
-  service_.RequestRequestStream(
-      &srv_ctx, &srv_stream, &srv_cq_, tag(2));
+  service_.RequestRequestStream(&srv_ctx, &srv_stream, &srv_cq_, tag(2));
 
   server_ok(2);
   client_ok(1);
@@ -245,10 +233,10 @@
 
   send_request.set_message("Hello");
   std::unique_ptr<ClientAsyncReader<EchoResponse> > cli_stream(
-      stub_->ResponseStream(&cli_ctx, send_request, &cli_cq_, tag(1)));
+      stub_->AsyncResponseStream(&cli_ctx, send_request, &cli_cq_, tag(1)));
 
-  service_.RequestResponseStream(
-      &srv_ctx, &recv_request, &srv_stream, &srv_cq_, tag(2));
+  service_.RequestResponseStream(&srv_ctx, &recv_request, &srv_stream, &srv_cq_,
+                                 tag(2));
 
   server_ok(2);
   client_ok(1);
@@ -296,10 +284,9 @@
 
   send_request.set_message("Hello");
   std::unique_ptr<ClientAsyncReaderWriter<EchoRequest, EchoResponse> >
-      cli_stream(stub_->BidiStream(&cli_ctx, &cli_cq_, tag(1)));
+      cli_stream(stub_->AsyncBidiStream(&cli_ctx, &cli_cq_, tag(1)));
 
-  service_.RequestBidiStream(
-      &srv_ctx, &srv_stream, &srv_cq_, tag(2));
+  service_.RequestBidiStream(&srv_ctx, &srv_stream, &srv_cq_, tag(2));
 
   server_ok(2);
   client_ok(1);
@@ -355,10 +342,10 @@
   cli_ctx.AddMetadata(meta2.first, meta2.second);
 
   std::unique_ptr<ClientAsyncResponseReader<EchoResponse> > response_reader(
-      stub_->Echo(&cli_ctx, send_request, &cli_cq_, tag(1)));
+      stub_->AsyncEcho(&cli_ctx, send_request, &cli_cq_, tag(1)));
 
-  service_.RequestEcho(
-      &srv_ctx, &recv_request, &response_writer, &srv_cq_, tag(2));
+  service_.RequestEcho(&srv_ctx, &recv_request, &response_writer, &srv_cq_,
+                       tag(2));
   server_ok(2);
   EXPECT_EQ(send_request.message(), recv_request.message());
   auto client_initial_metadata = srv_ctx.client_metadata();
@@ -397,10 +384,10 @@
   std::pair<grpc::string, grpc::string> meta2("key2", "val2");
 
   std::unique_ptr<ClientAsyncResponseReader<EchoResponse> > response_reader(
-      stub_->Echo(&cli_ctx, send_request, &cli_cq_, tag(1)));
+      stub_->AsyncEcho(&cli_ctx, send_request, &cli_cq_, tag(1)));
 
-  service_.RequestEcho(
-      &srv_ctx, &recv_request, &response_writer, &srv_cq_, tag(2));
+  service_.RequestEcho(&srv_ctx, &recv_request, &response_writer, &srv_cq_,
+                       tag(2));
   server_ok(2);
   EXPECT_EQ(send_request.message(), recv_request.message());
   srv_ctx.AddInitialMetadata(meta1.first, meta1.second);
@@ -445,10 +432,10 @@
   std::pair<grpc::string, grpc::string> meta2("key2", "val2");
 
   std::unique_ptr<ClientAsyncResponseReader<EchoResponse> > response_reader(
-      stub_->Echo(&cli_ctx, send_request, &cli_cq_, tag(1)));
+      stub_->AsyncEcho(&cli_ctx, send_request, &cli_cq_, tag(1)));
 
-  service_.RequestEcho(
-      &srv_ctx, &recv_request, &response_writer, &srv_cq_, tag(2));
+  service_.RequestEcho(&srv_ctx, &recv_request, &response_writer, &srv_cq_,
+                       tag(2));
   server_ok(2);
   EXPECT_EQ(send_request.message(), recv_request.message());
   response_writer.SendInitialMetadata(tag(3));
@@ -462,7 +449,6 @@
 
   server_ok(4);
 
-
   response_reader->Finish(&recv_response, &recv_status, tag(5));
   client_ok(5);
   EXPECT_EQ(send_response.message(), recv_response.message());
@@ -491,20 +477,22 @@
   std::pair<grpc::string, grpc::string> meta2(
       "key2-bin", {"\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc", 13});
   std::pair<grpc::string, grpc::string> meta3("key3", "val3");
-  std::pair<grpc::string, grpc::string> meta6("key4-bin",
+  std::pair<grpc::string, grpc::string> meta6(
+      "key4-bin",
       {"\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d", 14});
   std::pair<grpc::string, grpc::string> meta5("key5", "val5");
-  std::pair<grpc::string, grpc::string> meta4("key6-bin",
+  std::pair<grpc::string, grpc::string> meta4(
+      "key6-bin",
       {"\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee", 15});
 
   cli_ctx.AddMetadata(meta1.first, meta1.second);
   cli_ctx.AddMetadata(meta2.first, meta2.second);
 
   std::unique_ptr<ClientAsyncResponseReader<EchoResponse> > response_reader(
-      stub_->Echo(&cli_ctx, send_request, &cli_cq_, tag(1)));
+      stub_->AsyncEcho(&cli_ctx, send_request, &cli_cq_, tag(1)));
 
-  service_.RequestEcho(
-      &srv_ctx, &recv_request, &response_writer, &srv_cq_, tag(2));
+  service_.RequestEcho(&srv_ctx, &recv_request, &response_writer, &srv_cq_,
+                       tag(2));
   server_ok(2);
   EXPECT_EQ(send_request.message(), recv_request.message());
   auto client_initial_metadata = srv_ctx.client_metadata();
@@ -531,7 +519,6 @@
 
   server_ok(5);
 
-
   response_reader->Finish(&recv_response, &recv_status, tag(6));
   client_ok(6);
   EXPECT_EQ(send_response.message(), recv_response.message());
diff --git a/test/cpp/end2end/end2end_test.cc b/test/cpp/end2end/end2end_test.cc
index 45f12a9..1d5dfc4 100644
--- a/test/cpp/end2end/end2end_test.cc
+++ b/test/cpp/end2end/end2end_test.cc
@@ -83,7 +83,7 @@
 class TestServiceImpl : public ::grpc::cpp::test::util::TestService::Service {
  public:
   Status Echo(ServerContext* context, const EchoRequest* request,
-              EchoResponse* response) override {
+              EchoResponse* response) GRPC_OVERRIDE {
     response->set_message(request->message());
     MaybeEchoDeadline(context, request, response);
     return Status::OK;
@@ -93,7 +93,7 @@
 
   Status RequestStream(ServerContext* context,
                        ServerReader<EchoRequest>* reader,
-                       EchoResponse* response) override {
+                       EchoResponse* response) GRPC_OVERRIDE {
     EchoRequest request;
     response->set_message("");
     while (reader->Read(&request)) {
@@ -105,7 +105,7 @@
   // Return 3 messages.
   // TODO(yangg) make it generic by adding a parameter into EchoRequest
   Status ResponseStream(ServerContext* context, const EchoRequest* request,
-                        ServerWriter<EchoResponse>* writer) override {
+                        ServerWriter<EchoResponse>* writer) GRPC_OVERRIDE {
     EchoResponse response;
     response.set_message(request->message() + "0");
     writer->Write(response);
@@ -117,9 +117,9 @@
     return Status::OK;
   }
 
-  Status BidiStream(
-      ServerContext* context,
-      ServerReaderWriter<EchoResponse, EchoRequest>* stream) override {
+  Status BidiStream(ServerContext* context,
+                    ServerReaderWriter<EchoResponse, EchoRequest>* stream)
+      GRPC_OVERRIDE {
     EchoRequest request;
     EchoResponse response;
     while (stream->Read(&request)) {
@@ -135,7 +135,7 @@
     : public ::grpc::cpp::test::util::duplicate::TestService::Service {
  public:
   Status Echo(ServerContext* context, const EchoRequest* request,
-              EchoResponse* response) override {
+              EchoResponse* response) GRPC_OVERRIDE {
     response->set_message("no package");
     return Status::OK;
   }
@@ -145,7 +145,7 @@
  protected:
   End2endTest() : thread_pool_(2) {}
 
-  void SetUp() override {
+  void SetUp() GRPC_OVERRIDE {
     int port = grpc_pick_unused_port_or_die();
     server_address_ << "localhost:" << port;
     // Setup server
@@ -157,7 +157,7 @@
     server_ = builder.BuildAndStart();
   }
 
-  void TearDown() override { server_->Shutdown(); }
+  void TearDown() GRPC_OVERRIDE { server_->Shutdown(); }
 
   void ResetStub() {
     std::shared_ptr<ChannelInterface> channel =
diff --git a/test/cpp/interop/client.cc b/test/cpp/interop/client.cc
index 78f2063..f7537c2 100644
--- a/test/cpp/interop/client.cc
+++ b/test/cpp/interop/client.cc
@@ -38,6 +38,8 @@
 #include <string>
 #include <thread>
 
+#include <unistd.h>
+
 #include <grpc/grpc.h>
 #include <grpc/support/log.h>
 #include <gflags/gflags.h>
@@ -57,7 +59,7 @@
 DEFINE_bool(use_prod_roots, false, "True to use SSL roots for google");
 DEFINE_int32(server_port, 0, "Server port.");
 DEFINE_string(server_host, "127.0.0.1", "Server host to connect to");
-DEFINE_string(server_host_override, "foo.test.google.com",
+DEFINE_string(server_host_override, "foo.test.google.fr",
               "Override the server host which is sent in HTTP header");
 DEFINE_string(test_case, "large_unary",
               "Configure different test cases. Valid options are: "
@@ -313,8 +315,7 @@
     GPR_ASSERT(response.payload().body() ==
                grpc::string(kResponseMessageSize, '\0'));
     gpr_log(GPR_INFO, "received message %d", i);
-    std::this_thread::sleep_for(
-        std::chrono::milliseconds(kReceiveDelayMilliSeconds));
+    usleep(kReceiveDelayMilliSeconds * 1000);
     ++i;
   }
   GPR_ASSERT(kNumResponseMessages == i);
diff --git a/test/cpp/interop/server.cc b/test/cpp/interop/server.cc
index 263bd8e..9810ff6 100644
--- a/test/cpp/interop/server.cc
+++ b/test/cpp/interop/server.cc
@@ -36,6 +36,7 @@
 #include <thread>
 
 #include <signal.h>
+#include <unistd.h>
 
 #include <gflags/gflags.h>
 #include <grpc/grpc.h>
@@ -222,7 +223,7 @@
   std::unique_ptr<Server> server(builder.BuildAndStart());
   gpr_log(GPR_INFO, "Server listening on %s", server_address.str().c_str());
   while (!got_sigint) {
-    std::this_thread::sleep_for(std::chrono::seconds(5));
+    sleep(5);
   }
 }
 
diff --git a/test/cpp/qps/client_async.cc b/test/cpp/qps/client_async.cc
new file mode 100644
index 0000000..9ea9cfe
--- /dev/null
+++ b/test/cpp/qps/client_async.cc
@@ -0,0 +1,341 @@
+/*
+ *
+ * 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 <cassert>
+#include <functional>
+#include <memory>
+#include <string>
+#include <thread>
+#include <vector>
+#include <sstream>
+
+#include <grpc/grpc.h>
+#include <grpc/support/histogram.h>
+#include <grpc/support/log.h>
+#include <gflags/gflags.h>
+#include <grpc++/async_unary_call.h>
+#include <grpc++/client_context.h>
+#include <grpc++/status.h>
+#include "test/core/util/grpc_profiler.h"
+#include "test/cpp/util/create_test_channel.h"
+#include "test/cpp/qps/qpstest.pb.h"
+
+DEFINE_bool(enable_ssl, false, "Whether to use ssl/tls.");
+DEFINE_int32(server_port, 0, "Server port.");
+DEFINE_string(server_host, "127.0.0.1", "Server host.");
+DEFINE_int32(client_threads, 4, "Number of client threads.");
+
+// We have a configurable number of channels for sending RPCs.
+// RPCs are sent round-robin on the available channels by the
+// various threads. Interesting cases are 1 global channel or
+// 1 per-thread channel, but we can support any number.
+// The channels are assigned round-robin on an RPC by RPC basis
+// rather than just at initialization time in order to also measure the
+// impact of cache thrashing caused by channel changes. This is an issue
+// if you are not in one of the above "interesting cases"
+DEFINE_int32(client_channels, 4, "Number of client channels.");
+
+DEFINE_int32(num_rpcs, 1000, "Number of RPCs per thread.");
+DEFINE_int32(payload_size, 1, "Payload size in bytes");
+
+// Alternatively, specify parameters for test as a workload so that multiple
+// tests are initiated back-to-back. This is convenient for keeping a borg
+// allocation consistent. This is a space-separated list of
+// [threads channels num_rpcs payload_size ]*
+DEFINE_string(workload, "", "Workload parameters");
+
+using grpc::ChannelInterface;
+using grpc::CreateTestChannel;
+using grpc::testing::ServerStats;
+using grpc::testing::SimpleRequest;
+using grpc::testing::SimpleResponse;
+using grpc::testing::StatsRequest;
+using grpc::testing::TestService;
+
+// In some distros, gflags is in the namespace google, and in some others,
+// in gflags. This hack is enabling us to find both.
+namespace google {}
+namespace gflags {}
+using namespace google;
+using namespace gflags;
+
+static double now() {
+  gpr_timespec tv = gpr_now();
+  return 1e9 * tv.tv_sec + tv.tv_nsec;
+}
+
+class ClientRpcContext {
+ public:
+  ClientRpcContext() {}
+  virtual ~ClientRpcContext() {}
+  virtual bool RunNextState() = 0;  // do next state, return false if steps done
+  static void *tag(ClientRpcContext *c) { return reinterpret_cast<void *>(c); }
+  static ClientRpcContext *detag(void *t) {
+    return reinterpret_cast<ClientRpcContext *>(t);
+  }
+  virtual void report_stats(gpr_histogram *hist) = 0;
+};
+template <class RequestType, class ResponseType>
+class ClientRpcContextUnaryImpl : public ClientRpcContext {
+ public:
+  ClientRpcContextUnaryImpl(
+      TestService::Stub *stub,
+      const RequestType &req,
+      std::function<
+          std::unique_ptr<grpc::ClientAsyncResponseReader<ResponseType>>(
+	      TestService::Stub *, grpc::ClientContext *, const RequestType &,
+	      void *)> start_req,
+      std::function<void(grpc::Status, ResponseType *)> on_done)
+      : context_(),
+	stub_(stub),
+        req_(req),
+        response_(),
+        next_state_(&ClientRpcContextUnaryImpl::ReqSent),
+        callback_(on_done),
+        start_(now()),
+        response_reader_(
+	    start_req(stub_, &context_, req_, ClientRpcContext::tag(this))) {}
+  ~ClientRpcContextUnaryImpl() GRPC_OVERRIDE {}
+  bool RunNextState() GRPC_OVERRIDE { return (this->*next_state_)(); }
+  void report_stats(gpr_histogram *hist) GRPC_OVERRIDE {
+    gpr_histogram_add(hist, now() - start_);
+  }
+
+ private:
+  bool ReqSent() {
+    next_state_ = &ClientRpcContextUnaryImpl::RespDone;
+    response_reader_->Finish(&response_, &status_, ClientRpcContext::tag(this));
+    return true;
+  }
+  bool RespDone() {
+    next_state_ = &ClientRpcContextUnaryImpl::DoCallBack;
+    return false;
+  }
+  bool DoCallBack() {
+    callback_(status_, &response_);
+    return false;
+  }
+  grpc::ClientContext context_;
+  TestService::Stub *stub_;
+  RequestType req_;
+  ResponseType response_;
+  bool (ClientRpcContextUnaryImpl::*next_state_)();
+  std::function<void(grpc::Status, ResponseType *)> callback_;
+  grpc::Status status_;
+  double start_;
+  std::unique_ptr<grpc::ClientAsyncResponseReader<ResponseType>>
+      response_reader_;
+};
+
+static void RunTest(const int client_threads, const int client_channels,
+                    const int num_rpcs, const int payload_size) {
+  gpr_log(GPR_INFO,
+          "QPS test with parameters\n"
+          "enable_ssl = %d\n"
+          "client_channels = %d\n"
+          "client_threads = %d\n"
+          "num_rpcs = %d\n"
+          "payload_size = %d\n"
+          "server_host:server_port = %s:%d\n\n",
+          FLAGS_enable_ssl, client_channels, client_threads, num_rpcs,
+          payload_size, FLAGS_server_host.c_str(), FLAGS_server_port);
+
+  std::ostringstream oss;
+  oss << FLAGS_server_host << ":" << FLAGS_server_port;
+
+  class ClientChannelInfo {
+   public:
+    explicit ClientChannelInfo(const grpc::string &server)
+        : channel_(CreateTestChannel(server, FLAGS_enable_ssl)),
+          stub_(TestService::NewStub(channel_)) {}
+    ChannelInterface *get_channel() { return channel_.get(); }
+    TestService::Stub *get_stub() { return stub_.get(); }
+
+   private:
+    std::shared_ptr<ChannelInterface> channel_;
+    std::unique_ptr<TestService::Stub> stub_;
+  };
+
+  std::vector<ClientChannelInfo> channels;
+  for (int i = 0; i < client_channels; i++) {
+    channels.push_back(ClientChannelInfo(oss.str()));
+  }
+
+  std::vector<std::thread> threads;  // Will add threads when ready to execute
+  std::vector< ::gpr_histogram *> thread_stats(client_threads);
+
+  TestService::Stub *stub_stats = channels[0].get_stub();
+  grpc::ClientContext context_stats_begin;
+  StatsRequest stats_request;
+  ServerStats server_stats_begin;
+  stats_request.set_test_num(0);
+  grpc::Status status_beg = stub_stats->CollectServerStats(
+      &context_stats_begin, stats_request, &server_stats_begin);
+
+  grpc_profiler_start("qps_client_async.prof");
+
+  auto CheckDone = [=](grpc::Status s, SimpleResponse *response) {
+    GPR_ASSERT(s.IsOk() && (response->payload().type() ==
+                            grpc::testing::PayloadType::COMPRESSABLE) &&
+               (response->payload().body().length() ==
+                static_cast<size_t>(payload_size)));
+  };
+
+  for (int i = 0; i < client_threads; i++) {
+    gpr_histogram *hist = gpr_histogram_create(0.01, 60e9);
+    GPR_ASSERT(hist != NULL);
+    thread_stats[i] = hist;
+
+    threads.push_back(std::thread(
+        [hist, client_threads, client_channels, num_rpcs, payload_size,
+         &channels, &CheckDone](int channel_num) {
+          using namespace std::placeholders;
+          SimpleRequest request;
+          request.set_response_type(grpc::testing::PayloadType::COMPRESSABLE);
+          request.set_response_size(payload_size);
+
+          grpc::CompletionQueue cli_cq;
+	  auto start_req = std::bind(&TestService::Stub::AsyncUnaryCall, _1,
+				     _2, _3, &cli_cq, _4);
+
+          int rpcs_sent = 0;
+          while (rpcs_sent < num_rpcs) {
+            rpcs_sent++;
+            TestService::Stub *stub = channels[channel_num].get_stub();
+            new ClientRpcContextUnaryImpl<SimpleRequest, SimpleResponse>(stub,
+                request, start_req, CheckDone);
+            void *got_tag;
+            bool ok;
+
+            // Need to call 2 next for every 1 RPC (1 for req done, 1 for resp
+            // done)
+            cli_cq.Next(&got_tag, &ok);
+            if (!ok) break;
+            ClientRpcContext *ctx = ClientRpcContext::detag(got_tag);
+            if (ctx->RunNextState() == false) {
+              // call the callback and then delete it
+              ctx->report_stats(hist);
+              ctx->RunNextState();
+              delete ctx;
+            }
+            cli_cq.Next(&got_tag, &ok);
+            if (!ok) break;
+            ctx = ClientRpcContext::detag(got_tag);
+            if (ctx->RunNextState() == false) {
+              // call the callback and then delete it
+              ctx->report_stats(hist);
+	      ctx->RunNextState();
+              delete ctx;
+            }
+            // Now do runtime round-robin assignment of the next
+            // channel number
+            channel_num += client_threads;
+            channel_num %= client_channels;
+          }
+        },
+        i % client_channels));
+  }
+
+  gpr_histogram *hist = gpr_histogram_create(0.01, 60e9);
+  GPR_ASSERT(hist != NULL);
+  for (auto &t : threads) {
+    t.join();
+  }
+
+  grpc_profiler_stop();
+
+  for (int i = 0; i < client_threads; i++) {
+    gpr_histogram *h = thread_stats[i];
+    gpr_log(GPR_INFO, "latency at thread %d (50/90/95/99/99.9): %f/%f/%f/%f/%f",
+            i, gpr_histogram_percentile(h, 50), gpr_histogram_percentile(h, 90),
+            gpr_histogram_percentile(h, 95), gpr_histogram_percentile(h, 99),
+            gpr_histogram_percentile(h, 99.9));
+    gpr_histogram_merge(hist, h);
+    gpr_histogram_destroy(h);
+  }
+
+  gpr_log(
+      GPR_INFO,
+      "latency across %d threads with %d channels and %d payload "
+      "(50/90/95/99/99.9): %f / %f / %f / %f / %f",
+      client_threads, client_channels, payload_size,
+      gpr_histogram_percentile(hist, 50), gpr_histogram_percentile(hist, 90),
+      gpr_histogram_percentile(hist, 95), gpr_histogram_percentile(hist, 99),
+      gpr_histogram_percentile(hist, 99.9));
+  gpr_histogram_destroy(hist);
+
+  grpc::ClientContext context_stats_end;
+  ServerStats server_stats_end;
+  grpc::Status status_end = stub_stats->CollectServerStats(
+      &context_stats_end, stats_request, &server_stats_end);
+
+  double elapsed = server_stats_end.time_now() - server_stats_begin.time_now();
+  int total_rpcs = client_threads * num_rpcs;
+  double utime = server_stats_end.time_user() - server_stats_begin.time_user();
+  double stime =
+      server_stats_end.time_system() - server_stats_begin.time_system();
+  gpr_log(GPR_INFO,
+          "Elapsed time: %.3f\n"
+          "RPC Count: %d\n"
+          "QPS: %.3f\n"
+          "System time: %.3f\n"
+          "User time: %.3f\n"
+          "Resource usage: %.1f%%\n",
+          elapsed, total_rpcs, total_rpcs / elapsed, stime, utime,
+          (stime + utime) / elapsed * 100.0);
+}
+
+int main(int argc, char **argv) {
+  grpc_init();
+  ParseCommandLineFlags(&argc, &argv, true);
+
+  GPR_ASSERT(FLAGS_server_port);
+
+  if (FLAGS_workload.length() == 0) {
+    RunTest(FLAGS_client_threads, FLAGS_client_channels, FLAGS_num_rpcs,
+            FLAGS_payload_size);
+  } else {
+    std::istringstream workload(FLAGS_workload);
+    int client_threads, client_channels, num_rpcs, payload_size;
+    workload >> client_threads;
+    while (!workload.eof()) {
+      workload >> client_channels >> num_rpcs >> payload_size;
+      RunTest(client_threads, client_channels, num_rpcs, payload_size);
+      workload >> client_threads;
+    }
+    gpr_log(GPR_INFO, "Done with specified workload.");
+  }
+
+  grpc_shutdown();
+  return 0;
+}
diff --git a/test/cpp/qps/server.cc b/test/cpp/qps/server.cc
index 7d9a9d1..75425c9 100644
--- a/test/cpp/qps/server.cc
+++ b/test/cpp/qps/server.cc
@@ -34,6 +34,8 @@
 #include <sys/signal.h>
 #include <thread>
 
+#include <unistd.h>
+
 #include <gflags/gflags.h>
 #include <grpc/support/alloc.h>
 #include <grpc/support/host_port.h>
@@ -97,7 +99,7 @@
 
 namespace {
 
-class TestServiceImpl final : public TestService::Service {
+class TestServiceImpl GRPC_FINAL : public TestService::Service {
  public:
   Status UnaryCall(ServerContext* context, const SimpleRequest* request,
                    SimpleResponse* response) override {
@@ -180,7 +182,7 @@
   auto server = builder.BuildAndStart();
 
   while (!got_sigint) {
-    std::this_thread::sleep_for(std::chrono::seconds(5));
+    sleep(5);
   }
 }
 
diff --git a/test/cpp/qps/server_async.cc b/test/cpp/qps/server_async.cc
new file mode 100644
index 0000000..c797d8a
--- /dev/null
+++ b/test/cpp/qps/server_async.cc
@@ -0,0 +1,299 @@
+/*
+ *
+ * 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 <forward_list>
+#include <functional>
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <sys/signal.h>
+#include <thread>
+
+#include <gflags/gflags.h>
+#include <grpc/support/alloc.h>
+#include <grpc/support/host_port.h>
+#include <grpc++/async_unary_call.h>
+#include <grpc++/config.h>
+#include <grpc++/server.h>
+#include <grpc++/server_builder.h>
+#include <grpc++/server_context.h>
+#include <grpc++/status.h>
+#include <gtest/gtest.h>
+#include "src/cpp/server/thread_pool.h"
+#include "test/core/util/grpc_profiler.h"
+#include "test/cpp/qps/qpstest.pb.h"
+
+#include <grpc/grpc.h>
+#include <grpc/support/log.h>
+
+DEFINE_bool(enable_ssl, false, "Whether to use ssl/tls.");
+DEFINE_int32(port, 0, "Server port.");
+DEFINE_int32(server_threads, 4, "Number of server threads.");
+
+using grpc::CompletionQueue;
+using grpc::Server;
+using grpc::ServerBuilder;
+using grpc::ServerContext;
+using grpc::ThreadPool;
+using grpc::testing::Payload;
+using grpc::testing::PayloadType;
+using grpc::testing::ServerStats;
+using grpc::testing::SimpleRequest;
+using grpc::testing::SimpleResponse;
+using grpc::testing::StatsRequest;
+using grpc::testing::TestService;
+using grpc::Status;
+
+// In some distros, gflags is in the namespace google, and in some others,
+// in gflags. This hack is enabling us to find both.
+namespace google {}
+namespace gflags {}
+using namespace google;
+using namespace gflags;
+
+static bool got_sigint = false;
+
+static void sigint_handler(int x) { got_sigint = 1; }
+
+static double time_double(struct timeval *tv) {
+  return tv->tv_sec + 1e-6 * tv->tv_usec;
+}
+
+static bool SetPayload(PayloadType type, int size, Payload *payload) {
+  PayloadType response_type = type;
+  // TODO(yangg): Support UNCOMPRESSABLE payload.
+  if (type != PayloadType::COMPRESSABLE) {
+    return false;
+  }
+  payload->set_type(response_type);
+  std::unique_ptr<char[]> body(new char[size]());
+  payload->set_body(body.get(), size);
+  return true;
+}
+
+namespace {
+
+class AsyncQpsServerTest {
+ public:
+  AsyncQpsServerTest() : srv_cq_(), async_service_(&srv_cq_), server_(nullptr) {
+    char *server_address = NULL;
+    gpr_join_host_port(&server_address, "::", FLAGS_port);
+
+    ServerBuilder builder;
+    builder.AddPort(server_address);
+
+    builder.RegisterAsyncService(&async_service_);
+
+    server_ = builder.BuildAndStart();
+    gpr_log(GPR_INFO, "Server listening on %s\n", server_address);
+    gpr_free(server_address);
+
+    using namespace std::placeholders;
+    request_unary_ = std::bind(&TestService::AsyncService::RequestUnaryCall,
+                               &async_service_, _1, _2, _3, &srv_cq_, _4);
+    request_stats_ =
+        std::bind(&TestService::AsyncService::RequestCollectServerStats,
+                  &async_service_, _1, _2, _3, &srv_cq_, _4);
+    for (int i = 0; i < 100; i++) {
+      contexts_.push_front(
+          new ServerRpcContextUnaryImpl<SimpleRequest, SimpleResponse>(
+              request_unary_, UnaryCall));
+      contexts_.push_front(
+          new ServerRpcContextUnaryImpl<StatsRequest, ServerStats>(
+              request_stats_, CollectServerStats));
+    }
+  }
+  ~AsyncQpsServerTest() {
+    server_->Shutdown();
+    void *ignored_tag;
+    bool ignored_ok;
+    srv_cq_.Shutdown();
+    while (srv_cq_.Next(&ignored_tag, &ignored_ok)) {
+    }
+    while (!contexts_.empty()) {
+      delete contexts_.front();
+      contexts_.pop_front();
+    }
+  }
+  void ServeRpcs(int num_threads) {
+    std::vector<std::thread> threads;
+    for (int i = 0; i < num_threads; i++) {
+      threads.push_back(std::thread([=]() {
+        // Wait until work is available or we are shutting down
+        bool ok;
+        void *got_tag;
+        while (srv_cq_.Next(&got_tag, &ok)) {
+          EXPECT_EQ(ok, true);
+          ServerRpcContext *ctx = detag(got_tag);
+          // The tag is a pointer to an RPC context to invoke
+          if (ctx->RunNextState() == false) {
+            // this RPC context is done, so refresh it
+            ctx->Reset();
+          }
+        }
+        return;
+      }));
+    }
+    while (!got_sigint) {
+      std::this_thread::sleep_for(std::chrono::seconds(5));
+    }
+  }
+
+ private:
+  class ServerRpcContext {
+   public:
+    ServerRpcContext() {}
+    virtual ~ServerRpcContext(){};
+    virtual bool RunNextState() = 0;// do next state, return false if all done
+    virtual void Reset() = 0;     // start this back at a clean state
+  };
+  static void *tag(ServerRpcContext *func) {
+    return reinterpret_cast<void *>(func);
+  }
+  static ServerRpcContext *detag(void *tag) {
+    return reinterpret_cast<ServerRpcContext *>(tag);
+  }
+
+  template <class RequestType, class ResponseType>
+  class ServerRpcContextUnaryImpl : public ServerRpcContext {
+   public:
+    ServerRpcContextUnaryImpl(
+        std::function<void(ServerContext *, RequestType *,
+                           grpc::ServerAsyncResponseWriter<ResponseType> *,
+                           void *)> request_method,
+        std::function<grpc::Status(const RequestType *, ResponseType *)>
+            invoke_method)
+        : next_state_(&ServerRpcContextUnaryImpl::invoker),
+          request_method_(request_method),
+          invoke_method_(invoke_method),
+          response_writer_(&srv_ctx_) {
+      request_method_(&srv_ctx_, &req_, &response_writer_,
+                      AsyncQpsServerTest::tag(this));
+    }
+    ~ServerRpcContextUnaryImpl() GRPC_OVERRIDE {}
+    bool RunNextState() GRPC_OVERRIDE { return (this->*next_state_)(); }
+    void Reset() GRPC_OVERRIDE {
+      srv_ctx_ = ServerContext();
+      req_ = RequestType();
+      response_writer_ =
+          grpc::ServerAsyncResponseWriter<ResponseType>(&srv_ctx_);
+
+      // Then request the method
+      next_state_ = &ServerRpcContextUnaryImpl::invoker;
+      request_method_(&srv_ctx_, &req_, &response_writer_,
+                      AsyncQpsServerTest::tag(this));
+    }
+
+   private:
+    bool finisher() { return false; }
+    bool invoker() {
+      ResponseType response;
+
+      // Call the RPC processing function
+      grpc::Status status = invoke_method_(&req_, &response);
+
+      // Have the response writer work and invoke on_finish when done
+      next_state_ = &ServerRpcContextUnaryImpl::finisher;
+      response_writer_.Finish(response, status, AsyncQpsServerTest::tag(this));
+      return true;
+    }
+    ServerContext srv_ctx_;
+    RequestType req_;
+    bool (ServerRpcContextUnaryImpl::*next_state_)();
+    std::function<void(ServerContext *, RequestType *,
+                       grpc::ServerAsyncResponseWriter<ResponseType> *, void *)>
+        request_method_;
+    std::function<grpc::Status(const RequestType *, ResponseType *)>
+        invoke_method_;
+    grpc::ServerAsyncResponseWriter<ResponseType> response_writer_;
+  };
+
+  static Status CollectServerStats(const StatsRequest *,
+                                   ServerStats *response) {
+    struct rusage usage;
+    struct timeval tv;
+    gettimeofday(&tv, NULL);
+    getrusage(RUSAGE_SELF, &usage);
+    response->set_time_now(time_double(&tv));
+    response->set_time_user(time_double(&usage.ru_utime));
+    response->set_time_system(time_double(&usage.ru_stime));
+    return Status::OK;
+  }
+  static Status UnaryCall(const SimpleRequest *request,
+                          SimpleResponse *response) {
+    if (request->has_response_size() && request->response_size() > 0) {
+      if (!SetPayload(request->response_type(), request->response_size(),
+                      response->mutable_payload())) {
+        return Status(grpc::StatusCode::INTERNAL, "Error creating payload.");
+      }
+    }
+    return Status::OK;
+  }
+  CompletionQueue srv_cq_;
+  TestService::AsyncService async_service_;
+  std::unique_ptr<Server> server_;
+  std::function<void(ServerContext *, SimpleRequest *,
+                     grpc::ServerAsyncResponseWriter<SimpleResponse> *, void *)>
+      request_unary_;
+  std::function<void(ServerContext *, StatsRequest *,
+                     grpc::ServerAsyncResponseWriter<ServerStats> *, void *)>
+      request_stats_;
+  std::forward_list<ServerRpcContext *> contexts_;
+};
+
+}  // namespace
+
+static void RunServer() {
+  AsyncQpsServerTest server;
+
+  grpc_profiler_start("qps_server_async.prof");
+
+  server.ServeRpcs(FLAGS_server_threads);
+
+  grpc_profiler_stop();
+}
+
+int main(int argc, char **argv) {
+  grpc_init();
+  ParseCommandLineFlags(&argc, &argv, true);
+  GPR_ASSERT(FLAGS_port != 0);
+  GPR_ASSERT(!FLAGS_enable_ssl);
+
+  signal(SIGINT, sigint_handler);
+
+  RunServer();
+
+  grpc_shutdown();
+  google::protobuf::ShutdownProtobufLibrary();
+
+  return 0;
+}
diff --git a/test/cpp/util/create_test_channel.cc b/test/cpp/util/create_test_channel.cc
index be6c567..745496f 100644
--- a/test/cpp/util/create_test_channel.cc
+++ b/test/cpp/util/create_test_channel.cc
@@ -93,7 +93,7 @@
 // Shortcut for end2end and interop tests.
 std::shared_ptr<ChannelInterface> CreateTestChannel(const grpc::string& server,
                                                     bool enable_ssl) {
-  return CreateTestChannel(server, "foo.test.google.com", enable_ssl, false);
+  return CreateTestChannel(server, "foo.test.google.fr", enable_ssl, false);
 }
 
 }  // namespace grpc
diff --git a/test/cpp/util/create_test_channel.h b/test/cpp/util/create_test_channel.h
index 3476b83..5c298ce 100644
--- a/test/cpp/util/create_test_channel.h
+++ b/test/cpp/util/create_test_channel.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef __GRPCPP_TEST_UTIL_CREATE_TEST_CHANNEL_H_
-#define __GRPCPP_TEST_UTIL_CREATE_TEST_CHANNEL_H_
+#ifndef GRPC_TEST_CPP_UTIL_CREATE_TEST_CHANNEL_H
+#define GRPC_TEST_CPP_UTIL_CREATE_TEST_CHANNEL_H
 
 #include <memory>
 
@@ -56,4 +56,4 @@
 
 }  // namespace grpc
 
-#endif  // __GRPCPP_TEST_UTIL_CREATE_TEST_CHANNEL_H_
+#endif  // GRPC_TEST_CPP_UTIL_CREATE_TEST_CHANNEL_H
diff --git a/tools/distpackages/build_deb_packages.sh b/tools/distpackages/build_deb_packages.sh
index a5f945b..7b2acb6 100755
--- a/tools/distpackages/build_deb_packages.sh
+++ b/tools/distpackages/build_deb_packages.sh
@@ -33,7 +33,8 @@
 deb_dest="deb_out"
 mkdir -p $deb_dest
 
-version='0.8.0.0'
+version='0.5.0.0'
+pkg_version='0.5.0'
 
 if [ -f /.dockerinit ]; then
   # We're in Docker where uname -p returns "unknown".
@@ -97,7 +98,7 @@
   # Build the debian package
   fakeroot dpkg-deb --build $tmp_dir/$pkg_name || { echo "dpkg-deb failed"; exit 1; }
 
-  deb_path=$deb_dest/${pkg_name}_amd64.deb
+  deb_path=$deb_dest/${pkg_name}_${pkg_version}_amd64.deb
 
   # Copy the .deb file to destination dir
   cp $tmp_dir/$pkg_name.deb $deb_path
diff --git a/tools/distpackages/templates/libgrpc-dev/DEBIAN/control b/tools/distpackages/templates/libgrpc-dev/DEBIAN/control
index 64dc79a..289a278 100644
--- a/tools/distpackages/templates/libgrpc-dev/DEBIAN/control
+++ b/tools/distpackages/templates/libgrpc-dev/DEBIAN/control
@@ -1,5 +1,5 @@
 Package: libgrpc-dev
-Version: 0.8.0
+Version: 0.5.0
 Architecture: amd64
 Maintainer: Jan Tattermusch <jtattermusch@google.com>
 Depends: libgrpc, libc6-dev | libc-dev
diff --git a/tools/distpackages/templates/libgrpc-dev/usr/share/doc/libgrpc-dev/changelog.gz b/tools/distpackages/templates/libgrpc-dev/usr/share/doc/libgrpc-dev/changelog.gz
index eabdf46..4f557b8 100644
--- a/tools/distpackages/templates/libgrpc-dev/usr/share/doc/libgrpc-dev/changelog.gz
+++ b/tools/distpackages/templates/libgrpc-dev/usr/share/doc/libgrpc-dev/changelog.gz
Binary files differ
diff --git a/tools/distpackages/templates/libgrpc/DEBIAN/control b/tools/distpackages/templates/libgrpc/DEBIAN/control
index 75c224e..417a825 100644
--- a/tools/distpackages/templates/libgrpc/DEBIAN/control
+++ b/tools/distpackages/templates/libgrpc/DEBIAN/control
@@ -1,5 +1,5 @@
 Package: libgrpc
-Version: 0.8.0
+Version: 0.5.0
 Architecture: amd64
 Maintainer: Jan Tattermusch <jtattermusch@google.com>
 Depends: libc6
diff --git a/tools/distpackages/templates/libgrpc/usr/share/doc/libgrpc/changelog.gz b/tools/distpackages/templates/libgrpc/usr/share/doc/libgrpc/changelog.gz
index c07b4d2..12d4cd9 100644
--- a/tools/distpackages/templates/libgrpc/usr/share/doc/libgrpc/changelog.gz
+++ b/tools/distpackages/templates/libgrpc/usr/share/doc/libgrpc/changelog.gz
Binary files differ
diff --git a/tools/distrib/guard_headers.sh b/tools/distrib/guard_headers.sh
new file mode 100755
index 0000000..2a54cf8
--- /dev/null
+++ b/tools/distrib/guard_headers.sh
@@ -0,0 +1,90 @@
+#!/bin/bash
+# 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.
+
+
+set -e
+
+cd `dirname $0`/../..
+
+function process_dir {
+  base_dir=$1
+  prefix=$2
+  comment_language=$3
+  (
+    cd $base_dir
+    find . -name "*.h" | while read f ; do
+      guard=${prefix}_`echo ${f#*/} | tr '[:lower:]/.-' '[:upper:]___'`
+      if [ "$comment_language" = "c++" ] ; then
+        comment="// $guard"
+      else
+        comment="/* $guard */"
+      fi
+      awk '
+        BEGIN {
+          guard = "'${guard}'";
+          comment_language = "'${comment_language}'";
+        }
+        prev ~ /^#ifndef/ && !got_first_ifndef {
+          got_first_ifndef = 1;
+          prev = "#ifndef " guard;
+        }
+        prev ~ /^#define/ && !got_first_define {
+          got_first_define = 1;
+          prev = "#define " guard;
+        }
+        NR > 1 { print prev; }
+        { prev = $0; }
+        END {
+          if (prev ~ /^#endif/) {
+            if (comment_language ~ /^c$/) {
+              print "#endif  /* " guard " */";
+            } else if (comment_language ~ /^c\+\+$/) {
+              print "#endif  // " guard;
+            } else {
+              print "ERROR: unknown comment language: " comment_language;
+            }
+          } else {
+            print "ERROR: file does not end with #endif";
+          }
+        }
+      ' "${f}" > "${f}.rewritten"
+      mv "${f}.rewritten" "${f}"
+    done
+  )
+}
+
+process_dir include/grpc GRPC c
+process_dir include/grpc++ GRPCXX c++
+process_dir src/core GRPC_INTERNAL_CORE c
+process_dir src/cpp GRPC_INTERNAL_CPP c++
+process_dir src/compiler GRPC_INTERNAL_COMPILER c++
+process_dir test/core GRPC_TEST_CORE c
+process_dir test/cpp GRPC_TEST_CPP c++
+process_dir examples GRPC_EXAMPLES c++
diff --git a/tools/dockerfile/grpc_base/Dockerfile b/tools/dockerfile/grpc_base/Dockerfile
index d2b5569..9186277 100644
--- a/tools/dockerfile/grpc_base/Dockerfile
+++ b/tools/dockerfile/grpc_base/Dockerfile
@@ -64,13 +64,5 @@
 RUN $CLOUD_SDK/install.sh --usage-reporting=true --path-update=true --bash-completion=true --rc-path=/.bashrc --disable-installation-options
 ENV PATH $CLOUD_SDK/bin:$PATH
 
-# Install a GitHub SSH service credential that gives access to the GitHub repo while it's private
-# TODO: remove this once the repo is public
-ADD .ssh .ssh
-RUN chmod 600 .ssh/github.rsa
-RUN mkdir -p $HOME/.ssh && echo 'Host github.com' > $HOME/.ssh/config
-RUN echo "    IdentityFile /.ssh/github.rsa" >> $HOME/.ssh/config
-RUN echo 'StrictHostKeyChecking no' >> $HOME/.ssh/config
-
 # Define the default command.
 CMD ["bash"]
diff --git a/tools/dockerfile/grpc_build_deb/Dockerfile b/tools/dockerfile/grpc_build_deb/Dockerfile
index 6cba74e..24ffc73 100644
--- a/tools/dockerfile/grpc_build_deb/Dockerfile
+++ b/tools/dockerfile/grpc_build_deb/Dockerfile
@@ -34,7 +34,7 @@
 RUN apt-get update && apt-get install -y lintian
 
 # Get the source from GitHub
-RUN git clone git@github.com:grpc/grpc.git /var/local/git/grpc
+RUN git clone https://github.com/grpc/grpc.git /var/local/git/grpc
 RUN cd /var/local/git/grpc && \
   git pull --recurse-submodules && \
   git submodule update --init --recursive
diff --git a/tools/dockerfile/grpc_cxx/Dockerfile b/tools/dockerfile/grpc_cxx/Dockerfile
index 18c6732..ac09e25 100644
--- a/tools/dockerfile/grpc_cxx/Dockerfile
+++ b/tools/dockerfile/grpc_cxx/Dockerfile
@@ -33,7 +33,7 @@
 RUN apt-get update && apt-get -y install libgflags-dev libgtest-dev
 
 # Get the source from GitHub
-RUN git clone git@github.com:grpc/grpc.git /var/local/git/grpc
+RUN git clone https://github.com/grpc/grpc.git /var/local/git/grpc
 RUN cd /var/local/git/grpc && \
   git pull --recurse-submodules && \
   git submodule update --init --recursive
diff --git a/tools/dockerfile/grpc_go/Dockerfile b/tools/dockerfile/grpc_go/Dockerfile
index e1671ea..06bb3e2 100644
--- a/tools/dockerfile/grpc_go/Dockerfile
+++ b/tools/dockerfile/grpc_go/Dockerfile
@@ -30,21 +30,6 @@
 # Dockerfile for gRPC Go
 FROM golang:1.4
 
-# Install SSH to that Go source can be pulled securely.
-RUN apt-get update && apt-get install -y ssh
-
-# Install a GitHub SSH service credential that gives access to the GitHub repo while it's private
-#
-# TODO: remove this once the repo is public
-ADD .ssh .ssh
-RUN chmod 600 /.ssh/github.rsa
-RUN mkdir -p $HOME/.ssh && echo 'Host github.com' > $HOME/.ssh/config
-RUN echo "    IdentityFile /.ssh/github.rsa" >> $HOME/.ssh/config
-RUN echo 'StrictHostKeyChecking no' >> $HOME/.ssh/config
-
-# Force go get to use the GitHub ssh url instead of https, and use the SSH creds
-RUN git config --global url."git@github.com:".insteadOf "https://github.com/"
-
 # Get the source from GitHub
 RUN go get google.golang.org/grpc
 
diff --git a/tools/dockerfile/grpc_java/Dockerfile b/tools/dockerfile/grpc_java/Dockerfile
index affbec9..6b2612b 100644
--- a/tools/dockerfile/grpc_java/Dockerfile
+++ b/tools/dockerfile/grpc_java/Dockerfile
@@ -30,7 +30,7 @@
 # Dockerfile for the gRPC Java dev image
 FROM grpc/java_base
 
-RUN git clone --recursive --depth 1 git@github.com:grpc/grpc-java.git /var/local/git/grpc-java
+RUN git clone --recursive --depth 1 https://github.com/grpc/grpc-java.git /var/local/git/grpc-java
 RUN cd /var/local/git/grpc-java/lib/netty && \
   mvn -pl codec-http2 -am -DskipTests install clean
 RUN cd /var/local/git/grpc-java && \
diff --git a/tools/dockerfile/grpc_java_base/Dockerfile b/tools/dockerfile/grpc_java_base/Dockerfile
index feac5e7..2ee0a62 100644
--- a/tools/dockerfile/grpc_java_base/Dockerfile
+++ b/tools/dockerfile/grpc_java_base/Dockerfile
@@ -51,24 +51,19 @@
 ENV LD_LIBRARY_PATH /usr/local/lib
 
 # Get the protobuf source from GitHub and install it
-RUN wget -O - https://github.com/google/protobuf/archive/master.tar.gz | \
+RUN wget -O - https://github.com/google/protobuf/archive/v3.0.0-alpha-2.tar.gz | \
   tar xz && \
-  cd protobuf-master && \
+  cd protobuf-3.0.0-alpha-2 && \
   ./autogen.sh && \
   ./configure --prefix=/usr && \
   make -j12 && make check && make install && \
   cd java && mvn install && cd .. && \
+  cd javanano && mvn install && cd .. && \
   rm -r "$(pwd)"
 
-# Install a GitHub SSH service credential that gives access to the GitHub repo while it's private
-# TODO: remove this once the repo is public
-COPY .ssh/github.rsa /root/.ssh/id_rsa
-RUN chmod 600 /root/.ssh/id_rsa
-RUN echo 'Host github.com\nStrictHostKeyChecking no' > /root/.ssh/config
-
 # Trigger download of as many Maven and Gradle artifacts as possible. We don't build grpc-java
 # because we don't want to install netty
-RUN git clone --recursive --depth 1 git@github.com:grpc/grpc-java.git && \
+RUN git clone --recursive --depth 1 https://github.com/grpc/grpc-java.git && \
   cd grpc-java/lib/netty && \
   mvn -pl codec-http2 -am -DskipTests verify && \
   cd ../.. && \
diff --git a/tools/dockerfile/grpc_node_base/Dockerfile b/tools/dockerfile/grpc_node_base/Dockerfile
index 55ae608..1f3a236 100644
--- a/tools/dockerfile/grpc_node_base/Dockerfile
+++ b/tools/dockerfile/grpc_node_base/Dockerfile
@@ -34,12 +34,12 @@
 
 RUN curl -sL https://deb.nodesource.com/setup | bash -
 
-RUN apt-get update && apt-get install -y nodejs
+RUN apt-get update && apt-get install -y nodejs nodejs-legacy
 
 RUN npm install -g node-gyp
 
 # Get the source from GitHub, this gets the protobuf library as well
-RUN git clone git@github.com:grpc/grpc.git /var/local/git/grpc
+RUN git clone https://github.com/grpc/grpc.git /var/local/git/grpc
 RUN cd /var/local/git/grpc && \
   git pull --recurse-submodules && \
   git submodule update --init --recursive
diff --git a/tools/dockerfile/grpc_php_base/Dockerfile b/tools/dockerfile/grpc_php_base/Dockerfile
index 49f5da8..cc874fd 100644
--- a/tools/dockerfile/grpc_php_base/Dockerfile
+++ b/tools/dockerfile/grpc_php_base/Dockerfile
@@ -76,7 +76,7 @@
 
 # Download the patched PHP protobuf so that PHP gRPC clients can be generated
 # from proto3 schemas.
-RUN git clone git@github.com:murgatroid99/Protobuf-PHP.git /var/local/git/protobuf-php
+RUN git clone https://github.com/murgatroid99/Protobuf-PHP.git /var/local/git/protobuf-php
 
 # Install ruby (via RVM) as ruby tools are dependencies for building Protobuf
 # PHP extensions.
@@ -91,7 +91,7 @@
 RUN rvm all do gem install ronn rake
 
 # Get the source from GitHub, this gets the protobuf library as well
-RUN git clone git@github.com:grpc/grpc.git /var/local/git/grpc
+RUN git clone https://github.com/grpc/grpc.git /var/local/git/grpc
 RUN cd /var/local/git/grpc && \
   git pull --recurse-submodules && \
   git submodule update --init --recursive
diff --git a/tools/dockerfile/grpc_python_base/Dockerfile b/tools/dockerfile/grpc_python_base/Dockerfile
index 18dd40a..0d45f40 100644
--- a/tools/dockerfile/grpc_python_base/Dockerfile
+++ b/tools/dockerfile/grpc_python_base/Dockerfile
@@ -46,4 +46,4 @@
 RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.0.0-alpha-1
 
 # Get the GRPC source from GitHub
-RUN git clone --recursive git@github.com:grpc/grpc.git /var/local/git/grpc
+RUN git clone --recursive https://github.com/grpc/grpc.git /var/local/git/grpc
diff --git a/tools/dockerfile/grpc_ruby_base/Dockerfile b/tools/dockerfile/grpc_ruby_base/Dockerfile
index f3c7289..d58eeaa 100644
--- a/tools/dockerfile/grpc_ruby_base/Dockerfile
+++ b/tools/dockerfile/grpc_ruby_base/Dockerfile
@@ -72,7 +72,7 @@
 RUN /bin/bash -l -c "gem install bundler --no-ri --no-rdoc"
 
 # Get the source from GitHub
-RUN git clone git@github.com:grpc/grpc.git /var/local/git/grpc
+RUN git clone https://github.com/grpc/grpc.git /var/local/git/grpc
 RUN cd /var/local/git/grpc && \
   git pull --recurse-submodules && \
   git submodule update --init --recursive
diff --git a/tools/gce_setup/cloud_prod_runner.sh b/tools/gce_setup/cloud_prod_runner.sh
index 52e9b5e..e11185c 100755
--- a/tools/gce_setup/cloud_prod_runner.sh
+++ b/tools/gce_setup/cloud_prod_runner.sh
@@ -31,7 +31,8 @@
 
 main() {
   source grpc_docker.sh
-  test_cases=(large_unary empty_unary ping_pong client_streaming server_streaming service_account_creds compute_engine_creds)
+  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)
   clients=(cxx java go ruby node)
   for test_case in "${test_cases[@]}"
   do
@@ -45,6 +46,18 @@
       fi
     done
   done
+  for test_case in "${auth_test_cases[@]}"
+  do
+    for client in "${clients[@]}"
+    do
+      if grpc_cloud_prod_auth_test $test_case grpc-docker-testclients $client
+      then
+        echo "$test_case $client $server passed" >> /tmp/cloud_prod_result.txt
+      else
+        echo "$test_case $client $server failed" >> /tmp/cloud_prod_result.txt
+      fi
+    done
+  done
   gsutil cp /tmp/cloud_prod_result.txt gs://stoked-keyword-656-output/cloud_prod_result.txt
   rm /tmp/cloud_prod_result.txt
 }
diff --git a/tools/gce_setup/grpc_docker.sh b/tools/gce_setup/grpc_docker.sh
index bbc138c..0203926 100755
--- a/tools/gce_setup/grpc_docker.sh
+++ b/tools/gce_setup/grpc_docker.sh
@@ -350,7 +350,7 @@
     echo "$FUNCNAME: missing arg: test_case" 1>&2
     return 1
   }
-  echo "--server_host=$server_ip --server_port=$port --test_case=$test_case"
+  echo "--server_host_override=foo.test.google.fr --server_host=$server_ip --server_port=$port --test_case=$test_case"
 }
 
 # checks the positional args and assigns them to variables visible in the caller
@@ -503,7 +503,7 @@
 
   [[ -n $1 ]] && {  # client_type
     case $1 in
-      cxx|go|java|nodejs|php|python|ruby)
+      cxx|go|java|node|php|python|ruby)
         grpc_gen_test_cmd+="_gen_$1_cmd"
         declare -F $grpc_gen_test_cmd >> /dev/null || {
           echo "-f: test_func for $1 => $grpc_gen_test_cmd is not defined" 1>&2
@@ -673,7 +673,7 @@
   [[ -n $1 ]] && {
     servers="$@"
   } || {
-    servers="cxx java go node ruby"
+    servers="cxx java go node ruby python"
     echo "$FUNCNAME: no servers specified, will launch defaults '$servers'"
   }
 }
@@ -795,16 +795,7 @@
   echo "  $ssh_cmd"
   echo "on $host"
   [[ $dry_run == 1 ]] && return 0  # don't run the command on a dry run
-  gcloud compute $project_opt ssh $zone_opt $host --command "$cmd" &
-  PID=$!
-  sleep 10
-  echo "pid is $PID"
-  if ps -p $PID
-  then
-    kill $PID
-    return 1
-  fi
-
+  gcloud compute $project_opt ssh $zone_opt $host --command "$cmd" 
 }
 
 # Runs a test command on a docker instance.
@@ -850,16 +841,7 @@
   echo "  $ssh_cmd"
   echo "on $host"
   [[ $dry_run == 1 ]] && return 0  # don't run the command on a dry run
-  gcloud compute $project_opt ssh $zone_opt $host --command "$cmd" &
-  PID=$!
-  sleep 10
-  echo "pid is $PID"
-  if ps -p $PID
-  then
-    kill $PID
-    return 1
-  fi
-
+  gcloud compute $project_opt ssh $zone_opt $host --command "$cmd"
 }
 
 # Runs a test command on a docker instance.
@@ -944,8 +926,9 @@
   local cmd_prefix="sudo docker run grpc/go /bin/bash -c"
   local test_script="cd src/google.golang.org/grpc/interop/client"
   local test_script+=" && go run client.go --use_tls=true"
-  local gfe_flags="  --tls_ca_file=\"\" --tls_server_name=\"\" --server_port=443 --server_host=grpc-test.sandbox.google.com"
-  local added_gfe_flags=$(_grpc_svc_acc_test_flags) 
+  local gfe_flags=$(_grpc_prod_gfe_flags)
+  local gfe_flags+="  --tls_ca_file=\"\""
+  local added_gfe_flags=$(_grpc_svc_acc_test_flags)
   local the_cmd="$cmd_prefix '$test_script $gfe_flags $added_gfe_flags $@'"
   echo $the_cmd
 }
@@ -959,8 +942,9 @@
   local cmd_prefix="sudo docker run grpc/go /bin/bash -c"
   local test_script="cd src/google.golang.org/grpc/interop/client"
   local test_script+=" && go run client.go --use_tls=true"
-  local gfe_flags="  --tls_ca_file=\"\" --tls_server_name=\"\" --server_port=443 --server_host=grpc-test.sandbox.google.com"
-  local added_gfe_flags=$(_grpc_gce_test_flags) 
+  local gfe_flags=$(_grpc_prod_gfe_flags)
+  local gfe_flags+="  --tls_ca_file=\"\""
+  local added_gfe_flags=$(_grpc_gce_test_flags)
   local the_cmd="$cmd_prefix '$test_script $gfe_flags $added_gfe_flags $@'"
   echo $the_cmd
 }
@@ -975,9 +959,10 @@
   local test_script="/var/local/git/grpc/src/ruby/bin/interop/interop_client.rb"
   local test_script+=" --use_tls"
   local gfe_flags=$(_grpc_prod_gfe_flags)
-  local added_gfe_flags=$(_grpc_svc_acc_test_flags)
+  local added_gfe_flags=$(_grpc_default_creds_test_flags)
   local env_prefix="SSL_CERT_FILE=/cacerts/roots.pem"
-  local the_cmd="$cmd_prefix '$env_prefix ruby $test_script $gfe_flags $added_gfe_flag $@'"
+  env_prefix+=" GOOGLE_APPLICATION_CREDENTIALS=/service_account/stubbyCloudTestingTest-7dd63462c60c.json"
+  local the_cmd="$cmd_prefix '$env_prefix ruby $test_script $gfe_flags $added_gfe_flags $@'"
   echo $the_cmd
 }
 
@@ -993,7 +978,7 @@
   local gfe_flags=$(_grpc_prod_gfe_flags)
   local added_gfe_flags=$(_grpc_gce_test_flags)
   local env_prefix="SSL_CERT_FILE=/cacerts/roots.pem"
-  local the_cmd="$cmd_prefix '$env_prefix ruby $test_script $gfe_flags $added_gfe_flag $@'"
+  local the_cmd="$cmd_prefix '$env_prefix ruby $test_script $gfe_flags $added_gfe_flags $@'"
   echo $the_cmd
 }
 
@@ -1019,7 +1004,8 @@
   local cmd_prefix="sudo docker run grpc/go /bin/bash -c"
   local test_script="cd src/google.golang.org/grpc/interop/client"
   local test_script+=" && go run client.go --use_tls=true"
-  local gfe_flags="  --tls_ca_file=\"\" --tls_server_name=\"\" --server_port=443 --server_host=grpc-test.sandbox.google.com"
+  local gfe_flags=$(_grpc_prod_gfe_flags)
+  local gfe_flags+="  --tls_ca_file=\"\""
   local the_cmd="$cmd_prefix '$test_script $gfe_flags $@'"
   echo $the_cmd
 }
@@ -1085,7 +1071,8 @@
 #   flags= .... # generic flags to include the command
 #   cmd=$($grpc_gen_test_cmd $flags)
 grpc_cloud_prod_gen_node_cmd() {
-  local cmd_prefix="sudo docker run grpc/node";
+  local env_flag="-e SSL_CERT_FILE=/cacerts/roots.pem "
+  local cmd_prefix="sudo docker run $env_flag grpc/node";
   local test_script="/usr/bin/nodejs /var/local/git/grpc/src/node/interop/interop_client.js --use_tls=true";
   local gfe_flags=$(_grpc_prod_gfe_flags);
   local the_cmd="$cmd_prefix $test_script $gfe_flags $@";
@@ -1098,12 +1085,27 @@
 #   flags= .... # generic flags to include the command
 #   cmd=$($grpc_gen_test_cmd $flags)
 grpc_cloud_prod_auth_service_account_creds_gen_node_cmd() {
-  local cmd_prefix="sudo docker run grpc/node";
+  local env_flag="-e SSL_CERT_FILE=/cacerts/roots.pem "
+  env_flag+="-e GOOGLE_APPLICATION_CREDENTIALS=/service_account/stubbyCloudTestingTest-7dd63462c60c.json "
+  local cmd_prefix="sudo docker run $env_flag grpc/node";
   local test_script="/usr/bin/nodejs /var/local/git/grpc/src/node/interop/interop_client.js --use_tls=true";
   local gfe_flags=$(_grpc_prod_gfe_flags);
-  local env_prefix="SSL_CERT_FILE=/cacerts/roots.pem"
-  env_prefix+=" GOOGLE_APPLICATION_CREDENTIALS=/service_account/stubbyCloudTestingTest-7dd63462c60c.json"
-  local the_cmd="$env_prefix $cmd_prefix $test_script $gfe_flags $@";
+  local the_cmd="$cmd_prefix $test_script $gfe_flags $@";
+  echo $the_cmd
+}
+
+# constructs the full dockerized node gce auth interop test cmd.
+#
+# call-seq:
+#   flags= .... # generic flags to include the command
+#   cmd=$($grpc_gen_test_cmd $flags)
+grpc_cloud_prod_auth_compute_engine_creds_gen_node_cmd() {
+  local env_flag="-e SSL_CERT_FILE=/cacerts/roots.pem "
+  local cmd_prefix="sudo docker run $env_flag grpc/node";
+  local test_script="/usr/bin/nodejs /var/local/git/grpc/src/node/interop/interop_client.js --use_tls=true";
+  local gfe_flags=$(_grpc_prod_gfe_flags)
+  local added_gfe_flags=$(_grpc_gce_test_flags)
+  local the_cmd="$cmd_prefix $test_script $gfe_flags $added_gfe_flags $@";
   echo $the_cmd
 }
 
@@ -1170,6 +1172,11 @@
   echo " --service_account_key_file=/service_account/stubbyCloudTestingTest-7dd63462c60c.json --oauth_scope=https://www.googleapis.com/auth/xapi.zoo"
 }
 
+# default credentials test flag
+_grpc_default_creds_test_flags() {
+  echo " --oauth_scope=https://www.googleapis.com/auth/xapi.zoo"
+}
+
 # outputs the flags passed to the gcloud auth tests
 _grpc_gce_test_flags() {
   echo " --default_service_account=155450119199-r5aaqa2vqoa9g5mv2m6s3m1l293rlmel@developer.gserviceaccount.com --oauth_scope=https://www.googleapis.com/auth/xapi.zoo"
diff --git a/tools/gce_setup/interop_test_runner.sh b/tools/gce_setup/interop_test_runner.sh
index 465c2ab..5f8c0e7 100755
--- a/tools/gce_setup/interop_test_runner.sh
+++ b/tools/gce_setup/interop_test_runner.sh
@@ -35,7 +35,7 @@
 
 main() {
   source grpc_docker.sh
-  test_cases=(large_unary empty_unary ping_pong client_streaming server_streaming cancel_after_being cancel_after_first_response)
+  test_cases=(large_unary empty_unary ping_pong client_streaming server_streaming cancel_after_begin cancel_after_first_response)
   clients=(cxx java go ruby node)
   servers=(cxx java go ruby node python)
   for test_case in "${test_cases[@]}"
diff --git a/tools/run_tests/build_python.sh b/tools/run_tests/build_python.sh
index 9303a67..5a3c720 100755
--- a/tools/run_tests/build_python.sh
+++ b/tools/run_tests/build_python.sh
@@ -37,7 +37,6 @@
 
 root=`pwd`
 virtualenv python2.7_virtual_environment
-ln -sf $root/include/grpc python2.7_virtual_environment/include/grpc
 source python2.7_virtual_environment/bin/activate
 pip install enum34==1.0.4 futures==2.2.0 protobuf==3.0.0-alpha-1
 CFLAGS=-I$root/include LDFLAGS=-L$root/libs/opt pip install src/python/src
diff --git a/tools/run_tests/build_ruby.sh b/tools/run_tests/build_ruby.sh
new file mode 100755
index 0000000..53a69cf
--- /dev/null
+++ b/tools/run_tests/build_ruby.sh
@@ -0,0 +1,47 @@
+#!/bin/bash
+
+# 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.
+
+set -ex
+
+CONFIG=${CONFIG:-opt}
+
+# change to grpc repo root
+cd $(dirname $0)/../..
+
+# tells npm install to look for files in that directory
+export GRPC_ROOT=`pwd`
+# tells npm install the subdirectory with library files
+export GRPC_LIB_SUBDIR=libs/$CONFIG
+
+cd src/ruby
+
+bundle install
+rake compile:grpc
diff --git a/tools/run_tests/jobset.py b/tools/run_tests/jobset.py
index 569cb5b..ad65da5 100755
--- a/tools/run_tests/jobset.py
+++ b/tools/run_tests/jobset.py
@@ -43,10 +43,17 @@
 _DEFAULT_MAX_JOBS = 16 * multiprocessing.cpu_count()
 
 
+have_alarm = False
+def alarm_handler(unused_signum, unused_frame):
+  global have_alarm
+  have_alarm = False
+
+
 # setup a signal handler so that signal.pause registers 'something'
 # when a child finishes
 # not using futures and threading to avoid a dependency on subprocess32
 signal.signal(signal.SIGCHLD, lambda unused_signum, unused_frame: None)
+signal.signal(signal.SIGALRM, alarm_handler)
 
 
 def shuffle_iteratable(it):
@@ -92,6 +99,7 @@
 
 _TAG_COLOR = {
     'FAILED': 'red',
+    'TIMEOUT': 'red',
     'PASSED': 'green',
     'START': 'gray',
     'WAITING': 'yellow',
@@ -154,24 +162,27 @@
 class Job(object):
   """Manages one job."""
 
-  def __init__(self, spec, bin_hash, newline_on_success):
+  def __init__(self, spec, bin_hash, newline_on_success, travis):
     self._spec = spec
     self._bin_hash = bin_hash
     self._tempfile = tempfile.TemporaryFile()
     env = os.environ.copy()
     for k, v in spec.environ.iteritems():
       env[k] = v
+    self._start = time.time()
     self._process = subprocess.Popen(args=spec.cmdline,
                                      stderr=subprocess.STDOUT,
                                      stdout=self._tempfile,
                                      env=env)
     self._state = _RUNNING
     self._newline_on_success = newline_on_success
-    message('START', spec.shortname)
+    self._travis = travis
+    message('START', spec.shortname, do_newline=self._travis)
 
   def state(self, update_cache):
     """Poll current state of the job. Prints messages at completion."""
     if self._state == _RUNNING and self._process.poll() is not None:
+      elapsed = time.time() - self._start
       if self._process.returncode != 0:
         self._state = _FAILURE
         self._tempfile.seek(0)
@@ -180,10 +191,13 @@
             self._spec.shortname, self._process.returncode), stdout)
       else:
         self._state = _SUCCESS
-        message('PASSED', self._spec.shortname,
-                do_newline=self._newline_on_success)
+        message('PASSED', '%s [time=%.1fsec]' % (self._spec.shortname, elapsed),
+                do_newline=self._newline_on_success or self._travis)
         if self._bin_hash:
           update_cache.finished(self._spec.identity(), self._bin_hash)
+    elif self._state == _RUNNING and time.time() - self._start > 300:
+      message('TIMEOUT', self._spec.shortname, do_newline=self._travis)
+      self.kill()
     return self._state
 
   def kill(self):
@@ -195,7 +209,7 @@
 class Jobset(object):
   """Manages one run of jobs."""
 
-  def __init__(self, check_cancelled, maxjobs, newline_on_success, cache):
+  def __init__(self, check_cancelled, maxjobs, newline_on_success, travis, cache):
     self._running = set()
     self._check_cancelled = check_cancelled
     self._cancelled = False
@@ -203,6 +217,7 @@
     self._completed = 0
     self._maxjobs = maxjobs
     self._newline_on_success = newline_on_success
+    self._travis = travis
     self._cache = cache
 
   def start(self, spec):
@@ -224,7 +239,8 @@
     if should_run:
       self._running.add(Job(spec,
                             bin_hash,
-                            self._newline_on_success))
+                            self._newline_on_success,
+                            self._travis))
     return True
 
   def reap(self):
@@ -235,13 +251,19 @@
         st = job.state(self._cache)
         if st == _RUNNING: continue
         if st == _FAILURE: self._failures += 1
+        if st == _KILLED: self._failures += 1
         dead.add(job)
       for job in dead:
         self._completed += 1
         self._running.remove(job)
       if dead: return
-      message('WAITING', '%d jobs running, %d complete, %d failed' % (
-          len(self._running), self._completed, self._failures))
+      if (not self._travis):
+        message('WAITING', '%d jobs running, %d complete, %d failed' % (
+            len(self._running), self._completed, self._failures))
+      global have_alarm
+      if not have_alarm:
+        have_alarm = True
+        signal.alarm(10)
       signal.pause()
 
   def cancelled(self):
@@ -277,12 +299,17 @@
         check_cancelled=_never_cancelled,
         maxjobs=None,
         newline_on_success=False,
+        travis=False,
         cache=None):
   js = Jobset(check_cancelled,
               maxjobs if maxjobs is not None else _DEFAULT_MAX_JOBS,
-              newline_on_success,
+              newline_on_success, travis,
               cache if cache is not None else NoCache())
-  for cmdline in shuffle_iteratable(cmdlines):
+  if not travis:
+    cmdlines = shuffle_iteratable(cmdlines)
+  else:
+    cmdlines = sorted(cmdlines, key=lambda x: x.shortname)
+  for cmdline in cmdlines:
     if not js.start(cmdline):
       break
   return js.finish()
diff --git a/tools/run_tests/run_python.sh b/tools/run_tests/run_python.sh
index fe40b51..06ddb8e 100755
--- a/tools/run_tests/run_python.sh
+++ b/tools/run_tests/run_python.sh
@@ -37,7 +37,8 @@
 export LD_LIBRARY_PATH=$root/libs/opt
 source python2.7_virtual_environment/bin/activate
 # TODO(issue 215): Properly itemize these in run_tests.py so that they can be parallelized.
-python2.7 -B test/compiler/python_plugin_test.py
+# TODO(atash): Enable dynamic unused port discovery for this test.
+python2.7 -B test/compiler/python_plugin_test.py --build_mode=opt
 python2.7 -B -m grpc._adapter._blocking_invocation_inline_service_test
 python2.7 -B -m grpc._adapter._c_test
 python2.7 -B -m grpc._adapter._event_invocation_synchronous_event_service_test
@@ -45,6 +46,7 @@
 python2.7 -B -m grpc._adapter._links_test
 python2.7 -B -m grpc._adapter._lonely_rear_link_test
 python2.7 -B -m grpc._adapter._low_test
+python2.7 -B -m grpc.early_adopter.implementations_test
 python2.7 -B -m grpc.framework.assembly.implementations_test
 python2.7 -B -m grpc.framework.base.packets.implementations_test
 python2.7 -B -m grpc.framework.face.blocking_invocation_inline_service_test
diff --git a/tools/run_tests/run_ruby.sh b/tools/run_tests/run_ruby.sh
new file mode 100755
index 0000000..b82ce52
--- /dev/null
+++ b/tools/run_tests/run_ruby.sh
@@ -0,0 +1,36 @@
+#!/bin/bash
+# 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.
+
+set -ex
+
+# change to grpc repo root
+cd $(dirname $0)/../../src/ruby
+
+rake
diff --git a/tools/run_tests/run_tests.py b/tools/run_tests/run_tests.py
index 7732466..b737032 100755
--- a/tools/run_tests/run_tests.py
+++ b/tools/run_tests/run_tests.py
@@ -44,6 +44,10 @@
 import watch_dirs
 
 
+ROOT = os.path.abspath(os.path.join(os.path.dirname(sys.argv[0]), '../..'))
+os.chdir(ROOT)
+
+
 # SimpleConfig: just compile with CONFIG=config, and run the binary to test
 class SimpleConfig(object):
 
@@ -83,14 +87,14 @@
     self.make_target = make_target
     with open('tools/run_tests/tests.json') as f:
       js = json.load(f)
-      self.binaries = [tgt['name']
-                       for tgt in js
-                       if tgt['language'] == test_lang]
+      self.binaries = [tgt for tgt in js if tgt['language'] == test_lang]
 
-  def test_specs(self, config):
+  def test_specs(self, config, travis):
     out = []
-    for name in self.binaries:
-      binary = 'bins/%s/%s' % (config.build_config, name)
+    for target in self.binaries:
+      if travis and target['flaky']:
+        continue
+      binary = 'bins/%s/%s' % (config.build_config, target['name'])
       out.append(config.job_spec(binary, [binary]))
     return out
 
@@ -103,7 +107,7 @@
 
 class NodeLanguage(object):
 
-  def test_specs(self, config):
+  def test_specs(self, config, travis):
     return [config.job_spec('tools/run_tests/run_node.sh', None)]
 
   def make_targets(self):
@@ -115,7 +119,7 @@
 
 class PhpLanguage(object):
 
-  def test_specs(self, config):
+  def test_specs(self, config, travis):
     return [config.job_spec('src/php/bin/run_tests.sh', None)]
 
   def make_targets(self):
@@ -127,7 +131,7 @@
 
 class PythonLanguage(object):
 
-  def test_specs(self, config):
+  def test_specs(self, config, travis):
     return [config.job_spec('tools/run_tests/run_python.sh', None)]
 
   def make_targets(self):
@@ -136,6 +140,17 @@
   def build_steps(self):
     return [['tools/run_tests/build_python.sh']]
 
+class RubyLanguage(object):
+
+  def test_specs(self, config, travis):
+    return [config.job_spec('tools/run_tests/run_ruby.sh', None)]
+
+  def make_targets(self):
+    return ['static_c']
+
+  def build_steps(self):
+    return [['tools/run_tests/build_ruby.sh']]
+
 
 # different configurations we can run under
 _CONFIGS = {
@@ -160,6 +175,7 @@
     'node': NodeLanguage(),
     'php': PhpLanguage(),
     'python': PythonLanguage(),
+    'ruby': RubyLanguage()
     }
 
 # parse command line
@@ -171,10 +187,15 @@
 argp.add_argument('-n', '--runs_per_test', default=1, type=int)
 argp.add_argument('-r', '--regex', default='.*', type=str)
 argp.add_argument('-j', '--jobs', default=1000, type=int)
+argp.add_argument('-s', '--slowdown', default=1.0, type=float)
 argp.add_argument('-f', '--forever',
                   default=False,
                   action='store_const',
                   const=True)
+argp.add_argument('-t', '--travis',
+                  default=False,
+                  action='store_const',
+                  const=True)
 argp.add_argument('--newline_on_success',
                   default=False,
                   action='store_const',
@@ -196,6 +217,7 @@
 languages = set(_LANGUAGES[l] for l in args.language)
 build_steps = [jobset.JobSpec(['make',
                                '-j', '%d' % (multiprocessing.cpu_count() + 1),
+                               'EXTRA_DEFINES=GRPC_TEST_SLOWDOWN_MACHINE_FACTOR=%f' % args.slowdown,
                                'CONFIG=%s' % cfg] + list(set(
                                    itertools.chain.from_iterable(
                                        l.make_targets() for l in languages))))
@@ -207,7 +229,7 @@
     spec
     for config in run_configs
     for language in args.language
-    for spec in _LANGUAGES[language].test_specs(config)
+    for spec in _LANGUAGES[language].test_specs(config, args.travis)
     if re.search(args.regex, spec.shortname))
 
 runs_per_test = args.runs_per_test
@@ -232,6 +254,7 @@
 
   def finished(self, cmdline, bin_hash):
     self._last_successful_run[cmdline] = bin_hash
+    self.save()
 
   def dump(self):
     return [{'cmdline': k, 'hash': v}
@@ -250,17 +273,18 @@
         self.parse(json.loads(f.read()))
 
 
-def _build_and_run(check_cancelled, newline_on_success, cache):
+def _build_and_run(check_cancelled, newline_on_success, travis, cache):
   """Do one pass of building & running tests."""
   # build latest sequentially
-  if not jobset.run(build_steps, maxjobs=1):
+  if not jobset.run(build_steps, maxjobs=1,
+                    newline_on_success=newline_on_success, travis=travis):
     return 1
 
   # run all the tests
   all_runs = itertools.chain.from_iterable(
       itertools.repeat(one_run, runs_per_test))
   if not jobset.run(all_runs, check_cancelled,
-                    newline_on_success=newline_on_success,
+                    newline_on_success=newline_on_success, travis=travis,
                     maxjobs=min(args.jobs, min(c.maxjobs for c in run_configs)),
                     cache=cache):
     return 2
@@ -286,16 +310,15 @@
                      'All tests are now passing properly',
                      do_newline=True)
     jobset.message('IDLE', 'No change detected')
-    test_cache.save()
     while not have_files_changed():
       time.sleep(1)
 else:
   result = _build_and_run(check_cancelled=lambda: False,
                           newline_on_success=args.newline_on_success,
+                          travis=args.travis,
                           cache=test_cache)
   if result == 0:
     jobset.message('SUCCESS', 'All tests passed', do_newline=True)
   else:
     jobset.message('FAILED', 'Some tests failed', do_newline=True)
-  test_cache.save()
   sys.exit(result)
diff --git a/tools/run_tests/tests.json b/tools/run_tests/tests.json
index 84f830c..772856b 100644
--- a/tools/run_tests/tests.json
+++ b/tools/run_tests/tests.json
@@ -2,1646 +2,2062 @@
 
 [
   {
+    "flaky": false, 
     "language": "c", 
     "name": "alarm_heap_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "alarm_list_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "alarm_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "alpn_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "bin_encoder_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "census_hash_table_test"
   }, 
   {
+    "flaky": true, 
     "language": "c", 
     "name": "census_statistics_multiple_writers_circular_buffer_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "census_statistics_multiple_writers_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "census_statistics_performance_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "census_statistics_quick_test"
   }, 
   {
+    "flaky": true, 
     "language": "c", 
     "name": "census_statistics_small_log_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "census_stub_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "census_window_stats_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_status_conversion_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_stream_encoder_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_stream_map_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_transport_end2end_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "dualstack_socket_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "echo_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "fd_posix_test"
   }, 
   {
+    "flaky": true, 
     "language": "c", 
     "name": "fling_stream_test"
   }, 
   {
+    "flaky": true, 
     "language": "c", 
     "name": "fling_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "gpr_cancellable_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "gpr_cmdline_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "gpr_env_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "gpr_file_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "gpr_histogram_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "gpr_host_port_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "gpr_log_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "gpr_slice_buffer_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "gpr_slice_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "gpr_string_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "gpr_sync_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "gpr_thd_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "gpr_time_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "gpr_useful_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "grpc_base64_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "grpc_byte_buffer_reader_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "grpc_channel_stack_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "grpc_completion_queue_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "grpc_credentials_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "grpc_json_token_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "grpc_stream_op_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "hpack_parser_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "hpack_table_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "httpcli_format_request_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "httpcli_parser_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "json_rewrite_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "json_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "lame_client_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "message_compress_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "metadata_buffer_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "multi_init_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "murmur_hash_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "no_server_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "poll_kick_posix_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "resolve_address_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "secure_endpoint_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "sockaddr_utils_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "tcp_client_posix_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "tcp_posix_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "tcp_server_posix_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "time_averaged_stats_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "time_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "timeout_encoding_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "transport_metadata_test"
   }, 
   {
+    "flaky": false, 
+    "language": "c", 
+    "name": "transport_security_test"
+  }, 
+  {
+    "flaky": false, 
     "language": "c++", 
     "name": "async_end2end_test"
   }, 
   {
+    "flaky": false, 
     "language": "c++", 
     "name": "channel_arguments_test"
   }, 
   {
+    "flaky": false, 
     "language": "c++", 
     "name": "credentials_test"
   }, 
   {
+    "flaky": false, 
     "language": "c++", 
     "name": "end2end_test"
   }, 
   {
+    "flaky": false, 
     "language": "c++", 
     "name": "interop_test"
   }, 
   {
+    "flaky": false, 
     "language": "c++", 
     "name": "pubsub_publisher_test"
   }, 
   {
+    "flaky": false, 
     "language": "c++", 
     "name": "pubsub_subscriber_test"
   }, 
   {
+    "flaky": false, 
     "language": "c++", 
     "name": "status_test"
   }, 
   {
+    "flaky": false, 
     "language": "c++", 
     "name": "thread_pool_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fake_security_cancel_after_accept_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fake_security_cancel_after_accept_and_writes_closed_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fake_security_cancel_after_invoke_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fake_security_cancel_before_invoke_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fake_security_cancel_in_a_vacuum_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fake_security_census_simple_request_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fake_security_disappearing_server_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fake_security_early_server_shutdown_finishes_inflight_calls_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fake_security_early_server_shutdown_finishes_tags_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fake_security_empty_batch_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fake_security_graceful_server_shutdown_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fake_security_invoke_large_request_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fake_security_max_concurrent_streams_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fake_security_no_op_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fake_security_ping_pong_streaming_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fake_security_request_response_with_binary_metadata_and_payload_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fake_security_request_response_with_metadata_and_payload_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fake_security_request_response_with_payload_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fake_security_request_with_large_metadata_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fake_security_request_with_payload_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fake_security_simple_delayed_request_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fake_security_simple_request_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fake_security_thread_stress_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fake_security_writes_done_hangs_with_pending_read_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fake_security_cancel_after_accept_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fake_security_cancel_after_accept_and_writes_closed_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fake_security_cancel_after_invoke_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fake_security_cancel_before_invoke_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fake_security_cancel_in_a_vacuum_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fake_security_census_simple_request_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fake_security_disappearing_server_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fake_security_early_server_shutdown_finishes_inflight_calls_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fake_security_early_server_shutdown_finishes_tags_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fake_security_graceful_server_shutdown_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fake_security_invoke_large_request_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fake_security_max_concurrent_streams_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fake_security_no_op_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fake_security_ping_pong_streaming_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fake_security_request_response_with_binary_metadata_and_payload_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fake_security_request_response_with_metadata_and_payload_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fake_security_request_response_with_payload_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fake_security_request_response_with_trailing_metadata_and_payload_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fake_security_request_with_large_metadata_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fake_security_request_with_payload_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fake_security_simple_delayed_request_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fake_security_simple_request_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fake_security_thread_stress_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fake_security_writes_done_hangs_with_pending_read_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_cancel_after_accept_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_cancel_after_accept_and_writes_closed_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_cancel_after_invoke_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_cancel_before_invoke_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_cancel_in_a_vacuum_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_census_simple_request_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_disappearing_server_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_early_server_shutdown_finishes_inflight_calls_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_early_server_shutdown_finishes_tags_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_empty_batch_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_graceful_server_shutdown_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_invoke_large_request_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_max_concurrent_streams_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_no_op_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_ping_pong_streaming_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_request_response_with_binary_metadata_and_payload_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_request_response_with_metadata_and_payload_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_request_response_with_payload_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_request_with_large_metadata_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_request_with_payload_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_simple_delayed_request_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_simple_request_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_thread_stress_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_writes_done_hangs_with_pending_read_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_cancel_after_accept_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_cancel_after_accept_and_writes_closed_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_cancel_after_invoke_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_cancel_before_invoke_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_cancel_in_a_vacuum_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_census_simple_request_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_disappearing_server_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_early_server_shutdown_finishes_inflight_calls_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_early_server_shutdown_finishes_tags_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_graceful_server_shutdown_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_invoke_large_request_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_max_concurrent_streams_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_no_op_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_ping_pong_streaming_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_request_response_with_binary_metadata_and_payload_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_request_response_with_metadata_and_payload_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_request_response_with_payload_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_request_response_with_trailing_metadata_and_payload_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_request_with_large_metadata_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_request_with_payload_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_simple_delayed_request_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_simple_request_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_thread_stress_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_writes_done_hangs_with_pending_read_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_cancel_after_accept_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_cancel_after_accept_and_writes_closed_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_cancel_after_invoke_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_cancel_before_invoke_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_cancel_in_a_vacuum_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_census_simple_request_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_disappearing_server_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_early_server_shutdown_finishes_inflight_calls_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_early_server_shutdown_finishes_tags_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_empty_batch_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_graceful_server_shutdown_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_invoke_large_request_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_max_concurrent_streams_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_no_op_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_ping_pong_streaming_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_request_response_with_binary_metadata_and_payload_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_request_response_with_metadata_and_payload_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_request_response_with_payload_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_request_with_large_metadata_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_request_with_payload_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_simple_delayed_request_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_simple_request_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_thread_stress_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_writes_done_hangs_with_pending_read_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_cancel_after_accept_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_cancel_after_accept_and_writes_closed_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_cancel_after_invoke_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_cancel_before_invoke_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_cancel_in_a_vacuum_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_census_simple_request_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_disappearing_server_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_early_server_shutdown_finishes_inflight_calls_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_early_server_shutdown_finishes_tags_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_graceful_server_shutdown_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_invoke_large_request_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_max_concurrent_streams_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_no_op_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_ping_pong_streaming_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_request_response_with_binary_metadata_and_payload_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_request_response_with_metadata_and_payload_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_request_response_with_payload_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_request_response_with_trailing_metadata_and_payload_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_request_with_large_metadata_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_request_with_payload_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_simple_delayed_request_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_simple_request_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_thread_stress_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_fullstack_uds_writes_done_hangs_with_pending_read_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_cancel_after_accept_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_cancel_after_accept_and_writes_closed_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_cancel_after_invoke_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_cancel_before_invoke_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_cancel_in_a_vacuum_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_census_simple_request_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_disappearing_server_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_inflight_calls_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_tags_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_empty_batch_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_graceful_server_shutdown_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_invoke_large_request_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_max_concurrent_streams_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_no_op_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_ping_pong_streaming_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_request_response_with_binary_metadata_and_payload_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_request_response_with_metadata_and_payload_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_request_response_with_payload_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_request_with_large_metadata_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_request_with_payload_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_simple_delayed_request_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_simple_request_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_thread_stress_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_writes_done_hangs_with_pending_read_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_cancel_after_accept_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_cancel_after_accept_and_writes_closed_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_cancel_after_invoke_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_cancel_before_invoke_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_cancel_in_a_vacuum_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_census_simple_request_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_disappearing_server_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_inflight_calls_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_tags_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_graceful_server_shutdown_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_invoke_large_request_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_max_concurrent_streams_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_no_op_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_ping_pong_streaming_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_request_response_with_binary_metadata_and_payload_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_request_response_with_metadata_and_payload_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_request_response_with_payload_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_request_response_with_trailing_metadata_and_payload_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_request_with_large_metadata_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_request_with_payload_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_simple_delayed_request_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_simple_request_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_thread_stress_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_fullstack_writes_done_hangs_with_pending_read_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_accept_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_accept_and_writes_closed_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_invoke_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_with_oauth2_fullstack_cancel_before_invoke_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_with_oauth2_fullstack_cancel_in_a_vacuum_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_with_oauth2_fullstack_census_simple_request_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_with_oauth2_fullstack_disappearing_server_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_inflight_calls_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_tags_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_with_oauth2_fullstack_empty_batch_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_with_oauth2_fullstack_graceful_server_shutdown_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_with_oauth2_fullstack_invoke_large_request_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_with_oauth2_fullstack_max_concurrent_streams_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_with_oauth2_fullstack_no_op_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_with_oauth2_fullstack_ping_pong_streaming_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_binary_metadata_and_payload_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_metadata_and_payload_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_payload_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_with_oauth2_fullstack_request_with_large_metadata_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_with_oauth2_fullstack_request_with_payload_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_with_oauth2_fullstack_simple_delayed_request_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_with_oauth2_fullstack_simple_request_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_with_oauth2_fullstack_thread_stress_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_with_oauth2_fullstack_writes_done_hangs_with_pending_read_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_accept_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_accept_and_writes_closed_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_invoke_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_with_oauth2_fullstack_cancel_before_invoke_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_with_oauth2_fullstack_cancel_in_a_vacuum_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_with_oauth2_fullstack_census_simple_request_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_with_oauth2_fullstack_disappearing_server_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_inflight_calls_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_tags_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_with_oauth2_fullstack_graceful_server_shutdown_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_with_oauth2_fullstack_invoke_large_request_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_with_oauth2_fullstack_max_concurrent_streams_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_with_oauth2_fullstack_no_op_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_with_oauth2_fullstack_ping_pong_streaming_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_binary_metadata_and_payload_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_metadata_and_payload_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_payload_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_trailing_metadata_and_payload_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_with_oauth2_fullstack_request_with_large_metadata_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_with_oauth2_fullstack_request_with_payload_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_with_oauth2_fullstack_simple_delayed_request_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_with_oauth2_fullstack_simple_request_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_with_oauth2_fullstack_thread_stress_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_simple_ssl_with_oauth2_fullstack_writes_done_hangs_with_pending_read_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_cancel_after_accept_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_cancel_after_accept_and_writes_closed_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_cancel_after_invoke_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_cancel_before_invoke_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_cancel_in_a_vacuum_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_census_simple_request_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_disappearing_server_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_early_server_shutdown_finishes_inflight_calls_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_early_server_shutdown_finishes_tags_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_empty_batch_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_graceful_server_shutdown_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_invoke_large_request_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_max_concurrent_streams_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_no_op_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_ping_pong_streaming_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_request_response_with_binary_metadata_and_payload_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_request_response_with_metadata_and_payload_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_request_response_with_payload_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_request_with_large_metadata_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_request_with_payload_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_simple_delayed_request_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_simple_request_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_thread_stress_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_writes_done_hangs_with_pending_read_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_cancel_after_accept_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_cancel_after_accept_and_writes_closed_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_cancel_after_invoke_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_cancel_before_invoke_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_cancel_in_a_vacuum_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_census_simple_request_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_disappearing_server_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_early_server_shutdown_finishes_inflight_calls_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_early_server_shutdown_finishes_tags_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_graceful_server_shutdown_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_invoke_large_request_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_max_concurrent_streams_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_no_op_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_ping_pong_streaming_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_request_response_with_binary_metadata_and_payload_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_request_response_with_metadata_and_payload_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_request_response_with_payload_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_request_response_with_trailing_metadata_and_payload_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_request_with_large_metadata_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_request_with_payload_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_simple_delayed_request_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_simple_request_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_thread_stress_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_writes_done_hangs_with_pending_read_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_and_writes_closed_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_one_byte_at_a_time_cancel_after_invoke_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_one_byte_at_a_time_cancel_before_invoke_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_one_byte_at_a_time_cancel_in_a_vacuum_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_one_byte_at_a_time_census_simple_request_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_one_byte_at_a_time_disappearing_server_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_inflight_calls_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_tags_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_one_byte_at_a_time_empty_batch_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_one_byte_at_a_time_graceful_server_shutdown_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_one_byte_at_a_time_invoke_large_request_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_one_byte_at_a_time_max_concurrent_streams_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_one_byte_at_a_time_no_op_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_one_byte_at_a_time_ping_pong_streaming_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_one_byte_at_a_time_request_response_with_binary_metadata_and_payload_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_one_byte_at_a_time_request_response_with_metadata_and_payload_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_one_byte_at_a_time_request_response_with_payload_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_one_byte_at_a_time_request_with_large_metadata_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_one_byte_at_a_time_request_with_payload_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_one_byte_at_a_time_simple_delayed_request_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_one_byte_at_a_time_simple_request_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_one_byte_at_a_time_thread_stress_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_one_byte_at_a_time_writes_done_hangs_with_pending_read_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_and_writes_closed_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_one_byte_at_a_time_cancel_after_invoke_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_one_byte_at_a_time_cancel_before_invoke_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_one_byte_at_a_time_cancel_in_a_vacuum_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_one_byte_at_a_time_census_simple_request_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_one_byte_at_a_time_disappearing_server_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_inflight_calls_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_tags_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_one_byte_at_a_time_graceful_server_shutdown_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_one_byte_at_a_time_invoke_large_request_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_one_byte_at_a_time_max_concurrent_streams_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_one_byte_at_a_time_no_op_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_one_byte_at_a_time_ping_pong_streaming_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_one_byte_at_a_time_request_response_with_binary_metadata_and_payload_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_one_byte_at_a_time_request_response_with_metadata_and_payload_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_one_byte_at_a_time_request_response_with_payload_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_one_byte_at_a_time_request_response_with_trailing_metadata_and_payload_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_one_byte_at_a_time_request_with_large_metadata_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_one_byte_at_a_time_request_with_payload_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_one_byte_at_a_time_simple_delayed_request_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_one_byte_at_a_time_simple_request_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_one_byte_at_a_time_thread_stress_legacy_test"
   }, 
   {
+    "flaky": false, 
     "language": "c", 
     "name": "chttp2_socket_pair_one_byte_at_a_time_writes_done_hangs_with_pending_read_legacy_test"
   }
diff --git a/tools/tsan_suppressions.txt b/tools/tsan_suppressions.txt
index 23d57f9..65e7e2e 100644
--- a/tools/tsan_suppressions.txt
+++ b/tools/tsan_suppressions.txt
@@ -1,2 +1,8 @@
 # OPENSSL_cleanse does racy access to a global
 race:OPENSSL_cleanse
+race:cleanse_ctr
+# these are legitimate races in OpenSSL, and it appears those folks are looking at it
+# https://www.mail-archive.com/openssl-dev@openssl.org/msg09019.html
+race:ssleay_rand_add
+race:ssleay_rand_bytes
+
diff --git a/vsprojects/vs2013/Grpc.mak b/vsprojects/vs2013/Grpc.mak
index 9272d07..203c787 100644
--- a/vsprojects/vs2013/Grpc.mak
+++ b/vsprojects/vs2013/Grpc.mak
@@ -53,10 +53,10 @@
 $(OUT_DIR):
 	mkdir $(OUT_DIR)
 
-buildtests: 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_stats_store_test.exe census_stub_test.exe census_trace_store_test.exe census_window_stats_test.exe chttp2_status_conversion_test.exe chttp2_stream_encoder_test.exe chttp2_stream_map_test.exe chttp2_transport_end2end_test.exe dualstack_socket_test.exe echo_test.exe fd_posix_test.exe fling_stream_test.exe fling_test.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_useful_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_test.exe json_test.exe lame_client_test.exe message_compress_test.exe metadata_buffer_test.exe multi_init_test.exe murmur_hash_test.exe no_server_test.exe poll_kick_posix_test.exe resolve_address_test.exe secure_endpoint_test.exe sockaddr_utils_test.exe tcp_client_posix_test.exe tcp_posix_test.exe tcp_server_posix_test.exe time_averaged_stats_test.exe time_test.exe timeout_encoding_test.exe transport_metadata_test.exe 
+buildtests: 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_stats_store_test.exe census_stub_test.exe census_trace_store_test.exe census_window_stats_test.exe chttp2_status_conversion_test.exe chttp2_stream_encoder_test.exe chttp2_stream_map_test.exe chttp2_transport_end2end_test.exe dualstack_socket_test.exe echo_test.exe fd_posix_test.exe fling_stream_test.exe fling_test.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_useful_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_test.exe json_test.exe lame_client_test.exe message_compress_test.exe metadata_buffer_test.exe multi_init_test.exe murmur_hash_test.exe no_server_test.exe poll_kick_posix_test.exe resolve_address_test.exe secure_endpoint_test.exe sockaddr_utils_test.exe tcp_client_posix_test.exe tcp_posix_test.exe tcp_server_posix_test.exe time_averaged_stats_test.exe time_test.exe timeout_encoding_test.exe transport_metadata_test.exe transport_security_test.exe 
 	echo All tests built.
 
-test: alarm_heap_test alarm_list_test alarm_test alpn_test bin_encoder_test census_hash_table_test census_statistics_multiple_writers_circular_buffer_test census_statistics_multiple_writers_test census_statistics_performance_test census_statistics_quick_test census_statistics_small_log_test census_stats_store_test census_stub_test census_trace_store_test census_window_stats_test chttp2_status_conversion_test chttp2_stream_encoder_test chttp2_stream_map_test chttp2_transport_end2end_test dualstack_socket_test echo_test fd_posix_test fling_stream_test fling_test gpr_cancellable_test gpr_cmdline_test gpr_env_test gpr_file_test gpr_histogram_test gpr_host_port_test gpr_log_test gpr_slice_buffer_test gpr_slice_test gpr_string_test gpr_sync_test gpr_thd_test gpr_time_test gpr_useful_test grpc_base64_test grpc_byte_buffer_reader_test grpc_channel_stack_test grpc_completion_queue_test grpc_credentials_test grpc_json_token_test grpc_stream_op_test hpack_parser_test hpack_table_test httpcli_format_request_test httpcli_parser_test httpcli_test json_rewrite_test json_test lame_client_test message_compress_test metadata_buffer_test multi_init_test murmur_hash_test no_server_test poll_kick_posix_test resolve_address_test secure_endpoint_test sockaddr_utils_test tcp_client_posix_test tcp_posix_test tcp_server_posix_test time_averaged_stats_test time_test timeout_encoding_test transport_metadata_test 
+test: alarm_heap_test alarm_list_test alarm_test alpn_test bin_encoder_test census_hash_table_test census_statistics_multiple_writers_circular_buffer_test census_statistics_multiple_writers_test census_statistics_performance_test census_statistics_quick_test census_statistics_small_log_test census_stats_store_test census_stub_test census_trace_store_test census_window_stats_test chttp2_status_conversion_test chttp2_stream_encoder_test chttp2_stream_map_test chttp2_transport_end2end_test dualstack_socket_test echo_test fd_posix_test fling_stream_test fling_test gpr_cancellable_test gpr_cmdline_test gpr_env_test gpr_file_test gpr_histogram_test gpr_host_port_test gpr_log_test gpr_slice_buffer_test gpr_slice_test gpr_string_test gpr_sync_test gpr_thd_test gpr_time_test gpr_useful_test grpc_base64_test grpc_byte_buffer_reader_test grpc_channel_stack_test grpc_completion_queue_test grpc_credentials_test grpc_json_token_test grpc_stream_op_test hpack_parser_test hpack_table_test httpcli_format_request_test httpcli_parser_test httpcli_test json_rewrite_test json_test lame_client_test message_compress_test metadata_buffer_test multi_init_test murmur_hash_test no_server_test poll_kick_posix_test resolve_address_test secure_endpoint_test sockaddr_utils_test tcp_client_posix_test tcp_posix_test tcp_server_posix_test time_averaged_stats_test time_test timeout_encoding_test transport_metadata_test transport_security_test 
 	echo All tests ran.
 
 test_gpr: gpr_cancellable_test gpr_cmdline_test gpr_env_test gpr_file_test gpr_histogram_test gpr_host_port_test gpr_log_test gpr_slice_buffer_test gpr_slice_test gpr_string_test gpr_sync_test gpr_thd_test gpr_time_test gpr_useful_test 
@@ -702,3 +702,11 @@
 	echo Running transport_metadata_test
 	$(OUT_DIR)\transport_metadata_test.exe
 
+transport_security_test.exe: grpc_test_util
+	echo Building transport_security_test
+	$(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\tsi\transport_security_test.c 
+	$(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\transport_security_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\transport_security_test.obj 
+transport_security_test: transport_security_test.exe
+	echo Running transport_security_test
+	$(OUT_DIR)\transport_security_test.exe
+