Merge pull request #5754 from ctiller/new_boring_ssl

Reference github boringssl, move to chromium-stable branch head
diff --git a/BUILD b/BUILD
index 0e9f37a..514aea8 100644
--- a/BUILD
+++ b/BUILD
@@ -45,6 +45,7 @@
   name = "gpr",
   srcs = [
     "src/core/profiling/timers.h",
+    "src/core/support/backoff.h",
     "src/core/support/block_annotate.h",
     "src/core/support/env.h",
     "src/core/support/load_file.h",
@@ -59,6 +60,7 @@
     "src/core/profiling/stap_timers.c",
     "src/core/support/alloc.c",
     "src/core/support/avl.c",
+    "src/core/support/backoff.c",
     "src/core/support/cmdline.c",
     "src/core/support/cpu_iphone.c",
     "src/core/support/cpu_linux.c",
@@ -156,8 +158,10 @@
   name = "grpc",
   srcs = [
     "src/core/census/grpc_filter.h",
+    "src/core/census/grpc_plugin.h",
     "src/core/channel/channel_args.h",
     "src/core/channel/channel_stack.h",
+    "src/core/channel/channel_stack_builder.h",
     "src/core/channel/client_channel.h",
     "src/core/channel/client_uchannel.h",
     "src/core/channel/compress_filter.h",
@@ -237,9 +241,12 @@
     "src/core/surface/call.h",
     "src/core/surface/call_test_only.h",
     "src/core/surface/channel.h",
+    "src/core/surface/channel_init.h",
+    "src/core/surface/channel_stack_type.h",
     "src/core/surface/completion_queue.h",
     "src/core/surface/event_string.h",
     "src/core/surface/init.h",
+    "src/core/surface/lame_client.h",
     "src/core/surface/server.h",
     "src/core/surface/surface_trace.h",
     "src/core/transport/byte_stream.h",
@@ -293,8 +300,10 @@
     "third_party/nanopb/pb_encode.h",
     "src/core/census/grpc_context.c",
     "src/core/census/grpc_filter.c",
+    "src/core/census/grpc_plugin.c",
     "src/core/channel/channel_args.c",
     "src/core/channel/channel_stack.c",
+    "src/core/channel/channel_stack_builder.c",
     "src/core/channel/client_channel.c",
     "src/core/channel/client_uchannel.c",
     "src/core/channel/compress_filter.c",
@@ -382,7 +391,9 @@
     "src/core/surface/channel.c",
     "src/core/surface/channel_connectivity.c",
     "src/core/surface/channel_create.c",
+    "src/core/surface/channel_init.c",
     "src/core/surface/channel_ping.c",
+    "src/core/surface/channel_stack_type.c",
     "src/core/surface/completion_queue.c",
     "src/core/surface/event_string.c",
     "src/core/surface/init.c",
@@ -390,7 +401,6 @@
     "src/core/surface/metadata_array.c",
     "src/core/surface/server.c",
     "src/core/surface/server_chttp2.c",
-    "src/core/surface/server_create.c",
     "src/core/surface/validate_metadata.c",
     "src/core/surface/version.c",
     "src/core/transport/byte_stream.c",
@@ -454,17 +464,17 @@
   ],
   hdrs = [
     "include/grpc/grpc_security.h",
+    "include/grpc/byte_buffer.h",
+    "include/grpc/byte_buffer_reader.h",
+    "include/grpc/compression.h",
+    "include/grpc/grpc.h",
+    "include/grpc/status.h",
     "include/grpc/impl/codegen/byte_buffer.h",
     "include/grpc/impl/codegen/compression_types.h",
     "include/grpc/impl/codegen/connectivity_state.h",
     "include/grpc/impl/codegen/grpc_types.h",
     "include/grpc/impl/codegen/propagation_bits.h",
     "include/grpc/impl/codegen/status.h",
-    "include/grpc/byte_buffer.h",
-    "include/grpc/byte_buffer_reader.h",
-    "include/grpc/compression.h",
-    "include/grpc/grpc.h",
-    "include/grpc/status.h",
     "include/grpc/census.h",
   ],
   includes = [
@@ -483,11 +493,49 @@
 
 
 cc_library(
+  name = "grpc_codegen_lib",
+  srcs = [
+  ],
+  hdrs = [
+    "include/grpc/impl/codegen/alloc.h",
+    "include/grpc/impl/codegen/atm.h",
+    "include/grpc/impl/codegen/atm_gcc_atomic.h",
+    "include/grpc/impl/codegen/atm_gcc_sync.h",
+    "include/grpc/impl/codegen/atm_win32.h",
+    "include/grpc/impl/codegen/log.h",
+    "include/grpc/impl/codegen/port_platform.h",
+    "include/grpc/impl/codegen/slice.h",
+    "include/grpc/impl/codegen/slice_buffer.h",
+    "include/grpc/impl/codegen/sync.h",
+    "include/grpc/impl/codegen/sync_generic.h",
+    "include/grpc/impl/codegen/sync_posix.h",
+    "include/grpc/impl/codegen/sync_win32.h",
+    "include/grpc/impl/codegen/time.h",
+    "include/grpc/impl/codegen/byte_buffer.h",
+    "include/grpc/impl/codegen/compression_types.h",
+    "include/grpc/impl/codegen/connectivity_state.h",
+    "include/grpc/impl/codegen/grpc_types.h",
+    "include/grpc/impl/codegen/propagation_bits.h",
+    "include/grpc/impl/codegen/status.h",
+  ],
+  includes = [
+    "include",
+    ".",
+  ],
+  deps = [
+    "//external:protobuf_compiler",
+  ],
+)
+
+
+cc_library(
   name = "grpc_unsecure",
   srcs = [
     "src/core/census/grpc_filter.h",
+    "src/core/census/grpc_plugin.h",
     "src/core/channel/channel_args.h",
     "src/core/channel/channel_stack.h",
+    "src/core/channel/channel_stack_builder.h",
     "src/core/channel/client_channel.h",
     "src/core/channel/client_uchannel.h",
     "src/core/channel/compress_filter.h",
@@ -567,9 +615,12 @@
     "src/core/surface/call.h",
     "src/core/surface/call_test_only.h",
     "src/core/surface/channel.h",
+    "src/core/surface/channel_init.h",
+    "src/core/surface/channel_stack_type.h",
     "src/core/surface/completion_queue.h",
     "src/core/surface/event_string.h",
     "src/core/surface/init.h",
+    "src/core/surface/lame_client.h",
     "src/core/surface/server.h",
     "src/core/surface/surface_trace.h",
     "src/core/transport/byte_stream.h",
@@ -610,8 +661,10 @@
     "src/core/surface/init_unsecure.c",
     "src/core/census/grpc_context.c",
     "src/core/census/grpc_filter.c",
+    "src/core/census/grpc_plugin.c",
     "src/core/channel/channel_args.c",
     "src/core/channel/channel_stack.c",
+    "src/core/channel/channel_stack_builder.c",
     "src/core/channel/client_channel.c",
     "src/core/channel/client_uchannel.c",
     "src/core/channel/compress_filter.c",
@@ -699,7 +752,9 @@
     "src/core/surface/channel.c",
     "src/core/surface/channel_connectivity.c",
     "src/core/surface/channel_create.c",
+    "src/core/surface/channel_init.c",
     "src/core/surface/channel_ping.c",
+    "src/core/surface/channel_stack_type.c",
     "src/core/surface/completion_queue.c",
     "src/core/surface/event_string.c",
     "src/core/surface/init.c",
@@ -707,7 +762,6 @@
     "src/core/surface/metadata_array.c",
     "src/core/surface/server.c",
     "src/core/surface/server_chttp2.c",
-    "src/core/surface/server_create.c",
     "src/core/surface/validate_metadata.c",
     "src/core/surface/version.c",
     "src/core/transport/byte_stream.c",
@@ -799,9 +853,11 @@
   name = "grpc++",
   srcs = [
     "src/cpp/client/secure_credentials.h",
+    "src/cpp/common/core_codegen.h",
     "src/cpp/common/secure_auth_context.h",
     "src/cpp/server/secure_server_credentials.h",
     "src/cpp/client/create_channel_internal.h",
+    "src/cpp/common/core_codegen.h",
     "src/cpp/common/create_auth_context.h",
     "src/cpp/server/dynamic_thread_pool.h",
     "src/cpp/server/thread_pool_interface.h",
@@ -818,11 +874,10 @@
     "src/cpp/client/credentials.cc",
     "src/cpp/client/generic_stub.cc",
     "src/cpp/client/insecure_credentials.cc",
-    "src/cpp/common/call.cc",
     "src/cpp/common/channel_arguments.cc",
     "src/cpp/common/completion_queue.cc",
+    "src/cpp/common/core_codegen.cc",
     "src/cpp/common/rpc_method.cc",
-    "src/cpp/proto/proto_utils.cc",
     "src/cpp/server/async_generic_service.cc",
     "src/cpp/server/create_default_thread_pool.cc",
     "src/cpp/server/dynamic_thread_pool.cc",
@@ -836,7 +891,7 @@
     "src/cpp/util/status.cc",
     "src/cpp/util/string_ref.cc",
     "src/cpp/util/time.cc",
-    "src/cpp/codegen/grpc_library.cc",
+    "src/cpp/codegen/codegen_init.cc",
   ],
   hdrs = [
     "include/grpc++/alarm.h",
@@ -894,6 +949,7 @@
     "include/grpc++/impl/codegen/completion_queue_tag.h",
     "include/grpc++/impl/codegen/config.h",
     "include/grpc++/impl/codegen/config_protobuf.h",
+    "include/grpc++/impl/codegen/core_codegen_interface.h",
     "include/grpc++/impl/codegen/grpc_library.h",
     "include/grpc++/impl/codegen/method_handler_impl.h",
     "include/grpc++/impl/codegen/proto_utils.h",
@@ -927,9 +983,78 @@
 
 
 cc_library(
+  name = "grpc++_codegen_lib",
+  srcs = [
+    "src/cpp/codegen/codegen_init.cc",
+  ],
+  hdrs = [
+    "include/grpc/impl/codegen/alloc.h",
+    "include/grpc/impl/codegen/atm.h",
+    "include/grpc/impl/codegen/atm_gcc_atomic.h",
+    "include/grpc/impl/codegen/atm_gcc_sync.h",
+    "include/grpc/impl/codegen/atm_win32.h",
+    "include/grpc/impl/codegen/log.h",
+    "include/grpc/impl/codegen/port_platform.h",
+    "include/grpc/impl/codegen/slice.h",
+    "include/grpc/impl/codegen/slice_buffer.h",
+    "include/grpc/impl/codegen/sync.h",
+    "include/grpc/impl/codegen/sync_generic.h",
+    "include/grpc/impl/codegen/sync_posix.h",
+    "include/grpc/impl/codegen/sync_win32.h",
+    "include/grpc/impl/codegen/time.h",
+    "include/grpc/impl/codegen/byte_buffer.h",
+    "include/grpc/impl/codegen/compression_types.h",
+    "include/grpc/impl/codegen/connectivity_state.h",
+    "include/grpc/impl/codegen/grpc_types.h",
+    "include/grpc/impl/codegen/propagation_bits.h",
+    "include/grpc/impl/codegen/status.h",
+    "include/grpc++/impl/codegen/async_stream.h",
+    "include/grpc++/impl/codegen/async_unary_call.h",
+    "include/grpc++/impl/codegen/call.h",
+    "include/grpc++/impl/codegen/call_hook.h",
+    "include/grpc++/impl/codegen/channel_interface.h",
+    "include/grpc++/impl/codegen/client_context.h",
+    "include/grpc++/impl/codegen/client_unary_call.h",
+    "include/grpc++/impl/codegen/completion_queue.h",
+    "include/grpc++/impl/codegen/completion_queue_tag.h",
+    "include/grpc++/impl/codegen/config.h",
+    "include/grpc++/impl/codegen/config_protobuf.h",
+    "include/grpc++/impl/codegen/core_codegen_interface.h",
+    "include/grpc++/impl/codegen/grpc_library.h",
+    "include/grpc++/impl/codegen/method_handler_impl.h",
+    "include/grpc++/impl/codegen/proto_utils.h",
+    "include/grpc++/impl/codegen/rpc_method.h",
+    "include/grpc++/impl/codegen/rpc_service_method.h",
+    "include/grpc++/impl/codegen/security/auth_context.h",
+    "include/grpc++/impl/codegen/serialization_traits.h",
+    "include/grpc++/impl/codegen/server_context.h",
+    "include/grpc++/impl/codegen/server_interface.h",
+    "include/grpc++/impl/codegen/service_type.h",
+    "include/grpc++/impl/codegen/status.h",
+    "include/grpc++/impl/codegen/status_code_enum.h",
+    "include/grpc++/impl/codegen/string_ref.h",
+    "include/grpc++/impl/codegen/stub_options.h",
+    "include/grpc++/impl/codegen/sync.h",
+    "include/grpc++/impl/codegen/sync_cxx11.h",
+    "include/grpc++/impl/codegen/sync_no_cxx11.h",
+    "include/grpc++/impl/codegen/sync_stream.h",
+    "include/grpc++/impl/codegen/time.h",
+  ],
+  includes = [
+    "include",
+    ".",
+  ],
+  deps = [
+    "//external:protobuf_compiler",
+  ],
+)
+
+
+cc_library(
   name = "grpc++_unsecure",
   srcs = [
     "src/cpp/client/create_channel_internal.h",
+    "src/cpp/common/core_codegen.h",
     "src/cpp/common/create_auth_context.h",
     "src/cpp/server/dynamic_thread_pool.h",
     "src/cpp/server/thread_pool_interface.h",
@@ -941,11 +1066,10 @@
     "src/cpp/client/credentials.cc",
     "src/cpp/client/generic_stub.cc",
     "src/cpp/client/insecure_credentials.cc",
-    "src/cpp/common/call.cc",
     "src/cpp/common/channel_arguments.cc",
     "src/cpp/common/completion_queue.cc",
+    "src/cpp/common/core_codegen.cc",
     "src/cpp/common/rpc_method.cc",
-    "src/cpp/proto/proto_utils.cc",
     "src/cpp/server/async_generic_service.cc",
     "src/cpp/server/create_default_thread_pool.cc",
     "src/cpp/server/dynamic_thread_pool.cc",
@@ -959,7 +1083,7 @@
     "src/cpp/util/status.cc",
     "src/cpp/util/string_ref.cc",
     "src/cpp/util/time.cc",
-    "src/cpp/codegen/grpc_library.cc",
+    "src/cpp/codegen/codegen_init.cc",
   ],
   hdrs = [
     "include/grpc++/alarm.h",
@@ -1017,6 +1141,7 @@
     "include/grpc++/impl/codegen/completion_queue_tag.h",
     "include/grpc++/impl/codegen/config.h",
     "include/grpc++/impl/codegen/config_protobuf.h",
+    "include/grpc++/impl/codegen/core_codegen_interface.h",
     "include/grpc++/impl/codegen/grpc_library.h",
     "include/grpc++/impl/codegen/method_handler_impl.h",
     "include/grpc++/impl/codegen/proto_utils.h",
@@ -1072,45 +1197,8 @@
     "src/compiler/objective_c_generator.cc",
     "src/compiler/python_generator.cc",
     "src/compiler/ruby_generator.cc",
-    "src/cpp/codegen/grpc_library.cc",
   ],
   hdrs = [
-    "include/grpc++/impl/codegen/async_stream.h",
-    "include/grpc++/impl/codegen/async_unary_call.h",
-    "include/grpc++/impl/codegen/call.h",
-    "include/grpc++/impl/codegen/call_hook.h",
-    "include/grpc++/impl/codegen/channel_interface.h",
-    "include/grpc++/impl/codegen/client_context.h",
-    "include/grpc++/impl/codegen/client_unary_call.h",
-    "include/grpc++/impl/codegen/completion_queue.h",
-    "include/grpc++/impl/codegen/completion_queue_tag.h",
-    "include/grpc++/impl/codegen/config.h",
-    "include/grpc++/impl/codegen/config_protobuf.h",
-    "include/grpc++/impl/codegen/grpc_library.h",
-    "include/grpc++/impl/codegen/method_handler_impl.h",
-    "include/grpc++/impl/codegen/proto_utils.h",
-    "include/grpc++/impl/codegen/rpc_method.h",
-    "include/grpc++/impl/codegen/rpc_service_method.h",
-    "include/grpc++/impl/codegen/security/auth_context.h",
-    "include/grpc++/impl/codegen/serialization_traits.h",
-    "include/grpc++/impl/codegen/server_context.h",
-    "include/grpc++/impl/codegen/server_interface.h",
-    "include/grpc++/impl/codegen/service_type.h",
-    "include/grpc++/impl/codegen/status.h",
-    "include/grpc++/impl/codegen/status_code_enum.h",
-    "include/grpc++/impl/codegen/string_ref.h",
-    "include/grpc++/impl/codegen/stub_options.h",
-    "include/grpc++/impl/codegen/sync.h",
-    "include/grpc++/impl/codegen/sync_cxx11.h",
-    "include/grpc++/impl/codegen/sync_no_cxx11.h",
-    "include/grpc++/impl/codegen/sync_stream.h",
-    "include/grpc++/impl/codegen/time.h",
-    "include/grpc/impl/codegen/byte_buffer.h",
-    "include/grpc/impl/codegen/compression_types.h",
-    "include/grpc/impl/codegen/connectivity_state.h",
-    "include/grpc/impl/codegen/grpc_types.h",
-    "include/grpc/impl/codegen/propagation_bits.h",
-    "include/grpc/impl/codegen/status.h",
     "include/grpc/impl/codegen/alloc.h",
     "include/grpc/impl/codegen/atm.h",
     "include/grpc/impl/codegen/atm_gcc_atomic.h",
@@ -1132,6 +1220,7 @@
   ],
   deps = [
     "//external:protobuf_compiler",
+    ":grpc++_codegen_lib",
   ],
 )
 
@@ -1162,6 +1251,7 @@
     "src/core/profiling/stap_timers.c",
     "src/core/support/alloc.c",
     "src/core/support/avl.c",
+    "src/core/support/backoff.c",
     "src/core/support/cmdline.c",
     "src/core/support/cpu_iphone.c",
     "src/core/support/cpu_linux.c",
@@ -1246,6 +1336,7 @@
     "include/grpc/impl/codegen/sync_win32.h",
     "include/grpc/impl/codegen/time.h",
     "src/core/profiling/timers.h",
+    "src/core/support/backoff.h",
     "src/core/support/block_annotate.h",
     "src/core/support/env.h",
     "src/core/support/load_file.h",
@@ -1271,8 +1362,10 @@
   srcs = [
     "src/core/census/grpc_context.c",
     "src/core/census/grpc_filter.c",
+    "src/core/census/grpc_plugin.c",
     "src/core/channel/channel_args.c",
     "src/core/channel/channel_stack.c",
+    "src/core/channel/channel_stack_builder.c",
     "src/core/channel/client_channel.c",
     "src/core/channel/client_uchannel.c",
     "src/core/channel/compress_filter.c",
@@ -1360,7 +1453,9 @@
     "src/core/surface/channel.c",
     "src/core/surface/channel_connectivity.c",
     "src/core/surface/channel_create.c",
+    "src/core/surface/channel_init.c",
     "src/core/surface/channel_ping.c",
+    "src/core/surface/channel_stack_type.c",
     "src/core/surface/completion_queue.c",
     "src/core/surface/event_string.c",
     "src/core/surface/init.c",
@@ -1368,7 +1463,6 @@
     "src/core/surface/metadata_array.c",
     "src/core/surface/server.c",
     "src/core/surface/server_chttp2.c",
-    "src/core/surface/server_create.c",
     "src/core/surface/validate_metadata.c",
     "src/core/surface/version.c",
     "src/core/transport/byte_stream.c",
@@ -1432,21 +1526,23 @@
   ],
   hdrs = [
     "include/grpc/grpc_security.h",
+    "include/grpc/byte_buffer.h",
+    "include/grpc/byte_buffer_reader.h",
+    "include/grpc/compression.h",
+    "include/grpc/grpc.h",
+    "include/grpc/status.h",
     "include/grpc/impl/codegen/byte_buffer.h",
     "include/grpc/impl/codegen/compression_types.h",
     "include/grpc/impl/codegen/connectivity_state.h",
     "include/grpc/impl/codegen/grpc_types.h",
     "include/grpc/impl/codegen/propagation_bits.h",
     "include/grpc/impl/codegen/status.h",
-    "include/grpc/byte_buffer.h",
-    "include/grpc/byte_buffer_reader.h",
-    "include/grpc/compression.h",
-    "include/grpc/grpc.h",
-    "include/grpc/status.h",
     "include/grpc/census.h",
     "src/core/census/grpc_filter.h",
+    "src/core/census/grpc_plugin.h",
     "src/core/channel/channel_args.h",
     "src/core/channel/channel_stack.h",
+    "src/core/channel/channel_stack_builder.h",
     "src/core/channel/client_channel.h",
     "src/core/channel/client_uchannel.h",
     "src/core/channel/compress_filter.h",
@@ -1526,9 +1622,12 @@
     "src/core/surface/call.h",
     "src/core/surface/call_test_only.h",
     "src/core/surface/channel.h",
+    "src/core/surface/channel_init.h",
+    "src/core/surface/channel_stack_type.h",
     "src/core/surface/completion_queue.h",
     "src/core/surface/event_string.h",
     "src/core/surface/init.h",
+    "src/core/surface/lame_client.h",
     "src/core/surface/server.h",
     "src/core/surface/surface_trace.h",
     "src/core/transport/byte_stream.h",
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index b4e958d..35eb5e6 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -59,7 +59,7 @@
 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
+files. Instead, modify the template files, or the build.yaml file, and
 re-generate the project files using the following command:
 
 `./tools/buildgen/generate_projects.sh`
diff --git a/INSTALL.md b/INSTALL.md
index 454a8b7..66e6c33 100644
--- a/INSTALL.md
+++ b/INSTALL.md
@@ -52,6 +52,6 @@
  $ git clone https://github.com/grpc/grpc.git
  $ cd grpc
  $ git submodule update --init
- $ make 
+ $ make
  $ [sudo] make install
 ```
diff --git a/Makefile b/Makefile
index b3ae274..8af8ade 100644
--- a/Makefile
+++ b/Makefile
@@ -95,6 +95,46 @@
 CPPFLAGS_opt = -O2
 DEFINES_opt = NDEBUG
 
+VALID_CONFIG_dbg = 1
+CC_dbg = $(DEFAULT_CC)
+CXX_dbg = $(DEFAULT_CXX)
+LD_dbg = $(DEFAULT_CC)
+LDXX_dbg = $(DEFAULT_CXX)
+CPPFLAGS_dbg = -O0
+DEFINES_dbg = _DEBUG DEBUG
+
+VALID_CONFIG_easan = 1
+REQUIRE_CUSTOM_LIBRARIES_easan = 1
+CC_easan = clang
+CXX_easan = clang++
+LD_easan = clang
+LDXX_easan = clang++
+CPPFLAGS_easan = -O0 -fsanitize=address -fno-omit-frame-pointer -Wno-unused-command-line-argument -DGPR_NO_DIRECT_SYSCALLS
+LDFLAGS_easan = -fsanitize=address
+DEFINES_easan = _DEBUG DEBUG GRPC_EXECUTION_CONTEXT_SANITIZER
+DEFINES_easan += GRPC_TEST_SLOWDOWN_BUILD_FACTOR=3
+
+VALID_CONFIG_asan = 1
+REQUIRE_CUSTOM_LIBRARIES_asan = 1
+CC_asan = clang
+CXX_asan = clang++
+LD_asan = clang
+LDXX_asan = clang++
+CPPFLAGS_asan = -O0 -fsanitize=address -fno-omit-frame-pointer -Wno-unused-command-line-argument -DGPR_NO_DIRECT_SYSCALLS
+LDFLAGS_asan = -fsanitize=address
+DEFINES_asan += GRPC_TEST_SLOWDOWN_BUILD_FACTOR=3
+
+VALID_CONFIG_msan = 1
+REQUIRE_CUSTOM_LIBRARIES_msan = 1
+CC_msan = clang
+CXX_msan = clang++
+LD_msan = clang
+LDXX_msan = clang++
+CPPFLAGS_msan = -O0 -fsanitize=memory -fsanitize-memory-track-origins -fno-omit-frame-pointer -DGTEST_HAS_TR1_TUPLE=0 -DGTEST_USE_OWN_TR1_TUPLE=1 -Wno-unused-command-line-argument -fPIE -pie -DGPR_NO_DIRECT_SYSCALLS
+LDFLAGS_msan = -fsanitize=memory -DGTEST_HAS_TR1_TUPLE=0 -DGTEST_USE_OWN_TR1_TUPLE=1 -fPIE -pie $(if $(JENKINS_BUILD),-Wl$(comma)-Ttext-segment=0x7e0000000000,)
+DEFINES_msan = NDEBUG
+DEFINES_msan += GRPC_TEST_SLOWDOWN_BUILD_FACTOR=4
+
 VALID_CONFIG_basicprof = 1
 CC_basicprof = $(DEFAULT_CC)
 CXX_basicprof = $(DEFAULT_CXX)
@@ -123,6 +163,14 @@
 LDFLAGS_asan-noleaks = -fsanitize=address
 DEFINES_asan-noleaks += GRPC_TEST_SLOWDOWN_BUILD_FACTOR=3
 
+VALID_CONFIG_edbg = 1
+CC_edbg = $(DEFAULT_CC)
+CXX_edbg = $(DEFAULT_CXX)
+LD_edbg = $(DEFAULT_CC)
+LDXX_edbg = $(DEFAULT_CXX)
+CPPFLAGS_edbg = -O0
+DEFINES_edbg = _DEBUG DEBUG GRPC_EXECUTION_CONTEXT_SANITIZER
+
 VALID_CONFIG_ubsan = 1
 REQUIRE_CUSTOM_LIBRARIES_ubsan = 1
 CC_ubsan = clang
@@ -134,13 +182,15 @@
 DEFINES_ubsan = NDEBUG
 DEFINES_ubsan += GRPC_TEST_SLOWDOWN_BUILD_FACTOR=1.5
 
-VALID_CONFIG_dbg = 1
-CC_dbg = $(DEFAULT_CC)
-CXX_dbg = $(DEFAULT_CXX)
-LD_dbg = $(DEFAULT_CC)
-LDXX_dbg = $(DEFAULT_CXX)
-CPPFLAGS_dbg = -O0
-DEFINES_dbg = _DEBUG DEBUG
+VALID_CONFIG_tsan = 1
+REQUIRE_CUSTOM_LIBRARIES_tsan = 1
+CC_tsan = clang
+CXX_tsan = clang++
+LD_tsan = clang
+LDXX_tsan = clang++
+CPPFLAGS_tsan = -O0 -fsanitize=thread -fno-omit-frame-pointer -Wno-unused-command-line-argument -fPIE -pie -DGPR_NO_DIRECT_SYSCALLS
+LDFLAGS_tsan = -fsanitize=thread -fPIE -pie $(if $(JENKINS_BUILD),-Wl$(comma)-Ttext-segment=0x7e0000000000,)
+DEFINES_tsan += GRPC_TEST_SLOWDOWN_BUILD_FACTOR=5
 
 VALID_CONFIG_stapprof = 1
 CC_stapprof = $(DEFAULT_CC)
@@ -150,14 +200,14 @@
 CPPFLAGS_stapprof = -O2 -DGRPC_STAP_PROFILER
 DEFINES_stapprof = NDEBUG
 
-VALID_CONFIG_gcov = 1
-CC_gcov = gcc
-CXX_gcov = g++
-LD_gcov = gcc
-LDXX_gcov = g++
-CPPFLAGS_gcov = -O0 -fprofile-arcs -ftest-coverage -Wno-return-type
-LDFLAGS_gcov = -fprofile-arcs -ftest-coverage -rdynamic
-DEFINES_gcov = _DEBUG DEBUG GPR_GCOV
+VALID_CONFIG_mutrace = 1
+CC_mutrace = $(DEFAULT_CC)
+CXX_mutrace = $(DEFAULT_CXX)
+LD_mutrace = $(DEFAULT_CC)
+LDXX_mutrace = $(DEFAULT_CXX)
+CPPFLAGS_mutrace = -O0
+LDFLAGS_mutrace = -rdynamic
+DEFINES_mutrace = _DEBUG DEBUG
 
 VALID_CONFIG_memcheck = 1
 CC_memcheck = $(DEFAULT_CC)
@@ -169,45 +219,25 @@
 DEFINES_memcheck = _DEBUG DEBUG
 DEFINES_memcheck += GRPC_TEST_SLOWDOWN_BUILD_FACTOR=10
 
-VALID_CONFIG_asan = 1
-REQUIRE_CUSTOM_LIBRARIES_asan = 1
-CC_asan = clang
-CXX_asan = clang++
-LD_asan = clang
-LDXX_asan = clang++
-CPPFLAGS_asan = -O0 -fsanitize=address -fno-omit-frame-pointer -Wno-unused-command-line-argument -DGPR_NO_DIRECT_SYSCALLS
-LDFLAGS_asan = -fsanitize=address
-DEFINES_asan += GRPC_TEST_SLOWDOWN_BUILD_FACTOR=3
+VALID_CONFIG_etsan = 1
+REQUIRE_CUSTOM_LIBRARIES_etsan = 1
+CC_etsan = clang
+CXX_etsan = clang++
+LD_etsan = clang
+LDXX_etsan = clang++
+CPPFLAGS_etsan = -O0 -fsanitize=thread -fno-omit-frame-pointer -Wno-unused-command-line-argument -fPIE -pie -DGPR_NO_DIRECT_SYSCALLS
+LDFLAGS_etsan = -fsanitize=thread -fPIE -pie $(if $(JENKINS_BUILD),-Wl$(comma)-Ttext-segment=0x7e0000000000,)
+DEFINES_etsan = _DEBUG DEBUG GRPC_EXECUTION_CONTEXT_SANITIZER
+DEFINES_etsan += GRPC_TEST_SLOWDOWN_BUILD_FACTOR=5
 
-VALID_CONFIG_tsan = 1
-REQUIRE_CUSTOM_LIBRARIES_tsan = 1
-CC_tsan = clang
-CXX_tsan = clang++
-LD_tsan = clang
-LDXX_tsan = clang++
-CPPFLAGS_tsan = -O0 -fsanitize=thread -fno-omit-frame-pointer -Wno-unused-command-line-argument -fPIE -pie -DGPR_NO_DIRECT_SYSCALLS
-LDFLAGS_tsan = -fsanitize=thread -fPIE -pie $(if $(JENKINS_BUILD),-Wl$(comma)-Ttext-segment=0x7e0000000000,)
-DEFINES_tsan += GRPC_TEST_SLOWDOWN_BUILD_FACTOR=5
-
-VALID_CONFIG_msan = 1
-REQUIRE_CUSTOM_LIBRARIES_msan = 1
-CC_msan = clang
-CXX_msan = clang++
-LD_msan = clang
-LDXX_msan = clang++
-CPPFLAGS_msan = -O0 -fsanitize=memory -fsanitize-memory-track-origins -fno-omit-frame-pointer -DGTEST_HAS_TR1_TUPLE=0 -DGTEST_USE_OWN_TR1_TUPLE=1 -Wno-unused-command-line-argument -fPIE -pie -DGPR_NO_DIRECT_SYSCALLS
-LDFLAGS_msan = -fsanitize=memory -DGTEST_HAS_TR1_TUPLE=0 -DGTEST_USE_OWN_TR1_TUPLE=1 -fPIE -pie $(if $(JENKINS_BUILD),-Wl$(comma)-Ttext-segment=0x7e0000000000,)
-DEFINES_msan = NDEBUG
-DEFINES_msan += GRPC_TEST_SLOWDOWN_BUILD_FACTOR=4
-
-VALID_CONFIG_mutrace = 1
-CC_mutrace = $(DEFAULT_CC)
-CXX_mutrace = $(DEFAULT_CXX)
-LD_mutrace = $(DEFAULT_CC)
-LDXX_mutrace = $(DEFAULT_CXX)
-CPPFLAGS_mutrace = -O0
-LDFLAGS_mutrace = -rdynamic
-DEFINES_mutrace = _DEBUG DEBUG
+VALID_CONFIG_gcov = 1
+CC_gcov = gcc
+CXX_gcov = g++
+LD_gcov = gcc
+LDXX_gcov = g++
+CPPFLAGS_gcov = -O0 -fprofile-arcs -ftest-coverage -Wno-return-type
+LDFLAGS_gcov = -fprofile-arcs -ftest-coverage -rdynamic
+DEFINES_gcov = _DEBUG DEBUG GPR_GCOV
 
 
 
@@ -863,6 +893,7 @@
 gen_hpack_tables: $(BINDIR)/$(CONFIG)/gen_hpack_tables
 gen_legal_metadata_characters: $(BINDIR)/$(CONFIG)/gen_legal_metadata_characters
 gpr_avl_test: $(BINDIR)/$(CONFIG)/gpr_avl_test
+gpr_backoff_test: $(BINDIR)/$(CONFIG)/gpr_backoff_test
 gpr_cmdline_test: $(BINDIR)/$(CONFIG)/gpr_cmdline_test
 gpr_cpu_test: $(BINDIR)/$(CONFIG)/gpr_cpu_test
 gpr_env_test: $(BINDIR)/$(CONFIG)/gpr_env_test
@@ -946,6 +977,7 @@
 cli_call_test: $(BINDIR)/$(CONFIG)/cli_call_test
 client_crash_test: $(BINDIR)/$(CONFIG)/client_crash_test
 client_crash_test_server: $(BINDIR)/$(CONFIG)/client_crash_test_server
+codegen_test: $(BINDIR)/$(CONFIG)/codegen_test
 credentials_test: $(BINDIR)/$(CONFIG)/credentials_test
 cxx_byte_buffer_test: $(BINDIR)/$(CONFIG)/cxx_byte_buffer_test
 cxx_slice_test: $(BINDIR)/$(CONFIG)/cxx_slice_test
@@ -1043,6 +1075,7 @@
 h2_full+pipe_test: $(BINDIR)/$(CONFIG)/h2_full+pipe_test
 h2_full+poll_test: $(BINDIR)/$(CONFIG)/h2_full+poll_test
 h2_full+poll+pipe_test: $(BINDIR)/$(CONFIG)/h2_full+poll+pipe_test
+h2_full+trace_test: $(BINDIR)/$(CONFIG)/h2_full+trace_test
 h2_oauth2_test: $(BINDIR)/$(CONFIG)/h2_oauth2_test
 h2_proxy_test: $(BINDIR)/$(CONFIG)/h2_proxy_test
 h2_sockpair_test: $(BINDIR)/$(CONFIG)/h2_sockpair_test
@@ -1060,6 +1093,7 @@
 h2_full+pipe_nosec_test: $(BINDIR)/$(CONFIG)/h2_full+pipe_nosec_test
 h2_full+poll_nosec_test: $(BINDIR)/$(CONFIG)/h2_full+poll_nosec_test
 h2_full+poll+pipe_nosec_test: $(BINDIR)/$(CONFIG)/h2_full+poll+pipe_nosec_test
+h2_full+trace_nosec_test: $(BINDIR)/$(CONFIG)/h2_full+trace_nosec_test
 h2_proxy_nosec_test: $(BINDIR)/$(CONFIG)/h2_proxy_nosec_test
 h2_sockpair_nosec_test: $(BINDIR)/$(CONFIG)/h2_sockpair_nosec_test
 h2_sockpair+trace_nosec_test: $(BINDIR)/$(CONFIG)/h2_sockpair+trace_nosec_test
@@ -1123,7 +1157,7 @@
 
 privatelibs: privatelibs_c privatelibs_cxx
 
-privatelibs_c:  $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libreconnect_server.a $(LIBDIR)/$(CONFIG)/libtest_tcp_server.a $(LIBDIR)/$(CONFIG)/libz.a $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libbad_ssl_test_server.a $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libend2end_certs.a
+privatelibs_c:  $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libreconnect_server.a $(LIBDIR)/$(CONFIG)/libtest_tcp_server.a $(LIBDIR)/$(CONFIG)/libz.a $(LIBDIR)/$(CONFIG)/libbad_client_test.a $(LIBDIR)/$(CONFIG)/libbad_ssl_test_server.a $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a
 pc_c: $(LIBDIR)/$(CONFIG)/pkgconfig/grpc.pc
 
 pc_c_unsecure: $(LIBDIR)/$(CONFIG)/pkgconfig/grpc_unsecure.pc
@@ -1174,6 +1208,7 @@
   $(BINDIR)/$(CONFIG)/fling_stream_test \
   $(BINDIR)/$(CONFIG)/fling_test \
   $(BINDIR)/$(CONFIG)/gpr_avl_test \
+  $(BINDIR)/$(CONFIG)/gpr_backoff_test \
   $(BINDIR)/$(CONFIG)/gpr_cmdline_test \
   $(BINDIR)/$(CONFIG)/gpr_cpu_test \
   $(BINDIR)/$(CONFIG)/gpr_env_test \
@@ -1263,6 +1298,7 @@
   $(BINDIR)/$(CONFIG)/h2_full+pipe_test \
   $(BINDIR)/$(CONFIG)/h2_full+poll_test \
   $(BINDIR)/$(CONFIG)/h2_full+poll+pipe_test \
+  $(BINDIR)/$(CONFIG)/h2_full+trace_test \
   $(BINDIR)/$(CONFIG)/h2_oauth2_test \
   $(BINDIR)/$(CONFIG)/h2_proxy_test \
   $(BINDIR)/$(CONFIG)/h2_sockpair_test \
@@ -1280,6 +1316,7 @@
   $(BINDIR)/$(CONFIG)/h2_full+pipe_nosec_test \
   $(BINDIR)/$(CONFIG)/h2_full+poll_nosec_test \
   $(BINDIR)/$(CONFIG)/h2_full+poll+pipe_nosec_test \
+  $(BINDIR)/$(CONFIG)/h2_full+trace_nosec_test \
   $(BINDIR)/$(CONFIG)/h2_proxy_nosec_test \
   $(BINDIR)/$(CONFIG)/h2_sockpair_nosec_test \
   $(BINDIR)/$(CONFIG)/h2_sockpair+trace_nosec_test \
@@ -1299,6 +1336,7 @@
   $(BINDIR)/$(CONFIG)/cli_call_test \
   $(BINDIR)/$(CONFIG)/client_crash_test \
   $(BINDIR)/$(CONFIG)/client_crash_test_server \
+  $(BINDIR)/$(CONFIG)/codegen_test \
   $(BINDIR)/$(CONFIG)/credentials_test \
   $(BINDIR)/$(CONFIG)/cxx_byte_buffer_test \
   $(BINDIR)/$(CONFIG)/cxx_slice_test \
@@ -1428,6 +1466,8 @@
 	$(Q) $(BINDIR)/$(CONFIG)/fling_test || ( echo test fling_test failed ; exit 1 )
 	$(E) "[RUN]     Testing gpr_avl_test"
 	$(Q) $(BINDIR)/$(CONFIG)/gpr_avl_test || ( echo test gpr_avl_test failed ; exit 1 )
+	$(E) "[RUN]     Testing gpr_backoff_test"
+	$(Q) $(BINDIR)/$(CONFIG)/gpr_backoff_test || ( echo test gpr_backoff_test failed ; exit 1 )
 	$(E) "[RUN]     Testing gpr_cmdline_test"
 	$(Q) $(BINDIR)/$(CONFIG)/gpr_cmdline_test || ( echo test gpr_cmdline_test failed ; exit 1 )
 	$(E) "[RUN]     Testing gpr_cpu_test"
@@ -1506,8 +1546,6 @@
 	$(Q) $(BINDIR)/$(CONFIG)/json_test || ( echo test json_test failed ; exit 1 )
 	$(E) "[RUN]     Testing lame_client_test"
 	$(Q) $(BINDIR)/$(CONFIG)/lame_client_test || ( echo test lame_client_test failed ; exit 1 )
-	$(E) "[RUN]     Testing lb_policies_test"
-	$(Q) $(BINDIR)/$(CONFIG)/lb_policies_test || ( echo test lb_policies_test failed ; exit 1 )
 	$(E) "[RUN]     Testing message_compress_test"
 	$(Q) $(BINDIR)/$(CONFIG)/message_compress_test || ( echo test message_compress_test failed ; exit 1 )
 	$(E) "[RUN]     Testing mlog_test"
@@ -1589,6 +1627,8 @@
 
 
 flaky_test_c: buildtests_c
+	$(E) "[RUN]     Testing lb_policies_test"
+	$(Q) $(BINDIR)/$(CONFIG)/lb_policies_test || ( echo test lb_policies_test failed ; exit 1 )
 
 
 test_cxx: test_zookeeper buildtests_cxx
@@ -1608,6 +1648,8 @@
 	$(Q) $(BINDIR)/$(CONFIG)/cli_call_test || ( echo test cli_call_test failed ; exit 1 )
 	$(E) "[RUN]     Testing client_crash_test"
 	$(Q) $(BINDIR)/$(CONFIG)/client_crash_test || ( echo test client_crash_test failed ; exit 1 )
+	$(E) "[RUN]     Testing codegen_test"
+	$(Q) $(BINDIR)/$(CONFIG)/codegen_test || ( echo test codegen_test failed ; exit 1 )
 	$(E) "[RUN]     Testing credentials_test"
 	$(Q) $(BINDIR)/$(CONFIG)/credentials_test || ( echo test credentials_test failed ; exit 1 )
 	$(E) "[RUN]     Testing cxx_byte_buffer_test"
@@ -2218,6 +2260,7 @@
     src/core/profiling/stap_timers.c \
     src/core/support/alloc.c \
     src/core/support/avl.c \
+    src/core/support/backoff.c \
     src/core/support/cmdline.c \
     src/core/support/cpu_iphone.c \
     src/core/support/cpu_linux.c \
@@ -2366,8 +2409,10 @@
 LIBGRPC_SRC = \
     src/core/census/grpc_context.c \
     src/core/census/grpc_filter.c \
+    src/core/census/grpc_plugin.c \
     src/core/channel/channel_args.c \
     src/core/channel/channel_stack.c \
+    src/core/channel/channel_stack_builder.c \
     src/core/channel/client_channel.c \
     src/core/channel/client_uchannel.c \
     src/core/channel/compress_filter.c \
@@ -2455,7 +2500,9 @@
     src/core/surface/channel.c \
     src/core/surface/channel_connectivity.c \
     src/core/surface/channel_create.c \
+    src/core/surface/channel_init.c \
     src/core/surface/channel_ping.c \
+    src/core/surface/channel_stack_type.c \
     src/core/surface/completion_queue.c \
     src/core/surface/event_string.c \
     src/core/surface/init.c \
@@ -2463,7 +2510,6 @@
     src/core/surface/metadata_array.c \
     src/core/surface/server.c \
     src/core/surface/server_chttp2.c \
-    src/core/surface/server_create.c \
     src/core/surface/validate_metadata.c \
     src/core/surface/version.c \
     src/core/transport/byte_stream.c \
@@ -2527,17 +2573,17 @@
 
 PUBLIC_HEADERS_C += \
     include/grpc/grpc_security.h \
+    include/grpc/byte_buffer.h \
+    include/grpc/byte_buffer_reader.h \
+    include/grpc/compression.h \
+    include/grpc/grpc.h \
+    include/grpc/status.h \
     include/grpc/impl/codegen/byte_buffer.h \
     include/grpc/impl/codegen/compression_types.h \
     include/grpc/impl/codegen/connectivity_state.h \
     include/grpc/impl/codegen/grpc_types.h \
     include/grpc/impl/codegen/propagation_bits.h \
     include/grpc/impl/codegen/status.h \
-    include/grpc/byte_buffer.h \
-    include/grpc/byte_buffer_reader.h \
-    include/grpc/compression.h \
-    include/grpc/grpc.h \
-    include/grpc/status.h \
     include/grpc/census.h \
 
 LIBGRPC_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC_SRC))))
@@ -2592,6 +2638,50 @@
 endif
 
 
+LIBGRPC_CODEGEN_LIB_SRC = \
+
+PUBLIC_HEADERS_C += \
+    include/grpc/impl/codegen/alloc.h \
+    include/grpc/impl/codegen/atm.h \
+    include/grpc/impl/codegen/atm_gcc_atomic.h \
+    include/grpc/impl/codegen/atm_gcc_sync.h \
+    include/grpc/impl/codegen/atm_win32.h \
+    include/grpc/impl/codegen/log.h \
+    include/grpc/impl/codegen/port_platform.h \
+    include/grpc/impl/codegen/slice.h \
+    include/grpc/impl/codegen/slice_buffer.h \
+    include/grpc/impl/codegen/sync.h \
+    include/grpc/impl/codegen/sync_generic.h \
+    include/grpc/impl/codegen/sync_posix.h \
+    include/grpc/impl/codegen/sync_win32.h \
+    include/grpc/impl/codegen/time.h \
+    include/grpc/impl/codegen/byte_buffer.h \
+    include/grpc/impl/codegen/compression_types.h \
+    include/grpc/impl/codegen/connectivity_state.h \
+    include/grpc/impl/codegen/grpc_types.h \
+    include/grpc/impl/codegen/propagation_bits.h \
+    include/grpc/impl/codegen/status.h \
+
+LIBGRPC_CODEGEN_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC_CODEGEN_LIB_SRC))))
+
+
+$(LIBDIR)/$(CONFIG)/libgrpc_codegen_lib.a: $(ZLIB_DEP)  $(LIBGRPC_CODEGEN_LIB_OBJS) 
+	$(E) "[AR]      Creating $@"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc_codegen_lib.a
+	$(Q) $(AR) $(LIBDIR)/$(CONFIG)/libgrpc_codegen_lib.a $(LIBGRPC_CODEGEN_LIB_OBJS) 
+ifeq ($(SYSTEM),Darwin)
+	$(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libgrpc_codegen_lib.a
+endif
+
+
+
+
+ifneq ($(NO_DEPS),true)
+-include $(LIBGRPC_CODEGEN_LIB_OBJS:.o=.dep)
+endif
+
+
 LIBGRPC_TEST_UTIL_SRC = \
     test/core/end2end/data/server1_cert.c \
     test/core/end2end/data/server1_key.c \
@@ -2603,6 +2693,7 @@
     test/core/util/grpc_profiler.c \
     test/core/util/parse_hexstring.c \
     test/core/util/port_posix.c \
+    test/core/util/port_server_client.c \
     test/core/util/port_windows.c \
     test/core/util/slice_splitter.c \
 
@@ -2649,6 +2740,7 @@
     test/core/util/grpc_profiler.c \
     test/core/util/parse_hexstring.c \
     test/core/util/port_posix.c \
+    test/core/util/port_server_client.c \
     test/core/util/port_windows.c \
     test/core/util/slice_splitter.c \
 
@@ -2678,8 +2770,10 @@
     src/core/surface/init_unsecure.c \
     src/core/census/grpc_context.c \
     src/core/census/grpc_filter.c \
+    src/core/census/grpc_plugin.c \
     src/core/channel/channel_args.c \
     src/core/channel/channel_stack.c \
+    src/core/channel/channel_stack_builder.c \
     src/core/channel/client_channel.c \
     src/core/channel/client_uchannel.c \
     src/core/channel/compress_filter.c \
@@ -2767,7 +2861,9 @@
     src/core/surface/channel.c \
     src/core/surface/channel_connectivity.c \
     src/core/surface/channel_create.c \
+    src/core/surface/channel_init.c \
     src/core/surface/channel_ping.c \
+    src/core/surface/channel_stack_type.c \
     src/core/surface/completion_queue.c \
     src/core/surface/event_string.c \
     src/core/surface/init.c \
@@ -2775,7 +2871,6 @@
     src/core/surface/metadata_array.c \
     src/core/surface/server.c \
     src/core/surface/server_chttp2.c \
-    src/core/surface/server_create.c \
     src/core/surface/validate_metadata.c \
     src/core/surface/version.c \
     src/core/transport/byte_stream.c \
@@ -3000,11 +3095,10 @@
     src/cpp/client/credentials.cc \
     src/cpp/client/generic_stub.cc \
     src/cpp/client/insecure_credentials.cc \
-    src/cpp/common/call.cc \
     src/cpp/common/channel_arguments.cc \
     src/cpp/common/completion_queue.cc \
+    src/cpp/common/core_codegen.cc \
     src/cpp/common/rpc_method.cc \
-    src/cpp/proto/proto_utils.cc \
     src/cpp/server/async_generic_service.cc \
     src/cpp/server/create_default_thread_pool.cc \
     src/cpp/server/dynamic_thread_pool.cc \
@@ -3018,7 +3112,7 @@
     src/cpp/util/status.cc \
     src/cpp/util/string_ref.cc \
     src/cpp/util/time.cc \
-    src/cpp/codegen/grpc_library.cc \
+    src/cpp/codegen/codegen_init.cc \
 
 PUBLIC_HEADERS_CXX += \
     include/grpc++/alarm.h \
@@ -3076,6 +3170,7 @@
     include/grpc++/impl/codegen/completion_queue_tag.h \
     include/grpc++/impl/codegen/config.h \
     include/grpc++/impl/codegen/config_protobuf.h \
+    include/grpc++/impl/codegen/core_codegen_interface.h \
     include/grpc++/impl/codegen/grpc_library.h \
     include/grpc++/impl/codegen/method_handler_impl.h \
     include/grpc++/impl/codegen/proto_utils.h \
@@ -3159,6 +3254,93 @@
 endif
 
 
+LIBGRPC++_CODEGEN_LIB_SRC = \
+    src/cpp/codegen/codegen_init.cc \
+
+PUBLIC_HEADERS_CXX += \
+    include/grpc/impl/codegen/alloc.h \
+    include/grpc/impl/codegen/atm.h \
+    include/grpc/impl/codegen/atm_gcc_atomic.h \
+    include/grpc/impl/codegen/atm_gcc_sync.h \
+    include/grpc/impl/codegen/atm_win32.h \
+    include/grpc/impl/codegen/log.h \
+    include/grpc/impl/codegen/port_platform.h \
+    include/grpc/impl/codegen/slice.h \
+    include/grpc/impl/codegen/slice_buffer.h \
+    include/grpc/impl/codegen/sync.h \
+    include/grpc/impl/codegen/sync_generic.h \
+    include/grpc/impl/codegen/sync_posix.h \
+    include/grpc/impl/codegen/sync_win32.h \
+    include/grpc/impl/codegen/time.h \
+    include/grpc/impl/codegen/byte_buffer.h \
+    include/grpc/impl/codegen/compression_types.h \
+    include/grpc/impl/codegen/connectivity_state.h \
+    include/grpc/impl/codegen/grpc_types.h \
+    include/grpc/impl/codegen/propagation_bits.h \
+    include/grpc/impl/codegen/status.h \
+    include/grpc++/impl/codegen/async_stream.h \
+    include/grpc++/impl/codegen/async_unary_call.h \
+    include/grpc++/impl/codegen/call.h \
+    include/grpc++/impl/codegen/call_hook.h \
+    include/grpc++/impl/codegen/channel_interface.h \
+    include/grpc++/impl/codegen/client_context.h \
+    include/grpc++/impl/codegen/client_unary_call.h \
+    include/grpc++/impl/codegen/completion_queue.h \
+    include/grpc++/impl/codegen/completion_queue_tag.h \
+    include/grpc++/impl/codegen/config.h \
+    include/grpc++/impl/codegen/config_protobuf.h \
+    include/grpc++/impl/codegen/core_codegen_interface.h \
+    include/grpc++/impl/codegen/grpc_library.h \
+    include/grpc++/impl/codegen/method_handler_impl.h \
+    include/grpc++/impl/codegen/proto_utils.h \
+    include/grpc++/impl/codegen/rpc_method.h \
+    include/grpc++/impl/codegen/rpc_service_method.h \
+    include/grpc++/impl/codegen/security/auth_context.h \
+    include/grpc++/impl/codegen/serialization_traits.h \
+    include/grpc++/impl/codegen/server_context.h \
+    include/grpc++/impl/codegen/server_interface.h \
+    include/grpc++/impl/codegen/service_type.h \
+    include/grpc++/impl/codegen/status.h \
+    include/grpc++/impl/codegen/status_code_enum.h \
+    include/grpc++/impl/codegen/string_ref.h \
+    include/grpc++/impl/codegen/stub_options.h \
+    include/grpc++/impl/codegen/sync.h \
+    include/grpc++/impl/codegen/sync_cxx11.h \
+    include/grpc++/impl/codegen/sync_no_cxx11.h \
+    include/grpc++/impl/codegen/sync_stream.h \
+    include/grpc++/impl/codegen/time.h \
+
+LIBGRPC++_CODEGEN_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC++_CODEGEN_LIB_SRC))))
+
+
+ifeq ($(NO_PROTOBUF),true)
+
+# You can't build a C++ library if you don't have protobuf - a bit overreached, but still okay.
+
+$(LIBDIR)/$(CONFIG)/libgrpc++_codegen_lib.a: protobuf_dep_error
+
+
+else
+
+$(LIBDIR)/$(CONFIG)/libgrpc++_codegen_lib.a: $(ZLIB_DEP)  $(PROTOBUF_DEP) $(LIBGRPC++_CODEGEN_LIB_OBJS) 
+	$(E) "[AR]      Creating $@"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc++_codegen_lib.a
+	$(Q) $(AR) $(LIBDIR)/$(CONFIG)/libgrpc++_codegen_lib.a $(LIBGRPC++_CODEGEN_LIB_OBJS) 
+ifeq ($(SYSTEM),Darwin)
+	$(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libgrpc++_codegen_lib.a
+endif
+
+
+
+
+endif
+
+ifneq ($(NO_DEPS),true)
+-include $(LIBGRPC++_CODEGEN_LIB_OBJS:.o=.dep)
+endif
+
+
 LIBGRPC++_TEST_CONFIG_SRC = \
     test/cpp/util/test_config.cc \
 
@@ -3280,11 +3462,10 @@
     src/cpp/client/credentials.cc \
     src/cpp/client/generic_stub.cc \
     src/cpp/client/insecure_credentials.cc \
-    src/cpp/common/call.cc \
     src/cpp/common/channel_arguments.cc \
     src/cpp/common/completion_queue.cc \
+    src/cpp/common/core_codegen.cc \
     src/cpp/common/rpc_method.cc \
-    src/cpp/proto/proto_utils.cc \
     src/cpp/server/async_generic_service.cc \
     src/cpp/server/create_default_thread_pool.cc \
     src/cpp/server/dynamic_thread_pool.cc \
@@ -3298,7 +3479,7 @@
     src/cpp/util/status.cc \
     src/cpp/util/string_ref.cc \
     src/cpp/util/time.cc \
-    src/cpp/codegen/grpc_library.cc \
+    src/cpp/codegen/codegen_init.cc \
 
 PUBLIC_HEADERS_CXX += \
     include/grpc++/alarm.h \
@@ -3356,6 +3537,7 @@
     include/grpc++/impl/codegen/completion_queue_tag.h \
     include/grpc++/impl/codegen/config.h \
     include/grpc++/impl/codegen/config_protobuf.h \
+    include/grpc++/impl/codegen/core_codegen_interface.h \
     include/grpc++/impl/codegen/grpc_library.h \
     include/grpc++/impl/codegen/method_handler_impl.h \
     include/grpc++/impl/codegen/proto_utils.h \
@@ -3431,45 +3613,8 @@
     src/compiler/objective_c_generator.cc \
     src/compiler/python_generator.cc \
     src/compiler/ruby_generator.cc \
-    src/cpp/codegen/grpc_library.cc \
 
 PUBLIC_HEADERS_CXX += \
-    include/grpc++/impl/codegen/async_stream.h \
-    include/grpc++/impl/codegen/async_unary_call.h \
-    include/grpc++/impl/codegen/call.h \
-    include/grpc++/impl/codegen/call_hook.h \
-    include/grpc++/impl/codegen/channel_interface.h \
-    include/grpc++/impl/codegen/client_context.h \
-    include/grpc++/impl/codegen/client_unary_call.h \
-    include/grpc++/impl/codegen/completion_queue.h \
-    include/grpc++/impl/codegen/completion_queue_tag.h \
-    include/grpc++/impl/codegen/config.h \
-    include/grpc++/impl/codegen/config_protobuf.h \
-    include/grpc++/impl/codegen/grpc_library.h \
-    include/grpc++/impl/codegen/method_handler_impl.h \
-    include/grpc++/impl/codegen/proto_utils.h \
-    include/grpc++/impl/codegen/rpc_method.h \
-    include/grpc++/impl/codegen/rpc_service_method.h \
-    include/grpc++/impl/codegen/security/auth_context.h \
-    include/grpc++/impl/codegen/serialization_traits.h \
-    include/grpc++/impl/codegen/server_context.h \
-    include/grpc++/impl/codegen/server_interface.h \
-    include/grpc++/impl/codegen/service_type.h \
-    include/grpc++/impl/codegen/status.h \
-    include/grpc++/impl/codegen/status_code_enum.h \
-    include/grpc++/impl/codegen/string_ref.h \
-    include/grpc++/impl/codegen/stub_options.h \
-    include/grpc++/impl/codegen/sync.h \
-    include/grpc++/impl/codegen/sync_cxx11.h \
-    include/grpc++/impl/codegen/sync_no_cxx11.h \
-    include/grpc++/impl/codegen/sync_stream.h \
-    include/grpc++/impl/codegen/time.h \
-    include/grpc/impl/codegen/byte_buffer.h \
-    include/grpc/impl/codegen/compression_types.h \
-    include/grpc/impl/codegen/connectivity_state.h \
-    include/grpc/impl/codegen/grpc_types.h \
-    include/grpc/impl/codegen/propagation_bits.h \
-    include/grpc/impl/codegen/status.h \
     include/grpc/impl/codegen/alloc.h \
     include/grpc/impl/codegen/atm.h \
     include/grpc/impl/codegen/atm_gcc_atomic.h \
@@ -5694,46 +5839,6 @@
 endif
 
 
-LIBEND2END_CERTS_SRC = \
-    test/core/end2end/data/test_root_cert.c \
-    test/core/end2end/data/server1_cert.c \
-    test/core/end2end/data/server1_key.c \
-
-
-LIBEND2END_CERTS_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBEND2END_CERTS_SRC))))
-
-
-ifeq ($(NO_SECURE),true)
-
-# You can't build secure libraries if you don't have OpenSSL.
-
-$(LIBDIR)/$(CONFIG)/libend2end_certs.a: openssl_dep_error
-
-
-else
-
-
-$(LIBDIR)/$(CONFIG)/libend2end_certs.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(LIBEND2END_CERTS_OBJS) 
-	$(E) "[AR]      Creating $@"
-	$(Q) mkdir -p `dirname $@`
-	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libend2end_certs.a
-	$(Q) $(AR) $(LIBDIR)/$(CONFIG)/libend2end_certs.a $(LIBEND2END_CERTS_OBJS) 
-ifeq ($(SYSTEM),Darwin)
-	$(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libend2end_certs.a
-endif
-
-
-
-
-endif
-
-ifneq ($(NO_SECURE),true)
-ifneq ($(NO_DEPS),true)
--include $(LIBEND2END_CERTS_OBJS:.o=.dep)
-endif
-endif
-
-
 
 # All of the test targets, and protoc plugins
 
@@ -6570,6 +6675,38 @@
 endif
 
 
+GPR_BACKOFF_TEST_SRC = \
+    test/core/support/backoff_test.c \
+
+GPR_BACKOFF_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(GPR_BACKOFF_TEST_SRC))))
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure targets if you don't have OpenSSL.
+
+$(BINDIR)/$(CONFIG)/gpr_backoff_test: openssl_dep_error
+
+else
+
+
+
+$(BINDIR)/$(CONFIG)/gpr_backoff_test: $(GPR_BACKOFF_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+	$(E) "[LD]      Linking $@"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(LD) $(LDFLAGS) $(GPR_BACKOFF_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/gpr_backoff_test
+
+endif
+
+$(OBJDIR)/$(CONFIG)/test/core/support/backoff_test.o:  $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+deps_gpr_backoff_test: $(GPR_BACKOFF_TEST_OBJS:.o=.dep)
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(GPR_BACKOFF_TEST_OBJS:.o=.dep)
+endif
+endif
+
+
 GPR_CMDLINE_TEST_SRC = \
     test/core/support/cmdline_test.c \
 
@@ -9325,6 +9462,68 @@
 endif
 
 
+CODEGEN_TEST_SRC = \
+    $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc \
+    $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc \
+    $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc \
+    $(GENDIR)/src/proto/grpc/testing/perf_db.pb.cc $(GENDIR)/src/proto/grpc/testing/perf_db.grpc.pb.cc \
+    $(GENDIR)/src/proto/grpc/testing/services.pb.cc $(GENDIR)/src/proto/grpc/testing/services.grpc.pb.cc \
+    $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc \
+    test/cpp/codegen/codegen_test.cc \
+
+CODEGEN_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(CODEGEN_TEST_SRC))))
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure targets if you don't have OpenSSL.
+
+$(BINDIR)/$(CONFIG)/codegen_test: openssl_dep_error
+
+else
+
+
+
+
+ifeq ($(NO_PROTOBUF),true)
+
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+
+$(BINDIR)/$(CONFIG)/codegen_test: protobuf_dep_error
+
+else
+
+$(BINDIR)/$(CONFIG)/codegen_test: $(PROTOBUF_DEP) $(CODEGEN_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_codegen_lib.a
+	$(E) "[LD]      Linking $@"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(LDXX) $(LDFLAGS) $(CODEGEN_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_codegen_lib.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/codegen_test
+
+endif
+
+endif
+
+$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/control.o:  $(LIBDIR)/$(CONFIG)/libgrpc++_codegen_lib.a
+
+$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/messages.o:  $(LIBDIR)/$(CONFIG)/libgrpc++_codegen_lib.a
+
+$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/payloads.o:  $(LIBDIR)/$(CONFIG)/libgrpc++_codegen_lib.a
+
+$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/perf_db.o:  $(LIBDIR)/$(CONFIG)/libgrpc++_codegen_lib.a
+
+$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/services.o:  $(LIBDIR)/$(CONFIG)/libgrpc++_codegen_lib.a
+
+$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/stats.o:  $(LIBDIR)/$(CONFIG)/libgrpc++_codegen_lib.a
+
+$(OBJDIR)/$(CONFIG)/test/cpp/codegen/codegen_test.o:  $(LIBDIR)/$(CONFIG)/libgrpc++_codegen_lib.a
+
+deps_codegen_test: $(CODEGEN_TEST_OBJS:.o=.dep)
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(CODEGEN_TEST_OBJS:.o=.dep)
+endif
+endif
+$(OBJDIR)/$(CONFIG)/test/cpp/codegen/codegen_test.o: $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/perf_db.pb.cc $(GENDIR)/src/proto/grpc/testing/perf_db.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/services.pb.cc $(GENDIR)/src/proto/grpc/testing/services.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc
+
+
 CREDENTIALS_TEST_SRC = \
     test/cpp/client/credentials_test.cc \
 
@@ -12355,14 +12554,14 @@
 
 
 
-$(BINDIR)/$(CONFIG)/h2_census_test: $(H2_CENSUS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libend2end_certs.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(BINDIR)/$(CONFIG)/h2_census_test: $(H2_CENSUS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(LD) $(LDFLAGS) $(H2_CENSUS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libend2end_certs.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_census_test
+	$(Q) $(LD) $(LDFLAGS) $(H2_CENSUS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_census_test
 
 endif
 
-$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_census.o:  $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libend2end_certs.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_census.o:  $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 
 deps_h2_census_test: $(H2_CENSUS_TEST_OBJS:.o=.dep)
 
@@ -12387,14 +12586,14 @@
 
 
 
-$(BINDIR)/$(CONFIG)/h2_compress_test: $(H2_COMPRESS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libend2end_certs.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(BINDIR)/$(CONFIG)/h2_compress_test: $(H2_COMPRESS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(LD) $(LDFLAGS) $(H2_COMPRESS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libend2end_certs.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_compress_test
+	$(Q) $(LD) $(LDFLAGS) $(H2_COMPRESS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_compress_test
 
 endif
 
-$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_compress.o:  $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libend2end_certs.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_compress.o:  $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 
 deps_h2_compress_test: $(H2_COMPRESS_TEST_OBJS:.o=.dep)
 
@@ -12419,14 +12618,14 @@
 
 
 
-$(BINDIR)/$(CONFIG)/h2_fakesec_test: $(H2_FAKESEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libend2end_certs.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(BINDIR)/$(CONFIG)/h2_fakesec_test: $(H2_FAKESEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(LD) $(LDFLAGS) $(H2_FAKESEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libend2end_certs.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_fakesec_test
+	$(Q) $(LD) $(LDFLAGS) $(H2_FAKESEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_fakesec_test
 
 endif
 
-$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_fakesec.o:  $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libend2end_certs.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_fakesec.o:  $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 
 deps_h2_fakesec_test: $(H2_FAKESEC_TEST_OBJS:.o=.dep)
 
@@ -12451,14 +12650,14 @@
 
 
 
-$(BINDIR)/$(CONFIG)/h2_full_test: $(H2_FULL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libend2end_certs.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(BINDIR)/$(CONFIG)/h2_full_test: $(H2_FULL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(LD) $(LDFLAGS) $(H2_FULL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libend2end_certs.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_full_test
+	$(Q) $(LD) $(LDFLAGS) $(H2_FULL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_full_test
 
 endif
 
-$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_full.o:  $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libend2end_certs.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_full.o:  $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 
 deps_h2_full_test: $(H2_FULL_TEST_OBJS:.o=.dep)
 
@@ -12483,14 +12682,14 @@
 
 
 
-$(BINDIR)/$(CONFIG)/h2_full+pipe_test: $(H2_FULL+PIPE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libend2end_certs.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(BINDIR)/$(CONFIG)/h2_full+pipe_test: $(H2_FULL+PIPE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(LD) $(LDFLAGS) $(H2_FULL+PIPE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libend2end_certs.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_full+pipe_test
+	$(Q) $(LD) $(LDFLAGS) $(H2_FULL+PIPE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_full+pipe_test
 
 endif
 
-$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_full+pipe.o:  $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libend2end_certs.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_full+pipe.o:  $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 
 deps_h2_full+pipe_test: $(H2_FULL+PIPE_TEST_OBJS:.o=.dep)
 
@@ -12515,14 +12714,14 @@
 
 
 
-$(BINDIR)/$(CONFIG)/h2_full+poll_test: $(H2_FULL+POLL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libend2end_certs.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(BINDIR)/$(CONFIG)/h2_full+poll_test: $(H2_FULL+POLL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(LD) $(LDFLAGS) $(H2_FULL+POLL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libend2end_certs.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_full+poll_test
+	$(Q) $(LD) $(LDFLAGS) $(H2_FULL+POLL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_full+poll_test
 
 endif
 
-$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_full+poll.o:  $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libend2end_certs.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_full+poll.o:  $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 
 deps_h2_full+poll_test: $(H2_FULL+POLL_TEST_OBJS:.o=.dep)
 
@@ -12547,14 +12746,14 @@
 
 
 
-$(BINDIR)/$(CONFIG)/h2_full+poll+pipe_test: $(H2_FULL+POLL+PIPE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libend2end_certs.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(BINDIR)/$(CONFIG)/h2_full+poll+pipe_test: $(H2_FULL+POLL+PIPE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(LD) $(LDFLAGS) $(H2_FULL+POLL+PIPE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libend2end_certs.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_full+poll+pipe_test
+	$(Q) $(LD) $(LDFLAGS) $(H2_FULL+POLL+PIPE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_full+poll+pipe_test
 
 endif
 
-$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_full+poll+pipe.o:  $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libend2end_certs.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_full+poll+pipe.o:  $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 
 deps_h2_full+poll+pipe_test: $(H2_FULL+POLL+PIPE_TEST_OBJS:.o=.dep)
 
@@ -12565,6 +12764,38 @@
 endif
 
 
+H2_FULL+TRACE_TEST_SRC = \
+    test/core/end2end/fixtures/h2_full+trace.c \
+
+H2_FULL+TRACE_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(H2_FULL+TRACE_TEST_SRC))))
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure targets if you don't have OpenSSL.
+
+$(BINDIR)/$(CONFIG)/h2_full+trace_test: openssl_dep_error
+
+else
+
+
+
+$(BINDIR)/$(CONFIG)/h2_full+trace_test: $(H2_FULL+TRACE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+	$(E) "[LD]      Linking $@"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(LD) $(LDFLAGS) $(H2_FULL+TRACE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_full+trace_test
+
+endif
+
+$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_full+trace.o:  $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+deps_h2_full+trace_test: $(H2_FULL+TRACE_TEST_OBJS:.o=.dep)
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(H2_FULL+TRACE_TEST_OBJS:.o=.dep)
+endif
+endif
+
+
 H2_OAUTH2_TEST_SRC = \
     test/core/end2end/fixtures/h2_oauth2.c \
 
@@ -12579,14 +12810,14 @@
 
 
 
-$(BINDIR)/$(CONFIG)/h2_oauth2_test: $(H2_OAUTH2_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libend2end_certs.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(BINDIR)/$(CONFIG)/h2_oauth2_test: $(H2_OAUTH2_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(LD) $(LDFLAGS) $(H2_OAUTH2_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libend2end_certs.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_oauth2_test
+	$(Q) $(LD) $(LDFLAGS) $(H2_OAUTH2_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_oauth2_test
 
 endif
 
-$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_oauth2.o:  $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libend2end_certs.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_oauth2.o:  $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 
 deps_h2_oauth2_test: $(H2_OAUTH2_TEST_OBJS:.o=.dep)
 
@@ -12611,14 +12842,14 @@
 
 
 
-$(BINDIR)/$(CONFIG)/h2_proxy_test: $(H2_PROXY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libend2end_certs.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(BINDIR)/$(CONFIG)/h2_proxy_test: $(H2_PROXY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(LD) $(LDFLAGS) $(H2_PROXY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libend2end_certs.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_proxy_test
+	$(Q) $(LD) $(LDFLAGS) $(H2_PROXY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_proxy_test
 
 endif
 
-$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_proxy.o:  $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libend2end_certs.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_proxy.o:  $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 
 deps_h2_proxy_test: $(H2_PROXY_TEST_OBJS:.o=.dep)
 
@@ -12643,14 +12874,14 @@
 
 
 
-$(BINDIR)/$(CONFIG)/h2_sockpair_test: $(H2_SOCKPAIR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libend2end_certs.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(BINDIR)/$(CONFIG)/h2_sockpair_test: $(H2_SOCKPAIR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(LD) $(LDFLAGS) $(H2_SOCKPAIR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libend2end_certs.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_sockpair_test
+	$(Q) $(LD) $(LDFLAGS) $(H2_SOCKPAIR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_sockpair_test
 
 endif
 
-$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_sockpair.o:  $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libend2end_certs.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_sockpair.o:  $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 
 deps_h2_sockpair_test: $(H2_SOCKPAIR_TEST_OBJS:.o=.dep)
 
@@ -12675,14 +12906,14 @@
 
 
 
-$(BINDIR)/$(CONFIG)/h2_sockpair+trace_test: $(H2_SOCKPAIR+TRACE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libend2end_certs.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(BINDIR)/$(CONFIG)/h2_sockpair+trace_test: $(H2_SOCKPAIR+TRACE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(LD) $(LDFLAGS) $(H2_SOCKPAIR+TRACE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libend2end_certs.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_sockpair+trace_test
+	$(Q) $(LD) $(LDFLAGS) $(H2_SOCKPAIR+TRACE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_sockpair+trace_test
 
 endif
 
-$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_sockpair+trace.o:  $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libend2end_certs.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_sockpair+trace.o:  $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 
 deps_h2_sockpair+trace_test: $(H2_SOCKPAIR+TRACE_TEST_OBJS:.o=.dep)
 
@@ -12707,14 +12938,14 @@
 
 
 
-$(BINDIR)/$(CONFIG)/h2_sockpair_1byte_test: $(H2_SOCKPAIR_1BYTE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libend2end_certs.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(BINDIR)/$(CONFIG)/h2_sockpair_1byte_test: $(H2_SOCKPAIR_1BYTE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(LD) $(LDFLAGS) $(H2_SOCKPAIR_1BYTE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libend2end_certs.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_test
+	$(Q) $(LD) $(LDFLAGS) $(H2_SOCKPAIR_1BYTE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_sockpair_1byte_test
 
 endif
 
-$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_sockpair_1byte.o:  $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libend2end_certs.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_sockpair_1byte.o:  $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 
 deps_h2_sockpair_1byte_test: $(H2_SOCKPAIR_1BYTE_TEST_OBJS:.o=.dep)
 
@@ -12739,14 +12970,14 @@
 
 
 
-$(BINDIR)/$(CONFIG)/h2_ssl_test: $(H2_SSL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libend2end_certs.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(BINDIR)/$(CONFIG)/h2_ssl_test: $(H2_SSL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(LD) $(LDFLAGS) $(H2_SSL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libend2end_certs.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_ssl_test
+	$(Q) $(LD) $(LDFLAGS) $(H2_SSL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_ssl_test
 
 endif
 
-$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_ssl.o:  $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libend2end_certs.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_ssl.o:  $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 
 deps_h2_ssl_test: $(H2_SSL_TEST_OBJS:.o=.dep)
 
@@ -12771,14 +13002,14 @@
 
 
 
-$(BINDIR)/$(CONFIG)/h2_ssl+poll_test: $(H2_SSL+POLL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libend2end_certs.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(BINDIR)/$(CONFIG)/h2_ssl+poll_test: $(H2_SSL+POLL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(LD) $(LDFLAGS) $(H2_SSL+POLL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libend2end_certs.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_ssl+poll_test
+	$(Q) $(LD) $(LDFLAGS) $(H2_SSL+POLL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_ssl+poll_test
 
 endif
 
-$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_ssl+poll.o:  $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libend2end_certs.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_ssl+poll.o:  $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 
 deps_h2_ssl+poll_test: $(H2_SSL+POLL_TEST_OBJS:.o=.dep)
 
@@ -12803,14 +13034,14 @@
 
 
 
-$(BINDIR)/$(CONFIG)/h2_ssl_proxy_test: $(H2_SSL_PROXY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libend2end_certs.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(BINDIR)/$(CONFIG)/h2_ssl_proxy_test: $(H2_SSL_PROXY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(LD) $(LDFLAGS) $(H2_SSL_PROXY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libend2end_certs.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_ssl_proxy_test
+	$(Q) $(LD) $(LDFLAGS) $(H2_SSL_PROXY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_ssl_proxy_test
 
 endif
 
-$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_ssl_proxy.o:  $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libend2end_certs.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_ssl_proxy.o:  $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 
 deps_h2_ssl_proxy_test: $(H2_SSL_PROXY_TEST_OBJS:.o=.dep)
 
@@ -12835,14 +13066,14 @@
 
 
 
-$(BINDIR)/$(CONFIG)/h2_uchannel_test: $(H2_UCHANNEL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libend2end_certs.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(BINDIR)/$(CONFIG)/h2_uchannel_test: $(H2_UCHANNEL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(LD) $(LDFLAGS) $(H2_UCHANNEL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libend2end_certs.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_uchannel_test
+	$(Q) $(LD) $(LDFLAGS) $(H2_UCHANNEL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_uchannel_test
 
 endif
 
-$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_uchannel.o:  $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libend2end_certs.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_uchannel.o:  $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 
 deps_h2_uchannel_test: $(H2_UCHANNEL_TEST_OBJS:.o=.dep)
 
@@ -12867,14 +13098,14 @@
 
 
 
-$(BINDIR)/$(CONFIG)/h2_uds_test: $(H2_UDS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libend2end_certs.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(BINDIR)/$(CONFIG)/h2_uds_test: $(H2_UDS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(LD) $(LDFLAGS) $(H2_UDS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libend2end_certs.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_uds_test
+	$(Q) $(LD) $(LDFLAGS) $(H2_UDS_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_uds_test
 
 endif
 
-$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_uds.o:  $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libend2end_certs.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_uds.o:  $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 
 deps_h2_uds_test: $(H2_UDS_TEST_OBJS:.o=.dep)
 
@@ -12899,14 +13130,14 @@
 
 
 
-$(BINDIR)/$(CONFIG)/h2_uds+poll_test: $(H2_UDS+POLL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libend2end_certs.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(BINDIR)/$(CONFIG)/h2_uds+poll_test: $(H2_UDS+POLL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(LD) $(LDFLAGS) $(H2_UDS+POLL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libend2end_certs.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_uds+poll_test
+	$(Q) $(LD) $(LDFLAGS) $(H2_UDS+POLL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_uds+poll_test
 
 endif
 
-$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_uds+poll.o:  $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libend2end_certs.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_uds+poll.o:  $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 
 deps_h2_uds+poll_test: $(H2_UDS+POLL_TEST_OBJS:.o=.dep)
 
@@ -13037,6 +13268,26 @@
 endif
 
 
+H2_FULL+TRACE_NOSEC_TEST_SRC = \
+    test/core/end2end/fixtures/h2_full+trace.c \
+
+H2_FULL+TRACE_NOSEC_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(H2_FULL+TRACE_NOSEC_TEST_SRC))))
+
+
+$(BINDIR)/$(CONFIG)/h2_full+trace_nosec_test: $(H2_FULL+TRACE_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+	$(E) "[LD]      Linking $@"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(LD) $(LDFLAGS) $(H2_FULL+TRACE_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/h2_full+trace_nosec_test
+
+$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_full+trace.o:  $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+deps_h2_full+trace_nosec_test: $(H2_FULL+TRACE_NOSEC_TEST_OBJS:.o=.dep)
+
+ifneq ($(NO_DEPS),true)
+-include $(H2_FULL+TRACE_NOSEC_TEST_OBJS:.o=.dep)
+endif
+
+
 H2_PROXY_NOSEC_TEST_SRC = \
     test/core/end2end/fixtures/h2_proxy.c \
 
diff --git a/binding.gyp b/binding.gyp
index d1e086c..5f9dfd9 100644
--- a/binding.gyp
+++ b/binding.gyp
@@ -496,6 +496,7 @@
         'src/core/profiling/stap_timers.c',
         'src/core/support/alloc.c',
         'src/core/support/avl.c',
+        'src/core/support/backoff.c',
         'src/core/support/cmdline.c',
         'src/core/support/cpu_iphone.c',
         'src/core/support/cpu_linux.c',
@@ -559,8 +560,10 @@
       'sources': [
         'src/core/census/grpc_context.c',
         'src/core/census/grpc_filter.c',
+        'src/core/census/grpc_plugin.c',
         'src/core/channel/channel_args.c',
         'src/core/channel/channel_stack.c',
+        'src/core/channel/channel_stack_builder.c',
         'src/core/channel/client_channel.c',
         'src/core/channel/client_uchannel.c',
         'src/core/channel/compress_filter.c',
@@ -648,7 +651,9 @@
         'src/core/surface/channel.c',
         'src/core/surface/channel_connectivity.c',
         'src/core/surface/channel_create.c',
+        'src/core/surface/channel_init.c',
         'src/core/surface/channel_ping.c',
+        'src/core/surface/channel_stack_type.c',
         'src/core/surface/completion_queue.c',
         'src/core/surface/event_string.c',
         'src/core/surface/init.c',
@@ -656,7 +661,6 @@
         'src/core/surface/metadata_array.c',
         'src/core/surface/server.c',
         'src/core/surface/server_chttp2.c',
-        'src/core/surface/server_create.c',
         'src/core/surface/validate_metadata.c',
         'src/core/surface/version.c',
         'src/core/transport/byte_stream.c',
diff --git a/build.yaml b/build.yaml
index 83b7714..03ee95a 100644
--- a/build.yaml
+++ b/build.yaml
@@ -55,6 +55,7 @@
   - include/grpc/support/useful.h
   headers:
   - src/core/profiling/timers.h
+  - src/core/support/backoff.h
   - src/core/support/block_annotate.h
   - src/core/support/env.h
   - src/core/support/load_file.h
@@ -70,6 +71,7 @@
   - src/core/profiling/stap_timers.c
   - src/core/support/alloc.c
   - src/core/support/avl.c
+  - src/core/support/backoff.c
   - src/core/support/cmdline.c
   - src/core/support/cpu_iphone.c
   - src/core/support/cpu_linux.c
@@ -173,6 +175,7 @@
   - include/grpc++/support/time.h
   headers:
   - src/cpp/client/create_channel_internal.h
+  - src/cpp/common/core_codegen.h
   - src/cpp/common/create_auth_context.h
   - src/cpp/server/dynamic_thread_pool.h
   - src/cpp/server/thread_pool_interface.h
@@ -184,11 +187,10 @@
   - src/cpp/client/credentials.cc
   - src/cpp/client/generic_stub.cc
   - src/cpp/client/insecure_credentials.cc
-  - src/cpp/common/call.cc
   - src/cpp/common/channel_arguments.cc
   - src/cpp/common/completion_queue.cc
+  - src/cpp/common/core_codegen.cc
   - src/cpp/common/rpc_method.cc
-  - src/cpp/proto/proto_utils.cc
   - src/cpp/server/async_generic_service.cc
   - src/cpp/server/create_default_thread_pool.cc
   - src/cpp/server/dynamic_thread_pool.cc
@@ -215,6 +217,7 @@
   - include/grpc++/impl/codegen/completion_queue_tag.h
   - include/grpc++/impl/codegen/config.h
   - include/grpc++/impl/codegen/config_protobuf.h
+  - include/grpc++/impl/codegen/core_codegen_interface.h
   - include/grpc++/impl/codegen/grpc_library.h
   - include/grpc++/impl/codegen/method_handler_impl.h
   - include/grpc++/impl/codegen/proto_utils.h
@@ -235,7 +238,7 @@
   - include/grpc++/impl/codegen/sync_stream.h
   - include/grpc++/impl/codegen/time.h
   src:
-  - src/cpp/codegen/grpc_library.cc
+  - src/cpp/codegen/codegen_init.cc
 - name: grpc_base
   public_headers:
   - include/grpc/byte_buffer.h
@@ -245,8 +248,10 @@
   - include/grpc/status.h
   headers:
   - src/core/census/grpc_filter.h
+  - src/core/census/grpc_plugin.h
   - src/core/channel/channel_args.h
   - src/core/channel/channel_stack.h
+  - src/core/channel/channel_stack_builder.h
   - src/core/channel/client_channel.h
   - src/core/channel/client_uchannel.h
   - src/core/channel/compress_filter.h
@@ -326,9 +331,12 @@
   - src/core/surface/call.h
   - src/core/surface/call_test_only.h
   - src/core/surface/channel.h
+  - src/core/surface/channel_init.h
+  - src/core/surface/channel_stack_type.h
   - src/core/surface/completion_queue.h
   - src/core/surface/event_string.h
   - src/core/surface/init.h
+  - src/core/surface/lame_client.h
   - src/core/surface/server.h
   - src/core/surface/surface_trace.h
   - src/core/transport/byte_stream.h
@@ -362,8 +370,10 @@
   src:
   - src/core/census/grpc_context.c
   - src/core/census/grpc_filter.c
+  - src/core/census/grpc_plugin.c
   - src/core/channel/channel_args.c
   - src/core/channel/channel_stack.c
+  - src/core/channel/channel_stack_builder.c
   - src/core/channel/client_channel.c
   - src/core/channel/client_uchannel.c
   - src/core/channel/compress_filter.c
@@ -451,7 +461,9 @@
   - src/core/surface/channel.c
   - src/core/surface/channel_connectivity.c
   - src/core/surface/channel_create.c
+  - src/core/surface/channel_init.c
   - src/core/surface/channel_ping.c
+  - src/core/surface/channel_stack_type.c
   - src/core/surface/completion_queue.c
   - src/core/surface/event_string.c
   - src/core/surface/init.c
@@ -459,7 +471,6 @@
   - src/core/surface/metadata_array.c
   - src/core/surface/server.c
   - src/core/surface/server_chttp2.c
-  - src/core/surface/server_create.c
   - src/core/surface/validate_metadata.c
   - src/core/surface/version.c
   - src/core/transport/byte_stream.c
@@ -544,6 +555,7 @@
   - test/core/util/grpc_profiler.h
   - test/core/util/parse_hexstring.h
   - test/core/util/port.h
+  - test/core/util/port_server_client.h
   - test/core/util/slice_splitter.h
   src:
   - test/core/end2end/cq_verifier.c
@@ -552,6 +564,7 @@
   - test/core/util/grpc_profiler.c
   - test/core/util/parse_hexstring.c
   - test/core/util/port_posix.c
+  - test/core/util/port_server_client.c
   - test/core/util/port_windows.c
   - test/core/util/slice_splitter.c
 - name: nanopb
@@ -595,9 +608,9 @@
   deps_linkage: static
   dll: true
   filegroups:
-  - grpc_codegen
   - grpc_base
   - grpc_secure
+  - grpc_codegen
   - census
   - nanopb
   secure: true
@@ -605,6 +618,16 @@
   - grpc.dependencies.openssl
   - grpc.dependencies.zlib
   vs_project_guid: '{29D16885-7228-4C31-81ED-5F9187C7F2A9}'
+- name: grpc_codegen_lib
+  build: protoc
+  language: c
+  headers: []
+  src: []
+  filegroups:
+  - gpr_codegen
+  - grpc_codegen
+  secure: false
+  vs_project_guid: '{A828FD72-44CE-4EA5-8966-6E4624458D58}'
 - name: grpc_dll
   build: private
   language: c
@@ -719,6 +742,7 @@
   language: c++
   headers:
   - src/cpp/client/secure_credentials.h
+  - src/cpp/common/core_codegen.h
   - src/cpp/common/secure_auth_context.h
   - src/cpp/server/secure_server_credentials.h
   src:
@@ -737,6 +761,17 @@
   - grpc++_codegen
   secure: check
   vs_project_guid: '{C187A093-A0FE-489D-A40A-6E33DE0F9FEB}'
+- name: grpc++_codegen_lib
+  build: protoc
+  language: c++
+  headers: []
+  src: []
+  filegroups:
+  - gpr_codegen
+  - grpc_codegen
+  - grpc++_codegen
+  secure: false
+  vs_project_guid: '{AAC6AF12-94C8-4A3C-A1BF-DAA4738F4500}'
 - name: grpc++_test_config
   build: private
   language: c++
@@ -809,10 +844,9 @@
   - src/compiler/objective_c_generator.cc
   - src/compiler/python_generator.cc
   - src/compiler/ruby_generator.cc
-  deps: []
+  deps:
+  - grpc++_codegen_lib
   filegroups:
-  - grpc++_codegen
-  - grpc_codegen
   - gpr_codegen
   secure: false
   vs_project_guid: '{B6E81D84-2ACB-41B8-8781-493A944C7817}'
@@ -1215,6 +1249,14 @@
   deps:
   - gpr_test_util
   - gpr
+- name: gpr_backoff_test
+  build: test
+  language: c
+  src:
+  - test/core/support/backoff_test.c
+  deps:
+  - gpr_test_util
+  - gpr
 - name: gpr_cmdline_test
   build: test
   language: c
@@ -1639,6 +1681,7 @@
   - gpr
 - name: lb_policies_test
   cpu_cost: 0.1
+  flaky: true
   build: test
   language: c
   src:
@@ -2100,6 +2143,20 @@
   - grpc
   - gpr_test_util
   - gpr
+- name: codegen_test
+  gtest: true
+  build: test
+  language: c++
+  src:
+  - src/proto/grpc/testing/control.proto
+  - src/proto/grpc/testing/messages.proto
+  - src/proto/grpc/testing/payloads.proto
+  - src/proto/grpc/testing/perf_db.proto
+  - src/proto/grpc/testing/services.proto
+  - src/proto/grpc/testing/stats.proto
+  - test/cpp/codegen/codegen_test.cc
+  deps:
+  - grpc++_codegen_lib
 - name: credentials_test
   gtest: true
   build: test
@@ -2400,7 +2457,7 @@
   - linux
   - posix
 - name: qps_openloop_test
-  cpu_cost: 10
+  cpu_cost: 0.5
   build: test
   language: c++
   src:
@@ -2414,6 +2471,8 @@
   - gpr_test_util
   - gpr
   - grpc++_test_config
+  exclude_configs:
+  - tsan
   platforms:
   - mac
   - linux
@@ -2433,6 +2492,8 @@
   - gpr_test_util
   - gpr
   - grpc++_test_config
+  exclude_configs:
+  - tsan
   platforms:
   - mac
   - linux
@@ -2745,6 +2806,36 @@
   dbg:
     CPPFLAGS: -O0
     DEFINES: _DEBUG DEBUG
+  easan:
+    CC: clang
+    CPPFLAGS: -O0 -fsanitize=address -fno-omit-frame-pointer -Wno-unused-command-line-argument
+      -DGPR_NO_DIRECT_SYSCALLS
+    CXX: clang++
+    DEFINES: _DEBUG DEBUG GRPC_EXECUTION_CONTEXT_SANITIZER
+    LD: clang
+    LDFLAGS: -fsanitize=address
+    LDXX: clang++
+    compile_the_world: true
+    test_environ:
+      ASAN_OPTIONS: detect_leaks=1:color=always
+      LSAN_OPTIONS: suppressions=tools/lsan_suppressions.txt:report_objects=1
+    timeout_multiplier: 3
+  edbg:
+    CPPFLAGS: -O0
+    DEFINES: _DEBUG DEBUG GRPC_EXECUTION_CONTEXT_SANITIZER
+  etsan:
+    CC: clang
+    CPPFLAGS: -O0 -fsanitize=thread -fno-omit-frame-pointer -Wno-unused-command-line-argument
+      -fPIE -pie -DGPR_NO_DIRECT_SYSCALLS
+    CXX: clang++
+    DEFINES: _DEBUG DEBUG GRPC_EXECUTION_CONTEXT_SANITIZER
+    LD: clang
+    LDFLAGS: -fsanitize=thread -fPIE -pie $(if $(JENKINS_BUILD),-Wl$(comma)-Ttext-segment=0x7e0000000000,)
+    LDXX: clang++
+    compile_the_world: true
+    test_environ:
+      TSAN_OPTIONS: suppressions=tools/tsan_suppressions.txt:halt_on_error=1:second_deadlock_stack=1
+    timeout_multiplier: 5
   gcov:
     CC: gcc
     CPPFLAGS: -O0 -fprofile-arcs -ftest-coverage -Wno-return-type
@@ -2859,7 +2950,7 @@
   - src/node/ext/server_credentials.cc
   - src/node/ext/timeval.cc
 openssl_fallback:
-  base_uri: http://openssl.org/source/
+  base_uri: https://openssl.org/source/old/1.0.2/
   extraction_dir: openssl-1.0.2f
   tarball: openssl-1.0.2f.tar.gz
 php_config_m4:
diff --git a/config.m4 b/config.m4
index 8ab45e6..91b87e2 100644
--- a/config.m4
+++ b/config.m4
@@ -40,6 +40,7 @@
     src/core/profiling/stap_timers.c \
     src/core/support/alloc.c \
     src/core/support/avl.c \
+    src/core/support/backoff.c \
     src/core/support/cmdline.c \
     src/core/support/cpu_iphone.c \
     src/core/support/cpu_linux.c \
@@ -81,8 +82,10 @@
     src/core/support/wrap_memcpy.c \
     src/core/census/grpc_context.c \
     src/core/census/grpc_filter.c \
+    src/core/census/grpc_plugin.c \
     src/core/channel/channel_args.c \
     src/core/channel/channel_stack.c \
+    src/core/channel/channel_stack_builder.c \
     src/core/channel/client_channel.c \
     src/core/channel/client_uchannel.c \
     src/core/channel/compress_filter.c \
@@ -170,7 +173,9 @@
     src/core/surface/channel.c \
     src/core/surface/channel_connectivity.c \
     src/core/surface/channel_create.c \
+    src/core/surface/channel_init.c \
     src/core/surface/channel_ping.c \
+    src/core/surface/channel_stack_type.c \
     src/core/surface/completion_queue.c \
     src/core/surface/event_string.c \
     src/core/surface/init.c \
@@ -178,7 +183,6 @@
     src/core/surface/metadata_array.c \
     src/core/surface/server.c \
     src/core/surface/server_chttp2.c \
-    src/core/surface/server_create.c \
     src/core/surface/validate_metadata.c \
     src/core/surface/version.c \
     src/core/transport/byte_stream.c \
diff --git a/examples/cpp/helloworld/README.md b/examples/cpp/helloworld/README.md
index 8e11f7c..04283ea 100644
--- a/examples/cpp/helloworld/README.md
+++ b/examples/cpp/helloworld/README.md
@@ -207,7 +207,7 @@
     helloworld::Greeter::AsyncService service;
     ServerBuilder builder;
     builder.AddListeningPort("0.0.0.0:50051", InsecureServerCredentials());
-    builder.RegisterAsyncService(&service);
+    builder.RegisterService(&service);
     auto cq = builder.AddCompletionQueue();
     auto server = builder.BuildAndStart();
     ```
diff --git a/examples/node/package.json b/examples/node/package.json
index 00ba428..d135df2 100644
--- a/examples/node/package.json
+++ b/examples/node/package.json
@@ -2,6 +2,9 @@
   "name": "grpc-examples",
   "version": "0.1.0",
   "dependencies": {
-    "grpc": "0.13.0"
+    "async": "^1.5.2",
+    "grpc": "0.13.0",
+    "lodash": "^4.6.1",
+    "minimist": "^1.2.0"
   }
 }
diff --git a/examples/ruby/route_guide/route_guide_client.rb b/examples/ruby/route_guide/route_guide_client.rb
index 715a3c0..86dd1fe 100755
--- a/examples/ruby/route_guide/route_guide_client.rb
+++ b/examples/ruby/route_guide/route_guide_client.rb
@@ -38,6 +38,7 @@
 $LOAD_PATH.unshift(lib_dir) unless $LOAD_PATH.include?(lib_dir)
 
 require 'grpc'
+require 'multi_json'
 require 'route_guide_services'
 
 include Routeguide
@@ -115,9 +116,8 @@
   p 'RecordRoute'
   p '-----------'
   points_on_route = 10  # arbitrary
-  deadline = points_on_route  # as delay b/w each is max 1 second
   reqs = RandomRoute.new(features, points_on_route)
-  resp = stub.record_route(reqs.each, deadline)
+  resp = stub.record_route(reqs.each)
   p "summary: #{resp.inspect}"
 end
 
diff --git a/gRPC.podspec b/gRPC.podspec
index f3103ea..86121c9 100644
--- a/gRPC.podspec
+++ b/gRPC.podspec
@@ -64,6 +64,7 @@
   # Core cross-platform gRPC library, written in C.
   s.subspec 'C-Core' do |ss|
     ss.source_files = 'src/core/profiling/timers.h',
+                      'src/core/support/backoff.h',
                       'src/core/support/block_annotate.h',
                       'src/core/support/env.h',
                       'src/core/support/load_file.h',
@@ -120,6 +121,7 @@
                       'src/core/profiling/stap_timers.c',
                       'src/core/support/alloc.c',
                       'src/core/support/avl.c',
+                      'src/core/support/backoff.c',
                       'src/core/support/cmdline.c',
                       'src/core/support/cpu_iphone.c',
                       'src/core/support/cpu_linux.c',
@@ -160,8 +162,10 @@
                       'src/core/support/tmpfile_win32.c',
                       'src/core/support/wrap_memcpy.c',
                       'src/core/census/grpc_filter.h',
+                      'src/core/census/grpc_plugin.h',
                       'src/core/channel/channel_args.h',
                       'src/core/channel/channel_stack.h',
+                      'src/core/channel/channel_stack_builder.h',
                       'src/core/channel/client_channel.h',
                       'src/core/channel/client_uchannel.h',
                       'src/core/channel/compress_filter.h',
@@ -241,9 +245,12 @@
                       'src/core/surface/call.h',
                       'src/core/surface/call_test_only.h',
                       'src/core/surface/channel.h',
+                      'src/core/surface/channel_init.h',
+                      'src/core/surface/channel_stack_type.h',
                       'src/core/surface/completion_queue.h',
                       'src/core/surface/event_string.h',
                       'src/core/surface/init.h',
+                      'src/core/surface/lame_client.h',
                       'src/core/surface/server.h',
                       'src/core/surface/surface_trace.h',
                       'src/core/transport/byte_stream.h',
@@ -296,22 +303,24 @@
                       'third_party/nanopb/pb_decode.h',
                       'third_party/nanopb/pb_encode.h',
                       'include/grpc/grpc_security.h',
+                      'include/grpc/byte_buffer.h',
+                      'include/grpc/byte_buffer_reader.h',
+                      'include/grpc/compression.h',
+                      'include/grpc/grpc.h',
+                      'include/grpc/status.h',
                       'include/grpc/impl/codegen/byte_buffer.h',
                       'include/grpc/impl/codegen/compression_types.h',
                       'include/grpc/impl/codegen/connectivity_state.h',
                       'include/grpc/impl/codegen/grpc_types.h',
                       'include/grpc/impl/codegen/propagation_bits.h',
                       'include/grpc/impl/codegen/status.h',
-                      'include/grpc/byte_buffer.h',
-                      'include/grpc/byte_buffer_reader.h',
-                      'include/grpc/compression.h',
-                      'include/grpc/grpc.h',
-                      'include/grpc/status.h',
                       'include/grpc/census.h',
                       'src/core/census/grpc_context.c',
                       'src/core/census/grpc_filter.c',
+                      'src/core/census/grpc_plugin.c',
                       'src/core/channel/channel_args.c',
                       'src/core/channel/channel_stack.c',
+                      'src/core/channel/channel_stack_builder.c',
                       'src/core/channel/client_channel.c',
                       'src/core/channel/client_uchannel.c',
                       'src/core/channel/compress_filter.c',
@@ -399,7 +408,9 @@
                       'src/core/surface/channel.c',
                       'src/core/surface/channel_connectivity.c',
                       'src/core/surface/channel_create.c',
+                      'src/core/surface/channel_init.c',
                       'src/core/surface/channel_ping.c',
+                      'src/core/surface/channel_stack_type.c',
                       'src/core/surface/completion_queue.c',
                       'src/core/surface/event_string.c',
                       'src/core/surface/init.c',
@@ -407,7 +418,6 @@
                       'src/core/surface/metadata_array.c',
                       'src/core/surface/server.c',
                       'src/core/surface/server_chttp2.c',
-                      'src/core/surface/server_create.c',
                       'src/core/surface/validate_metadata.c',
                       'src/core/surface/version.c',
                       'src/core/transport/byte_stream.c',
@@ -470,6 +480,7 @@
                       'third_party/nanopb/pb_encode.c'
 
     ss.private_header_files = 'src/core/profiling/timers.h',
+                              'src/core/support/backoff.h',
                               'src/core/support/block_annotate.h',
                               'src/core/support/env.h',
                               'src/core/support/load_file.h',
@@ -481,8 +492,10 @@
                               'src/core/support/time_precise.h',
                               'src/core/support/tmpfile.h',
                               'src/core/census/grpc_filter.h',
+                              'src/core/census/grpc_plugin.h',
                               'src/core/channel/channel_args.h',
                               'src/core/channel/channel_stack.h',
+                              'src/core/channel/channel_stack_builder.h',
                               'src/core/channel/client_channel.h',
                               'src/core/channel/client_uchannel.h',
                               'src/core/channel/compress_filter.h',
@@ -562,9 +575,12 @@
                               'src/core/surface/call.h',
                               'src/core/surface/call_test_only.h',
                               'src/core/surface/channel.h',
+                              'src/core/surface/channel_init.h',
+                              'src/core/surface/channel_stack_type.h',
                               'src/core/surface/completion_queue.h',
                               'src/core/surface/event_string.h',
                               'src/core/surface/init.h',
+                              'src/core/surface/lame_client.h',
                               'src/core/surface/server.h',
                               'src/core/surface/surface_trace.h',
                               'src/core/transport/byte_stream.h',
diff --git a/grpc.gemspec b/grpc.gemspec
index 1b3f15e..c062622 100755
--- a/grpc.gemspec
+++ b/grpc.gemspec
@@ -89,6 +89,7 @@
   s.files += %w( include/grpc/impl/codegen/sync_win32.h )
   s.files += %w( include/grpc/impl/codegen/time.h )
   s.files += %w( src/core/profiling/timers.h )
+  s.files += %w( src/core/support/backoff.h )
   s.files += %w( src/core/support/block_annotate.h )
   s.files += %w( src/core/support/env.h )
   s.files += %w( src/core/support/load_file.h )
@@ -103,6 +104,7 @@
   s.files += %w( src/core/profiling/stap_timers.c )
   s.files += %w( src/core/support/alloc.c )
   s.files += %w( src/core/support/avl.c )
+  s.files += %w( src/core/support/backoff.c )
   s.files += %w( src/core/support/cmdline.c )
   s.files += %w( src/core/support/cpu_iphone.c )
   s.files += %w( src/core/support/cpu_linux.c )
@@ -143,21 +145,23 @@
   s.files += %w( src/core/support/tmpfile_win32.c )
   s.files += %w( src/core/support/wrap_memcpy.c )
   s.files += %w( include/grpc/grpc_security.h )
+  s.files += %w( include/grpc/byte_buffer.h )
+  s.files += %w( include/grpc/byte_buffer_reader.h )
+  s.files += %w( include/grpc/compression.h )
+  s.files += %w( include/grpc/grpc.h )
+  s.files += %w( include/grpc/status.h )
   s.files += %w( include/grpc/impl/codegen/byte_buffer.h )
   s.files += %w( include/grpc/impl/codegen/compression_types.h )
   s.files += %w( include/grpc/impl/codegen/connectivity_state.h )
   s.files += %w( include/grpc/impl/codegen/grpc_types.h )
   s.files += %w( include/grpc/impl/codegen/propagation_bits.h )
   s.files += %w( include/grpc/impl/codegen/status.h )
-  s.files += %w( include/grpc/byte_buffer.h )
-  s.files += %w( include/grpc/byte_buffer_reader.h )
-  s.files += %w( include/grpc/compression.h )
-  s.files += %w( include/grpc/grpc.h )
-  s.files += %w( include/grpc/status.h )
   s.files += %w( include/grpc/census.h )
   s.files += %w( src/core/census/grpc_filter.h )
+  s.files += %w( src/core/census/grpc_plugin.h )
   s.files += %w( src/core/channel/channel_args.h )
   s.files += %w( src/core/channel/channel_stack.h )
+  s.files += %w( src/core/channel/channel_stack_builder.h )
   s.files += %w( src/core/channel/client_channel.h )
   s.files += %w( src/core/channel/client_uchannel.h )
   s.files += %w( src/core/channel/compress_filter.h )
@@ -237,9 +241,12 @@
   s.files += %w( src/core/surface/call.h )
   s.files += %w( src/core/surface/call_test_only.h )
   s.files += %w( src/core/surface/channel.h )
+  s.files += %w( src/core/surface/channel_init.h )
+  s.files += %w( src/core/surface/channel_stack_type.h )
   s.files += %w( src/core/surface/completion_queue.h )
   s.files += %w( src/core/surface/event_string.h )
   s.files += %w( src/core/surface/init.h )
+  s.files += %w( src/core/surface/lame_client.h )
   s.files += %w( src/core/surface/server.h )
   s.files += %w( src/core/surface/surface_trace.h )
   s.files += %w( src/core/transport/byte_stream.h )
@@ -293,8 +300,10 @@
   s.files += %w( third_party/nanopb/pb_encode.h )
   s.files += %w( src/core/census/grpc_context.c )
   s.files += %w( src/core/census/grpc_filter.c )
+  s.files += %w( src/core/census/grpc_plugin.c )
   s.files += %w( src/core/channel/channel_args.c )
   s.files += %w( src/core/channel/channel_stack.c )
+  s.files += %w( src/core/channel/channel_stack_builder.c )
   s.files += %w( src/core/channel/client_channel.c )
   s.files += %w( src/core/channel/client_uchannel.c )
   s.files += %w( src/core/channel/compress_filter.c )
@@ -382,7 +391,9 @@
   s.files += %w( src/core/surface/channel.c )
   s.files += %w( src/core/surface/channel_connectivity.c )
   s.files += %w( src/core/surface/channel_create.c )
+  s.files += %w( src/core/surface/channel_init.c )
   s.files += %w( src/core/surface/channel_ping.c )
+  s.files += %w( src/core/surface/channel_stack_type.c )
   s.files += %w( src/core/surface/completion_queue.c )
   s.files += %w( src/core/surface/event_string.c )
   s.files += %w( src/core/surface/init.c )
@@ -390,7 +401,6 @@
   s.files += %w( src/core/surface/metadata_array.c )
   s.files += %w( src/core/surface/server.c )
   s.files += %w( src/core/surface/server_chttp2.c )
-  s.files += %w( src/core/surface/server_create.c )
   s.files += %w( src/core/surface/validate_metadata.c )
   s.files += %w( src/core/surface/version.c )
   s.files += %w( src/core/transport/byte_stream.c )
diff --git a/include/grpc++/alarm.h b/include/grpc++/alarm.h
index 3b8104d..764837a 100644
--- a/include/grpc++/alarm.h
+++ b/include/grpc++/alarm.h
@@ -50,7 +50,7 @@
 class CompletionQueue;
 
 /// A thin wrapper around \a grpc_alarm (see / \a / src/core/surface/alarm.h).
-class Alarm : private GrpcLibrary {
+class Alarm : private GrpcLibraryCodegen {
  public:
   /// Create a completion queue alarm instance associated to \a cq.
   ///
diff --git a/include/grpc++/channel.h b/include/grpc++/channel.h
index 80547f7..679d473 100644
--- a/include/grpc++/channel.h
+++ b/include/grpc++/channel.h
@@ -49,7 +49,7 @@
 class Channel GRPC_FINAL : public ChannelInterface,
                            public CallHook,
                            public std::enable_shared_from_this<Channel>,
-                           private GrpcLibrary {
+                           private GrpcLibraryCodegen {
  public:
   ~Channel();
 
diff --git a/include/grpc++/impl/codegen/async_stream.h b/include/grpc++/impl/codegen/async_stream.h
index b041048..8f9afe8 100644
--- a/include/grpc++/impl/codegen/async_stream.h
+++ b/include/grpc++/impl/codegen/async_stream.h
@@ -34,10 +34,11 @@
 #ifndef GRPCXX_IMPL_CODEGEN_ASYNC_STREAM_H
 #define GRPCXX_IMPL_CODEGEN_ASYNC_STREAM_H
 
-#include <grpc++/impl/codegen/channel_interface.h>
 #include <grpc++/impl/codegen/call.h>
-#include <grpc++/impl/codegen/service_type.h>
+#include <grpc++/impl/codegen/channel_interface.h>
+#include <grpc++/impl/codegen/core_codegen_interface.h>
 #include <grpc++/impl/codegen/server_context.h>
+#include <grpc++/impl/codegen/service_type.h>
 #include <grpc++/impl/codegen/status.h>
 
 namespace grpc {
@@ -109,13 +110,13 @@
     init_ops_.set_output_tag(tag);
     init_ops_.SendInitialMetadata(context->send_initial_metadata_);
     // TODO(ctiller): don't assert
-    GPR_ASSERT(init_ops_.SendMessage(request).ok());
+    GPR_CODEGEN_ASSERT(init_ops_.SendMessage(request).ok());
     init_ops_.ClientSendClose();
     call_.PerformOps(&init_ops_);
   }
 
   void ReadInitialMetadata(void* tag) GRPC_OVERRIDE {
-    GPR_ASSERT(!context_->initial_metadata_received_);
+    GPR_CODEGEN_ASSERT(!context_->initial_metadata_received_);
 
     meta_ops_.set_output_tag(tag);
     meta_ops_.RecvInitialMetadata(context_);
@@ -177,7 +178,7 @@
   }
 
   void ReadInitialMetadata(void* tag) GRPC_OVERRIDE {
-    GPR_ASSERT(!context_->initial_metadata_received_);
+    GPR_CODEGEN_ASSERT(!context_->initial_metadata_received_);
 
     meta_ops_.set_output_tag(tag);
     meta_ops_.RecvInitialMetadata(context_);
@@ -187,7 +188,7 @@
   void Write(const W& msg, void* tag) GRPC_OVERRIDE {
     write_ops_.set_output_tag(tag);
     // TODO(ctiller): don't assert
-    GPR_ASSERT(write_ops_.SendMessage(msg).ok());
+    GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg).ok());
     call_.PerformOps(&write_ops_);
   }
 
@@ -243,7 +244,7 @@
   }
 
   void ReadInitialMetadata(void* tag) GRPC_OVERRIDE {
-    GPR_ASSERT(!context_->initial_metadata_received_);
+    GPR_CODEGEN_ASSERT(!context_->initial_metadata_received_);
 
     meta_ops_.set_output_tag(tag);
     meta_ops_.RecvInitialMetadata(context_);
@@ -262,7 +263,7 @@
   void Write(const W& msg, void* tag) GRPC_OVERRIDE {
     write_ops_.set_output_tag(tag);
     // TODO(ctiller): don't assert
-    GPR_ASSERT(write_ops_.SendMessage(msg).ok());
+    GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg).ok());
     call_.PerformOps(&write_ops_);
   }
 
@@ -300,7 +301,7 @@
       : call_(nullptr, nullptr, nullptr), ctx_(ctx) {}
 
   void SendInitialMetadata(void* tag) GRPC_OVERRIDE {
-    GPR_ASSERT(!ctx_->sent_initial_metadata_);
+    GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_);
 
     meta_ops_.set_output_tag(tag);
     meta_ops_.SendInitialMetadata(ctx_->initial_metadata_);
@@ -331,7 +332,7 @@
   }
 
   void FinishWithError(const Status& status, void* tag) {
-    GPR_ASSERT(!status.ok());
+    GPR_CODEGEN_ASSERT(!status.ok());
     finish_ops_.set_output_tag(tag);
     if (!ctx_->sent_initial_metadata_) {
       finish_ops_.SendInitialMetadata(ctx_->initial_metadata_);
@@ -360,7 +361,7 @@
       : call_(nullptr, nullptr, nullptr), ctx_(ctx) {}
 
   void SendInitialMetadata(void* tag) GRPC_OVERRIDE {
-    GPR_ASSERT(!ctx_->sent_initial_metadata_);
+    GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_);
 
     meta_ops_.set_output_tag(tag);
     meta_ops_.SendInitialMetadata(ctx_->initial_metadata_);
@@ -375,7 +376,7 @@
       ctx_->sent_initial_metadata_ = true;
     }
     // TODO(ctiller): don't assert
-    GPR_ASSERT(write_ops_.SendMessage(msg).ok());
+    GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg).ok());
     call_.PerformOps(&write_ops_);
   }
 
@@ -409,7 +410,7 @@
       : call_(nullptr, nullptr, nullptr), ctx_(ctx) {}
 
   void SendInitialMetadata(void* tag) GRPC_OVERRIDE {
-    GPR_ASSERT(!ctx_->sent_initial_metadata_);
+    GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_);
 
     meta_ops_.set_output_tag(tag);
     meta_ops_.SendInitialMetadata(ctx_->initial_metadata_);
@@ -430,7 +431,7 @@
       ctx_->sent_initial_metadata_ = true;
     }
     // TODO(ctiller): don't assert
-    GPR_ASSERT(write_ops_.SendMessage(msg).ok());
+    GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg).ok());
     call_.PerformOps(&write_ops_);
   }
 
diff --git a/include/grpc++/impl/codegen/async_unary_call.h b/include/grpc++/impl/codegen/async_unary_call.h
index f3c75dc..9c6dbd5 100644
--- a/include/grpc++/impl/codegen/async_unary_call.h
+++ b/include/grpc++/impl/codegen/async_unary_call.h
@@ -45,6 +45,7 @@
 namespace grpc {
 
 class CompletionQueue;
+extern CoreCodegenInterface* g_core_codegen_interface;
 
 template <class R>
 class ClientAsyncResponseReaderInterface {
@@ -68,13 +69,13 @@
     collection_->init_buf_.SetCollection(collection_);
     collection_->init_buf_.SendInitialMetadata(context->send_initial_metadata_);
     // TODO(ctiller): don't assert
-    GPR_ASSERT(collection_->init_buf_.SendMessage(request).ok());
+    GPR_CODEGEN_ASSERT(collection_->init_buf_.SendMessage(request).ok());
     collection_->init_buf_.ClientSendClose();
     call_.PerformOps(&collection_->init_buf_);
   }
 
   void ReadInitialMetadata(void* tag) {
-    GPR_ASSERT(!context_->initial_metadata_received_);
+    GPR_CODEGEN_ASSERT(!context_->initial_metadata_received_);
 
     collection_->meta_buf_.SetCollection(collection_);
     collection_->meta_buf_.set_output_tag(tag);
@@ -116,7 +117,7 @@
       : call_(nullptr, nullptr, nullptr), ctx_(ctx) {}
 
   void SendInitialMetadata(void* tag) GRPC_OVERRIDE {
-    GPR_ASSERT(!ctx_->sent_initial_metadata_);
+    GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_);
 
     meta_buf_.set_output_tag(tag);
     meta_buf_.SendInitialMetadata(ctx_->initial_metadata_);
@@ -141,7 +142,7 @@
   }
 
   void FinishWithError(const Status& status, void* tag) {
-    GPR_ASSERT(!status.ok());
+    GPR_CODEGEN_ASSERT(!status.ok());
     finish_buf_.set_output_tag(tag);
     if (!ctx_->sent_initial_metadata_) {
       finish_buf_.SendInitialMetadata(ctx_->initial_metadata_);
diff --git a/include/grpc++/impl/codegen/call.h b/include/grpc++/impl/codegen/call.h
index 5e450b0..03affc2 100644
--- a/include/grpc++/impl/codegen/call.h
+++ b/include/grpc++/impl/codegen/call.h
@@ -34,19 +34,21 @@
 #ifndef GRPCXX_IMPL_CODEGEN_CALL_H
 #define GRPCXX_IMPL_CODEGEN_CALL_H
 
-#include <functional>
-#include <memory>
-#include <map>
 #include <cstring>
+#include <functional>
+#include <map>
+#include <memory>
 
+#include <grpc++/impl/codegen/call_hook.h>
+#include <grpc++/impl/codegen/client_context.h>
+#include <grpc++/impl/codegen/completion_queue_tag.h>
+#include <grpc++/impl/codegen/config.h>
+#include <grpc++/impl/codegen/core_codegen_interface.h>
+#include <grpc++/impl/codegen/serialization_traits.h>
+#include <grpc++/impl/codegen/status.h>
+#include <grpc++/impl/codegen/string_ref.h>
 #include <grpc/impl/codegen/alloc.h>
 #include <grpc/impl/codegen/grpc_types.h>
-#include <grpc++/impl/codegen/client_context.h>
-#include <grpc++/impl/codegen/call_hook.h>
-#include <grpc++/impl/codegen/completion_queue_tag.h>
-#include <grpc++/impl/codegen/serialization_traits.h>
-#include <grpc++/impl/codegen/config.h>
-#include <grpc++/impl/codegen/status.h>
 
 struct grpc_byte_buffer;
 
@@ -56,12 +58,39 @@
 class Call;
 class CallHook;
 class CompletionQueue;
+extern CoreCodegenInterface* g_core_codegen_interface;
 
-void FillMetadataMap(
+inline void FillMetadataMap(
     grpc_metadata_array* arr,
-    std::multimap<grpc::string_ref, grpc::string_ref>* metadata);
-grpc_metadata* FillMetadataArray(
-    const std::multimap<grpc::string, grpc::string>& metadata);
+    std::multimap<grpc::string_ref, grpc::string_ref>* metadata) {
+  for (size_t i = 0; i < arr->count; i++) {
+    // TODO(yangg) handle duplicates?
+    metadata->insert(std::pair<grpc::string_ref, grpc::string_ref>(
+        arr->metadata[i].key, grpc::string_ref(arr->metadata[i].value,
+                                               arr->metadata[i].value_length)));
+  }
+  g_core_codegen_interface->grpc_metadata_array_destroy(arr);
+  g_core_codegen_interface->grpc_metadata_array_init(arr);
+}
+
+// TODO(yangg) if the map is changed before we send, the pointers will be a
+// mess. Make sure it does not happen.
+inline grpc_metadata* FillMetadataArray(
+    const std::multimap<grpc::string, grpc::string>& metadata) {
+  if (metadata.empty()) {
+    return nullptr;
+  }
+  grpc_metadata* metadata_array =
+      (grpc_metadata*)(g_core_codegen_interface->gpr_malloc(
+          metadata.size() * sizeof(grpc_metadata)));
+  size_t i = 0;
+  for (auto iter = metadata.cbegin(); iter != metadata.cend(); ++iter, ++i) {
+    metadata_array[i].key = iter->first.c_str();
+    metadata_array[i].value = iter->second.c_str();
+    metadata_array[i].value_length = iter->second.size();
+  }
+  return metadata_array;
+}
 
 /// Per-message write options.
 class WriteOptions {
@@ -170,7 +199,7 @@
   }
   void FinishOp(bool* status, int max_message_size) {
     if (!send_) return;
-    gpr_free(initial_metadata_);
+    g_core_codegen_interface->gpr_free(initial_metadata_);
     send_ = false;
   }
 
@@ -204,7 +233,7 @@
     write_options_.Clear();
   }
   void FinishOp(bool* status, int max_message_size) {
-    if (own_buf_) grpc_byte_buffer_destroy(send_buf_);
+    if (own_buf_) g_core_codegen_interface->grpc_byte_buffer_destroy(send_buf_);
     send_buf_ = nullptr;
   }
 
@@ -254,7 +283,7 @@
                                                       max_message_size).ok();
       } else {
         got_message = false;
-        grpc_byte_buffer_destroy(recv_buf_);
+        g_core_codegen_interface->grpc_byte_buffer_destroy(recv_buf_);
       }
     } else {
       got_message = false;
@@ -321,7 +350,7 @@
         *status = deserialize_->Deserialize(recv_buf_, max_message_size).ok();
       } else {
         got_message = false;
-        grpc_byte_buffer_destroy(recv_buf_);
+        g_core_codegen_interface->grpc_byte_buffer_destroy(recv_buf_);
       }
     } else {
       got_message = false;
@@ -386,7 +415,7 @@
 
   void FinishOp(bool* status, int max_message_size) {
     if (!send_status_available_) return;
-    gpr_free(trailing_metadata_);
+    g_core_codegen_interface->gpr_free(trailing_metadata_);
     send_status_available_ = false;
   }
 
@@ -462,7 +491,7 @@
     *recv_status_ = Status(
         static_cast<StatusCode>(status_code_),
         status_details_ ? grpc::string(status_details_) : grpc::string());
-    gpr_free(status_details_);
+    g_core_codegen_interface->gpr_free(status_details_);
     recv_status_ = nullptr;
   }
 
@@ -576,11 +605,22 @@
 class Call GRPC_FINAL {
  public:
   /* call is owned by the caller */
-  Call(grpc_call* call, CallHook* call_hook_, CompletionQueue* cq);
-  Call(grpc_call* call, CallHook* call_hook_, CompletionQueue* cq,
-       int max_message_size);
+  Call(grpc_call* call, CallHook* call_hook, CompletionQueue* cq)
+      : call_hook_(call_hook), cq_(cq), call_(call), max_message_size_(-1) {}
 
-  void PerformOps(CallOpSetInterface* ops);
+  Call(grpc_call* call, CallHook* call_hook, CompletionQueue* cq,
+       int max_message_size)
+      : call_hook_(call_hook),
+        cq_(cq),
+        call_(call),
+        max_message_size_(max_message_size) {}
+
+  void PerformOps(CallOpSetInterface* ops) {
+    if (max_message_size_ > 0) {
+      ops->set_max_message_size(max_message_size_);
+    }
+    call_hook_->PerformOpsOnCall(ops, this);
+  }
 
   grpc_call* call() { return call_; }
   CompletionQueue* cq() { return cq_; }
diff --git a/include/grpc++/impl/codegen/client_context.h b/include/grpc++/impl/codegen/client_context.h
index db2afe9..271d464 100644
--- a/include/grpc++/impl/codegen/client_context.h
+++ b/include/grpc++/impl/codegen/client_context.h
@@ -54,6 +54,7 @@
 #include <string>
 
 #include <grpc++/impl/codegen/config.h>
+#include <grpc++/impl/codegen/core_codegen_interface.h>
 #include <grpc++/impl/codegen/security/auth_context.h>
 #include <grpc++/impl/codegen/status.h>
 #include <grpc++/impl/codegen/string_ref.h>
@@ -192,7 +193,7 @@
   /// \return A multimap of initial metadata key-value pairs from the server.
   const std::multimap<grpc::string_ref, grpc::string_ref>&
   GetServerInitialMetadata() {
-    GPR_ASSERT(initial_metadata_received_);
+    GPR_CODEGEN_ASSERT(initial_metadata_received_);
     return recv_initial_metadata_;
   }
 
diff --git a/include/grpc++/impl/codegen/client_unary_call.h b/include/grpc++/impl/codegen/client_unary_call.h
index 0134dec..a2b7d92 100644
--- a/include/grpc++/impl/codegen/client_unary_call.h
+++ b/include/grpc++/impl/codegen/client_unary_call.h
@@ -37,6 +37,7 @@
 #include <grpc++/impl/codegen/call.h>
 #include <grpc++/impl/codegen/channel_interface.h>
 #include <grpc++/impl/codegen/config.h>
+#include <grpc++/impl/codegen/core_codegen_interface.h>
 #include <grpc++/impl/codegen/status.h>
 
 namespace grpc {
@@ -66,7 +67,7 @@
   ops.ClientSendClose();
   ops.ClientRecvStatus(context, &status);
   call.PerformOps(&ops);
-  GPR_ASSERT((cq.Pluck(&ops) && ops.got_message) || !status.ok());
+  GPR_CODEGEN_ASSERT((cq.Pluck(&ops) && ops.got_message) || !status.ok());
   return status;
 }
 
diff --git a/include/grpc++/impl/codegen/completion_queue.h b/include/grpc++/impl/codegen/completion_queue.h
index 102831e..42ec287 100644
--- a/include/grpc++/impl/codegen/completion_queue.h
+++ b/include/grpc++/impl/codegen/completion_queue.h
@@ -36,9 +36,12 @@
 #ifndef GRPCXX_IMPL_CODEGEN_COMPLETION_QUEUE_H
 #define GRPCXX_IMPL_CODEGEN_COMPLETION_QUEUE_H
 
+#include <grpc++/impl/codegen/completion_queue_tag.h>
+#include <grpc++/impl/codegen/core_codegen_interface.h>
 #include <grpc++/impl/codegen/grpc_library.h>
 #include <grpc++/impl/codegen/status.h>
 #include <grpc++/impl/codegen/time.h>
+#include <grpc/impl/codegen/time.h>
 
 struct grpc_completion_queue;
 
@@ -76,13 +79,17 @@
 class ServerBuilder;
 class ServerContext;
 
+extern CoreCodegenInterface* g_core_codegen_interface;
+
 /// A thin wrapper around \a grpc_completion_queue (see / \a
 /// src/core/surface/completion_queue.h).
-class CompletionQueue : private GrpcLibrary {
+class CompletionQueue : private GrpcLibraryCodegen {
  public:
   /// Default constructor. Implicitly creates a \a grpc_completion_queue
   /// instance.
-  CompletionQueue();
+  CompletionQueue() {
+    cq_ = g_core_codegen_interface->grpc_completion_queue_create(nullptr);
+  }
 
   /// Wrap \a take, taking ownership of the instance.
   ///
@@ -90,7 +97,9 @@
   explicit CompletionQueue(grpc_completion_queue* take);
 
   /// Destructor. Destroys the owned wrapped completion queue / instance.
-  ~CompletionQueue();
+  ~CompletionQueue() {
+    g_core_codegen_interface->grpc_completion_queue_destroy(cq_);
+  }
 
   /// Tri-state return for AsyncNext: SHUTDOWN, GOT_EVENT, TIMEOUT.
   enum NextStatus {
@@ -124,8 +133,8 @@
   ///
   /// \return true if read a regular event, false if the queue is shutting down.
   bool Next(void** tag, bool* ok) {
-    return (AsyncNextInternal(tag, ok, gpr_inf_future(GPR_CLOCK_REALTIME)) !=
-            SHUTDOWN);
+    return (AsyncNextInternal(tag, ok, g_core_codegen_interface->gpr_inf_future(
+                                           GPR_CLOCK_REALTIME)) != SHUTDOWN);
   }
 
   /// Request the shutdown of the queue.
@@ -181,10 +190,31 @@
 
   /// Wraps \a grpc_completion_queue_pluck.
   /// \warning Must not be mixed with calls to \a Next.
-  bool Pluck(CompletionQueueTag* tag);
+  bool Pluck(CompletionQueueTag* tag) {
+    auto deadline =
+        g_core_codegen_interface->gpr_inf_future(GPR_CLOCK_REALTIME);
+    auto ev = g_core_codegen_interface->grpc_completion_queue_pluck(
+        cq_, tag, deadline, nullptr);
+    bool ok = ev.success != 0;
+    void* ignored = tag;
+    GPR_CODEGEN_ASSERT(tag->FinalizeResult(&ignored, &ok));
+    GPR_CODEGEN_ASSERT(ignored == tag);
+    // Ignore mutations by FinalizeResult: Pluck returns the C API status
+    return ev.success != 0;
+  }
 
   /// Performs a single polling pluck on \a tag.
-  void TryPluck(CompletionQueueTag* tag);
+  /// \warning Must not be mixed with calls to \a Next.
+  void TryPluck(CompletionQueueTag* tag) {
+    auto deadline = gpr_time_0(GPR_CLOCK_REALTIME);
+    auto ev = g_core_codegen_interface->grpc_completion_queue_pluck(
+        cq_, tag, deadline, nullptr);
+    if (ev.type == GRPC_QUEUE_TIMEOUT) return;
+    bool ok = ev.success != 0;
+    void* ignored = tag;
+    // the tag must be swallowed if using TryPluck
+    GPR_CODEGEN_ASSERT(!tag->FinalizeResult(&ignored, &ok));
+  }
 
   grpc_completion_queue* cq_;  // owned
 };
diff --git a/include/grpc++/impl/codegen/completion_queue_tag.h b/include/grpc++/impl/codegen/completion_queue_tag.h
index 8be2ac3..e904f73 100644
--- a/include/grpc++/impl/codegen/completion_queue_tag.h
+++ b/include/grpc++/impl/codegen/completion_queue_tag.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPCXX_COMPLETION_QUEUE_TAG_H
-#define GRPCXX_COMPLETION_QUEUE_TAG_H
+#ifndef GRPCXX_IMPL_CODEGEN_COMPLETION_QUEUE_TAG_H
+#define GRPCXX_IMPL_CODEGEN_COMPLETION_QUEUE_TAG_H
 
 namespace grpc {
 
@@ -49,4 +49,4 @@
 
 }  // namespace grpc
 
-#endif  // GRPCXX_COMPLETION_QUEUE_TAG_H
+#endif  // GRPCXX_IMPL_CODEGEN_COMPLETION_QUEUE_TAG_H
diff --git a/include/grpc++/impl/codegen/core_codegen_interface.h b/include/grpc++/impl/codegen/core_codegen_interface.h
new file mode 100644
index 0000000..a23031f
--- /dev/null
+++ b/include/grpc++/impl/codegen/core_codegen_interface.h
@@ -0,0 +1,97 @@
+/*
+ *
+ * Copyright 2015-2016, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef GRPCXX_IMPL_CODEGEN_CORE_CODEGEN_INTERFACE_H
+#define GRPCXX_IMPL_CODEGEN_CORE_CODEGEN_INTERFACE_H
+
+#include <grpc++/impl/codegen/config_protobuf.h>
+#include <grpc++/impl/codegen/status.h>
+#include <grpc/impl/codegen/grpc_types.h>
+
+namespace grpc {
+
+/// Interface between the codegen library and the minimal subset of core
+/// features required by the generated code.
+///
+/// All undocumented methods are simply forwarding the call to their namesakes.
+/// Please refer to their corresponding documentation for details.
+///
+/// \warning This interface should be considered internal and private.
+class CoreCodegenInterface {
+ public:
+  // Serialize the msg into a buffer created inside the function. The caller
+  // should destroy the returned buffer when done with it. If serialization
+  // fails,
+  // false is returned and buffer is left unchanged.
+  virtual Status SerializeProto(const grpc::protobuf::Message& msg,
+                                grpc_byte_buffer** buffer) = 0;
+
+  // The caller keeps ownership of buffer and msg.
+  virtual Status DeserializeProto(grpc_byte_buffer* buffer,
+                                  grpc::protobuf::Message* msg,
+                                  int max_message_size) = 0;
+
+  /// Upon a failed assertion, log the error.
+  virtual void assert_fail(const char* failed_assertion) = 0;
+
+  virtual grpc_completion_queue* grpc_completion_queue_create(
+      void* reserved) = 0;
+  virtual void grpc_completion_queue_destroy(grpc_completion_queue* cq) = 0;
+  virtual grpc_event grpc_completion_queue_pluck(grpc_completion_queue* cq,
+                                                 void* tag,
+                                                 gpr_timespec deadline,
+                                                 void* reserved) = 0;
+
+  virtual void* gpr_malloc(size_t size) = 0;
+  virtual void gpr_free(void* p) = 0;
+
+  virtual void grpc_byte_buffer_destroy(grpc_byte_buffer* bb) = 0;
+  virtual void grpc_metadata_array_init(grpc_metadata_array* array) = 0;
+  virtual void grpc_metadata_array_destroy(grpc_metadata_array* array) = 0;
+
+  virtual gpr_timespec gpr_inf_future(gpr_clock_type type) = 0;
+};
+
+extern CoreCodegenInterface* g_core_codegen_interface;
+
+/// Codegen specific version of \a GPR_ASSERT.
+#define GPR_CODEGEN_ASSERT(x)                          \
+  do {                                                 \
+    if (!(x)) {                                        \
+      grpc::g_core_codegen_interface->assert_fail(#x); \
+    }                                                  \
+  } while (0)
+
+}  // namespace grpc
+
+#endif  // GRPCXX_IMPL_CODEGEN_CORE_CODEGEN_INTERFACE_H
diff --git a/include/grpc++/impl/codegen/grpc_library.h b/include/grpc++/impl/codegen/grpc_library.h
index eb7152a..3cdc6f3 100644
--- a/include/grpc++/impl/codegen/grpc_library.h
+++ b/include/grpc++/impl/codegen/grpc_library.h
@@ -34,6 +34,7 @@
 #ifndef GRPCXX_IMPL_CODEGEN_GRPC_LIBRARY_H
 #define GRPCXX_IMPL_CODEGEN_GRPC_LIBRARY_H
 
+#include <grpc++/impl/codegen/core_codegen_interface.h>
 #include <grpc/impl/codegen/log.h>
 
 namespace grpc {
@@ -44,24 +45,27 @@
   virtual void shutdown() = 0;
 };
 
+/// Initialized by \a grpc::GrpcLibraryInitializer from
+/// <grpc++/impl/grpc_library.h>
 extern GrpcLibraryInterface* g_glip;
 
-class GrpcLibrary {
+/// Classes that require gRPC to be initialized should inherit from this class.
+class GrpcLibraryCodegen {
  public:
-  GrpcLibrary() {
-    GPR_ASSERT(g_glip &&
-               "gRPC library not initialized. See "
-               "grpc::internal::GrpcLibraryInitializer.");
+  GrpcLibraryCodegen() {
+    GPR_CODEGEN_ASSERT(g_glip &&
+                       "gRPC library not initialized. See "
+                       "grpc::internal::GrpcLibraryInitializer.");
     g_glip->init();
   }
-  virtual ~GrpcLibrary() {
-    GPR_ASSERT(g_glip &&
-               "gRPC library not initialized. See "
-               "grpc::internal::GrpcLibraryInitializer.");
+  virtual ~GrpcLibraryCodegen() {
+    GPR_CODEGEN_ASSERT(g_glip &&
+                       "gRPC library not initialized. See "
+                       "grpc::internal::GrpcLibraryInitializer.");
     g_glip->shutdown();
   }
 };
 
 }  // namespace grpc
 
-#endif  // GRPCXX_IMPL_GRPC_LIBRARY_H
+#endif  // GRPCXX_IMPL_CODEGEN_GRPC_LIBRARY_H
diff --git a/include/grpc++/impl/codegen/impl/async_stream.h b/include/grpc++/impl/codegen/impl/async_stream.h
new file mode 100644
index 0000000..413eab7
--- /dev/null
+++ b/include/grpc++/impl/codegen/impl/async_stream.h
@@ -0,0 +1,463 @@
+/*
+ *
+ * Copyright 2015-2016, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef GRPCXX_IMPL_CODEGEN_IMPL_ASYNC_STREAM_H
+#define GRPCXX_IMPL_CODEGEN_IMPL_ASYNC_STREAM_H
+
+#include <grpc++/impl/codegen/call.h>
+#include <grpc++/impl/codegen/channel_interface.h>
+#include <grpc++/impl/codegen/core_codegen_interface.h>
+#include <grpc++/impl/codegen/server_context.h>
+#include <grpc++/impl/codegen/service_type.h>
+#include <grpc++/impl/codegen/status.h>
+
+namespace grpc {
+
+class CompletionQueue;
+
+/// Common interface for all client side asynchronous streaming.
+class ClientAsyncStreamingInterface {
+ public:
+  virtual ~ClientAsyncStreamingInterface() {}
+
+  /// Request notification of the reading of the initial metadata. Completion
+  /// will be notified by \a tag on the associated completion queue.
+  ///
+  /// \param[in] tag Tag identifying this request.
+  virtual void ReadInitialMetadata(void* tag) = 0;
+
+  /// Request notification completion.
+  ///
+  /// \param[out] status To be updated with the operation status.
+  /// \param[in] tag Tag identifying this request.
+  virtual void Finish(Status* status, void* tag) = 0;
+};
+
+/// An interface that yields a sequence of messages of type \a R.
+template <class R>
+class AsyncReaderInterface {
+ public:
+  virtual ~AsyncReaderInterface() {}
+
+  /// Read a message of type \a R into \a msg. Completion will be notified by \a
+  /// tag on the associated completion queue.
+  ///
+  /// \param[out] msg Where to eventually store the read message.
+  /// \param[in] tag The tag identifying the operation.
+  virtual void Read(R* msg, void* tag) = 0;
+};
+
+/// An interface that can be fed a sequence of messages of type \a W.
+template <class W>
+class AsyncWriterInterface {
+ public:
+  virtual ~AsyncWriterInterface() {}
+
+  /// Request the writing of \a msg with identifying tag \a tag.
+  ///
+  /// Only one write may be outstanding at any given time. This means that
+  /// after calling Write, one must wait to receive \a tag from the completion
+  /// queue BEFORE calling Write again.
+  ///
+  /// \param[in] msg The message to be written.
+  /// \param[in] tag The tag identifying the operation.
+  virtual void Write(const W& msg, void* tag) = 0;
+};
+
+template <class R>
+class ClientAsyncReaderInterface : public ClientAsyncStreamingInterface,
+                                   public AsyncReaderInterface<R> {};
+
+template <class R>
+class ClientAsyncReader GRPC_FINAL : public ClientAsyncReaderInterface<R> {
+ public:
+  /// Create a stream and write the first request out.
+  template <class W>
+  ClientAsyncReader(ChannelInterface* channel, CompletionQueue* cq,
+                    const RpcMethod& method, ClientContext* context,
+                    const W& request, void* tag)
+      : context_(context), call_(channel->CreateCall(method, context, cq)) {
+    init_ops_.set_output_tag(tag);
+    init_ops_.SendInitialMetadata(context->send_initial_metadata_);
+    // TODO(ctiller): don't assert
+    GPR_CODEGEN_ASSERT(init_ops_.SendMessage(request).ok());
+    init_ops_.ClientSendClose();
+    call_.PerformOps(&init_ops_);
+  }
+
+  void ReadInitialMetadata(void* tag) GRPC_OVERRIDE {
+    GPR_CODEGEN_ASSERT(!context_->initial_metadata_received_);
+
+    meta_ops_.set_output_tag(tag);
+    meta_ops_.RecvInitialMetadata(context_);
+    call_.PerformOps(&meta_ops_);
+  }
+
+  void Read(R* msg, void* tag) GRPC_OVERRIDE {
+    read_ops_.set_output_tag(tag);
+    if (!context_->initial_metadata_received_) {
+      read_ops_.RecvInitialMetadata(context_);
+    }
+    read_ops_.RecvMessage(msg);
+    call_.PerformOps(&read_ops_);
+  }
+
+  void Finish(Status* status, void* tag) GRPC_OVERRIDE {
+    finish_ops_.set_output_tag(tag);
+    if (!context_->initial_metadata_received_) {
+      finish_ops_.RecvInitialMetadata(context_);
+    }
+    finish_ops_.ClientRecvStatus(context_, status);
+    call_.PerformOps(&finish_ops_);
+  }
+
+ private:
+  ClientContext* context_;
+  Call call_;
+  CallOpSet<CallOpSendInitialMetadata, CallOpSendMessage, CallOpClientSendClose>
+      init_ops_;
+  CallOpSet<CallOpRecvInitialMetadata> meta_ops_;
+  CallOpSet<CallOpRecvInitialMetadata, CallOpRecvMessage<R>> read_ops_;
+  CallOpSet<CallOpRecvInitialMetadata, CallOpClientRecvStatus> finish_ops_;
+};
+
+/// Common interface for client side asynchronous writing.
+template <class W>
+class ClientAsyncWriterInterface : public ClientAsyncStreamingInterface,
+                                   public AsyncWriterInterface<W> {
+ public:
+  /// Signal the client is done with the writes.
+  ///
+  /// \param[in] tag The tag identifying the operation.
+  virtual void WritesDone(void* tag) = 0;
+};
+
+template <class W>
+class ClientAsyncWriter GRPC_FINAL : public ClientAsyncWriterInterface<W> {
+ public:
+  template <class R>
+  ClientAsyncWriter(ChannelInterface* channel, CompletionQueue* cq,
+                    const RpcMethod& method, ClientContext* context,
+                    R* response, void* tag)
+      : context_(context), call_(channel->CreateCall(method, context, cq)) {
+    finish_ops_.RecvMessage(response);
+
+    init_ops_.set_output_tag(tag);
+    init_ops_.SendInitialMetadata(context->send_initial_metadata_);
+    call_.PerformOps(&init_ops_);
+  }
+
+  void ReadInitialMetadata(void* tag) GRPC_OVERRIDE {
+    GPR_CODEGEN_ASSERT(!context_->initial_metadata_received_);
+
+    meta_ops_.set_output_tag(tag);
+    meta_ops_.RecvInitialMetadata(context_);
+    call_.PerformOps(&meta_ops_);
+  }
+
+  void Write(const W& msg, void* tag) GRPC_OVERRIDE {
+    write_ops_.set_output_tag(tag);
+    // TODO(ctiller): don't assert
+    GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg).ok());
+    call_.PerformOps(&write_ops_);
+  }
+
+  void WritesDone(void* tag) GRPC_OVERRIDE {
+    writes_done_ops_.set_output_tag(tag);
+    writes_done_ops_.ClientSendClose();
+    call_.PerformOps(&writes_done_ops_);
+  }
+
+  void Finish(Status* status, void* tag) GRPC_OVERRIDE {
+    finish_ops_.set_output_tag(tag);
+    if (!context_->initial_metadata_received_) {
+      finish_ops_.RecvInitialMetadata(context_);
+    }
+    finish_ops_.ClientRecvStatus(context_, status);
+    call_.PerformOps(&finish_ops_);
+  }
+
+ private:
+  ClientContext* context_;
+  Call call_;
+  CallOpSet<CallOpSendInitialMetadata> init_ops_;
+  CallOpSet<CallOpRecvInitialMetadata> meta_ops_;
+  CallOpSet<CallOpSendMessage> write_ops_;
+  CallOpSet<CallOpClientSendClose> writes_done_ops_;
+  CallOpSet<CallOpRecvInitialMetadata, CallOpGenericRecvMessage,
+            CallOpClientRecvStatus> finish_ops_;
+};
+
+/// Client-side interface for asynchronous bi-directional streaming.
+template <class W, class R>
+class ClientAsyncReaderWriterInterface : public ClientAsyncStreamingInterface,
+                                         public AsyncWriterInterface<W>,
+                                         public AsyncReaderInterface<R> {
+ public:
+  /// Signal the client is done with the writes.
+  ///
+  /// \param[in] tag The tag identifying the operation.
+  virtual void WritesDone(void* tag) = 0;
+};
+
+template <class W, class R>
+class ClientAsyncReaderWriter GRPC_FINAL
+    : public ClientAsyncReaderWriterInterface<W, R> {
+ public:
+  ClientAsyncReaderWriter(ChannelInterface* channel, CompletionQueue* cq,
+                          const RpcMethod& method, ClientContext* context,
+                          void* tag)
+      : context_(context), call_(channel->CreateCall(method, context, cq)) {
+    init_ops_.set_output_tag(tag);
+    init_ops_.SendInitialMetadata(context->send_initial_metadata_);
+    call_.PerformOps(&init_ops_);
+  }
+
+  void ReadInitialMetadata(void* tag) GRPC_OVERRIDE {
+    GPR_CODEGEN_ASSERT(!context_->initial_metadata_received_);
+
+    meta_ops_.set_output_tag(tag);
+    meta_ops_.RecvInitialMetadata(context_);
+    call_.PerformOps(&meta_ops_);
+  }
+
+  void Read(R* msg, void* tag) GRPC_OVERRIDE {
+    read_ops_.set_output_tag(tag);
+    if (!context_->initial_metadata_received_) {
+      read_ops_.RecvInitialMetadata(context_);
+    }
+    read_ops_.RecvMessage(msg);
+    call_.PerformOps(&read_ops_);
+  }
+
+  void Write(const W& msg, void* tag) GRPC_OVERRIDE {
+    write_ops_.set_output_tag(tag);
+    // TODO(ctiller): don't assert
+    GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg).ok());
+    call_.PerformOps(&write_ops_);
+  }
+
+  void WritesDone(void* tag) GRPC_OVERRIDE {
+    writes_done_ops_.set_output_tag(tag);
+    writes_done_ops_.ClientSendClose();
+    call_.PerformOps(&writes_done_ops_);
+  }
+
+  void Finish(Status* status, void* tag) GRPC_OVERRIDE {
+    finish_ops_.set_output_tag(tag);
+    if (!context_->initial_metadata_received_) {
+      finish_ops_.RecvInitialMetadata(context_);
+    }
+    finish_ops_.ClientRecvStatus(context_, status);
+    call_.PerformOps(&finish_ops_);
+  }
+
+ private:
+  ClientContext* context_;
+  Call call_;
+  CallOpSet<CallOpSendInitialMetadata> init_ops_;
+  CallOpSet<CallOpRecvInitialMetadata> meta_ops_;
+  CallOpSet<CallOpRecvInitialMetadata, CallOpRecvMessage<R>> read_ops_;
+  CallOpSet<CallOpSendMessage> write_ops_;
+  CallOpSet<CallOpClientSendClose> writes_done_ops_;
+  CallOpSet<CallOpRecvInitialMetadata, CallOpClientRecvStatus> finish_ops_;
+};
+
+template <class W, class 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) GRPC_OVERRIDE {
+    GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_);
+
+    meta_ops_.set_output_tag(tag);
+    meta_ops_.SendInitialMetadata(ctx_->initial_metadata_);
+    ctx_->sent_initial_metadata_ = true;
+    call_.PerformOps(&meta_ops_);
+  }
+
+  void Read(R* msg, void* tag) GRPC_OVERRIDE {
+    read_ops_.set_output_tag(tag);
+    read_ops_.RecvMessage(msg);
+    call_.PerformOps(&read_ops_);
+  }
+
+  void Finish(const W& msg, const Status& status, void* tag) {
+    finish_ops_.set_output_tag(tag);
+    if (!ctx_->sent_initial_metadata_) {
+      finish_ops_.SendInitialMetadata(ctx_->initial_metadata_);
+      ctx_->sent_initial_metadata_ = true;
+    }
+    // The response is dropped if the status is not OK.
+    if (status.ok()) {
+      finish_ops_.ServerSendStatus(ctx_->trailing_metadata_,
+                                   finish_ops_.SendMessage(msg));
+    } else {
+      finish_ops_.ServerSendStatus(ctx_->trailing_metadata_, status);
+    }
+    call_.PerformOps(&finish_ops_);
+  }
+
+  void FinishWithError(const Status& status, void* tag) {
+    GPR_CODEGEN_ASSERT(!status.ok());
+    finish_ops_.set_output_tag(tag);
+    if (!ctx_->sent_initial_metadata_) {
+      finish_ops_.SendInitialMetadata(ctx_->initial_metadata_);
+      ctx_->sent_initial_metadata_ = true;
+    }
+    finish_ops_.ServerSendStatus(ctx_->trailing_metadata_, status);
+    call_.PerformOps(&finish_ops_);
+  }
+
+ private:
+  void BindCall(Call* call) GRPC_OVERRIDE { call_ = *call; }
+
+  Call call_;
+  ServerContext* ctx_;
+  CallOpSet<CallOpSendInitialMetadata> meta_ops_;
+  CallOpSet<CallOpRecvMessage<R>> read_ops_;
+  CallOpSet<CallOpSendInitialMetadata, CallOpSendMessage,
+            CallOpServerSendStatus> finish_ops_;
+};
+
+template <class 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) GRPC_OVERRIDE {
+    GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_);
+
+    meta_ops_.set_output_tag(tag);
+    meta_ops_.SendInitialMetadata(ctx_->initial_metadata_);
+    ctx_->sent_initial_metadata_ = true;
+    call_.PerformOps(&meta_ops_);
+  }
+
+  void Write(const W& msg, void* tag) GRPC_OVERRIDE {
+    write_ops_.set_output_tag(tag);
+    if (!ctx_->sent_initial_metadata_) {
+      write_ops_.SendInitialMetadata(ctx_->initial_metadata_);
+      ctx_->sent_initial_metadata_ = true;
+    }
+    // TODO(ctiller): don't assert
+    GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg).ok());
+    call_.PerformOps(&write_ops_);
+  }
+
+  void Finish(const Status& status, void* tag) {
+    finish_ops_.set_output_tag(tag);
+    if (!ctx_->sent_initial_metadata_) {
+      finish_ops_.SendInitialMetadata(ctx_->initial_metadata_);
+      ctx_->sent_initial_metadata_ = true;
+    }
+    finish_ops_.ServerSendStatus(ctx_->trailing_metadata_, status);
+    call_.PerformOps(&finish_ops_);
+  }
+
+ private:
+  void BindCall(Call* call) GRPC_OVERRIDE { call_ = *call; }
+
+  Call call_;
+  ServerContext* ctx_;
+  CallOpSet<CallOpSendInitialMetadata> meta_ops_;
+  CallOpSet<CallOpSendInitialMetadata, CallOpSendMessage> write_ops_;
+  CallOpSet<CallOpSendInitialMetadata, CallOpServerSendStatus> finish_ops_;
+};
+
+/// Server-side interface for asynchronous bi-directional streaming.
+template <class W, class 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) GRPC_OVERRIDE {
+    GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_);
+
+    meta_ops_.set_output_tag(tag);
+    meta_ops_.SendInitialMetadata(ctx_->initial_metadata_);
+    ctx_->sent_initial_metadata_ = true;
+    call_.PerformOps(&meta_ops_);
+  }
+
+  void Read(R* msg, void* tag) GRPC_OVERRIDE {
+    read_ops_.set_output_tag(tag);
+    read_ops_.RecvMessage(msg);
+    call_.PerformOps(&read_ops_);
+  }
+
+  void Write(const W& msg, void* tag) GRPC_OVERRIDE {
+    write_ops_.set_output_tag(tag);
+    if (!ctx_->sent_initial_metadata_) {
+      write_ops_.SendInitialMetadata(ctx_->initial_metadata_);
+      ctx_->sent_initial_metadata_ = true;
+    }
+    // TODO(ctiller): don't assert
+    GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg).ok());
+    call_.PerformOps(&write_ops_);
+  }
+
+  void Finish(const Status& status, void* tag) {
+    finish_ops_.set_output_tag(tag);
+    if (!ctx_->sent_initial_metadata_) {
+      finish_ops_.SendInitialMetadata(ctx_->initial_metadata_);
+      ctx_->sent_initial_metadata_ = true;
+    }
+    finish_ops_.ServerSendStatus(ctx_->trailing_metadata_, status);
+    call_.PerformOps(&finish_ops_);
+  }
+
+ private:
+  friend class ::grpc::Server;
+
+  void BindCall(Call* call) GRPC_OVERRIDE { call_ = *call; }
+
+  Call call_;
+  ServerContext* ctx_;
+  CallOpSet<CallOpSendInitialMetadata> meta_ops_;
+  CallOpSet<CallOpRecvMessage<R>> read_ops_;
+  CallOpSet<CallOpSendInitialMetadata, CallOpSendMessage> write_ops_;
+  CallOpSet<CallOpSendInitialMetadata, CallOpServerSendStatus> finish_ops_;
+};
+
+}  // namespace grpc
+
+#endif  // GRPCXX_IMPL_CODEGEN_IMPL_ASYNC_STREAM_H
diff --git a/include/grpc++/impl/codegen/impl/status_code_enum.h b/include/grpc++/impl/codegen/impl/status_code_enum.h
new file mode 100644
index 0000000..f8caec0
--- /dev/null
+++ b/include/grpc++/impl/codegen/impl/status_code_enum.h
@@ -0,0 +1,152 @@
+/*
+ *
+ * Copyright 2016, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef GRPCXX_IMPL_CODEGEN_IMPL_STATUS_CODE_ENUM_H
+#define GRPCXX_IMPL_CODEGEN_IMPL_STATUS_CODE_ENUM_H
+
+namespace grpc {
+
+enum StatusCode {
+  /// Not an error; returned on success.
+  OK = 0,
+
+  /// The operation was cancelled (typically by the caller).
+  CANCELLED = 1,
+
+  /// Unknown error. An example of where this error may be returned is if a
+  /// Status value received from another address space belongs to an error-space
+  /// that is not known in this address space. Also errors raised by APIs that
+  /// do not return enough error information may be converted to this error.
+  UNKNOWN = 2,
+
+  /// Client specified an invalid argument. Note that this differs from
+  /// FAILED_PRECONDITION. INVALID_ARGUMENT indicates arguments that are
+  /// problematic regardless of the state of the system (e.g., a malformed file
+  /// name).
+  INVALID_ARGUMENT = 3,
+
+  /// Deadline expired before operation could complete. For operations that
+  /// change the state of the system, this error may be returned even if the
+  /// operation has completed successfully. For example, a successful response
+  /// from a server could have been delayed long enough for the deadline to
+  /// expire.
+  DEADLINE_EXCEEDED = 4,
+
+  /// Some requested entity (e.g., file or directory) was not found.
+  NOT_FOUND = 5,
+
+  /// Some entity that we attempted to create (e.g., file or directory) already
+  /// exists.
+  ALREADY_EXISTS = 6,
+
+  /// The caller does not have permission to execute the specified operation.
+  /// PERMISSION_DENIED must not be used for rejections caused by exhausting
+  /// some resource (use RESOURCE_EXHAUSTED instead for those errors).
+  /// PERMISSION_DENIED must not be used if the caller can not be identified
+  /// (use UNAUTHENTICATED instead for those errors).
+  PERMISSION_DENIED = 7,
+
+  /// The request does not have valid authentication credentials for the
+  /// operation.
+  UNAUTHENTICATED = 16,
+
+  /// Some resource has been exhausted, perhaps a per-user quota, or perhaps the
+  /// entire file system is out of space.
+  RESOURCE_EXHAUSTED = 8,
+
+  /// Operation was rejected because the system is not in a state required for
+  /// the operation's execution. For example, directory to be deleted may be
+  /// non-empty, an rmdir operation is applied to a non-directory, etc.
+  ///
+  /// A litmus test that may help a service implementor in deciding
+  /// between FAILED_PRECONDITION, ABORTED, and UNAVAILABLE:
+  ///  (a) Use UNAVAILABLE if the client can retry just the failing call.
+  ///  (b) Use ABORTED if the client should retry at a higher-level
+  ///      (e.g., restarting a read-modify-write sequence).
+  ///  (c) Use FAILED_PRECONDITION if the client should not retry until
+  ///      the system state has been explicitly fixed. E.g., if an "rmdir"
+  ///      fails because the directory is non-empty, FAILED_PRECONDITION
+  ///      should be returned since the client should not retry unless
+  ///      they have first fixed up the directory by deleting files from it.
+  ///  (d) Use FAILED_PRECONDITION if the client performs conditional
+  ///      REST Get/Update/Delete on a resource and the resource on the
+  ///      server does not match the condition. E.g., conflicting
+  ///      read-modify-write on the same resource.
+  FAILED_PRECONDITION = 9,
+
+  /// The operation was aborted, typically due to a concurrency issue like
+  /// sequencer check failures, transaction aborts, etc.
+  ///
+  /// See litmus test above for deciding between FAILED_PRECONDITION, ABORTED,
+  /// and UNAVAILABLE.
+  ABORTED = 10,
+
+  /// Operation was attempted past the valid range. E.g., seeking or reading
+  /// past end of file.
+  ///
+  /// Unlike INVALID_ARGUMENT, this error indicates a problem that may be fixed
+  /// if the system state changes. For example, a 32-bit file system will
+  /// generate INVALID_ARGUMENT if asked to read at an offset that is not in the
+  /// range [0,2^32-1], but it will generate OUT_OF_RANGE if asked to read from
+  /// an offset past the current file size.
+  ///
+  /// There is a fair bit of overlap between FAILED_PRECONDITION and
+  /// OUT_OF_RANGE. We recommend using OUT_OF_RANGE (the more specific error)
+  /// when it applies so that callers who are iterating through a space can
+  /// easily look for an OUT_OF_RANGE error to detect when they are done.
+  OUT_OF_RANGE = 11,
+
+  /// Operation is not implemented or not supported/enabled in this service.
+  UNIMPLEMENTED = 12,
+
+  /// Internal errors. Means some invariants expected by underlying System has
+  /// been broken. If you see one of these errors, Something is very broken.
+  INTERNAL = 13,
+
+  /// The service is currently unavailable. This is a most likely a transient
+  /// condition and may be corrected by retrying with a backoff.
+  ///
+  /// See litmus test above for deciding between FAILED_PRECONDITION, ABORTED,
+  /// and UNAVAILABLE.
+  UNAVAILABLE = 14,
+
+  /// Unrecoverable data loss or corruption.
+  DATA_LOSS = 15,
+
+  /// Force users to include a default branch:
+  DO_NOT_USE = -1
+};
+
+}  // namespace grpc
+
+#endif  // GRPCXX_IMPL_CODEGEN_IMPL_STATUS_CODE_ENUM_H
diff --git a/src/cpp/codegen/grpc_library.cc b/include/grpc++/impl/codegen/impl/sync.h
similarity index 81%
copy from src/cpp/codegen/grpc_library.cc
copy to include/grpc++/impl/codegen/impl/sync.h
index 48acec3..68fd0c4 100644
--- a/src/cpp/codegen/grpc_library.cc
+++ b/include/grpc++/impl/codegen/impl/sync.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2016, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,10 +31,15 @@
  *
  */
 
-#include <grpc++/impl/codegen/grpc_library.h>
+#ifndef GRPCXX_IMPL_CODEGEN_IMPL_SYNC_H
+#define GRPCXX_IMPL_CODEGEN_IMPL_SYNC_H
 
-namespace grpc {
+#include <grpc++/impl/codegen/config.h>
 
-GrpcLibraryInterface *g_glip = nullptr;
+#ifdef GRPC_CXX0X_NO_THREAD
+#include <grpc++/impl/codegen/sync_no_cxx11.h>
+#else
+#include <grpc++/impl/codegen/sync_cxx11.h>
+#endif
 
-}  // namespace grpc
+#endif  // GRPCXX_IMPL_CODEGEN_IMPL_SYNC_H
diff --git a/include/grpc++/impl/codegen/method_handler_impl.h b/include/grpc++/impl/codegen/method_handler_impl.h
index 1bf9bf0..3ecca0a 100644
--- a/include/grpc++/impl/codegen/method_handler_impl.h
+++ b/include/grpc++/impl/codegen/method_handler_impl.h
@@ -34,6 +34,7 @@
 #ifndef GRPCXX_IMPL_CODEGEN_METHOD_HANDLER_IMPL_H
 #define GRPCXX_IMPL_CODEGEN_METHOD_HANDLER_IMPL_H
 
+#include <grpc++/impl/codegen/core_codegen_interface.h>
 #include <grpc++/impl/codegen/rpc_service_method.h>
 #include <grpc++/impl/codegen/sync_stream.h>
 
@@ -58,7 +59,7 @@
       status = func_(service_, param.server_context, &req, &rsp);
     }
 
-    GPR_ASSERT(!param.server_context->sent_initial_metadata_);
+    GPR_CODEGEN_ASSERT(!param.server_context->sent_initial_metadata_);
     CallOpSet<CallOpSendInitialMetadata, CallOpSendMessage,
               CallOpServerSendStatus> ops;
     ops.SendInitialMetadata(param.server_context->initial_metadata_);
@@ -93,7 +94,7 @@
     ResponseType rsp;
     Status status = func_(service_, param.server_context, &reader, &rsp);
 
-    GPR_ASSERT(!param.server_context->sent_initial_metadata_);
+    GPR_CODEGEN_ASSERT(!param.server_context->sent_initial_metadata_);
     CallOpSet<CallOpSendInitialMetadata, CallOpSendMessage,
               CallOpServerSendStatus> ops;
     ops.SendInitialMetadata(param.server_context->initial_metadata_);
diff --git a/include/grpc++/impl/codegen/proto_utils.h b/include/grpc++/impl/codegen/proto_utils.h
index ce17710..f77f8ee 100644
--- a/include/grpc++/impl/codegen/proto_utils.h
+++ b/include/grpc++/impl/codegen/proto_utils.h
@@ -36,22 +36,16 @@
 
 #include <type_traits>
 
-#include <grpc/impl/codegen/byte_buffer.h>
-#include <grpc++/impl/codegen/serialization_traits.h>
 #include <grpc++/impl/codegen/config_protobuf.h>
+#include <grpc++/impl/codegen/core_codegen_interface.h>
+#include <grpc++/impl/codegen/serialization_traits.h>
 #include <grpc++/impl/codegen/status.h>
+#include <grpc/impl/codegen/byte_buffer.h>
+#include <grpc/impl/codegen/log.h>
 
 namespace grpc {
 
-// Serialize the msg into a buffer created inside the function. The caller
-// should destroy the returned buffer when done with it. If serialization fails,
-// false is returned and buffer is left unchanged.
-Status SerializeProto(const grpc::protobuf::Message& msg,
-                      grpc_byte_buffer** buffer);
-
-// The caller keeps ownership of buffer and msg.
-Status DeserializeProto(grpc_byte_buffer* buffer, grpc::protobuf::Message* msg,
-                        int max_message_size);
+extern CoreCodegenInterface* g_core_codegen_interface;
 
 template <class T>
 class SerializationTraits<T, typename std::enable_if<std::is_base_of<
@@ -60,14 +54,13 @@
   static Status Serialize(const grpc::protobuf::Message& msg,
                           grpc_byte_buffer** buffer, bool* own_buffer) {
     *own_buffer = true;
-    return SerializeProto(msg, buffer);
+    return g_core_codegen_interface->SerializeProto(msg, buffer);
   }
   static Status Deserialize(grpc_byte_buffer* buffer,
                             grpc::protobuf::Message* msg,
                             int max_message_size) {
-    auto status = DeserializeProto(buffer, msg, max_message_size);
-    grpc_byte_buffer_destroy(buffer);
-    return status;
+    return g_core_codegen_interface->DeserializeProto(buffer, msg,
+                                                      max_message_size);
   }
 };
 
diff --git a/include/grpc++/impl/codegen/server_context.h b/include/grpc++/impl/codegen/server_context.h
index ad08b82..91ebe57 100644
--- a/include/grpc++/impl/codegen/server_context.h
+++ b/include/grpc++/impl/codegen/server_context.h
@@ -103,6 +103,9 @@
   void AddInitialMetadata(const grpc::string& key, const grpc::string& value);
   void AddTrailingMetadata(const grpc::string& key, const grpc::string& value);
 
+  // IsCancelled is always safe to call when using sync API
+  // When using async API, it is only safe to call IsCancelled after
+  // the AsyncNotifyWhenDone tag has been delivered
   bool IsCancelled() const;
 
   // Cancel the Call from the server. This is a best-effort API and depending on
diff --git a/include/grpc++/impl/codegen/server_interface.h b/include/grpc++/impl/codegen/server_interface.h
index f934619..7d4ed27 100644
--- a/include/grpc++/impl/codegen/server_interface.h
+++ b/include/grpc++/impl/codegen/server_interface.h
@@ -34,10 +34,11 @@
 #ifndef GRPCXX_IMPL_CODEGEN_SERVER_INTERFACE_H
 #define GRPCXX_IMPL_CODEGEN_SERVER_INTERFACE_H
 
-#include <grpc/impl/codegen/grpc_types.h>
 #include <grpc++/impl/codegen/call_hook.h>
 #include <grpc++/impl/codegen/completion_queue_tag.h>
+#include <grpc++/impl/codegen/core_codegen_interface.h>
 #include <grpc++/impl/codegen/rpc_service_method.h>
+#include <grpc/impl/codegen/grpc_types.h>
 
 namespace grpc {
 
@@ -223,7 +224,7 @@
                         CompletionQueue* call_cq,
                         ServerCompletionQueue* notification_cq, void* tag,
                         Message* message) {
-    GPR_ASSERT(method);
+    GPR_CODEGEN_ASSERT(method);
     new PayloadAsyncRequest<Message>(method->server_tag(), this, context,
                                      stream, call_cq, notification_cq, tag,
                                      message);
@@ -233,7 +234,7 @@
                         ServerAsyncStreamingInterface* stream,
                         CompletionQueue* call_cq,
                         ServerCompletionQueue* notification_cq, void* tag) {
-    GPR_ASSERT(method);
+    GPR_CODEGEN_ASSERT(method);
     new NoPayloadAsyncRequest(method->server_tag(), this, context, stream,
                               call_cq, notification_cq, tag);
   }
diff --git a/include/grpc++/impl/codegen/service_type.h b/include/grpc++/impl/codegen/service_type.h
index deb91a4..faf1893 100644
--- a/include/grpc++/impl/codegen/service_type.h
+++ b/include/grpc++/impl/codegen/service_type.h
@@ -35,6 +35,7 @@
 #define GRPCXX_IMPL_CODEGEN_SERVICE_TYPE_H
 
 #include <grpc++/impl/codegen/config.h>
+#include <grpc++/impl/codegen/core_codegen_interface.h>
 #include <grpc++/impl/codegen/rpc_service_method.h>
 #include <grpc++/impl/codegen/serialization_traits.h>
 #include <grpc++/impl/codegen/server_interface.h>
@@ -131,21 +132,18 @@
   void AddMethod(RpcServiceMethod* method) { methods_.emplace_back(method); }
 
   void MarkMethodAsync(int index) {
-    if (methods_[index].get() == nullptr) {
-      gpr_log(GPR_ERROR,
-              "Cannot mark the method as 'async' because it has already been "
-              "marked as 'generic'.");
-      return;
-    }
+    GPR_CODEGEN_ASSERT(
+        methods_[index].get() != nullptr &&
+        "Cannot mark the method as 'async' because it has already been "
+        "marked as 'generic'.");
     methods_[index]->ResetHandler();
   }
 
   void MarkMethodGeneric(int index) {
-    if (methods_[index]->handler() == nullptr) {
-      gpr_log(GPR_ERROR,
-              "Cannot mark the method as 'generic' because it has already been "
-              "marked as 'async'.");
-    }
+    GPR_CODEGEN_ASSERT(
+        methods_[index]->handler() != nullptr &&
+        "Cannot mark the method as 'generic' because it has already been "
+        "marked as 'async'.");
     methods_[index].reset();
   }
 
diff --git a/include/grpc++/impl/codegen/string_ref.h b/include/grpc++/impl/codegen/string_ref.h
index e3af37e..4af2000 100644
--- a/include/grpc++/impl/codegen/string_ref.h
+++ b/include/grpc++/impl/codegen/string_ref.h
@@ -34,8 +34,12 @@
 #ifndef GRPCXX_IMPL_CODEGEN_STRING_REF_H
 #define GRPCXX_IMPL_CODEGEN_STRING_REF_H
 
-#include <iterator>
+#include <string.h>
+
+#include <algorithm>
 #include <iosfwd>
+#include <iostream>
+#include <iterator>
 
 #include <grpc++/impl/codegen/config.h>
 
@@ -62,8 +66,13 @@
   string_ref() : data_(nullptr), length_(0) {}
   string_ref(const string_ref& other)
       : data_(other.data_), length_(other.length_) {}
-  string_ref& operator=(const string_ref& rhs);
-  string_ref(const char* s);
+  string_ref& operator=(const string_ref& rhs) {
+    data_ = rhs.data_;
+    length_ = rhs.length_;
+    return *this;
+  }
+
+  string_ref(const char* s) : data_(s), length_(strlen(s)) {}
   string_ref(const char* s, size_t l) : data_(s), length_(l) {}
   string_ref(const grpc::string& s) : data_(s.data()), length_(s.length()) {}
 
@@ -95,13 +104,40 @@
   const char* data() const { return data_; }
 
   // string operations
-  int compare(string_ref x) const;
-  bool starts_with(string_ref x) const;
-  bool ends_with(string_ref x) const;
-  size_t find(string_ref s) const;
-  size_t find(char c) const;
+  int compare(string_ref x) const {
+    size_t min_size = length_ < x.length_ ? length_ : x.length_;
+    int r = memcmp(data_, x.data_, min_size);
+    if (r < 0) return -1;
+    if (r > 0) return 1;
+    if (length_ < x.length_) return -1;
+    if (length_ > x.length_) return 1;
+    return 0;
+  }
 
-  string_ref substr(size_t pos, size_t n = npos) const;
+  bool starts_with(string_ref x) const {
+    return length_ >= x.length_ && (memcmp(data_, x.data_, x.length_) == 0);
+  }
+
+  bool ends_with(string_ref x) const {
+    return length_ >= x.length_ &&
+           (memcmp(data_ + (length_ - x.length_), x.data_, x.length_) == 0);
+  }
+
+  size_t find(string_ref s) const {
+    auto it = std::search(cbegin(), cend(), s.cbegin(), s.cend());
+    return it == cend() ? npos : std::distance(cbegin(), it);
+  }
+
+  size_t find(char c) const {
+    auto it = std::find(cbegin(), cend(), c);
+    return it == cend() ? npos : std::distance(cbegin(), it);
+  }
+
+  string_ref substr(size_t pos, size_t n = npos) const {
+    if (pos > length_) pos = length_;
+    if (n > (length_ - pos)) n = length_ - pos;
+    return string_ref(data_ + pos, n);
+  }
 
  private:
   const char* data_;
@@ -109,14 +145,16 @@
 };
 
 // Comparison operators
-bool operator==(string_ref x, string_ref y);
-bool operator!=(string_ref x, string_ref y);
-bool operator<(string_ref x, string_ref y);
-bool operator>(string_ref x, string_ref y);
-bool operator<=(string_ref x, string_ref y);
-bool operator>=(string_ref x, string_ref y);
+inline bool operator==(string_ref x, string_ref y) { return x.compare(y) == 0; }
+inline bool operator!=(string_ref x, string_ref y) { return x.compare(y) != 0; }
+inline bool operator<(string_ref x, string_ref y) { return x.compare(y) < 0; }
+inline bool operator<=(string_ref x, string_ref y) { return x.compare(y) <= 0; }
+inline bool operator>(string_ref x, string_ref y) { return x.compare(y) > 0; }
+inline bool operator>=(string_ref x, string_ref y) { return x.compare(y) >= 0; }
 
-std::ostream& operator<<(std::ostream& stream, const string_ref& string);
+inline std::ostream& operator<<(std::ostream& out, const string_ref& string) {
+  return out << grpc::string(string.begin(), string.end());
+}
 
 }  // namespace grpc
 
diff --git a/include/grpc++/impl/codegen/sync_stream.h b/include/grpc++/impl/codegen/sync_stream.h
index 9ae48bd..5f87846 100644
--- a/include/grpc++/impl/codegen/sync_stream.h
+++ b/include/grpc++/impl/codegen/sync_stream.h
@@ -38,6 +38,7 @@
 #include <grpc++/impl/codegen/channel_interface.h>
 #include <grpc++/impl/codegen/client_context.h>
 #include <grpc++/impl/codegen/completion_queue.h>
+#include <grpc++/impl/codegen/core_codegen_interface.h>
 #include <grpc++/impl/codegen/server_context.h>
 #include <grpc++/impl/codegen/service_type.h>
 #include <grpc++/impl/codegen/status.h>
@@ -125,14 +126,14 @@
               CallOpClientSendClose> ops;
     ops.SendInitialMetadata(context->send_initial_metadata_);
     // TODO(ctiller): don't assert
-    GPR_ASSERT(ops.SendMessage(request).ok());
+    GPR_CODEGEN_ASSERT(ops.SendMessage(request).ok());
     ops.ClientSendClose();
     call_.PerformOps(&ops);
     cq_.Pluck(&ops);
   }
 
   void WaitForInitialMetadata() GRPC_OVERRIDE {
-    GPR_ASSERT(!context_->initial_metadata_received_);
+    GPR_CODEGEN_ASSERT(!context_->initial_metadata_received_);
 
     CallOpSet<CallOpRecvInitialMetadata> ops;
     ops.RecvInitialMetadata(context_);
@@ -155,7 +156,7 @@
     Status status;
     ops.ClientRecvStatus(context_, &status);
     call_.PerformOps(&ops);
-    GPR_ASSERT(cq_.Pluck(&ops));
+    GPR_CODEGEN_ASSERT(cq_.Pluck(&ops));
     return status;
   }
 
@@ -194,7 +195,7 @@
   }
 
   void WaitForInitialMetadata() {
-    GPR_ASSERT(!context_->initial_metadata_received_);
+    GPR_CODEGEN_ASSERT(!context_->initial_metadata_received_);
 
     CallOpSet<CallOpRecvInitialMetadata> ops;
     ops.RecvInitialMetadata(context_);
@@ -227,7 +228,7 @@
     }
     finish_ops_.ClientRecvStatus(context_, &status);
     call_.PerformOps(&finish_ops_);
-    GPR_ASSERT(cq_.Pluck(&finish_ops_));
+    GPR_CODEGEN_ASSERT(cq_.Pluck(&finish_ops_));
     return status;
   }
 
@@ -271,7 +272,7 @@
   }
 
   void WaitForInitialMetadata() GRPC_OVERRIDE {
-    GPR_ASSERT(!context_->initial_metadata_received_);
+    GPR_CODEGEN_ASSERT(!context_->initial_metadata_received_);
 
     CallOpSet<CallOpRecvInitialMetadata> ops;
     ops.RecvInitialMetadata(context_);
@@ -312,7 +313,7 @@
     Status status;
     ops.ClientRecvStatus(context_, &status);
     call_.PerformOps(&ops);
-    GPR_ASSERT(cq_.Pluck(&ops));
+    GPR_CODEGEN_ASSERT(cq_.Pluck(&ops));
     return status;
   }
 
@@ -328,7 +329,7 @@
   ServerReader(Call* call, ServerContext* ctx) : call_(call), ctx_(ctx) {}
 
   void SendInitialMetadata() {
-    GPR_ASSERT(!ctx_->sent_initial_metadata_);
+    GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_);
 
     CallOpSet<CallOpSendInitialMetadata> ops;
     ops.SendInitialMetadata(ctx_->initial_metadata_);
@@ -355,7 +356,7 @@
   ServerWriter(Call* call, ServerContext* ctx) : call_(call), ctx_(ctx) {}
 
   void SendInitialMetadata() {
-    GPR_ASSERT(!ctx_->sent_initial_metadata_);
+    GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_);
 
     CallOpSet<CallOpSendInitialMetadata> ops;
     ops.SendInitialMetadata(ctx_->initial_metadata_);
@@ -391,7 +392,7 @@
   ServerReaderWriter(Call* call, ServerContext* ctx) : call_(call), ctx_(ctx) {}
 
   void SendInitialMetadata() {
-    GPR_ASSERT(!ctx_->sent_initial_metadata_);
+    GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_);
 
     CallOpSet<CallOpSendInitialMetadata> ops;
     ops.SendInitialMetadata(ctx_->initial_metadata_);
diff --git a/include/grpc++/impl/grpc_library.h b/include/grpc++/impl/grpc_library.h
index e8a075f..ecb5a4d 100644
--- a/include/grpc++/impl/grpc_library.h
+++ b/include/grpc++/impl/grpc_library.h
@@ -40,21 +40,31 @@
 #include <grpc++/impl/codegen/grpc_library.h>
 #include <grpc/grpc.h>
 
+#include "src/cpp/common/core_codegen.h"
+
 namespace grpc {
 
 namespace internal {
 class GrpcLibrary GRPC_FINAL : public GrpcLibraryInterface {
  public:
   void init() GRPC_OVERRIDE { grpc_init(); }
-
   void shutdown() GRPC_OVERRIDE { grpc_shutdown(); }
 };
 
 static GrpcLibrary g_gli;
+static CoreCodegen g_core_codegen;
 
+/// Instantiating this class ensures the proper initialization of gRPC.
 class GrpcLibraryInitializer GRPC_FINAL {
  public:
-  GrpcLibraryInitializer() { grpc::g_glip = &g_gli; }
+  GrpcLibraryInitializer() {
+    if (grpc::g_glip == nullptr) {
+      grpc::g_glip = &g_gli;
+    }
+    if (grpc::g_core_codegen_interface == nullptr) {
+      grpc::g_core_codegen_interface = &g_core_codegen;
+    }
+  }
 
   /// A no-op method to force the linker to reference this class, which will
   /// take care of initializing and shutting down the gRPC runtime.
diff --git a/include/grpc++/impl/proto_utils.h b/include/grpc++/impl/proto_utils.h
index 9124001..36acabb 100644
--- a/include/grpc++/impl/proto_utils.h
+++ b/include/grpc++/impl/proto_utils.h
@@ -31,9 +31,9 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CPP_PROTO_PROTO_UTILS_H
-#define GRPC_INTERNAL_CPP_PROTO_PROTO_UTILS_H
+#ifndef GRPCXX_IMPL_PROTO_UTILS_H
+#define GRPCXX_IMPL_PROTO_UTILS_H
 
 #include <grpc++/impl/codegen/proto_utils.h>
 
-#endif  // GRPC_INTERNAL_CPP_PROTO_PROTO_UTILS_H
+#endif  // GRPCXX_IMPL_PROTO_UTILS_H
diff --git a/include/grpc++/security/auth_context.h b/include/grpc++/security/auth_context.h
index bca8fa7..548f9a2 100644
--- a/include/grpc++/security/auth_context.h
+++ b/include/grpc++/security/auth_context.h
@@ -31,9 +31,9 @@
  *
  */
 
-#ifndef GRPCXX_SUPPORT_AUTH_CONTEXT_H
-#define GRPCXX_SUPPORT_AUTH_CONTEXT_H
+#ifndef GRPCXX_SECURITY_AUTH_CONTEXT_H
+#define GRPCXX_SECURITY_AUTH_CONTEXT_H
 
 #include <grpc++/impl/codegen/security/auth_context.h>
 
-#endif  // GRPCXX_SUPPORT_AUTH_CONTEXT_H
+#endif  // GRPCXX_SECURITY_AUTH_CONTEXT_H
diff --git a/include/grpc++/security/auth_metadata_processor.h b/include/grpc++/security/auth_metadata_processor.h
index 25011f3..b39451f 100644
--- a/include/grpc++/security/auth_metadata_processor.h
+++ b/include/grpc++/security/auth_metadata_processor.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPCXX_AUTH_METADATA_PROCESSOR_H_
-#define GRPCXX_AUTH_METADATA_PROCESSOR_H_
+#ifndef GRPCXX_SECURITY_AUTH_METADATA_PROCESSOR_H
+#define GRPCXX_SECURITY_AUTH_METADATA_PROCESSOR_H
 
 #include <map>
 
@@ -70,4 +70,4 @@
 
 }  // namespace grpc
 
-#endif  // GRPCXX_AUTH_METADATA_PROCESSOR_H_
+#endif  // GRPCXX_SECURITY_AUTH_METADATA_PROCESSOR_H
diff --git a/include/grpc++/security/credentials.h b/include/grpc++/security/credentials.h
index e0806c0..bedfc9c 100644
--- a/include/grpc++/security/credentials.h
+++ b/include/grpc++/security/credentials.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPCXX_CREDENTIALS_H
-#define GRPCXX_CREDENTIALS_H
+#ifndef GRPCXX_SECURITY_CREDENTIALS_H
+#define GRPCXX_SECURITY_CREDENTIALS_H
 
 #include <map>
 #include <memory>
@@ -57,7 +57,7 @@
 /// for all the calls on that channel.
 ///
 /// \see http://www.grpc.io/docs/guides/auth.html
-class ChannelCredentials : private GrpcLibrary {
+class ChannelCredentials : private GrpcLibraryCodegen {
  public:
   ChannelCredentials();
   ~ChannelCredentials();
@@ -83,7 +83,7 @@
 /// authenticate with a server for a given call on a channel.
 ///
 /// \see http://www.grpc.io/docs/guides/auth.html
-class CallCredentials : private GrpcLibrary {
+class CallCredentials : private GrpcLibraryCodegen {
  public:
   CallCredentials();
   ~CallCredentials();
@@ -229,4 +229,4 @@
 
 }  // namespace grpc
 
-#endif  // GRPCXX_CREDENTIALS_H
+#endif  // GRPCXX_SECURITY_CREDENTIALS_H
diff --git a/include/grpc++/security/server_credentials.h b/include/grpc++/security/server_credentials.h
index e933825..addb11c 100644
--- a/include/grpc++/security/server_credentials.h
+++ b/include/grpc++/security/server_credentials.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPCXX_SERVER_CREDENTIALS_H
-#define GRPCXX_SERVER_CREDENTIALS_H
+#ifndef GRPCXX_SECURITY_SERVER_CREDENTIALS_H
+#define GRPCXX_SECURITY_SERVER_CREDENTIALS_H
 
 #include <memory>
 #include <vector>
@@ -89,4 +89,4 @@
 
 }  // namespace grpc
 
-#endif  // GRPCXX_SERVER_CREDENTIALS_H
+#endif  // GRPCXX_SECURITY_SERVER_CREDENTIALS_H
diff --git a/include/grpc++/server.h b/include/grpc++/server.h
index c177805..9eb8c28 100644
--- a/include/grpc++/server.h
+++ b/include/grpc++/server.h
@@ -62,7 +62,7 @@
 /// Models a gRPC server.
 ///
 /// Servers are configured and started via \a grpc::ServerBuilder.
-class Server GRPC_FINAL : public ServerInterface, private GrpcLibrary {
+class Server GRPC_FINAL : public ServerInterface, private GrpcLibraryCodegen {
  public:
   ~Server();
 
diff --git a/include/grpc/census.h b/include/grpc/census.h
index 442a754..4ccf4af 100644
--- a/include/grpc/census.h
+++ b/include/grpc/census.h
@@ -35,8 +35,8 @@
  * they can (ultimately) be used in many different RPC systems (with differing
  * implementations). */
 
-#ifndef CENSUS_CENSUS_H
-#define CENSUS_CENSUS_H
+#ifndef GRPC_CENSUS_H
+#define GRPC_CENSUS_H
 
 #include <grpc/grpc.h>
 
@@ -537,4 +537,4 @@
 }
 #endif
 
-#endif /* CENSUS_CENSUS_H */
+#endif /* GRPC_CENSUS_H */
diff --git a/include/grpc/compression.h b/include/grpc/compression.h
index acc168a..70ba393 100644
--- a/include/grpc/compression.h
+++ b/include/grpc/compression.h
@@ -55,11 +55,13 @@
 GRPCAPI int grpc_compression_algorithm_name(
     grpc_compression_algorithm algorithm, char **name);
 
-/** Returns the compression algorithm corresponding to \a level.
+/** Returns the compression algorithm corresponding to \a level for the
+ * compression algorithms encoded in the \a accepted_encodings bitset.
  *
  * It abort()s for unknown levels . */
 GRPCAPI grpc_compression_algorithm
-grpc_compression_algorithm_for_level(grpc_compression_level level);
+grpc_compression_algorithm_for_level(grpc_compression_level level,
+                                     uint32_t accepted_encodings);
 
 GRPCAPI void grpc_compression_options_init(grpc_compression_options *opts);
 
diff --git a/include/grpc/grpc_security.h b/include/grpc/grpc_security.h
index ef7205d..368d5dd 100644
--- a/include/grpc/grpc_security.h
+++ b/include/grpc/grpc_security.h
@@ -48,6 +48,7 @@
 
 #define GRPC_X509_CN_PROPERTY_NAME "x509_common_name"
 #define GRPC_X509_SAN_PROPERTY_NAME "x509_subject_alternative_name"
+#define GRPC_X509_PEM_CERT_PROPERTY_NAME "x509_pem_cert"
 
 typedef struct grpc_auth_context grpc_auth_context;
 
diff --git a/include/grpc/impl/codegen/port_platform.h b/include/grpc/impl/codegen/port_platform.h
index 9256904..fd55cb4 100644
--- a/include/grpc/impl/codegen/port_platform.h
+++ b/include/grpc/impl/codegen/port_platform.h
@@ -247,8 +247,41 @@
 #else /* _LP64 */
 #define GPR_ARCH_32 1
 #endif /* _LP64 */
+#elif defined(__native_client__)
+#define GPR_PLATFORM_STRING "nacl"
+#ifndef _BSD_SOURCE
+#define _BSD_SOURCE
+#endif
+#ifndef _DEFAULT_SOURCE
+#define _DEFAULT_SOURCE
+#endif
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+#define GPR_CPU_POSIX 1
+#define GPR_GCC_ATOMIC 1
+#define GPR_GCC_TLS 1
+#define GPR_POSIX_LOG 1
+#define GPR_POSIX_MULTIPOLL_WITH_POLL 1
+#define GPR_POSIX_WAKEUP_FD 1
+#define GPR_POSIX_NO_SPECIAL_WAKEUP_FD 1
+#define GPR_POSIX_SOCKET 1
+#define GPR_POSIX_SOCKETADDR 1
+#define GPR_POSIX_SOCKETUTILS 1
+#define GPR_POSIX_ENV 1
+#define GPR_POSIX_FILE 1
+#define GPR_POSIX_STRING 1
+#define GPR_POSIX_SUBPROCESS 1
+#define GPR_POSIX_SYNC 1
+#define GPR_POSIX_TIME 1
+#define GPR_GETPID_IN_UNISTD_H 1
+#ifdef _LP64
+#define GPR_ARCH_64 1
+#else /* _LP64 */
+#define GPR_ARCH_32 1
+#endif /* _LP64 */
 #else
-#error Could not auto-detect platform
+#error "Could not auto-detect platform"
 #endif
 #endif /* GPR_NO_AUTODETECT_PLATFORM */
 
diff --git a/include/grpc/impl/codegen/propagation_bits.h b/include/grpc/impl/codegen/propagation_bits.h
index cdd6997..4b64558 100644
--- a/include/grpc/impl/codegen/propagation_bits.h
+++ b/include/grpc/impl/codegen/propagation_bits.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_IMPL_CODEGEN_H
-#define GRPC_IMPL_CODEGEN_H
+#ifndef GRPC_IMPL_CODEGEN_PROPAGATION_BITS_H
+#define GRPC_IMPL_CODEGEN_PROPAGATION_BITS_H
 
 #include <grpc/impl/codegen/port_platform.h>
 
@@ -64,4 +64,4 @@
 }
 #endif
 
-#endif /* GRPC_IMPL_CODEGEN_H */
+#endif /* GRPC_IMPL_CODEGEN_PROPAGATION_BITS_H */
diff --git a/include/grpc/support/atm_gcc_atomic.h b/include/grpc/support/atm_gcc_atomic.h
index 7e1f7fd..2fc8f60 100644
--- a/include/grpc/support/atm_gcc_atomic.h
+++ b/include/grpc/support/atm_gcc_atomic.h
@@ -31,9 +31,9 @@
  *
  */
 
-#ifndef GRPC_IMPL_CODEGEN_ATM_GCC_ATOMIC_H
-#define GRPC_IMPL_CODEGEN_ATM_GCC_ATOMIC_H
+#ifndef GRPC_SUPPORT_ATM_GCC_ATOMIC_H
+#define GRPC_SUPPORT_ATM_GCC_ATOMIC_H
 
 #include <grpc/impl/codegen/atm_gcc_atomic.h>
 
-#endif /* GRPC_IMPL_CODEGEN_ATM_GCC_ATOMIC_H */
+#endif /* GRPC_SUPPORT_ATM_GCC_ATOMIC_H */
diff --git a/include/grpc/support/subprocess.h b/include/grpc/support/subprocess.h
index 6a49460..e013b70 100644
--- a/include/grpc/support/subprocess.h
+++ b/include/grpc/support/subprocess.h
@@ -56,4 +56,4 @@
 }  // extern "C"
 #endif
 
-#endif
+#endif /* GRPC_SUPPORT_SUBPROCESS_H */
diff --git a/include/grpc/support/tls.h b/include/grpc/support/tls.h
index 43addc7..0ff19bb 100644
--- a/include/grpc/support/tls.h
+++ b/include/grpc/support/tls.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -74,4 +74,4 @@
 #include <grpc/support/tls_pthread.h>
 #endif
 
-#endif
+#endif /* GRPC_SUPPORT_TLS_H */
diff --git a/include/grpc/support/tls_gcc.h b/include/grpc/support/tls_gcc.h
index a697ad0..21269e4 100644
--- a/include/grpc/support/tls_gcc.h
+++ b/include/grpc/support/tls_gcc.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -34,9 +34,51 @@
 #ifndef GRPC_SUPPORT_TLS_GCC_H
 #define GRPC_SUPPORT_TLS_GCC_H
 
+#include <stdbool.h>
+
+#include <grpc/support/log.h>
+
 /* Thread local storage based on gcc compiler primitives.
    #include tls.h to use this - and see that file for documentation */
 
+#ifndef NDEBUG
+
+struct gpr_gcc_thread_local {
+  intptr_t value;
+  bool *inited;
+};
+
+#define GPR_TLS_DECL(name)           \
+  static bool name##_inited = false; \
+  static __thread struct gpr_gcc_thread_local name = {0, &(name##_inited)}
+
+#define gpr_tls_init(tls)                  \
+  do {                                     \
+    GPR_ASSERT(*((tls)->inited) == false); \
+    *((tls)->inited) = true;               \
+  } while (0)
+
+/* It is allowed to call gpr_tls_init after gpr_tls_destroy is called. */
+#define gpr_tls_destroy(tls)      \
+  do {                            \
+    GPR_ASSERT(*((tls)->inited)); \
+    *((tls)->inited) = false;     \
+  } while (0)
+
+#define gpr_tls_set(tls, new_value) \
+  do {                              \
+    GPR_ASSERT(*((tls)->inited));   \
+    (tls)->value = (new_value);     \
+  } while (0)
+
+#define gpr_tls_get(tls)          \
+  ({                              \
+    GPR_ASSERT(*((tls)->inited)); \
+    (tls)->value;                 \
+  })
+
+#else /* NDEBUG */
+
 struct gpr_gcc_thread_local {
   intptr_t value;
 };
@@ -53,4 +95,6 @@
 #define gpr_tls_set(tls, new_value) (((tls)->value) = (new_value))
 #define gpr_tls_get(tls) ((tls)->value)
 
-#endif
+#endif /* NDEBUG */
+
+#endif /* GRPC_SUPPORT_TLS_GCC_H */
diff --git a/include/grpc/support/tls_msvc.h b/include/grpc/support/tls_msvc.h
index 987a514..751ec35 100644
--- a/include/grpc/support/tls_msvc.h
+++ b/include/grpc/support/tls_msvc.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_SUPPORT_TLS_GCC_H
-#define GRPC_SUPPORT_TLS_GCC_H
+#ifndef GRPC_SUPPORT_TLS_MSVC_H
+#define GRPC_SUPPORT_TLS_MSVC_H
 
 /* Thread local storage based on ms visual c compiler primitives.
    #include tls.h to use this - and see that file for documentation */
@@ -53,4 +53,4 @@
 #define gpr_tls_set(tls, new_value) (((tls)->value) = (new_value))
 #define gpr_tls_get(tls) ((tls)->value)
 
-#endif
+#endif /* GRPC_SUPPORT_TLS_MSVC_H */
diff --git a/include/grpc/support/tls_pthread.h b/include/grpc/support/tls_pthread.h
index 699ee6b..93ba782 100644
--- a/include/grpc/support/tls_pthread.h
+++ b/include/grpc/support/tls_pthread.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -57,4 +57,4 @@
 }
 #endif
 
-#endif
+#endif /* GRPC_SUPPORT_TLS_PTHREAD_H */
diff --git a/package.json b/package.json
index db7f299..371dfdc 100644
--- a/package.json
+++ b/package.json
@@ -87,21 +87,23 @@
     "src/node/src/metadata.js",
     "src/node/src/server.js",
     "include/grpc/grpc_security.h",
+    "include/grpc/byte_buffer.h",
+    "include/grpc/byte_buffer_reader.h",
+    "include/grpc/compression.h",
+    "include/grpc/grpc.h",
+    "include/grpc/status.h",
     "include/grpc/impl/codegen/byte_buffer.h",
     "include/grpc/impl/codegen/compression_types.h",
     "include/grpc/impl/codegen/connectivity_state.h",
     "include/grpc/impl/codegen/grpc_types.h",
     "include/grpc/impl/codegen/propagation_bits.h",
     "include/grpc/impl/codegen/status.h",
-    "include/grpc/byte_buffer.h",
-    "include/grpc/byte_buffer_reader.h",
-    "include/grpc/compression.h",
-    "include/grpc/grpc.h",
-    "include/grpc/status.h",
     "include/grpc/census.h",
     "src/core/census/grpc_filter.h",
+    "src/core/census/grpc_plugin.h",
     "src/core/channel/channel_args.h",
     "src/core/channel/channel_stack.h",
+    "src/core/channel/channel_stack_builder.h",
     "src/core/channel/client_channel.h",
     "src/core/channel/client_uchannel.h",
     "src/core/channel/compress_filter.h",
@@ -181,9 +183,12 @@
     "src/core/surface/call.h",
     "src/core/surface/call_test_only.h",
     "src/core/surface/channel.h",
+    "src/core/surface/channel_init.h",
+    "src/core/surface/channel_stack_type.h",
     "src/core/surface/completion_queue.h",
     "src/core/surface/event_string.h",
     "src/core/surface/init.h",
+    "src/core/surface/lame_client.h",
     "src/core/surface/server.h",
     "src/core/surface/surface_trace.h",
     "src/core/transport/byte_stream.h",
@@ -237,8 +242,10 @@
     "third_party/nanopb/pb_encode.h",
     "src/core/census/grpc_context.c",
     "src/core/census/grpc_filter.c",
+    "src/core/census/grpc_plugin.c",
     "src/core/channel/channel_args.c",
     "src/core/channel/channel_stack.c",
+    "src/core/channel/channel_stack_builder.c",
     "src/core/channel/client_channel.c",
     "src/core/channel/client_uchannel.c",
     "src/core/channel/compress_filter.c",
@@ -326,7 +333,9 @@
     "src/core/surface/channel.c",
     "src/core/surface/channel_connectivity.c",
     "src/core/surface/channel_create.c",
+    "src/core/surface/channel_init.c",
     "src/core/surface/channel_ping.c",
+    "src/core/surface/channel_stack_type.c",
     "src/core/surface/completion_queue.c",
     "src/core/surface/event_string.c",
     "src/core/surface/init.c",
@@ -334,7 +343,6 @@
     "src/core/surface/metadata_array.c",
     "src/core/surface/server.c",
     "src/core/surface/server_chttp2.c",
-    "src/core/surface/server_create.c",
     "src/core/surface/validate_metadata.c",
     "src/core/surface/version.c",
     "src/core/transport/byte_stream.c",
@@ -865,6 +873,7 @@
     "include/grpc/impl/codegen/sync_win32.h",
     "include/grpc/impl/codegen/time.h",
     "src/core/profiling/timers.h",
+    "src/core/support/backoff.h",
     "src/core/support/block_annotate.h",
     "src/core/support/env.h",
     "src/core/support/load_file.h",
@@ -879,6 +888,7 @@
     "src/core/profiling/stap_timers.c",
     "src/core/support/alloc.c",
     "src/core/support/avl.c",
+    "src/core/support/backoff.c",
     "src/core/support/cmdline.c",
     "src/core/support/cpu_iphone.c",
     "src/core/support/cpu_linux.c",
diff --git a/package.xml b/package.xml
index bb4dcc2..a0d8bfd 100644
--- a/package.xml
+++ b/package.xml
@@ -93,6 +93,7 @@
     <file baseinstalldir="/" name="include/grpc/impl/codegen/sync_win32.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/impl/codegen/time.h" role="src" />
     <file baseinstalldir="/" name="src/core/profiling/timers.h" role="src" />
+    <file baseinstalldir="/" name="src/core/support/backoff.h" role="src" />
     <file baseinstalldir="/" name="src/core/support/block_annotate.h" role="src" />
     <file baseinstalldir="/" name="src/core/support/env.h" role="src" />
     <file baseinstalldir="/" name="src/core/support/load_file.h" role="src" />
@@ -107,6 +108,7 @@
     <file baseinstalldir="/" name="src/core/profiling/stap_timers.c" role="src" />
     <file baseinstalldir="/" name="src/core/support/alloc.c" role="src" />
     <file baseinstalldir="/" name="src/core/support/avl.c" role="src" />
+    <file baseinstalldir="/" name="src/core/support/backoff.c" role="src" />
     <file baseinstalldir="/" name="src/core/support/cmdline.c" role="src" />
     <file baseinstalldir="/" name="src/core/support/cpu_iphone.c" role="src" />
     <file baseinstalldir="/" name="src/core/support/cpu_linux.c" role="src" />
@@ -147,21 +149,23 @@
     <file baseinstalldir="/" name="src/core/support/tmpfile_win32.c" role="src" />
     <file baseinstalldir="/" name="src/core/support/wrap_memcpy.c" role="src" />
     <file baseinstalldir="/" name="include/grpc/grpc_security.h" role="src" />
+    <file baseinstalldir="/" name="include/grpc/byte_buffer.h" role="src" />
+    <file baseinstalldir="/" name="include/grpc/byte_buffer_reader.h" role="src" />
+    <file baseinstalldir="/" name="include/grpc/compression.h" role="src" />
+    <file baseinstalldir="/" name="include/grpc/grpc.h" role="src" />
+    <file baseinstalldir="/" name="include/grpc/status.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/impl/codegen/byte_buffer.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/impl/codegen/compression_types.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/impl/codegen/connectivity_state.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/impl/codegen/grpc_types.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/impl/codegen/propagation_bits.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/impl/codegen/status.h" role="src" />
-    <file baseinstalldir="/" name="include/grpc/byte_buffer.h" role="src" />
-    <file baseinstalldir="/" name="include/grpc/byte_buffer_reader.h" role="src" />
-    <file baseinstalldir="/" name="include/grpc/compression.h" role="src" />
-    <file baseinstalldir="/" name="include/grpc/grpc.h" role="src" />
-    <file baseinstalldir="/" name="include/grpc/status.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/census.h" role="src" />
     <file baseinstalldir="/" name="src/core/census/grpc_filter.h" role="src" />
+    <file baseinstalldir="/" name="src/core/census/grpc_plugin.h" role="src" />
     <file baseinstalldir="/" name="src/core/channel/channel_args.h" role="src" />
     <file baseinstalldir="/" name="src/core/channel/channel_stack.h" role="src" />
+    <file baseinstalldir="/" name="src/core/channel/channel_stack_builder.h" role="src" />
     <file baseinstalldir="/" name="src/core/channel/client_channel.h" role="src" />
     <file baseinstalldir="/" name="src/core/channel/client_uchannel.h" role="src" />
     <file baseinstalldir="/" name="src/core/channel/compress_filter.h" role="src" />
@@ -241,9 +245,12 @@
     <file baseinstalldir="/" name="src/core/surface/call.h" role="src" />
     <file baseinstalldir="/" name="src/core/surface/call_test_only.h" role="src" />
     <file baseinstalldir="/" name="src/core/surface/channel.h" role="src" />
+    <file baseinstalldir="/" name="src/core/surface/channel_init.h" role="src" />
+    <file baseinstalldir="/" name="src/core/surface/channel_stack_type.h" role="src" />
     <file baseinstalldir="/" name="src/core/surface/completion_queue.h" role="src" />
     <file baseinstalldir="/" name="src/core/surface/event_string.h" role="src" />
     <file baseinstalldir="/" name="src/core/surface/init.h" role="src" />
+    <file baseinstalldir="/" name="src/core/surface/lame_client.h" role="src" />
     <file baseinstalldir="/" name="src/core/surface/server.h" role="src" />
     <file baseinstalldir="/" name="src/core/surface/surface_trace.h" role="src" />
     <file baseinstalldir="/" name="src/core/transport/byte_stream.h" role="src" />
@@ -297,8 +304,10 @@
     <file baseinstalldir="/" name="third_party/nanopb/pb_encode.h" role="src" />
     <file baseinstalldir="/" name="src/core/census/grpc_context.c" role="src" />
     <file baseinstalldir="/" name="src/core/census/grpc_filter.c" role="src" />
+    <file baseinstalldir="/" name="src/core/census/grpc_plugin.c" role="src" />
     <file baseinstalldir="/" name="src/core/channel/channel_args.c" role="src" />
     <file baseinstalldir="/" name="src/core/channel/channel_stack.c" role="src" />
+    <file baseinstalldir="/" name="src/core/channel/channel_stack_builder.c" role="src" />
     <file baseinstalldir="/" name="src/core/channel/client_channel.c" role="src" />
     <file baseinstalldir="/" name="src/core/channel/client_uchannel.c" role="src" />
     <file baseinstalldir="/" name="src/core/channel/compress_filter.c" role="src" />
@@ -386,7 +395,9 @@
     <file baseinstalldir="/" name="src/core/surface/channel.c" role="src" />
     <file baseinstalldir="/" name="src/core/surface/channel_connectivity.c" role="src" />
     <file baseinstalldir="/" name="src/core/surface/channel_create.c" role="src" />
+    <file baseinstalldir="/" name="src/core/surface/channel_init.c" role="src" />
     <file baseinstalldir="/" name="src/core/surface/channel_ping.c" role="src" />
+    <file baseinstalldir="/" name="src/core/surface/channel_stack_type.c" role="src" />
     <file baseinstalldir="/" name="src/core/surface/completion_queue.c" role="src" />
     <file baseinstalldir="/" name="src/core/surface/event_string.c" role="src" />
     <file baseinstalldir="/" name="src/core/surface/init.c" role="src" />
@@ -394,7 +405,6 @@
     <file baseinstalldir="/" name="src/core/surface/metadata_array.c" role="src" />
     <file baseinstalldir="/" name="src/core/surface/server.c" role="src" />
     <file baseinstalldir="/" name="src/core/surface/server_chttp2.c" role="src" />
-    <file baseinstalldir="/" name="src/core/surface/server_create.c" role="src" />
     <file baseinstalldir="/" name="src/core/surface/validate_metadata.c" role="src" />
     <file baseinstalldir="/" name="src/core/surface/version.c" role="src" />
     <file baseinstalldir="/" name="src/core/transport/byte_stream.c" role="src" />
diff --git a/setup.py b/setup.py
index 45ff2ce..afa9872 100644
--- a/setup.py
+++ b/setup.py
@@ -42,6 +42,7 @@
 # Redirect the manifest template from MANIFEST.in to PYTHON-MANIFEST.in.
 egg_info.manifest_maker.template = 'PYTHON-MANIFEST.in'
 
+PY3 = sys.version_info.major == 3
 PYTHON_STEM = './src/python/grpcio'
 CORE_INCLUDE = ('./include', '.',)
 BORINGSSL_INCLUDE = ('./third_party/boringssl/include',)
@@ -103,7 +104,11 @@
   LDFLAGS += ('-Wl,-wrap,memcpy',)
 if "linux" in sys.platform or "darwin" in sys.platform:
   CFLAGS += ('-fvisibility=hidden',)
-  DEFINE_MACROS += (('PyMODINIT_FUNC', '__attribute__((visibility ("default"))) void'),)
+
+  pymodinit_type = 'PyObject*' if PY3 else 'void'
+
+  pymodinit = '__attribute__((visibility ("default"))) {}'.format(pymodinit_type)
+  DEFINE_MACROS += (('PyMODINIT_FUNC', pymodinit),)
 
 
 def cython_extensions(package_names, module_names, extra_sources, include_dirs,
diff --git a/src/core/census/aggregation.h b/src/core/census/aggregation.h
index e9bc6ad..e0ef963 100644
--- a/src/core/census/aggregation.h
+++ b/src/core/census/aggregation.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -33,8 +33,8 @@
 
 #include <stddef.h>
 
-#ifndef GRPC_INTERNAL_CORE_CENSUS_AGGREGATION_H
-#define GRPC_INTERNAL_CORE_CENSUS_AGGREGATION_H
+#ifndef GRPC_CORE_CENSUS_AGGREGATION_H
+#define GRPC_CORE_CENSUS_AGGREGATION_H
 
 /** Structure used to describe an aggregation type. */
 struct census_aggregation_ops {
@@ -63,4 +63,4 @@
   size_t (*print)(const void *aggregation, char *buffer, size_t n);
 };
 
-#endif /* GRPC_INTERNAL_CORE_CENSUS_AGGREGATION_H */
+#endif /* GRPC_CORE_CENSUS_AGGREGATION_H */
diff --git a/src/core/census/grpc_filter.h b/src/core/census/grpc_filter.h
index b3de3ad..4699e4d 100644
--- a/src/core/census/grpc_filter.h
+++ b/src/core/census/grpc_filter.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_CENSUS_GRPC_FILTER_H
-#define GRPC_INTERNAL_CORE_CENSUS_GRPC_FILTER_H
+#ifndef GRPC_CORE_CENSUS_GRPC_FILTER_H
+#define GRPC_CORE_CENSUS_GRPC_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_CORE_CENSUS_GRPC_FILTER_H */
+#endif /* GRPC_CORE_CENSUS_GRPC_FILTER_H */
diff --git a/src/core/census/grpc_plugin.c b/src/core/census/grpc_plugin.c
new file mode 100644
index 0000000..3be2a48
--- /dev/null
+++ b/src/core/census/grpc_plugin.c
@@ -0,0 +1,72 @@
+/*
+ *
+ * Copyright 2015-2016, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "src/core/census/grpc_plugin.h"
+
+#include <limits.h>
+
+#include <grpc/census.h>
+
+#include "src/core/census/grpc_filter.h"
+#include "src/core/surface/channel_init.h"
+#include "src/core/channel/channel_stack_builder.h"
+
+static bool maybe_add_census_filter(grpc_channel_stack_builder *builder,
+                                    void *arg_must_be_null) {
+  const grpc_channel_args *args =
+      grpc_channel_stack_builder_get_channel_arguments(builder);
+  if (grpc_channel_args_is_census_enabled(args)) {
+    return grpc_channel_stack_builder_prepend_filter(
+        builder, &grpc_client_census_filter, NULL, NULL);
+  }
+  return true;
+}
+
+void census_grpc_plugin_init(void) {
+  /* Only initialize census if no one else has and some features are
+   * available. */
+  if (census_enabled() == CENSUS_FEATURE_NONE &&
+      census_supported() != CENSUS_FEATURE_NONE) {
+    if (census_initialize(census_supported())) { /* enable all features. */
+      gpr_log(GPR_ERROR, "Could not initialize census.");
+    }
+  }
+  grpc_channel_init_register_stage(GRPC_CLIENT_CHANNEL, INT_MAX,
+                                   maybe_add_census_filter, NULL);
+  grpc_channel_init_register_stage(GRPC_CLIENT_UCHANNEL, INT_MAX,
+                                   maybe_add_census_filter, NULL);
+  grpc_channel_init_register_stage(GRPC_SERVER_CHANNEL, INT_MAX,
+                                   maybe_add_census_filter, NULL);
+}
+
+void census_grpc_plugin_destroy(void) { census_shutdown(); }
diff --git a/src/cpp/codegen/grpc_library.cc b/src/core/census/grpc_plugin.h
similarity index 86%
copy from src/cpp/codegen/grpc_library.cc
copy to src/core/census/grpc_plugin.h
index 48acec3..9321c2c 100644
--- a/src/cpp/codegen/grpc_library.cc
+++ b/src/core/census/grpc_plugin.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2016, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,10 +31,10 @@
  *
  */
 
-#include <grpc++/impl/codegen/grpc_library.h>
+#ifndef GRPC_CORE_CENSUS_GRPC_PLUGIN_H
+#define GRPC_CORE_CENSUS_GRPC_PLUGIN_H
 
-namespace grpc {
+void census_grpc_plugin_init(void);
+void census_grpc_plugin_destroy(void);
 
-GrpcLibraryInterface *g_glip = nullptr;
-
-}  // namespace grpc
+#endif /* GRPC_CORE_CENSUS_GRPC_PLUGIN_H */
diff --git a/src/core/census/mlog.h b/src/core/census/mlog.h
index aaba9e1..bc6eaea 100644
--- a/src/core/census/mlog.h
+++ b/src/core/census/mlog.h
@@ -33,8 +33,8 @@
 
 /* A very fast in-memory log, optimized for multiple writers. */
 
-#ifndef GRPC_INTERNAL_CORE_CENSUS_MLOG_H
-#define GRPC_INTERNAL_CORE_CENSUS_MLOG_H
+#ifndef GRPC_CORE_CENSUS_MLOG_H
+#define GRPC_CORE_CENSUS_MLOG_H
 
 #include <grpc/support/port_platform.h>
 #include <stddef.h>
@@ -92,4 +92,4 @@
    out-of-space. */
 int64_t census_log_out_of_space_count(void);
 
-#endif /* GRPC_INTERNAL_CORE_CENSUS_LOG_H */
+#endif /* GRPC_CORE_CENSUS_MLOG_H */
diff --git a/src/core/census/rpc_metric_id.h b/src/core/census/rpc_metric_id.h
index f199839..f8d8dad 100644
--- a/src/core/census/rpc_metric_id.h
+++ b/src/core/census/rpc_metric_id.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef CENSUS_RPC_METRIC_ID_H
-#define CENSUS_RPC_METRIC_ID_H
+#ifndef GRPC_CORE_CENSUS_RPC_METRIC_ID_H
+#define GRPC_CORE_CENSUS_RPC_METRIC_ID_H
 
 /* Metric ID's used for RPC measurements. */
 /* Count of client requests sent. */
@@ -48,4 +48,4 @@
 /* Server side request latency. */
 #define CENSUS_METRIC_RPC_SERVER_LATENCY ((uint32_t)5)
 
-#endif /* CENSUS_RPC_METRIC_ID_H */
+#endif /* GRPC_CORE_CENSUS_RPC_METRIC_ID_H */
diff --git a/src/core/channel/channel_args.h b/src/core/channel/channel_args.h
index b3a7c9f..e19440f 100644
--- a/src/core/channel/channel_args.h
+++ b/src/core/channel/channel_args.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_CHANNEL_CHANNEL_ARGS_H
-#define GRPC_INTERNAL_CORE_CHANNEL_CHANNEL_ARGS_H
+#ifndef GRPC_CORE_CHANNEL_CHANNEL_ARGS_H
+#define GRPC_CORE_CHANNEL_CHANNEL_ARGS_H
 
 #include <grpc/compression.h>
 #include <grpc/grpc.h>
@@ -91,4 +91,4 @@
 int grpc_channel_args_compare(const grpc_channel_args *a,
                               const grpc_channel_args *b);
 
-#endif /* GRPC_INTERNAL_CORE_CHANNEL_CHANNEL_ARGS_H */
+#endif /* GRPC_CORE_CHANNEL_CHANNEL_ARGS_H */
diff --git a/src/core/channel/channel_stack.h b/src/core/channel/channel_stack.h
index c01050e..52362f0 100644
--- a/src/core/channel/channel_stack.h
+++ b/src/core/channel/channel_stack.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_CHANNEL_CHANNEL_STACK_H
-#define GRPC_INTERNAL_CORE_CHANNEL_CHANNEL_STACK_H
+#ifndef GRPC_CORE_CHANNEL_CHANNEL_STACK_H
+#define GRPC_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
@@ -257,4 +257,4 @@
 #define GRPC_CALL_LOG_OP(sev, elem, op) \
   if (grpc_trace_channel) grpc_call_log_op(sev, elem, op)
 
-#endif /* GRPC_INTERNAL_CORE_CHANNEL_CHANNEL_STACK_H */
+#endif /* GRPC_CORE_CHANNEL_CHANNEL_STACK_H */
diff --git a/src/core/channel/channel_stack_builder.c b/src/core/channel/channel_stack_builder.c
new file mode 100644
index 0000000..80e2e39
--- /dev/null
+++ b/src/core/channel/channel_stack_builder.c
@@ -0,0 +1,259 @@
+/*
+ *
+ * Copyright 2016, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "src/core/channel/channel_stack_builder.h"
+
+#include <string.h>
+
+#include <grpc/support/alloc.h>
+
+int grpc_trace_channel_stack_builder = 0;
+
+typedef struct filter_node {
+  struct filter_node *next;
+  struct filter_node *prev;
+  const grpc_channel_filter *filter;
+  grpc_post_filter_create_init_func init;
+  void *init_arg;
+} filter_node;
+
+struct grpc_channel_stack_builder {
+  // sentinel nodes for filters that have been added
+  filter_node begin;
+  filter_node end;
+  // various set/get-able parameters
+  const grpc_channel_args *args;
+  grpc_transport *transport;
+  const char *name;
+};
+
+struct grpc_channel_stack_builder_iterator {
+  grpc_channel_stack_builder *builder;
+  filter_node *node;
+};
+
+grpc_channel_stack_builder *grpc_channel_stack_builder_create(void) {
+  grpc_channel_stack_builder *b = gpr_malloc(sizeof(*b));
+  memset(b, 0, sizeof(*b));
+
+  b->begin.filter = NULL;
+  b->end.filter = NULL;
+  b->begin.next = &b->end;
+  b->begin.prev = &b->end;
+  b->end.next = &b->begin;
+  b->end.prev = &b->begin;
+
+  return b;
+}
+
+static grpc_channel_stack_builder_iterator *create_iterator_at_filter_node(
+    grpc_channel_stack_builder *builder, filter_node *node) {
+  grpc_channel_stack_builder_iterator *it = gpr_malloc(sizeof(*it));
+  it->builder = builder;
+  it->node = node;
+  return it;
+}
+
+void grpc_channel_stack_builder_iterator_destroy(
+    grpc_channel_stack_builder_iterator *it) {
+  gpr_free(it);
+}
+
+grpc_channel_stack_builder_iterator *
+grpc_channel_stack_builder_create_iterator_at_first(
+    grpc_channel_stack_builder *builder) {
+  return create_iterator_at_filter_node(builder, &builder->begin);
+}
+
+grpc_channel_stack_builder_iterator *
+grpc_channel_stack_builder_create_iterator_at_last(
+    grpc_channel_stack_builder *builder) {
+  return create_iterator_at_filter_node(builder, &builder->end);
+}
+
+bool grpc_channel_stack_builder_move_next(
+    grpc_channel_stack_builder_iterator *iterator) {
+  if (iterator->node == &iterator->builder->end) return false;
+  iterator->node = iterator->node->next;
+  return true;
+}
+
+bool grpc_channel_stack_builder_move_prev(
+    grpc_channel_stack_builder_iterator *iterator) {
+  if (iterator->node == &iterator->builder->begin) return false;
+  iterator->node = iterator->node->prev;
+  return true;
+}
+
+bool grpc_channel_stack_builder_move_prev(
+    grpc_channel_stack_builder_iterator *iterator);
+
+void grpc_channel_stack_builder_set_name(grpc_channel_stack_builder *builder,
+                                         const char *name) {
+  GPR_ASSERT(builder->name == NULL);
+  builder->name = name;
+}
+
+void grpc_channel_stack_builder_set_channel_arguments(
+    grpc_channel_stack_builder *builder, const grpc_channel_args *args) {
+  GPR_ASSERT(builder->args == NULL);
+  builder->args = args;
+}
+
+void grpc_channel_stack_builder_set_transport(
+    grpc_channel_stack_builder *builder, grpc_transport *transport) {
+  GPR_ASSERT(builder->transport == NULL);
+  builder->transport = transport;
+}
+
+grpc_transport *grpc_channel_stack_builder_get_transport(
+    grpc_channel_stack_builder *builder) {
+  return builder->transport;
+}
+
+const grpc_channel_args *grpc_channel_stack_builder_get_channel_arguments(
+    grpc_channel_stack_builder *builder) {
+  return builder->args;
+}
+
+bool grpc_channel_stack_builder_append_filter(
+    grpc_channel_stack_builder *builder, const grpc_channel_filter *filter,
+    grpc_post_filter_create_init_func post_init_func, void *user_data) {
+  grpc_channel_stack_builder_iterator *it =
+      grpc_channel_stack_builder_create_iterator_at_last(builder);
+  bool ok = grpc_channel_stack_builder_add_filter_before(
+      it, filter, post_init_func, user_data);
+  grpc_channel_stack_builder_iterator_destroy(it);
+  return ok;
+}
+
+bool grpc_channel_stack_builder_prepend_filter(
+    grpc_channel_stack_builder *builder, const grpc_channel_filter *filter,
+    grpc_post_filter_create_init_func post_init_func, void *user_data) {
+  grpc_channel_stack_builder_iterator *it =
+      grpc_channel_stack_builder_create_iterator_at_first(builder);
+  bool ok = grpc_channel_stack_builder_add_filter_after(
+      it, filter, post_init_func, user_data);
+  grpc_channel_stack_builder_iterator_destroy(it);
+  return ok;
+}
+
+static void add_after(filter_node *before, const grpc_channel_filter *filter,
+                      grpc_post_filter_create_init_func post_init_func,
+                      void *user_data) {
+  filter_node *new = gpr_malloc(sizeof(*new));
+  new->next = before->next;
+  new->prev = before;
+  new->next->prev = new->prev->next = new;
+  new->filter = filter;
+  new->init = post_init_func;
+  new->init_arg = user_data;
+}
+
+bool grpc_channel_stack_builder_add_filter_before(
+    grpc_channel_stack_builder_iterator *iterator,
+    const grpc_channel_filter *filter,
+    grpc_post_filter_create_init_func post_init_func, void *user_data) {
+  if (iterator->node == &iterator->builder->begin) return false;
+  add_after(iterator->node->prev, filter, post_init_func, user_data);
+  return true;
+}
+
+bool grpc_channel_stack_builder_add_filter_after(
+    grpc_channel_stack_builder_iterator *iterator,
+    const grpc_channel_filter *filter,
+    grpc_post_filter_create_init_func post_init_func, void *user_data) {
+  if (iterator->node == &iterator->builder->end) return false;
+  add_after(iterator->node, filter, post_init_func, user_data);
+  return true;
+}
+
+void grpc_channel_stack_builder_destroy(grpc_channel_stack_builder *builder) {
+  filter_node *p = builder->begin.next;
+  while (p != &builder->end) {
+    filter_node *next = p->next;
+    gpr_free(p);
+    p = next;
+  }
+  gpr_free(builder);
+}
+
+void *grpc_channel_stack_builder_finish(grpc_exec_ctx *exec_ctx,
+                                        grpc_channel_stack_builder *builder,
+                                        size_t prefix_bytes, int initial_refs,
+                                        grpc_iomgr_cb_func destroy,
+                                        void *destroy_arg) {
+  // count the number of filters
+  size_t num_filters = 0;
+  for (filter_node *p = builder->begin.next; p != &builder->end; p = p->next) {
+    gpr_log(GPR_DEBUG, "%d: %s", num_filters, p->filter->name);
+    num_filters++;
+  }
+
+  // create an array of filters
+  const grpc_channel_filter **filters =
+      gpr_malloc(sizeof(*filters) * num_filters);
+  size_t i = 0;
+  for (filter_node *p = builder->begin.next; p != &builder->end; p = p->next) {
+    filters[i++] = p->filter;
+  }
+
+  // calculate the size of the channel stack
+  size_t channel_stack_size = grpc_channel_stack_size(filters, num_filters);
+
+  // allocate memory, with prefix_bytes followed by channel_stack_size
+  char *result = gpr_malloc(prefix_bytes + channel_stack_size);
+  // fetch a pointer to the channel stack
+  grpc_channel_stack *channel_stack =
+      (grpc_channel_stack *)(result + prefix_bytes);
+  // and initialize it
+  grpc_channel_stack_init(exec_ctx, initial_refs, destroy,
+                          destroy_arg == NULL ? result : destroy_arg, filters,
+                          num_filters, builder->args, builder->name,
+                          channel_stack);
+
+  // run post-initialization functions
+  i = 0;
+  for (filter_node *p = builder->begin.next; p != &builder->end; p = p->next) {
+    if (p->init != NULL) {
+      p->init(channel_stack, grpc_channel_stack_element(channel_stack, i),
+              p->init_arg);
+    }
+    i++;
+  }
+
+  grpc_channel_stack_builder_destroy(builder);
+  gpr_free((grpc_channel_filter **)filters);
+
+  return result;
+}
diff --git a/src/core/channel/channel_stack_builder.h b/src/core/channel/channel_stack_builder.h
new file mode 100644
index 0000000..15f395e
--- /dev/null
+++ b/src/core/channel/channel_stack_builder.h
@@ -0,0 +1,155 @@
+/*
+ *
+ * Copyright 2016, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef GRPC_CORE_CHANNEL_CHANNEL_STACK_BUILDER_H
+#define GRPC_CORE_CHANNEL_CHANNEL_STACK_BUILDER_H
+
+#include <stdbool.h>
+
+#include "src/core/channel/channel_args.h"
+#include "src/core/channel/channel_stack.h"
+
+/// grpc_channel_stack_builder offers a programmatic interface to selected
+/// and order channel filters
+typedef struct grpc_channel_stack_builder grpc_channel_stack_builder;
+typedef struct grpc_channel_stack_builder_iterator
+    grpc_channel_stack_builder_iterator;
+
+/// Create a new channel stack builder
+grpc_channel_stack_builder *grpc_channel_stack_builder_create(void);
+
+/// Assign a name to the channel stack: \a name must be statically allocated
+void grpc_channel_stack_builder_set_name(grpc_channel_stack_builder *builder,
+                                         const char *name);
+
+/// Attach \a transport to the builder (does not take ownership)
+void grpc_channel_stack_builder_set_transport(
+    grpc_channel_stack_builder *builder, grpc_transport *transport);
+
+/// Fetch attached transport
+grpc_transport *grpc_channel_stack_builder_get_transport(
+    grpc_channel_stack_builder *builder);
+
+/// Set channel arguments: \a args must continue to exist until after
+/// grpc_channel_stack_builder_finish returns
+void grpc_channel_stack_builder_set_channel_arguments(
+    grpc_channel_stack_builder *builder, const grpc_channel_args *args);
+
+/// Return a borrowed pointer to the channel arguments
+const grpc_channel_args *grpc_channel_stack_builder_get_channel_arguments(
+    grpc_channel_stack_builder *builder);
+
+/// Begin iterating over already defined filters in the builder at the beginning
+grpc_channel_stack_builder_iterator *
+grpc_channel_stack_builder_create_iterator_at_first(
+    grpc_channel_stack_builder *builder);
+
+/// Begin iterating over already defined filters in the builder at the end
+grpc_channel_stack_builder_iterator *
+grpc_channel_stack_builder_create_iterator_at_last(
+    grpc_channel_stack_builder *builder);
+
+/// Is an iterator at the first element?
+bool grpc_channel_stack_builder_iterator_is_first(
+    grpc_channel_stack_builder_iterator *iterator);
+
+/// Is an iterator at the end?
+bool grpc_channel_stack_builder_iterator_is_end(
+    grpc_channel_stack_builder_iterator *iterator);
+
+/// Move an iterator to the next item
+bool grpc_channel_stack_builder_move_next(
+    grpc_channel_stack_builder_iterator *iterator);
+
+/// Move an iterator to the previous item
+bool grpc_channel_stack_builder_move_prev(
+    grpc_channel_stack_builder_iterator *iterator);
+
+typedef void (*grpc_post_filter_create_init_func)(
+    grpc_channel_stack *channel_stack, grpc_channel_element *elem, void *arg);
+
+/// Add \a filter to the stack, after \a iterator.
+/// Call \a post_init_func(..., \a user_data) once the channel stack is
+/// created.
+bool grpc_channel_stack_builder_add_filter_after(
+    grpc_channel_stack_builder_iterator *iterator,
+    const grpc_channel_filter *filter,
+    grpc_post_filter_create_init_func post_init_func,
+    void *user_data) GRPC_MUST_USE_RESULT;
+
+/// Add \a filter to the stack, before \a iterator.
+/// Call \a post_init_func(..., \a user_data) once the channel stack is
+/// created.
+bool grpc_channel_stack_builder_add_filter_before(
+    grpc_channel_stack_builder_iterator *iterator,
+    const grpc_channel_filter *filter,
+    grpc_post_filter_create_init_func post_init_func,
+    void *user_data) GRPC_MUST_USE_RESULT;
+
+/// Add \a filter to the beginning of the filter list.
+/// Call \a post_init_func(..., \a user_data) once the channel stack is
+/// created.
+bool grpc_channel_stack_builder_prepend_filter(
+    grpc_channel_stack_builder *builder, const grpc_channel_filter *filter,
+    grpc_post_filter_create_init_func post_init_func,
+    void *user_data) GRPC_MUST_USE_RESULT;
+
+/// Add \a filter to the end of the filter list.
+/// Call \a post_init_func(..., \a user_data) once the channel stack is
+/// created.
+bool grpc_channel_stack_builder_append_filter(
+    grpc_channel_stack_builder *builder, const grpc_channel_filter *filter,
+    grpc_post_filter_create_init_func post_init_func,
+    void *user_data) GRPC_MUST_USE_RESULT;
+
+/// Terminate iteration and destroy \a iterator
+void grpc_channel_stack_builder_iterator_destroy(
+    grpc_channel_stack_builder_iterator *iterator);
+
+/// Destroy the builder, return the freshly minted channel stack
+/// Allocates \a prefix_bytes bytes before the channel stack
+/// Returns the base pointer of the allocated block
+/// \a initial_refs, \a destroy, \a destroy_arg are as per
+/// grpc_channel_stack_init
+void *grpc_channel_stack_builder_finish(grpc_exec_ctx *exec_ctx,
+                                        grpc_channel_stack_builder *builder,
+                                        size_t prefix_bytes, int initial_refs,
+                                        grpc_iomgr_cb_func destroy,
+                                        void *destroy_arg);
+
+/// Destroy the builder without creating a channel stack
+void grpc_channel_stack_builder_destroy(grpc_channel_stack_builder *builder);
+
+extern int grpc_trace_channel_stack_builder;
+
+#endif /* GRPC_CORE_CHANNEL_CHANNEL_STACK_BUILDER_H */
diff --git a/src/core/channel/client_channel.h b/src/core/channel/client_channel.h
index d9bc497..422f7f8 100644
--- a/src/core/channel/client_channel.h
+++ b/src/core/channel/client_channel.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_CHANNEL_CLIENT_CHANNEL_H
-#define GRPC_INTERNAL_CORE_CHANNEL_CLIENT_CHANNEL_H
+#ifndef GRPC_CORE_CHANNEL_CLIENT_CHANNEL_H
+#define GRPC_CORE_CHANNEL_CLIENT_CHANNEL_H
 
 #include "src/core/channel/channel_stack.h"
 #include "src/core/client_config/resolver.h"
@@ -60,4 +60,4 @@
     grpc_exec_ctx *exec_ctx, grpc_channel_element *elem, grpc_pollset *pollset,
     grpc_connectivity_state *state, grpc_closure *on_complete);
 
-#endif /* GRPC_INTERNAL_CORE_CHANNEL_CLIENT_CHANNEL_H */
+#endif /* GRPC_CORE_CHANNEL_CLIENT_CHANNEL_H */
diff --git a/src/core/channel/client_uchannel.c b/src/core/channel/client_uchannel.c
index 83fcc3a..d323272 100644
--- a/src/core/channel/client_uchannel.c
+++ b/src/core/channel/client_uchannel.c
@@ -212,20 +212,10 @@
 grpc_channel *grpc_client_uchannel_create(grpc_subchannel *subchannel,
                                           grpc_channel_args *args) {
   grpc_channel *channel = NULL;
-#define MAX_FILTERS 3
-  const grpc_channel_filter *filters[MAX_FILTERS];
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
-  size_t n = 0;
-
-  if (grpc_channel_args_is_census_enabled(args)) {
-    filters[n++] = &grpc_client_census_filter;
-  }
-  filters[n++] = &grpc_compress_filter;
-  filters[n++] = &grpc_client_uchannel_filter;
-  GPR_ASSERT(n <= MAX_FILTERS);
 
   channel =
-      grpc_channel_create_from_filters(&exec_ctx, NULL, filters, n, args, 1);
+      grpc_channel_create(&exec_ctx, NULL, args, GRPC_CLIENT_UCHANNEL, NULL);
 
   return channel;
 }
diff --git a/src/core/channel/client_uchannel.h b/src/core/channel/client_uchannel.h
index 92a8314..8bb288e 100644
--- a/src/core/channel/client_uchannel.h
+++ b/src/core/channel/client_uchannel.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_CHANNEL_CLIENT_MICROCHANNEL_H
-#define GRPC_INTERNAL_CORE_CHANNEL_CLIENT_MICROCHANNEL_H
+#ifndef GRPC_CORE_CHANNEL_CLIENT_UCHANNEL_H
+#define GRPC_CORE_CHANNEL_CLIENT_UCHANNEL_H
 
 #include "src/core/channel/channel_stack.h"
 #include "src/core/client_config/resolver.h"
@@ -57,4 +57,4 @@
 void grpc_client_uchannel_set_connected_subchannel(
     grpc_channel *uchannel, grpc_connected_subchannel *connected_subchannel);
 
-#endif /* GRPC_INTERNAL_CORE_CHANNEL_CLIENT_MICROCHANNEL_H */
+#endif /* GRPC_CORE_CHANNEL_CLIENT_UCHANNEL_H */
diff --git a/src/core/channel/compress_filter.h b/src/core/channel/compress_filter.h
index 415459b..8c208ac 100644
--- a/src/core/channel/compress_filter.h
+++ b/src/core/channel/compress_filter.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_CHANNEL_COMPRESS_FILTER_H
-#define GRPC_INTERNAL_CORE_CHANNEL_COMPRESS_FILTER_H
+#ifndef GRPC_CORE_CHANNEL_COMPRESS_FILTER_H
+#define GRPC_CORE_CHANNEL_COMPRESS_FILTER_H
 
 #include "src/core/channel/channel_stack.h"
 
@@ -62,4 +62,4 @@
 
 extern const grpc_channel_filter grpc_compress_filter;
 
-#endif /* GRPC_INTERNAL_CORE_CHANNEL_COMPRESS_FILTER_H */
+#endif /* GRPC_CORE_CHANNEL_COMPRESS_FILTER_H */
diff --git a/src/core/channel/connected_channel.c b/src/core/channel/connected_channel.c
index e8eb9dc..e7ed3cc 100644
--- a/src/core/channel/connected_channel.c
+++ b/src/core/channel/connected_channel.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -67,7 +67,6 @@
                                           grpc_transport_stream_op *op) {
   call_data *calld = elem->call_data;
   channel_data *chand = elem->channel_data;
-  GPR_ASSERT(elem->filter == &grpc_connected_channel_filter);
   GRPC_CALL_LOG_OP(GPR_INFO, elem, op);
 
   grpc_transport_perform_stream_op(exec_ctx, chand->transport,
@@ -88,7 +87,6 @@
   channel_data *chand = elem->channel_data;
   int r;
 
-  GPR_ASSERT(elem->filter == &grpc_connected_channel_filter);
   r = grpc_transport_init_stream(
       exec_ctx, chand->transport, TRANSPORT_STREAM_FROM_CALL_DATA(calld),
       &args->call_stack->refcount, args->server_transport_data);
@@ -108,7 +106,6 @@
                               grpc_call_element *elem) {
   call_data *calld = elem->call_data;
   channel_data *chand = elem->channel_data;
-  GPR_ASSERT(elem->filter == &grpc_connected_channel_filter);
   grpc_transport_destroy_stream(exec_ctx, chand->transport,
                                 TRANSPORT_STREAM_FROM_CALL_DATA(calld));
 }
@@ -119,7 +116,6 @@
                               grpc_channel_element_args *args) {
   channel_data *cd = (channel_data *)elem->channel_data;
   GPR_ASSERT(args->is_last);
-  GPR_ASSERT(elem->filter == &grpc_connected_channel_filter);
   cd->transport = NULL;
 }
 
@@ -127,7 +123,6 @@
 static void destroy_channel_elem(grpc_exec_ctx *exec_ctx,
                                  grpc_channel_element *elem) {
   channel_data *cd = (channel_data *)elem->channel_data;
-  GPR_ASSERT(elem->filter == &grpc_connected_channel_filter);
   grpc_transport_destroy(exec_ctx, cd->transport);
 }
 
@@ -136,21 +131,18 @@
   return grpc_transport_get_peer(exec_ctx, chand->transport);
 }
 
-const grpc_channel_filter grpc_connected_channel_filter = {
+static const grpc_channel_filter connected_channel_filter = {
     con_start_transport_stream_op, con_start_transport_op, sizeof(call_data),
     init_call_elem, set_pollset, destroy_call_elem, sizeof(channel_data),
     init_channel_elem, destroy_channel_elem, con_get_peer, "connected",
 };
 
-void grpc_connected_channel_bind_transport(grpc_channel_stack *channel_stack,
-                                           grpc_transport *transport) {
-  /* Assumes that the connected channel filter is always the last filter
-     in a channel stack */
-  grpc_channel_element *elem = grpc_channel_stack_last_element(channel_stack);
+static void bind_transport(grpc_channel_stack *channel_stack,
+                           grpc_channel_element *elem, void *t) {
   channel_data *cd = (channel_data *)elem->channel_data;
-  GPR_ASSERT(elem->filter == &grpc_connected_channel_filter);
+  GPR_ASSERT(elem->filter == &connected_channel_filter);
   GPR_ASSERT(cd->transport == NULL);
-  cd->transport = transport;
+  cd->transport = t;
 
   /* HACK(ctiller): increase call stack size for the channel to make space
      for channel data. We need a cleaner (but performant) way to do this,
@@ -158,7 +150,16 @@
      This is only "safe" because call stacks place no additional data after
      the last call element, and the last call element MUST be the connected
      channel. */
-  channel_stack->call_stack_size += grpc_transport_stream_size(transport);
+  channel_stack->call_stack_size += grpc_transport_stream_size(t);
+}
+
+bool grpc_add_connected_filter(grpc_channel_stack_builder *builder,
+                               void *arg_must_be_null) {
+  GPR_ASSERT(arg_must_be_null == NULL);
+  grpc_transport *t = grpc_channel_stack_builder_get_transport(builder);
+  GPR_ASSERT(t != NULL);
+  return grpc_channel_stack_builder_append_filter(
+      builder, &connected_channel_filter, bind_transport, t);
 }
 
 grpc_stream *grpc_connected_channel_get_stream(grpc_call_element *elem) {
diff --git a/src/core/channel/connected_channel.h b/src/core/channel/connected_channel.h
index 95c1834..7c0c835 100644
--- a/src/core/channel/connected_channel.h
+++ b/src/core/channel/connected_channel.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,21 +31,12 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_CHANNEL_CONNECTED_CHANNEL_H
-#define GRPC_INTERNAL_CORE_CHANNEL_CONNECTED_CHANNEL_H
+#ifndef GRPC_CORE_CHANNEL_CONNECTED_CHANNEL_H
+#define GRPC_CORE_CHANNEL_CONNECTED_CHANNEL_H
 
-#include "src/core/channel/channel_stack.h"
+#include "src/core/channel/channel_stack_builder.h"
 
-/* A channel filter representing a channel that is on a connected transport.
-   This filter performs actual sending and receiving of messages. */
+bool grpc_add_connected_filter(grpc_channel_stack_builder *builder,
+                               void *arg_must_be_null);
 
-extern const grpc_channel_filter grpc_connected_channel_filter;
-
-/* Post construction fixup: set the transport in the connected channel.
-   Must be called before any call stack using this filter is used. */
-void grpc_connected_channel_bind_transport(grpc_channel_stack* channel_stack,
-                                           grpc_transport* transport);
-
-grpc_stream* grpc_connected_channel_get_stream(grpc_call_element* elem);
-
-#endif /* GRPC_INTERNAL_CORE_CHANNEL_CONNECTED_CHANNEL_H */
+#endif /* GRPC_CORE_CHANNEL_CONNECTED_CHANNEL_H */
diff --git a/src/core/channel/context.h b/src/core/channel/context.h
index ac5796b..db217dc 100644
--- a/src/core/channel/context.h
+++ b/src/core/channel/context.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_CHANNEL_CONTEXT_H
-#define GRPC_INTERNAL_CORE_CHANNEL_CONTEXT_H
+#ifndef GRPC_CORE_CHANNEL_CONTEXT_H
+#define GRPC_CORE_CHANNEL_CONTEXT_H
 
 /* Call object context pointers */
 typedef enum {
@@ -46,4 +46,4 @@
   void (*destroy)(void *);
 } grpc_call_context_element;
 
-#endif /* GRPC_INTERNAL_CORE_CHANNEL_CONTEXT_H */
+#endif /* GRPC_CORE_CHANNEL_CONTEXT_H */
diff --git a/src/core/channel/http_client_filter.h b/src/core/channel/http_client_filter.h
index 21c66b9..6f619bb 100644
--- a/src/core/channel/http_client_filter.h
+++ b/src/core/channel/http_client_filter.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_CHANNEL_HTTP_CLIENT_FILTER_H
-#define GRPC_INTERNAL_CORE_CHANNEL_HTTP_CLIENT_FILTER_H
+#ifndef GRPC_CORE_CHANNEL_HTTP_CLIENT_FILTER_H
+#define GRPC_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_CORE_CHANNEL_HTTP_CLIENT_FILTER_H */
+#endif /* GRPC_CORE_CHANNEL_HTTP_CLIENT_FILTER_H */
diff --git a/src/core/channel/http_server_filter.h b/src/core/channel/http_server_filter.h
index f219d4e..528c864 100644
--- a/src/core/channel/http_server_filter.h
+++ b/src/core/channel/http_server_filter.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,12 +31,12 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_CHANNEL_HTTP_SERVER_FILTER_H
-#define GRPC_INTERNAL_CORE_CHANNEL_HTTP_SERVER_FILTER_H
+#ifndef GRPC_CORE_CHANNEL_HTTP_SERVER_FILTER_H
+#define GRPC_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_CORE_CHANNEL_HTTP_SERVER_FILTER_H */
+#endif /* GRPC_CORE_CHANNEL_HTTP_SERVER_FILTER_H */
diff --git a/src/core/channel/subchannel_call_holder.h b/src/core/channel/subchannel_call_holder.h
index 9cf72c6..9086cdc 100644
--- a/src/core/channel/subchannel_call_holder.h
+++ b/src/core/channel/subchannel_call_holder.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_CHANNEL_SUBCHANNEL_CALL_HOLDER_H
-#define GRPC_INTERNAL_CORE_CHANNEL_SUBCHANNEL_CALL_HOLDER_H
+#ifndef GRPC_CORE_CHANNEL_SUBCHANNEL_CALL_HOLDER_H
+#define GRPC_CORE_CHANNEL_SUBCHANNEL_CALL_HOLDER_H
 
 #include "src/core/client_config/subchannel.h"
 
@@ -95,4 +95,4 @@
 char *grpc_subchannel_call_holder_get_peer(grpc_exec_ctx *exec_ctx,
                                            grpc_subchannel_call_holder *holder);
 
-#endif
+#endif /* GRPC_CORE_CHANNEL_SUBCHANNEL_CALL_HOLDER_H */
diff --git a/src/core/client_config/client_config.h b/src/core/client_config/client_config.h
index 04bf036..9b37fdc 100644
--- a/src/core/client_config/client_config.h
+++ b/src/core/client_config/client_config.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_CLIENT_CONFIG_CLIENT_CONFIG_H
-#define GRPC_INTERNAL_CORE_CLIENT_CONFIG_CLIENT_CONFIG_H
+#ifndef GRPC_CORE_CLIENT_CONFIG_CLIENT_CONFIG_H
+#define GRPC_CORE_CLIENT_CONFIG_CLIENT_CONFIG_H
 
 #include "src/core/client_config/lb_policy.h"
 
@@ -50,4 +50,4 @@
 grpc_lb_policy *grpc_client_config_get_lb_policy(
     grpc_client_config *client_config);
 
-#endif /* GRPC_INTERNAL_CORE_CLIENT_CONFIG_CLIENT_CONFIG_H */
+#endif /* GRPC_CORE_CLIENT_CONFIG_CLIENT_CONFIG_H */
diff --git a/src/core/client_config/connector.h b/src/core/client_config/connector.h
index b91eb51..93248fc 100644
--- a/src/core/client_config/connector.h
+++ b/src/core/client_config/connector.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_CLIENT_CONFIG_CONNECTOR_H
-#define GRPC_INTERNAL_CORE_CLIENT_CONFIG_CONNECTOR_H
+#ifndef GRPC_CORE_CLIENT_CONFIG_CONNECTOR_H
+#define GRPC_CORE_CLIENT_CONFIG_CONNECTOR_H
 
 #include "src/core/channel/channel_stack.h"
 #include "src/core/iomgr/sockaddr.h"
@@ -62,9 +62,6 @@
 typedef struct {
   /** the connected transport */
   grpc_transport *transport;
-  /** any additional filters (owned by the caller of connect) */
-  const grpc_channel_filter **filters;
-  size_t num_filters;
 
   /** channel arguments (to be passed to the filters) */
   const grpc_channel_args *channel_args;
@@ -92,4 +89,4 @@
 void grpc_connector_shutdown(grpc_exec_ctx *exec_ctx,
                              grpc_connector *connector);
 
-#endif
+#endif /* GRPC_CORE_CLIENT_CONFIG_CONNECTOR_H */
diff --git a/src/core/client_config/initial_connect_string.h b/src/core/client_config/initial_connect_string.h
index b6dca71..e6d2d8f 100644
--- a/src/core/client_config/initial_connect_string.h
+++ b/src/core/client_config/initial_connect_string.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_CLIENT_CONFIG_INITIAL_CONNECT_STRING_H
-#define GRPC_INTERNAL_CORE_CLIENT_CONFIG_INITIAL_CONNECT_STRING_H
+#ifndef GRPC_CORE_CLIENT_CONFIG_INITIAL_CONNECT_STRING_H
+#define GRPC_CORE_CLIENT_CONFIG_INITIAL_CONNECT_STRING_H
 
 #include <grpc/support/slice.h>
 #include "src/core/iomgr/sockaddr.h"
@@ -47,4 +47,4 @@
 void grpc_set_initial_connect_string(struct sockaddr **addr, size_t *addr_len,
                                      gpr_slice *connect_string);
 
-#endif /* GRPC_INTERNAL_CORE_CLIENT_CONFIG_INITIAL_CONNECT_STRING_H */
+#endif /* GRPC_CORE_CLIENT_CONFIG_INITIAL_CONNECT_STRING_H */
diff --git a/src/core/client_config/lb_policies/load_balancer_api.h b/src/core/client_config/lb_policies/load_balancer_api.h
index 4dbe1d6..b7a4c9c 100644
--- a/src/core/client_config/lb_policies/load_balancer_api.h
+++ b/src/core/client_config/lb_policies/load_balancer_api.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_CLIENT_CONFIG_LB_POLICIES_LOAD_BALANCER_API_H
-#define GRPC_INTERNAL_CORE_CLIENT_CONFIG_LB_POLICIES_LOAD_BALANCER_API_H
+#ifndef GRPC_CORE_CLIENT_CONFIG_LB_POLICIES_LOAD_BALANCER_API_H
+#define GRPC_CORE_CLIENT_CONFIG_LB_POLICIES_LOAD_BALANCER_API_H
 
 #include <grpc/support/slice_buffer.h>
 
@@ -82,4 +82,4 @@
 }
 #endif
 
-#endif /* GRPC_INTERNAL_CORE_CLIENT_CONFIG_LB_POLICIES_LOAD_BALANCER_API_H */
+#endif /* GRPC_CORE_CLIENT_CONFIG_LB_POLICIES_LOAD_BALANCER_API_H */
diff --git a/src/core/client_config/lb_policies/pick_first.h b/src/core/client_config/lb_policies/pick_first.h
index 3ca53ad..3a3f195 100644
--- a/src/core/client_config/lb_policies/pick_first.h
+++ b/src/core/client_config/lb_policies/pick_first.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_CLIENT_CONFIG_PICK_FIRST_H
-#define GRPC_INTERNAL_CORE_CLIENT_CONFIG_PICK_FIRST_H
+#ifndef GRPC_CORE_CLIENT_CONFIG_LB_POLICIES_PICK_FIRST_H
+#define GRPC_CORE_CLIENT_CONFIG_LB_POLICIES_PICK_FIRST_H
 
 #include "src/core/client_config/lb_policy_factory.h"
 
@@ -40,4 +40,4 @@
  * the first subchannel from \a subchannels to succesfully connect */
 grpc_lb_policy_factory *grpc_pick_first_lb_factory_create();
 
-#endif
+#endif /* GRPC_CORE_CLIENT_CONFIG_LB_POLICIES_PICK_FIRST_H */
diff --git a/src/core/client_config/lb_policies/round_robin.h b/src/core/client_config/lb_policies/round_robin.h
index cf1f69c..7e6f176 100644
--- a/src/core/client_config/lb_policies/round_robin.h
+++ b/src/core/client_config/lb_policies/round_robin.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_CLIENT_CONFIG_ROUND_ROBIN_H
-#define GRPC_INTERNAL_CORE_CLIENT_CONFIG_ROUND_ROBIN_H
+#ifndef GRPC_CORE_CLIENT_CONFIG_LB_POLICIES_ROUND_ROBIN_H
+#define GRPC_CORE_CLIENT_CONFIG_LB_POLICIES_ROUND_ROBIN_H
 
 #include "src/core/client_config/lb_policy.h"
 
@@ -43,4 +43,4 @@
 /** Returns a load balancing factory for the round robin policy */
 grpc_lb_policy_factory *grpc_round_robin_lb_factory_create();
 
-#endif
+#endif /* GRPC_CORE_CLIENT_CONFIG_LB_POLICIES_ROUND_ROBIN_H */
diff --git a/src/core/client_config/lb_policy.h b/src/core/client_config/lb_policy.h
index 3457390..ffebc2a 100644
--- a/src/core/client_config/lb_policy.h
+++ b/src/core/client_config/lb_policy.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_CLIENT_CONFIG_LB_POLICY_H
-#define GRPC_INTERNAL_CORE_CLIENT_CONFIG_LB_POLICY_H
+#ifndef GRPC_CORE_CLIENT_CONFIG_LB_POLICY_H
+#define GRPC_CORE_CLIENT_CONFIG_LB_POLICY_H
 
 #include "src/core/client_config/subchannel.h"
 #include "src/core/transport/connectivity_state.h"
@@ -141,4 +141,4 @@
 grpc_connectivity_state grpc_lb_policy_check_connectivity(
     grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy);
 
-#endif /* GRPC_INTERNAL_CORE_CONFIG_LB_POLICY_H */
+#endif /* GRPC_CORE_CLIENT_CONFIG_LB_POLICY_H */
diff --git a/src/core/client_config/lb_policy_factory.h b/src/core/client_config/lb_policy_factory.h
index 0461031..842ba96 100644
--- a/src/core/client_config/lb_policy_factory.h
+++ b/src/core/client_config/lb_policy_factory.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_CLIENT_CONFIG_LB_POLICY_FACTORY_H
-#define GRPC_INTERNAL_CORE_CLIENT_CONFIG_LB_POLICY_FACTORY_H
+#ifndef GRPC_CORE_CLIENT_CONFIG_LB_POLICY_FACTORY_H
+#define GRPC_CORE_CLIENT_CONFIG_LB_POLICY_FACTORY_H
 
 #include "src/core/client_config/lb_policy.h"
 #include "src/core/client_config/subchannel.h"
@@ -70,4 +70,4 @@
 grpc_lb_policy *grpc_lb_policy_factory_create_lb_policy(
     grpc_lb_policy_factory *factory, grpc_lb_policy_args *args);
 
-#endif /* GRPC_INTERNAL_CORE_CONFIG_LB_POLICY_FACTORY_H */
+#endif /* GRPC_CORE_CLIENT_CONFIG_LB_POLICY_FACTORY_H */
diff --git a/src/core/client_config/lb_policy_registry.h b/src/core/client_config/lb_policy_registry.h
index 96fc2a1..f3a08a3 100644
--- a/src/core/client_config/lb_policy_registry.h
+++ b/src/core/client_config/lb_policy_registry.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_CLIENT_CONFIG_LB_POLICY_REGISTRY_H
-#define GRPC_INTERNAL_CORE_CLIENT_CONFIG_LB_POLICY_REGISTRY_H
+#ifndef GRPC_CORE_CLIENT_CONFIG_LB_POLICY_REGISTRY_H
+#define GRPC_CORE_CLIENT_CONFIG_LB_POLICY_REGISTRY_H
 
 #include "src/core/client_config/lb_policy_factory.h"
 
@@ -51,4 +51,4 @@
 grpc_lb_policy *grpc_lb_policy_create(const char *name,
                                       grpc_lb_policy_args *args);
 
-#endif /* GRPC_INTERNAL_CORE_CLIENT_CONFIG_LB_POLICY_REGISTRY_H */
+#endif /* GRPC_CORE_CLIENT_CONFIG_LB_POLICY_REGISTRY_H */
diff --git a/src/core/client_config/resolver.h b/src/core/client_config/resolver.h
index e612eaf..96f88fe 100644
--- a/src/core/client_config/resolver.h
+++ b/src/core/client_config/resolver.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_CLIENT_CONFIG_RESOLVER_H
-#define GRPC_INTERNAL_CORE_CLIENT_CONFIG_RESOLVER_H
+#ifndef GRPC_CORE_CLIENT_CONFIG_RESOLVER_H
+#define GRPC_CORE_CLIENT_CONFIG_RESOLVER_H
 
 #include "src/core/client_config/client_config.h"
 #include "src/core/client_config/subchannel.h"
@@ -91,4 +91,4 @@
                         grpc_client_config **target_config,
                         grpc_closure *on_complete);
 
-#endif /* GRPC_INTERNAL_CORE_CONFIG_RESOLVER_H */
+#endif /* GRPC_CORE_CLIENT_CONFIG_RESOLVER_H */
diff --git a/src/core/client_config/resolver_factory.h b/src/core/client_config/resolver_factory.h
index 4c4df35..477f8db 100644
--- a/src/core/client_config/resolver_factory.h
+++ b/src/core/client_config/resolver_factory.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_CLIENT_CONFIG_RESOLVER_FACTORY_H
-#define GRPC_INTERNAL_CORE_CLIENT_CONFIG_RESOLVER_FACTORY_H
+#ifndef GRPC_CORE_CLIENT_CONFIG_RESOLVER_FACTORY_H
+#define GRPC_CORE_CLIENT_CONFIG_RESOLVER_FACTORY_H
 
 #include "src/core/client_config/resolver.h"
 #include "src/core/client_config/subchannel_factory.h"
@@ -79,4 +79,4 @@
 char *grpc_resolver_factory_get_default_authority(
     grpc_resolver_factory *factory, grpc_uri *uri);
 
-#endif /* GRPC_INTERNAL_CORE_CONFIG_RESOLVER_FACTORY_H */
+#endif /* GRPC_CORE_CLIENT_CONFIG_RESOLVER_FACTORY_H */
diff --git a/src/core/client_config/resolver_registry.h b/src/core/client_config/resolver_registry.h
index 5a7193b..1e4cebe 100644
--- a/src/core/client_config/resolver_registry.h
+++ b/src/core/client_config/resolver_registry.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_CLIENT_CONFIG_RESOLVER_REGISTRY_H
-#define GRPC_INTERNAL_CORE_CLIENT_CONFIG_RESOLVER_REGISTRY_H
+#ifndef GRPC_CORE_CLIENT_CONFIG_RESOLVER_REGISTRY_H
+#define GRPC_CORE_CLIENT_CONFIG_RESOLVER_REGISTRY_H
 
 #include "src/core/client_config/resolver_factory.h"
 
@@ -62,4 +62,4 @@
     representing the default authority to pass from a client. */
 char *grpc_get_default_authority(const char *target);
 
-#endif /* GRPC_INTERNAL_CORE_CLIENT_CONFIG_RESOLVER_REGISTRY_H */
+#endif /* GRPC_CORE_CLIENT_CONFIG_RESOLVER_REGISTRY_H */
diff --git a/src/core/client_config/resolvers/dns_resolver.h b/src/core/client_config/resolvers/dns_resolver.h
index a3ef316..b24280b 100644
--- a/src/core/client_config/resolvers/dns_resolver.h
+++ b/src/core/client_config/resolvers/dns_resolver.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,12 +31,12 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_CLIENT_CONFIG_RESOLVERS_DNS_RESOLVER_H
-#define GRPC_INTERNAL_CORE_CLIENT_CONFIG_RESOLVERS_DNS_RESOLVER_H
+#ifndef GRPC_CORE_CLIENT_CONFIG_RESOLVERS_DNS_RESOLVER_H
+#define GRPC_CORE_CLIENT_CONFIG_RESOLVERS_DNS_RESOLVER_H
 
 #include "src/core/client_config/resolver_factory.h"
 
 /** Create a dns resolver factory */
 grpc_resolver_factory *grpc_dns_resolver_factory_create(void);
 
-#endif /* GRPC_INTERNAL_CORE_CLIENT_CONFIG_RESOLVERS_DNS_RESOLVER_H */
+#endif /* GRPC_CORE_CLIENT_CONFIG_RESOLVERS_DNS_RESOLVER_H */
diff --git a/src/core/client_config/resolvers/sockaddr_resolver.h b/src/core/client_config/resolvers/sockaddr_resolver.h
index 1b7a18f..f050329 100644
--- a/src/core/client_config/resolvers/sockaddr_resolver.h
+++ b/src/core/client_config/resolvers/sockaddr_resolver.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_CLIENT_CONFIG_RESOLVERS_UNIX_RESOLVER_H
-#define GRPC_INTERNAL_CORE_CLIENT_CONFIG_RESOLVERS_UNIX_RESOLVER_H
+#ifndef GRPC_CORE_CLIENT_CONFIG_RESOLVERS_SOCKADDR_RESOLVER_H
+#define GRPC_CORE_CLIENT_CONFIG_RESOLVERS_SOCKADDR_RESOLVER_H
 
 #include <grpc/support/port_platform.h>
 
@@ -47,4 +47,4 @@
 grpc_resolver_factory *grpc_unix_resolver_factory_create(void);
 #endif
 
-#endif /* GRPC_INTERNAL_CORE_CLIENT_CONFIG_RESOLVERS_UNIX_RESOLVER_H */
+#endif /* GRPC_CORE_CLIENT_CONFIG_RESOLVERS_SOCKADDR_RESOLVER_H */
diff --git a/src/core/client_config/resolvers/zookeeper_resolver.h b/src/core/client_config/resolvers/zookeeper_resolver.h
index a6f002d..04bd3ca 100644
--- a/src/core/client_config/resolvers/zookeeper_resolver.h
+++ b/src/core/client_config/resolvers/zookeeper_resolver.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,12 +31,12 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_CLIENT_CONFIG_RESOLVERS_ZOOKEEPER_RESOLVER_H
-#define GRPC_INTERNAL_CORE_CLIENT_CONFIG_RESOLVERS_ZOOKEEPER_RESOLVER_H
+#ifndef GRPC_CORE_CLIENT_CONFIG_RESOLVERS_ZOOKEEPER_RESOLVER_H
+#define GRPC_CORE_CLIENT_CONFIG_RESOLVERS_ZOOKEEPER_RESOLVER_H
 
 #include "src/core/client_config/resolver_factory.h"
 
 /** Create a zookeeper resolver factory */
 grpc_resolver_factory *grpc_zookeeper_resolver_factory_create(void);
 
-#endif /* GRPC_INTERNAL_CORE_CLIENT_CONFIG_RESOLVERS_ZOOKEEPER_RESOLVER_H */
+#endif /* GRPC_CORE_CLIENT_CONFIG_RESOLVERS_ZOOKEEPER_RESOLVER_H */
diff --git a/src/core/client_config/subchannel.c b/src/core/client_config/subchannel.c
index ec9e47a..8f150a8 100644
--- a/src/core/client_config/subchannel.c
+++ b/src/core/client_config/subchannel.c
@@ -45,7 +45,9 @@
 #include "src/core/client_config/subchannel_index.h"
 #include "src/core/iomgr/timer.h"
 #include "src/core/profiling/timers.h"
+#include "src/core/support/backoff.h"
 #include "src/core/surface/channel.h"
+#include "src/core/surface/channel_init.h"
 #include "src/core/transport/connectivity_state.h"
 
 #define INTERNAL_REF_BITS 16
@@ -127,8 +129,8 @@
 
   /** next connect attempt time */
   gpr_timespec next_attempt;
-  /** amount to backoff each failure */
-  gpr_timespec backoff_delta;
+  /** backoff state */
+  gpr_backoff backoff_state;
   /** do we have an active alarm? */
   int have_alarm;
   /** our alarm */
@@ -146,7 +148,6 @@
 #define CALLSTACK_TO_SUBCHANNEL_CALL(callstack) \
   (((grpc_subchannel_call *)(callstack)) - 1)
 
-static gpr_timespec compute_connect_deadline(grpc_subchannel *c);
 static void subchannel_connected(grpc_exec_ctx *exec_ctx, void *subchannel,
                                  bool iomgr_success);
 
@@ -337,6 +338,22 @@
   grpc_closure_init(&c->connected, subchannel_connected, c);
   grpc_connectivity_state_init(&c->state_tracker, GRPC_CHANNEL_IDLE,
                                "subchannel");
+  gpr_backoff_init(&c->backoff_state,
+                   GRPC_SUBCHANNEL_RECONNECT_BACKOFF_MULTIPLIER,
+                   GRPC_SUBCHANNEL_RECONNECT_JITTER,
+                   GRPC_SUBCHANNEL_INITIAL_CONNECT_BACKOFF_SECONDS * 1000,
+                   GRPC_SUBCHANNEL_RECONNECT_MAX_BACKOFF_SECONDS * 1000);
+  if (c->args) {
+    for (size_t i = 0; i < c->args->num_args; i++) {
+      if (0 == strcmp(c->args->args[i].key,
+                      "grpc.testing.fixed_reconnect_backoff")) {
+        GPR_ASSERT(c->args->args[i].type == GRPC_ARG_INTEGER);
+        gpr_backoff_init(&c->backoff_state, 1.0, 0.0,
+                         c->args->args[i].value.integer,
+                         c->args->args[i].value.integer);
+      }
+    }
+  }
   gpr_mu_init(&c->mu);
 
   return grpc_subchannel_index_register(exec_ctx, key, c);
@@ -348,7 +365,7 @@
   args.interested_parties = c->pollset_set;
   args.addr = c->addr;
   args.addr_len = c->addr_len;
-  args.deadline = compute_connect_deadline(c);
+  args.deadline = c->next_attempt;
   args.channel_args = c->args;
   args.initial_connect_string = c->initial_connect_string;
 
@@ -359,10 +376,8 @@
 }
 
 static void start_connect(grpc_exec_ctx *exec_ctx, grpc_subchannel *c) {
-  c->backoff_delta = gpr_time_from_seconds(
-      GRPC_SUBCHANNEL_INITIAL_CONNECT_BACKOFF_SECONDS, GPR_TIMESPAN);
   c->next_attempt =
-      gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), c->backoff_delta);
+      gpr_backoff_begin(&c->backoff_state, gpr_now(GPR_CLOCK_MONOTONIC));
   continue_connect(exec_ctx, c);
 }
 
@@ -507,32 +522,15 @@
 
 static void publish_transport_locked(grpc_exec_ctx *exec_ctx,
                                      grpc_subchannel *c) {
-  size_t channel_stack_size;
   grpc_connected_subchannel *con;
   grpc_channel_stack *stk;
-  size_t num_filters;
-  const grpc_channel_filter **filters;
   state_watcher *sw_subchannel;
 
-  /* build final filter list */
-  num_filters = c->num_filters + c->connecting_result.num_filters + 1;
-  filters = gpr_malloc(sizeof(*filters) * num_filters);
-  if (c->num_filters > 0) {
-    memcpy((void *)filters, c->filters, sizeof(*filters) * c->num_filters);
-  }
-  memcpy((void *)(filters + c->num_filters), c->connecting_result.filters,
-         sizeof(*filters) * c->connecting_result.num_filters);
-  filters[num_filters - 1] = &grpc_connected_channel_filter;
-
   /* construct channel stack */
-  channel_stack_size = grpc_channel_stack_size(filters, num_filters);
-  con = gpr_malloc(channel_stack_size);
+  con = grpc_channel_init_create_stack(
+      exec_ctx, GRPC_CLIENT_SUBCHANNEL, 0, c->connecting_result.channel_args, 1,
+      connection_destroy, NULL, c->connecting_result.transport);
   stk = CHANNEL_STACK_FROM_CONNECTION(con);
-  grpc_channel_stack_init(exec_ctx, 1, connection_destroy, con, filters,
-                          num_filters, c->connecting_result.channel_args,
-                          "CONNECTED_SUBCHANNEL", stk);
-  grpc_connected_channel_bind_transport(stk, c->connecting_result.transport);
-  gpr_free((void *)c->connecting_result.filters);
   memset(&c->connecting_result, 0, sizeof(c->connecting_result));
 
   /* initialize state watcher */
@@ -543,9 +541,7 @@
                     sw_subchannel);
 
   if (c->disconnected) {
-    gpr_mu_unlock(&c->mu);
     gpr_free(sw_subchannel);
-    gpr_free((void *)filters);
     grpc_channel_stack_destroy(exec_ctx, stk);
     gpr_free(con);
     GRPC_SUBCHANNEL_WEAK_UNREF(exec_ctx, c, "connecting");
@@ -573,52 +569,6 @@
   /* signal completion */
   grpc_connectivity_state_set(exec_ctx, &c->state_tracker, GRPC_CHANNEL_READY,
                               "connected");
-
-  gpr_free((void *)filters);
-}
-
-/* Generate a random number between 0 and 1. */
-static double generate_uniform_random_number(grpc_subchannel *c) {
-  c->random = (1103515245 * c->random + 12345) % ((uint32_t)1 << 31);
-  return c->random / (double)((uint32_t)1 << 31);
-}
-
-/* Update backoff_delta and next_attempt in subchannel */
-static void update_reconnect_parameters(grpc_subchannel *c) {
-  size_t i;
-  int32_t backoff_delta_millis, jitter;
-  int32_t max_backoff_millis =
-      GRPC_SUBCHANNEL_RECONNECT_MAX_BACKOFF_SECONDS * 1000;
-  double jitter_range;
-
-  if (c->args) {
-    for (i = 0; i < c->args->num_args; i++) {
-      if (0 == strcmp(c->args->args[i].key,
-                      "grpc.testing.fixed_reconnect_backoff")) {
-        GPR_ASSERT(c->args->args[i].type == GRPC_ARG_INTEGER);
-        c->next_attempt = gpr_time_add(
-            gpr_now(GPR_CLOCK_MONOTONIC),
-            gpr_time_from_millis(c->args->args[i].value.integer, GPR_TIMESPAN));
-        return;
-      }
-    }
-  }
-
-  backoff_delta_millis =
-      (int32_t)(gpr_time_to_millis(c->backoff_delta) *
-                GRPC_SUBCHANNEL_RECONNECT_BACKOFF_MULTIPLIER);
-  if (backoff_delta_millis > max_backoff_millis) {
-    backoff_delta_millis = max_backoff_millis;
-  }
-  c->backoff_delta = gpr_time_from_millis(backoff_delta_millis, GPR_TIMESPAN);
-  c->next_attempt =
-      gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), c->backoff_delta);
-
-  jitter_range = GRPC_SUBCHANNEL_RECONNECT_JITTER * backoff_delta_millis;
-  jitter =
-      (int32_t)((2 * generate_uniform_random_number(c) - 1) * jitter_range);
-  c->next_attempt =
-      gpr_time_add(c->next_attempt, gpr_time_from_millis(jitter, GPR_TIMESPAN));
 }
 
 static void on_alarm(grpc_exec_ctx *exec_ctx, void *arg, bool iomgr_success) {
@@ -629,7 +579,8 @@
     iomgr_success = 0;
   }
   if (iomgr_success) {
-    update_reconnect_parameters(c);
+    c->next_attempt =
+        gpr_backoff_step(&c->backoff_state, gpr_now(GPR_CLOCK_MONOTONIC));
     continue_connect(exec_ctx, c);
     gpr_mu_unlock(&c->mu);
   } else {
@@ -661,17 +612,6 @@
   GRPC_SUBCHANNEL_WEAK_UNREF(exec_ctx, c, "connecting");
 }
 
-static gpr_timespec compute_connect_deadline(grpc_subchannel *c) {
-  gpr_timespec current_deadline =
-      gpr_time_add(c->next_attempt, c->backoff_delta);
-  gpr_timespec min_deadline = gpr_time_add(
-      gpr_now(GPR_CLOCK_MONOTONIC),
-      gpr_time_from_seconds(GRPC_SUBCHANNEL_MIN_CONNECT_TIMEOUT_SECONDS,
-                            GPR_TIMESPAN));
-  return gpr_time_cmp(current_deadline, min_deadline) > 0 ? current_deadline
-                                                          : min_deadline;
-}
-
 /*
  * grpc_subchannel_call implementation
  */
diff --git a/src/core/client_config/subchannel.h b/src/core/client_config/subchannel.h
index 313e63c..ef9f2f1 100644
--- a/src/core/client_config/subchannel.h
+++ b/src/core/client_config/subchannel.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_CLIENT_CONFIG_SUBCHANNEL_H
-#define GRPC_INTERNAL_CORE_CLIENT_CONFIG_SUBCHANNEL_H
+#ifndef GRPC_CORE_CLIENT_CONFIG_SUBCHANNEL_H
+#define GRPC_CORE_CLIENT_CONFIG_SUBCHANNEL_H
 
 #include "src/core/channel/channel_stack.h"
 #include "src/core/client_config/connector.h"
@@ -171,4 +171,4 @@
                                         grpc_connector *connector,
                                         grpc_subchannel_args *args);
 
-#endif /* GRPC_INTERNAL_CORE_CLIENT_CONFIG_SUBCHANNEL_H */
+#endif /* GRPC_CORE_CLIENT_CONFIG_SUBCHANNEL_H */
diff --git a/src/core/client_config/subchannel_factory.h b/src/core/client_config/subchannel_factory.h
index c6d8cc9..c638f37 100644
--- a/src/core/client_config/subchannel_factory.h
+++ b/src/core/client_config/subchannel_factory.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_CLIENT_CONFIG_SUBCHANNEL_FACTORY_H
-#define GRPC_INTERNAL_CORE_CLIENT_CONFIG_SUBCHANNEL_FACTORY_H
+#ifndef GRPC_CORE_CLIENT_CONFIG_SUBCHANNEL_FACTORY_H
+#define GRPC_CORE_CLIENT_CONFIG_SUBCHANNEL_FACTORY_H
 
 #include "src/core/channel/channel_stack.h"
 #include "src/core/client_config/subchannel.h"
@@ -63,4 +63,4 @@
     grpc_exec_ctx *exec_ctx, grpc_subchannel_factory *factory,
     grpc_subchannel_args *args);
 
-#endif /* GRPC_INTERNAL_CORE_CLIENT_CONFIG_SUBCHANNEL_FACTORY_H */
+#endif /* GRPC_CORE_CLIENT_CONFIG_SUBCHANNEL_FACTORY_H */
diff --git a/src/core/client_config/subchannel_index.c b/src/core/client_config/subchannel_index.c
index 3f94899..24cc76c 100644
--- a/src/core/client_config/subchannel_index.c
+++ b/src/core/client_config/subchannel_index.c
@@ -108,6 +108,7 @@
   if (c != 0) return c;
   c = memcmp(a->args.filters, b->args.filters,
              a->args.filter_count * sizeof(*a->args.filters));
+  if (c != 0) return c;
   return grpc_channel_args_compare(a->args.args, b->args.args);
 }
 
diff --git a/src/core/client_config/subchannel_index.h b/src/core/client_config/subchannel_index.h
index 095ef17..3cd5d12 100644
--- a/src/core/client_config/subchannel_index.h
+++ b/src/core/client_config/subchannel_index.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_CLIENT_CONFIG_SUBCHANNEL_INDEX_H
-#define GRPC_INTERNAL_CORE_CLIENT_CONFIG_SUBCHANNEL_INDEX_H
+#ifndef GRPC_CORE_CLIENT_CONFIG_SUBCHANNEL_INDEX_H
+#define GRPC_CORE_CLIENT_CONFIG_SUBCHANNEL_INDEX_H
 
 #include "src/core/client_config/connector.h"
 #include "src/core/client_config/subchannel.h"
@@ -74,4 +74,4 @@
 /** Shutdown the subchannel index (global) */
 void grpc_subchannel_index_shutdown(void);
 
-#endif /* GRPC_INTERNAL_CORE_CLIENT_CONFIG_SUBCHANNEL_INDEX_H */
+#endif /* GRPC_CORE_CLIENT_CONFIG_SUBCHANNEL_INDEX_H */
diff --git a/src/core/client_config/uri_parser.h b/src/core/client_config/uri_parser.h
index b8daa13..af013d8 100644
--- a/src/core/client_config/uri_parser.h
+++ b/src/core/client_config/uri_parser.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_CLIENT_CONFIG_URI_PARSER_H
-#define GRPC_INTERNAL_CORE_CLIENT_CONFIG_URI_PARSER_H
+#ifndef GRPC_CORE_CLIENT_CONFIG_URI_PARSER_H
+#define GRPC_CORE_CLIENT_CONFIG_URI_PARSER_H
 
 typedef struct {
   char *scheme;
@@ -48,4 +48,4 @@
 /** destroy a uri */
 void grpc_uri_destroy(grpc_uri *uri);
 
-#endif
+#endif /* GRPC_CORE_CLIENT_CONFIG_URI_PARSER_H */
diff --git a/src/core/compression/algorithm_metadata.h b/src/core/compression/algorithm_metadata.h
index 882633c..34abf1d 100644
--- a/src/core/compression/algorithm_metadata.h
+++ b/src/core/compression/algorithm_metadata.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_COMPRESSION_ALGORITHM_METADATA_H
-#define GRPC_INTERNAL_CORE_COMPRESSION_ALGORITHM_METADATA_H
+#ifndef GRPC_CORE_COMPRESSION_ALGORITHM_METADATA_H
+#define GRPC_CORE_COMPRESSION_ALGORITHM_METADATA_H
 
 #include <grpc/compression.h>
 #include "src/core/transport/metadata.h"
@@ -50,4 +50,4 @@
 grpc_compression_algorithm grpc_compression_algorithm_from_mdstr(
     grpc_mdstr *str);
 
-#endif /* GRPC_INTERNAL_CORE_COMPRESSION_ALGORITHM_METADATA_H */
+#endif /* GRPC_CORE_COMPRESSION_ALGORITHM_METADATA_H */
diff --git a/src/core/compression/compression_algorithm.c b/src/core/compression/compression_algorithm.c
index 6f3a8eb..2810a38 100644
--- a/src/core/compression/compression_algorithm.c
+++ b/src/core/compression/compression_algorithm.c
@@ -128,20 +128,57 @@
 /* TODO(dgq): Add the ability to specify parameters to the individual
  * compression algorithms */
 grpc_compression_algorithm grpc_compression_algorithm_for_level(
-    grpc_compression_level level) {
+    grpc_compression_level level, uint32_t accepted_encodings) {
   GRPC_API_TRACE("grpc_compression_algorithm_for_level(level=%d)", 1,
                  ((int)level));
+  if (level > GRPC_COMPRESS_LEVEL_HIGH) {
+    gpr_log(GPR_ERROR, "Unknown compression level %d.", (int)level);
+    abort();
+  }
+
+  const size_t num_supported =
+      GPR_BITCOUNT(accepted_encodings) - 1; /* discard NONE */
+  if (level == GRPC_COMPRESS_LEVEL_NONE || num_supported == 0) {
+    return GRPC_COMPRESS_NONE;
+  }
+
+  GPR_ASSERT(level > 0);
+
+  /* Establish a "ranking" or compression algorithms in increasing order of
+   * compression.
+   * This is simplistic and we will probably want to introduce other dimensions
+   * in the future (cpu/memory cost, etc). */
+  const grpc_compression_algorithm algos_ranking[] = {GRPC_COMPRESS_GZIP,
+                                                      GRPC_COMPRESS_DEFLATE};
+
+  /* intersect algos_ranking with the supported ones keeping the ranked order */
+  grpc_compression_algorithm
+      sorted_supported_algos[GRPC_COMPRESS_ALGORITHMS_COUNT];
+  size_t algos_supported_idx = 0;
+  for (size_t i = 0; i < GPR_ARRAY_SIZE(algos_ranking); i++) {
+    const grpc_compression_algorithm alg = algos_ranking[i];
+    for (size_t j = 0; j < num_supported; j++) {
+      if (GPR_BITGET(accepted_encodings, alg) == 1) {
+        /* if \a alg in supported */
+        sorted_supported_algos[algos_supported_idx++] = alg;
+        break;
+      }
+    }
+    if (algos_supported_idx == num_supported) break;
+  }
+
   switch (level) {
     case GRPC_COMPRESS_LEVEL_NONE:
-      return GRPC_COMPRESS_NONE;
+      abort(); /* should have been handled already */
     case GRPC_COMPRESS_LEVEL_LOW:
+      return sorted_supported_algos[0];
     case GRPC_COMPRESS_LEVEL_MED:
+      return sorted_supported_algos[num_supported / 2];
     case GRPC_COMPRESS_LEVEL_HIGH:
-      return GRPC_COMPRESS_DEFLATE;
+      return sorted_supported_algos[num_supported - 1];
     default:
-      gpr_log(GPR_ERROR, "Unknown compression level %d.", (int)level);
       abort();
-  }
+  };
 }
 
 void grpc_compression_options_init(grpc_compression_options *opts) {
diff --git a/src/core/compression/message_compress.h b/src/core/compression/message_compress.h
index 1465200..20b78c0 100644
--- a/src/core/compression/message_compress.h
+++ b/src/core/compression/message_compress.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_COMPRESSION_MESSAGE_COMPRESS_H
-#define GRPC_INTERNAL_CORE_COMPRESSION_MESSAGE_COMPRESS_H
+#ifndef GRPC_CORE_COMPRESSION_MESSAGE_COMPRESS_H
+#define GRPC_CORE_COMPRESSION_MESSAGE_COMPRESS_H
 
 #include <grpc/compression.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_CORE_COMPRESSION_MESSAGE_COMPRESS_H */
+#endif /* GRPC_CORE_COMPRESSION_MESSAGE_COMPRESS_H */
diff --git a/src/core/debug/trace.h b/src/core/debug/trace.h
index dc58759..91ec140 100644
--- a/src/core/debug/trace.h
+++ b/src/core/debug/trace.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_DEBUG_TRACE_H
-#define GRPC_INTERNAL_CORE_DEBUG_TRACE_H
+#ifndef GRPC_CORE_DEBUG_TRACE_H
+#define GRPC_CORE_DEBUG_TRACE_H
 
 #include <grpc/support/port_platform.h>
 
@@ -40,4 +40,4 @@
 void grpc_tracer_init(const char *env_var_name);
 void grpc_tracer_shutdown(void);
 
-#endif /* GRPC_INTERNAL_CORE_DEBUG_TRACE_H */
+#endif /* GRPC_CORE_DEBUG_TRACE_H */
diff --git a/src/core/httpcli/format_request.h b/src/core/httpcli/format_request.h
index c8dc8f7..eb47cc9 100644
--- a/src/core/httpcli/format_request.h
+++ b/src/core/httpcli/format_request.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_HTTPCLI_FORMAT_REQUEST_H
-#define GRPC_INTERNAL_CORE_HTTPCLI_FORMAT_REQUEST_H
+#ifndef GRPC_CORE_HTTPCLI_FORMAT_REQUEST_H
+#define GRPC_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_CORE_HTTPCLI_FORMAT_REQUEST_H */
+#endif /* GRPC_CORE_HTTPCLI_FORMAT_REQUEST_H */
diff --git a/src/core/httpcli/httpcli.h b/src/core/httpcli/httpcli.h
index c9cd987..1fe5782 100644
--- a/src/core/httpcli/httpcli.h
+++ b/src/core/httpcli/httpcli.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_HTTPCLI_HTTPCLI_H
-#define GRPC_INTERNAL_CORE_HTTPCLI_HTTPCLI_H
+#ifndef GRPC_CORE_HTTPCLI_HTTPCLI_H
+#define GRPC_CORE_HTTPCLI_HTTPCLI_H
 
 #include <stddef.h>
 
@@ -160,4 +160,4 @@
 void grpc_httpcli_set_override(grpc_httpcli_get_override get,
                                grpc_httpcli_post_override post);
 
-#endif /* GRPC_INTERNAL_CORE_HTTPCLI_HTTPCLI_H */
+#endif /* GRPC_CORE_HTTPCLI_HTTPCLI_H */
diff --git a/src/core/httpcli/parser.h b/src/core/httpcli/parser.h
index cd03836..cd4a737 100644
--- a/src/core/httpcli/parser.h
+++ b/src/core/httpcli/parser.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_HTTPCLI_PARSER_H
-#define GRPC_INTERNAL_CORE_HTTPCLI_PARSER_H
+#ifndef GRPC_CORE_HTTPCLI_PARSER_H
+#define GRPC_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_CORE_HTTPCLI_PARSER_H */
+#endif /* GRPC_CORE_HTTPCLI_PARSER_H */
diff --git a/src/core/iomgr/closure.h b/src/core/iomgr/closure.h
index ea96c19..d5e1f45 100644
--- a/src/core/iomgr/closure.h
+++ b/src/core/iomgr/closure.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_IOMGR_CLOSURE_H
-#define GRPC_INTERNAL_CORE_IOMGR_CLOSURE_H
+#ifndef GRPC_CORE_IOMGR_CLOSURE_H
+#define GRPC_CORE_IOMGR_CLOSURE_H
 
 #include <grpc/support/port_platform.h>
 #include <stdbool.h>
@@ -95,4 +95,4 @@
 /** return the next pointer for a queued closure list */
 grpc_closure *grpc_closure_next(grpc_closure *closure);
 
-#endif /* GRPC_INTERNAL_CORE_IOMGR_CLOSURE_H */
+#endif /* GRPC_CORE_IOMGR_CLOSURE_H */
diff --git a/src/core/iomgr/endpoint.h b/src/core/iomgr/endpoint.h
index cbdc947..788f3ac 100644
--- a/src/core/iomgr/endpoint.h
+++ b/src/core/iomgr/endpoint.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_IOMGR_ENDPOINT_H
-#define GRPC_INTERNAL_CORE_IOMGR_ENDPOINT_H
+#ifndef GRPC_CORE_IOMGR_ENDPOINT_H
+#define GRPC_CORE_IOMGR_ENDPOINT_H
 
 #include "src/core/iomgr/pollset.h"
 #include "src/core/iomgr/pollset_set.h"
@@ -99,4 +99,4 @@
   const grpc_endpoint_vtable *vtable;
 };
 
-#endif /* GRPC_INTERNAL_CORE_IOMGR_ENDPOINT_H */
+#endif /* GRPC_CORE_IOMGR_ENDPOINT_H */
diff --git a/src/core/iomgr/endpoint_pair.h b/src/core/iomgr/endpoint_pair.h
index 095ec5f..59015d8 100644
--- a/src/core/iomgr/endpoint_pair.h
+++ b/src/core/iomgr/endpoint_pair.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_IOMGR_ENDPOINT_PAIR_H
-#define GRPC_INTERNAL_CORE_IOMGR_ENDPOINT_PAIR_H
+#ifndef GRPC_CORE_IOMGR_ENDPOINT_PAIR_H
+#define GRPC_CORE_IOMGR_ENDPOINT_PAIR_H
 
 #include "src/core/iomgr/endpoint.h"
 
@@ -44,4 +44,4 @@
 grpc_endpoint_pair grpc_iomgr_create_endpoint_pair(const char *name,
                                                    size_t read_slice_size);
 
-#endif /* GRPC_INTERNAL_CORE_IOMGR_ENDPOINT_PAIR_H */
+#endif /* GRPC_CORE_IOMGR_ENDPOINT_PAIR_H */
diff --git a/src/core/iomgr/exec_ctx.c b/src/core/iomgr/exec_ctx.c
index 1fd79f6..893fe45 100644
--- a/src/core/iomgr/exec_ctx.c
+++ b/src/core/iomgr/exec_ctx.c
@@ -34,9 +34,12 @@
 #include "src/core/iomgr/exec_ctx.h"
 
 #include <grpc/support/log.h>
+#include <grpc/support/sync.h>
+#include <grpc/support/thd.h>
 
 #include "src/core/profiling/timers.h"
 
+#ifndef GRPC_EXECUTION_CONTEXT_SANITIZER
 bool grpc_exec_ctx_flush(grpc_exec_ctx *exec_ctx) {
   bool did_something = 0;
   GPR_TIMER_BEGIN("grpc_exec_ctx_flush", 0);
@@ -74,3 +77,75 @@
   GPR_ASSERT(offload_target_or_null == NULL);
   grpc_closure_list_move(list, &exec_ctx->closure_list);
 }
+
+void grpc_exec_ctx_global_init(void) {}
+void grpc_exec_ctx_global_shutdown(void) {}
+#else
+static gpr_mu g_mu;
+static gpr_cv g_cv;
+static int g_threads = 0;
+
+static void run_closure(void *arg) {
+  grpc_closure *closure = arg;
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+  closure->cb(&exec_ctx, closure->cb_arg, (closure->final_data & 1) != 0);
+  grpc_exec_ctx_finish(&exec_ctx);
+  gpr_mu_lock(&g_mu);
+  if (--g_threads == 0) {
+    gpr_cv_signal(&g_cv);
+  }
+  gpr_mu_unlock(&g_mu);
+}
+
+static void start_closure(grpc_closure *closure) {
+  gpr_thd_id id;
+  gpr_mu_lock(&g_mu);
+  g_threads++;
+  gpr_mu_unlock(&g_mu);
+  gpr_thd_new(&id, run_closure, closure, NULL);
+}
+
+bool grpc_exec_ctx_flush(grpc_exec_ctx *exec_ctx) { return false; }
+
+void grpc_exec_ctx_finish(grpc_exec_ctx *exec_ctx) {}
+
+void grpc_exec_ctx_enqueue(grpc_exec_ctx *exec_ctx, grpc_closure *closure,
+                           bool success,
+                           grpc_workqueue *offload_target_or_null) {
+  GPR_ASSERT(offload_target_or_null == NULL);
+  if (closure == NULL) return;
+  closure->final_data = success;
+  start_closure(closure);
+}
+
+void grpc_exec_ctx_enqueue_list(grpc_exec_ctx *exec_ctx,
+                                grpc_closure_list *list,
+                                grpc_workqueue *offload_target_or_null) {
+  GPR_ASSERT(offload_target_or_null == NULL);
+  if (list == NULL) return;
+  grpc_closure *p = list->head;
+  while (p) {
+    grpc_closure *start = p;
+    p = grpc_closure_next(start);
+    start_closure(start);
+  }
+  grpc_closure_list r = GRPC_CLOSURE_LIST_INIT;
+  *list = r;
+}
+
+void grpc_exec_ctx_global_init(void) {
+  gpr_mu_init(&g_mu);
+  gpr_cv_init(&g_cv);
+}
+
+void grpc_exec_ctx_global_shutdown(void) {
+  gpr_mu_lock(&g_mu);
+  while (g_threads != 0) {
+    gpr_cv_wait(&g_cv, &g_mu, gpr_inf_future(GPR_CLOCK_REALTIME));
+  }
+  gpr_mu_unlock(&g_mu);
+
+  gpr_mu_destroy(&g_mu);
+  gpr_cv_destroy(&g_cv);
+}
+#endif
diff --git a/src/core/iomgr/exec_ctx.h b/src/core/iomgr/exec_ctx.h
index 9a9b2e5..07b54a0 100644
--- a/src/core/iomgr/exec_ctx.h
+++ b/src/core/iomgr/exec_ctx.h
@@ -31,11 +31,19 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_IOMGR_EXEC_CTX_H
-#define GRPC_INTERNAL_CORE_IOMGR_EXEC_CTX_H
+#ifndef GRPC_CORE_IOMGR_EXEC_CTX_H
+#define GRPC_CORE_IOMGR_EXEC_CTX_H
 
 #include "src/core/iomgr/closure.h"
 
+/* #define GRPC_EXECUTION_CONTEXT_SANITIZER 1 */
+
+/** A workqueue represents a list of work to be executed asynchronously.
+    Forward declared here to avoid a circular dependency with workqueue.h. */
+struct grpc_workqueue;
+typedef struct grpc_workqueue grpc_workqueue;
+
+#ifndef GRPC_EXECUTION_CONTEXT_SANITIZER
 /** Execution context.
  *  A bag of data that collects information along a callstack.
  *  Generally created at public API entry points, and passed down as
@@ -57,13 +65,15 @@
   grpc_closure_list closure_list;
 };
 
-/** A workqueue represents a list of work to be executed asynchronously.
-    Forward declared here to avoid a circular dependency with workqueue.h. */
-struct grpc_workqueue;
-typedef struct grpc_workqueue grpc_workqueue;
-
 #define GRPC_EXEC_CTX_INIT \
   { GRPC_CLOSURE_LIST_INIT }
+#else
+struct grpc_exec_ctx {
+  int unused;
+};
+#define GRPC_EXEC_CTX_INIT \
+  { 0 }
+#endif
 
 /** Flush any work that has been enqueued onto this grpc_exec_ctx.
  *  Caller must guarantee that no interfering locks are held.
@@ -82,4 +92,7 @@
                                 grpc_closure_list *list,
                                 grpc_workqueue *offload_target_or_null);
 
-#endif
+void grpc_exec_ctx_global_init(void);
+void grpc_exec_ctx_global_shutdown(void);
+
+#endif /* GRPC_CORE_IOMGR_EXEC_CTX_H */
diff --git a/src/core/iomgr/executor.h b/src/core/iomgr/executor.h
index aac057d..f66b356 100644
--- a/src/core/iomgr/executor.h
+++ b/src/core/iomgr/executor.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_IOMGR_EXECUTOR_H
-#define GRPC_INTERNAL_CORE_IOMGR_EXECUTOR_H
+#ifndef GRPC_CORE_IOMGR_EXECUTOR_H
+#define GRPC_CORE_IOMGR_EXECUTOR_H
 
 #include "src/core/iomgr/closure.h"
 
@@ -50,4 +50,4 @@
 /** Shutdown the executor, running all pending work as part of the call */
 void grpc_executor_shutdown();
 
-#endif /* GRPC_INTERNAL_CORE_IOMGR_EXECUTOR_H */
+#endif /* GRPC_CORE_IOMGR_EXECUTOR_H */
diff --git a/src/core/iomgr/fd_posix.h b/src/core/iomgr/fd_posix.h
index 17e7de8..a5c8ff1 100644
--- a/src/core/iomgr/fd_posix.h
+++ b/src/core/iomgr/fd_posix.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_IOMGR_FD_POSIX_H
-#define GRPC_INTERNAL_CORE_IOMGR_FD_POSIX_H
+#ifndef GRPC_CORE_IOMGR_FD_POSIX_H
+#define GRPC_CORE_IOMGR_FD_POSIX_H
 
 #include "src/core/iomgr/iomgr_internal.h"
 #include "src/core/iomgr/pollset.h"
@@ -189,4 +189,4 @@
 void grpc_fd_global_init(void);
 void grpc_fd_global_shutdown(void);
 
-#endif /* GRPC_INTERNAL_CORE_IOMGR_FD_POSIX_H */
+#endif /* GRPC_CORE_IOMGR_FD_POSIX_H */
diff --git a/src/core/iomgr/iocp_windows.h b/src/core/iomgr/iocp_windows.h
index 8b2b1ae..570b892 100644
--- a/src/core/iomgr/iocp_windows.h
+++ b/src/core/iomgr/iocp_windows.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_IOMGR_IOCP_WINDOWS_H
-#define GRPC_INTERNAL_CORE_IOMGR_IOCP_WINDOWS_H
+#ifndef GRPC_CORE_IOMGR_IOCP_WINDOWS_H
+#define GRPC_CORE_IOMGR_IOCP_WINDOWS_H
 
 #include <grpc/support/sync.h>
 
@@ -60,4 +60,4 @@
                                 grpc_winsocket *winsocket,
                                 grpc_closure *closure);
 
-#endif /* GRPC_INTERNAL_CORE_IOMGR_IOCP_WINDOWS_H */
+#endif /* GRPC_CORE_IOMGR_IOCP_WINDOWS_H */
diff --git a/src/core/iomgr/iomgr.c b/src/core/iomgr/iomgr.c
index 9c89c2c..3ab4430 100644
--- a/src/core/iomgr/iomgr.c
+++ b/src/core/iomgr/iomgr.c
@@ -43,6 +43,7 @@
 #include <grpc/support/thd.h>
 #include <grpc/support/useful.h>
 
+#include "src/core/iomgr/exec_ctx.h"
 #include "src/core/iomgr/iomgr_internal.h"
 #include "src/core/iomgr/timer.h"
 #include "src/core/support/env.h"
@@ -57,6 +58,7 @@
   g_shutdown = 0;
   gpr_mu_init(&g_mu);
   gpr_cv_init(&g_rcv);
+  grpc_exec_ctx_global_init();
   grpc_timer_list_init(gpr_now(GPR_CLOCK_MONOTONIC));
   g_root_object.next = g_root_object.prev = &g_root_object;
   g_root_object.name = "root";
@@ -138,6 +140,7 @@
 
   grpc_pollset_global_shutdown();
   grpc_iomgr_platform_shutdown();
+  grpc_exec_ctx_global_shutdown();
   gpr_mu_destroy(&g_mu);
   gpr_cv_destroy(&g_rcv);
 }
diff --git a/src/core/iomgr/iomgr.h b/src/core/iomgr/iomgr.h
index c9ea84c..e1237a4 100644
--- a/src/core/iomgr/iomgr.h
+++ b/src/core/iomgr/iomgr.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_IOMGR_IOMGR_H
-#define GRPC_INTERNAL_CORE_IOMGR_IOMGR_H
+#ifndef GRPC_CORE_IOMGR_IOMGR_H
+#define GRPC_CORE_IOMGR_IOMGR_H
 
 /** Initializes the iomgr. */
 void grpc_iomgr_init(void);
@@ -40,4 +40,4 @@
 /** Signals the intention to shutdown the iomgr. */
 void grpc_iomgr_shutdown(void);
 
-#endif /* GRPC_INTERNAL_CORE_IOMGR_IOMGR_H */
+#endif /* GRPC_CORE_IOMGR_IOMGR_H */
diff --git a/src/core/iomgr/iomgr_internal.h b/src/core/iomgr/iomgr_internal.h
index ac2c46e..d06b068 100644
--- a/src/core/iomgr/iomgr_internal.h
+++ b/src/core/iomgr/iomgr_internal.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_IOMGR_IOMGR_INTERNAL_H
-#define GRPC_INTERNAL_CORE_IOMGR_IOMGR_INTERNAL_H
+#ifndef GRPC_CORE_IOMGR_IOMGR_INTERNAL_H
+#define GRPC_CORE_IOMGR_IOMGR_INTERNAL_H
 
 #include <stdbool.h>
 
@@ -59,4 +59,4 @@
 
 bool grpc_iomgr_abort_on_leaks(void);
 
-#endif /* GRPC_INTERNAL_CORE_IOMGR_IOMGR_INTERNAL_H */
+#endif /* GRPC_CORE_IOMGR_IOMGR_INTERNAL_H */
diff --git a/src/core/iomgr/iomgr_posix.h b/src/core/iomgr/iomgr_posix.h
index 068a5c6..698fb6a 100644
--- a/src/core/iomgr/iomgr_posix.h
+++ b/src/core/iomgr/iomgr_posix.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,9 +31,9 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_IOMGR_IOMGR_POSIX_H
-#define GRPC_INTERNAL_CORE_IOMGR_IOMGR_POSIX_H
+#ifndef GRPC_CORE_IOMGR_IOMGR_POSIX_H
+#define GRPC_CORE_IOMGR_IOMGR_POSIX_H
 
 #include "src/core/iomgr/iomgr_internal.h"
 
-#endif /* GRPC_INTERNAL_CORE_IOMGR_IOMGR_POSIX_H */
+#endif /* GRPC_CORE_IOMGR_IOMGR_POSIX_H */
diff --git a/src/core/iomgr/pollset.h b/src/core/iomgr/pollset.h
index 92a0374..9500b1a 100644
--- a/src/core/iomgr/pollset.h
+++ b/src/core/iomgr/pollset.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_IOMGR_POLLSET_H
-#define GRPC_INTERNAL_CORE_IOMGR_POLLSET_H
+#ifndef GRPC_CORE_IOMGR_POLLSET_H
+#define GRPC_CORE_IOMGR_POLLSET_H
 
 #include <grpc/support/port_platform.h>
 #include <grpc/support/sync.h>
@@ -55,7 +55,7 @@
 size_t grpc_pollset_size(void);
 void grpc_pollset_init(grpc_pollset *pollset, gpr_mu **mu);
 /* Begin shutting down the pollset, and call closure when done.
- * GRPC_POLLSET_MU(pollset) must be held */
+ * pollset's mutex must be held */
 void grpc_pollset_shutdown(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
                            grpc_closure *closure);
 /** Reset the pollset to its initial state (perhaps with some cached objects);
@@ -66,16 +66,16 @@
 /* Do some work on a pollset.
    May involve invoking asynchronous callbacks, or actually polling file
    descriptors.
-   Requires GRPC_POLLSET_MU(pollset) locked.
-   May unlock GRPC_POLLSET_MU(pollset) during its execution.
+   Requires pollset's mutex locked.
+   May unlock its mutex during its execution.
 
    worker is a (platform-specific) handle that can be used to wake up
    from grpc_pollset_work before any events are received and before the timeout
    has expired. It is both initialized and destroyed by grpc_pollset_work.
    Initialization of worker is guaranteed to occur BEFORE the
-   GRPC_POLLSET_MU(pollset) is released for the first time by
-   grpc_pollset_work, and it is guaranteed that GRPC_POLLSET_MU(pollset) will
-   not be released by grpc_pollset_work AFTER worker has been destroyed.
+   pollset's mutex is released for the first time by grpc_pollset_work
+   and it is guaranteed that it will not be released by grpc_pollset_work
+   AFTER worker has been destroyed.
 
    Tries not to block past deadline.
    May call grpc_closure_list_run on grpc_closure_list, without holding the
@@ -91,4 +91,4 @@
 void grpc_pollset_kick(grpc_pollset *pollset,
                        grpc_pollset_worker *specific_worker);
 
-#endif /* GRPC_INTERNAL_CORE_IOMGR_POLLSET_H */
+#endif /* GRPC_CORE_IOMGR_POLLSET_H */
diff --git a/src/core/iomgr/pollset_posix.h b/src/core/iomgr/pollset_posix.h
index bbedb66..e0cfc44 100644
--- a/src/core/iomgr/pollset_posix.h
+++ b/src/core/iomgr/pollset_posix.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_IOMGR_POLLSET_POSIX_H
-#define GRPC_INTERNAL_CORE_IOMGR_POLLSET_POSIX_H
+#ifndef GRPC_CORE_IOMGR_POLLSET_POSIX_H
+#define GRPC_CORE_IOMGR_POLLSET_POSIX_H
 
 #include <poll.h>
 
@@ -150,4 +150,4 @@
 extern grpc_poll_function_type grpc_poll_function;
 extern grpc_wakeup_fd grpc_global_wakeup_fd;
 
-#endif /* GRPC_INTERNAL_CORE_IOMGR_POLLSET_POSIX_H */
+#endif /* GRPC_CORE_IOMGR_POLLSET_POSIX_H */
diff --git a/src/core/iomgr/pollset_set.h b/src/core/iomgr/pollset_set.h
index dddcd83..204c625 100644
--- a/src/core/iomgr/pollset_set.h
+++ b/src/core/iomgr/pollset_set.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_IOMGR_POLLSET_SET_H
-#define GRPC_INTERNAL_CORE_IOMGR_POLLSET_SET_H
+#ifndef GRPC_CORE_IOMGR_POLLSET_SET_H
+#define GRPC_CORE_IOMGR_POLLSET_SET_H
 
 #include "src/core/iomgr/pollset.h"
 
@@ -58,4 +58,4 @@
                                       grpc_pollset_set *bag,
                                       grpc_pollset_set *item);
 
-#endif /* GRPC_INTERNAL_CORE_IOMGR_POLLSET_H */
+#endif /* GRPC_CORE_IOMGR_POLLSET_SET_H */
diff --git a/src/core/iomgr/pollset_set_posix.h b/src/core/iomgr/pollset_set_posix.h
index 7d1aaf4..80f4877 100644
--- a/src/core/iomgr/pollset_set_posix.h
+++ b/src/core/iomgr/pollset_set_posix.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_IOMGR_POLLSET_SET_POSIX_H
-#define GRPC_INTERNAL_CORE_IOMGR_POLLSET_SET_POSIX_H
+#ifndef GRPC_CORE_IOMGR_POLLSET_SET_POSIX_H
+#define GRPC_CORE_IOMGR_POLLSET_SET_POSIX_H
 
 #include "src/core/iomgr/fd_posix.h"
 #include "src/core/iomgr/pollset_set.h"
@@ -42,4 +42,4 @@
 void grpc_pollset_set_del_fd(grpc_exec_ctx *exec_ctx,
                              grpc_pollset_set *pollset_set, grpc_fd *fd);
 
-#endif /* GRPC_INTERNAL_CORE_IOMGR_POLLSET_WINDOWS_H */
+#endif /* GRPC_CORE_IOMGR_POLLSET_SET_POSIX_H */
diff --git a/src/core/iomgr/pollset_set_windows.h b/src/core/iomgr/pollset_set_windows.h
index 9661cd2..0f040fe 100644
--- a/src/core/iomgr/pollset_set_windows.h
+++ b/src/core/iomgr/pollset_set_windows.h
@@ -31,9 +31,9 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_IOMGR_POLLSET_SET_WINDOWS_H
-#define GRPC_INTERNAL_CORE_IOMGR_POLLSET_SET_WINDOWS_H
+#ifndef GRPC_CORE_IOMGR_POLLSET_SET_WINDOWS_H
+#define GRPC_CORE_IOMGR_POLLSET_SET_WINDOWS_H
 
 #include "src/core/iomgr/pollset_set.h"
 
-#endif /* GRPC_INTERNAL_CORE_IOMGR_POLLSET_WINDOWS_H */
+#endif /* GRPC_CORE_IOMGR_POLLSET_SET_WINDOWS_H */
diff --git a/src/core/iomgr/pollset_windows.h b/src/core/iomgr/pollset_windows.h
index dc0b7a4..f1d1585 100644
--- a/src/core/iomgr/pollset_windows.h
+++ b/src/core/iomgr/pollset_windows.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_IOMGR_POLLSET_WINDOWS_H
-#define GRPC_INTERNAL_CORE_IOMGR_POLLSET_WINDOWS_H
+#ifndef GRPC_CORE_IOMGR_POLLSET_WINDOWS_H
+#define GRPC_CORE_IOMGR_POLLSET_WINDOWS_H
 
 #include <grpc/support/sync.h>
 
@@ -72,4 +72,4 @@
   grpc_closure *on_shutdown;
 };
 
-#endif /* GRPC_INTERNAL_CORE_IOMGR_POLLSET_WINDOWS_H */
+#endif /* GRPC_CORE_IOMGR_POLLSET_WINDOWS_H */
diff --git a/src/core/iomgr/resolve_address.h b/src/core/iomgr/resolve_address.h
index b059630..aa0d7d1 100644
--- a/src/core/iomgr/resolve_address.h
+++ b/src/core/iomgr/resolve_address.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_IOMGR_RESOLVE_ADDRESS_H
-#define GRPC_INTERNAL_CORE_IOMGR_RESOLVE_ADDRESS_H
+#ifndef GRPC_CORE_IOMGR_RESOLVE_ADDRESS_H
+#define GRPC_CORE_IOMGR_RESOLVE_ADDRESS_H
 
 #include <stddef.h>
 #include "src/core/iomgr/exec_ctx.h"
@@ -69,4 +69,4 @@
 extern grpc_resolved_addresses *(*grpc_blocking_resolve_address)(
     const char *name, const char *default_port);
 
-#endif /* GRPC_INTERNAL_CORE_IOMGR_RESOLVE_ADDRESS_H */
+#endif /* GRPC_CORE_IOMGR_RESOLVE_ADDRESS_H */
diff --git a/src/core/iomgr/sockaddr.h b/src/core/iomgr/sockaddr.h
index e41e1ec..68241bd 100644
--- a/src/core/iomgr/sockaddr.h
+++ b/src/core/iomgr/sockaddr.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_IOMGR_SOCKADDR_H
-#define GRPC_INTERNAL_CORE_IOMGR_SOCKADDR_H
+#ifndef GRPC_CORE_IOMGR_SOCKADDR_H
+#define GRPC_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_CORE_IOMGR_SOCKADDR_H */
+#endif /* GRPC_CORE_IOMGR_SOCKADDR_H */
diff --git a/src/core/iomgr/sockaddr_posix.h b/src/core/iomgr/sockaddr_posix.h
index 388abb3..e4425ed 100644
--- a/src/core/iomgr/sockaddr_posix.h
+++ b/src/core/iomgr/sockaddr_posix.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_IOMGR_SOCKADDR_POSIX_H
-#define GRPC_INTERNAL_CORE_IOMGR_SOCKADDR_POSIX_H
+#ifndef GRPC_CORE_IOMGR_SOCKADDR_POSIX_H
+#define GRPC_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_CORE_IOMGR_SOCKADDR_POSIX_H */
+#endif /* GRPC_CORE_IOMGR_SOCKADDR_POSIX_H */
diff --git a/src/core/iomgr/sockaddr_utils.h b/src/core/iomgr/sockaddr_utils.h
index 6f7a279..43dc7a4 100644
--- a/src/core/iomgr/sockaddr_utils.h
+++ b/src/core/iomgr/sockaddr_utils.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_IOMGR_SOCKADDR_UTILS_H
-#define GRPC_INTERNAL_CORE_IOMGR_SOCKADDR_UTILS_H
+#ifndef GRPC_CORE_IOMGR_SOCKADDR_UTILS_H
+#define GRPC_CORE_IOMGR_SOCKADDR_UTILS_H
 
 #include "src/core/iomgr/sockaddr.h"
 
@@ -86,4 +86,4 @@
 
 char *grpc_sockaddr_to_uri(const struct sockaddr *addr);
 
-#endif /* GRPC_INTERNAL_CORE_IOMGR_SOCKADDR_UTILS_H */
+#endif /* GRPC_CORE_IOMGR_SOCKADDR_UTILS_H */
diff --git a/src/core/iomgr/sockaddr_win32.h b/src/core/iomgr/sockaddr_win32.h
index 8e3946a..7acb8f7 100644
--- a/src/core/iomgr/sockaddr_win32.h
+++ b/src/core/iomgr/sockaddr_win32.h
@@ -31,11 +31,11 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_IOMGR_SOCKADDR_WIN32_H
-#define GRPC_INTERNAL_CORE_IOMGR_SOCKADDR_WIN32_H
+#ifndef GRPC_CORE_IOMGR_SOCKADDR_WIN32_H
+#define GRPC_CORE_IOMGR_SOCKADDR_WIN32_H
 
 #include <winsock2.h>
 #include <ws2tcpip.h>
 #include <mswsock.h>
 
-#endif /* GRPC_INTERNAL_CORE_IOMGR_SOCKADDR_WIN32_H */
+#endif /* GRPC_CORE_IOMGR_SOCKADDR_WIN32_H */
diff --git a/src/core/iomgr/socket_utils_posix.h b/src/core/iomgr/socket_utils_posix.h
index d330d19..b01e28b 100644
--- a/src/core/iomgr/socket_utils_posix.h
+++ b/src/core/iomgr/socket_utils_posix.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_IOMGR_SOCKET_UTILS_POSIX_H
-#define GRPC_INTERNAL_CORE_IOMGR_SOCKET_UTILS_POSIX_H
+#ifndef GRPC_CORE_IOMGR_SOCKET_UTILS_POSIX_H
+#define GRPC_CORE_IOMGR_SOCKET_UTILS_POSIX_H
 
 #include <unistd.h>
 #include <sys/socket.h>
@@ -110,4 +110,4 @@
 int grpc_create_dualstack_socket(const struct sockaddr *addr, int type,
                                  int protocol, grpc_dualstack_mode *dsmode);
 
-#endif /* GRPC_INTERNAL_CORE_IOMGR_SOCKET_UTILS_POSIX_H */
+#endif /* GRPC_CORE_IOMGR_SOCKET_UTILS_POSIX_H */
diff --git a/src/core/iomgr/socket_windows.h b/src/core/iomgr/socket_windows.h
index dfbfabe..8e50e7a 100644
--- a/src/core/iomgr/socket_windows.h
+++ b/src/core/iomgr/socket_windows.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_IOMGR_SOCKET_WINDOWS_H
-#define GRPC_INTERNAL_CORE_IOMGR_SOCKET_WINDOWS_H
+#ifndef GRPC_CORE_IOMGR_SOCKET_WINDOWS_H
+#define GRPC_CORE_IOMGR_SOCKET_WINDOWS_H
 
 #include <grpc/support/port_platform.h>
 #include <winsock2.h>
@@ -108,4 +108,4 @@
 /* Destroy a socket. Should only be called if there's no pending operation. */
 void grpc_winsocket_destroy(grpc_winsocket *socket);
 
-#endif /* GRPC_INTERNAL_CORE_IOMGR_SOCKET_WINDOWS_H */
+#endif /* GRPC_CORE_IOMGR_SOCKET_WINDOWS_H */
diff --git a/src/core/iomgr/tcp_client.h b/src/core/iomgr/tcp_client.h
index 5e18e71..2e29833 100644
--- a/src/core/iomgr/tcp_client.h
+++ b/src/core/iomgr/tcp_client.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_IOMGR_TCP_CLIENT_H
-#define GRPC_INTERNAL_CORE_IOMGR_TCP_CLIENT_H
+#ifndef GRPC_CORE_IOMGR_TCP_CLIENT_H
+#define GRPC_CORE_IOMGR_TCP_CLIENT_H
 
 #include "src/core/iomgr/endpoint.h"
 #include "src/core/iomgr/pollset_set.h"
@@ -50,4 +50,4 @@
                              const struct sockaddr *addr, size_t addr_len,
                              gpr_timespec deadline);
 
-#endif /* GRPC_INTERNAL_CORE_IOMGR_TCP_CLIENT_H */
+#endif /* GRPC_CORE_IOMGR_TCP_CLIENT_H */
diff --git a/src/core/iomgr/tcp_posix.h b/src/core/iomgr/tcp_posix.h
index 2a40cdd..d846ec5 100644
--- a/src/core/iomgr/tcp_posix.h
+++ b/src/core/iomgr/tcp_posix.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_IOMGR_TCP_POSIX_H
-#define GRPC_INTERNAL_CORE_IOMGR_TCP_POSIX_H
+#ifndef GRPC_CORE_IOMGR_TCP_POSIX_H
+#define GRPC_CORE_IOMGR_TCP_POSIX_H
 /*
    Low level TCP "bottom half" implementation, for use by transports built on
    top of a TCP connection.
@@ -68,4 +68,4 @@
 void grpc_tcp_destroy_and_release_fd(grpc_exec_ctx *exec_ctx, grpc_endpoint *ep,
                                      int *fd, grpc_closure *done);
 
-#endif /* GRPC_INTERNAL_CORE_IOMGR_TCP_POSIX_H */
+#endif /* GRPC_CORE_IOMGR_TCP_POSIX_H */
diff --git a/src/core/iomgr/tcp_server.h b/src/core/iomgr/tcp_server.h
index a39dd3b..93247e9 100644
--- a/src/core/iomgr/tcp_server.h
+++ b/src/core/iomgr/tcp_server.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_IOMGR_TCP_SERVER_H
-#define GRPC_INTERNAL_CORE_IOMGR_TCP_SERVER_H
+#ifndef GRPC_CORE_IOMGR_TCP_SERVER_H
+#define GRPC_CORE_IOMGR_TCP_SERVER_H
 
 #include "src/core/iomgr/closure.h"
 #include "src/core/iomgr/endpoint.h"
@@ -100,4 +100,4 @@
    a call (exec_ctx!=NULL) to shutdown_complete. */
 void grpc_tcp_server_unref(grpc_exec_ctx *exec_ctx, grpc_tcp_server *s);
 
-#endif /* GRPC_INTERNAL_CORE_IOMGR_TCP_SERVER_H */
+#endif /* GRPC_CORE_IOMGR_TCP_SERVER_H */
diff --git a/src/core/iomgr/tcp_windows.h b/src/core/iomgr/tcp_windows.h
index deb3e48..78bc133 100644
--- a/src/core/iomgr/tcp_windows.h
+++ b/src/core/iomgr/tcp_windows.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_IOMGR_TCP_WINDOWS_H
-#define GRPC_INTERNAL_CORE_IOMGR_TCP_WINDOWS_H
+#ifndef GRPC_CORE_IOMGR_TCP_WINDOWS_H
+#define GRPC_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_CORE_IOMGR_TCP_WINDOWS_H */
+#endif /* GRPC_CORE_IOMGR_TCP_WINDOWS_H */
diff --git a/src/core/iomgr/time_averaged_stats.h b/src/core/iomgr/time_averaged_stats.h
index 4e9e395..048e244 100644
--- a/src/core/iomgr/time_averaged_stats.h
+++ b/src/core/iomgr/time_averaged_stats.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_IOMGR_TIME_AVERAGED_STATS_H
-#define GRPC_INTERNAL_CORE_IOMGR_TIME_AVERAGED_STATS_H
+#ifndef GRPC_CORE_IOMGR_TIME_AVERAGED_STATS_H
+#define GRPC_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_CORE_IOMGR_TIME_AVERAGED_STATS_H */
+#endif /* GRPC_CORE_IOMGR_TIME_AVERAGED_STATS_H */
diff --git a/src/core/iomgr/timer.h b/src/core/iomgr/timer.h
index e239e88..63505df 100644
--- a/src/core/iomgr/timer.h
+++ b/src/core/iomgr/timer.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_IOMGR_TIMER_H
-#define GRPC_INTERNAL_CORE_IOMGR_TIMER_H
+#ifndef GRPC_CORE_IOMGR_TIMER_H
+#define GRPC_CORE_IOMGR_TIMER_H
 
 #include "src/core/iomgr/iomgr.h"
 #include "src/core/iomgr/exec_ctx.h"
@@ -105,4 +105,4 @@
 
 void grpc_kick_poller(void);
 
-#endif /* GRPC_INTERNAL_CORE_IOMGR_TIMER_H */
+#endif /* GRPC_CORE_IOMGR_TIMER_H */
diff --git a/src/core/iomgr/timer_heap.h b/src/core/iomgr/timer_heap.h
index 2d220f1..c2912ef 100644
--- a/src/core/iomgr/timer_heap.h
+++ b/src/core/iomgr/timer_heap.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_IOMGR_TIMER_HEAP_H
-#define GRPC_INTERNAL_CORE_IOMGR_TIMER_HEAP_H
+#ifndef GRPC_CORE_IOMGR_TIMER_HEAP_H
+#define GRPC_CORE_IOMGR_TIMER_HEAP_H
 
 #include "src/core/iomgr/timer.h"
 
@@ -54,4 +54,4 @@
 
 int grpc_timer_heap_is_empty(grpc_timer_heap *heap);
 
-#endif /* GRPC_INTERNAL_CORE_IOMGR_TIMER_HEAP_H */
+#endif /* GRPC_CORE_IOMGR_TIMER_HEAP_H */
diff --git a/src/core/iomgr/udp_server.h b/src/core/iomgr/udp_server.h
index a9d0489..1e59a92 100644
--- a/src/core/iomgr/udp_server.h
+++ b/src/core/iomgr/udp_server.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_IOMGR_UDP_SERVER_H
-#define GRPC_INTERNAL_CORE_IOMGR_UDP_SERVER_H
+#ifndef GRPC_CORE_IOMGR_UDP_SERVER_H
+#define GRPC_CORE_IOMGR_UDP_SERVER_H
 
 #include "src/core/iomgr/endpoint.h"
 #include "src/core/iomgr/fd_posix.h"
@@ -73,4 +73,4 @@
 void grpc_udp_server_destroy(grpc_exec_ctx *exec_ctx, grpc_udp_server *server,
                              grpc_closure *on_done);
 
-#endif /* GRPC_INTERNAL_CORE_IOMGR_UDP_SERVER_H */
+#endif /* GRPC_CORE_IOMGR_UDP_SERVER_H */
diff --git a/src/core/iomgr/wakeup_fd_pipe.h b/src/core/iomgr/wakeup_fd_pipe.h
index 01a13a9..eb3e02b 100644
--- a/src/core/iomgr/wakeup_fd_pipe.h
+++ b/src/core/iomgr/wakeup_fd_pipe.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,11 +31,11 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_IOMGR_WAKEUP_FD_PIPE_H
-#define GRPC_INTERNAL_CORE_IOMGR_WAKEUP_FD_PIPE_H
+#ifndef GRPC_CORE_IOMGR_WAKEUP_FD_PIPE_H
+#define GRPC_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_CORE_IOMGR_WAKEUP_FD_PIPE_H */
+#endif /* GRPC_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 ffd60d1..d7e3cf4 100644
--- a/src/core/iomgr/wakeup_fd_posix.h
+++ b/src/core/iomgr/wakeup_fd_posix.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -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_CORE_IOMGR_WAKEUP_FD_POSIX_H
-#define GRPC_INTERNAL_CORE_IOMGR_WAKEUP_FD_POSIX_H
+#ifndef GRPC_CORE_IOMGR_WAKEUP_FD_POSIX_H
+#define GRPC_CORE_IOMGR_WAKEUP_FD_POSIX_H
 
 void grpc_wakeup_fd_global_init(void);
 void grpc_wakeup_fd_global_destroy(void);
@@ -98,4 +98,4 @@
  * wakeup_fd_nospecial.c if no such implementation exists. */
 extern const grpc_wakeup_fd_vtable grpc_specialized_wakeup_fd_vtable;
 
-#endif /* GRPC_INTERNAL_CORE_IOMGR_WAKEUP_FD_POSIX_H */
+#endif /* GRPC_CORE_IOMGR_WAKEUP_FD_POSIX_H */
diff --git a/src/core/iomgr/workqueue.h b/src/core/iomgr/workqueue.h
index 36dd133..2ba1e5d 100644
--- a/src/core/iomgr/workqueue.h
+++ b/src/core/iomgr/workqueue.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_IOMGR_WORKQUEUE_H
-#define GRPC_INTERNAL_CORE_IOMGR_WORKQUEUE_H
+#ifndef GRPC_CORE_IOMGR_WORKQUEUE_H
+#define GRPC_CORE_IOMGR_WORKQUEUE_H
 
 #include "src/core/iomgr/iomgr.h"
 #include "src/core/iomgr/pollset.h"
@@ -80,4 +80,4 @@
 void grpc_workqueue_push(grpc_workqueue *workqueue, grpc_closure *closure,
                          int success);
 
-#endif
+#endif /* GRPC_CORE_IOMGR_WORKQUEUE_H */
diff --git a/src/core/iomgr/workqueue_posix.c b/src/core/iomgr/workqueue_posix.c
index c096dbf..2b42e6d 100644
--- a/src/core/iomgr/workqueue_posix.c
+++ b/src/core/iomgr/workqueue_posix.c
@@ -107,7 +107,7 @@
   if (grpc_closure_list_empty(workqueue->closure_list)) {
     grpc_wakeup_fd_wakeup(&workqueue->wakeup_fd);
   }
-  grpc_closure_list_move(&exec_ctx->closure_list, &workqueue->closure_list);
+  grpc_exec_ctx_enqueue_list(exec_ctx, &workqueue->closure_list, NULL);
   gpr_mu_unlock(&workqueue->mu);
 }
 
@@ -123,7 +123,7 @@
     gpr_free(workqueue);
   } else {
     gpr_mu_lock(&workqueue->mu);
-    grpc_closure_list_move(&workqueue->closure_list, &exec_ctx->closure_list);
+    grpc_exec_ctx_enqueue_list(exec_ctx, &workqueue->closure_list, NULL);
     grpc_wakeup_fd_consume_wakeup(&workqueue->wakeup_fd);
     gpr_mu_unlock(&workqueue->mu);
     grpc_fd_notify_on_read(exec_ctx, workqueue->wakeup_read_fd,
diff --git a/src/core/iomgr/workqueue_posix.h b/src/core/iomgr/workqueue_posix.h
index 68f195e..89937b1 100644
--- a/src/core/iomgr/workqueue_posix.h
+++ b/src/core/iomgr/workqueue_posix.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_IOMGR_WORKQUEUE_POSIX_H
-#define GRPC_INTERNAL_CORE_IOMGR_WORKQUEUE_POSIX_H
+#ifndef GRPC_CORE_IOMGR_WORKQUEUE_POSIX_H
+#define GRPC_CORE_IOMGR_WORKQUEUE_POSIX_H
 
 #include "src/core/iomgr/wakeup_fd_posix.h"
 
@@ -50,4 +50,4 @@
   grpc_closure read_closure;
 };
 
-#endif /* GRPC_INTERNAL_CORE_IOMGR_WORKQUEUE_POSIX_H */
+#endif /* GRPC_CORE_IOMGR_WORKQUEUE_POSIX_H */
diff --git a/src/core/iomgr/workqueue_windows.h b/src/core/iomgr/workqueue_windows.h
index 941f195..7e81869 100644
--- a/src/core/iomgr/workqueue_windows.h
+++ b/src/core/iomgr/workqueue_windows.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,7 +31,7 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_IOMGR_WORKQUEUE_WINDOWS_H
-#define GRPC_INTERNAL_CORE_IOMGR_WORKQUEUE_WINDOWS_H
+#ifndef GRPC_CORE_IOMGR_WORKQUEUE_WINDOWS_H
+#define GRPC_CORE_IOMGR_WORKQUEUE_WINDOWS_H
 
-#endif /* GRPC_INTERNAL_CORE_IOMGR_WORKQUEUE_WINDOWS_H */
+#endif /* GRPC_CORE_IOMGR_WORKQUEUE_WINDOWS_H */
diff --git a/src/core/json/json.h b/src/core/json/json.h
index c4df299..aea9d5d 100644
--- a/src/core/json/json.h
+++ b/src/core/json/json.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_JSON_JSON_H
-#define GRPC_INTERNAL_CORE_JSON_JSON_H
+#ifndef GRPC_CORE_JSON_JSON_H
+#define GRPC_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_INTERNAL_CORE_JSON_JSON_H */
+#endif /* GRPC_CORE_JSON_JSON_H */
diff --git a/src/core/json/json_common.h b/src/core/json/json_common.h
index 481695b..7205a94 100644
--- a/src/core/json/json_common.h
+++ b/src/core/json/json_common.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_JSON_JSON_COMMON_H
-#define GRPC_INTERNAL_CORE_JSON_JSON_COMMON_H
+#ifndef GRPC_CORE_JSON_JSON_COMMON_H
+#define GRPC_CORE_JSON_JSON_COMMON_H
 
 /* The various json types. */
 typedef enum {
@@ -46,4 +46,4 @@
   GRPC_JSON_TOP_LEVEL
 } grpc_json_type;
 
-#endif /* GRPC_INTERNAL_CORE_JSON_JSON_COMMON_H */
+#endif /* GRPC_CORE_JSON_JSON_COMMON_H */
diff --git a/src/core/json/json_reader.h b/src/core/json/json_reader.h
index 90b9f1f..f25f44b 100644
--- a/src/core/json/json_reader.h
+++ b/src/core/json/json_reader.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_JSON_JSON_READER_H
-#define GRPC_INTERNAL_CORE_JSON_JSON_READER_H
+#ifndef GRPC_CORE_JSON_JSON_READER_H
+#define GRPC_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_INTERNAL_CORE_JSON_JSON_READER_H */
+#endif /* GRPC_CORE_JSON_JSON_READER_H */
diff --git a/src/core/json/json_writer.h b/src/core/json/json_writer.h
index 9ef04aa..c392126 100644
--- a/src/core/json/json_writer.h
+++ b/src/core/json/json_writer.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -43,8 +43,8 @@
  * a valid UTF-8 string overall.
  */
 
-#ifndef GRPC_INTERNAL_CORE_JSON_JSON_WRITER_H
-#define GRPC_INTERNAL_CORE_JSON_JSON_WRITER_H
+#ifndef GRPC_CORE_JSON_JSON_WRITER_H
+#define GRPC_CORE_JSON_JSON_WRITER_H
 
 #include <stdlib.h>
 
@@ -94,4 +94,4 @@
 void grpc_json_writer_value_string(grpc_json_writer *writer,
                                    const char *string);
 
-#endif /* GRPC_INTERNAL_CORE_JSON_JSON_WRITER_H */
+#endif /* GRPC_CORE_JSON_JSON_WRITER_H */
diff --git a/src/core/security/auth_filters.h b/src/core/security/auth_filters.h
index c179b54..1154a1d 100644
--- a/src/core/security/auth_filters.h
+++ b/src/core/security/auth_filters.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,12 +31,12 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_SECURITY_AUTH_FILTERS_H
-#define GRPC_INTERNAL_CORE_SECURITY_AUTH_FILTERS_H
+#ifndef GRPC_CORE_SECURITY_AUTH_FILTERS_H
+#define GRPC_CORE_SECURITY_AUTH_FILTERS_H
 
 #include "src/core/channel/channel_stack.h"
 
 extern const grpc_channel_filter grpc_client_auth_filter;
 extern const grpc_channel_filter grpc_server_auth_filter;
 
-#endif /* GRPC_INTERNAL_CORE_SECURITY_AUTH_FILTERS_H */
+#endif /* GRPC_CORE_SECURITY_AUTH_FILTERS_H */
diff --git a/src/core/security/b64.h b/src/core/security/b64.h
index 3e3b521..d18f695 100644
--- a/src/core/security/b64.h
+++ b/src/core/security/b64.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_SECURITY_BASE64_H
-#define GRPC_INTERNAL_CORE_SECURITY_BASE64_H
+#ifndef GRPC_CORE_SECURITY_B64_H
+#define GRPC_CORE_SECURITY_B64_H
 
 #include <grpc/support/slice.h>
 
@@ -49,4 +49,4 @@
 gpr_slice grpc_base64_decode_with_len(const char *b64, size_t b64_len,
                                       int url_safe);
 
-#endif /* GRPC_INTERNAL_CORE_SECURITY_BASE64_H */
+#endif /* GRPC_CORE_SECURITY_B64_H */
diff --git a/src/core/security/credentials.h b/src/core/security/credentials.h
index 0de4cd9..133aa9d 100644
--- a/src/core/security/credentials.h
+++ b/src/core/security/credentials.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_SECURITY_CREDENTIALS_H
-#define GRPC_INTERNAL_CORE_SECURITY_CREDENTIALS_H
+#ifndef GRPC_CORE_SECURITY_CREDENTIALS_H
+#define GRPC_CORE_SECURITY_CREDENTIALS_H
 
 #include "src/core/transport/metadata_batch.h"
 #include <grpc/grpc.h>
@@ -373,4 +373,4 @@
   grpc_credentials_md_store *plugin_md;
 } grpc_plugin_credentials;
 
-#endif /* GRPC_INTERNAL_CORE_SECURITY_CREDENTIALS_H */
+#endif /* GRPC_CORE_SECURITY_CREDENTIALS_H */
diff --git a/src/core/security/handshake.h b/src/core/security/handshake.h
index db8b374..4872045 100644
--- a/src/core/security/handshake.h
+++ b/src/core/security/handshake.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_SECURITY_HANDSHAKE_H
-#define GRPC_INTERNAL_CORE_SECURITY_HANDSHAKE_H
+#ifndef GRPC_CORE_SECURITY_HANDSHAKE_H
+#define GRPC_CORE_SECURITY_HANDSHAKE_H
 
 #include "src/core/iomgr/endpoint.h"
 #include "src/core/security/security_connector.h"
@@ -48,4 +48,4 @@
 
 void grpc_security_handshake_shutdown(grpc_exec_ctx *exec_ctx, void *handshake);
 
-#endif /* GRPC_INTERNAL_CORE_SECURITY_HANDSHAKE_H */
+#endif /* GRPC_CORE_SECURITY_HANDSHAKE_H */
diff --git a/src/core/security/json_token.h b/src/core/security/json_token.h
index 7e06864..d183f9b 100644
--- a/src/core/security/json_token.h
+++ b/src/core/security/json_token.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_SECURITY_JSON_TOKEN_H
-#define GRPC_INTERNAL_CORE_SECURITY_JSON_TOKEN_H
+#ifndef GRPC_CORE_SECURITY_JSON_TOKEN_H
+#define GRPC_CORE_SECURITY_JSON_TOKEN_H
 
 #include <grpc/support/slice.h>
 #include <openssl/rsa.h>
@@ -115,4 +115,4 @@
 /* Destructs the object. */
 void grpc_auth_refresh_token_destruct(grpc_auth_refresh_token *refresh_token);
 
-#endif /* GRPC_INTERNAL_CORE_SECURITY_JSON_TOKEN_H */
+#endif /* GRPC_CORE_SECURITY_JSON_TOKEN_H */
diff --git a/src/core/security/jwt_verifier.h b/src/core/security/jwt_verifier.h
index 25613f0..d898d21 100644
--- a/src/core/security/jwt_verifier.h
+++ b/src/core/security/jwt_verifier.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_SECURITY_JWT_VERIFIER_H
-#define GRPC_INTERNAL_CORE_SECURITY_JWT_VERIFIER_H
+#ifndef GRPC_CORE_SECURITY_JWT_VERIFIER_H
+#define GRPC_CORE_SECURITY_JWT_VERIFIER_H
 
 #include "src/core/iomgr/pollset.h"
 #include "src/core/json/json.h"
@@ -133,4 +133,4 @@
 grpc_jwt_verifier_status grpc_jwt_claims_check(const grpc_jwt_claims *claims,
                                                const char *audience);
 
-#endif /* GRPC_INTERNAL_CORE_SECURITY_JWT_VERIFIER_H */
+#endif /* GRPC_CORE_SECURITY_JWT_VERIFIER_H */
diff --git a/src/core/security/secure_endpoint.h b/src/core/security/secure_endpoint.h
index c563bdd..5176ef2 100644
--- a/src/core/security/secure_endpoint.h
+++ b/src/core/security/secure_endpoint.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_SECURITY_SECURE_ENDPOINT_H
-#define GRPC_INTERNAL_CORE_SECURITY_SECURE_ENDPOINT_H
+#ifndef GRPC_CORE_SECURITY_SECURE_ENDPOINT_H
+#define GRPC_CORE_SECURITY_SECURE_ENDPOINT_H
 
 #include "src/core/iomgr/endpoint.h"
 #include <grpc/support/slice.h>
@@ -46,4 +46,4 @@
     struct tsi_frame_protector *protector, grpc_endpoint *to_wrap,
     gpr_slice *leftover_slices, size_t leftover_nslices);
 
-#endif /* GRPC_INTERNAL_CORE_SECURITY_SECURE_ENDPOINT_H */
+#endif /* GRPC_CORE_SECURITY_SECURE_ENDPOINT_H */
diff --git a/src/core/security/security_connector.c b/src/core/security/security_connector.c
index 33c62a2..fbec263 100644
--- a/src/core/security/security_connector.c
+++ b/src/core/security/security_connector.c
@@ -492,6 +492,9 @@
       peer_identity_property_name = GRPC_X509_SAN_PROPERTY_NAME;
       grpc_auth_context_add_property(ctx, GRPC_X509_SAN_PROPERTY_NAME,
                                      prop->value.data, prop->value.length);
+    } else if (strcmp(prop->name, TSI_X509_PEM_CERT_PROPERTY) == 0) {
+      grpc_auth_context_add_property(ctx, GRPC_X509_PEM_CERT_PROPERTY_NAME,
+                                     prop->value.data, prop->value.length);
     }
   }
   if (peer_identity_property_name != NULL) {
@@ -554,9 +557,9 @@
   grpc_auth_context_unref(auth_context);
 }
 
-static void add_shalow_auth_property_to_peer(tsi_peer *peer,
-                                             const grpc_auth_property *prop,
-                                             const char *tsi_prop_name) {
+static void add_shallow_auth_property_to_peer(tsi_peer *peer,
+                                              const grpc_auth_property *prop,
+                                              const char *tsi_prop_name) {
   tsi_peer_property *tsi_prop = &peer->properties[peer->property_count++];
   tsi_prop->name = (char *)tsi_prop_name;
   tsi_prop->value.data = prop->value;
@@ -579,11 +582,14 @@
     it = grpc_auth_context_property_iterator(auth_context);
     while ((prop = grpc_auth_property_iterator_next(&it)) != NULL) {
       if (strcmp(prop->name, GRPC_X509_SAN_PROPERTY_NAME) == 0) {
-        add_shalow_auth_property_to_peer(
+        add_shallow_auth_property_to_peer(
             &peer, prop, TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY);
       } else if (strcmp(prop->name, GRPC_X509_CN_PROPERTY_NAME) == 0) {
-        add_shalow_auth_property_to_peer(
+        add_shallow_auth_property_to_peer(
             &peer, prop, TSI_X509_SUBJECT_COMMON_NAME_PEER_PROPERTY);
+      } else if (strcmp(prop->name, GRPC_X509_PEM_CERT_PROPERTY_NAME) == 0) {
+        add_shallow_auth_property_to_peer(&peer, prop,
+                                          TSI_X509_PEM_CERT_PROPERTY);
       }
     }
   }
diff --git a/src/core/security/security_connector.h b/src/core/security/security_connector.h
index 1e35d3f..6f915eb 100644
--- a/src/core/security/security_connector.h
+++ b/src/core/security/security_connector.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_SECURITY_SECURITY_CONNECTOR_H
-#define GRPC_INTERNAL_CORE_SECURITY_SECURITY_CONNECTOR_H
+#ifndef GRPC_CORE_SECURITY_SECURITY_CONNECTOR_H
+#define GRPC_CORE_SECURITY_SECURITY_CONNECTOR_H
 
 #include <grpc/grpc_security.h>
 #include "src/core/iomgr/endpoint.h"
@@ -263,4 +263,4 @@
     const grpc_auth_context *auth_context);
 void tsi_shallow_peer_destruct(tsi_peer *peer);
 
-#endif /* GRPC_INTERNAL_CORE_SECURITY_SECURITY_CONNECTOR_H */
+#endif /* GRPC_CORE_SECURITY_SECURITY_CONNECTOR_H */
diff --git a/src/core/security/security_context.h b/src/core/security/security_context.h
index 794258e..61601f5 100644
--- a/src/core/security/security_context.h
+++ b/src/core/security/security_context.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_SECURITY_SECURITY_CONTEXT_H
-#define GRPC_INTERNAL_CORE_SECURITY_SECURITY_CONTEXT_H
+#ifndef GRPC_CORE_SECURITY_SECURITY_CONTEXT_H
+#define GRPC_CORE_SECURITY_SECURITY_CONTEXT_H
 
 #include "src/core/iomgr/pollset.h"
 #include "src/core/security/credentials.h"
@@ -111,4 +111,4 @@
 grpc_auth_context *grpc_find_auth_context_in_args(
     const grpc_channel_args *args);
 
-#endif /* GRPC_INTERNAL_CORE_SECURITY_SECURITY_CONTEXT_H */
+#endif /* GRPC_CORE_SECURITY_SECURITY_CONTEXT_H */
diff --git a/src/core/security/server_secure_chttp2.c b/src/core/security/server_secure_chttp2.c
index 91547eb..009ec95 100644
--- a/src/core/security/server_secure_chttp2.c
+++ b/src/core/security/server_secure_chttp2.c
@@ -83,8 +83,6 @@
 static void setup_transport(grpc_exec_ctx *exec_ctx, void *statep,
                             grpc_transport *transport,
                             grpc_auth_context *auth_context) {
-  static grpc_channel_filter const *extra_filters[] = {
-      &grpc_server_auth_filter, &grpc_http_server_filter};
   grpc_server_secure_state *state = statep;
   grpc_channel_args *args_copy;
   grpc_arg args_to_add[2];
@@ -93,8 +91,7 @@
   args_copy = grpc_channel_args_copy_and_add(
       grpc_server_get_channel_args(state->server), args_to_add,
       GPR_ARRAY_SIZE(args_to_add));
-  grpc_server_setup_transport(exec_ctx, state->server, transport, extra_filters,
-                              GPR_ARRAY_SIZE(extra_filters), args_copy);
+  grpc_server_setup_transport(exec_ctx, state->server, transport, args_copy);
   grpc_channel_args_destroy(args_copy);
 }
 
diff --git a/src/core/statistics/census_interface.h b/src/core/statistics/census_interface.h
index c43acbd..ce8ff92 100644
--- a/src/core/statistics/census_interface.h
+++ b/src/core/statistics/census_interface.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_STATISTICS_CENSUS_INTERFACE_H
-#define GRPC_INTERNAL_CORE_STATISTICS_CENSUS_INTERFACE_H
+#ifndef GRPC_CORE_STATISTICS_CENSUS_INTERFACE_H
+#define GRPC_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_CORE_STATISTICS_CENSUS_INTERFACE_H */
+#endif /* GRPC_CORE_STATISTICS_CENSUS_INTERFACE_H */
diff --git a/src/core/statistics/census_log.h b/src/core/statistics/census_log.h
index 356437c..e7ce0d4 100644
--- a/src/core/statistics/census_log.h
+++ b/src/core/statistics/census_log.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_STATISTICS_CENSUS_LOG_H
-#define GRPC_INTERNAL_CORE_STATISTICS_CENSUS_LOG_H
+#ifndef GRPC_CORE_STATISTICS_CENSUS_LOG_H
+#define GRPC_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_CORE_STATISTICS_CENSUS_LOG_H */
+#endif /* GRPC_CORE_STATISTICS_CENSUS_LOG_H */
diff --git a/src/core/statistics/census_rpc_stats.h b/src/core/statistics/census_rpc_stats.h
index 8bdbc49..4cf17d2 100644
--- a/src/core/statistics/census_rpc_stats.h
+++ b/src/core/statistics/census_rpc_stats.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_STATISTICS_CENSUS_RPC_STATS_H
-#define GRPC_INTERNAL_CORE_STATISTICS_CENSUS_RPC_STATS_H
+#ifndef GRPC_CORE_STATISTICS_CENSUS_RPC_STATS_H
+#define GRPC_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_CORE_STATISTICS_CENSUS_RPC_STATS_H */
+#endif /* GRPC_CORE_STATISTICS_CENSUS_RPC_STATS_H */
diff --git a/src/core/statistics/census_tracing.h b/src/core/statistics/census_tracing.h
index bb3f255..b611e95 100644
--- a/src/core/statistics/census_tracing.h
+++ b/src/core/statistics/census_tracing.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_STATISTICS_CENSUS_TRACING_H
-#define GRPC_INTERNAL_CORE_STATISTICS_CENSUS_TRACING_H
+#ifndef GRPC_CORE_STATISTICS_CENSUS_TRACING_H
+#define GRPC_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_CORE_STATISTICS_CENSUS_TRACING_H */
+#endif /* GRPC_CORE_STATISTICS_CENSUS_TRACING_H */
diff --git a/src/core/statistics/hash_table.h b/src/core/statistics/hash_table.h
index d9860a9..f4bf2ba 100644
--- a/src/core/statistics/hash_table.h
+++ b/src/core/statistics/hash_table.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_STATISTICS_HASH_TABLE_H
-#define GRPC_INTERNAL_CORE_STATISTICS_HASH_TABLE_H
+#ifndef GRPC_CORE_STATISTICS_HASH_TABLE_H
+#define GRPC_CORE_STATISTICS_HASH_TABLE_H
 
 #include <stddef.h>
 
@@ -128,4 +128,4 @@
    should not invalidate data entries. */
 uint64_t census_ht_for_all(const census_ht *ht, census_ht_itr_cb);
 
-#endif /* GRPC_INTERNAL_CORE_STATISTICS_HASH_TABLE_H */
+#endif /* GRPC_CORE_STATISTICS_HASH_TABLE_H */
diff --git a/src/core/statistics/window_stats.h b/src/core/statistics/window_stats.h
index f4732e9..7742771 100644
--- a/src/core/statistics/window_stats.h
+++ b/src/core/statistics/window_stats.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_STATISTICS_WINDOW_STATS_H
-#define GRPC_INTERNAL_CORE_STATISTICS_WINDOW_STATS_H
+#ifndef GRPC_CORE_STATISTICS_WINDOW_STATS_H
+#define GRPC_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_CORE_STATISTICS_WINDOW_STATS_H */
+#endif /* GRPC_CORE_STATISTICS_WINDOW_STATS_H */
diff --git a/src/core/support/alloc.c b/src/core/support/alloc.c
index 0a064b2..b99584b 100644
--- a/src/core/support/alloc.c
+++ b/src/core/support/alloc.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -87,4 +87,4 @@
   return (void *)ret;
 }
 
-void gpr_free_aligned(void *ptr) { free(((void **)ptr)[-1]); }
+void gpr_free_aligned(void *ptr) { gpr_free(((void **)ptr)[-1]); }
diff --git a/src/core/support/backoff.c b/src/core/support/backoff.c
new file mode 100644
index 0000000..7458219
--- /dev/null
+++ b/src/core/support/backoff.c
@@ -0,0 +1,71 @@
+/*
+ *
+ * Copyright 2016, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "src/core/support/backoff.h"
+
+#include <grpc/support/useful.h>
+
+void gpr_backoff_init(gpr_backoff *backoff, double multiplier, double jitter,
+                      int64_t min_timeout_millis, int64_t max_timeout_millis) {
+  backoff->multiplier = multiplier;
+  backoff->jitter = jitter;
+  backoff->min_timeout_millis = min_timeout_millis;
+  backoff->max_timeout_millis = max_timeout_millis;
+  backoff->rng_state = (uint32_t)gpr_now(GPR_CLOCK_REALTIME).tv_nsec;
+}
+
+gpr_timespec gpr_backoff_begin(gpr_backoff *backoff, gpr_timespec now) {
+  backoff->current_timeout_millis = backoff->min_timeout_millis;
+  return gpr_time_add(
+      now, gpr_time_from_millis(backoff->current_timeout_millis, GPR_TIMESPAN));
+}
+
+/* Generate a random number between 0 and 1. */
+static double generate_uniform_random_number(uint32_t *rng_state) {
+  *rng_state = (1103515245 * *rng_state + 12345) % ((uint32_t)1 << 31);
+  return *rng_state / (double)((uint32_t)1 << 31);
+}
+
+gpr_timespec gpr_backoff_step(gpr_backoff *backoff, gpr_timespec now) {
+  double new_timeout_millis =
+      backoff->multiplier * (double)backoff->current_timeout_millis;
+  double jitter_range = backoff->jitter * new_timeout_millis;
+  double jitter =
+      (2 * generate_uniform_random_number(&backoff->rng_state) - 1) *
+      jitter_range;
+  backoff->current_timeout_millis =
+      GPR_CLAMP((int64_t)(new_timeout_millis + jitter),
+                backoff->min_timeout_millis, backoff->max_timeout_millis);
+  return gpr_time_add(
+      now, gpr_time_from_millis(backoff->current_timeout_millis, GPR_TIMESPAN));
+}
diff --git a/src/core/support/backoff.h b/src/core/support/backoff.h
new file mode 100644
index 0000000..f7730fd
--- /dev/null
+++ b/src/core/support/backoff.h
@@ -0,0 +1,65 @@
+/*
+ *
+ * Copyright 2016, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef GRPC_CORE_SUPPORT_BACKOFF_H
+#define GRPC_CORE_SUPPORT_BACKOFF_H
+
+#include <grpc/support/time.h>
+
+typedef struct {
+  /// const: multiplier between retry attempts
+  double multiplier;
+  /// const: amount to randomize backoffs
+  double jitter;
+  /// const: minimum time between retries in milliseconds
+  int64_t min_timeout_millis;
+  /// const: maximum time between retries in milliseconds
+  int64_t max_timeout_millis;
+
+  /// random number generator
+  uint32_t rng_state;
+
+  /// current retry timeout in milliseconds
+  int64_t current_timeout_millis;
+} gpr_backoff;
+
+/// Initialize backoff machinery - does not need to be destroyed
+void gpr_backoff_init(gpr_backoff *backoff, double multiplier, double jitter,
+                      int64_t min_timeout_millis, int64_t max_timeout_millis);
+
+/// Begin retry loop: returns a timespec for the NEXT retry
+gpr_timespec gpr_backoff_begin(gpr_backoff *backoff, gpr_timespec now);
+/// Step a retry loop: returns a timespec for the NEXT retry
+gpr_timespec gpr_backoff_step(gpr_backoff *backoff, gpr_timespec now);
+
+#endif /* GRPC_CORE_SUPPORT_BACKOFF_H */
diff --git a/src/core/support/block_annotate.h b/src/core/support/block_annotate.h
index 3cd8eee..79a1803 100644
--- a/src/core/support/block_annotate.h
+++ b/src/core/support/block_annotate.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_SUPPORT_BLOCK_ANNOTATE_H
-#define GRPC_INTERNAL_CORE_SUPPORT_BLOCK_ANNOTATE_H
+#ifndef GRPC_CORE_SUPPORT_BLOCK_ANNOTATE_H
+#define GRPC_CORE_SUPPORT_BLOCK_ANNOTATE_H
 
 /* These annotations identify the beginning and end of regions where
    the code may block for reasons other than synchronization functions.
@@ -45,4 +45,4 @@
   do {                                      \
   } while (0)
 
-#endif /* GRPC_INTERNAL_CORE_SUPPORT_BLOCK_ANNOTATE_H */
+#endif /* GRPC_CORE_SUPPORT_BLOCK_ANNOTATE_H */
diff --git a/src/core/support/env.h b/src/core/support/env.h
index 24172d8..2902456 100644
--- a/src/core/support/env.h
+++ b/src/core/support/env.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_SUPPORT_ENV_H
-#define GRPC_INTERNAL_CORE_SUPPORT_ENV_H
+#ifndef GRPC_CORE_SUPPORT_ENV_H
+#define GRPC_CORE_SUPPORT_ENV_H
 
 #include <stdio.h>
 
@@ -57,4 +57,4 @@
 }
 #endif
 
-#endif /* GRPC_INTERNAL_CORE_SUPPORT_ENV_H */
+#endif /* GRPC_CORE_SUPPORT_ENV_H */
diff --git a/src/core/support/load_file.h b/src/core/support/load_file.h
index 746319a..5896654 100644
--- a/src/core/support/load_file.h
+++ b/src/core/support/load_file.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_SUPPORT_LOAD_FILE_H
-#define GRPC_INTERNAL_CORE_SUPPORT_LOAD_FILE_H
+#ifndef GRPC_CORE_SUPPORT_LOAD_FILE_H
+#define GRPC_CORE_SUPPORT_LOAD_FILE_H
 
 #include <stdio.h>
 
@@ -52,4 +52,4 @@
 }
 #endif
 
-#endif /* GRPC_INTERNAL_CORE_SUPPORT_LOAD_FILE_H */
+#endif /* GRPC_CORE_SUPPORT_LOAD_FILE_H */
diff --git a/src/core/support/murmur_hash.h b/src/core/support/murmur_hash.h
index 0bf04f7..0f0b399 100644
--- a/src/core/support/murmur_hash.h
+++ b/src/core/support/murmur_hash.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_SUPPORT_MURMUR_HASH_H
-#define GRPC_INTERNAL_CORE_SUPPORT_MURMUR_HASH_H
+#ifndef GRPC_CORE_SUPPORT_MURMUR_HASH_H
+#define GRPC_CORE_SUPPORT_MURMUR_HASH_H
 
 #include <grpc/support/port_platform.h>
 
@@ -41,4 +41,4 @@
 /* compute the hash of key (length len) */
 uint32_t gpr_murmur_hash3(const void *key, size_t len, uint32_t seed);
 
-#endif /* GRPC_INTERNAL_CORE_SUPPORT_MURMUR_HASH_H */
+#endif /* GRPC_CORE_SUPPORT_MURMUR_HASH_H */
diff --git a/src/core/support/stack_lockfree.h b/src/core/support/stack_lockfree.h
index ca58dd0..d6fd06d 100644
--- a/src/core/support/stack_lockfree.h
+++ b/src/core/support/stack_lockfree.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_SUPPORT_STACK_LOCKFREE_H
-#define GRPC_INTERNAL_CORE_SUPPORT_STACK_LOCKFREE_H
+#ifndef GRPC_CORE_SUPPORT_STACK_LOCKFREE_H
+#define GRPC_CORE_SUPPORT_STACK_LOCKFREE_H
 
 #include <stddef.h>
 
@@ -50,4 +50,4 @@
 /* Returns -1 on empty or the actual entry number */
 int gpr_stack_lockfree_pop(gpr_stack_lockfree *stack);
 
-#endif /* GRPC_INTERNAL_CORE_SUPPORT_STACK_LOCKFREE_H */
+#endif /* GRPC_CORE_SUPPORT_STACK_LOCKFREE_H */
diff --git a/src/core/support/string.h b/src/core/support/string.h
index e6755de..a367ed7 100644
--- a/src/core/support/string.h
+++ b/src/core/support/string.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_SUPPORT_STRING_H
-#define GRPC_INTERNAL_CORE_SUPPORT_STRING_H
+#ifndef GRPC_CORE_SUPPORT_STRING_H
+#define GRPC_CORE_SUPPORT_STRING_H
 
 #include <stddef.h>
 
@@ -118,4 +118,4 @@
 }
 #endif
 
-#endif /* GRPC_INTERNAL_CORE_SUPPORT_STRING_H */
+#endif /* GRPC_CORE_SUPPORT_STRING_H */
diff --git a/src/core/support/string_win32.h b/src/core/support/string_win32.h
index e304365..c9ae8d9 100644
--- a/src/core/support/string_win32.h
+++ b/src/core/support/string_win32.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_SUPPORT_STRING_WIN32_H
-#define GRPC_INTERNAL_CORE_SUPPORT_STRING_WIN32_H
+#ifndef GRPC_CORE_SUPPORT_STRING_WIN32_H
+#define GRPC_CORE_SUPPORT_STRING_WIN32_H
 
 #include <grpc/support/port_platform.h>
 
@@ -44,4 +44,4 @@
 
 #endif /* GPR_WIN32 */
 
-#endif /* GRPC_INTERNAL_CORE_SUPPORT_STRING_WIN32_H */
+#endif /* GRPC_CORE_SUPPORT_STRING_WIN32_H */
diff --git a/src/core/support/thd_internal.h b/src/core/support/thd_internal.h
index 1508c46..33b904e 100644
--- a/src/core/support/thd_internal.h
+++ b/src/core/support/thd_internal.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,9 +31,9 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_SUPPORT_THD_INTERNAL_H
-#define GRPC_INTERNAL_CORE_SUPPORT_THD_INTERNAL_H
+#ifndef GRPC_CORE_SUPPORT_THD_INTERNAL_H
+#define GRPC_CORE_SUPPORT_THD_INTERNAL_H
 
 /* Internal interfaces between modules within the gpr support library.  */
 
-#endif /* GRPC_INTERNAL_CORE_SUPPORT_THD_INTERNAL_H */
+#endif /* GRPC_CORE_SUPPORT_THD_INTERNAL_H */
diff --git a/src/core/support/time_precise.h b/src/core/support/time_precise.h
index 80c5000..871c99a 100644
--- a/src/core/support/time_precise.h
+++ b/src/core/support/time_precise.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,12 +31,12 @@
  *
  */
 
-#ifndef GRPC_CORE_SUPPORT_TIME_PRECISE_H_
-#define GRPC_CORE_SUPPORT_TIME_PRECISE_H_
+#ifndef GRPC_CORE_SUPPORT_TIME_PRECISE_H
+#define GRPC_CORE_SUPPORT_TIME_PRECISE_H
 
 #include <grpc/support/time.h>
 
 void gpr_precise_clock_init(void);
 void gpr_precise_clock_now(gpr_timespec *clk);
 
-#endif /* GRPC_CORE_SUPPORT_TIME_PRECISE_ */
+#endif /* GRPC_CORE_SUPPORT_TIME_PRECISE_H */
diff --git a/src/core/support/tmpfile.h b/src/core/support/tmpfile.h
index cecc71e..df6f869 100644
--- a/src/core/support/tmpfile.h
+++ b/src/core/support/tmpfile.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_SUPPORT_TMPFILE_H
-#define GRPC_INTERNAL_CORE_SUPPORT_TMPFILE_H
+#ifndef GRPC_CORE_SUPPORT_TMPFILE_H
+#define GRPC_CORE_SUPPORT_TMPFILE_H
 
 #include <stdio.h>
 
@@ -52,4 +52,4 @@
 }
 #endif
 
-#endif /* GRPC_INTERNAL_CORE_SUPPORT_TMPFILE_H */
+#endif /* GRPC_CORE_SUPPORT_TMPFILE_H */
diff --git a/src/core/surface/api_trace.h b/src/core/surface/api_trace.h
index 82bbf3b..29a9b2d 100644
--- a/src/core/surface/api_trace.h
+++ b/src/core/surface/api_trace.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_SURFACE_API_TRACE_H
-#define GRPC_INTERNAL_CORE_SURFACE_API_TRACE_H
+#ifndef GRPC_CORE_SURFACE_API_TRACE_H
+#define GRPC_CORE_SURFACE_API_TRACE_H
 
 #include "src/core/debug/trace.h"
 #include <grpc/support/log.h>
@@ -62,4 +62,4 @@
     gpr_log(GPR_INFO, fmt GRPC_API_TRACE_UNWRAP##nargs args); \
   }
 
-#endif /* GRPC_INTERNAL_CORE_SURFACE_API_TRACE_H */
+#endif /* GRPC_CORE_SURFACE_API_TRACE_H */
diff --git a/src/core/surface/call.c b/src/core/surface/call.c
index 1b117aa..6f1cd1d 100644
--- a/src/core/surface/call.c
+++ b/src/core/surface/call.c
@@ -1481,3 +1481,11 @@
 }
 
 uint8_t grpc_call_is_client(grpc_call *call) { return call->is_client; }
+
+grpc_compression_algorithm grpc_call_compression_for_level(
+    grpc_call *call, grpc_compression_level level) {
+  gpr_mu_lock(&call->mu);
+  const uint32_t accepted_encodings = call->encodings_accepted_by_peer;
+  gpr_mu_unlock(&call->mu);
+  return grpc_compression_algorithm_for_level(level, accepted_encodings);
+}
diff --git a/src/core/surface/call.h b/src/core/surface/call.h
index 0bbffb9..d2edf03 100644
--- a/src/core/surface/call.h
+++ b/src/core/surface/call.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,14 +31,16 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_SURFACE_CALL_H
-#define GRPC_INTERNAL_CORE_SURFACE_CALL_H
+#ifndef GRPC_CORE_SURFACE_CALL_H
+#define GRPC_CORE_SURFACE_CALL_H
 
 #include "src/core/channel/channel_stack.h"
 #include "src/core/channel/context.h"
 #include "src/core/surface/api_trace.h"
 #include "src/core/surface/surface_trace.h"
+
 #include <grpc/grpc.h>
+#include <grpc/impl/codegen/compression_types.h>
 
 #ifdef __cplusplus
 extern "C" {
@@ -102,8 +104,13 @@
 
 uint8_t grpc_call_is_client(grpc_call *call);
 
+/* Return an appropriate compression algorithm for the requested compression \a
+ * level in the context of \a call. */
+grpc_compression_algorithm grpc_call_compression_for_level(
+    grpc_call *call, grpc_compression_level level);
+
 #ifdef __cplusplus
 }
 #endif
 
-#endif /* GRPC_INTERNAL_CORE_SURFACE_CALL_H */
+#endif /* GRPC_CORE_SURFACE_CALL_H */
diff --git a/src/core/surface/call_test_only.h b/src/core/surface/call_test_only.h
index b57c95c..fdc43a3 100644
--- a/src/core/surface/call_test_only.h
+++ b/src/core/surface/call_test_only.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_SURFACE_CALL_TEST_ONLY_H
-#define GRPC_INTERNAL_CORE_SURFACE_CALL_TEST_ONLY_H
+#ifndef GRPC_CORE_SURFACE_CALL_TEST_ONLY_H
+#define GRPC_CORE_SURFACE_CALL_TEST_ONLY_H
 
 #include <grpc/grpc.h>
 
@@ -61,4 +61,4 @@
 }
 #endif
 
-#endif /* GRPC_INTERNAL_CORE_SURFACE_CALL_TEST_ONLY_H */
+#endif /* GRPC_CORE_SURFACE_CALL_TEST_ONLY_H */
diff --git a/src/core/surface/channel.c b/src/core/surface/channel.c
index 12d8ebc..964ab34 100644
--- a/src/core/surface/channel.c
+++ b/src/core/surface/channel.c
@@ -40,6 +40,7 @@
 #include <grpc/support/log.h>
 #include <grpc/support/string_util.h>
 
+#include "src/core/surface/channel_init.h"
 #include "src/core/client_config/resolver_registry.h"
 #include "src/core/iomgr/iomgr.h"
 #include "src/core/support/string.h"
@@ -82,24 +83,25 @@
 
 static void destroy_channel(grpc_exec_ctx *exec_ctx, void *arg, bool success);
 
-grpc_channel *grpc_channel_create_from_filters(
-    grpc_exec_ctx *exec_ctx, const char *target,
-    const grpc_channel_filter **filters, size_t num_filters,
-    const grpc_channel_args *args, int is_client) {
-  size_t i;
-  size_t size =
-      sizeof(grpc_channel) + grpc_channel_stack_size(filters, num_filters);
-  grpc_channel *channel = gpr_malloc(size);
+grpc_channel *grpc_channel_create(grpc_exec_ctx *exec_ctx, const char *target,
+                                  const grpc_channel_args *args,
+                                  grpc_channel_stack_type channel_stack_type,
+                                  grpc_transport *optional_transport) {
+  bool is_client = grpc_channel_stack_type_is_client(channel_stack_type);
+
+  grpc_channel *channel = grpc_channel_init_create_stack(
+      exec_ctx, channel_stack_type, sizeof(grpc_channel), args, 1,
+      destroy_channel, NULL, optional_transport);
+
   memset(channel, 0, sizeof(*channel));
   channel->target = gpr_strdup(target);
-  GPR_ASSERT(grpc_is_initialized() && "call grpc_init()");
   channel->is_client = is_client;
   gpr_mu_init(&channel->registered_call_mu);
   channel->registered_calls = NULL;
 
   channel->max_message_length = DEFAULT_MAX_MESSAGE_LENGTH;
   if (args) {
-    for (i = 0; i < args->num_args; i++) {
+    for (size_t i = 0; i < args->num_args; i++) {
       if (0 == strcmp(args->args[i].key, GRPC_ARG_MAX_MESSAGE_LENGTH)) {
         if (args->args[i].type != GRPC_ARG_INTEGER) {
           gpr_log(GPR_ERROR, "%s ignored: it must be an integer",
@@ -152,11 +154,6 @@
     gpr_free(default_authority);
   }
 
-  grpc_channel_stack_init(exec_ctx, 1, destroy_channel, channel, filters,
-                          num_filters, args,
-                          is_client ? "CLIENT_CHANNEL" : "SERVER_CHANNEL",
-                          CHANNEL_STACK_FROM_CHANNEL(channel));
-
   return channel;
 }
 
diff --git a/src/core/surface/channel.h b/src/core/surface/channel.h
index 00240c6..c08988d 100644
--- a/src/core/surface/channel.h
+++ b/src/core/surface/channel.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,16 +31,17 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_SURFACE_CHANNEL_H
-#define GRPC_INTERNAL_CORE_SURFACE_CHANNEL_H
+#ifndef GRPC_CORE_SURFACE_CHANNEL_H
+#define GRPC_CORE_SURFACE_CHANNEL_H
 
 #include "src/core/channel/channel_stack.h"
+#include "src/core/surface/channel_stack_type.h"
 #include "src/core/client_config/subchannel_factory.h"
 
-grpc_channel *grpc_channel_create_from_filters(
-    grpc_exec_ctx *exec_ctx, const char *target,
-    const grpc_channel_filter **filters, size_t count,
-    const grpc_channel_args *args, int is_client);
+grpc_channel *grpc_channel_create(grpc_exec_ctx *exec_ctx, const char *target,
+                                  const grpc_channel_args *args,
+                                  grpc_channel_stack_type channel_stack_type,
+                                  grpc_transport *optional_transport);
 
 /** Get a (borrowed) pointer to this channels underlying channel stack */
 grpc_channel_stack *grpc_channel_get_channel_stack(grpc_channel *channel);
@@ -71,4 +72,4 @@
   grpc_channel_internal_unref(exec_ctx, channel)
 #endif
 
-#endif /* GRPC_INTERNAL_CORE_SURFACE_CHANNEL_H */
+#endif /* GRPC_CORE_SURFACE_CHANNEL_H */
diff --git a/src/core/surface/channel_create.c b/src/core/surface/channel_create.c
index fd7e20e..123447c 100644
--- a/src/core/surface/channel_create.c
+++ b/src/core/surface/channel_create.c
@@ -105,9 +105,6 @@
                                         0);
     GPR_ASSERT(c->result->transport);
     c->result->channel_args = c->args.channel_args;
-    c->result->filters = gpr_malloc(sizeof(grpc_channel_filter *));
-    c->result->filters[0] = &grpc_http_client_filter;
-    c->result->num_filters = 1;
   } else {
     memset(c->result, 0, sizeof(*c->result));
   }
@@ -190,25 +187,16 @@
                                            const grpc_channel_args *args,
                                            void *reserved) {
   grpc_channel *channel = NULL;
-#define MAX_FILTERS 3
-  const grpc_channel_filter *filters[MAX_FILTERS];
   grpc_resolver *resolver;
   subchannel_factory *f;
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
-  size_t n = 0;
   GRPC_API_TRACE(
       "grpc_insecure_channel_create(target=%p, args=%p, reserved=%p)", 3,
       (target, args, reserved));
   GPR_ASSERT(!reserved);
-  if (grpc_channel_args_is_census_enabled(args)) {
-    filters[n++] = &grpc_client_census_filter;
-  }
-  filters[n++] = &grpc_compress_filter;
-  filters[n++] = &grpc_client_channel_filter;
-  GPR_ASSERT(n <= MAX_FILTERS);
 
   channel =
-      grpc_channel_create_from_filters(&exec_ctx, target, filters, n, args, 1);
+      grpc_channel_create(&exec_ctx, target, args, GRPC_CLIENT_CHANNEL, NULL);
 
   f = gpr_malloc(sizeof(*f));
   f->base.vtable = &subchannel_factory_vtable;
diff --git a/src/core/surface/channel_init.c b/src/core/surface/channel_init.c
new file mode 100644
index 0000000..538be84
--- /dev/null
+++ b/src/core/surface/channel_init.c
@@ -0,0 +1,148 @@
+/*
+ *
+ * Copyright 2016, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "src/core/surface/channel_init.h"
+
+#include <grpc/support/alloc.h>
+#include <grpc/support/useful.h>
+
+typedef struct stage_slot {
+  grpc_channel_init_stage fn;
+  void *arg;
+  int priority;
+  size_t insertion_order;
+} stage_slot;
+
+typedef struct stage_slots {
+  stage_slot *slots;
+  size_t num_slots;
+  size_t cap_slots;
+} stage_slots;
+
+static stage_slots g_slots[GRPC_NUM_CHANNEL_STACK_TYPES];
+static bool g_finalized;
+
+void grpc_channel_init_init(void) {
+  for (int i = 0; i < GRPC_NUM_CHANNEL_STACK_TYPES; i++) {
+    g_slots[i].slots = NULL;
+    g_slots[i].num_slots = 0;
+    g_slots[i].cap_slots = 0;
+  }
+  g_finalized = false;
+}
+
+void grpc_channel_init_register_stage(grpc_channel_stack_type type,
+                                      int priority,
+                                      grpc_channel_init_stage stage,
+                                      void *stage_arg) {
+  GPR_ASSERT(!g_finalized);
+  if (g_slots[type].cap_slots == g_slots[type].num_slots) {
+    g_slots[type].cap_slots = GPR_MAX(8, 3 * g_slots[type].cap_slots / 2);
+    g_slots[type].slots =
+        gpr_realloc(g_slots[type].slots,
+                    g_slots[type].cap_slots * sizeof(*g_slots[type].slots));
+  }
+  stage_slot *s = &g_slots[type].slots[g_slots[type].num_slots++];
+  s->insertion_order = g_slots[type].num_slots;
+  s->priority = priority;
+  s->fn = stage;
+  s->arg = stage_arg;
+}
+
+static int compare_slots(const void *a, const void *b) {
+  const stage_slot *sa = a;
+  const stage_slot *sb = b;
+
+  int c = GPR_ICMP(sa->priority, sb->priority);
+  if (c != 0) return c;
+  return GPR_ICMP(sa->insertion_order, sb->insertion_order);
+}
+
+void grpc_channel_init_finalize(void) {
+  GPR_ASSERT(!g_finalized);
+  for (int i = 0; i < GRPC_NUM_CHANNEL_STACK_TYPES; i++) {
+    qsort(g_slots[i].slots, g_slots[i].num_slots, sizeof(*g_slots[i].slots),
+          compare_slots);
+  }
+  g_finalized = true;
+}
+
+void grpc_channel_init_shutdown(void) {
+  for (int i = 0; i < GRPC_NUM_CHANNEL_STACK_TYPES; i++) {
+    gpr_free(g_slots[i].slots);
+    g_slots[i].slots = (void *)(uintptr_t)0xdeadbeef;
+  }
+}
+
+static const char *name_for_type(grpc_channel_stack_type type) {
+  switch (type) {
+    case GRPC_CLIENT_CHANNEL:
+      return "CLIENT_CHANNEL";
+    case GRPC_CLIENT_SUBCHANNEL:
+      return "CLIENT_SUBCHANNEL";
+    case GRPC_SERVER_CHANNEL:
+      return "SERVER_CHANNEL";
+    case GRPC_CLIENT_UCHANNEL:
+      return "CLIENT_UCHANNEL";
+    case GRPC_CLIENT_LAME_CHANNEL:
+      return "CLIENT_LAME_CHANNEL";
+    case GRPC_CLIENT_DIRECT_CHANNEL:
+      return "CLIENT_DIRECT_CHANNEL";
+    case GRPC_NUM_CHANNEL_STACK_TYPES:
+      break;
+  }
+  GPR_UNREACHABLE_CODE(return "UNKNOWN");
+}
+
+void *grpc_channel_init_create_stack(
+    grpc_exec_ctx *exec_ctx, grpc_channel_stack_type type, size_t prefix_bytes,
+    const grpc_channel_args *args, int initial_refs, grpc_iomgr_cb_func destroy,
+    void *destroy_arg, grpc_transport *transport) {
+  GPR_ASSERT(g_finalized);
+
+  grpc_channel_stack_builder *builder = grpc_channel_stack_builder_create();
+  grpc_channel_stack_builder_set_name(builder, name_for_type(type));
+  grpc_channel_stack_builder_set_channel_arguments(builder, args);
+  grpc_channel_stack_builder_set_transport(builder, transport);
+
+  for (size_t i = 0; i < g_slots[type].num_slots; i++) {
+    const stage_slot *slot = &g_slots[type].slots[i];
+    if (!slot->fn(builder, slot->arg)) {
+      grpc_channel_stack_builder_destroy(builder);
+      return NULL;
+    }
+  }
+
+  return grpc_channel_stack_builder_finish(exec_ctx, builder, prefix_bytes,
+                                           initial_refs, destroy, destroy_arg);
+}
diff --git a/src/core/surface/channel_init.h b/src/core/surface/channel_init.h
new file mode 100644
index 0000000..06faef6
--- /dev/null
+++ b/src/core/surface/channel_init.h
@@ -0,0 +1,86 @@
+/*
+ *
+ * Copyright 2016, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef GRPC_CORE_SURFACE_CHANNEL_INIT_H
+#define GRPC_CORE_SURFACE_CHANNEL_INIT_H
+
+#include "src/core/channel/channel_stack_builder.h"
+#include "src/core/surface/channel_stack_type.h"
+#include "src/core/transport/transport.h"
+
+/// This module provides a way for plugins (and the grpc core library itself)
+/// to register mutators for channel stacks.
+/// It also provides a universal entry path to run those mutators to build
+/// a channel stack for various subsystems.
+
+/// One stage of mutation: call functions against \a builder to influence the
+/// finally constructed channel stack
+typedef bool (*grpc_channel_init_stage)(grpc_channel_stack_builder *builder,
+                                        void *arg);
+
+/// Global initialization of the system
+void grpc_channel_init_init(void);
+
+/// Register one stage of mutators.
+/// Stages are run in priority order (lowest to highest), and then in
+/// registration order (in the case of a tie).
+/// Stages are registered against one of the pre-determined channel stack
+/// types.
+void grpc_channel_init_register_stage(grpc_channel_stack_type type,
+                                      int priority,
+                                      grpc_channel_init_stage stage_fn,
+                                      void *stage_arg);
+
+/// Finalize registration. No more calls to grpc_channel_init_register_stage are
+/// allowed.
+void grpc_channel_init_finalize(void);
+/// Shutdown the channel init system
+void grpc_channel_init_shutdown(void);
+
+/// Construct a channel stack of some sort: see channel_stack.h for details
+/// \a type is the type of channel stack to create
+/// \a prefix_bytes is the number of bytes before the channel stack to allocate
+/// \a args are configuration arguments for the channel stack
+/// \a initial_refs is the initial refcount to give the channel stack
+/// \a destroy and \a destroy_arg specify how to destroy the channel stack
+///    if destroy_arg is NULL, the returned value from this function will be
+///    substituted
+/// \a optional_transport is either NULL or a constructed transport object
+/// Returns a pointer to the base of the memory allocated (the actual channel
+/// stack object will be prefix_bytes past that pointer)
+void *grpc_channel_init_create_stack(
+    grpc_exec_ctx *exec_ctx, grpc_channel_stack_type type, size_t prefix_bytes,
+    const grpc_channel_args *args, int initial_refs, grpc_iomgr_cb_func destroy,
+    void *destroy_arg, grpc_transport *optional_transport);
+
+#endif /* GRPC_CORE_SURFACE_CHANNEL_INIT_H */
diff --git a/src/cpp/codegen/grpc_library.cc b/src/core/surface/channel_stack_type.c
similarity index 71%
copy from src/cpp/codegen/grpc_library.cc
copy to src/core/surface/channel_stack_type.c
index 48acec3..6fd33d4 100644
--- a/src/cpp/codegen/grpc_library.cc
+++ b/src/core/surface/channel_stack_type.c
@@ -31,10 +31,26 @@
  *
  */
 
-#include <grpc++/impl/codegen/grpc_library.h>
+#include <grpc/support/port_platform.h>
+#include "src/core/surface/channel_stack_type.h"
+#include <grpc/support/log.h>
 
-namespace grpc {
-
-GrpcLibraryInterface *g_glip = nullptr;
-
-}  // namespace grpc
+bool grpc_channel_stack_type_is_client(grpc_channel_stack_type type) {
+  switch (type) {
+    case GRPC_CLIENT_CHANNEL:
+      return true;
+    case GRPC_CLIENT_UCHANNEL:
+      return true;
+    case GRPC_CLIENT_SUBCHANNEL:
+      return true;
+    case GRPC_CLIENT_LAME_CHANNEL:
+      return true;
+    case GRPC_CLIENT_DIRECT_CHANNEL:
+      return true;
+    case GRPC_SERVER_CHANNEL:
+      return false;
+    case GRPC_NUM_CHANNEL_STACK_TYPES:
+      break;
+  }
+  GPR_UNREACHABLE_CODE(return true;);
+}
diff --git a/src/core/surface/server_create.c b/src/core/surface/channel_stack_type.h
similarity index 61%
rename from src/core/surface/server_create.c
rename to src/core/surface/channel_stack_type.h
index 5e37e80..846391a 100644
--- a/src/core/surface/server_create.c
+++ b/src/core/surface/channel_stack_type.h
@@ -31,18 +31,31 @@
  *
  */
 
-#include <grpc/grpc.h>
-#include "src/core/census/grpc_filter.h"
-#include "src/core/channel/channel_args.h"
-#include "src/core/channel/compress_filter.h"
-#include "src/core/surface/api_trace.h"
-#include "src/core/surface/completion_queue.h"
-#include "src/core/surface/server.h"
+#ifndef GRPC_CORE_SURFACE_CHANNEL_STACK_TYPE_H
+#define GRPC_CORE_SURFACE_CHANNEL_STACK_TYPE_H
 
-grpc_server *grpc_server_create(const grpc_channel_args *args, void *reserved) {
-  const grpc_channel_filter *filters[3];
-  size_t num_filters = 0;
-  filters[num_filters++] = &grpc_compress_filter;
-  GRPC_API_TRACE("grpc_server_create(%p, %p)", 2, (args, reserved));
-  return grpc_server_create_from_filters(filters, num_filters, args);
-}
+#include <stdbool.h>
+
+typedef enum {
+  // normal top-half client channel with load-balancing, connection management
+  GRPC_CLIENT_CHANNEL,
+  // abbreviated top-half client channel bound to one subchannel - for internal
+  // load balancing implementation
+  GRPC_CLIENT_UCHANNEL,
+  // bottom-half of a client channel: everything that happens post-load
+  // balancing (bound to a specific transport)
+  GRPC_CLIENT_SUBCHANNEL,
+  // a permanently broken client channel
+  GRPC_CLIENT_LAME_CHANNEL,
+  // a directly connected client channel (without load-balancing, directly talks
+  // to a transport)
+  GRPC_CLIENT_DIRECT_CHANNEL,
+  // server side channel
+  GRPC_SERVER_CHANNEL,
+  // must be last
+  GRPC_NUM_CHANNEL_STACK_TYPES
+} grpc_channel_stack_type;
+
+bool grpc_channel_stack_type_is_client(grpc_channel_stack_type type);
+
+#endif /* GRPC_CORE_SURFACE_CHANNEL_STACK_TYPE_H */
diff --git a/src/core/surface/completion_queue.h b/src/core/surface/completion_queue.h
index 27ef90f..07f6d0c 100644
--- a/src/core/surface/completion_queue.h
+++ b/src/core/surface/completion_queue.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_SURFACE_COMPLETION_QUEUE_H
-#define GRPC_INTERNAL_CORE_SURFACE_COMPLETION_QUEUE_H
+#ifndef GRPC_CORE_SURFACE_COMPLETION_QUEUE_H
+#define GRPC_CORE_SURFACE_COMPLETION_QUEUE_H
 
 /* Internal API for completion queues */
 
@@ -88,4 +88,4 @@
 void grpc_cq_global_init(void);
 void grpc_cq_global_shutdown(void);
 
-#endif /* GRPC_INTERNAL_CORE_SURFACE_COMPLETION_QUEUE_H */
+#endif /* GRPC_CORE_SURFACE_COMPLETION_QUEUE_H */
diff --git a/src/core/surface/event_string.h b/src/core/surface/event_string.h
index 07c474e..d0598ce 100644
--- a/src/core/surface/event_string.h
+++ b/src/core/surface/event_string.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,12 +31,12 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_SURFACE_EVENT_STRING_H
-#define GRPC_INTERNAL_CORE_SURFACE_EVENT_STRING_H
+#ifndef GRPC_CORE_SURFACE_EVENT_STRING_H
+#define GRPC_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_CORE_SURFACE_EVENT_STRING_H */
+#endif /* GRPC_CORE_SURFACE_EVENT_STRING_H */
diff --git a/src/core/surface/init.c b/src/core/surface/init.c
index a4a53d3..b507709 100644
--- a/src/core/surface/init.c
+++ b/src/core/surface/init.c
@@ -33,13 +33,21 @@
 
 #include <grpc/support/port_platform.h>
 
+#include <limits.h>
 #include <memory.h>
 
-#include <grpc/census.h>
 #include <grpc/grpc.h>
 #include <grpc/support/alloc.h>
 #include <grpc/support/time.h>
+/* TODO(ctiller): find another way? - better not to include census here */
+#include "src/core/census/grpc_plugin.h"
 #include "src/core/channel/channel_stack.h"
+#include "src/core/channel/compress_filter.h"
+#include "src/core/channel/connected_channel.h"
+#include "src/core/channel/client_channel.h"
+#include "src/core/channel/client_uchannel.h"
+#include "src/core/channel/http_client_filter.h"
+#include "src/core/channel/http_server_filter.h"
 #include "src/core/client_config/lb_policy_registry.h"
 #include "src/core/client_config/lb_policies/pick_first.h"
 #include "src/core/client_config/lb_policies/round_robin.h"
@@ -54,11 +62,15 @@
 #include "src/core/profiling/timers.h"
 #include "src/core/surface/api_trace.h"
 #include "src/core/surface/call.h"
+#include "src/core/surface/channel_init.h"
 #include "src/core/surface/completion_queue.h"
 #include "src/core/surface/init.h"
+#include "src/core/surface/lame_client.h"
+#include "src/core/surface/server.h"
 #include "src/core/surface/surface_trace.h"
 #include "src/core/transport/chttp2_transport.h"
 #include "src/core/transport/connectivity_state.h"
+#include "src/core/transport/transport_impl.h"
 
 #ifndef GRPC_DEFAULT_NAME_PREFIX
 #define GRPC_DEFAULT_NAME_PREFIX "dns:///"
@@ -72,9 +84,64 @@
 
 static void do_basic_init(void) {
   gpr_mu_init(&g_init_mu);
+  /* TODO(ctiller): ideally remove this strict linkage */
+  grpc_register_plugin(census_grpc_plugin_init, census_grpc_plugin_destroy);
   g_initializations = 0;
 }
 
+static bool append_filter(grpc_channel_stack_builder *builder, void *arg) {
+  return grpc_channel_stack_builder_append_filter(builder, arg, NULL, NULL);
+}
+
+static bool prepend_filter(grpc_channel_stack_builder *builder, void *arg) {
+  return grpc_channel_stack_builder_prepend_filter(builder, arg, NULL, NULL);
+}
+
+static bool maybe_add_http_filter(grpc_channel_stack_builder *builder,
+                                  void *arg) {
+  grpc_transport *t = grpc_channel_stack_builder_get_transport(builder);
+  if (t && strstr(t->vtable->name, "http")) {
+    return grpc_channel_stack_builder_prepend_filter(builder, arg, NULL, NULL);
+  }
+  return true;
+}
+
+static void register_builtin_channel_init() {
+  grpc_channel_init_register_stage(GRPC_CLIENT_CHANNEL, INT_MAX, prepend_filter,
+                                   (void *)&grpc_compress_filter);
+  grpc_channel_init_register_stage(GRPC_CLIENT_DIRECT_CHANNEL, INT_MAX,
+                                   prepend_filter,
+                                   (void *)&grpc_compress_filter);
+  grpc_channel_init_register_stage(GRPC_CLIENT_UCHANNEL, INT_MAX,
+                                   prepend_filter,
+                                   (void *)&grpc_compress_filter);
+  grpc_channel_init_register_stage(GRPC_SERVER_CHANNEL, INT_MAX, prepend_filter,
+                                   (void *)&grpc_compress_filter);
+  grpc_channel_init_register_stage(GRPC_CLIENT_SUBCHANNEL, INT_MAX,
+                                   maybe_add_http_filter,
+                                   (void *)&grpc_http_client_filter);
+  grpc_channel_init_register_stage(GRPC_CLIENT_SUBCHANNEL, INT_MAX,
+                                   grpc_add_connected_filter, NULL);
+  grpc_channel_init_register_stage(GRPC_CLIENT_DIRECT_CHANNEL, INT_MAX,
+                                   maybe_add_http_filter,
+                                   (void *)&grpc_http_client_filter);
+  grpc_channel_init_register_stage(GRPC_CLIENT_DIRECT_CHANNEL, INT_MAX,
+                                   grpc_add_connected_filter, NULL);
+  grpc_channel_init_register_stage(GRPC_SERVER_CHANNEL, INT_MAX,
+                                   maybe_add_http_filter,
+                                   (void *)&grpc_http_server_filter);
+  grpc_channel_init_register_stage(GRPC_SERVER_CHANNEL, INT_MAX,
+                                   grpc_add_connected_filter, NULL);
+  grpc_channel_init_register_stage(GRPC_CLIENT_CHANNEL, INT_MAX, append_filter,
+                                   (void *)&grpc_client_channel_filter);
+  grpc_channel_init_register_stage(GRPC_CLIENT_UCHANNEL, INT_MAX, append_filter,
+                                   (void *)&grpc_client_uchannel_filter);
+  grpc_channel_init_register_stage(GRPC_CLIENT_LAME_CHANNEL, INT_MAX,
+                                   append_filter, (void *)&grpc_lame_filter);
+  grpc_channel_init_register_stage(GRPC_SERVER_CHANNEL, INT_MAX, prepend_filter,
+                                   (void *)&grpc_server_top_filter);
+}
+
 typedef struct grpc_plugin {
   void (*init)();
   void (*destroy)();
@@ -85,7 +152,7 @@
 
 void grpc_register_plugin(void (*init)(void), void (*destroy)(void)) {
   GRPC_API_TRACE("grpc_register_plugin(init=%p, destroy=%p)", 2,
-                 ((void*)(intptr_t)init, (void*)(intptr_t)destroy));
+                 ((void *)(intptr_t)init, (void *)(intptr_t)destroy));
   GPR_ASSERT(g_number_of_plugins != MAX_PLUGINS);
   g_all_of_the_plugins[g_number_of_plugins].init = init;
   g_all_of_the_plugins[g_number_of_plugins].destroy = destroy;
@@ -100,6 +167,7 @@
   if (++g_initializations == 1) {
     gpr_time_init();
     grpc_mdctx_global_init();
+    grpc_channel_init_init();
     grpc_lb_policy_registry_init(grpc_pick_first_lb_factory_create());
     grpc_register_lb_policy(grpc_pick_first_lb_factory_create());
     grpc_register_lb_policy(grpc_round_robin_lb_factory_create());
@@ -115,18 +183,12 @@
     grpc_register_tracer("http", &grpc_http_trace);
     grpc_register_tracer("flowctl", &grpc_flowctl_trace);
     grpc_register_tracer("connectivity_state", &grpc_connectivity_state_trace);
+    grpc_register_tracer("channel_stack_builder",
+                         &grpc_trace_channel_stack_builder);
     grpc_security_pre_init();
     grpc_iomgr_init();
     grpc_executor_init();
     grpc_tracer_init("GRPC_TRACE");
-    /* Only initialize census if no one else has and some features are
-     * available. */
-    if (census_enabled() == CENSUS_FEATURE_NONE &&
-        census_supported() != CENSUS_FEATURE_NONE) {
-      if (census_initialize(census_supported())) { /* enable all features. */
-        gpr_log(GPR_ERROR, "Could not initialize census.");
-      }
-    }
     gpr_timers_global_init();
     grpc_cq_global_init();
     grpc_subchannel_index_init();
@@ -135,6 +197,12 @@
         g_all_of_the_plugins[i].init();
       }
     }
+    /* register channel finalization AFTER all plugins, to ensure that it's run
+     * at the appropriate time */
+    grpc_register_security_filters();
+    register_builtin_channel_init();
+    /* no more changes to channel init pipelines */
+    grpc_channel_init_finalize();
   }
   gpr_mu_unlock(&g_init_mu);
   GRPC_API_TRACE("grpc_init(void)", 0, ());
@@ -149,7 +217,6 @@
     grpc_cq_global_shutdown();
     grpc_iomgr_shutdown();
     grpc_subchannel_index_shutdown();
-    census_shutdown();
     gpr_timers_global_destroy();
     grpc_tracer_shutdown();
     grpc_resolver_registry_shutdown();
@@ -159,6 +226,7 @@
         g_all_of_the_plugins[i].destroy();
       }
     }
+    grpc_channel_init_shutdown();
     grpc_mdctx_global_shutdown();
   }
   gpr_mu_unlock(&g_init_mu);
diff --git a/src/core/surface/init.h b/src/core/surface/init.h
index 771c30f..5e358c7 100644
--- a/src/core/surface/init.h
+++ b/src/core/surface/init.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,10 +31,11 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_SURFACE_INIT_H
-#define GRPC_INTERNAL_CORE_SURFACE_INIT_H
+#ifndef GRPC_CORE_SURFACE_INIT_H
+#define GRPC_CORE_SURFACE_INIT_H
 
+void grpc_register_security_filters(void);
 void grpc_security_pre_init(void);
 int grpc_is_initialized(void);
 
-#endif /* GRPC_INTERNAL_CORE_SURFACE_INIT_H */
+#endif /* GRPC_CORE_SURFACE_INIT_H */
diff --git a/src/core/surface/init_secure.c b/src/core/surface/init_secure.c
index fa20e91..311dda9 100644
--- a/src/core/surface/init_secure.c
+++ b/src/core/surface/init_secure.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -32,11 +32,58 @@
  */
 
 #include "src/core/surface/init.h"
+
+#include <limits.h>
+#include <string.h>
+
+#include "src/core/surface/channel_init.h"
 #include "src/core/debug/trace.h"
+#include "src/core/security/auth_filters.h"
+#include "src/core/security/credentials.h"
 #include "src/core/security/secure_endpoint.h"
+#include "src/core/security/security_connector.h"
 #include "src/core/tsi/transport_security_interface.h"
 
 void grpc_security_pre_init(void) {
   grpc_register_tracer("secure_endpoint", &grpc_trace_secure_endpoint);
   grpc_register_tracer("transport_security", &tsi_tracing_enabled);
 }
+
+static bool maybe_prepend_client_auth_filter(
+    grpc_channel_stack_builder *builder, void *arg) {
+  const grpc_channel_args *args =
+      grpc_channel_stack_builder_get_channel_arguments(builder);
+  if (args) {
+    for (size_t i = 0; i < args->num_args; i++) {
+      if (0 == strcmp(GRPC_SECURITY_CONNECTOR_ARG, args->args[i].key)) {
+        return grpc_channel_stack_builder_prepend_filter(
+            builder, &grpc_client_auth_filter, NULL, NULL);
+      }
+    }
+  }
+  return true;
+}
+
+static bool maybe_prepend_server_auth_filter(
+    grpc_channel_stack_builder *builder, void *arg) {
+  const grpc_channel_args *args =
+      grpc_channel_stack_builder_get_channel_arguments(builder);
+  if (args) {
+    for (size_t i = 0; i < args->num_args; i++) {
+      if (0 == strcmp(GRPC_SERVER_CREDENTIALS_ARG, args->args[i].key)) {
+        return grpc_channel_stack_builder_prepend_filter(
+            builder, &grpc_server_auth_filter, NULL, NULL);
+      }
+    }
+  }
+  return true;
+}
+
+void grpc_register_security_filters(void) {
+  grpc_channel_init_register_stage(GRPC_CLIENT_SUBCHANNEL, INT_MAX,
+                                   maybe_prepend_client_auth_filter, NULL);
+  grpc_channel_init_register_stage(GRPC_CLIENT_DIRECT_CHANNEL, INT_MAX,
+                                   maybe_prepend_client_auth_filter, NULL);
+  grpc_channel_init_register_stage(GRPC_SERVER_CHANNEL, INT_MAX,
+                                   maybe_prepend_server_auth_filter, NULL);
+}
diff --git a/src/core/surface/init_unsecure.c b/src/core/surface/init_unsecure.c
index 630d564..278fcc8 100644
--- a/src/core/surface/init_unsecure.c
+++ b/src/core/surface/init_unsecure.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -34,3 +34,5 @@
 #include "src/core/surface/init.h"
 
 void grpc_security_pre_init(void) {}
+
+void grpc_register_security_filters(void) {}
diff --git a/src/core/surface/lame_client.c b/src/core/surface/lame_client.c
index 537069e..58f8994 100644
--- a/src/core/surface/lame_client.c
+++ b/src/core/surface/lame_client.c
@@ -31,6 +31,8 @@
  *
  */
 
+#include "src/core/surface/lame_client.h"
+
 #include <grpc/grpc.h>
 
 #include <string.h>
@@ -115,7 +117,7 @@
 static void destroy_channel_elem(grpc_exec_ctx *exec_ctx,
                                  grpc_channel_element *elem) {}
 
-static const grpc_channel_filter lame_filter = {
+const grpc_channel_filter grpc_lame_filter = {
     lame_start_transport_stream_op, lame_start_transport_op, sizeof(call_data),
     init_call_elem, grpc_call_stack_ignore_set_pollset, destroy_call_elem,
     sizeof(channel_data), init_channel_elem, destroy_channel_elem,
@@ -127,19 +129,17 @@
 grpc_channel *grpc_lame_client_channel_create(const char *target,
                                               grpc_status_code error_code,
                                               const char *error_message) {
-  grpc_channel *channel;
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   grpc_channel_element *elem;
   channel_data *chand;
-  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
-  static const grpc_channel_filter *filters[] = {&lame_filter};
-  channel =
-      grpc_channel_create_from_filters(&exec_ctx, target, filters, 1, NULL, 1);
+  grpc_channel *channel = grpc_channel_create(&exec_ctx, target, NULL,
+                                              GRPC_CLIENT_LAME_CHANNEL, NULL);
   elem = grpc_channel_stack_element(grpc_channel_get_channel_stack(channel), 0);
   GRPC_API_TRACE(
       "grpc_lame_client_channel_create(target=%s, error_code=%d, "
       "error_message=%s)",
       3, (target, (int)error_code, error_message));
-  GPR_ASSERT(elem->filter == &lame_filter);
+  GPR_ASSERT(elem->filter == &grpc_lame_filter);
   chand = (channel_data *)elem->channel_data;
   chand->error_code = error_code;
   chand->error_message = error_message;
diff --git a/src/cpp/codegen/grpc_library.cc b/src/core/surface/lame_client.h
similarity index 86%
rename from src/cpp/codegen/grpc_library.cc
rename to src/core/surface/lame_client.h
index 48acec3..3f3abd2 100644
--- a/src/cpp/codegen/grpc_library.cc
+++ b/src/core/surface/lame_client.h
@@ -31,10 +31,11 @@
  *
  */
 
-#include <grpc++/impl/codegen/grpc_library.h>
+#ifndef GRPC_CORE_SURFACE_LAME_CLIENT_H
+#define GRPC_CORE_SURFACE_LAME_CLIENT_H
 
-namespace grpc {
+#include "src/core/channel/channel_stack.h"
 
-GrpcLibraryInterface *g_glip = nullptr;
+extern const grpc_channel_filter grpc_lame_filter;
 
-}  // namespace grpc
+#endif /* GRPC_CORE_SURFACE_LAME_CLIENT_H */
diff --git a/src/core/surface/secure_channel_create.c b/src/core/surface/secure_channel_create.c
index aadfac4..cc75222 100644
--- a/src/core/surface/secure_channel_create.c
+++ b/src/core/surface/secure_channel_create.c
@@ -40,11 +40,8 @@
 #include <grpc/support/slice.h>
 #include <grpc/support/slice_buffer.h>
 
-#include "src/core/census/grpc_filter.h"
 #include "src/core/channel/channel_args.h"
 #include "src/core/channel/client_channel.h"
-#include "src/core/channel/compress_filter.h"
-#include "src/core/channel/http_client_filter.h"
 #include "src/core/client_config/resolver_registry.h"
 #include "src/core/iomgr/tcp_client.h"
 #include "src/core/security/auth_filters.h"
@@ -115,10 +112,6 @@
     args_copy = grpc_channel_args_copy_and_add(c->args.channel_args,
                                                &auth_context_arg, 1);
     c->result->channel_args = args_copy;
-    c->result->filters = gpr_malloc(sizeof(grpc_channel_filter *) * 2);
-    c->result->filters[0] = &grpc_http_client_filter;
-    c->result->filters[1] = &grpc_client_auth_filter;
-    c->result->num_filters = 2;
   }
   notify = c->notify;
   c->notify = NULL;
@@ -262,10 +255,7 @@
   grpc_channel_security_connector *security_connector;
   grpc_resolver *resolver;
   subchannel_factory *f;
-#define MAX_FILTERS 3
-  const grpc_channel_filter *filters[MAX_FILTERS];
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
-  size_t n = 0;
 
   GRPC_API_TRACE(
       "grpc_secure_channel_create(creds=%p, target=%s, args=%p, "
@@ -294,15 +284,9 @@
   args_copy = grpc_channel_args_copy_and_add(
       new_args_from_connector != NULL ? new_args_from_connector : args,
       &connector_arg, 1);
-  if (grpc_channel_args_is_census_enabled(args)) {
-    filters[n++] = &grpc_client_census_filter;
-  }
-  filters[n++] = &grpc_compress_filter;
-  filters[n++] = &grpc_client_channel_filter;
-  GPR_ASSERT(n <= MAX_FILTERS);
 
-  channel = grpc_channel_create_from_filters(&exec_ctx, target, filters, n,
-                                             args_copy, 1);
+  channel = grpc_channel_create(&exec_ctx, target, args_copy,
+                                GRPC_CLIENT_CHANNEL, NULL);
 
   f = gpr_malloc(sizeof(*f));
   f->base.vtable = &subchannel_factory_vtable;
diff --git a/src/core/surface/server.c b/src/core/surface/server.c
index 5b13d4b..da93474 100644
--- a/src/core/surface/server.c
+++ b/src/core/surface/server.c
@@ -42,7 +42,6 @@
 #include <grpc/support/string_util.h>
 #include <grpc/support/useful.h>
 
-#include "src/core/census/grpc_filter.h"
 #include "src/core/channel/channel_args.h"
 #include "src/core/channel/connected_channel.h"
 #include "src/core/iomgr/iomgr.h"
@@ -182,8 +181,6 @@
 } channel_broadcaster;
 
 struct grpc_server {
-  size_t channel_filter_count;
-  grpc_channel_filter const **channel_filters;
   grpc_channel_args *channel_args;
 
   grpc_completion_queue **cqs;
@@ -355,7 +352,6 @@
   grpc_channel_args_destroy(server->channel_args);
   gpr_mu_destroy(&server->mu_global);
   gpr_mu_destroy(&server->mu_call);
-  gpr_free((void *)server->channel_filters);
   while ((rm = server->registered_methods) != NULL) {
     server->registered_methods = rm->next;
     request_matcher_destroy(&rm->request_matcher);
@@ -757,7 +753,7 @@
   }
 }
 
-static const grpc_channel_filter server_surface_filter = {
+const grpc_channel_filter grpc_server_top_filter = {
     server_start_transport_stream_op, grpc_channel_next_op, sizeof(call_data),
     init_call_elem, grpc_call_stack_ignore_set_pollset, destroy_call_elem,
     sizeof(channel_data), init_channel_elem, destroy_channel_elem,
@@ -783,11 +779,10 @@
   server->cqs[n] = cq;
 }
 
-grpc_server *grpc_server_create_from_filters(
-    const grpc_channel_filter **filters, size_t filter_count,
-    const grpc_channel_args *args) {
+grpc_server *grpc_server_create(const grpc_channel_args *args, void *reserved) {
   size_t i;
-  int census_enabled = grpc_channel_args_is_census_enabled(args);
+
+  GRPC_API_TRACE("grpc_server_create(%p, %p)", 2, (args, reserved));
 
   grpc_server *server = gpr_malloc(sizeof(grpc_server));
 
@@ -815,23 +810,6 @@
   server->requested_calls = gpr_malloc(server->max_requested_calls *
                                        sizeof(*server->requested_calls));
 
-  /* Server filter stack is:
-
-     server_surface_filter - for making surface API calls
-     grpc_server_census_filter (optional) - for stats collection and tracing
-     {passed in filter stack}
-     grpc_connected_channel_filter - for interfacing with transports */
-  server->channel_filter_count = filter_count + 1u + (census_enabled ? 1u : 0u);
-  server->channel_filters =
-      gpr_malloc(server->channel_filter_count * sizeof(grpc_channel_filter *));
-  server->channel_filters[0] = &server_surface_filter;
-  if (census_enabled) {
-    server->channel_filters[1] = &grpc_server_census_filter;
-  }
-  for (i = 0; i < filter_count; i++) {
-    server->channel_filters[i + 1u + (census_enabled ? 1u : 0u)] = filters[i];
-  }
-
   server->channel_args = grpc_channel_args_copy(args);
 
   return server;
@@ -892,12 +870,7 @@
 
 void grpc_server_setup_transport(grpc_exec_ctx *exec_ctx, grpc_server *s,
                                  grpc_transport *transport,
-                                 grpc_channel_filter const **extra_filters,
-                                 size_t num_extra_filters,
                                  const grpc_channel_args *args) {
-  size_t num_filters = s->channel_filter_count + num_extra_filters + 1;
-  grpc_channel_filter const **filters =
-      gpr_malloc(sizeof(grpc_channel_filter *) * num_filters);
   size_t i;
   size_t num_registered_methods;
   size_t alloc;
@@ -913,22 +886,14 @@
   uint32_t max_probes = 0;
   grpc_transport_op op;
 
-  for (i = 0; i < s->channel_filter_count; i++) {
-    filters[i] = s->channel_filters[i];
-  }
-  for (; i < s->channel_filter_count + num_extra_filters; i++) {
-    filters[i] = extra_filters[i - s->channel_filter_count];
-  }
-  filters[i] = &grpc_connected_channel_filter;
-
   for (i = 0; i < s->cq_count; i++) {
     memset(&op, 0, sizeof(op));
     op.bind_pollset = grpc_cq_pollset(s->cqs[i]);
     grpc_transport_perform_op(exec_ctx, transport, &op);
   }
 
-  channel = grpc_channel_create_from_filters(exec_ctx, NULL, filters,
-                                             num_filters, args, 0);
+  channel =
+      grpc_channel_create(exec_ctx, NULL, args, GRPC_SERVER_CHANNEL, transport);
   chand = (channel_data *)grpc_channel_stack_element(
               grpc_channel_get_channel_stack(channel), 0)->channel_data;
   chand->server = s;
@@ -965,17 +930,12 @@
     chand->registered_method_max_probes = max_probes;
   }
 
-  grpc_connected_channel_bind_transport(grpc_channel_get_channel_stack(channel),
-                                        transport);
-
   gpr_mu_lock(&s->mu_global);
   chand->next = &s->root_channel_data;
   chand->prev = chand->next->prev;
   chand->next->prev = chand->prev->next = chand;
   gpr_mu_unlock(&s->mu_global);
 
-  gpr_free((void *)filters);
-
   GRPC_CHANNEL_INTERNAL_REF(channel, "connectivity");
   memset(&op, 0, sizeof(op));
   op.set_accept_stream = true;
diff --git a/src/core/surface/server.h b/src/core/surface/server.h
index a957fdb..cd62ead 100644
--- a/src/core/surface/server.h
+++ b/src/core/surface/server.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,17 +31,14 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_SURFACE_SERVER_H
-#define GRPC_INTERNAL_CORE_SURFACE_SERVER_H
+#ifndef GRPC_CORE_SURFACE_SERVER_H
+#define GRPC_CORE_SURFACE_SERVER_H
 
-#include "src/core/channel/channel_stack.h"
 #include <grpc/grpc.h>
+#include "src/core/channel/channel_stack.h"
 #include "src/core/transport/transport.h"
 
-/* Create a server */
-grpc_server *grpc_server_create_from_filters(
-    const grpc_channel_filter **filters, size_t filter_count,
-    const grpc_channel_args *args);
+extern const grpc_channel_filter grpc_server_top_filter;
 
 /* Add a listener to the server: when the server starts, it will call start,
    and when it shuts down, it will call destroy */
@@ -56,12 +53,10 @@
    server */
 void grpc_server_setup_transport(grpc_exec_ctx *exec_ctx, grpc_server *server,
                                  grpc_transport *transport,
-                                 grpc_channel_filter const **extra_filters,
-                                 size_t num_extra_filters,
                                  const grpc_channel_args *args);
 
 const grpc_channel_args *grpc_server_get_channel_args(grpc_server *server);
 
 int grpc_server_has_open_connections(grpc_server *server);
 
-#endif /* GRPC_INTERNAL_CORE_SURFACE_SERVER_H */
+#endif /* GRPC_CORE_SURFACE_SERVER_H */
diff --git a/src/core/surface/server_chttp2.c b/src/core/surface/server_chttp2.c
index ce970df..ff2840f 100644
--- a/src/core/surface/server_chttp2.c
+++ b/src/core/surface/server_chttp2.c
@@ -45,10 +45,7 @@
 
 static void setup_transport(grpc_exec_ctx *exec_ctx, void *server,
                             grpc_transport *transport) {
-  static grpc_channel_filter const *extra_filters[] = {
-      &grpc_http_server_filter};
-  grpc_server_setup_transport(exec_ctx, server, transport, extra_filters,
-                              GPR_ARRAY_SIZE(extra_filters),
+  grpc_server_setup_transport(exec_ctx, server, transport,
                               grpc_server_get_channel_args(server));
 }
 
diff --git a/src/core/surface/surface_trace.h b/src/core/surface/surface_trace.h
index 93b2859..ed820eb 100644
--- a/src/core/surface/surface_trace.h
+++ b/src/core/surface/surface_trace.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_SURFACE_SURFACE_TRACE_H
-#define GRPC_INTERNAL_CORE_SURFACE_SURFACE_TRACE_H
+#ifndef GRPC_CORE_SURFACE_SURFACE_TRACE_H
+#define GRPC_CORE_SURFACE_SURFACE_TRACE_H
 
 #include "src/core/debug/trace.h"
 #include "src/core/surface/api_trace.h"
@@ -45,4 +45,4 @@
     gpr_free(_ev);                                      \
   }
 
-#endif /* GRPC_INTERNAL_CORE_SURFACE_SURFACE_TRACE_H */
+#endif /* GRPC_CORE_SURFACE_SURFACE_TRACE_H */
diff --git a/src/core/transport/byte_stream.h b/src/core/transport/byte_stream.h
index d2e51e7..b8d0ade 100644
--- a/src/core/transport/byte_stream.h
+++ b/src/core/transport/byte_stream.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_TRANSPORT_BYTE_STREAM_H
-#define GRPC_INTERNAL_CORE_TRANSPORT_BYTE_STREAM_H
+#ifndef GRPC_CORE_TRANSPORT_BYTE_STREAM_H
+#define GRPC_CORE_TRANSPORT_BYTE_STREAM_H
 
 #include "src/core/iomgr/exec_ctx.h"
 #include <grpc/support/slice_buffer.h>
@@ -86,4 +86,4 @@
                                    gpr_slice_buffer *slice_buffer,
                                    uint32_t flags);
 
-#endif /* GRPC_INTERNAL_CORE_TRANSPORT_BYTE_STREAM_H */
+#endif /* GRPC_CORE_TRANSPORT_BYTE_STREAM_H */
diff --git a/src/core/transport/chttp2/alpn.h b/src/core/transport/chttp2/alpn.h
index f38b4c3..68010e3 100644
--- a/src/core/transport/chttp2/alpn.h
+++ b/src/core/transport/chttp2/alpn.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_ALPN_H
-#define GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_ALPN_H
+#ifndef GRPC_CORE_TRANSPORT_CHTTP2_ALPN_H
+#define GRPC_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_CORE_TRANSPORT_CHTTP2_ALPN_H */
+#endif /* GRPC_CORE_TRANSPORT_CHTTP2_ALPN_H */
diff --git a/src/core/transport/chttp2/bin_encoder.h b/src/core/transport/chttp2/bin_encoder.h
index 036fddf..edb6f2d 100644
--- a/src/core/transport/chttp2/bin_encoder.h
+++ b/src/core/transport/chttp2/bin_encoder.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_BIN_ENCODER_H
-#define GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_BIN_ENCODER_H
+#ifndef GRPC_CORE_TRANSPORT_CHTTP2_BIN_ENCODER_H
+#define GRPC_CORE_TRANSPORT_CHTTP2_BIN_ENCODER_H
 
 #include <grpc/support/slice.h>
 
@@ -51,4 +51,4 @@
    return y; */
 gpr_slice grpc_chttp2_base64_encode_and_huffman_compress(gpr_slice input);
 
-#endif /* GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_BIN_ENCODER_H */
+#endif /* GRPC_CORE_TRANSPORT_CHTTP2_BIN_ENCODER_H */
diff --git a/src/core/transport/chttp2/frame.h b/src/core/transport/chttp2/frame.h
index 879ee03..560a667 100644
--- a/src/core/transport/chttp2/frame.h
+++ b/src/core/transport/chttp2/frame.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_FRAME_H
-#define GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_FRAME_H
+#ifndef GRPC_CORE_TRANSPORT_CHTTP2_FRAME_H
+#define GRPC_CORE_TRANSPORT_CHTTP2_FRAME_H
 
 #include <grpc/support/port_platform.h>
 #include <grpc/support/slice.h>
@@ -66,4 +66,4 @@
 #define GRPC_CHTTP2_DATA_FLAG_PADDED 8
 #define GRPC_CHTTP2_FLAG_HAS_PRIORITY 0x20
 
-#endif /* GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_FRAME_H */
+#endif /* GRPC_CORE_TRANSPORT_CHTTP2_FRAME_H */
diff --git a/src/core/transport/chttp2/frame_data.h b/src/core/transport/chttp2/frame_data.h
index 936b7a2..92929d5 100644
--- a/src/core/transport/chttp2/frame_data.h
+++ b/src/core/transport/chttp2/frame_data.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_FRAME_DATA_H
-#define GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_FRAME_DATA_H
+#ifndef GRPC_CORE_TRANSPORT_CHTTP2_FRAME_DATA_H
+#define GRPC_CORE_TRANSPORT_CHTTP2_FRAME_DATA_H
 
 /* Parser for GRPC streams embedded in DATA frames */
 
@@ -98,4 +98,4 @@
                              uint32_t write_bytes, int is_eof,
                              gpr_slice_buffer *outbuf);
 
-#endif /* GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_FRAME_DATA_H */
+#endif /* GRPC_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 e1a72b4..616287e 100644
--- a/src/core/transport/chttp2/frame_goaway.h
+++ b/src/core/transport/chttp2/frame_goaway.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_FRAME_GOAWAY_H
-#define GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_FRAME_GOAWAY_H
+#ifndef GRPC_CORE_TRANSPORT_CHTTP2_FRAME_GOAWAY_H
+#define GRPC_CORE_TRANSPORT_CHTTP2_FRAME_GOAWAY_H
 
 #include "src/core/iomgr/exec_ctx.h"
 #include "src/core/transport/chttp2/frame.h"
@@ -74,4 +74,4 @@
                                gpr_slice debug_data,
                                gpr_slice_buffer *slice_buffer);
 
-#endif /* GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_FRAME_GOAWAY_H */
+#endif /* GRPC_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 16d7a72..fc4dd7a 100644
--- a/src/core/transport/chttp2/frame_ping.h
+++ b/src/core/transport/chttp2/frame_ping.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_FRAME_PING_H
-#define GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_FRAME_PING_H
+#ifndef GRPC_CORE_TRANSPORT_CHTTP2_FRAME_PING_H
+#define GRPC_CORE_TRANSPORT_CHTTP2_FRAME_PING_H
 
 #include "src/core/iomgr/exec_ctx.h"
 #include <grpc/support/slice.h>
@@ -53,4 +53,4 @@
     grpc_chttp2_transport_parsing *transport_parsing,
     grpc_chttp2_stream_parsing *stream_parsing, gpr_slice slice, int is_last);
 
-#endif /* GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_FRAME_PING_H */
+#endif /* GRPC_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 72ca654..d563a22 100644
--- a/src/core/transport/chttp2/frame_rst_stream.h
+++ b/src/core/transport/chttp2/frame_rst_stream.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_FRAME_RST_STREAM_H
-#define GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_FRAME_RST_STREAM_H
+#ifndef GRPC_CORE_TRANSPORT_CHTTP2_FRAME_RST_STREAM_H
+#define GRPC_CORE_TRANSPORT_CHTTP2_FRAME_RST_STREAM_H
 
 #include <grpc/support/slice.h>
 #include "src/core/transport/chttp2/frame.h"
@@ -52,4 +52,4 @@
     grpc_chttp2_transport_parsing *transport_parsing,
     grpc_chttp2_stream_parsing *stream_parsing, gpr_slice slice, int is_last);
 
-#endif /* GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_FRAME_RST_STREAM_H */
+#endif /* GRPC_CORE_TRANSPORT_CHTTP2_FRAME_RST_STREAM_H */
diff --git a/src/core/transport/chttp2/frame_settings.h b/src/core/transport/chttp2/frame_settings.h
index 3c918e3..e3c10d3 100644
--- a/src/core/transport/chttp2/frame_settings.h
+++ b/src/core/transport/chttp2/frame_settings.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_FRAME_SETTINGS_H
-#define GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_FRAME_SETTINGS_H
+#ifndef GRPC_CORE_TRANSPORT_CHTTP2_FRAME_SETTINGS_H
+#define GRPC_CORE_TRANSPORT_CHTTP2_FRAME_SETTINGS_H
 
 #include <grpc/support/port_platform.h>
 #include <grpc/support/slice.h>
@@ -100,4 +100,4 @@
     grpc_chttp2_transport_parsing *transport_parsing,
     grpc_chttp2_stream_parsing *stream_parsing, gpr_slice slice, int is_last);
 
-#endif /* GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_FRAME_SETTINGS_H */
+#endif /* GRPC_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 89d835c..0b3712b 100644
--- a/src/core/transport/chttp2/frame_window_update.h
+++ b/src/core/transport/chttp2/frame_window_update.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_FRAME_WINDOW_UPDATE_H
-#define GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_FRAME_WINDOW_UPDATE_H
+#ifndef GRPC_CORE_TRANSPORT_CHTTP2_FRAME_WINDOW_UPDATE_H
+#define GRPC_CORE_TRANSPORT_CHTTP2_FRAME_WINDOW_UPDATE_H
 
 #include "src/core/iomgr/exec_ctx.h"
 #include <grpc/support/slice.h>
@@ -53,4 +53,4 @@
     grpc_chttp2_transport_parsing *transport_parsing,
     grpc_chttp2_stream_parsing *stream_parsing, gpr_slice slice, int is_last);
 
-#endif /* GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_FRAME_WINDOW_UPDATE_H */
+#endif /* GRPC_CORE_TRANSPORT_CHTTP2_FRAME_WINDOW_UPDATE_H */
diff --git a/src/core/transport/chttp2/hpack_encoder.h b/src/core/transport/chttp2/hpack_encoder.h
index 19b5cb7..90aaf86 100644
--- a/src/core/transport/chttp2/hpack_encoder.h
+++ b/src/core/transport/chttp2/hpack_encoder.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_HPACK_ENCODER_H
-#define GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_HPACK_ENCODER_H
+#ifndef GRPC_CORE_TRANSPORT_CHTTP2_HPACK_ENCODER_H
+#define GRPC_CORE_TRANSPORT_CHTTP2_HPACK_ENCODER_H
 
 #include "src/core/transport/chttp2/frame.h"
 #include "src/core/transport/metadata.h"
@@ -92,4 +92,4 @@
                                grpc_metadata_batch *metadata, int is_eof,
                                gpr_slice_buffer *outbuf);
 
-#endif /* GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_HPACK_ENCODER_H */
+#endif /* GRPC_CORE_TRANSPORT_CHTTP2_HPACK_ENCODER_H */
diff --git a/src/core/transport/chttp2/hpack_parser.h b/src/core/transport/chttp2/hpack_parser.h
index 1ad0c64..6a6d136 100644
--- a/src/core/transport/chttp2/hpack_parser.h
+++ b/src/core/transport/chttp2/hpack_parser.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_HPACK_PARSER_H
-#define GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_HPACK_PARSER_H
+#ifndef GRPC_CORE_TRANSPORT_CHTTP2_HPACK_PARSER_H
+#define GRPC_CORE_TRANSPORT_CHTTP2_HPACK_PARSER_H
 
 #include <stddef.h>
 
@@ -113,4 +113,4 @@
     grpc_chttp2_transport_parsing *transport_parsing,
     grpc_chttp2_stream_parsing *stream_parsing, gpr_slice slice, int is_last);
 
-#endif /* GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_HPACK_PARSER_H */
+#endif /* GRPC_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 e743125..6e1b5e6 100644
--- a/src/core/transport/chttp2/hpack_table.h
+++ b/src/core/transport/chttp2/hpack_table.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_HPACK_TABLE_H
-#define GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_HPACK_TABLE_H
+#ifndef GRPC_CORE_TRANSPORT_CHTTP2_HPACK_TABLE_H
+#define GRPC_CORE_TRANSPORT_CHTTP2_HPACK_TABLE_H
 
 #include "src/core/transport/metadata.h"
 #include <grpc/support/port_platform.h>
@@ -105,4 +105,4 @@
 grpc_chttp2_hptbl_find_result grpc_chttp2_hptbl_find(
     const grpc_chttp2_hptbl *tbl, grpc_mdelem *md);
 
-#endif /* GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_HPACK_TABLE_H */
+#endif /* GRPC_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 a4f309e..4290df3 100644
--- a/src/core/transport/chttp2/http2_errors.h
+++ b/src/core/transport/chttp2/http2_errors.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_HTTP2_ERRORS_H
-#define GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_HTTP2_ERRORS_H
+#ifndef GRPC_CORE_TRANSPORT_CHTTP2_HTTP2_ERRORS_H
+#define GRPC_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_CORE_TRANSPORT_CHTTP2_HTTP2_ERRORS_H */
+#endif /* GRPC_CORE_TRANSPORT_CHTTP2_HTTP2_ERRORS_H */
diff --git a/src/core/transport/chttp2/huffsyms.h b/src/core/transport/chttp2/huffsyms.h
index a3cdba8..9c4f09d 100644
--- a/src/core/transport/chttp2/huffsyms.h
+++ b/src/core/transport/chttp2/huffsyms.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_HUFFSYMS_H
-#define GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_HUFFSYMS_H
+#ifndef GRPC_CORE_TRANSPORT_CHTTP2_HUFFSYMS_H
+#define GRPC_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_CORE_TRANSPORT_CHTTP2_HUFFSYMS_H */
+#endif /* GRPC_CORE_TRANSPORT_CHTTP2_HUFFSYMS_H */
diff --git a/src/core/transport/chttp2/incoming_metadata.h b/src/core/transport/chttp2/incoming_metadata.h
index ea74cfc..52454f3 100644
--- a/src/core/transport/chttp2/incoming_metadata.h
+++ b/src/core/transport/chttp2/incoming_metadata.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_CHTTP2_INCOMING_METADATA_H
-#define GRPC_INTERNAL_CORE_CHTTP2_INCOMING_METADATA_H
+#ifndef GRPC_CORE_TRANSPORT_CHTTP2_INCOMING_METADATA_H
+#define GRPC_CORE_TRANSPORT_CHTTP2_INCOMING_METADATA_H
 
 #include "src/core/transport/transport.h"
 
@@ -57,4 +57,4 @@
 void grpc_chttp2_incoming_metadata_buffer_set_deadline(
     grpc_chttp2_incoming_metadata_buffer *buffer, gpr_timespec deadline);
 
-#endif /* GRPC_INTERNAL_CORE_CHTTP2_INCOMING_METADATA_H */
+#endif /* GRPC_CORE_TRANSPORT_CHTTP2_INCOMING_METADATA_H */
diff --git a/src/core/transport/chttp2/internal.h b/src/core/transport/chttp2/internal.h
index b720d1a..0690cb3 100644
--- a/src/core/transport/chttp2/internal.h
+++ b/src/core/transport/chttp2/internal.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_CHTTP2_INTERNAL_H
-#define GRPC_INTERNAL_CORE_CHTTP2_INTERNAL_H
+#ifndef GRPC_CORE_TRANSPORT_CHTTP2_INTERNAL_H
+#define GRPC_CORE_TRANSPORT_CHTTP2_INTERNAL_H
 
 #include <assert.h>
 #include <stdbool.h>
@@ -777,4 +777,4 @@
 void grpc_chttp2_become_writable(grpc_chttp2_transport_global *transport_global,
                                  grpc_chttp2_stream_global *stream_global);
 
-#endif
+#endif /* GRPC_CORE_TRANSPORT_CHTTP2_INTERNAL_H */
diff --git a/src/core/transport/chttp2/status_conversion.h b/src/core/transport/chttp2/status_conversion.h
index 0ec5b56..c6e066b 100644
--- a/src/core/transport/chttp2/status_conversion.h
+++ b/src/core/transport/chttp2/status_conversion.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_STATUS_CONVERSION_H
-#define GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_STATUS_CONVERSION_H
+#ifndef GRPC_CORE_TRANSPORT_CHTTP2_STATUS_CONVERSION_H
+#define GRPC_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_CORE_TRANSPORT_CHTTP2_STATUS_CONVERSION_H */
+#endif /* GRPC_CORE_TRANSPORT_CHTTP2_STATUS_CONVERSION_H */
diff --git a/src/core/transport/chttp2/stream_map.h b/src/core/transport/chttp2/stream_map.h
index 7a0e45f..957a58a 100644
--- a/src/core/transport/chttp2/stream_map.h
+++ b/src/core/transport/chttp2/stream_map.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_STREAM_MAP_H
-#define GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_STREAM_MAP_H
+#ifndef GRPC_CORE_TRANSPORT_CHTTP2_STREAM_MAP_H
+#define GRPC_CORE_TRANSPORT_CHTTP2_STREAM_MAP_H
 
 #include <grpc/support/port_platform.h>
 
@@ -81,4 +81,4 @@
                                                void *value),
                                      void *user_data);
 
-#endif /* GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_STREAM_MAP_H */
+#endif /* GRPC_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 9d8756e..81bae8e 100644
--- a/src/core/transport/chttp2/timeout_encoding.h
+++ b/src/core/transport/chttp2/timeout_encoding.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_TIMEOUT_ENCODING_H
-#define GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_TIMEOUT_ENCODING_H
+#ifndef GRPC_CORE_TRANSPORT_CHTTP2_TIMEOUT_ENCODING_H
+#define GRPC_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_CORE_TRANSPORT_CHTTP2_TIMEOUT_ENCODING_H */
+#endif /* GRPC_CORE_TRANSPORT_CHTTP2_TIMEOUT_ENCODING_H */
diff --git a/src/core/transport/chttp2/varint.h b/src/core/transport/chttp2/varint.h
index 2d92b66..7ab9d22 100644
--- a/src/core/transport/chttp2/varint.h
+++ b/src/core/transport/chttp2/varint.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_VARINT_H
-#define GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_VARINT_H
+#ifndef GRPC_CORE_TRANSPORT_CHTTP2_VARINT_H
+#define GRPC_CORE_TRANSPORT_CHTTP2_VARINT_H
 
 #include <grpc/support/port_platform.h>
 
@@ -72,4 +72,4 @@
     }                                                                         \
   } while (0)
 
-#endif /* GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_VARINT_H */
+#endif /* GRPC_CORE_TRANSPORT_CHTTP2_VARINT_H */
diff --git a/src/core/transport/chttp2_transport.c b/src/core/transport/chttp2_transport.c
index 03444fd..b16768d 100644
--- a/src/core/transport/chttp2_transport.c
+++ b/src/core/transport/chttp2_transport.c
@@ -1757,8 +1757,9 @@
 }
 
 static const grpc_transport_vtable vtable = {
-    sizeof(grpc_chttp2_stream), init_stream, set_pollset, perform_stream_op,
-    perform_transport_op, destroy_stream, destroy_transport, chttp2_get_peer};
+    sizeof(grpc_chttp2_stream), "chttp2", init_stream, set_pollset,
+    perform_stream_op, perform_transport_op, destroy_stream, destroy_transport,
+    chttp2_get_peer};
 
 grpc_transport *grpc_create_chttp2_transport(
     grpc_exec_ctx *exec_ctx, const grpc_channel_args *channel_args,
diff --git a/src/core/transport/chttp2_transport.h b/src/core/transport/chttp2_transport.h
index 9552050..9a6cf0e 100644
--- a/src/core/transport/chttp2_transport.h
+++ b/src/core/transport/chttp2_transport.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_TRANSPORT_H
-#define GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_TRANSPORT_H
+#ifndef GRPC_CORE_TRANSPORT_CHTTP2_TRANSPORT_H
+#define GRPC_CORE_TRANSPORT_CHTTP2_TRANSPORT_H
 
 #include "src/core/iomgr/endpoint.h"
 #include "src/core/transport/transport.h"
@@ -48,4 +48,4 @@
                                          grpc_transport *transport,
                                          gpr_slice *slices, size_t nslices);
 
-#endif /* GRPC_INTERNAL_CORE_TRANSPORT_CHTTP2_TRANSPORT_H */
+#endif /* GRPC_CORE_TRANSPORT_CHTTP2_TRANSPORT_H */
diff --git a/src/core/transport/connectivity_state.h b/src/core/transport/connectivity_state.h
index a4eb665..b4a3ce9 100644
--- a/src/core/transport/connectivity_state.h
+++ b/src/core/transport/connectivity_state.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_TRANSPORT_CONNECTIVITY_STATE_H
-#define GRPC_INTERNAL_CORE_TRANSPORT_CONNECTIVITY_STATE_H
+#ifndef GRPC_CORE_TRANSPORT_CONNECTIVITY_STATE_H
+#define GRPC_CORE_TRANSPORT_CONNECTIVITY_STATE_H
 
 #include <grpc/grpc.h>
 #include "src/core/iomgr/exec_ctx.h"
@@ -82,4 +82,4 @@
     grpc_exec_ctx *exec_ctx, grpc_connectivity_state_tracker *tracker,
     grpc_connectivity_state *current, grpc_closure *notify);
 
-#endif /* GRPC_INTERNAL_CORE_TRANSPORT_CONNECTIVITY_STATE_H */
+#endif /* GRPC_CORE_TRANSPORT_CONNECTIVITY_STATE_H */
diff --git a/src/core/transport/metadata.h b/src/core/transport/metadata.h
index 8742846..5ab3978 100644
--- a/src/core/transport/metadata.h
+++ b/src/core/transport/metadata.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_TRANSPORT_METADATA_H
-#define GRPC_INTERNAL_CORE_TRANSPORT_METADATA_H
+#ifndef GRPC_CORE_TRANSPORT_METADATA_H
+#define GRPC_CORE_TRANSPORT_METADATA_H
 
 #include <grpc/support/slice.h>
 #include <grpc/support/useful.h>
@@ -153,4 +153,4 @@
 void grpc_mdctx_global_init(void);
 void grpc_mdctx_global_shutdown(void);
 
-#endif /* GRPC_INTERNAL_CORE_TRANSPORT_METADATA_H */
+#endif /* GRPC_CORE_TRANSPORT_METADATA_H */
diff --git a/src/core/transport/metadata_batch.h b/src/core/transport/metadata_batch.h
index 1b0d1fd..9337b28 100644
--- a/src/core/transport/metadata_batch.h
+++ b/src/core/transport/metadata_batch.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_TRANSPORT_STREAM_OP_H
-#define GRPC_INTERNAL_CORE_TRANSPORT_STREAM_OP_H
+#ifndef GRPC_CORE_TRANSPORT_METADATA_BATCH_H
+#define GRPC_CORE_TRANSPORT_METADATA_BATCH_H
 
 #include <grpc/grpc.h>
 #include <grpc/support/port_platform.h>
@@ -122,4 +122,4 @@
   } while (0)
 #endif
 
-#endif /* GRPC_INTERNAL_CORE_TRANSPORT_STREAM_OP_H */
+#endif /* GRPC_CORE_TRANSPORT_METADATA_BATCH_H */
diff --git a/src/core/transport/static_metadata.h b/src/core/transport/static_metadata.h
index ef72b80..85442f8 100644
--- a/src/core/transport/static_metadata.h
+++ b/src/core/transport/static_metadata.h
@@ -43,8 +43,8 @@
  * explanation of what's going on.
  */
 
-#ifndef GRPC_INTERNAL_CORE_TRANSPORT_STATIC_METADATA_H
-#define GRPC_INTERNAL_CORE_TRANSPORT_STATIC_METADATA_H
+#ifndef GRPC_CORE_TRANSPORT_STATIC_METADATA_H
+#define GRPC_CORE_TRANSPORT_STATIC_METADATA_H
 
 #include "src/core/transport/metadata.h"
 
@@ -405,4 +405,4 @@
 extern const uint8_t grpc_static_accept_encoding_metadata[8];
 #define GRPC_MDELEM_ACCEPT_ENCODING_FOR_ALGORITHMS(algs) \
   (&grpc_static_mdelem_table[grpc_static_accept_encoding_metadata[(algs)]])
-#endif /* GRPC_INTERNAL_CORE_TRANSPORT_STATIC_METADATA_H */
+#endif /* GRPC_CORE_TRANSPORT_STATIC_METADATA_H */
diff --git a/src/core/transport/transport.h b/src/core/transport/transport.h
index ed6e121..0f068dc 100644
--- a/src/core/transport/transport.h
+++ b/src/core/transport/transport.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_TRANSPORT_TRANSPORT_H
-#define GRPC_INTERNAL_CORE_TRANSPORT_TRANSPORT_H
+#ifndef GRPC_CORE_TRANSPORT_TRANSPORT_H
+#define GRPC_CORE_TRANSPORT_TRANSPORT_H
 
 #include <stddef.h>
 
@@ -239,4 +239,4 @@
 char *grpc_transport_get_peer(grpc_exec_ctx *exec_ctx,
                               grpc_transport *transport);
 
-#endif /* GRPC_INTERNAL_CORE_TRANSPORT_TRANSPORT_H */
+#endif /* GRPC_CORE_TRANSPORT_TRANSPORT_H */
diff --git a/src/core/transport/transport_impl.h b/src/core/transport/transport_impl.h
index 40bfb4b..d9ecc4d 100644
--- a/src/core/transport/transport_impl.h
+++ b/src/core/transport/transport_impl.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_TRANSPORT_TRANSPORT_IMPL_H
-#define GRPC_INTERNAL_CORE_TRANSPORT_TRANSPORT_IMPL_H
+#ifndef GRPC_CORE_TRANSPORT_TRANSPORT_IMPL_H
+#define GRPC_CORE_TRANSPORT_TRANSPORT_IMPL_H
 
 #include "src/core/transport/transport.h"
 
@@ -41,6 +41,9 @@
      layers and initialized by the transport */
   size_t sizeof_stream; /* = sizeof(transport stream) */
 
+  /* name of this transport implementation */
+  const char *name;
+
   /* implementation of grpc_transport_init_stream */
   int (*init_stream)(grpc_exec_ctx *exec_ctx, grpc_transport *self,
                      grpc_stream *stream, grpc_stream_refcount *refcount,
@@ -75,4 +78,4 @@
   const grpc_transport_vtable *vtable;
 };
 
-#endif /* GRPC_INTERNAL_CORE_TRANSPORT_TRANSPORT_IMPL_H */
+#endif /* GRPC_CORE_TRANSPORT_TRANSPORT_IMPL_H */
diff --git a/src/core/tsi/fake_transport_security.h b/src/core/tsi/fake_transport_security.h
index fe295aa..6b8e596 100644
--- a/src/core/tsi/fake_transport_security.h
+++ b/src/core/tsi/fake_transport_security.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_TSI_FAKE_TRANSPORT_SECURITY_H
-#define GRPC_INTERNAL_CORE_TSI_FAKE_TRANSPORT_SECURITY_H
+#ifndef GRPC_CORE_TSI_FAKE_TRANSPORT_SECURITY_H
+#define GRPC_CORE_TSI_FAKE_TRANSPORT_SECURITY_H
 
 #include "src/core/tsi/transport_security_interface.h"
 
@@ -58,4 +58,4 @@
 }
 #endif
 
-#endif /* GRPC_INTERNAL_CORE_TSI_FAKE_TRANSPORT_SECURITY_H */
+#endif /* GRPC_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 fcbd910..42d25ca 100644
--- a/src/core/tsi/ssl_transport_security.c
+++ b/src/core/tsi/ssl_transport_security.c
@@ -293,6 +293,26 @@
   return result;
 }
 
+/* Gets the X509 cert in PEM format as a tsi_peer_property. */
+static tsi_result add_pem_certificate(X509 *cert, tsi_peer_property *property) {
+  BIO *bio = BIO_new(BIO_s_mem());
+  if (!PEM_write_bio_X509(bio, cert)) {
+    BIO_free(bio);
+    return TSI_INTERNAL_ERROR;
+  }
+  char *contents;
+  long len = BIO_get_mem_data(bio, &contents);
+  if (len <= 0) {
+    BIO_free(bio);
+    return TSI_INTERNAL_ERROR;
+  }
+  tsi_result result = tsi_construct_string_peer_property(
+      TSI_X509_PEM_CERT_PROPERTY, (const char *)contents, (size_t)len,
+      property);
+  BIO_free(bio);
+  return result;
+}
+
 /* Gets the subject SANs from an X509 cert as a tsi_peer_property. */
 static tsi_result add_subject_alt_names_properties_to_peer(
     tsi_peer *peer, GENERAL_NAMES *subject_alt_names,
@@ -363,7 +383,8 @@
   tsi_result result;
   GPR_ASSERT(subject_alt_name_count >= 0);
   property_count = (include_certificate_type ? (size_t)1 : 0) +
-                   1 /* common name */ + (size_t)subject_alt_name_count;
+                   2 /* common name, certificate */ +
+                   (size_t)subject_alt_name_count;
   result = tsi_construct_peer(property_count, peer);
   if (result != TSI_OK) return result;
   do {
@@ -377,6 +398,10 @@
         cert, &peer->properties[include_certificate_type ? 1 : 0]);
     if (result != TSI_OK) break;
 
+    result = add_pem_certificate(
+        cert, &peer->properties[include_certificate_type ? 2 : 1]);
+    if (result != TSI_OK) break;
+
     if (subject_alt_name_count != 0) {
       result = add_subject_alt_names_properties_to_peer(
           peer, subject_alt_names, (size_t)subject_alt_name_count);
diff --git a/src/core/tsi/ssl_transport_security.h b/src/core/tsi/ssl_transport_security.h
index 4909af4..612f5c6 100644
--- a/src/core/tsi/ssl_transport_security.h
+++ b/src/core/tsi/ssl_transport_security.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_TSI_SSL_TRANSPORT_SECURITY_H
-#define GRPC_INTERNAL_CORE_TSI_SSL_TRANSPORT_SECURITY_H
+#ifndef GRPC_CORE_TSI_SSL_TRANSPORT_SECURITY_H
+#define GRPC_CORE_TSI_SSL_TRANSPORT_SECURITY_H
 
 #include "src/core/tsi/transport_security_interface.h"
 
@@ -48,6 +48,8 @@
 #define TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY \
   "x509_subject_alternative_name"
 
+#define TSI_X509_PEM_CERT_PROPERTY "x509_pem_cert"
+
 #define TSI_SSL_ALPN_SELECTED_PROTOCOL "ssl_alpn_selected_protocol"
 
 /* --- tsi_ssl_handshaker_factory object ---
@@ -169,4 +171,4 @@
 }
 #endif
 
-#endif /* GRPC_INTERNAL_CORE_TSI_SSL_TRANSPORT_SECURITY_H */
+#endif /* GRPC_CORE_TSI_SSL_TRANSPORT_SECURITY_H */
diff --git a/src/core/tsi/ssl_types.h b/src/core/tsi/ssl_types.h
index 0d0225e..6ea85fe 100644
--- a/src/core/tsi/ssl_types.h
+++ b/src/core/tsi/ssl_types.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_TSI_SSL_TYPES_H
-#define GRPC_INTERNAL_CORE_TSI_SSL_TYPES_H
+#ifndef GRPC_CORE_TSI_SSL_TYPES_H
+#define GRPC_CORE_TSI_SSL_TYPES_H
 
 /* A collection of macros to cast between various integer types that are
  * used differently between BoringSSL and OpenSSL:
@@ -52,4 +52,4 @@
 #define TSI_SIZE_AS_SIZE(x) ((int)(x))
 #endif
 
-#endif
+#endif /* GRPC_CORE_TSI_SSL_TYPES_H */
diff --git a/src/core/tsi/transport_security.h b/src/core/tsi/transport_security.h
index 4077737..ecc0371 100644
--- a/src/core/tsi/transport_security.h
+++ b/src/core/tsi/transport_security.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_TSI_TRANSPORT_SECURITY_H
-#define GRPC_INTERNAL_CORE_TSI_TRANSPORT_SECURITY_H
+#ifndef GRPC_CORE_TSI_TRANSPORT_SECURITY_H
+#define GRPC_CORE_TSI_TRANSPORT_SECURITY_H
 
 #include "src/core/tsi/transport_security_interface.h"
 
@@ -108,4 +108,4 @@
 }
 #endif
 
-#endif /* GRPC_INTERNAL_CORE_TSI_TRANSPORT_SECURITY_H */
+#endif /* GRPC_CORE_TSI_TRANSPORT_SECURITY_H */
diff --git a/src/core/tsi/transport_security_interface.h b/src/core/tsi/transport_security_interface.h
index 69ee17a..0850180 100644
--- a/src/core/tsi/transport_security_interface.h
+++ b/src/core/tsi/transport_security_interface.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_INTERNAL_CORE_TSI_TRANSPORT_SECURITY_INTERFACE_H
-#define GRPC_INTERNAL_CORE_TSI_TRANSPORT_SECURITY_INTERFACE_H
+#ifndef GRPC_CORE_TSI_TRANSPORT_SECURITY_INTERFACE_H
+#define GRPC_CORE_TSI_TRANSPORT_SECURITY_INTERFACE_H
 
 #include <stdint.h>
 #include <stdlib.h>
@@ -341,4 +341,4 @@
 }
 #endif
 
-#endif /* GRPC_INTERNAL_CORE_TSI_TRANSPORT_SECURITY_INTERFACE_H */
+#endif /* GRPC_CORE_TSI_TRANSPORT_SECURITY_INTERFACE_H */
diff --git a/src/cpp/README.md b/src/cpp/README.md
index 83d37aa..f2935e5 100644
--- a/src/cpp/README.md
+++ b/src/cpp/README.md
@@ -61,7 +61,7 @@
 #Documentation
 
 You can find out how to build and run our simplest gRPC C++ example in our
-[C++ quick start](https://github.com/grpc/grpc/tree/{{ site.data.config.grpc_release_branch }}/examples/cpp).
+[C++ quick start](../../examples/cpp).
 
 For more detailed documentation on using gRPC in C++ , see our main
 documentation site at [grpc.io](http://grpc.io), specifically:
@@ -79,4 +79,4 @@
 # Examples
 
 Code examples for gRPC C++ live in this repository's
-[examples/cpp](https://github.com/grpc/grpc/tree/{{ site.data.config.grpc_release_branch }}/examples/cpp) directory.
+[examples/cpp](../../examples/cpp) directory.
diff --git a/src/cpp/client/secure_credentials.cc b/src/cpp/client/secure_credentials.cc
index 074dae7..c34b840 100644
--- a/src/cpp/client/secure_credentials.cc
+++ b/src/cpp/client/secure_credentials.cc
@@ -60,8 +60,7 @@
 
 SecureCallCredentials::SecureCallCredentials(grpc_call_credentials* c_creds)
     : c_creds_(c_creds) {
-  internal::GrpcLibraryInitializer gli_initializer;
-  gli_initializer.summon();
+  g_gli_initializer.summon();
 }
 
 bool SecureCallCredentials::ApplyToCall(grpc_call* call) {
@@ -83,14 +82,14 @@
 }  // namespace
 
 std::shared_ptr<ChannelCredentials> GoogleDefaultCredentials() {
-  GrpcLibrary init;  // To call grpc_init().
+  GrpcLibraryCodegen init;  // To call grpc_init().
   return WrapChannelCredentials(grpc_google_default_credentials_create());
 }
 
 // Builds SSL Credentials given SSL specific options
 std::shared_ptr<ChannelCredentials> SslCredentials(
     const SslCredentialsOptions& options) {
-  GrpcLibrary init;  // To call grpc_init().
+  GrpcLibraryCodegen init;  // To call grpc_init().
   grpc_ssl_pem_key_cert_pair pem_key_cert_pair = {
       options.pem_private_key.c_str(), options.pem_cert_chain.c_str()};
 
@@ -102,7 +101,7 @@
 
 // Builds credentials for use when running in GCE
 std::shared_ptr<CallCredentials> GoogleComputeEngineCredentials() {
-  GrpcLibrary init;  // To call grpc_init().
+  GrpcLibraryCodegen init;  // To call grpc_init().
   return WrapCallCredentials(
       grpc_google_compute_engine_credentials_create(nullptr));
 }
@@ -110,7 +109,7 @@
 // Builds JWT credentials.
 std::shared_ptr<CallCredentials> ServiceAccountJWTAccessCredentials(
     const grpc::string& json_key, long token_lifetime_seconds) {
-  GrpcLibrary init;  // To call grpc_init().
+  GrpcLibraryCodegen init;  // To call grpc_init().
   if (token_lifetime_seconds <= 0) {
     gpr_log(GPR_ERROR,
             "Trying to create JWTCredentials with non-positive lifetime");
@@ -125,7 +124,7 @@
 // Builds refresh token credentials.
 std::shared_ptr<CallCredentials> GoogleRefreshTokenCredentials(
     const grpc::string& json_refresh_token) {
-  GrpcLibrary init;  // To call grpc_init().
+  GrpcLibraryCodegen init;  // To call grpc_init().
   return WrapCallCredentials(grpc_google_refresh_token_credentials_create(
       json_refresh_token.c_str(), nullptr));
 }
@@ -133,7 +132,7 @@
 // Builds access token credentials.
 std::shared_ptr<CallCredentials> AccessTokenCredentials(
     const grpc::string& access_token) {
-  GrpcLibrary init;  // To call grpc_init().
+  GrpcLibraryCodegen init;  // To call grpc_init().
   return WrapCallCredentials(
       grpc_access_token_credentials_create(access_token.c_str(), nullptr));
 }
@@ -142,7 +141,7 @@
 std::shared_ptr<CallCredentials> GoogleIAMCredentials(
     const grpc::string& authorization_token,
     const grpc::string& authority_selector) {
-  GrpcLibrary init;  // To call grpc_init().
+  GrpcLibraryCodegen init;  // To call grpc_init().
   return WrapCallCredentials(grpc_google_iam_credentials_create(
       authorization_token.c_str(), authority_selector.c_str(), nullptr));
 }
@@ -224,7 +223,7 @@
 
 std::shared_ptr<CallCredentials> MetadataCredentialsFromPlugin(
     std::unique_ptr<MetadataCredentialsPlugin> plugin) {
-  GrpcLibrary init;  // To call grpc_init().
+  GrpcLibraryCodegen init;  // To call grpc_init().
   const char* type = plugin->GetType();
   MetadataCredentialsPluginWrapper* wrapper =
       new MetadataCredentialsPluginWrapper(std::move(plugin));
diff --git a/src/cpp/codegen/grpc_library.cc b/src/cpp/codegen/codegen_init.cc
similarity index 71%
copy from src/cpp/codegen/grpc_library.cc
copy to src/cpp/codegen/codegen_init.cc
index 48acec3..c5d2212 100644
--- a/src/cpp/codegen/grpc_library.cc
+++ b/src/cpp/codegen/codegen_init.cc
@@ -31,10 +31,15 @@
  *
  */
 
+#include <grpc++/impl/codegen/core_codegen_interface.h>
 #include <grpc++/impl/codegen/grpc_library.h>
 
-namespace grpc {
+/// Initializes the global gRPC variables for the codegen library. These will
+/// stay null in the absence of of grpc++ library. In this case, no gRPC
+/// features such as the ability to perform calls will be available. Trying to
+/// perform them would result in a segmentation fault when trying to deference
+/// the following nulled globals. These should be associated with actual
+/// as part of the instantiation of a \a grpc::GrpcLibraryInitializer variable.
 
-GrpcLibraryInterface *g_glip = nullptr;
-
-}  // namespace grpc
+grpc::CoreCodegenInterface* grpc::g_core_codegen_interface = nullptr;
+grpc::GrpcLibraryInterface* grpc::g_glip = nullptr;
diff --git a/src/cpp/common/call.cc b/src/cpp/common/call.cc
deleted file mode 100644
index 5b87c2a..0000000
--- a/src/cpp/common/call.cc
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- *
- * Copyright 2015, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#include <grpc++/impl/call.h>
-
-#include <grpc/support/alloc.h>
-#include <grpc++/channel.h>
-#include <grpc++/client_context.h>
-#include <grpc++/support/byte_buffer.h>
-#include "src/core/profiling/timers.h"
-
-namespace grpc {
-
-void FillMetadataMap(
-    grpc_metadata_array* arr,
-    std::multimap<grpc::string_ref, grpc::string_ref>* metadata) {
-  for (size_t i = 0; i < arr->count; i++) {
-    // TODO(yangg) handle duplicates?
-    metadata->insert(std::pair<grpc::string_ref, grpc::string_ref>(
-        arr->metadata[i].key, grpc::string_ref(arr->metadata[i].value,
-                                               arr->metadata[i].value_length)));
-  }
-  grpc_metadata_array_destroy(arr);
-  grpc_metadata_array_init(arr);
-}
-
-// TODO(yangg) if the map is changed before we send, the pointers will be a
-// mess. Make sure it does not happen.
-grpc_metadata* FillMetadataArray(
-    const std::multimap<grpc::string, grpc::string>& metadata) {
-  if (metadata.empty()) {
-    return nullptr;
-  }
-  grpc_metadata* metadata_array =
-      (grpc_metadata*)gpr_malloc(metadata.size() * sizeof(grpc_metadata));
-  size_t i = 0;
-  for (auto iter = metadata.cbegin(); iter != metadata.cend(); ++iter, ++i) {
-    metadata_array[i].key = iter->first.c_str();
-    metadata_array[i].value = iter->second.c_str();
-    metadata_array[i].value_length = iter->second.size();
-  }
-  return metadata_array;
-}
-
-Call::Call(grpc_call* call, CallHook* call_hook, CompletionQueue* cq)
-    : call_hook_(call_hook), cq_(cq), call_(call), max_message_size_(-1) {}
-
-Call::Call(grpc_call* call, CallHook* call_hook, CompletionQueue* cq,
-           int max_message_size)
-    : call_hook_(call_hook),
-      cq_(cq),
-      call_(call),
-      max_message_size_(max_message_size) {}
-
-void Call::PerformOps(CallOpSetInterface* ops) {
-  if (max_message_size_ > 0) {
-    ops->set_max_message_size(max_message_size_);
-  }
-  call_hook_->PerformOpsOnCall(ops, this);
-}
-
-}  // namespace grpc
diff --git a/src/cpp/common/completion_queue.cc b/src/cpp/common/completion_queue.cc
index 4f76dff..729dc33 100644
--- a/src/cpp/common/completion_queue.cc
+++ b/src/cpp/common/completion_queue.cc
@@ -34,7 +34,6 @@
 
 #include <memory>
 
-#include <grpc++/impl/codegen/completion_queue_tag.h>
 #include <grpc++/impl/grpc_library.h>
 #include <grpc++/support/time.h>
 #include <grpc/grpc.h>
@@ -43,16 +42,13 @@
 namespace grpc {
 
 static internal::GrpcLibraryInitializer g_gli_initializer;
-CompletionQueue::CompletionQueue() {
-  g_gli_initializer.summon();
-  cq_ = grpc_completion_queue_create(nullptr);
-}
 
 CompletionQueue::CompletionQueue(grpc_completion_queue* take) : cq_(take) {}
 
-CompletionQueue::~CompletionQueue() { grpc_completion_queue_destroy(cq_); }
-
-void CompletionQueue::Shutdown() { grpc_completion_queue_shutdown(cq_); }
+void CompletionQueue::Shutdown() {
+  g_gli_initializer.summon();
+  grpc_completion_queue_shutdown(cq_);
+}
 
 CompletionQueue::NextStatus CompletionQueue::AsyncNextInternal(
     void** tag, bool* ok, gpr_timespec deadline) {
@@ -75,25 +71,4 @@
   }
 }
 
-bool CompletionQueue::Pluck(CompletionQueueTag* tag) {
-  auto deadline = gpr_inf_future(GPR_CLOCK_REALTIME);
-  auto ev = grpc_completion_queue_pluck(cq_, tag, deadline, nullptr);
-  bool ok = ev.success != 0;
-  void* ignored = tag;
-  GPR_ASSERT(tag->FinalizeResult(&ignored, &ok));
-  GPR_ASSERT(ignored == tag);
-  // Ignore mutations by FinalizeResult: Pluck returns the C API status
-  return ev.success != 0;
-}
-
-void CompletionQueue::TryPluck(CompletionQueueTag* tag) {
-  auto deadline = gpr_time_0(GPR_CLOCK_REALTIME);
-  auto ev = grpc_completion_queue_pluck(cq_, tag, deadline, nullptr);
-  if (ev.type == GRPC_QUEUE_TIMEOUT) return;
-  bool ok = ev.success != 0;
-  void* ignored = tag;
-  // the tag must be swallowed if using TryPluck
-  GPR_ASSERT(!tag->FinalizeResult(&ignored, &ok));
-}
-
 }  // namespace grpc
diff --git a/src/cpp/proto/proto_utils.cc b/src/cpp/common/core_codegen.cc
similarity index 66%
rename from src/cpp/proto/proto_utils.cc
rename to src/cpp/common/core_codegen.cc
index 79e7bf1..45e9e27 100644
--- a/src/cpp/proto/proto_utils.cc
+++ b/src/cpp/common/core_codegen.cc
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,28 +31,31 @@
  *
  */
 
-#include <grpc++/impl/proto_utils.h>
+#include "src/cpp/common/core_codegen.h"
 
-#include <climits>
+#include <stdlib.h>
 
-#include <grpc/grpc.h>
+#include <grpc++/support/config.h>
 #include <grpc/byte_buffer.h>
 #include <grpc/byte_buffer_reader.h>
-#include <grpc/support/log.h>
+#include <grpc/grpc.h>
+#include <grpc/impl/codegen/alloc.h>
+#include <grpc/impl/codegen/byte_buffer.h>
+#include <grpc/impl/codegen/log.h>
+#include <grpc/support/port_platform.h>
 #include <grpc/support/slice.h>
 #include <grpc/support/slice_buffer.h>
-#include <grpc/support/port_platform.h>
-#include <grpc++/support/config.h>
 
 #include "src/core/profiling/timers.h"
 
-const int kMaxBufferLength = 8192;
+namespace {
+
+const int kGrpcBufferWriterMaxBufferLength = 8192;
 
 class GrpcBufferWriter GRPC_FINAL
     : public ::grpc::protobuf::io::ZeroCopyOutputStream {
  public:
-  explicit GrpcBufferWriter(grpc_byte_buffer** bp,
-                            int block_size = kMaxBufferLength)
+  explicit GrpcBufferWriter(grpc_byte_buffer** bp, int block_size)
       : block_size_(block_size), byte_count_(0), have_backup_(false) {
     *bp = grpc_raw_byte_buffer_create(NULL, 0);
     slice_buffer_ = &(*bp)->data.raw.slice_buffer;
@@ -161,14 +164,56 @@
   grpc_byte_buffer_reader reader_;
   gpr_slice slice_;
 };
+}  // namespace
 
 namespace grpc {
 
-Status SerializeProto(const grpc::protobuf::Message& msg,
-                      grpc_byte_buffer** bp) {
+grpc_completion_queue* CoreCodegen::grpc_completion_queue_create(
+    void* reserved) {
+  return ::grpc_completion_queue_create(reserved);
+}
+
+void CoreCodegen::grpc_completion_queue_destroy(grpc_completion_queue* cq) {
+  ::grpc_completion_queue_destroy(cq);
+}
+
+grpc_event CoreCodegen::grpc_completion_queue_pluck(grpc_completion_queue* cq,
+                                                    void* tag,
+                                                    gpr_timespec deadline,
+                                                    void* reserved) {
+  return ::grpc_completion_queue_pluck(cq, tag, deadline, reserved);
+}
+
+void* CoreCodegen::gpr_malloc(size_t size) { return ::gpr_malloc(size); }
+
+void CoreCodegen::gpr_free(void* p) { return ::gpr_free(p); }
+
+void CoreCodegen::grpc_byte_buffer_destroy(grpc_byte_buffer* bb) {
+  ::grpc_byte_buffer_destroy(bb);
+}
+
+void CoreCodegen::grpc_metadata_array_init(grpc_metadata_array* array) {
+  ::grpc_metadata_array_init(array);
+}
+
+void CoreCodegen::grpc_metadata_array_destroy(grpc_metadata_array* array) {
+  ::grpc_metadata_array_destroy(array);
+}
+
+gpr_timespec CoreCodegen::gpr_inf_future(gpr_clock_type type) {
+  return ::gpr_inf_future(type);
+}
+
+void CoreCodegen::assert_fail(const char* failed_assertion) {
+  gpr_log(GPR_ERROR, "assertion failed: %s", failed_assertion);
+  abort();
+}
+
+Status CoreCodegen::SerializeProto(const grpc::protobuf::Message& msg,
+                                   grpc_byte_buffer** bp) {
   GPR_TIMER_SCOPE("SerializeProto", 0);
   int byte_size = msg.ByteSize();
-  if (byte_size <= kMaxBufferLength) {
+  if (byte_size <= kGrpcBufferWriterMaxBufferLength) {
     gpr_slice slice = gpr_slice_malloc(byte_size);
     GPR_ASSERT(GPR_SLICE_END_PTR(slice) ==
                msg.SerializeWithCachedSizesToArray(GPR_SLICE_START_PTR(slice)));
@@ -176,31 +221,36 @@
     gpr_slice_unref(slice);
     return Status::OK;
   } else {
-    GrpcBufferWriter writer(bp);
+    GrpcBufferWriter writer(bp, kGrpcBufferWriterMaxBufferLength);
     return msg.SerializeToZeroCopyStream(&writer)
                ? Status::OK
                : Status(StatusCode::INTERNAL, "Failed to serialize message");
   }
 }
 
-Status DeserializeProto(grpc_byte_buffer* buffer, grpc::protobuf::Message* msg,
-                        int max_message_size) {
+Status CoreCodegen::DeserializeProto(grpc_byte_buffer* buffer,
+                                     grpc::protobuf::Message* msg,
+                                     int max_message_size) {
   GPR_TIMER_SCOPE("DeserializeProto", 0);
-  if (!buffer) {
+  if (buffer == nullptr) {
     return Status(StatusCode::INTERNAL, "No payload");
   }
-  GrpcBufferReader reader(buffer);
-  ::grpc::protobuf::io::CodedInputStream decoder(&reader);
-  if (max_message_size > 0) {
-    decoder.SetTotalBytesLimit(max_message_size, max_message_size);
+  Status result = Status::OK;
+  {
+    GrpcBufferReader reader(buffer);
+    ::grpc::protobuf::io::CodedInputStream decoder(&reader);
+    if (max_message_size > 0) {
+      decoder.SetTotalBytesLimit(max_message_size, max_message_size);
+    }
+    if (!msg->ParseFromCodedStream(&decoder)) {
+      result = Status(StatusCode::INTERNAL, msg->InitializationErrorString());
+    }
+    if (!decoder.ConsumedEntireMessage()) {
+      result = Status(StatusCode::INTERNAL, "Did not read entire message");
+    }
   }
-  if (!msg->ParseFromCodedStream(&decoder)) {
-    return Status(StatusCode::INTERNAL, msg->InitializationErrorString());
-  }
-  if (!decoder.ConsumedEntireMessage()) {
-    return Status(StatusCode::INTERNAL, "Did not read entire message");
-  }
-  return Status::OK;
+  grpc_byte_buffer_destroy(buffer);
+  return result;
 }
 
 }  // namespace grpc
diff --git a/src/cpp/common/core_codegen.h b/src/cpp/common/core_codegen.h
new file mode 100644
index 0000000..0d8c6b7
--- /dev/null
+++ b/src/cpp/common/core_codegen.h
@@ -0,0 +1,71 @@
+/*
+ *
+ * Copyright 2016, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+// This file should be compiled as part of grpc++.
+
+#include <grpc++/impl/codegen/core_codegen_interface.h>
+#include <grpc/impl/codegen/grpc_types.h>
+#include <grpc/byte_buffer.h>
+
+namespace grpc {
+
+/// Implementation of the core codegen interface.
+class CoreCodegen : public CoreCodegenInterface {
+ private:
+  Status SerializeProto(const grpc::protobuf::Message& msg,
+                        grpc_byte_buffer** bp) override;
+
+  Status DeserializeProto(grpc_byte_buffer* buffer,
+                          grpc::protobuf::Message* msg,
+                          int max_message_size) override;
+
+  grpc_completion_queue* grpc_completion_queue_create(void* reserved) override;
+  void grpc_completion_queue_destroy(grpc_completion_queue* cq) override;
+  grpc_event grpc_completion_queue_pluck(grpc_completion_queue* cq, void* tag,
+                                         gpr_timespec deadline,
+                                         void* reserved) override;
+
+  void* gpr_malloc(size_t size) override;
+  void gpr_free(void* p) override;
+
+  void grpc_byte_buffer_destroy(grpc_byte_buffer* bb) override;
+
+  void grpc_metadata_array_init(grpc_metadata_array* array) override;
+  void grpc_metadata_array_destroy(grpc_metadata_array* array) override;
+
+  gpr_timespec gpr_inf_future(gpr_clock_type type) override;
+
+  void assert_fail(const char* failed_assertion) override;
+};
+
+}  // namespace grpc
diff --git a/src/cpp/server/server_context.cc b/src/cpp/server/server_context.cc
index e205a19..5d12ce2 100644
--- a/src/cpp/server/server_context.cc
+++ b/src/cpp/server/server_context.cc
@@ -43,6 +43,7 @@
 #include <grpc/support/log.h>
 
 #include "src/core/channel/compress_filter.h"
+#include "src/core/surface/call.h"
 #include "src/cpp/common/create_auth_context.h"
 
 namespace grpc {
@@ -62,7 +63,11 @@
   void FillOps(grpc_op* ops, size_t* nops) GRPC_OVERRIDE;
   bool FinalizeResult(void** tag, bool* status) GRPC_OVERRIDE;
 
-  bool CheckCancelled(CompletionQueue* cq);
+  bool CheckCancelled(CompletionQueue* cq) {
+    cq->TryPluck(this);
+    return CheckCancelledNoPluck();
+  }
+  bool CheckCancelledAsync() { return CheckCancelledNoPluck(); }
 
   void set_tag(void* tag) {
     has_tag_ = true;
@@ -72,6 +77,11 @@
   void Unref();
 
  private:
+  bool CheckCancelledNoPluck() {
+    grpc::lock_guard<grpc::mutex> g(mu_);
+    return finalized_ ? (cancelled_ != 0) : false;
+  }
+
   bool has_tag_;
   void* tag_;
   grpc::mutex mu_;
@@ -88,12 +98,6 @@
   }
 }
 
-bool ServerContext::CompletionOp::CheckCancelled(CompletionQueue* cq) {
-  cq->TryPluck(this);
-  grpc::lock_guard<grpc::mutex> g(mu_);
-  return finalized_ ? cancelled_ != 0 : false;
-}
-
 void ServerContext::CompletionOp::FillOps(grpc_op* ops, size_t* nops) {
   ops->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
   ops->data.recv_close_on_server.cancelled = &cancelled_;
@@ -182,12 +186,19 @@
 }
 
 bool ServerContext::IsCancelled() const {
-  return completion_op_ && completion_op_->CheckCancelled(cq_);
+  if (has_notify_when_done_tag_) {
+    // when using async API, but the result is only valid
+    // if the tag has already been delivered at the completion queue
+    return completion_op_ && completion_op_->CheckCancelledAsync();
+  } else {
+    // when using sync API
+    return completion_op_ && completion_op_->CheckCancelled(cq_);
+  }
 }
 
 void ServerContext::set_compression_level(grpc_compression_level level) {
   const grpc_compression_algorithm algorithm_for_level =
-      grpc_compression_algorithm_for_level(level);
+      grpc_call_compression_for_level(call_, level);
   set_compression_algorithm(algorithm_for_level);
 }
 
diff --git a/src/cpp/util/string_ref.cc b/src/cpp/util/string_ref.cc
index 66c79a1..b55019b 100644
--- a/src/cpp/util/string_ref.cc
+++ b/src/cpp/util/string_ref.cc
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -33,72 +33,8 @@
 
 #include <grpc++/support/string_ref.h>
 
-#include <string.h>
-
-#include <algorithm>
-#include <iostream>
-
 namespace grpc {
 
 const size_t string_ref::npos = size_t(-1);
 
-string_ref& string_ref::operator=(const string_ref& rhs) {
-  data_ = rhs.data_;
-  length_ = rhs.length_;
-  return *this;
-}
-
-string_ref::string_ref(const char* s) : data_(s), length_(strlen(s)) {}
-
-string_ref string_ref::substr(size_t pos, size_t n) const {
-  if (pos > length_) pos = length_;
-  if (n > (length_ - pos)) n = length_ - pos;
-  return string_ref(data_ + pos, n);
-}
-
-int string_ref::compare(string_ref x) const {
-  size_t min_size = length_ < x.length_ ? length_ : x.length_;
-  int r = memcmp(data_, x.data_, min_size);
-  if (r < 0) return -1;
-  if (r > 0) return 1;
-  if (length_ < x.length_) return -1;
-  if (length_ > x.length_) return 1;
-  return 0;
-}
-
-bool string_ref::starts_with(string_ref x) const {
-  return length_ >= x.length_ && (memcmp(data_, x.data_, x.length_) == 0);
-}
-
-bool string_ref::ends_with(string_ref x) const {
-  return length_ >= x.length_ &&
-         (memcmp(data_ + (length_ - x.length_), x.data_, x.length_) == 0);
-}
-
-size_t string_ref::find(string_ref s) const {
-  auto it = std::search(cbegin(), cend(), s.cbegin(), s.cend());
-  return it == cend() ? npos : std::distance(cbegin(), it);
-}
-
-size_t string_ref::find(char c) const {
-  auto it = std::find(cbegin(), cend(), c);
-  return it == cend() ? npos : std::distance(cbegin(), it);
-}
-
-bool operator==(string_ref x, string_ref y) { return x.compare(y) == 0; }
-
-bool operator!=(string_ref x, string_ref y) { return x.compare(y) != 0; }
-
-bool operator<(string_ref x, string_ref y) { return x.compare(y) < 0; }
-
-bool operator<=(string_ref x, string_ref y) { return x.compare(y) <= 0; }
-
-bool operator>(string_ref x, string_ref y) { return x.compare(y) > 0; }
-
-bool operator>=(string_ref x, string_ref y) { return x.compare(y) >= 0; }
-
-std::ostream& operator<<(std::ostream& out, const string_ref& string) {
-  return out << grpc::string(string.begin(), string.end());
-}
-
 }  // namespace grpc
diff --git a/src/csharp/Grpc.Core/Internal/NativeExtension.cs b/src/csharp/Grpc.Core/Internal/NativeExtension.cs
index 4c742ab..282816d 100644
--- a/src/csharp/Grpc.Core/Internal/NativeExtension.cs
+++ b/src/csharp/Grpc.Core/Internal/NativeExtension.cs
@@ -32,6 +32,7 @@
 #endregion
 
 using System;
+using System.Globalization;
 using System.IO;
 using System.Reflection;
 
@@ -99,14 +100,30 @@
             // TODO: allow customizing path to native extension (possibly through exposing a GrpcEnvironment property).
 
             var libraryFlavor = string.Format("{0}_{1}", GetPlatformString(), GetArchitectureString());
-            var fullPath = Path.Combine(GetExecutingAssemblyDirectory(),
+            var fullPath = Path.Combine(Path.GetDirectoryName(GetAssemblyPath()),
                 NativeLibrariesDir, libraryFlavor, GetNativeLibraryFilename());
             return new UnmanagedLibrary(fullPath);
         }
 
-        private static string GetExecutingAssemblyDirectory()
+        private static string GetAssemblyPath()
         {
-            return Path.GetDirectoryName(typeof(NativeExtension).GetTypeInfo().Assembly.Location);
+            var assembly = typeof(NativeExtension).GetTypeInfo().Assembly;
+
+            // If assembly is shadowed (e.g. in a webapp), EscapedCodeBase is pointing
+            // to the original location of the assembly, and Location is pointing
+            // to the shadow copy. We care about the original location because
+            // the native dlls don't get shadowed.
+            var escapedCodeBase = assembly.EscapedCodeBase;
+            if (IsFileUri(escapedCodeBase))
+            {
+                return new Uri(escapedCodeBase).LocalPath;
+            }
+            return assembly.Location;
+        }
+
+        private static bool IsFileUri(string uri)
+        {
+            return uri.ToLowerInvariant().StartsWith(Uri.UriSchemeFile);
         }
 
         private static string GetPlatformString()
diff --git a/src/csharp/Grpc.Core/Logging/ConsoleLogger.cs b/src/csharp/Grpc.Core/Logging/ConsoleLogger.cs
index 5c5b802..d41b1b9 100644
--- a/src/csharp/Grpc.Core/Logging/ConsoleLogger.cs
+++ b/src/csharp/Grpc.Core/Logging/ConsoleLogger.cs
@@ -1,6 +1,6 @@
 #region Copyright notice and license
 
-// Copyright 2015, Google Inc.
+// Copyright 2015-2016, Google Inc.
 // All rights reserved.
 //
 // Redistribution and use in source and binary forms, with or without
@@ -33,12 +33,16 @@
 
 using System;
 using System.Collections.Generic;
+using System.Globalization;
 
 namespace Grpc.Core.Logging
 {
     /// <summary>Logger that logs to System.Console.</summary>
     public class ConsoleLogger : ILogger
     {
+        // Format similar enough to C core log format except nanosecond precision is not supported.
+        const string DateTimeFormatString = "MMdd HH:mm:ss.ffffff";
+
         readonly Type forType;
         readonly string forTypeString;
 
@@ -142,7 +146,7 @@
         {
             Console.Error.WriteLine("{0}{1} {2}{3}",
                 severityString,
-                DateTime.Now,
+                DateTime.Now.ToString(DateTimeFormatString, CultureInfo.InvariantCulture),
                 forTypeString,
                 message);
         }
diff --git a/src/csharp/README.md b/src/csharp/README.md
index b4fa945..201c5ab 100644
--- a/src/csharp/README.md
+++ b/src/csharp/README.md
@@ -55,16 +55,11 @@
 
 **Windows**
 
-- The grpc_csharp_ext native library needs to be built so you can build the gRPC C# solution. You can 
-  either build the native solution in `vsprojects/grpc_csharp_ext.sln` from Visual Studio manually, or you can use
-  a convenience batch script that builds everything for you.
+- The grpc_csharp_ext native library needs to be built so you can build the gRPC C# solution. Open the
+  solution `vsprojects/grpc_csharp_ext.sln` in Visual Studio and build it.
 
-  ```
-  > REM From src/csharp directory
-  > buildall.bat
-  ```
-
-- Open Grpc.sln using Visual Studio.
+- Open `src\csharp\Grpc.sln` (path is relative to gRPC repository root)
+  using Visual Studio
 
 **Linux**
 
@@ -79,7 +74,7 @@
 **Mac OS X**
 
 - The grpc_csharp_ext native library needs to be built so you can build the gRPC C# solution.
-  
+
   ```sh
   # from the gRPC repository root
   $ tools/run_tests/run_tests.py -c dbg -l csharp --build_only
diff --git a/src/objective-c/GRPCClient/private/GRPCCompletionQueue.m b/src/objective-c/GRPCClient/private/GRPCCompletionQueue.m
index 250bbf0..be214d4 100644
--- a/src/objective-c/GRPCClient/private/GRPCCompletionQueue.m
+++ b/src/objective-c/GRPCClient/private/GRPCCompletionQueue.m
@@ -41,7 +41,12 @@
 @implementation GRPCCompletionQueue
 
 + (instancetype)completionQueue {
-  return [[self alloc] init];
+  static GRPCCompletionQueue *singleton = nil;
+  static dispatch_once_t onceToken;
+  dispatch_once(&onceToken, ^{
+    singleton = [[self alloc] init];
+  });
+  return singleton;
 }
 
 - (instancetype)init {
diff --git a/src/php/ext/grpc/channel.c b/src/php/ext/grpc/channel.c
index f0bc734..b7e7c26 100644
--- a/src/php/ext/grpc/channel.c
+++ b/src/php/ext/grpc/channel.c
@@ -110,9 +110,11 @@
     switch (Z_TYPE_P(*data)) {
       case IS_LONG:
         args->args[args_index].value.integer = (int)Z_LVAL_P(*data);
+        args->args[args_index].type = GRPC_ARG_INTEGER;
         break;
       case IS_STRING:
         args->args[args_index].value.string = Z_STRVAL_P(*data);
+        args->args[args_index].type = GRPC_ARG_STRING;
         break;
       default:
         zend_throw_exception(spl_ce_InvalidArgumentException,
diff --git a/src/python/grpcio/README.rst b/src/python/grpcio/README.rst
index 3dfae50..33a462b 100644
--- a/src/python/grpcio/README.rst
+++ b/src/python/grpcio/README.rst
@@ -35,13 +35,14 @@
 
 ::
 
-  $ export REPO_ROOT=grpc
+  $ export REPO_ROOT=grpc  # REPO_ROOT can be any directory of your choice
   $ git clone https://github.com/grpc/grpc.git $REPO_ROOT
   $ cd $REPO_ROOT
-  $ pip install .
 
-Note that :code:`$REPO_ROOT` can be assigned to whatever directory name floats
-your fancy.
+  # For the next two commands do `sudo pip install` if you get permission-denied errors
+  $ pip install -rrequirements.txt
+  $ GRPC_PYTHON_BUILD_WITH_CYTHON=1 pip install .
+
 
 Troubleshooting
 ~~~~~~~~~~~~~~~
@@ -49,10 +50,43 @@
 Help, I ...
 
 * **... see a** :code:`pkg_resources.VersionConflict` **when I try to install
-  grpc!**
+  grpc**
 
   This is likely because :code:`pip` doesn't own the offending dependency,
   which in turn is likely because your operating system's package manager owns
   it. You'll need to force the installation of the dependency:
 
   :code:`pip install --ignore-installed $OFFENDING_DEPENDENCY`
+
+  For example, if you get an error like the following:
+
+  ::
+
+    Traceback (most recent call last):
+    File "<string>", line 17, in <module>
+     ...
+    File "/usr/lib/python2.7/dist-packages/pkg_resources.py", line 509, in find
+      raise VersionConflict(dist, req)
+    pkg_resources.VersionConflict: (six 1.8.0 (/usr/lib/python2.7/dist-packages), Requirement.parse('six>=1.10'))
+
+  You can fix it by doing:
+
+  ::
+
+    sudo pip install --ignore-installed six
+
+* **... see the following error on some platforms**
+
+  ::
+
+    /tmp/pip-build-U8pSsr/cython/Cython/Plex/Scanners.c:4:20: fatal error: Python.h: No such file or directory
+    #include "Python.h"
+                    ^
+    compilation terminated.
+
+  You can fix it by installing `python-dev` package. i.e
+
+  ::
+
+    sudo apt-get install python-dev
+
diff --git a/src/python/grpcio/commands.py b/src/python/grpcio/commands.py
index c1f444f..1d43547 100644
--- a/src/python/grpcio/commands.py
+++ b/src/python/grpcio/commands.py
@@ -288,15 +288,9 @@
       sys.exit('Test failure')
 
   def _add_eggs_to_path(self):
-    """Adds all egg files under .eggs to sys.path"""
-    # TODO(jtattemusch): there has to be a cleaner way to do this
-    import pkg_resources
-    eggs_dir = os.path.join(PYTHON_STEM, '../../../.eggs')
-    eggs = [os.path.join(eggs_dir, filename)
-            for filename in os.listdir(eggs_dir)
-            if filename.endswith('.egg')]
-    for egg in eggs:
-      sys.path.insert(0, pkg_resources.normalize_path(egg))
+    """Fetch install and test requirements"""
+    self.distribution.fetch_build_eggs(self.distribution.install_requires)
+    self.distribution.fetch_build_eggs(self.distribution.tests_require)
 
 
 class RunInterop(test.test):
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/call.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/call.pyx.pxi
index 80f4da5..d1b9c98 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/call.pyx.pxi
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/call.pyx.pxi
@@ -1,4 +1,4 @@
-# Copyright 2015, Google Inc.
+# Copyright 2015-2016, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
@@ -40,14 +40,17 @@
   def start_batch(self, operations, tag):
     if not self.is_valid:
       raise ValueError("invalid call object cannot be used from Python")
+    cdef grpc_call_error result
     cdef Operations cy_operations = Operations(operations)
     cdef OperationTag operation_tag = OperationTag(tag)
     operation_tag.operation_call = self
     operation_tag.batch_operations = cy_operations
     cpython.Py_INCREF(operation_tag)
-    return grpc_call_start_batch(
-        self.c_call, cy_operations.c_ops, cy_operations.c_nops,
-        <cpython.PyObject *>operation_tag, NULL)
+    with nogil:
+      result = grpc_call_start_batch(
+          self.c_call, cy_operations.c_ops, cy_operations.c_nops,
+          <cpython.PyObject *>operation_tag, NULL)
+    return result
 
   def cancel(
       self, grpc_status_code error_code=GRPC_STATUS__DO_NOT_USE,
@@ -57,6 +60,8 @@
     if (details is None) != (error_code == GRPC_STATUS__DO_NOT_USE):
       raise ValueError("if error_code is specified, so must details "
                        "(and vice-versa)")
+    cdef grpc_call_error result
+    cdef char *c_details = NULL
     if error_code != GRPC_STATUS__DO_NOT_USE:
       if isinstance(details, bytes):
         pass
@@ -65,25 +70,37 @@
       else:
         raise TypeError("expected details to be str or bytes")
       self.references.append(details)
-      return grpc_call_cancel_with_status(
-          self.c_call, error_code, details, NULL)
+      c_details = details
+      with nogil:
+        result = grpc_call_cancel_with_status(
+            self.c_call, error_code, c_details, NULL)
+      return result
     else:
-      return grpc_call_cancel(self.c_call, NULL)
+      with nogil:
+        result = grpc_call_cancel(self.c_call, NULL)
+      return result
 
   def set_credentials(
       self, CallCredentials call_credentials not None):
-    return grpc_call_set_credentials(
-        self.c_call, call_credentials.c_credentials)
+    cdef grpc_call_error result
+    with nogil:
+      result = grpc_call_set_credentials(
+          self.c_call, call_credentials.c_credentials)
+    return result
 
   def peer(self):
-    cdef char *peer = grpc_call_get_peer(self.c_call)
+    cdef char *peer = NULL
+    with nogil:
+      peer = grpc_call_get_peer(self.c_call)
     result = <bytes>peer
-    gpr_free(peer)
+    with nogil:
+      gpr_free(peer)
     return result
 
   def __dealloc__(self):
     if self.c_call != NULL:
-      grpc_call_destroy(self.c_call)
+      with nogil:
+        grpc_call_destroy(self.c_call)
 
   # The object *should* always be valid from Python. Used for debugging.
   @property
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi
index bc03c4d..d612c90 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi
@@ -35,6 +35,7 @@
   def __cinit__(self, target, ChannelArgs arguments=None,
                 ChannelCredentials channel_credentials=None):
     cdef grpc_channel_args *c_arguments = NULL
+    cdef char *c_target = NULL
     self.c_channel = NULL
     self.references = []
     if arguments is not None:
@@ -45,12 +46,15 @@
       target = target.encode()
     else:
       raise TypeError("expected target to be str or bytes")
+    c_target = target
     if channel_credentials is None:
-      self.c_channel = grpc_insecure_channel_create(target, c_arguments,
-                                                         NULL)
+      with nogil:
+        self.c_channel = grpc_insecure_channel_create(c_target, c_arguments,
+                                                      NULL)
     else:
-      self.c_channel = grpc_secure_channel_create(
-          channel_credentials.c_credentials, target, c_arguments, NULL)
+      with nogil:
+        self.c_channel = grpc_secure_channel_create(
+            channel_credentials.c_credentials, c_target, c_arguments, NULL)
       self.references.append(channel_credentials)
     self.references.append(target)
     self.references.append(arguments)
@@ -66,6 +70,7 @@
       method = method.encode()
     else:
       raise TypeError("expected method to be str or bytes")
+    cdef char *method_c_string = method
     cdef char *host_c_string = NULL
     if host is None:
       pass
@@ -81,31 +86,40 @@
     cdef grpc_call *parent_call = NULL
     if parent is not None:
       parent_call = parent.c_call
-    operation_call.c_call = grpc_channel_create_call(
-        self.c_channel, parent_call, flags,
-        queue.c_completion_queue, method, host_c_string, deadline.c_time,
-        NULL)
+    with nogil:
+      operation_call.c_call = grpc_channel_create_call(
+          self.c_channel, parent_call, flags,
+          queue.c_completion_queue, method_c_string, host_c_string,
+          deadline.c_time, NULL)
     return operation_call
 
   def check_connectivity_state(self, bint try_to_connect):
-    return grpc_channel_check_connectivity_state(self.c_channel,
-                                                 try_to_connect)
+    cdef grpc_connectivity_state result
+    with nogil:
+      result = grpc_channel_check_connectivity_state(self.c_channel,
+                                                     try_to_connect)
+    return result
 
   def watch_connectivity_state(
       self, grpc_connectivity_state last_observed_state,
       Timespec deadline not None, CompletionQueue queue not None, tag):
     cdef OperationTag operation_tag = OperationTag(tag)
     cpython.Py_INCREF(operation_tag)
-    grpc_channel_watch_connectivity_state(
-        self.c_channel, last_observed_state, deadline.c_time,
-        queue.c_completion_queue, <cpython.PyObject *>operation_tag)
+    with nogil:
+      grpc_channel_watch_connectivity_state(
+          self.c_channel, last_observed_state, deadline.c_time,
+          queue.c_completion_queue, <cpython.PyObject *>operation_tag)
 
   def target(self):
-    cdef char * target = grpc_channel_get_target(self.c_channel)
+    cdef char *target = NULL
+    with nogil:
+      target = grpc_channel_get_target(self.c_channel)
     result = <bytes>target
-    gpr_free(target)
+    with nogil:
+      gpr_free(target)
     return result
 
   def __dealloc__(self):
     if self.c_channel != NULL:
-      grpc_channel_destroy(self.c_channel)
+      with nogil:
+        grpc_channel_destroy(self.c_channel)
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pyx.pxi
index e11138b..09e47d4 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pyx.pxi
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/completion_queue.pyx.pxi
@@ -36,7 +36,8 @@
 cdef class CompletionQueue:
 
   def __cinit__(self):
-    self.c_completion_queue = grpc_completion_queue_create(NULL)
+    with nogil:
+      self.c_completion_queue = grpc_completion_queue_create(NULL)
     self.is_shutting_down = False
     self.is_shutdown = False
     self.pluck_condition = threading.Condition()
@@ -82,8 +83,9 @@
   def poll(self, Timespec deadline=None):
     # We name this 'poll' to avoid problems with CPython's expectations for
     # 'special' methods (like next and __next__).
-    cdef gpr_timespec c_deadline = gpr_inf_future(
-        GPR_CLOCK_REALTIME)
+    cdef gpr_timespec c_deadline
+    with nogil:
+      c_deadline = gpr_inf_future(GPR_CLOCK_REALTIME)
     if deadline is not None:
       c_deadline = deadline.c_time
     cdef grpc_event event
@@ -123,7 +125,8 @@
     return self._interpret_event(event)
 
   def shutdown(self):
-    grpc_completion_queue_shutdown(self.c_completion_queue)
+    with nogil:
+      grpc_completion_queue_shutdown(self.c_completion_queue)
     self.is_shutting_down = True
 
   def clear(self):
@@ -133,15 +136,19 @@
       pass
 
   def __dealloc__(self):
-    cdef gpr_timespec c_deadline = gpr_inf_future(GPR_CLOCK_REALTIME)
+    cdef gpr_timespec c_deadline
+    with nogil:
+      c_deadline = gpr_inf_future(GPR_CLOCK_REALTIME)
     if self.c_completion_queue != NULL:
       # Ensure shutdown
       if not self.is_shutting_down:
-        grpc_completion_queue_shutdown(self.c_completion_queue)
+        with nogil:
+          grpc_completion_queue_shutdown(self.c_completion_queue)
       # Pump the queue
       while not self.is_shutdown:
         with nogil:
           event = grpc_completion_queue_next(
               self.c_completion_queue, c_deadline, NULL)
         self._interpret_event(event)
-      grpc_completion_queue_destroy(self.c_completion_queue)
+      with nogil:
+        grpc_completion_queue_destroy(self.c_completion_queue)
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi
index 3f439c8..1d7adca 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi
@@ -1,4 +1,4 @@
-# Copyright 2015, Google Inc.
+# Copyright 2015-2016, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
@@ -46,7 +46,8 @@
 
   def __dealloc__(self):
     if self.c_credentials != NULL:
-      grpc_channel_credentials_release(self.c_credentials)
+      with nogil:
+        grpc_channel_credentials_release(self.c_credentials)
 
 
 cdef class CallCredentials:
@@ -63,7 +64,8 @@
 
   def __dealloc__(self):
     if self.c_credentials != NULL:
-      grpc_call_credentials_release(self.c_credentials)
+      with nogil:
+        grpc_call_credentials_release(self.c_credentials)
 
 
 cdef class ServerCredentials:
@@ -74,7 +76,8 @@
 
   def __dealloc__(self):
     if self.c_credentials != NULL:
-      grpc_server_credentials_release(self.c_credentials)
+      with nogil:
+        grpc_server_credentials_release(self.c_credentials)
 
 
 cdef class CredentialsMetadataPlugin:
@@ -139,7 +142,8 @@
 
 def channel_credentials_google_default():
   cdef ChannelCredentials credentials = ChannelCredentials();
-  credentials.c_credentials = grpc_google_default_credentials_create()
+  with nogil:
+    credentials.c_credentials = grpc_google_default_credentials_create()
   return credentials
 
 def channel_credentials_ssl(pem_root_certificates,
@@ -158,12 +162,14 @@
     c_pem_root_certificates = pem_root_certificates
     credentials.references.append(pem_root_certificates)
   if ssl_pem_key_cert_pair is not None:
-    credentials.c_credentials = grpc_ssl_credentials_create(
-        c_pem_root_certificates, &ssl_pem_key_cert_pair.c_pair, NULL)
+    with nogil:
+      credentials.c_credentials = grpc_ssl_credentials_create(
+          c_pem_root_certificates, &ssl_pem_key_cert_pair.c_pair, NULL)
     credentials.references.append(ssl_pem_key_cert_pair)
   else:
-    credentials.c_credentials = grpc_ssl_credentials_create(
-      c_pem_root_certificates, NULL, NULL)
+    with nogil:
+      credentials.c_credentials = grpc_ssl_credentials_create(
+        c_pem_root_certificates, NULL, NULL)
   return credentials
 
 def channel_credentials_composite(
@@ -172,8 +178,9 @@
   if not credentials_1.is_valid or not credentials_2.is_valid:
     raise ValueError("passed credentials must both be valid")
   cdef ChannelCredentials credentials = ChannelCredentials()
-  credentials.c_credentials = grpc_composite_channel_credentials_create(
-      credentials_1.c_credentials, credentials_2.c_credentials, NULL)
+  with nogil:
+    credentials.c_credentials = grpc_composite_channel_credentials_create(
+        credentials_1.c_credentials, credentials_2.c_credentials, NULL)
   credentials.references.append(credentials_1)
   credentials.references.append(credentials_2)
   return credentials
@@ -184,16 +191,18 @@
   if not credentials_1.is_valid or not credentials_2.is_valid:
     raise ValueError("passed credentials must both be valid")
   cdef CallCredentials credentials = CallCredentials()
-  credentials.c_credentials = grpc_composite_call_credentials_create(
-      credentials_1.c_credentials, credentials_2.c_credentials, NULL)
+  with nogil:
+    credentials.c_credentials = grpc_composite_call_credentials_create(
+        credentials_1.c_credentials, credentials_2.c_credentials, NULL)
   credentials.references.append(credentials_1)
   credentials.references.append(credentials_2)
   return credentials
 
 def call_credentials_google_compute_engine():
   cdef CallCredentials credentials = CallCredentials()
-  credentials.c_credentials = (
-      grpc_google_compute_engine_credentials_create(NULL))
+  with nogil:
+    credentials.c_credentials = (
+        grpc_google_compute_engine_credentials_create(NULL))
   return credentials
 
 def call_credentials_service_account_jwt_access(
@@ -205,9 +214,11 @@
   else:
     raise TypeError("expected json_key to be str or bytes")
   cdef CallCredentials credentials = CallCredentials()
-  credentials.c_credentials = (
-      grpc_service_account_jwt_access_credentials_create(
-          json_key, token_lifetime.c_time, NULL))
+  cdef char *json_key_c_string = json_key
+  with nogil:
+    credentials.c_credentials = (
+        grpc_service_account_jwt_access_credentials_create(
+            json_key_c_string, token_lifetime.c_time, NULL))
   credentials.references.append(json_key)
   return credentials
 
@@ -219,8 +230,10 @@
   else:
     raise TypeError("expected json_refresh_token to be str or bytes")
   cdef CallCredentials credentials = CallCredentials()
-  credentials.c_credentials = grpc_google_refresh_token_credentials_create(
-      json_refresh_token, NULL)
+  cdef char *json_refresh_token_c_string = json_refresh_token
+  with nogil:
+    credentials.c_credentials = grpc_google_refresh_token_credentials_create(
+        json_refresh_token_c_string, NULL)
   credentials.references.append(json_refresh_token)
   return credentials
 
@@ -238,17 +251,21 @@
   else:
     raise TypeError("expected authority_selector to be str or bytes")
   cdef CallCredentials credentials = CallCredentials()
-  credentials.c_credentials = grpc_google_iam_credentials_create(
-      authorization_token, authority_selector, NULL)
+  cdef char *authorization_token_c_string = authorization_token
+  cdef char *authority_selector_c_string = authority_selector
+  with nogil:
+    credentials.c_credentials = grpc_google_iam_credentials_create(
+        authorization_token_c_string, authority_selector_c_string, NULL)
   credentials.references.append(authorization_token)
   credentials.references.append(authority_selector)
   return credentials
 
 def call_credentials_metadata_plugin(CredentialsMetadataPlugin plugin):
   cdef CallCredentials credentials = CallCredentials()
-  credentials.c_credentials = (
-      grpc_metadata_credentials_create_from_plugin(plugin.make_c_plugin(),
-                                                        NULL))
+  cdef grpc_metadata_credentials_plugin c_plugin = plugin.make_c_plugin()
+  with nogil:
+    credentials.c_credentials = (
+        grpc_metadata_credentials_create_from_plugin(c_plugin, NULL))
   # TODO(atash): the following held reference is *probably* never necessary
   credentials.references.append(plugin)
   return credentials
@@ -274,11 +291,12 @@
   credentials.references.append(pem_key_cert_pairs)
   credentials.references.append(pem_root_certs)
   credentials.c_ssl_pem_key_cert_pairs_count = len(pem_key_cert_pairs)
-  credentials.c_ssl_pem_key_cert_pairs = (
-      <grpc_ssl_pem_key_cert_pair *>gpr_malloc(
-          sizeof(grpc_ssl_pem_key_cert_pair) *
-              credentials.c_ssl_pem_key_cert_pairs_count
-      ))
+  with nogil:
+    credentials.c_ssl_pem_key_cert_pairs = (
+        <grpc_ssl_pem_key_cert_pair *>gpr_malloc(
+            sizeof(grpc_ssl_pem_key_cert_pair) *
+                credentials.c_ssl_pem_key_cert_pairs_count
+        ))
   for i in range(credentials.c_ssl_pem_key_cert_pairs_count):
     credentials.c_ssl_pem_key_cert_pairs[i] = (
         (<SslPemKeyCertPair>pem_key_cert_pairs[i]).c_pair)
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi
index dbf0045..61165cb 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi
@@ -38,27 +38,27 @@
 
   int pygrpc_load_core(char*)
 
-  void *gpr_malloc(size_t size)
-  void gpr_free(void *ptr)
-  void *gpr_realloc(void *p, size_t size)
+  void *gpr_malloc(size_t size) nogil
+  void gpr_free(void *ptr) nogil
+  void *gpr_realloc(void *p, size_t size) nogil
 
   ctypedef struct gpr_slice:
     # don't worry about writing out the members of gpr_slice; we never access
     # them directly.
     pass
 
-  gpr_slice gpr_slice_ref(gpr_slice s)
-  void gpr_slice_unref(gpr_slice s)
-  gpr_slice gpr_slice_new(void *p, size_t len, void (*destroy)(void *))
+  gpr_slice gpr_slice_ref(gpr_slice s) nogil
+  void gpr_slice_unref(gpr_slice s) nogil
+  gpr_slice gpr_slice_new(void *p, size_t len, void (*destroy)(void *)) nogil
   gpr_slice gpr_slice_new_with_len(
-      void *p, size_t len, void (*destroy)(void *, size_t))
-  gpr_slice gpr_slice_malloc(size_t length)
-  gpr_slice gpr_slice_from_copied_string(const char *source)
-  gpr_slice gpr_slice_from_copied_buffer(const char *source, size_t len)
+      void *p, size_t len, void (*destroy)(void *, size_t)) nogil
+  gpr_slice gpr_slice_malloc(size_t length) nogil
+  gpr_slice gpr_slice_from_copied_string(const char *source) nogil
+  gpr_slice gpr_slice_from_copied_buffer(const char *source, size_t len) nogil
 
   # Declare functions for function-like macros (because Cython)...
-  void *gpr_slice_start_ptr "GPR_SLICE_START_PTR" (gpr_slice s)
-  size_t gpr_slice_length "GPR_SLICE_LENGTH" (gpr_slice s)
+  void *gpr_slice_start_ptr "GPR_SLICE_START_PTR" (gpr_slice s) nogil
+  size_t gpr_slice_length "GPR_SLICE_LENGTH" (gpr_slice s) nogil
 
   ctypedef enum gpr_clock_type:
     GPR_CLOCK_MONOTONIC
@@ -71,14 +71,14 @@
     int32_t nanoseconds "tv_nsec"
     gpr_clock_type clock_type
 
-  gpr_timespec gpr_time_0(gpr_clock_type type)
-  gpr_timespec gpr_inf_future(gpr_clock_type type)
-  gpr_timespec gpr_inf_past(gpr_clock_type type)
+  gpr_timespec gpr_time_0(gpr_clock_type type) nogil
+  gpr_timespec gpr_inf_future(gpr_clock_type type) nogil
+  gpr_timespec gpr_inf_past(gpr_clock_type type) nogil
 
-  gpr_timespec gpr_now(gpr_clock_type clock)
+  gpr_timespec gpr_now(gpr_clock_type clock) nogil
 
   gpr_timespec gpr_convert_clock_type(gpr_timespec t,
-                                      gpr_clock_type target_clock)
+                                      gpr_clock_type target_clock) nogil
 
   ctypedef enum grpc_status_code:
     GRPC_STATUS_OK
@@ -114,15 +114,15 @@
     pass
 
   grpc_byte_buffer *grpc_raw_byte_buffer_create(gpr_slice *slices,
-                                                size_t nslices)
-  size_t grpc_byte_buffer_length(grpc_byte_buffer *bb)
-  void grpc_byte_buffer_destroy(grpc_byte_buffer *byte_buffer)
+                                                size_t nslices) nogil
+  size_t grpc_byte_buffer_length(grpc_byte_buffer *bb) nogil
+  void grpc_byte_buffer_destroy(grpc_byte_buffer *byte_buffer) nogil
 
   void grpc_byte_buffer_reader_init(grpc_byte_buffer_reader *reader,
-                                    grpc_byte_buffer *buffer)
+                                    grpc_byte_buffer *buffer) nogil
   int grpc_byte_buffer_reader_next(grpc_byte_buffer_reader *reader,
-                                   gpr_slice *slice)
-  void grpc_byte_buffer_reader_destroy(grpc_byte_buffer_reader *reader)
+                                   gpr_slice *slice) nogil
+  void grpc_byte_buffer_reader_destroy(grpc_byte_buffer_reader *reader) nogil
 
   const char *GRPC_ARG_PRIMARY_USER_AGENT_STRING
   const char *GRPC_ARG_ENABLE_CENSUS
@@ -221,8 +221,8 @@
     size_t capacity
     grpc_metadata *metadata
 
-  void grpc_metadata_array_init(grpc_metadata_array *array)
-  void grpc_metadata_array_destroy(grpc_metadata_array *array)
+  void grpc_metadata_array_init(grpc_metadata_array *array) nogil
+  void grpc_metadata_array_destroy(grpc_metadata_array *array) nogil
 
   ctypedef struct grpc_call_details:
     char *method
@@ -231,8 +231,8 @@
     size_t host_capacity
     gpr_timespec deadline
 
-  void grpc_call_details_init(grpc_call_details *details)
-  void grpc_call_details_destroy(grpc_call_details *details)
+  void grpc_call_details_init(grpc_call_details *details) nogil
+  void grpc_call_details_destroy(grpc_call_details *details) nogil
 
   ctypedef enum grpc_op_type:
     GRPC_OP_SEND_INITIAL_METADATA
@@ -277,61 +277,62 @@
     uint32_t flags
     grpc_op_data data
 
-  void grpc_init()
-  void grpc_shutdown()
+  void grpc_init() nogil
+  void grpc_shutdown() nogil
 
-  grpc_completion_queue *grpc_completion_queue_create(void *reserved)
+  grpc_completion_queue *grpc_completion_queue_create(void *reserved) nogil
   grpc_event grpc_completion_queue_next(grpc_completion_queue *cq,
                                         gpr_timespec deadline,
                                         void *reserved) nogil
   grpc_event grpc_completion_queue_pluck(grpc_completion_queue *cq, void *tag,
                                          gpr_timespec deadline,
                                          void *reserved) nogil
-  void grpc_completion_queue_shutdown(grpc_completion_queue *cq)
-  void grpc_completion_queue_destroy(grpc_completion_queue *cq)
+  void grpc_completion_queue_shutdown(grpc_completion_queue *cq) nogil
+  void grpc_completion_queue_destroy(grpc_completion_queue *cq) nogil
 
-  grpc_call_error grpc_call_start_batch(grpc_call *call, const grpc_op *ops,
-                                        size_t nops, void *tag, void *reserved)
-  grpc_call_error grpc_call_cancel(grpc_call *call, void *reserved)
+  grpc_call_error grpc_call_start_batch(
+      grpc_call *call, const grpc_op *ops, size_t nops, void *tag,
+      void *reserved) nogil
+  grpc_call_error grpc_call_cancel(grpc_call *call, void *reserved) nogil
   grpc_call_error grpc_call_cancel_with_status(grpc_call *call,
                                                grpc_status_code status,
                                                const char *description,
-                                               void *reserved)
-  char *grpc_call_get_peer(grpc_call *call)
-  void grpc_call_destroy(grpc_call *call)
+                                               void *reserved) nogil
+  char *grpc_call_get_peer(grpc_call *call) nogil
+  void grpc_call_destroy(grpc_call *call) nogil
 
   grpc_channel *grpc_insecure_channel_create(const char *target,
                                              const grpc_channel_args *args,
-                                             void *reserved)
-  grpc_call *grpc_channel_create_call(grpc_channel *channel,
-                                      grpc_call *parent_call,
-                                      uint32_t propagation_mask,
-                                      grpc_completion_queue *completion_queue,
-                                      const char *method, const char *host,
-                                      gpr_timespec deadline, void *reserved)
+                                             void *reserved) nogil
+  grpc_call *grpc_channel_create_call(
+      grpc_channel *channel, grpc_call *parent_call, uint32_t propagation_mask,
+      grpc_completion_queue *completion_queue, const char *method,
+      const char *host, gpr_timespec deadline, void *reserved) nogil
   grpc_connectivity_state grpc_channel_check_connectivity_state(
-      grpc_channel *channel, int try_to_connect)
+      grpc_channel *channel, int try_to_connect) nogil
   void grpc_channel_watch_connectivity_state(
       grpc_channel *channel, grpc_connectivity_state last_observed_state,
-      gpr_timespec deadline, grpc_completion_queue *cq, void *tag)
-  char *grpc_channel_get_target(grpc_channel *channel)
-  void grpc_channel_destroy(grpc_channel *channel)
+      gpr_timespec deadline, grpc_completion_queue *cq, void *tag) nogil
+  char *grpc_channel_get_target(grpc_channel *channel) nogil
+  void grpc_channel_destroy(grpc_channel *channel) nogil
 
-  grpc_server *grpc_server_create(const grpc_channel_args *args, void *reserved)
+  grpc_server *grpc_server_create(
+      const grpc_channel_args *args, void *reserved) nogil
   grpc_call_error grpc_server_request_call(
       grpc_server *server, grpc_call **call, grpc_call_details *details,
       grpc_metadata_array *request_metadata, grpc_completion_queue
       *cq_bound_to_call, grpc_completion_queue *cq_for_notification, void
-      *tag_new)
+      *tag_new) nogil
   void grpc_server_register_completion_queue(grpc_server *server,
                                              grpc_completion_queue *cq,
-                                             void *reserved)
-  int grpc_server_add_insecure_http2_port(grpc_server *server, const char *addr)
-  void grpc_server_start(grpc_server *server)
+                                             void *reserved) nogil
+  int grpc_server_add_insecure_http2_port(
+      grpc_server *server, const char *addr) nogil
+  void grpc_server_start(grpc_server *server) nogil
   void grpc_server_shutdown_and_notify(
-      grpc_server *server, grpc_completion_queue *cq, void *tag)
-  void grpc_server_cancel_all_calls(grpc_server *server)
-  void grpc_server_destroy(grpc_server *server)
+      grpc_server *server, grpc_completion_queue *cq, void *tag) nogil
+  void grpc_server_cancel_all_calls(grpc_server *server) nogil
+  void grpc_server_destroy(grpc_server *server) nogil
 
   ctypedef struct grpc_ssl_pem_key_cert_pair:
     const char *private_key
@@ -347,35 +348,36 @@
 
   ctypedef void (*grpc_ssl_roots_override_callback)(char **pem_root_certs)
 
-  void grpc_set_ssl_roots_override_callback(grpc_ssl_roots_override_callback cb)
+  void grpc_set_ssl_roots_override_callback(
+      grpc_ssl_roots_override_callback cb) nogil
 
-  grpc_channel_credentials *grpc_google_default_credentials_create()
+  grpc_channel_credentials *grpc_google_default_credentials_create() nogil
   grpc_channel_credentials *grpc_ssl_credentials_create(
       const char *pem_root_certs, grpc_ssl_pem_key_cert_pair *pem_key_cert_pair,
-      void *reserved)
+      void *reserved) nogil
   grpc_channel_credentials *grpc_composite_channel_credentials_create(
       grpc_channel_credentials *creds1, grpc_call_credentials *creds2,
-      void *reserved)
-  void grpc_channel_credentials_release(grpc_channel_credentials *creds)
+      void *reserved) nogil
+  void grpc_channel_credentials_release(grpc_channel_credentials *creds) nogil
 
   grpc_call_credentials *grpc_composite_call_credentials_create(
       grpc_call_credentials *creds1, grpc_call_credentials *creds2,
-      void *reserved)
+      void *reserved) nogil
   grpc_call_credentials *grpc_google_compute_engine_credentials_create(
-      void *reserved)
+      void *reserved) nogil
   grpc_call_credentials *grpc_service_account_jwt_access_credentials_create(
       const char *json_key,
-      gpr_timespec token_lifetime, void *reserved)
+      gpr_timespec token_lifetime, void *reserved) nogil
   grpc_call_credentials *grpc_google_refresh_token_credentials_create(
-      const char *json_refresh_token, void *reserved)
+      const char *json_refresh_token, void *reserved) nogil
   grpc_call_credentials *grpc_google_iam_credentials_create(
       const char *authorization_token, const char *authority_selector,
-      void *reserved)
-  void grpc_call_credentials_release(grpc_call_credentials *creds)
+      void *reserved) nogil
+  void grpc_call_credentials_release(grpc_call_credentials *creds) nogil
 
   grpc_channel *grpc_secure_channel_create(
       grpc_channel_credentials *creds, const char *target,
-      const grpc_channel_args *args, void *reserved)
+      const grpc_channel_args *args, void *reserved) nogil
 
   ctypedef struct grpc_server_credentials:
     # We don't care about the internals (and in fact don't know them)
@@ -385,13 +387,13 @@
       const char *pem_root_certs,
       grpc_ssl_pem_key_cert_pair *pem_key_cert_pairs,
       size_t num_key_cert_pairs, int force_client_auth, void *reserved)
-  void grpc_server_credentials_release(grpc_server_credentials *creds)
+  void grpc_server_credentials_release(grpc_server_credentials *creds) nogil
 
   int grpc_server_add_secure_http2_port(grpc_server *server, const char *addr,
-                                        grpc_server_credentials *creds)
+                                        grpc_server_credentials *creds) nogil
 
   grpc_call_error grpc_call_set_credentials(grpc_call *call,
-                                            grpc_call_credentials *creds)
+                                            grpc_call_credentials *creds) nogil
 
   ctypedef struct grpc_auth_context:
     # We don't care about the internals (and in fact don't know them)
@@ -415,4 +417,4 @@
     const char *type
 
   grpc_call_credentials *grpc_metadata_credentials_create_from_plugin(
-      grpc_metadata_credentials_plugin plugin, void *reserved)
+      grpc_metadata_credentials_plugin plugin, void *reserved) nogil
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/records.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/records.pyx.pxi
index fa4ea99..851389a 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/records.pyx.pxi
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/records.pyx.pxi
@@ -107,15 +107,18 @@
 
   def __cinit__(self, time):
     if time is None:
-      self.c_time = gpr_now(GPR_CLOCK_REALTIME)
+      with nogil:
+        self.c_time = gpr_now(GPR_CLOCK_REALTIME)
       return
     if isinstance(time, int):
       time = float(time)
     if isinstance(time, float):
       if time == float("+inf"):
-        self.c_time = gpr_inf_future(GPR_CLOCK_REALTIME)
+        with nogil:
+          self.c_time = gpr_inf_future(GPR_CLOCK_REALTIME)
       elif time == float("-inf"):
-        self.c_time = gpr_inf_past(GPR_CLOCK_REALTIME)
+        with nogil:
+          self.c_time = gpr_inf_past(GPR_CLOCK_REALTIME)
       else:
         self.c_time.seconds = time
         self.c_time.nanoseconds = (time - float(self.c_time.seconds)) * 1e9
@@ -131,8 +134,10 @@
     # TODO(atash) ensure that everywhere a Timespec is created that it's
     # converted to GPR_CLOCK_REALTIME then and not every time someone wants to
     # read values off in Python.
-    cdef gpr_timespec real_time = (
-        gpr_convert_clock_type(self.c_time, GPR_CLOCK_REALTIME))
+    cdef gpr_timespec real_time
+    with nogil:
+      real_time = (
+          gpr_convert_clock_type(self.c_time, GPR_CLOCK_REALTIME))
     return real_time.seconds
 
   @property
@@ -158,10 +163,12 @@
 cdef class CallDetails:
 
   def __cinit__(self):
-    grpc_call_details_init(&self.c_details)
+    with nogil:
+      grpc_call_details_init(&self.c_details)
 
   def __dealloc__(self):
-    grpc_call_details_destroy(&self.c_details)
+    with nogil:
+      grpc_call_details_destroy(&self.c_details)
 
   @property
   def method(self):
@@ -229,10 +236,15 @@
                       "ByteBuffer, not {}".format(type(data)))
 
     cdef char *c_data = data
-    data_slice = gpr_slice_from_copied_buffer(c_data, len(data))
-    self.c_byte_buffer = grpc_raw_byte_buffer_create(
-        &data_slice, 1)
-    gpr_slice_unref(data_slice)
+    cdef gpr_slice data_slice
+    cdef size_t data_length = len(data)
+    with nogil:
+      data_slice = gpr_slice_from_copied_buffer(c_data, data_length)
+    with nogil:
+      self.c_byte_buffer = grpc_raw_byte_buffer_create(
+          &data_slice, 1)
+    with nogil:
+      gpr_slice_unref(data_slice)
 
   def bytes(self):
     cdef grpc_byte_buffer_reader reader
@@ -240,20 +252,27 @@
     cdef size_t data_slice_length
     cdef void *data_slice_pointer
     if self.c_byte_buffer != NULL:
-      grpc_byte_buffer_reader_init(&reader, self.c_byte_buffer)
+      with nogil:
+        grpc_byte_buffer_reader_init(&reader, self.c_byte_buffer)
       result = b""
-      while grpc_byte_buffer_reader_next(&reader, &data_slice):
-        data_slice_pointer = gpr_slice_start_ptr(data_slice)
-        data_slice_length = gpr_slice_length(data_slice)
-        result += (<char *>data_slice_pointer)[:data_slice_length]
-      grpc_byte_buffer_reader_destroy(&reader)
+      with nogil:
+        while grpc_byte_buffer_reader_next(&reader, &data_slice):
+          data_slice_pointer = gpr_slice_start_ptr(data_slice)
+          data_slice_length = gpr_slice_length(data_slice)
+          with gil:
+            result += (<char *>data_slice_pointer)[:data_slice_length]
+      with nogil:
+        grpc_byte_buffer_reader_destroy(&reader)
       return result
     else:
       return None
 
   def __len__(self):
+    cdef size_t result
     if self.c_byte_buffer != NULL:
-      return grpc_byte_buffer_length(self.c_byte_buffer)
+      with nogil:
+        result = grpc_byte_buffer_length(self.c_byte_buffer)
+      return result
     else:
       return 0
 
@@ -262,7 +281,8 @@
 
   def __dealloc__(self):
     if self.c_byte_buffer != NULL:
-      grpc_byte_buffer_destroy(self.c_byte_buffer)
+      with nogil:
+        grpc_byte_buffer_destroy(self.c_byte_buffer)
 
 
 cdef class SslPemKeyCertPair:
@@ -319,14 +339,15 @@
       if not isinstance(arg, ChannelArg):
         raise TypeError("expected list of ChannelArg")
     self.c_args.arguments_length = len(self.args)
-    self.c_args.arguments = <grpc_arg *>gpr_malloc(
-        self.c_args.arguments_length*sizeof(grpc_arg)
-    )
+    with nogil:
+      self.c_args.arguments = <grpc_arg *>gpr_malloc(
+          self.c_args.arguments_length*sizeof(grpc_arg))
     for i in range(self.c_args.arguments_length):
       self.c_args.arguments[i] = (<ChannelArg>self.args[i]).c_arg
 
   def __dealloc__(self):
-    gpr_free(self.c_args.arguments)
+    with nogil:
+      gpr_free(self.c_args.arguments)
 
   def __len__(self):
     # self.args is never stale; it's only updated from this file
@@ -407,21 +428,24 @@
     for metadatum in metadata:
       if not isinstance(metadatum, Metadatum):
         raise TypeError("expected list of Metadatum")
-    grpc_metadata_array_init(&self.c_metadata_array)
+    with nogil:
+      grpc_metadata_array_init(&self.c_metadata_array)
     self.c_metadata_array.count = len(self.metadata)
     self.c_metadata_array.capacity = len(self.metadata)
-    self.c_metadata_array.metadata = <grpc_metadata *>gpr_malloc(
-        self.c_metadata_array.count*sizeof(grpc_metadata)
-    )
+    with nogil:
+      self.c_metadata_array.metadata = <grpc_metadata *>gpr_malloc(
+          self.c_metadata_array.count*sizeof(grpc_metadata)
+      )
     for i in range(self.c_metadata_array.count):
       self.c_metadata_array.metadata[i] = (
           (<Metadatum>self.metadata[i]).c_metadata)
 
   def __dealloc__(self):
     # this frees the allocated memory for the grpc_metadata_array (although
-    # it'd be nice if that were documented somewhere...) TODO(atash): document
-    # this in the C core
-    grpc_metadata_array_destroy(&self.c_metadata_array)
+    # it'd be nice if that were documented somewhere...)
+    # TODO(atash): document this in the C core
+    with nogil:
+      grpc_metadata_array_destroy(&self.c_metadata_array)
 
   def __len__(self):
     return self.c_metadata_array.count
@@ -526,7 +550,8 @@
     # Python. The remaining one(s) are primitive fields filled in by GRPC core.
     # This means that we need to clean up after receive_status_on_client.
     if self.c_op.type == GRPC_OP_RECV_STATUS_ON_CLIENT:
-      gpr_free(self._received_status_details)
+      with nogil:
+        gpr_free(self._received_status_details)
 
 def operation_send_initial_metadata(Metadata metadata):
   cdef Operation op = Operation()
@@ -648,8 +673,8 @@
       if not isinstance(operation, Operation):
         raise TypeError("expected operations to be iterable of Operation")
     self.c_nops = len(self.operations)
-    self.c_ops = <grpc_op *>gpr_malloc(
-        sizeof(grpc_op)*self.c_nops)
+    with nogil:
+      self.c_ops = <grpc_op *>gpr_malloc(sizeof(grpc_op)*self.c_nops)
     for i in range(self.c_nops):
       self.c_ops[i] = (<Operation>(self.operations[i])).c_op
 
@@ -661,7 +686,8 @@
     return self.operations[i]
 
   def __dealloc__(self):
-    gpr_free(self.c_ops)
+    with nogil:
+      gpr_free(self.c_ops)
 
   def __iter__(self):
     return _OperationsIterator(self)
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi
index 5f85923..a098f11 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi
@@ -41,7 +41,8 @@
     if arguments is not None:
       c_arguments = &arguments.c_args
       self.references.append(arguments)
-    self.c_server = grpc_server_create(c_arguments, NULL)
+    with nogil:
+      self.c_server = grpc_server_create(c_arguments, NULL)
     self.is_started = False
     self.is_shutting_down = False
     self.is_shutdown = False
@@ -53,6 +54,7 @@
       raise ValueError("server must be started and not shutting down")
     if server_queue not in self.registered_completion_queues:
       raise ValueError("server_queue must be a registered completion queue")
+    cdef grpc_call_error result
     cdef OperationTag operation_tag = OperationTag(tag)
     operation_tag.operation_call = Call()
     operation_tag.request_call_details = CallDetails()
@@ -61,19 +63,22 @@
     operation_tag.is_new_request = True
     operation_tag.batch_operations = Operations([])
     cpython.Py_INCREF(operation_tag)
-    return grpc_server_request_call(
-        self.c_server, &operation_tag.operation_call.c_call,
-        &operation_tag.request_call_details.c_details,
-        &operation_tag.request_metadata.c_metadata_array,
-        call_queue.c_completion_queue, server_queue.c_completion_queue,
-        <cpython.PyObject *>operation_tag)
+    with nogil:
+      result = grpc_server_request_call(
+          self.c_server, &operation_tag.operation_call.c_call,
+          &operation_tag.request_call_details.c_details,
+          &operation_tag.request_metadata.c_metadata_array,
+          call_queue.c_completion_queue, server_queue.c_completion_queue,
+          <cpython.PyObject *>operation_tag)
+    return result
 
   def register_completion_queue(
       self, CompletionQueue queue not None):
     if self.is_started:
       raise ValueError("cannot register completion queues after start")
-    grpc_server_register_completion_queue(
-        self.c_server, queue.c_completion_queue, NULL)
+    with nogil:
+      grpc_server_register_completion_queue(
+          self.c_server, queue.c_completion_queue, NULL)
     self.registered_completion_queues.append(queue)
 
   def start(self):
@@ -82,7 +87,8 @@
     self.backup_shutdown_queue = CompletionQueue()
     self.register_completion_queue(self.backup_shutdown_queue)
     self.is_started = True
-    grpc_server_start(self.c_server)
+    with nogil:
+      grpc_server_start(self.c_server)
     # Ensure the core has gotten a chance to do the start-up work
     self.backup_shutdown_queue.pluck(None, Timespec(None))
 
@@ -95,21 +101,28 @@
     else:
       raise TypeError("expected address to be a str or bytes")
     self.references.append(address)
+    cdef int result
+    cdef char *address_c_string = address
     if server_credentials is not None:
       self.references.append(server_credentials)
-      return grpc_server_add_secure_http2_port(
-          self.c_server, address, server_credentials.c_credentials)
+      with nogil:
+        result = grpc_server_add_secure_http2_port(
+            self.c_server, address_c_string, server_credentials.c_credentials)
     else:
-      return grpc_server_add_insecure_http2_port(self.c_server, address)
+      with nogil:
+        result = grpc_server_add_insecure_http2_port(self.c_server,
+                                                     address_c_string)
+    return result
 
   cdef _c_shutdown(self, CompletionQueue queue, tag):
     self.is_shutting_down = True
     operation_tag = OperationTag(tag)
     operation_tag.shutting_down_server = self
     cpython.Py_INCREF(operation_tag)
-    grpc_server_shutdown_and_notify(
-        self.c_server, queue.c_completion_queue,
-        <cpython.PyObject *>operation_tag)
+    with nogil:
+      grpc_server_shutdown_and_notify(
+          self.c_server, queue.c_completion_queue,
+          <cpython.PyObject *>operation_tag)
 
   def shutdown(self, CompletionQueue queue not None, tag):
     cdef OperationTag operation_tag
@@ -134,7 +147,8 @@
     elif self.is_shutdown:
       return
     else:
-      grpc_server_cancel_all_calls(self.c_server)
+      with nogil:
+        grpc_server_cancel_all_calls(self.c_server)
 
   def __dealloc__(self):
     if self.c_server != NULL:
@@ -153,5 +167,6 @@
         # much but repeatedly release the GIL and wait
         while not self.is_shutdown:
           time.sleep(0)
-      grpc_server_destroy(self.c_server)
+      with nogil:
+        grpc_server_destroy(self.c_server)
 
diff --git a/src/python/grpcio/grpc/_cython/cygrpc.pyx b/src/python/grpcio/grpc/_cython/cygrpc.pyx
index 30cc7a1..8a0f171 100644
--- a/src/python/grpcio/grpc/_cython/cygrpc.pyx
+++ b/src/python/grpcio/grpc/_cython/cygrpc.pyx
@@ -57,14 +57,17 @@
           'grpc._cython', '_windows/grpc_c.64.python')
       if not pygrpc_load_core(filename):
         raise ImportError('failed to load core gRPC library')
-    grpc_init()
+    with nogil:
+      grpc_init()
     self.is_loaded = True
-    grpc_set_ssl_roots_override_callback(
-        <grpc_ssl_roots_override_callback>ssl_roots_override_callback)
+    with nogil:
+      grpc_set_ssl_roots_override_callback(
+          <grpc_ssl_roots_override_callback>ssl_roots_override_callback)
 
   def __dealloc__(self):
     if self.is_loaded:
-      grpc_shutdown()
+      with nogil:
+        grpc_shutdown()
 
 _module_state = _ModuleState()
 
diff --git a/src/python/grpcio/grpc/_cython/imports.generated.h b/src/python/grpcio/grpc/_cython/imports.generated.h
index b70dccc..4d18369 100644
--- a/src/python/grpcio/grpc/_cython/imports.generated.h
+++ b/src/python/grpcio/grpc/_cython/imports.generated.h
@@ -166,7 +166,7 @@
 typedef int(*grpc_compression_algorithm_name_type)(grpc_compression_algorithm algorithm, char **name);
 extern grpc_compression_algorithm_name_type grpc_compression_algorithm_name_import;
 #define grpc_compression_algorithm_name grpc_compression_algorithm_name_import
-typedef grpc_compression_algorithm(*grpc_compression_algorithm_for_level_type)(grpc_compression_level level);
+typedef grpc_compression_algorithm(*grpc_compression_algorithm_for_level_type)(grpc_compression_level level, uint32_t accepted_encodings);
 extern grpc_compression_algorithm_for_level_type grpc_compression_algorithm_for_level_import;
 #define grpc_compression_algorithm_for_level grpc_compression_algorithm_for_level_import
 typedef void(*grpc_compression_options_init_type)(grpc_compression_options *opts);
diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py
index a543791..b9e7d8c 100644
--- a/src/python/grpcio/grpc_core_dependencies.py
+++ b/src/python/grpcio/grpc_core_dependencies.py
@@ -34,6 +34,7 @@
   'src/core/profiling/stap_timers.c',
   'src/core/support/alloc.c',
   'src/core/support/avl.c',
+  'src/core/support/backoff.c',
   'src/core/support/cmdline.c',
   'src/core/support/cpu_iphone.c',
   'src/core/support/cpu_linux.c',
@@ -75,8 +76,10 @@
   'src/core/support/wrap_memcpy.c',
   'src/core/census/grpc_context.c',
   'src/core/census/grpc_filter.c',
+  'src/core/census/grpc_plugin.c',
   'src/core/channel/channel_args.c',
   'src/core/channel/channel_stack.c',
+  'src/core/channel/channel_stack_builder.c',
   'src/core/channel/client_channel.c',
   'src/core/channel/client_uchannel.c',
   'src/core/channel/compress_filter.c',
@@ -164,7 +167,9 @@
   'src/core/surface/channel.c',
   'src/core/surface/channel_connectivity.c',
   'src/core/surface/channel_create.c',
+  'src/core/surface/channel_init.c',
   'src/core/surface/channel_ping.c',
+  'src/core/surface/channel_stack_type.c',
   'src/core/surface/completion_queue.c',
   'src/core/surface/event_string.c',
   'src/core/surface/init.c',
@@ -172,7 +177,6 @@
   'src/core/surface/metadata_array.c',
   'src/core/surface/server.c',
   'src/core/surface/server_chttp2.c',
-  'src/core/surface/server_create.c',
   'src/core/surface/validate_metadata.c',
   'src/core/surface/version.c',
   'src/core/transport/byte_stream.c',
diff --git a/src/python/grpcio/tests/_runner.py b/src/python/grpcio/tests/_runner.py
index b0dbd92..3b5ca03 100644
--- a/src/python/grpcio/tests/_runner.py
+++ b/src/python/grpcio/tests/_runner.py
@@ -35,6 +35,7 @@
 import select
 import signal
 import sys
+import tempfile
 import threading
 import time
 import unittest
@@ -44,60 +45,46 @@
 from tests import _result
 
 
-class CapturePipe(object):
-  """A context-manager pipe to redirect output to a byte array.
+class CaptureFile(object):
+  """A context-managed file to redirect output to a byte array.
+
+  Use by invoking `start` (`__enter__`) and at some point invoking `stop`
+  (`__exit__`). At any point after the initial call to `start` call `output` to
+  get the current redirected output. Note that we don't currently use file
+  locking, so calling `output` between calls to `start` and `stop` may muddle
+  the result (you should only be doing this during a Python-handled interrupt as
+  a last ditch effort to provide output to the user).
 
   Attributes:
-    _redirect_fd (int): File descriptor of file to redirect writes from.
+    _redirected_fd (int): File descriptor of file to redirect writes from.
     _saved_fd (int): A copy of the original value of the redirected file
       descriptor.
-    _read_thread (threading.Thread or None): Thread upon which reads through the
-      pipe are performed. Only non-None when self is started.
-    _read_fd (int or None): File descriptor of the read end of the redirect
-      pipe. Only non-None when self is started.
-    _write_fd (int or None): File descriptor of the write end of the redirect
-      pipe. Only non-None when self is started.
-    output (bytearray or None): Redirected output from writes to the redirected
-      file descriptor. Only valid during and after self has started.
+    _into_file (TemporaryFile or None): File to which writes are redirected.
+      Only non-None when self is started.
   """
 
   def __init__(self, fd):
-    self._redirect_fd = fd
-    self._saved_fd = os.dup(self._redirect_fd)
-    self._read_thread = None
-    self._read_fd = None
-    self._write_fd = None
-    self.output = None
+    self._redirected_fd = fd
+    self._saved_fd = os.dup(self._redirected_fd)
+    self._into_file = None
+
+  def output(self):
+    """Get all output from the redirected-to file if it exists."""
+    if self._into_file:
+      self._into_file.seek(0)
+      return bytes(self._into_file.read())
+    else:
+      return bytes()
 
   def start(self):
     """Start redirection of writes to the file descriptor."""
-    self._read_fd, self._write_fd = os.pipe()
-    os.dup2(self._write_fd, self._redirect_fd)
-    flags = fcntl.fcntl(self._read_fd, fcntl.F_GETFL)
-    fcntl.fcntl(self._read_fd, fcntl.F_SETFL, flags | os.O_NONBLOCK)
-    self._read_thread = threading.Thread(target=self._read)
-    self._read_thread.start()
+    self._into_file = tempfile.TemporaryFile()
+    os.dup2(self._into_file.fileno(), self._redirected_fd)
 
   def stop(self):
     """Stop redirection of writes to the file descriptor."""
-    os.close(self._write_fd)
-    os.dup2(self._saved_fd, self._redirect_fd)  # auto-close self._redirect_fd
-    self._read_thread.join()
-    self._read_thread = None
-    # we waited for the read thread to finish, so _read_fd has been read and we
-    # can close it.
-    os.close(self._read_fd)
-
-  def _read(self):
-    """Read-thread target for self."""
-    self.output = bytearray()
-    while True:
-      select.select([self._read_fd], [], [])
-      read_bytes = os.read(self._read_fd, 1024)
-      if read_bytes:
-        self.output.extend(read_bytes)
-      else:
-        break
+    # n.b. this dup2 call auto-closes self._redirected_fd
+    os.dup2(self._saved_fd, self._redirected_fd)
 
   def write_bypass(self, value):
     """Bypass the redirection and write directly to the original file.
@@ -159,8 +146,8 @@
     result_out = StringIO.StringIO()
     result = _result.TerminalResult(
         result_out, id_map=lambda case: case_id_by_case[case])
-    stdout_pipe = CapturePipe(sys.stdout.fileno())
-    stderr_pipe = CapturePipe(sys.stderr.fileno())
+    stdout_pipe = CaptureFile(sys.stdout.fileno())
+    stderr_pipe = CaptureFile(sys.stderr.fileno())
     kill_flag = [False]
 
     def sigint_handler(signal_number, frame):
@@ -171,7 +158,8 @@
     def fault_handler(signal_number, frame):
       stdout_pipe.write_bypass(
           'Received fault signal {}\nstdout:\n{}\n\nstderr:{}\n'
-          .format(signal_number, stdout_pipe.output, stderr_pipe.output))
+          .format(signal_number, stdout_pipe.output(),
+                  stderr_pipe.output()))
       os._exit(1)
 
     def check_kill_self():
@@ -180,9 +168,9 @@
         result.stopTestRun()
         stdout_pipe.write_bypass(result_out.getvalue())
         stdout_pipe.write_bypass(
-            '\ninterrupted stdout:\n{}\n'.format(stdout_pipe.output))
+            '\ninterrupted stdout:\n{}\n'.format(stdout_pipe.output()))
         stderr_pipe.write_bypass(
-            '\ninterrupted stderr:\n{}\n'.format(stderr_pipe.output))
+            '\ninterrupted stderr:\n{}\n'.format(stderr_pipe.output()))
         os._exit(1)
     signal.signal(signal.SIGINT, sigint_handler)
     signal.signal(signal.SIGSEGV, fault_handler)
@@ -212,7 +200,7 @@
         # re-raise the exception after forcing the with-block to end
         raise
       result.set_output(
-          augmented_case.case, stdout_pipe.output, stderr_pipe.output)
+          augmented_case.case, stdout_pipe.output(), stderr_pipe.output())
       sys.stdout.write(result_out.getvalue())
       sys.stdout.flush()
       result_out.truncate(0)
diff --git a/src/ruby/ext/grpc/rb_grpc_imports.generated.h b/src/ruby/ext/grpc/rb_grpc_imports.generated.h
index b972f60..3bf81af 100644
--- a/src/ruby/ext/grpc/rb_grpc_imports.generated.h
+++ b/src/ruby/ext/grpc/rb_grpc_imports.generated.h
@@ -166,7 +166,7 @@
 typedef int(*grpc_compression_algorithm_name_type)(grpc_compression_algorithm algorithm, char **name);
 extern grpc_compression_algorithm_name_type grpc_compression_algorithm_name_import;
 #define grpc_compression_algorithm_name grpc_compression_algorithm_name_import
-typedef grpc_compression_algorithm(*grpc_compression_algorithm_for_level_type)(grpc_compression_level level);
+typedef grpc_compression_algorithm(*grpc_compression_algorithm_for_level_type)(grpc_compression_level level, uint32_t accepted_encodings);
 extern grpc_compression_algorithm_for_level_type grpc_compression_algorithm_for_level_import;
 #define grpc_compression_algorithm_for_level grpc_compression_algorithm_for_level_import
 typedef void(*grpc_compression_options_init_type)(grpc_compression_options *opts);
diff --git a/templates/tools/dockerfile/apt_get_basic.include b/templates/tools/dockerfile/apt_get_basic.include
index 547ce01..9237e7d 100644
--- a/templates/tools/dockerfile/apt_get_basic.include
+++ b/templates/tools/dockerfile/apt_get_basic.include
@@ -1,4 +1,3 @@
-<%page args="skip_golang=False"/>\
 # Install Git and basic packages.
 RUN apt-get update && apt-get install -y ${'\\'}
   autoconf ${'\\'}
@@ -10,9 +9,7 @@
   gcc ${'\\'}
   gcc-multilib ${'\\'}
   git ${'\\'}
-% if not skip_golang:
   golang ${'\\'}
-% endif
   gyp ${'\\'}
   lcov ${'\\'}
   libc6 ${'\\'}
diff --git a/templates/tools/dockerfile/run_tests_addons.include b/templates/tools/dockerfile/run_tests_addons.include
index 30d22be..27ac67f 100644
--- a/templates/tools/dockerfile/run_tests_addons.include
+++ b/templates/tools/dockerfile/run_tests_addons.include
@@ -1,10 +1,7 @@
-<%page args="skip_zookeeper=False"/>\
 <%include file="ccache_setup.include"/>
-% if not skip_zookeeper:
 #======================
 # Zookeeper dependencies
 # TODO(jtattermusch): is zookeeper still needed?
 RUN apt-get install -y libzookeeper-mt-dev
-% endif
 
 RUN mkdir /var/local/jenkins
diff --git a/templates/tools/dockerfile/test/cxx_squeeze_x64/Dockerfile.template b/templates/tools/dockerfile/test/cxx_wheezy_x64/Dockerfile.template
similarity index 77%
rename from templates/tools/dockerfile/test/cxx_squeeze_x64/Dockerfile.template
rename to templates/tools/dockerfile/test/cxx_wheezy_x64/Dockerfile.template
index 49371aa..7956798 100644
--- a/templates/tools/dockerfile/test/cxx_squeeze_x64/Dockerfile.template
+++ b/templates/tools/dockerfile/test/cxx_wheezy_x64/Dockerfile.template
@@ -29,20 +29,19 @@
   # (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 debian:squeeze
+  FROM debian:wheezy
 
-  <%include file="../../apt_get_basic.include" args="skip_golang=True"/>
+  <%include file="../../apt_get_basic.include"/>
+  <%include file="../../cxx_deps.include"/>
 
-  # libgflags-dev is not available on squeezy
-  RUN apt-get update && apt-get -y install libgtest-dev libc++-dev clang && apt-get clean
-
-  RUN apt-get update && apt-get -y install python-pip && apt-get clean
-  RUN pip install argparse
+  RUN apt-get update && apt-get install -y ${'\\'}
+    gcc-4.4 ${'\\'}
+    gcc-4.4-multilib
 
   RUN wget ${openssl_fallback.base_uri + openssl_fallback.tarball}
 
-  ENV POST_GIT_STEP tools/dockerfile/test/cxx_squeeze_x64/post-git-setup.sh
+  ENV POST_GIT_STEP tools/dockerfile/test/cxx_wheezy_x64/post-git-setup.sh
 
-  <%include file="../../run_tests_addons.include" args="skip_zookeeper=True"/>
+  <%include file="../../run_tests_addons.include"/>
   # Define the default command.
   CMD ["bash"]
diff --git a/templates/tools/dockerfile/test/cxx_squeeze_x64/post-git-setup.sh.template b/templates/tools/dockerfile/test/cxx_wheezy_x64/post-git-setup.sh.template
similarity index 100%
rename from templates/tools/dockerfile/test/cxx_squeeze_x64/post-git-setup.sh.template
rename to templates/tools/dockerfile/test/cxx_wheezy_x64/post-git-setup.sh.template
diff --git a/templates/tools/dockerfile/test/sanity/Dockerfile.template b/templates/tools/dockerfile/test/sanity/Dockerfile.template
index ad1d92e..8265c09 100644
--- a/templates/tools/dockerfile/test/sanity/Dockerfile.template
+++ b/templates/tools/dockerfile/test/sanity/Dockerfile.template
@@ -34,7 +34,13 @@
   <%include file="../../apt_get_basic.include"/>
   #========================
   # Sanity test dependencies
-  RUN apt-get update && apt-get install -y python-pip
+  RUN apt-get update && apt-get install -y ${"\\"}
+        python-pip ${"\\"}
+        autoconf ${"\\"}
+        automake ${"\\"}
+        libtool ${"\\"}
+        curl ${"\\"}
+        python-virtualenv
   RUN pip install simplejson mako
 
   #===================
diff --git a/templates/vsprojects/vcxproj_defs.include b/templates/vsprojects/vcxproj_defs.include
index e598f13..72a077f 100644
--- a/templates/vsprojects/vcxproj_defs.include
+++ b/templates/vsprojects/vcxproj_defs.include
@@ -227,7 +227,7 @@
       % endif
     % endfor
   </ItemGroup>
-  % elif configuration_type != 'StaticLibrary':
+  % else:
   <ItemGroup>
     <ClCompile Include="${repo_root}\${to_windows_path('vsprojects/dummy.c')}">
     </ClCompile>
diff --git a/test/core/bad_client/bad_client.c b/test/core/bad_client/bad_client.c
index 1a2ca6f..ba19013 100644
--- a/test/core/bad_client/bad_client.c
+++ b/test/core/bad_client/bad_client.c
@@ -67,11 +67,8 @@
 
 static void server_setup_transport(void *ts, grpc_transport *transport) {
   thd_args *a = ts;
-  static grpc_channel_filter const *extra_filters[] = {
-      &grpc_http_server_filter};
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
-  grpc_server_setup_transport(&exec_ctx, a->server, transport, extra_filters,
-                              GPR_ARRAY_SIZE(extra_filters),
+  grpc_server_setup_transport(&exec_ctx, a->server, transport,
                               grpc_server_get_channel_args(a->server));
   grpc_exec_ctx_finish(&exec_ctx);
 }
@@ -105,7 +102,7 @@
   sfd = grpc_iomgr_create_endpoint_pair("fixture", 65536);
 
   /* Create server, completion events */
-  a.server = grpc_server_create_from_filters(NULL, 0, NULL);
+  a.server = grpc_server_create(NULL, NULL);
   a.cq = grpc_completion_queue_create(NULL);
   gpr_event_init(&a.done_thd);
   gpr_event_init(&a.done_write);
diff --git a/test/core/census/mlog_test.c b/test/core/census/mlog_test.c
index 5b6c594..000ac73 100644
--- a/test/core/census/mlog_test.c
+++ b/test/core/census/mlog_test.c
@@ -332,7 +332,7 @@
 
 static void setup_test(int circular_log) {
   census_log_initialize(LOG_SIZE_IN_MB, circular_log);
-  GPR_ASSERT(census_log_remaining_space() == LOG_SIZE_IN_BYTES);
+  //  GPR_ASSERT(census_log_remaining_space() == LOG_SIZE_IN_BYTES);
 }
 
 // Attempts to create a record of invalid size (size >
@@ -352,8 +352,8 @@
   // check can fail if the thread is context switched to a new CPU during the
   // start_write execution (multiple blocks get allocated), but this has not
   // been observed in practice.
-  GPR_ASSERT(LOG_SIZE_IN_BYTES - CENSUS_LOG_MAX_RECORD_SIZE ==
-             census_log_remaining_space());
+  //  GPR_ASSERT(LOG_SIZE_IN_BYTES - CENSUS_LOG_MAX_RECORD_SIZE ==
+  //             census_log_remaining_space());
   census_log_shutdown();
 }
 
diff --git a/test/core/client_config/lb_policies_test.c b/test/core/client_config/lb_policies_test.c
index cb99b3d..1ea0c42 100644
--- a/test/core/client_config/lb_policies_test.c
+++ b/test/core/client_config/lb_policies_test.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -52,6 +52,8 @@
 #include "test/core/util/port.h"
 #include "test/core/util/test_config.h"
 
+#define RETRY_TIMEOUT 300
+
 typedef struct servers_fixture {
   size_t num_servers;
   grpc_server **servers;
@@ -303,8 +305,8 @@
 
     s_idx = -1;
     while ((ev = grpc_completion_queue_next(
-                f->cq, GRPC_TIMEOUT_SECONDS_TO_DEADLINE(1), NULL)).type !=
-           GRPC_QUEUE_TIMEOUT) {
+                f->cq, GRPC_TIMEOUT_MILLIS_TO_DEADLINE(10 * RETRY_TIMEOUT),
+                NULL)).type != GRPC_QUEUE_TIMEOUT) {
       GPR_ASSERT(ev.type == GRPC_OP_COMPLETE);
       read_tag = ((int)(intptr_t)ev.tag);
       gpr_log(GPR_DEBUG, "EVENT: success:%d, type:%d, tag:%d iter:%d",
@@ -376,9 +378,9 @@
       }
     }
 
-    GPR_ASSERT(grpc_completion_queue_next(f->cq,
-                                          GRPC_TIMEOUT_MILLIS_TO_DEADLINE(200),
-                                          NULL).type == GRPC_QUEUE_TIMEOUT);
+    GPR_ASSERT(grpc_completion_queue_next(
+                   f->cq, GRPC_TIMEOUT_MILLIS_TO_DEADLINE(2 * RETRY_TIMEOUT),
+                   NULL).type == GRPC_QUEUE_TIMEOUT);
 
     grpc_metadata_array_destroy(&rdata->initial_metadata_recv);
     grpc_metadata_array_destroy(&rdata->trailing_metadata_recv);
@@ -506,7 +508,7 @@
 
   arg.type = GRPC_ARG_INTEGER;
   arg.key = "grpc.testing.fixed_reconnect_backoff";
-  arg.value.integer = 100;
+  arg.value.integer = RETRY_TIMEOUT;
   args.num_args = 1;
   args.args = &arg;
 
@@ -542,7 +544,7 @@
 
   arg.type = GRPC_ARG_INTEGER;
   arg.key = "grpc.testing.fixed_reconnect_backoff";
-  arg.value.integer = 100;
+  arg.value.integer = RETRY_TIMEOUT;
   args.num_args = 1;
   args.args = &arg;
 
diff --git a/test/core/compression/compression_test.c b/test/core/compression/compression_test.c
index 26d7b2b..5d8231f 100644
--- a/test/core/compression/compression_test.c
+++ b/test/core/compression/compression_test.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -93,18 +93,98 @@
 }
 
 static void test_compression_algorithm_for_level(void) {
-  size_t i;
-  grpc_compression_level levels[] = {
-      GRPC_COMPRESS_LEVEL_NONE, GRPC_COMPRESS_LEVEL_LOW,
-      GRPC_COMPRESS_LEVEL_MED, GRPC_COMPRESS_LEVEL_HIGH};
-  grpc_compression_algorithm algorithms[] = {
-      GRPC_COMPRESS_NONE, GRPC_COMPRESS_DEFLATE, GRPC_COMPRESS_DEFLATE,
-      GRPC_COMPRESS_DEFLATE};
   gpr_log(GPR_DEBUG, "test_compression_algorithm_for_level");
 
-  for (i = 0; i < GPR_ARRAY_SIZE(levels); i++) {
-    GPR_ASSERT(algorithms[i] ==
-               grpc_compression_algorithm_for_level(levels[i]));
+  {
+    /* accept only identity (aka none) */
+    uint32_t accepted_encodings = 0;
+    GPR_BITSET(&accepted_encodings, GRPC_COMPRESS_NONE); /* always */
+
+    GPR_ASSERT(GRPC_COMPRESS_NONE ==
+               grpc_compression_algorithm_for_level(GRPC_COMPRESS_LEVEL_NONE,
+                                                    accepted_encodings));
+
+    GPR_ASSERT(GRPC_COMPRESS_NONE ==
+               grpc_compression_algorithm_for_level(GRPC_COMPRESS_LEVEL_LOW,
+                                                    accepted_encodings));
+
+    GPR_ASSERT(GRPC_COMPRESS_NONE ==
+               grpc_compression_algorithm_for_level(GRPC_COMPRESS_LEVEL_MED,
+                                                    accepted_encodings));
+
+    GPR_ASSERT(GRPC_COMPRESS_NONE ==
+               grpc_compression_algorithm_for_level(GRPC_COMPRESS_LEVEL_HIGH,
+                                                    accepted_encodings));
+  }
+
+  {
+    /* accept only gzip */
+    uint32_t accepted_encodings = 0;
+    GPR_BITSET(&accepted_encodings, GRPC_COMPRESS_NONE); /* always */
+    GPR_BITSET(&accepted_encodings, GRPC_COMPRESS_GZIP);
+
+    GPR_ASSERT(GRPC_COMPRESS_NONE ==
+               grpc_compression_algorithm_for_level(GRPC_COMPRESS_LEVEL_NONE,
+                                                    accepted_encodings));
+
+    GPR_ASSERT(GRPC_COMPRESS_GZIP ==
+               grpc_compression_algorithm_for_level(GRPC_COMPRESS_LEVEL_LOW,
+                                                    accepted_encodings));
+
+    GPR_ASSERT(GRPC_COMPRESS_GZIP ==
+               grpc_compression_algorithm_for_level(GRPC_COMPRESS_LEVEL_MED,
+                                                    accepted_encodings));
+
+    GPR_ASSERT(GRPC_COMPRESS_GZIP ==
+               grpc_compression_algorithm_for_level(GRPC_COMPRESS_LEVEL_HIGH,
+                                                    accepted_encodings));
+  }
+
+  {
+    /* accept only deflate */
+    uint32_t accepted_encodings = 0;
+    GPR_BITSET(&accepted_encodings, GRPC_COMPRESS_NONE); /* always */
+    GPR_BITSET(&accepted_encodings, GRPC_COMPRESS_DEFLATE);
+
+    GPR_ASSERT(GRPC_COMPRESS_NONE ==
+               grpc_compression_algorithm_for_level(GRPC_COMPRESS_LEVEL_NONE,
+                                                    accepted_encodings));
+
+    GPR_ASSERT(GRPC_COMPRESS_DEFLATE ==
+               grpc_compression_algorithm_for_level(GRPC_COMPRESS_LEVEL_LOW,
+                                                    accepted_encodings));
+
+    GPR_ASSERT(GRPC_COMPRESS_DEFLATE ==
+               grpc_compression_algorithm_for_level(GRPC_COMPRESS_LEVEL_MED,
+                                                    accepted_encodings));
+
+    GPR_ASSERT(GRPC_COMPRESS_DEFLATE ==
+               grpc_compression_algorithm_for_level(GRPC_COMPRESS_LEVEL_HIGH,
+                                                    accepted_encodings));
+  }
+
+  {
+    /* accept gzip and deflate */
+    uint32_t accepted_encodings = 0;
+    GPR_BITSET(&accepted_encodings, GRPC_COMPRESS_NONE); /* always */
+    GPR_BITSET(&accepted_encodings, GRPC_COMPRESS_GZIP);
+    GPR_BITSET(&accepted_encodings, GRPC_COMPRESS_DEFLATE);
+
+    GPR_ASSERT(GRPC_COMPRESS_NONE ==
+               grpc_compression_algorithm_for_level(GRPC_COMPRESS_LEVEL_NONE,
+                                                    accepted_encodings));
+
+    GPR_ASSERT(GRPC_COMPRESS_GZIP ==
+               grpc_compression_algorithm_for_level(GRPC_COMPRESS_LEVEL_LOW,
+                                                    accepted_encodings));
+
+    GPR_ASSERT(GRPC_COMPRESS_DEFLATE ==
+               grpc_compression_algorithm_for_level(GRPC_COMPRESS_LEVEL_MED,
+                                                    accepted_encodings));
+
+    GPR_ASSERT(GRPC_COMPRESS_DEFLATE ==
+               grpc_compression_algorithm_for_level(GRPC_COMPRESS_LEVEL_HIGH,
+                                                    accepted_encodings));
   }
 }
 
diff --git a/test/core/end2end/fixtures/h2_full+trace.c b/test/core/end2end/fixtures/h2_full+trace.c
new file mode 100644
index 0000000..90b0063
--- /dev/null
+++ b/test/core/end2end/fixtures/h2_full+trace.c
@@ -0,0 +1,132 @@
+/*
+ *
+ * Copyright 2015-2016, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "test/core/end2end/end2end_tests.h"
+
+#include <string.h>
+
+#include "src/core/channel/client_channel.h"
+#include "src/core/channel/connected_channel.h"
+#include "src/core/channel/http_server_filter.h"
+#include "src/core/surface/channel.h"
+#include "src/core/surface/server.h"
+#include "src/core/transport/chttp2_transport.h"
+#include <grpc/support/alloc.h>
+#include <grpc/support/host_port.h>
+#include <grpc/support/log.h>
+#include <grpc/support/sync.h>
+#include <grpc/support/thd.h>
+#include <grpc/support/useful.h>
+#include "test/core/util/port.h"
+#include "test/core/util/test_config.h"
+#include "src/core/support/env.h"
+
+typedef struct fullstack_fixture_data {
+  char *localaddr;
+} fullstack_fixture_data;
+
+static grpc_end2end_test_fixture chttp2_create_fixture_fullstack(
+    grpc_channel_args *client_args, grpc_channel_args *server_args) {
+  grpc_end2end_test_fixture f;
+  int port = grpc_pick_unused_port_or_die();
+  fullstack_fixture_data *ffd = gpr_malloc(sizeof(fullstack_fixture_data));
+  memset(&f, 0, sizeof(f));
+
+  gpr_join_host_port(&ffd->localaddr, "localhost", port);
+
+  f.fixture_data = ffd;
+  f.cq = grpc_completion_queue_create(NULL);
+
+  return f;
+}
+
+void chttp2_init_client_fullstack(grpc_end2end_test_fixture *f,
+                                  grpc_channel_args *client_args) {
+  fullstack_fixture_data *ffd = f->fixture_data;
+  f->client = grpc_insecure_channel_create(ffd->localaddr, client_args, NULL);
+  GPR_ASSERT(f->client);
+}
+
+void chttp2_init_server_fullstack(grpc_end2end_test_fixture *f,
+                                  grpc_channel_args *server_args) {
+  fullstack_fixture_data *ffd = f->fixture_data;
+  if (f->server) {
+    grpc_server_destroy(f->server);
+  }
+  f->server = grpc_server_create(server_args, NULL);
+  grpc_server_register_completion_queue(f->server, f->cq, NULL);
+  GPR_ASSERT(grpc_server_add_insecure_http2_port(f->server, ffd->localaddr));
+  grpc_server_start(f->server);
+}
+
+void chttp2_tear_down_fullstack(grpc_end2end_test_fixture *f) {
+  fullstack_fixture_data *ffd = f->fixture_data;
+  gpr_free(ffd->localaddr);
+  gpr_free(ffd);
+}
+
+/* All test configurations */
+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},
+};
+
+int main(int argc, char **argv) {
+  size_t i;
+
+  /* force tracing on, with a value to force many
+     code paths in trace.c to be taken */
+  gpr_setenv("GRPC_TRACE", "doesnt-exist,http,all");
+
+#ifdef GPR_POSIX_SOCKET
+  g_fixture_slowdown_factor = isatty(STDOUT_FILENO) ? 10.0 : 1.0;
+#else
+  g_fixture_slowdown_factor = 10.0;
+#endif
+
+  grpc_test_init(argc, argv);
+  grpc_init();
+
+  for (i = 0; i < sizeof(configs) / sizeof(*configs); i++) {
+    grpc_end2end_tests(argc, argv, configs[i]);
+  }
+
+  GPR_ASSERT(0 == grpc_tracer_set_enabled("also-doesnt-exist", 0));
+  GPR_ASSERT(1 == grpc_tracer_set_enabled("http", 1));
+  GPR_ASSERT(1 == grpc_tracer_set_enabled("all", 1));
+
+  grpc_shutdown();
+
+  return 0;
+}
diff --git a/test/core/end2end/fixtures/h2_sockpair+trace.c b/test/core/end2end/fixtures/h2_sockpair+trace.c
index 511c8b1..482aa8d 100644
--- a/test/core/end2end/fixtures/h2_sockpair+trace.c
+++ b/test/core/end2end/fixtures/h2_sockpair+trace.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -59,11 +59,8 @@
 
 static void server_setup_transport(void *ts, grpc_transport *transport) {
   grpc_end2end_test_fixture *f = ts;
-  static grpc_channel_filter const *extra_filters[] = {
-      &grpc_http_server_filter};
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
-  grpc_server_setup_transport(&exec_ctx, f->server, transport, extra_filters,
-                              GPR_ARRAY_SIZE(extra_filters),
+  grpc_server_setup_transport(&exec_ctx, f->server, transport,
                               grpc_server_get_channel_args(f->server));
   grpc_exec_ctx_finish(&exec_ctx);
 }
@@ -77,17 +74,9 @@
                                    grpc_transport *transport) {
   sp_client_setup *cs = ts;
 
-  const grpc_channel_filter *filters[] = {&grpc_http_client_filter,
-                                          &grpc_compress_filter,
-                                          &grpc_connected_channel_filter};
-  size_t nfilters = sizeof(filters) / sizeof(*filters);
-  grpc_channel *channel = grpc_channel_create_from_filters(
-      exec_ctx, "socketpair-target", filters, nfilters, cs->client_args, 1);
-
-  cs->f->client = channel;
-
-  grpc_connected_channel_bind_transport(grpc_channel_get_channel_stack(channel),
-                                        transport);
+  cs->f->client =
+      grpc_channel_create(exec_ctx, "socketpair-target", cs->client_args,
+                          GRPC_CLIENT_DIRECT_CHANNEL, transport);
 }
 
 static grpc_end2end_test_fixture chttp2_create_fixture_socketpair(
@@ -126,7 +115,7 @@
   grpc_endpoint_pair *sfd = f->fixture_data;
   grpc_transport *transport;
   GPR_ASSERT(!f->server);
-  f->server = grpc_server_create_from_filters(NULL, 0, server_args);
+  f->server = grpc_server_create(server_args, NULL);
   grpc_server_register_completion_queue(f->server, f->cq, NULL);
   grpc_server_start(f->server);
   transport =
diff --git a/test/core/end2end/fixtures/h2_sockpair.c b/test/core/end2end/fixtures/h2_sockpair.c
index 6b4787b..cf1c4ac 100644
--- a/test/core/end2end/fixtures/h2_sockpair.c
+++ b/test/core/end2end/fixtures/h2_sockpair.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -58,11 +58,8 @@
 
 static void server_setup_transport(void *ts, grpc_transport *transport) {
   grpc_end2end_test_fixture *f = ts;
-  static grpc_channel_filter const *extra_filters[] = {
-      &grpc_http_server_filter};
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
-  grpc_server_setup_transport(&exec_ctx, f->server, transport, extra_filters,
-                              GPR_ARRAY_SIZE(extra_filters),
+  grpc_server_setup_transport(&exec_ctx, f->server, transport,
                               grpc_server_get_channel_args(f->server));
   grpc_exec_ctx_finish(&exec_ctx);
 }
@@ -76,17 +73,9 @@
                                    grpc_transport *transport) {
   sp_client_setup *cs = ts;
 
-  const grpc_channel_filter *filters[] = {&grpc_http_client_filter,
-                                          &grpc_compress_filter,
-                                          &grpc_connected_channel_filter};
-  size_t nfilters = sizeof(filters) / sizeof(*filters);
-  grpc_channel *channel = grpc_channel_create_from_filters(
-      exec_ctx, "socketpair-target", filters, nfilters, cs->client_args, 1);
-
-  cs->f->client = channel;
-
-  grpc_connected_channel_bind_transport(grpc_channel_get_channel_stack(channel),
-                                        transport);
+  cs->f->client =
+      grpc_channel_create(exec_ctx, "socketpair-target", cs->client_args,
+                          GRPC_CLIENT_DIRECT_CHANNEL, transport);
 }
 
 static grpc_end2end_test_fixture chttp2_create_fixture_socketpair(
@@ -125,7 +114,7 @@
   grpc_endpoint_pair *sfd = f->fixture_data;
   grpc_transport *transport;
   GPR_ASSERT(!f->server);
-  f->server = grpc_server_create_from_filters(NULL, 0, server_args);
+  f->server = grpc_server_create(server_args, NULL);
   grpc_server_register_completion_queue(f->server, f->cq, NULL);
   grpc_server_start(f->server);
   transport =
diff --git a/test/core/end2end/fixtures/h2_sockpair_1byte.c b/test/core/end2end/fixtures/h2_sockpair_1byte.c
index 3ae8e96..f49938c 100644
--- a/test/core/end2end/fixtures/h2_sockpair_1byte.c
+++ b/test/core/end2end/fixtures/h2_sockpair_1byte.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -58,11 +58,8 @@
 
 static void server_setup_transport(void *ts, grpc_transport *transport) {
   grpc_end2end_test_fixture *f = ts;
-  static grpc_channel_filter const *extra_filters[] = {
-      &grpc_http_server_filter};
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
-  grpc_server_setup_transport(&exec_ctx, f->server, transport, extra_filters,
-                              GPR_ARRAY_SIZE(extra_filters),
+  grpc_server_setup_transport(&exec_ctx, f->server, transport,
                               grpc_server_get_channel_args(f->server));
   grpc_exec_ctx_finish(&exec_ctx);
 }
@@ -76,17 +73,9 @@
                                    grpc_transport *transport) {
   sp_client_setup *cs = ts;
 
-  const grpc_channel_filter *filters[] = {&grpc_http_client_filter,
-                                          &grpc_compress_filter,
-                                          &grpc_connected_channel_filter};
-  size_t nfilters = sizeof(filters) / sizeof(*filters);
-  grpc_channel *channel = grpc_channel_create_from_filters(
-      exec_ctx, "socketpair-target", filters, nfilters, cs->client_args, 1);
-
-  cs->f->client = channel;
-
-  grpc_connected_channel_bind_transport(grpc_channel_get_channel_stack(channel),
-                                        transport);
+  cs->f->client =
+      grpc_channel_create(exec_ctx, "socketpair-target", cs->client_args,
+                          GRPC_CLIENT_DIRECT_CHANNEL, transport);
 }
 
 static grpc_end2end_test_fixture chttp2_create_fixture_socketpair(
@@ -125,7 +114,7 @@
   grpc_endpoint_pair *sfd = f->fixture_data;
   grpc_transport *transport;
   GPR_ASSERT(!f->server);
-  f->server = grpc_server_create_from_filters(NULL, 0, server_args);
+  f->server = grpc_server_create(server_args, NULL);
   grpc_server_register_completion_queue(f->server, f->cq, NULL);
   grpc_server_start(f->server);
   transport =
diff --git a/test/core/end2end/fixtures/h2_uchannel.c b/test/core/end2end/fixtures/h2_uchannel.c
index 87bbd64..25a4804 100644
--- a/test/core/end2end/fixtures/h2_uchannel.c
+++ b/test/core/end2end/fixtures/h2_uchannel.c
@@ -91,9 +91,6 @@
     grpc_chttp2_transport_start_reading(exec_ctx, c->result->transport, NULL,
                                         0);
     GPR_ASSERT(c->result->transport);
-    c->result->filters = gpr_malloc(sizeof(grpc_channel_filter *));
-    c->result->filters[0] = &grpc_http_client_filter;
-    c->result->num_filters = 1;
   } else {
     memset(c->result, 0, sizeof(*c->result));
   }
@@ -179,18 +176,12 @@
 grpc_channel *channel_create(const char *target, const grpc_channel_args *args,
                              grpc_subchannel **sniffed_subchannel) {
   grpc_channel *channel = NULL;
-#define MAX_FILTERS 1
-  const grpc_channel_filter *filters[MAX_FILTERS];
   grpc_resolver *resolver;
   subchannel_factory *f;
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
-  size_t n = 0;
-
-  filters[n++] = &grpc_client_channel_filter;
-  GPR_ASSERT(n <= MAX_FILTERS);
 
   channel =
-      grpc_channel_create_from_filters(&exec_ctx, target, filters, n, args, 1);
+      grpc_channel_create(&exec_ctx, target, args, GRPC_CLIENT_CHANNEL, NULL);
 
   f = gpr_malloc(sizeof(*f));
   f->sniffed_subchannel = sniffed_subchannel;
@@ -285,7 +276,7 @@
                                                grpc_channel_args *client_args) {
   micro_fullstack_fixture_data *ffd = f->fixture_data;
   grpc_connectivity_state conn_state;
-  grpc_connected_subchannel *connected;
+  grpc_connected_subchannel *connected_subchannel;
   char *ipv4_localaddr;
 
   gpr_asprintf(&ipv4_localaddr, "ipv4:%s", ffd->localaddr);
@@ -302,9 +293,10 @@
   GPR_ASSERT(conn_state == GRPC_CHANNEL_IDLE);
   GPR_ASSERT(ffd->sniffed_subchannel != NULL);
 
-  connected = connect_subchannel(ffd->sniffed_subchannel);
+  connected_subchannel = connect_subchannel(ffd->sniffed_subchannel);
   f->client = grpc_client_uchannel_create(ffd->sniffed_subchannel, client_args);
-  grpc_client_uchannel_set_connected_subchannel(f->client, connected);
+  grpc_client_uchannel_set_connected_subchannel(f->client,
+                                                connected_subchannel);
   gpr_log(GPR_INFO, "CHANNEL WRAPPING SUBCHANNEL: %p(%p)", f->client,
           ffd->sniffed_subchannel);
 
diff --git a/test/core/end2end/gen_build_yaml.py b/test/core/end2end/gen_build_yaml.py
index 4dfafce..fa32601 100755
--- a/test/core/end2end/gen_build_yaml.py
+++ b/test/core/end2end/gen_build_yaml.py
@@ -59,6 +59,7 @@
         platforms=['linux']),
     'h2_full+poll+pipe': default_unsecure_fixture_options._replace(
         platforms=['linux']),
+    'h2_full+trace': default_unsecure_fixture_options._replace(tracing=True),
     'h2_oauth2': default_secure_fixture_options._replace(ci_mac=False),
     'h2_proxy': default_unsecure_fixture_options._replace(includes_proxy=True,
                                                           ci_mac=False),
@@ -66,7 +67,7 @@
         ci_mac=False),
     'h2_sockpair': socketpair_unsecure_fixture_options._replace(ci_mac=False),
     'h2_sockpair+trace': socketpair_unsecure_fixture_options._replace(
-        tracing=True),
+        ci_mac=False, tracing=True),
     'h2_ssl': default_secure_fixture_options,
     'h2_ssl+poll': default_secure_fixture_options._replace(platforms=['linux']),
     'h2_ssl_proxy': default_secure_fixture_options._replace(includes_proxy=True,
@@ -150,7 +151,6 @@
 
 def main():
   sec_deps = [
-    'end2end_certs',
     'grpc_test_util',
     'grpc',
     'gpr_test_util',
@@ -193,18 +193,6 @@
               'deps': unsec_deps,
               'vs_proj_dir': 'test/end2end/tests',
           }
-      ] + [
-          {
-              'name': 'end2end_certs',
-              'build': 'private',
-              'language': 'c',
-              'src': [
-                  "test/core/end2end/data/test_root_cert.c",
-                  "test/core/end2end/data/server1_cert.c",
-                  "test/core/end2end/data/server1_key.c"
-              ],
-              'vs_proj_dir': 'test/end2end',
-          }
       ],
       'targets': [
           {
diff --git a/test/core/end2end/invalid_call_argument_test.c b/test/core/end2end/invalid_call_argument_test.c
index 4029e96..2fa1a0a 100644
--- a/test/core/end2end/invalid_call_argument_test.c
+++ b/test/core/end2end/invalid_call_argument_test.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -145,6 +145,8 @@
 }
 
 static void test_non_null_reserved_on_start_batch() {
+  gpr_log(GPR_INFO, "test_non_null_reserved_on_start_batch");
+
   prepare_test(1);
   GPR_ASSERT(GRPC_CALL_ERROR ==
              grpc_call_start_batch(g_state.call, NULL, 0, NULL, tag(1)));
@@ -152,6 +154,8 @@
 }
 
 static void test_non_null_reserved_on_op() {
+  gpr_log(GPR_INFO, "test_non_null_reserved_on_op");
+
   grpc_op *op;
   prepare_test(1);
 
@@ -168,6 +172,8 @@
 }
 
 static void test_send_initial_metadata_more_than_once() {
+  gpr_log(GPR_INFO, "test_send_initial_metadata_more_than_once");
+
   grpc_op *op;
   prepare_test(1);
 
@@ -196,6 +202,8 @@
 }
 
 static void test_too_many_metadata() {
+  gpr_log(GPR_INFO, "test_too_many_metadata");
+
   grpc_op *op;
   prepare_test(1);
 
@@ -212,6 +220,8 @@
 }
 
 static void test_send_null_message() {
+  gpr_log(GPR_INFO, "test_send_null_message");
+
   grpc_op *op;
   prepare_test(1);
 
@@ -233,6 +243,8 @@
 }
 
 static void test_send_messages_at_the_same_time() {
+  gpr_log(GPR_INFO, "test_send_messages_at_the_same_time");
+
   grpc_op *op;
   gpr_slice request_payload_slice = gpr_slice_from_copied_string("hello world");
   grpc_byte_buffer *request_payload =
@@ -262,6 +274,8 @@
 }
 
 static void test_send_server_status_from_client() {
+  gpr_log(GPR_INFO, "test_send_server_status_from_client");
+
   grpc_op *op;
   prepare_test(1);
 
@@ -280,6 +294,8 @@
 }
 
 static void test_receive_initial_metadata_twice_at_client() {
+  gpr_log(GPR_INFO, "test_receive_initial_metadata_twice_at_client");
+
   grpc_op *op;
   prepare_test(1);
   op = g_state.ops;
@@ -306,6 +322,8 @@
 }
 
 static void test_receive_message_with_invalid_flags() {
+  gpr_log(GPR_INFO, "test_receive_message_with_invalid_flags");
+
   grpc_op *op;
   grpc_byte_buffer *payload = NULL;
   prepare_test(1);
@@ -322,6 +340,8 @@
 }
 
 static void test_receive_two_messages_at_the_same_time() {
+  gpr_log(GPR_INFO, "test_receive_two_messages_at_the_same_time");
+
   grpc_op *op;
   grpc_byte_buffer *payload = NULL;
   prepare_test(1);
@@ -343,6 +363,8 @@
 }
 
 static void test_recv_close_on_server_from_client() {
+  gpr_log(GPR_INFO, "test_recv_close_on_server_from_client");
+
   grpc_op *op;
   prepare_test(1);
 
@@ -359,6 +381,8 @@
 }
 
 static void test_recv_status_on_client_twice() {
+  gpr_log(GPR_INFO, "test_recv_status_on_client_twice");
+
   grpc_op *op;
   prepare_test(1);
 
@@ -395,6 +419,8 @@
 }
 
 static void test_send_close_from_client_on_server() {
+  gpr_log(GPR_INFO, "test_send_close_from_client_on_server");
+
   grpc_op *op;
   prepare_test(0);
 
@@ -410,6 +436,8 @@
 }
 
 static void test_recv_status_on_client_from_server() {
+  gpr_log(GPR_INFO, "test_recv_status_on_client_from_server");
+
   grpc_op *op;
   prepare_test(0);
 
@@ -431,6 +459,8 @@
 }
 
 static void test_send_status_from_server_with_invalid_flags() {
+  gpr_log(GPR_INFO, "test_send_status_from_server_with_invalid_flags");
+
   grpc_op *op;
   prepare_test(0);
 
@@ -449,6 +479,8 @@
 }
 
 static void test_too_many_trailing_metadata() {
+  gpr_log(GPR_INFO, "test_too_many_trailing_metadata");
+
   grpc_op *op;
   prepare_test(0);
 
@@ -468,6 +500,8 @@
 }
 
 static void test_send_server_status_twice() {
+  gpr_log(GPR_INFO, "test_send_server_status_twice");
+
   grpc_op *op;
   prepare_test(0);
 
@@ -493,6 +527,8 @@
 }
 
 static void test_recv_close_on_server_with_invalid_flags() {
+  gpr_log(GPR_INFO, "test_recv_close_on_server_with_invalid_flags");
+
   grpc_op *op;
   prepare_test(0);
 
@@ -509,6 +545,8 @@
 }
 
 static void test_recv_close_on_server_twice() {
+  gpr_log(GPR_INFO, "test_recv_close_on_server_twice");
+
   grpc_op *op;
   prepare_test(0);
 
diff --git a/test/core/httpcli/httpcli_test.c b/test/core/httpcli/httpcli_test.c
index da14633..fbc5d4a 100644
--- a/test/core/httpcli/httpcli_test.c
+++ b/test/core/httpcli/httpcli_test.c
@@ -144,31 +144,35 @@
   char *lslash = strrchr(me, '/');
   char *args[4];
   int port = grpc_pick_unused_port_or_die();
+  int arg_shift = 0;
+  /* figure out where we are */
+  char *root;
+  if (lslash) {
+    root = gpr_malloc((size_t)(lslash - me + 1));
+    memcpy(root, me, (size_t)(lslash - me));
+    root[lslash - me] = 0;
+  } else {
+    root = gpr_strdup(".");
+  }
 
   GPR_ASSERT(argc <= 2);
   if (argc == 2) {
     args[0] = gpr_strdup(argv[1]);
   } else {
-    /* figure out where we are */
-    char *root;
-    if (lslash) {
-      root = gpr_malloc((size_t)(lslash - me + 1));
-      memcpy(root, me, (size_t)(lslash - me));
-      root[lslash - me] = 0;
-    } else {
-      root = gpr_strdup(".");
-    }
-    gpr_asprintf(&args[0], "%s/../../test/core/httpcli/test_server.py", root);
-    gpr_free(root);
+    arg_shift = 1;
+    gpr_asprintf(&args[0], "%s/../../tools/distrib/python_wrapper.sh", root);
+    gpr_asprintf(&args[1], "%s/../../test/core/httpcli/test_server.py", root);
   }
 
   /* start the server */
-  args[1] = "--port";
-  gpr_asprintf(&args[2], "%d", port);
-  server = gpr_subprocess_create(3, (const char **)args);
+  args[1 + arg_shift] = "--port";
+  gpr_asprintf(&args[2 + arg_shift], "%d", port);
+  server = gpr_subprocess_create(3 + arg_shift, (const char **)args);
   GPR_ASSERT(server);
   gpr_free(args[0]);
-  gpr_free(args[2]);
+  if (arg_shift) gpr_free(args[1]);
+  gpr_free(args[2 + arg_shift]);
+  gpr_free(root);
 
   gpr_sleep_until(gpr_time_add(gpr_now(GPR_CLOCK_REALTIME),
                                gpr_time_from_seconds(5, GPR_TIMESPAN)));
diff --git a/test/core/httpcli/httpscli_test.c b/test/core/httpcli/httpscli_test.c
index 7f765bc..04c57db 100644
--- a/test/core/httpcli/httpscli_test.c
+++ b/test/core/httpcli/httpscli_test.c
@@ -146,32 +146,36 @@
   char *lslash = strrchr(me, '/');
   char *args[5];
   int port = grpc_pick_unused_port_or_die();
+  int arg_shift = 0;
+  /* figure out where we are */
+  char *root;
+  if (lslash) {
+    root = gpr_malloc((size_t)(lslash - me + 1));
+    memcpy(root, me, (size_t)(lslash - me));
+    root[lslash - me] = 0;
+  } else {
+    root = gpr_strdup(".");
+  }
 
   GPR_ASSERT(argc <= 2);
   if (argc == 2) {
     args[0] = gpr_strdup(argv[1]);
   } else {
-    /* figure out where we are */
-    char *root;
-    if (lslash) {
-      root = gpr_malloc((size_t)(lslash - me + 1));
-      memcpy(root, me, (size_t)(lslash - me));
-      root[lslash - me] = 0;
-    } else {
-      root = gpr_strdup(".");
-    }
-    gpr_asprintf(&args[0], "%s/../../test/core/httpcli/test_server.py", root);
-    gpr_free(root);
+    arg_shift = 1;
+    gpr_asprintf(&args[0], "%s/../../tools/distrib/python_wrapper.sh", root);
+    gpr_asprintf(&args[1], "%s/../../test/core/httpcli/test_server.py", root);
   }
 
   /* start the server */
-  args[1] = "--port";
-  gpr_asprintf(&args[2], "%d", port);
-  args[3] = "--ssl";
-  server = gpr_subprocess_create(4, (const char **)args);
+  args[1 + arg_shift] = "--port";
+  gpr_asprintf(&args[2 + arg_shift], "%d", port);
+  args[3 + arg_shift] = "--ssl";
+  server = gpr_subprocess_create(4 + arg_shift, (const char **)args);
   GPR_ASSERT(server);
   gpr_free(args[0]);
-  gpr_free(args[2]);
+  if (arg_shift) gpr_free(args[1]);
+  gpr_free(args[2 + arg_shift]);
+  gpr_free(root);
 
   gpr_sleep_until(gpr_time_add(gpr_now(GPR_CLOCK_REALTIME),
                                gpr_time_from_seconds(5, GPR_TIMESPAN)));
diff --git a/test/core/iomgr/timer_heap_test.c b/test/core/iomgr/timer_heap_test.c
index cd34696..dd23a99 100644
--- a/test/core/iomgr/timer_heap_test.c
+++ b/test/core/iomgr/timer_heap_test.c
@@ -177,11 +177,12 @@
 
   grpc_timer_heap pq;
 
-  elem_struct elems[1000];
+  static const size_t elems_size = 1000;
+  elem_struct *elems = gpr_malloc(elems_size * sizeof(elem_struct));
   size_t num_inserted = 0;
 
   grpc_timer_heap_init(&pq);
-  memset(elems, 0, sizeof(elems));
+  memset(elems, 0, elems_size);
 
   for (size_t round = 0; round < 10000; round++) {
     int r = rand() % 1000;
@@ -209,7 +210,7 @@
       if (num_inserted > 0) {
         grpc_timer *top = grpc_timer_heap_top(&pq);
         grpc_timer_heap_pop(&pq);
-        for (size_t i = 0; i < GPR_ARRAY_SIZE(elems); i++) {
+        for (size_t i = 0; i < elems_size; i++) {
           if (top == &elems[i].elem) {
             GPR_ASSERT(elems[i].inserted);
             elems[i].inserted = false;
@@ -222,7 +223,7 @@
 
     if (num_inserted) {
       gpr_timespec *min_deadline = NULL;
-      for (size_t i = 0; i < GPR_ARRAY_SIZE(elems); i++) {
+      for (size_t i = 0; i < elems_size; i++) {
         if (elems[i].inserted) {
           if (min_deadline == NULL) {
             min_deadline = &elems[i].elem.deadline;
@@ -239,6 +240,7 @@
   }
 
   grpc_timer_heap_destroy(&pq);
+  gpr_free(elems);
 }
 
 static void shrink_test(void) {
diff --git a/test/core/iomgr/udp_server_test.c b/test/core/iomgr/udp_server_test.c
index 2e253d8..ce3c23b 100644
--- a/test/core/iomgr/udp_server_test.c
+++ b/test/core/iomgr/udp_server_test.c
@@ -31,8 +31,9 @@
  *
  */
 
-#include "src/core/iomgr/udp_server.h"
 #include "src/core/iomgr/iomgr.h"
+#include "src/core/iomgr/pollset_posix.h"
+#include "src/core/iomgr/udp_server.h"
 #include <grpc/support/log.h>
 #include <grpc/support/sync.h>
 #include <grpc/support/time.h>
@@ -48,6 +49,7 @@
 #define LOG_TEST(x) gpr_log(GPR_INFO, "%s", #x)
 
 static grpc_pollset g_pollset;
+static gpr_mu *g_mu;
 static int g_number_of_reads = 0;
 static int g_number_of_bytes_read = 0;
 
@@ -56,14 +58,14 @@
   char read_buffer[512];
   ssize_t byte_count;
 
-  gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+  gpr_mu_lock(g_mu);
   byte_count = recv(emfd->fd, read_buffer, sizeof(read_buffer), 0);
 
   g_number_of_reads++;
   g_number_of_bytes_read += (int)byte_count;
 
   grpc_pollset_kick(&g_pollset, NULL);
-  gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+  gpr_mu_unlock(g_mu);
 }
 
 static void test_no_op(void) {
@@ -142,7 +144,7 @@
   pollsets[0] = &g_pollset;
   grpc_udp_server_start(&exec_ctx, s, pollsets, 1, NULL);
 
-  gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+  gpr_mu_lock(g_mu);
 
   for (i = 0; i < number_of_clients; i++) {
     deadline = GRPC_TIMEOUT_SECONDS_TO_DEADLINE(10);
@@ -155,19 +157,19 @@
     GPR_ASSERT(5 == write(clifd, "hello", 5));
     while (g_number_of_reads == number_of_reads_before &&
            gpr_time_cmp(deadline, gpr_now(deadline.clock_type)) > 0) {
-      grpc_pollset_worker worker;
+      grpc_pollset_worker *worker = NULL;
       grpc_pollset_work(&exec_ctx, &g_pollset, &worker,
                         gpr_now(GPR_CLOCK_MONOTONIC), deadline);
-      gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+      gpr_mu_unlock(g_mu);
       grpc_exec_ctx_finish(&exec_ctx);
-      gpr_mu_lock(GRPC_POLLSET_MU(&g_pollset));
+      gpr_mu_lock(g_mu);
     }
     GPR_ASSERT(g_number_of_reads == number_of_reads_before + 1);
     close(clifd);
   }
   GPR_ASSERT(g_number_of_bytes_read == 5 * number_of_clients);
 
-  gpr_mu_unlock(GRPC_POLLSET_MU(&g_pollset));
+  gpr_mu_unlock(g_mu);
 
   grpc_udp_server_destroy(&exec_ctx, s, NULL);
   grpc_exec_ctx_finish(&exec_ctx);
@@ -181,8 +183,8 @@
   grpc_closure destroyed;
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   grpc_test_init(argc, argv);
-  grpc_iomgr_init();
-  grpc_pollset_init(&g_pollset);
+  grpc_init();
+  grpc_pollset_init(&g_pollset, &g_mu);
 
   test_no_op();
   test_no_op_with_start();
diff --git a/test/core/security/security_connector_test.c b/test/core/security/security_connector_test.c
index 420e3a4..609d874 100644
--- a/test/core/security/security_connector_test.c
+++ b/test/core/security/security_connector_test.c
@@ -80,13 +80,14 @@
 
 static int check_ssl_peer_equivalence(const tsi_peer *original,
                                       const tsi_peer *reconstructed) {
-  /* The reconstructed peer only has CN and SAN properties. */
+  /* The reconstructed peer only has CN, SAN and pem cert properties. */
   size_t i;
   for (i = 0; i < original->property_count; i++) {
     const tsi_peer_property *prop = &original->properties[i];
     if ((strcmp(prop->name, TSI_X509_SUBJECT_COMMON_NAME_PEER_PROPERTY) == 0) ||
         (strcmp(prop->name, TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY) ==
-         0)) {
+         0) ||
+        (strcmp(prop->name, TSI_X509_PEM_CERT_PROPERTY) == 0)) {
       if (!check_peer_property(reconstructed, prop)) return 0;
     }
   }
@@ -164,24 +165,50 @@
   return 1;
 }
 
+static int check_x509_pem_cert(const grpc_auth_context *ctx,
+                               const char *expected_pem_cert) {
+  grpc_auth_property_iterator it = grpc_auth_context_find_properties_by_name(
+      ctx, GRPC_X509_PEM_CERT_PROPERTY_NAME);
+  const grpc_auth_property *prop = grpc_auth_property_iterator_next(&it);
+  if (prop == NULL) {
+    gpr_log(GPR_ERROR, "Pem certificate property not found.");
+    return 0;
+  }
+  if (strncmp(prop->value, expected_pem_cert, prop->value_length) != 0) {
+    gpr_log(GPR_ERROR, "Expected pem cert %s and got %s", expected_pem_cert,
+            prop->value);
+    return 0;
+  }
+  if (grpc_auth_property_iterator_next(&it) != NULL) {
+    gpr_log(GPR_ERROR, "Expected only one property for pem cert.");
+    return 0;
+  }
+  return 1;
+}
+
 static void test_cn_only_ssl_peer_to_auth_context(void) {
   tsi_peer peer;
   tsi_peer rpeer;
   grpc_auth_context *ctx;
   const char *expected_cn = "cn1";
-  GPR_ASSERT(tsi_construct_peer(2, &peer) == TSI_OK);
+  const char *expected_pem_cert = "pem_cert1";
+  GPR_ASSERT(tsi_construct_peer(3, &peer) == TSI_OK);
   GPR_ASSERT(tsi_construct_string_peer_property_from_cstring(
                  TSI_CERTIFICATE_TYPE_PEER_PROPERTY, TSI_X509_CERTIFICATE_TYPE,
                  &peer.properties[0]) == TSI_OK);
   GPR_ASSERT(tsi_construct_string_peer_property_from_cstring(
                  TSI_X509_SUBJECT_COMMON_NAME_PEER_PROPERTY, expected_cn,
                  &peer.properties[1]) == TSI_OK);
+  GPR_ASSERT(tsi_construct_string_peer_property_from_cstring(
+                 TSI_X509_PEM_CERT_PROPERTY, expected_pem_cert,
+                 &peer.properties[2]) == TSI_OK);
   ctx = tsi_ssl_peer_to_auth_context(&peer);
   GPR_ASSERT(ctx != NULL);
   GPR_ASSERT(grpc_auth_context_peer_is_authenticated(ctx));
   GPR_ASSERT(check_identity(ctx, GRPC_X509_CN_PROPERTY_NAME, &expected_cn, 1));
   GPR_ASSERT(check_transport_security_type(ctx));
   GPR_ASSERT(check_x509_cn(ctx, expected_cn));
+  GPR_ASSERT(check_x509_pem_cert(ctx, expected_pem_cert));
 
   rpeer = tsi_shallow_peer_from_ssl_auth_context(ctx);
   GPR_ASSERT(check_ssl_peer_equivalence(&peer, &rpeer));
@@ -197,7 +224,8 @@
   grpc_auth_context *ctx;
   const char *expected_cn = "cn1";
   const char *expected_san = "san1";
-  GPR_ASSERT(tsi_construct_peer(3, &peer) == TSI_OK);
+  const char *expected_pem_cert = "pem_cert1";
+  GPR_ASSERT(tsi_construct_peer(4, &peer) == TSI_OK);
   GPR_ASSERT(tsi_construct_string_peer_property_from_cstring(
                  TSI_CERTIFICATE_TYPE_PEER_PROPERTY, TSI_X509_CERTIFICATE_TYPE,
                  &peer.properties[0]) == TSI_OK);
@@ -207,6 +235,9 @@
   GPR_ASSERT(tsi_construct_string_peer_property_from_cstring(
                  TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY, expected_san,
                  &peer.properties[2]) == TSI_OK);
+  GPR_ASSERT(tsi_construct_string_peer_property_from_cstring(
+                 TSI_X509_PEM_CERT_PROPERTY, expected_pem_cert,
+                 &peer.properties[3]) == TSI_OK);
   ctx = tsi_ssl_peer_to_auth_context(&peer);
   GPR_ASSERT(ctx != NULL);
   GPR_ASSERT(grpc_auth_context_peer_is_authenticated(ctx));
@@ -214,6 +245,7 @@
       check_identity(ctx, GRPC_X509_SAN_PROPERTY_NAME, &expected_san, 1));
   GPR_ASSERT(check_transport_security_type(ctx));
   GPR_ASSERT(check_x509_cn(ctx, expected_cn));
+  GPR_ASSERT(check_x509_pem_cert(ctx, expected_pem_cert));
 
   rpeer = tsi_shallow_peer_from_ssl_auth_context(ctx);
   GPR_ASSERT(check_ssl_peer_equivalence(&peer, &rpeer));
@@ -229,8 +261,9 @@
   grpc_auth_context *ctx;
   const char *expected_cn = "cn1";
   const char *expected_sans[] = {"san1", "san2", "san3"};
+  const char *expected_pem_cert = "pem_cert1";
   size_t i;
-  GPR_ASSERT(tsi_construct_peer(2 + GPR_ARRAY_SIZE(expected_sans), &peer) ==
+  GPR_ASSERT(tsi_construct_peer(3 + GPR_ARRAY_SIZE(expected_sans), &peer) ==
              TSI_OK);
   GPR_ASSERT(tsi_construct_string_peer_property_from_cstring(
                  TSI_CERTIFICATE_TYPE_PEER_PROPERTY, TSI_X509_CERTIFICATE_TYPE,
@@ -238,10 +271,13 @@
   GPR_ASSERT(tsi_construct_string_peer_property_from_cstring(
                  TSI_X509_SUBJECT_COMMON_NAME_PEER_PROPERTY, expected_cn,
                  &peer.properties[1]) == TSI_OK);
+  GPR_ASSERT(tsi_construct_string_peer_property_from_cstring(
+                 TSI_X509_PEM_CERT_PROPERTY, expected_pem_cert,
+                 &peer.properties[2]) == TSI_OK);
   for (i = 0; i < GPR_ARRAY_SIZE(expected_sans); i++) {
     GPR_ASSERT(tsi_construct_string_peer_property_from_cstring(
                    TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY,
-                   expected_sans[i], &peer.properties[2 + i]) == TSI_OK);
+                   expected_sans[i], &peer.properties[3 + i]) == TSI_OK);
   }
   ctx = tsi_ssl_peer_to_auth_context(&peer);
   GPR_ASSERT(ctx != NULL);
@@ -250,6 +286,7 @@
                             GPR_ARRAY_SIZE(expected_sans)));
   GPR_ASSERT(check_transport_security_type(ctx));
   GPR_ASSERT(check_x509_cn(ctx, expected_cn));
+  GPR_ASSERT(check_x509_pem_cert(ctx, expected_pem_cert));
 
   rpeer = tsi_shallow_peer_from_ssl_auth_context(ctx);
   GPR_ASSERT(check_ssl_peer_equivalence(&peer, &rpeer));
@@ -265,9 +302,10 @@
   tsi_peer rpeer;
   grpc_auth_context *ctx;
   const char *expected_cn = "cn1";
+  const char *expected_pem_cert = "pem_cert1";
   const char *expected_sans[] = {"san1", "san2", "san3"};
   size_t i;
-  GPR_ASSERT(tsi_construct_peer(4 + GPR_ARRAY_SIZE(expected_sans), &peer) ==
+  GPR_ASSERT(tsi_construct_peer(5 + GPR_ARRAY_SIZE(expected_sans), &peer) ==
              TSI_OK);
   GPR_ASSERT(tsi_construct_string_peer_property_from_cstring(
                  TSI_CERTIFICATE_TYPE_PEER_PROPERTY, TSI_X509_CERTIFICATE_TYPE,
@@ -279,10 +317,13 @@
                  &peer.properties[2]) == TSI_OK);
   GPR_ASSERT(tsi_construct_string_peer_property_from_cstring(
                  "chapi", "chapo", &peer.properties[3]) == TSI_OK);
+  GPR_ASSERT(tsi_construct_string_peer_property_from_cstring(
+                 TSI_X509_PEM_CERT_PROPERTY, expected_pem_cert,
+                 &peer.properties[4]) == TSI_OK);
   for (i = 0; i < GPR_ARRAY_SIZE(expected_sans); i++) {
     GPR_ASSERT(tsi_construct_string_peer_property_from_cstring(
                    TSI_X509_SUBJECT_ALTERNATIVE_NAME_PEER_PROPERTY,
-                   expected_sans[i], &peer.properties[4 + i]) == TSI_OK);
+                   expected_sans[i], &peer.properties[5 + i]) == TSI_OK);
   }
   ctx = tsi_ssl_peer_to_auth_context(&peer);
   GPR_ASSERT(ctx != NULL);
@@ -291,6 +332,7 @@
                             GPR_ARRAY_SIZE(expected_sans)));
   GPR_ASSERT(check_transport_security_type(ctx));
   GPR_ASSERT(check_x509_cn(ctx, expected_cn));
+  GPR_ASSERT(check_x509_pem_cert(ctx, expected_pem_cert));
 
   rpeer = tsi_shallow_peer_from_ssl_auth_context(ctx);
   GPR_ASSERT(check_ssl_peer_equivalence(&peer, &rpeer));
diff --git a/test/core/support/backoff_test.c b/test/core/support/backoff_test.c
new file mode 100644
index 0000000..870b60b
--- /dev/null
+++ b/test/core/support/backoff_test.c
@@ -0,0 +1,107 @@
+/*
+ *
+ * Copyright 2016, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "src/core/support/backoff.h"
+
+#include <grpc/support/log.h>
+
+#include "test/core/util/test_config.h"
+
+static void test_constant_backoff(void) {
+  gpr_backoff backoff;
+  gpr_backoff_init(&backoff, 1.0, 0.0, 1000, 1000);
+
+  gpr_timespec now = gpr_time_0(GPR_TIMESPAN);
+  gpr_timespec next = gpr_backoff_begin(&backoff, now);
+  GPR_ASSERT(gpr_time_to_millis(gpr_time_sub(next, now)) == 1000);
+  for (int i = 0; i < 10000; i++) {
+    next = gpr_backoff_step(&backoff, now);
+    GPR_ASSERT(gpr_time_to_millis(gpr_time_sub(next, now)) == 1000);
+    now = next;
+  }
+}
+
+static void test_no_jitter_backoff(void) {
+  gpr_backoff backoff;
+  gpr_backoff_init(&backoff, 2.0, 0.0, 1, 513);
+
+  gpr_timespec now = gpr_time_0(GPR_TIMESPAN);
+  gpr_timespec next = gpr_backoff_begin(&backoff, now);
+  GPR_ASSERT(gpr_time_cmp(gpr_time_from_millis(1, GPR_TIMESPAN), next) == 0);
+  now = next;
+  next = gpr_backoff_step(&backoff, now);
+  GPR_ASSERT(gpr_time_cmp(gpr_time_from_millis(3, GPR_TIMESPAN), next) == 0);
+  now = next;
+  next = gpr_backoff_step(&backoff, now);
+  GPR_ASSERT(gpr_time_cmp(gpr_time_from_millis(7, GPR_TIMESPAN), next) == 0);
+  now = next;
+  next = gpr_backoff_step(&backoff, now);
+  GPR_ASSERT(gpr_time_cmp(gpr_time_from_millis(15, GPR_TIMESPAN), next) == 0);
+  now = next;
+  next = gpr_backoff_step(&backoff, now);
+  GPR_ASSERT(gpr_time_cmp(gpr_time_from_millis(31, GPR_TIMESPAN), next) == 0);
+  now = next;
+  next = gpr_backoff_step(&backoff, now);
+  GPR_ASSERT(gpr_time_cmp(gpr_time_from_millis(63, GPR_TIMESPAN), next) == 0);
+  now = next;
+  next = gpr_backoff_step(&backoff, now);
+  GPR_ASSERT(gpr_time_cmp(gpr_time_from_millis(127, GPR_TIMESPAN), next) == 0);
+  now = next;
+  next = gpr_backoff_step(&backoff, now);
+  GPR_ASSERT(gpr_time_cmp(gpr_time_from_millis(255, GPR_TIMESPAN), next) == 0);
+  now = next;
+  next = gpr_backoff_step(&backoff, now);
+  GPR_ASSERT(gpr_time_cmp(gpr_time_from_millis(511, GPR_TIMESPAN), next) == 0);
+  now = next;
+  next = gpr_backoff_step(&backoff, now);
+  GPR_ASSERT(gpr_time_cmp(gpr_time_from_millis(1023, GPR_TIMESPAN), next) == 0);
+  now = next;
+  next = gpr_backoff_step(&backoff, now);
+  GPR_ASSERT(gpr_time_cmp(gpr_time_from_millis(1536, GPR_TIMESPAN), next) == 0);
+  now = next;
+  next = gpr_backoff_step(&backoff, now);
+  GPR_ASSERT(gpr_time_cmp(gpr_time_from_millis(2049, GPR_TIMESPAN), next) == 0);
+  now = next;
+  next = gpr_backoff_step(&backoff, now);
+  GPR_ASSERT(gpr_time_cmp(gpr_time_from_millis(2562, GPR_TIMESPAN), next) == 0);
+}
+
+int main(int argc, char **argv) {
+  grpc_test_init(argc, argv);
+  gpr_time_init();
+
+  test_constant_backoff();
+  test_no_jitter_backoff();
+
+  return 0;
+}
diff --git a/test/core/support/load_file_test.c b/test/core/support/load_file_test.c
index e6ba617..70189b7 100644
--- a/test/core/support/load_file_test.c
+++ b/test/core/support/load_file_test.c
@@ -135,33 +135,33 @@
   gpr_slice slice;
   int success;
   char *tmp_name;
-  unsigned char buffer[124631];
+  static const size_t buffer_size = 124631;
+  unsigned char *buffer = gpr_malloc(buffer_size);
   unsigned char *current;
   size_t i;
 
   LOG_TEST_NAME("test_load_big_file");
 
-  for (i = 0; i < sizeof(buffer); i++) {
-    buffer[i] = 42;
-  }
+  memset(buffer, 42, buffer_size);
 
   tmp = gpr_tmpfile(prefix, &tmp_name);
   GPR_ASSERT(tmp != NULL);
   GPR_ASSERT(tmp_name != NULL);
-  GPR_ASSERT(fwrite(buffer, 1, sizeof(buffer), tmp) == sizeof(buffer));
+  GPR_ASSERT(fwrite(buffer, 1, buffer_size, tmp) == buffer_size);
   fclose(tmp);
 
   slice = gpr_load_file(tmp_name, 0, &success);
   GPR_ASSERT(success == 1);
-  GPR_ASSERT(GPR_SLICE_LENGTH(slice) == sizeof(buffer));
+  GPR_ASSERT(GPR_SLICE_LENGTH(slice) == buffer_size);
   current = GPR_SLICE_START_PTR(slice);
-  for (i = 0; i < sizeof(buffer); i++) {
+  for (i = 0; i < buffer_size; i++) {
     GPR_ASSERT(current[i] == 42);
   }
 
   remove(tmp_name);
   gpr_free(tmp_name);
   gpr_slice_unref(slice);
+  gpr_free(buffer);
 }
 
 int main(int argc, char **argv) {
diff --git a/test/core/support/thd_test.c b/test/core/support/thd_test.c
index f7807d2..0c176da 100644
--- a/test/core/support/thd_test.c
+++ b/test/core/support/thd_test.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -41,6 +41,8 @@
 #include <grpc/support/time.h>
 #include "test/core/util/test_config.h"
 
+#define NUM_THREADS 300
+
 struct test {
   gpr_mu mu;
   int n;
@@ -79,15 +81,14 @@
 static void test(void) {
   int i;
   gpr_thd_id thd;
-  gpr_thd_id thds[1000];
+  gpr_thd_id thds[NUM_THREADS];
   struct test t;
-  int n = 1000;
   gpr_thd_options options = gpr_thd_options_default();
   gpr_mu_init(&t.mu);
   gpr_cv_init(&t.done_cv);
-  t.n = n;
+  t.n = NUM_THREADS;
   t.is_done = 0;
-  for (i = 0; i != n; i++) {
+  for (i = 0; i < NUM_THREADS; i++) {
     GPR_ASSERT(gpr_thd_new(&thd, &thd_body, &t, NULL));
   }
   gpr_mu_lock(&t.mu);
@@ -97,10 +98,10 @@
   gpr_mu_unlock(&t.mu);
   GPR_ASSERT(t.n == 0);
   gpr_thd_options_set_joinable(&options);
-  for (i = 0; i < n; i++) {
+  for (i = 0; i < NUM_THREADS; i++) {
     GPR_ASSERT(gpr_thd_new(&thds[i], &thd_body_joinable, NULL, &options));
   }
-  for (i = 0; i < n; i++) {
+  for (i = 0; i < NUM_THREADS; i++) {
     gpr_thd_join(thds[i]);
   }
 }
diff --git a/test/core/surface/concurrent_connectivity_test.c b/test/core/surface/concurrent_connectivity_test.c
index 4d3b7bf..96761b0 100644
--- a/test/core/surface/concurrent_connectivity_test.c
+++ b/test/core/surface/concurrent_connectivity_test.c
@@ -40,29 +40,27 @@
 #include "test/core/util/test_config.h"
 
 #define NUM_THREADS 100
-static grpc_channel* channels[NUM_THREADS];
-static grpc_completion_queue* queues[NUM_THREADS];
+#define NUM_OUTER_LOOPS 10
+#define NUM_INNER_LOOPS 10
+#define DELAY_MILLIS 10
+#define POLL_MILLIS 3000
 
-void create_loop_destroy(void* actually_an_int) {
-  int thread_index = (int)(intptr_t)(actually_an_int);
-  for (int i = 0; i < 10; ++i) {
+void create_loop_destroy(void* unused) {
+  for (int i = 0; i < NUM_OUTER_LOOPS; ++i) {
     grpc_completion_queue* cq = grpc_completion_queue_create(NULL);
     grpc_channel* chan = grpc_insecure_channel_create("localhost", NULL, NULL);
 
-    channels[thread_index] = chan;
-    queues[thread_index] = cq;
-
-    for (int j = 0; j < 10; ++j) {
-      gpr_timespec later_time = GRPC_TIMEOUT_MILLIS_TO_DEADLINE(10);
+    for (int j = 0; j < NUM_INNER_LOOPS; ++j) {
+      gpr_timespec later_time = GRPC_TIMEOUT_MILLIS_TO_DEADLINE(DELAY_MILLIS);
       grpc_connectivity_state state =
           grpc_channel_check_connectivity_state(chan, 1);
       grpc_channel_watch_connectivity_state(chan, state, later_time, cq, NULL);
-      GPR_ASSERT(grpc_completion_queue_next(cq,
-                                            GRPC_TIMEOUT_SECONDS_TO_DEADLINE(3),
-                                            NULL).type == GRPC_OP_COMPLETE);
+      gpr_timespec poll_time = GRPC_TIMEOUT_MILLIS_TO_DEADLINE(POLL_MILLIS);
+      GPR_ASSERT(grpc_completion_queue_next(cq, poll_time, NULL).type ==
+                 GRPC_OP_COMPLETE);
     }
-    grpc_channel_destroy(channels[thread_index]);
-    grpc_completion_queue_destroy(queues[thread_index]);
+    grpc_channel_destroy(chan);
+    grpc_completion_queue_destroy(cq);
   }
 }
 
@@ -70,12 +68,12 @@
   grpc_test_init(argc, argv);
   grpc_init();
   gpr_thd_id threads[NUM_THREADS];
-  for (intptr_t i = 0; i < NUM_THREADS; ++i) {
+  for (size_t i = 0; i < NUM_THREADS; ++i) {
     gpr_thd_options options = gpr_thd_options_default();
     gpr_thd_options_set_joinable(&options);
-    gpr_thd_new(&threads[i], create_loop_destroy, (void*)i, &options);
+    gpr_thd_new(&threads[i], create_loop_destroy, NULL, &options);
   }
-  for (int i = 0; i < NUM_THREADS; ++i) {
+  for (size_t i = 0; i < NUM_THREADS; ++i) {
     gpr_thd_join(threads[i]);
   }
   grpc_shutdown();
diff --git a/test/core/util/port_posix.c b/test/core/util/port_posix.c
index ba382d2..5c0b271 100644
--- a/test/core/util/port_posix.c
+++ b/test/core/util/port_posix.c
@@ -38,7 +38,6 @@
 #include "test/core/util/port.h"
 
 #include <errno.h>
-#include <math.h>
 #include <netinet/in.h>
 #include <stdio.h>
 #include <string.h>
@@ -50,8 +49,8 @@
 #include <grpc/support/log.h>
 #include <grpc/support/string_util.h>
 
-#include "src/core/httpcli/httpcli.h"
 #include "src/core/support/env.h"
+#include "test/core/util/port_server_client.h"
 
 #define NUM_RANDOM_PORTS_TO_PICK 100
 
@@ -68,76 +67,12 @@
   return 0;
 }
 
-typedef struct freereq {
-  gpr_mu *mu;
-  grpc_pollset *pollset;
-  int done;
-} freereq;
-
-static void destroy_pollset_and_shutdown(grpc_exec_ctx *exec_ctx, void *p,
-                                         bool success) {
-  grpc_pollset_destroy(p);
-  grpc_shutdown();
-}
-
-static void freed_port_from_server(grpc_exec_ctx *exec_ctx, void *arg,
-                                   const grpc_httpcli_response *response) {
-  freereq *pr = arg;
-  gpr_mu_lock(pr->mu);
-  pr->done = 1;
-  grpc_pollset_kick(pr->pollset, NULL);
-  gpr_mu_unlock(pr->mu);
-}
-
-static void free_port_using_server(char *server, int port) {
-  grpc_httpcli_context context;
-  grpc_httpcli_request req;
-  freereq pr;
-  char *path;
-  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
-  grpc_closure shutdown_closure;
-
-  grpc_init();
-
-  memset(&pr, 0, sizeof(pr));
-  memset(&req, 0, sizeof(req));
-
-  pr.pollset = gpr_malloc(grpc_pollset_size());
-  grpc_pollset_init(pr.pollset, &pr.mu);
-  grpc_closure_init(&shutdown_closure, destroy_pollset_and_shutdown,
-                    pr.pollset);
-
-  req.host = server;
-  gpr_asprintf(&path, "/drop/%d", port);
-  req.path = path;
-
-  grpc_httpcli_context_init(&context);
-  grpc_httpcli_get(&exec_ctx, &context, pr.pollset, &req,
-                   GRPC_TIMEOUT_SECONDS_TO_DEADLINE(10), freed_port_from_server,
-                   &pr);
-  gpr_mu_lock(pr.mu);
-  while (!pr.done) {
-    grpc_pollset_worker *worker = NULL;
-    grpc_pollset_work(&exec_ctx, pr.pollset, &worker,
-                      gpr_now(GPR_CLOCK_MONOTONIC),
-                      GRPC_TIMEOUT_SECONDS_TO_DEADLINE(1));
-  }
-  gpr_mu_unlock(pr.mu);
-
-  grpc_httpcli_context_destroy(&context);
-  grpc_exec_ctx_finish(&exec_ctx);
-  grpc_pollset_shutdown(&exec_ctx, pr.pollset, &shutdown_closure);
-  grpc_exec_ctx_finish(&exec_ctx);
-  gpr_free(pr.pollset);
-  gpr_free(path);
-}
-
-static void free_chosen_ports() {
+static void free_chosen_ports(void) {
   char *env = gpr_getenv("GRPC_TEST_PORT_SERVER");
   if (env != NULL) {
     size_t i;
     for (i = 0; i < num_chosen_ports; i++) {
-      free_port_using_server(env, chosen_ports[i]);
+      grpc_free_port_using_server(env, chosen_ports[i]);
     }
     gpr_free(env);
   }
@@ -205,102 +140,6 @@
   return 1;
 }
 
-typedef struct portreq {
-  gpr_mu *mu;
-  grpc_pollset *pollset;
-  int port;
-  int retries;
-  char *server;
-  grpc_httpcli_context *ctx;
-} portreq;
-
-static void got_port_from_server(grpc_exec_ctx *exec_ctx, void *arg,
-                                 const grpc_httpcli_response *response) {
-  size_t i;
-  int port = 0;
-  portreq *pr = arg;
-  int failed = 0;
-
-  if (!response) {
-    failed = 1;
-    gpr_log(GPR_DEBUG,
-            "failed port pick from server: retrying [response=NULL]");
-  } else if (response->status != 200) {
-    failed = 1;
-    gpr_log(GPR_DEBUG, "failed port pick from server: status=%d",
-            response->status);
-  }
-
-  if (failed) {
-    grpc_httpcli_request req;
-    memset(&req, 0, sizeof(req));
-    GPR_ASSERT(pr->retries < 10);
-    sleep(1 + (unsigned)(pow(1.3, pr->retries) * rand() / RAND_MAX));
-    pr->retries++;
-    req.host = pr->server;
-    req.path = "/get";
-    grpc_httpcli_get(exec_ctx, pr->ctx, pr->pollset, &req,
-                     GRPC_TIMEOUT_SECONDS_TO_DEADLINE(10), got_port_from_server,
-                     pr);
-    return;
-  }
-  GPR_ASSERT(response);
-  GPR_ASSERT(response->status == 200);
-  for (i = 0; i < response->body_length; i++) {
-    GPR_ASSERT(response->body[i] >= '0' && response->body[i] <= '9');
-    port = port * 10 + response->body[i] - '0';
-  }
-  GPR_ASSERT(port > 1024);
-  gpr_mu_lock(pr->mu);
-  pr->port = port;
-  grpc_pollset_kick(pr->pollset, NULL);
-  gpr_mu_unlock(pr->mu);
-}
-
-static int pick_port_using_server(char *server) {
-  grpc_httpcli_context context;
-  grpc_httpcli_request req;
-  portreq pr;
-  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
-  grpc_closure shutdown_closure;
-
-  grpc_init();
-
-  memset(&pr, 0, sizeof(pr));
-  memset(&req, 0, sizeof(req));
-  pr.pollset = gpr_malloc(grpc_pollset_size());
-  grpc_pollset_init(pr.pollset, &pr.mu);
-  grpc_closure_init(&shutdown_closure, destroy_pollset_and_shutdown,
-                    pr.pollset);
-  pr.port = -1;
-  pr.server = server;
-  pr.ctx = &context;
-
-  req.host = server;
-  req.path = "/get";
-
-  grpc_httpcli_context_init(&context);
-  grpc_httpcli_get(&exec_ctx, &context, pr.pollset, &req,
-                   GRPC_TIMEOUT_SECONDS_TO_DEADLINE(10), got_port_from_server,
-                   &pr);
-  grpc_exec_ctx_finish(&exec_ctx);
-  gpr_mu_lock(pr.mu);
-  while (pr.port == -1) {
-    grpc_pollset_worker *worker = NULL;
-    grpc_pollset_work(&exec_ctx, pr.pollset, &worker,
-                      gpr_now(GPR_CLOCK_MONOTONIC),
-                      GRPC_TIMEOUT_SECONDS_TO_DEADLINE(1));
-  }
-  gpr_mu_unlock(pr.mu);
-
-  grpc_httpcli_context_destroy(&context);
-  grpc_pollset_shutdown(&exec_ctx, pr.pollset, &shutdown_closure);
-  grpc_exec_ctx_finish(&exec_ctx);
-  gpr_free(pr.pollset);
-
-  return pr.port;
-}
-
 int grpc_pick_unused_port(void) {
   /* We repeatedly pick a port and then see whether or not it is
      available for use both as a TCP socket and a UDP socket.  First, we
@@ -320,7 +159,7 @@
 
   char *env = gpr_getenv("GRPC_TEST_PORT_SERVER");
   if (env) {
-    int port = pick_port_using_server(env);
+    int port = grpc_pick_port_using_server(env);
     gpr_free(env);
     if (port != 0) {
       chose_port(port);
diff --git a/test/core/util/port_server_client.c b/test/core/util/port_server_client.c
new file mode 100644
index 0000000..653ecb2
--- /dev/null
+++ b/test/core/util/port_server_client.c
@@ -0,0 +1,215 @@
+/*
+ *
+ * Copyright 2015-2016, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <grpc/support/port_platform.h>
+#include "test/core/util/test_config.h"
+
+#ifdef GRPC_TEST_PICK_PORT
+#include "test/core/util/port_server_client.h"
+
+#include <math.h>
+#include <string.h>
+
+#include <grpc/grpc.h>
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/string_util.h>
+#include <grpc/support/sync.h>
+#include <grpc/support/time.h>
+
+#include "src/core/httpcli/httpcli.h"
+
+typedef struct freereq {
+  gpr_mu *mu;
+  grpc_pollset *pollset;
+  int done;
+} freereq;
+
+static void destroy_pollset_and_shutdown(grpc_exec_ctx *exec_ctx, void *p,
+                                         bool success) {
+  grpc_pollset_destroy(p);
+  gpr_free(p);
+  grpc_shutdown();
+}
+
+static void freed_port_from_server(grpc_exec_ctx *exec_ctx, void *arg,
+                                   const grpc_httpcli_response *response) {
+  freereq *pr = arg;
+  gpr_mu_lock(pr->mu);
+  pr->done = 1;
+  grpc_pollset_kick(pr->pollset, NULL);
+  gpr_mu_unlock(pr->mu);
+}
+
+void grpc_free_port_using_server(char *server, int port) {
+  grpc_httpcli_context context;
+  grpc_httpcli_request req;
+  freereq pr;
+  char *path;
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+  grpc_closure *shutdown_closure;
+
+  grpc_init();
+
+  memset(&pr, 0, sizeof(pr));
+  memset(&req, 0, sizeof(req));
+
+  pr.pollset = gpr_malloc(grpc_pollset_size());
+  grpc_pollset_init(pr.pollset, &pr.mu);
+  shutdown_closure =
+      grpc_closure_create(destroy_pollset_and_shutdown, pr.pollset);
+
+  req.host = server;
+  gpr_asprintf(&path, "/drop/%d", port);
+  req.path = path;
+
+  grpc_httpcli_context_init(&context);
+  grpc_httpcli_get(&exec_ctx, &context, pr.pollset, &req,
+                   GRPC_TIMEOUT_SECONDS_TO_DEADLINE(10), freed_port_from_server,
+                   &pr);
+  gpr_mu_lock(pr.mu);
+  while (!pr.done) {
+    grpc_pollset_worker *worker = NULL;
+    grpc_pollset_work(&exec_ctx, pr.pollset, &worker,
+                      gpr_now(GPR_CLOCK_MONOTONIC),
+                      GRPC_TIMEOUT_SECONDS_TO_DEADLINE(1));
+  }
+  gpr_mu_unlock(pr.mu);
+
+  grpc_httpcli_context_destroy(&context);
+  grpc_exec_ctx_finish(&exec_ctx);
+  grpc_pollset_shutdown(&exec_ctx, pr.pollset, shutdown_closure);
+  grpc_exec_ctx_finish(&exec_ctx);
+  gpr_free(path);
+}
+
+typedef struct portreq {
+  gpr_mu *mu;
+  grpc_pollset *pollset;
+  int port;
+  int retries;
+  char *server;
+  grpc_httpcli_context *ctx;
+} portreq;
+
+static void got_port_from_server(grpc_exec_ctx *exec_ctx, void *arg,
+                                 const grpc_httpcli_response *response) {
+  size_t i;
+  int port = 0;
+  portreq *pr = arg;
+  int failed = 0;
+
+  if (!response) {
+    failed = 1;
+    gpr_log(GPR_DEBUG,
+            "failed port pick from server: retrying [response=NULL]");
+  } else if (response->status != 200) {
+    failed = 1;
+    gpr_log(GPR_DEBUG, "failed port pick from server: status=%d",
+            response->status);
+  }
+
+  if (failed) {
+    grpc_httpcli_request req;
+    memset(&req, 0, sizeof(req));
+    GPR_ASSERT(pr->retries < 10);
+    gpr_sleep_until(gpr_time_add(
+        gpr_now(GPR_CLOCK_REALTIME),
+        gpr_time_from_millis(
+            (int64_t)(1000.0 * (1 + pow(1.3, pr->retries) * rand() / RAND_MAX)),
+            GPR_TIMESPAN)));
+    pr->retries++;
+    req.host = pr->server;
+    req.path = "/get";
+    grpc_httpcli_get(exec_ctx, pr->ctx, pr->pollset, &req,
+                     GRPC_TIMEOUT_SECONDS_TO_DEADLINE(10), got_port_from_server,
+                     pr);
+    return;
+  }
+  GPR_ASSERT(response);
+  GPR_ASSERT(response->status == 200);
+  for (i = 0; i < response->body_length; i++) {
+    GPR_ASSERT(response->body[i] >= '0' && response->body[i] <= '9');
+    port = port * 10 + response->body[i] - '0';
+  }
+  GPR_ASSERT(port > 1024);
+  gpr_mu_lock(pr->mu);
+  pr->port = port;
+  grpc_pollset_kick(pr->pollset, NULL);
+  gpr_mu_unlock(pr->mu);
+}
+
+int grpc_pick_port_using_server(char *server) {
+  grpc_httpcli_context context;
+  grpc_httpcli_request req;
+  portreq pr;
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+  grpc_closure *shutdown_closure;
+
+  grpc_init();
+
+  memset(&pr, 0, sizeof(pr));
+  memset(&req, 0, sizeof(req));
+  pr.pollset = gpr_malloc(grpc_pollset_size());
+  grpc_pollset_init(pr.pollset, &pr.mu);
+  shutdown_closure =
+      grpc_closure_create(destroy_pollset_and_shutdown, pr.pollset);
+  pr.port = -1;
+  pr.server = server;
+  pr.ctx = &context;
+
+  req.host = server;
+  req.path = "/get";
+
+  grpc_httpcli_context_init(&context);
+  grpc_httpcli_get(&exec_ctx, &context, pr.pollset, &req,
+                   GRPC_TIMEOUT_SECONDS_TO_DEADLINE(10), got_port_from_server,
+                   &pr);
+  grpc_exec_ctx_finish(&exec_ctx);
+  gpr_mu_lock(pr.mu);
+  while (pr.port == -1) {
+    grpc_pollset_worker *worker = NULL;
+    grpc_pollset_work(&exec_ctx, pr.pollset, &worker,
+                      gpr_now(GPR_CLOCK_MONOTONIC),
+                      GRPC_TIMEOUT_SECONDS_TO_DEADLINE(1));
+  }
+  gpr_mu_unlock(pr.mu);
+
+  grpc_httpcli_context_destroy(&context);
+  grpc_pollset_shutdown(&exec_ctx, pr.pollset, shutdown_closure);
+  grpc_exec_ctx_finish(&exec_ctx);
+
+  return pr.port;
+}
+
+#endif  // GRPC_TEST_PICK_PORT
diff --git a/src/cpp/codegen/grpc_library.cc b/test/core/util/port_server_client.h
similarity index 81%
copy from src/cpp/codegen/grpc_library.cc
copy to test/core/util/port_server_client.h
index 48acec3..fc209cd 100644
--- a/src/cpp/codegen/grpc_library.cc
+++ b/test/core/util/port_server_client.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2016, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,10 +31,12 @@
  *
  */
 
-#include <grpc++/impl/codegen/grpc_library.h>
+#ifndef GRPC_TEST_CORE_UTIL_PORT_SERVER_CLIENT_H
+#define GRPC_TEST_CORE_UTIL_PORT_SERVER_CLIENT_H
 
-namespace grpc {
+// C interface to port_server.py
 
-GrpcLibraryInterface *g_glip = nullptr;
+int grpc_pick_port_using_server(char *server);
+void grpc_free_port_using_server(char *server, int port);
 
-}  // namespace grpc
+#endif  // GRPC_TEST_CORE_UTIL_PORT_SERVER_CLIENT_H
diff --git a/test/core/util/port_windows.c b/test/core/util/port_windows.c
index 3b20aeb..a810683 100644
--- a/test/core/util/port_windows.c
+++ b/test/core/util/port_windows.c
@@ -47,8 +47,8 @@
 #include <grpc/support/log.h>
 
 #include "src/core/support/env.h"
-#include "src/core/httpcli/httpcli.h"
 #include "src/core/iomgr/sockaddr_utils.h"
+#include "test/core/util/port_server_client.h"
 
 #define NUM_RANDOM_PORTS_TO_PICK 100
 
@@ -65,7 +65,18 @@
   return 0;
 }
 
-static void free_chosen_ports(void) { gpr_free(chosen_ports); }
+static void free_chosen_ports(void) {
+  char *env = gpr_getenv("GRPC_TEST_PORT_SERVER");
+  if (env != NULL) {
+    size_t i;
+    for (i = 0; i < num_chosen_ports; i++) {
+      grpc_free_port_using_server(env, chosen_ports[i]);
+    }
+    gpr_free(env);
+  }
+
+  gpr_free(chosen_ports);
+}
 
 static void chose_port(int port) {
   if (chosen_ports == NULL) {
@@ -128,80 +139,6 @@
   return 1;
 }
 
-typedef struct portreq {
-  grpc_pollset *pollset;
-  gpr_mu *mu;
-  int port;
-} portreq;
-
-static void got_port_from_server(grpc_exec_ctx *exec_ctx, void *arg,
-                                 const grpc_httpcli_response *response) {
-  size_t i;
-  int port = 0;
-  portreq *pr = arg;
-  GPR_ASSERT(response);
-  GPR_ASSERT(response->status == 200);
-  for (i = 0; i < response->body_length; i++) {
-    GPR_ASSERT(response->body[i] >= '0' && response->body[i] <= '9');
-    port = port * 10 + response->body[i] - '0';
-  }
-  GPR_ASSERT(port > 1024);
-  gpr_mu_lock(pr->mu);
-  pr->port = port;
-  grpc_pollset_kick(pr->pollset, NULL);
-  gpr_mu_unlock(pr->mu);
-}
-
-static void destroy_pollset_and_shutdown(grpc_exec_ctx *exec_ctx, void *p,
-                                         bool success) {
-  grpc_pollset_destroy(p);
-  grpc_shutdown();
-}
-
-static int pick_port_using_server(char *server) {
-  grpc_httpcli_context context;
-  grpc_httpcli_request req;
-  portreq pr;
-  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
-  grpc_closure destroy_pollset_closure;
-
-  grpc_init();
-
-  memset(&pr, 0, sizeof(pr));
-  memset(&req, 0, sizeof(req));
-  pr.pollset = gpr_malloc(grpc_pollset_size());
-  grpc_pollset_init(pr.pollset, &pr.mu);
-  pr.port = -1;
-
-  req.host = server;
-  req.path = "/get";
-
-  grpc_httpcli_context_init(&context);
-  grpc_httpcli_get(&exec_ctx, &context, pr.pollset, &req,
-                   GRPC_TIMEOUT_SECONDS_TO_DEADLINE(10), got_port_from_server,
-                   &pr);
-  gpr_mu_lock(pr.mu);
-  while (pr.port == -1) {
-    grpc_pollset_worker *worker = NULL;
-    grpc_pollset_work(&exec_ctx, pr.pollset, &worker,
-                      gpr_now(GPR_CLOCK_MONOTONIC),
-                      GRPC_TIMEOUT_SECONDS_TO_DEADLINE(1));
-    gpr_mu_unlock(pr.mu);
-    grpc_exec_ctx_flush(&exec_ctx);
-    gpr_mu_lock(pr.mu);
-  }
-  gpr_mu_unlock(pr.mu);
-
-  grpc_httpcli_context_destroy(&context);
-  grpc_closure_init(&destroy_pollset_closure, destroy_pollset_and_shutdown,
-                    &pr.pollset);
-  grpc_pollset_shutdown(&exec_ctx, pr.pollset, &destroy_pollset_closure);
-  gpr_free(pr.pollset);
-
-  grpc_exec_ctx_finish(&exec_ctx);
-  return pr.port;
-}
-
 int grpc_pick_unused_port(void) {
   /* We repeatedly pick a port and then see whether or not it is
      available for use both as a TCP socket and a UDP socket.  First, we
@@ -221,7 +158,7 @@
 
   char *env = gpr_getenv("GRPC_TEST_PORT_SERVER");
   if (env) {
-    int port = pick_port_using_server(env);
+    int port = grpc_pick_port_using_server(env);
     gpr_free(env);
     if (port != 0) {
       return port;
diff --git a/test/core/util/test_config.c b/test/core/util/test_config.c
index 14bfc95..bf672e8 100644
--- a/test/core/util/test_config.c
+++ b/test/core/util/test_config.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -33,11 +33,13 @@
 
 #include "test/core/util/test_config.h"
 
-#include <grpc/support/port_platform.h>
 #include <grpc/support/log.h>
-#include "src/core/support/string.h"
-#include <stdlib.h>
+#include <grpc/support/port_platform.h>
 #include <signal.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "src/core/support/string.h"
 
 double g_fixture_slowdown_factor = 1.0;
 
@@ -52,14 +54,125 @@
 #endif
 
 #if GPR_WINDOWS_CRASH_HANDLER
-LONG crash_handler(struct _EXCEPTION_POINTERS *ex_info) {
-  gpr_log(GPR_DEBUG, "Exception handler called, dumping information");
-  while (ex_info->ExceptionRecord) {
-    DWORD code = ex_info->ExceptionRecord->ExceptionCode;
-    DWORD flgs = ex_info->ExceptionRecord->ExceptionFlags;
-    PVOID addr = ex_info->ExceptionRecord->ExceptionAddress;
-    gpr_log("code: %x - flags: %d - address: %p", code, flgs, addr);
-    ex_info->ExceptionRecord = ex_info->ExceptionRecord->ExceptionRecord;
+#include <windows.h>
+
+#include <tchar.h>
+
+// disable warning 4091 - dbghelp.h is broken for msvc2015
+#pragma warning(disable : 4091)
+#define DBGHELP_TRANSLATE_TCHAR
+#include <dbghelp.h>
+
+#ifdef _MSC_VER
+#pragma comment(lib, "dbghelp.lib")
+#endif
+
+static void print_current_stack() {
+  typedef USHORT(WINAPI * CaptureStackBackTraceType)(
+      __in ULONG, __in ULONG, __out PVOID *, __out_opt PULONG);
+  CaptureStackBackTraceType func = (CaptureStackBackTraceType)(GetProcAddress(
+      LoadLibrary(_T("kernel32.dll")), "RtlCaptureStackBackTrace"));
+
+  if (func == NULL) return;  // WOE 29.SEP.2010
+
+// Quote from Microsoft Documentation:
+// ## Windows Server 2003 and Windows XP:
+// ## The sum of the FramesToSkip and FramesToCapture parameters must be less
+// than 63.
+#define MAX_CALLERS 62
+
+  void *callers_stack[MAX_CALLERS];
+  unsigned short frames;
+  SYMBOL_INFOW *symbol;
+  HANDLE process;
+  process = GetCurrentProcess();
+  SymInitialize(process, NULL, TRUE);
+  frames = (func)(0, MAX_CALLERS, callers_stack, NULL);
+  symbol =
+      (SYMBOL_INFOW *)calloc(sizeof(SYMBOL_INFOW) + 256 * sizeof(wchar_t), 1);
+  symbol->MaxNameLen = 255;
+  symbol->SizeOfStruct = sizeof(SYMBOL_INFOW);
+
+  const unsigned short MAX_CALLERS_SHOWN = 32;
+  frames = frames < MAX_CALLERS_SHOWN ? frames : MAX_CALLERS_SHOWN;
+  for (unsigned int i = 0; i < frames; i++) {
+    SymFromAddrW(process, (DWORD64)(callers_stack[i]), 0, symbol);
+    fwprintf(stderr, L"*** %d: %016I64X %ls - %016I64X\n", i,
+             (DWORD64)callers_stack[i], symbol->Name, (DWORD64)symbol->Address);
+  }
+
+  free(symbol);
+}
+
+static void print_stack_from_context(CONTEXT c) {
+  STACKFRAME s;  // in/out stackframe
+  memset(&s, 0, sizeof(s));
+  DWORD imageType;
+#ifdef _M_IX86
+  // normally, call ImageNtHeader() and use machine info from PE header
+  imageType = IMAGE_FILE_MACHINE_I386;
+  s.AddrPC.Offset = c.Eip;
+  s.AddrPC.Mode = AddrModeFlat;
+  s.AddrFrame.Offset = c.Ebp;
+  s.AddrFrame.Mode = AddrModeFlat;
+  s.AddrStack.Offset = c.Esp;
+  s.AddrStack.Mode = AddrModeFlat;
+#elif _M_X64
+  imageType = IMAGE_FILE_MACHINE_AMD64;
+  s.AddrPC.Offset = c.Rip;
+  s.AddrPC.Mode = AddrModeFlat;
+  s.AddrFrame.Offset = c.Rsp;
+  s.AddrFrame.Mode = AddrModeFlat;
+  s.AddrStack.Offset = c.Rsp;
+  s.AddrStack.Mode = AddrModeFlat;
+#elif _M_IA64
+  imageType = IMAGE_FILE_MACHINE_IA64;
+  s.AddrPC.Offset = c.StIIP;
+  s.AddrPC.Mode = AddrModeFlat;
+  s.AddrFrame.Offset = c.IntSp;
+  s.AddrFrame.Mode = AddrModeFlat;
+  s.AddrBStore.Offset = c.RsBSP;
+  s.AddrBStore.Mode = AddrModeFlat;
+  s.AddrStack.Offset = c.IntSp;
+  s.AddrStack.Mode = AddrModeFlat;
+#else
+#error "Platform not supported!"
+#endif
+
+  HANDLE process = GetCurrentProcess();
+  HANDLE thread = GetCurrentThread();
+
+  SYMBOL_INFOW *symbol =
+      (SYMBOL_INFOW *)calloc(sizeof(SYMBOL_INFOW) + 256 * sizeof(wchar_t), 1);
+  symbol->MaxNameLen = 255;
+  symbol->SizeOfStruct = sizeof(SYMBOL_INFOW);
+
+  while (StackWalk(imageType, process, thread, &s, &c, 0,
+                   SymFunctionTableAccess, SymGetModuleBase, 0)) {
+    BOOL has_symbol =
+        SymFromAddrW(process, (DWORD64)(s.AddrPC.Offset), 0, symbol);
+    fwprintf(
+        stderr, L"*** %016I64X %ls - %016I64X\n", (DWORD64)(s.AddrPC.Offset),
+        has_symbol ? symbol->Name : L"<<no symbol>>", (DWORD64)symbol->Address);
+  }
+
+  free(symbol);
+}
+
+static LONG crash_handler(struct _EXCEPTION_POINTERS *ex_info) {
+  fprintf(stderr, "Exception handler called, dumping information\n");
+  bool try_to_print_stack = true;
+  PEXCEPTION_RECORD exrec = ex_info->ExceptionRecord;
+  while (exrec) {
+    DWORD code = exrec->ExceptionCode;
+    DWORD flgs = exrec->ExceptionFlags;
+    PVOID addr = exrec->ExceptionAddress;
+    if (code == EXCEPTION_STACK_OVERFLOW) try_to_print_stack = false;
+    fprintf(stderr, "code: %x - flags: %d - address: %p\n", code, flgs, addr);
+    exrec = exrec->ExceptionRecord;
+  }
+  if (try_to_print_stack) {
+    print_stack_from_context(*ex_info->ContextRecord);
   }
   if (IsDebuggerPresent()) {
     __debugbreak();
@@ -69,8 +182,9 @@
   return EXCEPTION_EXECUTE_HANDLER;
 }
 
-void abort_handler(int sig) {
-  gpr_log(GPR_DEBUG, "Abort handler called.");
+static void abort_handler(int sig) {
+  fprintf(stderr, "Abort handler called.\n");
+  print_current_stack(NULL);
   if (IsDebuggerPresent()) {
     __debugbreak();
   } else {
@@ -79,17 +193,20 @@
 }
 
 static void install_crash_handler() {
+  if (!SymInitialize(GetCurrentProcess(), NULL, TRUE)) {
+    fprintf(stderr, "SymInitialize failed: %d\n", GetLastError());
+  }
   SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER)crash_handler);
   _set_abort_behavior(0, _WRITE_ABORT_MSG);
   _set_abort_behavior(0, _CALL_REPORTFAULT);
   signal(SIGABRT, abort_handler);
 }
 #elif GPR_POSIX_CRASH_HANDLER
+#include <errno.h>
 #include <execinfo.h>
+#include <grpc/support/useful.h>
 #include <stdio.h>
 #include <string.h>
-#include <grpc/support/useful.h>
-#include <errno.h>
 
 static char g_alt_stack[MINSIGSTKSZ];
 
diff --git a/src/cpp/codegen/grpc_library.cc b/test/cpp/codegen/codegen_test.cc
similarity index 86%
copy from src/cpp/codegen/grpc_library.cc
copy to test/cpp/codegen/codegen_test.cc
index 48acec3..735755a 100644
--- a/src/cpp/codegen/grpc_library.cc
+++ b/test/cpp/codegen/codegen_test.cc
@@ -31,10 +31,19 @@
  *
  */
 
-#include <grpc++/impl/codegen/grpc_library.h>
+#include <gtest/gtest.h>
 
 namespace grpc {
+namespace {
 
-GrpcLibraryInterface *g_glip = nullptr;
+class CodegenTest : public ::testing::Test {};
 
+TEST_F(CodegenTest, Build) {}
+
+}  // namespace
 }  // namespace grpc
+
+int main(int argc, char** argv) {
+  ::testing::InitGoogleTest(&argc, argv);
+  return RUN_ALL_TESTS();
+}
diff --git a/test/cpp/end2end/async_end2end_test.cc b/test/cpp/end2end/async_end2end_test.cc
index 9ca3bf9..dc8c2bb 100644
--- a/test/cpp/end2end/async_end2end_test.cc
+++ b/test/cpp/end2end/async_end2end_test.cc
@@ -68,6 +68,7 @@
 namespace {
 
 void* tag(int i) { return (void*)(intptr_t)i; }
+int detag(void* p) { return static_cast<int>(reinterpret_cast<intptr_t>(p)); }
 
 #ifdef GPR_POSIX_SOCKET
 static int maybe_assert_non_blocking_poll(struct pollfd* pfds, nfds_t nfds,
@@ -106,37 +107,50 @@
 class Verifier {
  public:
   explicit Verifier(bool spin) : spin_(spin) {}
+  // Expect sets the expected ok value for a specific tag
   Verifier& Expect(int i, bool expect_ok) {
     expectations_[tag(i)] = expect_ok;
     return *this;
   }
 
+  // Next waits for 1 async tag to complete, checks its
+  // expectations, and returns the tag
+  int Next(CompletionQueue* cq, bool ignore_ok) {
+    bool ok;
+    void* got_tag;
+    if (spin_) {
+      for (;;) {
+        auto r = cq->AsyncNext(&got_tag, &ok, gpr_time_0(GPR_CLOCK_REALTIME));
+        if (r == CompletionQueue::TIMEOUT) continue;
+        if (r == CompletionQueue::GOT_EVENT) break;
+        gpr_log(GPR_ERROR, "unexpected result from AsyncNext");
+        abort();
+      }
+    } else {
+      EXPECT_TRUE(cq->Next(&got_tag, &ok));
+    }
+    auto it = expectations_.find(got_tag);
+    EXPECT_TRUE(it != expectations_.end());
+    if (!ignore_ok) {
+      EXPECT_EQ(it->second, ok);
+    }
+    expectations_.erase(it);
+    return detag(got_tag);
+  }
+
+  // Verify keeps calling Next until all currently set
+  // expected tags are complete
   void Verify(CompletionQueue* cq) { Verify(cq, false); }
 
+  // This version of Verify allows optionally ignoring the
+  // outcome of the expectation
   void Verify(CompletionQueue* cq, bool ignore_ok) {
     GPR_ASSERT(!expectations_.empty());
     while (!expectations_.empty()) {
-      bool ok;
-      void* got_tag;
-      if (spin_) {
-        for (;;) {
-          auto r = cq->AsyncNext(&got_tag, &ok, gpr_time_0(GPR_CLOCK_REALTIME));
-          if (r == CompletionQueue::TIMEOUT) continue;
-          if (r == CompletionQueue::GOT_EVENT) break;
-          gpr_log(GPR_ERROR, "unexpected result from AsyncNext");
-          abort();
-        }
-      } else {
-        EXPECT_TRUE(cq->Next(&got_tag, &ok));
-      }
-      auto it = expectations_.find(got_tag);
-      EXPECT_TRUE(it != expectations_.end());
-      if (!ignore_ok) {
-        EXPECT_EQ(it->second, ok);
-      }
-      expectations_.erase(it);
+      Next(cq, ignore_ok);
     }
   }
+  // This version of Verify stops after a certain deadline
   void Verify(CompletionQueue* cq,
               std::chrono::system_clock::time_point deadline) {
     if (expectations_.empty()) {
@@ -793,7 +807,8 @@
 }
 
 // This class is for testing scenarios where RPCs are cancelled on the server
-// by calling ServerContext::TryCancel()
+// by calling ServerContext::TryCancel(). Server uses AsyncNotifyWhenDone
+// API to check for cancellation
 class AsyncEnd2endServerTryCancelTest : public AsyncEnd2endTest {
  protected:
   typedef enum {
@@ -803,13 +818,6 @@
     CANCEL_AFTER_PROCESSING
   } ServerTryCancelRequestPhase;
 
-  void ServerTryCancel(ServerContext* context) {
-    EXPECT_FALSE(context->IsCancelled());
-    context->TryCancel();
-    gpr_log(GPR_INFO, "Server called TryCancel()");
-    EXPECT_TRUE(context->IsCancelled());
-  }
-
   // Helper for testing client-streaming RPCs which are cancelled on the server.
   // Depending on the value of server_try_cancel parameter, this will test one
   // of the following three scenarios:
@@ -843,6 +851,7 @@
 
     // On the server, request to be notified of 'RequestStream' calls
     // and receive the 'RequestStream' call just made by the client
+    srv_ctx.AsyncNotifyWhenDone(tag(11));
     service_.RequestRequestStream(&srv_ctx, &srv_stream, cq_.get(), cq_.get(),
                                   tag(2));
     Verifier(GetParam()).Expect(2, true).Verify(cq_.get());
@@ -858,9 +867,12 @@
 
     bool expected_server_cq_result = true;
     bool ignore_cq_result = false;
+    bool want_done_tag = false;
 
     if (server_try_cancel == CANCEL_BEFORE_PROCESSING) {
-      ServerTryCancel(&srv_ctx);
+      srv_ctx.TryCancel();
+      Verifier(GetParam()).Expect(11, true).Verify(cq_.get());
+      EXPECT_TRUE(srv_ctx.IsCancelled());
 
       // Since cancellation is done before server reads any results, we know
       // for sure that all cq results will return false from this point forward
@@ -868,22 +880,39 @@
     }
 
     std::thread* server_try_cancel_thd = NULL;
+
+    auto verif = Verifier(GetParam());
+
     if (server_try_cancel == CANCEL_DURING_PROCESSING) {
-      server_try_cancel_thd = new std::thread(
-          &AsyncEnd2endServerTryCancelTest::ServerTryCancel, this, &srv_ctx);
+      server_try_cancel_thd =
+          new std::thread(&ServerContext::TryCancel, &srv_ctx);
       // Server will cancel the RPC in a parallel thread while reading the
       // requests from the client. Since the cancellation can happen at anytime,
       // some of the cq results (i.e those until cancellation) might be true but
       // its non deterministic. So better to ignore the cq results
       ignore_cq_result = true;
+      // Expect that we might possibly see the done tag that
+      // indicates cancellation completion in this case
+      want_done_tag = true;
+      verif.Expect(11, true);
     }
 
     // Server reads 3 messages (tags 6, 7 and 8)
+    // But if want_done_tag is true, we might also see tag 11
     for (int tag_idx = 6; tag_idx <= 8; tag_idx++) {
       srv_stream.Read(&recv_request, tag(tag_idx));
-      Verifier(GetParam())
-          .Expect(tag_idx, expected_server_cq_result)
-          .Verify(cq_.get(), ignore_cq_result);
+      // Note that we'll add something to the verifier and verify that
+      // something was seen, but it might be tag 11 and not what we
+      // just added
+      int got_tag = verif.Expect(tag_idx, expected_server_cq_result)
+                        .Next(cq_.get(), ignore_cq_result);
+      GPR_ASSERT((got_tag == tag_idx) || (got_tag == 11 && want_done_tag));
+      if (got_tag == 11) {
+        EXPECT_TRUE(srv_ctx.IsCancelled());
+        want_done_tag = false;
+        // Now get the other entry that we were waiting on
+        EXPECT_EQ(verif.Next(cq_.get(), ignore_cq_result), tag_idx);
+      }
     }
 
     if (server_try_cancel_thd != NULL) {
@@ -892,7 +921,15 @@
     }
 
     if (server_try_cancel == CANCEL_AFTER_PROCESSING) {
-      ServerTryCancel(&srv_ctx);
+      srv_ctx.TryCancel();
+      want_done_tag = true;
+      verif.Expect(11, true);
+    }
+
+    if (want_done_tag) {
+      verif.Verify(cq_.get());
+      EXPECT_TRUE(srv_ctx.IsCancelled());
+      want_done_tag = false;
     }
 
     // The RPC has been cancelled at this point for sure (i.e irrespective of
@@ -945,6 +982,7 @@
     Verifier(GetParam()).Expect(1, true).Verify(cq_.get());
     // On the server, request to be notified of 'ResponseStream' calls and
     // receive the call just made by the client
+    srv_ctx.AsyncNotifyWhenDone(tag(11));
     service_.RequestResponseStream(&srv_ctx, &recv_request, &srv_stream,
                                    cq_.get(), cq_.get(), tag(2));
     Verifier(GetParam()).Expect(2, true).Verify(cq_.get());
@@ -952,9 +990,12 @@
 
     bool expected_cq_result = true;
     bool ignore_cq_result = false;
+    bool want_done_tag = false;
 
     if (server_try_cancel == CANCEL_BEFORE_PROCESSING) {
-      ServerTryCancel(&srv_ctx);
+      srv_ctx.TryCancel();
+      Verifier(GetParam()).Expect(11, true).Verify(cq_.get());
+      EXPECT_TRUE(srv_ctx.IsCancelled());
 
       // We know for sure that all cq results will be false from this point
       // since the server cancelled the RPC
@@ -962,24 +1003,41 @@
     }
 
     std::thread* server_try_cancel_thd = NULL;
+
+    auto verif = Verifier(GetParam());
+
     if (server_try_cancel == CANCEL_DURING_PROCESSING) {
-      server_try_cancel_thd = new std::thread(
-          &AsyncEnd2endServerTryCancelTest::ServerTryCancel, this, &srv_ctx);
+      server_try_cancel_thd =
+          new std::thread(&ServerContext::TryCancel, &srv_ctx);
 
       // Server will cancel the RPC in a parallel thread while writing responses
       // to the client. Since the cancellation can happen at anytime, some of
       // the cq results (i.e those until cancellation) might be true but it is
       // non deterministic. So better to ignore the cq results
       ignore_cq_result = true;
+      // Expect that we might possibly see the done tag that
+      // indicates cancellation completion in this case
+      want_done_tag = true;
+      verif.Expect(11, true);
     }
 
     // Server sends three messages (tags 3, 4 and 5)
+    // But if want_done tag is true, we might also see tag 11
     for (int tag_idx = 3; tag_idx <= 5; tag_idx++) {
       send_response.set_message("Pong " + std::to_string(tag_idx));
       srv_stream.Write(send_response, tag(tag_idx));
-      Verifier(GetParam())
-          .Expect(tag_idx, expected_cq_result)
-          .Verify(cq_.get(), ignore_cq_result);
+      // Note that we'll add something to the verifier and verify that
+      // something was seen, but it might be tag 11 and not what we
+      // just added
+      int got_tag = verif.Expect(tag_idx, expected_cq_result)
+                        .Next(cq_.get(), ignore_cq_result);
+      GPR_ASSERT((got_tag == tag_idx) || (got_tag == 11 && want_done_tag));
+      if (got_tag == 11) {
+        EXPECT_TRUE(srv_ctx.IsCancelled());
+        want_done_tag = false;
+        // Now get the other entry that we were waiting on
+        EXPECT_EQ(verif.Next(cq_.get(), ignore_cq_result), tag_idx);
+      }
     }
 
     if (server_try_cancel_thd != NULL) {
@@ -988,13 +1046,21 @@
     }
 
     if (server_try_cancel == CANCEL_AFTER_PROCESSING) {
-      ServerTryCancel(&srv_ctx);
+      srv_ctx.TryCancel();
+      want_done_tag = true;
+      verif.Expect(11, true);
 
       // Client reads may fail bacause it is notified that the stream is
       // cancelled.
       ignore_cq_result = true;
     }
 
+    if (want_done_tag) {
+      verif.Verify(cq_.get());
+      EXPECT_TRUE(srv_ctx.IsCancelled());
+      want_done_tag = false;
+    }
+
     // Client attemts to read the three messages from the server
     for (int tag_idx = 6; tag_idx <= 8; tag_idx++) {
       cli_stream->Read(&recv_response, tag(tag_idx));
@@ -1052,6 +1118,7 @@
 
     // On the server, request to be notified of the 'BidiStream' call and
     // receive the call just made by the client
+    srv_ctx.AsyncNotifyWhenDone(tag(11));
     service_.RequestBidiStream(&srv_ctx, &srv_stream, cq_.get(), cq_.get(),
                                tag(2));
     Verifier(GetParam()).Expect(2, true).Verify(cq_.get());
@@ -1063,9 +1130,12 @@
 
     bool expected_cq_result = true;
     bool ignore_cq_result = false;
+    bool want_done_tag = false;
 
     if (server_try_cancel == CANCEL_BEFORE_PROCESSING) {
-      ServerTryCancel(&srv_ctx);
+      srv_ctx.TryCancel();
+      Verifier(GetParam()).Expect(11, true).Verify(cq_.get());
+      EXPECT_TRUE(srv_ctx.IsCancelled());
 
       // We know for sure that all cq results will be false from this point
       // since the server cancelled the RPC
@@ -1073,42 +1143,84 @@
     }
 
     std::thread* server_try_cancel_thd = NULL;
+
+    auto verif = Verifier(GetParam());
+
     if (server_try_cancel == CANCEL_DURING_PROCESSING) {
-      server_try_cancel_thd = new std::thread(
-          &AsyncEnd2endServerTryCancelTest::ServerTryCancel, this, &srv_ctx);
+      server_try_cancel_thd =
+          new std::thread(&ServerContext::TryCancel, &srv_ctx);
 
       // Since server is going to cancel the RPC in a parallel thread, some of
       // the cq results (i.e those until the cancellation) might be true. Since
       // that number is non-deterministic, it is better to ignore the cq results
       ignore_cq_result = true;
+      // Expect that we might possibly see the done tag that
+      // indicates cancellation completion in this case
+      want_done_tag = true;
+      verif.Expect(11, true);
     }
 
+    int got_tag;
     srv_stream.Read(&recv_request, tag(4));
-    Verifier(GetParam())
-        .Expect(4, expected_cq_result)
-        .Verify(cq_.get(), ignore_cq_result);
+    verif.Expect(4, expected_cq_result);
+    got_tag = verif.Next(cq_.get(), ignore_cq_result);
+    GPR_ASSERT((got_tag == 4) || (got_tag == 11 && want_done_tag));
+    if (got_tag == 11) {
+      EXPECT_TRUE(srv_ctx.IsCancelled());
+      want_done_tag = false;
+      // Now get the other entry that we were waiting on
+      EXPECT_EQ(verif.Next(cq_.get(), ignore_cq_result), 4);
+    }
 
     send_response.set_message("Pong");
     srv_stream.Write(send_response, tag(5));
-    Verifier(GetParam())
-        .Expect(5, expected_cq_result)
-        .Verify(cq_.get(), ignore_cq_result);
+    verif.Expect(5, expected_cq_result);
+    got_tag = verif.Next(cq_.get(), ignore_cq_result);
+    GPR_ASSERT((got_tag == 5) || (got_tag == 11 && want_done_tag));
+    if (got_tag == 11) {
+      EXPECT_TRUE(srv_ctx.IsCancelled());
+      want_done_tag = false;
+      // Now get the other entry that we were waiting on
+      EXPECT_EQ(verif.Next(cq_.get(), ignore_cq_result), 5);
+    }
 
     cli_stream->Read(&recv_response, tag(6));
-    Verifier(GetParam())
-        .Expect(6, expected_cq_result)
-        .Verify(cq_.get(), ignore_cq_result);
+    verif.Expect(6, expected_cq_result);
+    got_tag = verif.Next(cq_.get(), ignore_cq_result);
+    GPR_ASSERT((got_tag == 6) || (got_tag == 11 && want_done_tag));
+    if (got_tag == 11) {
+      EXPECT_TRUE(srv_ctx.IsCancelled());
+      want_done_tag = false;
+      // Now get the other entry that we were waiting on
+      EXPECT_EQ(verif.Next(cq_.get(), ignore_cq_result), 6);
+    }
 
     // This is expected to succeed in all cases
     cli_stream->WritesDone(tag(7));
-    Verifier(GetParam()).Expect(7, true).Verify(cq_.get());
+    verif.Expect(7, true);
+    got_tag = verif.Next(cq_.get(), ignore_cq_result);
+    GPR_ASSERT((got_tag == 7) || (got_tag == 11 && want_done_tag));
+    if (got_tag == 11) {
+      EXPECT_TRUE(srv_ctx.IsCancelled());
+      want_done_tag = false;
+      // Now get the other entry that we were waiting on
+      EXPECT_EQ(verif.Next(cq_.get(), ignore_cq_result), 7);
+    }
 
     // This is expected to fail in all cases i.e for all values of
     // server_try_cancel. This is because at this point, either there are no
     // more msgs from the client (because client called WritesDone) or the RPC
     // is cancelled on the server
     srv_stream.Read(&recv_request, tag(8));
-    Verifier(GetParam()).Expect(8, false).Verify(cq_.get());
+    verif.Expect(8, false);
+    got_tag = verif.Next(cq_.get(), ignore_cq_result);
+    GPR_ASSERT((got_tag == 8) || (got_tag == 11 && want_done_tag));
+    if (got_tag == 11) {
+      EXPECT_TRUE(srv_ctx.IsCancelled());
+      want_done_tag = false;
+      // Now get the other entry that we were waiting on
+      EXPECT_EQ(verif.Next(cq_.get(), ignore_cq_result), 8);
+    }
 
     if (server_try_cancel_thd != NULL) {
       server_try_cancel_thd->join();
@@ -1116,7 +1228,15 @@
     }
 
     if (server_try_cancel == CANCEL_AFTER_PROCESSING) {
-      ServerTryCancel(&srv_ctx);
+      srv_ctx.TryCancel();
+      want_done_tag = true;
+      verif.Expect(11, true);
+    }
+
+    if (want_done_tag) {
+      verif.Verify(cq_.get());
+      EXPECT_TRUE(srv_ctx.IsCancelled());
+      want_done_tag = false;
     }
 
     // The RPC has been cancelled at this point for sure (i.e irrespective of
diff --git a/test/cpp/interop/reconnect_interop_server.cc b/test/cpp/interop/reconnect_interop_server.cc
index 3602b8c..1f9147d 100644
--- a/test/cpp/interop/reconnect_interop_server.cc
+++ b/test/cpp/interop/reconnect_interop_server.cc
@@ -31,6 +31,8 @@
  *
  */
 
+// Test description at doc/connection-backoff-interop-test-description.md
+
 #include <signal.h>
 #include <unistd.h>
 
@@ -40,17 +42,17 @@
 #include <sstream>
 
 #include <gflags/gflags.h>
-#include <grpc/grpc.h>
-#include <grpc/support/log.h>
 #include <grpc++/server.h>
 #include <grpc++/server_builder.h>
 #include <grpc++/server_context.h>
+#include <grpc/grpc.h>
+#include <grpc/support/log.h>
 
-#include "test/core/util/reconnect_server.h"
-#include "test/cpp/util/test_config.h"
-#include "src/proto/grpc/testing/test.grpc.pb.h"
 #include "src/proto/grpc/testing/empty.grpc.pb.h"
 #include "src/proto/grpc/testing/messages.grpc.pb.h"
+#include "src/proto/grpc/testing/test.grpc.pb.h"
+#include "test/core/util/reconnect_server.h"
+#include "test/cpp/util/test_config.h"
 
 DEFINE_int32(control_port, 0, "Server port for controlling the server.");
 DEFINE_int32(retry_port, 0,
diff --git a/test/cpp/qps/async_streaming_ping_pong_test.cc b/test/cpp/qps/async_streaming_ping_pong_test.cc
index 9749932..d9fbb39 100644
--- a/test/cpp/qps/async_streaming_ping_pong_test.cc
+++ b/test/cpp/qps/async_streaming_ping_pong_test.cc
@@ -43,7 +43,7 @@
 namespace testing {
 
 static const int WARMUP = 5;
-static const int BENCHMARK = 10;
+static const int BENCHMARK = 5;
 
 static void RunAsyncStreamingPingPong() {
   gpr_log(GPR_INFO, "Running Async Streaming Ping Pong");
diff --git a/test/cpp/qps/async_unary_ping_pong_test.cc b/test/cpp/qps/async_unary_ping_pong_test.cc
index d801bdd..5ab8619 100644
--- a/test/cpp/qps/async_unary_ping_pong_test.cc
+++ b/test/cpp/qps/async_unary_ping_pong_test.cc
@@ -43,7 +43,7 @@
 namespace testing {
 
 static const int WARMUP = 5;
-static const int BENCHMARK = 10;
+static const int BENCHMARK = 5;
 
 static void RunAsyncUnaryPingPong() {
   gpr_log(GPR_INFO, "Running Async Unary Ping Pong");
diff --git a/test/cpp/qps/driver.cc b/test/cpp/qps/driver.cc
index bc8780f..6c05799 100644
--- a/test/cpp/qps/driver.cc
+++ b/test/cpp/qps/driver.cc
@@ -43,6 +43,7 @@
 #include <grpc/support/alloc.h>
 #include <grpc/support/host_port.h>
 #include <grpc/support/log.h>
+#include <gtest/gtest.h>
 
 #include "src/core/support/env.h"
 #include "src/proto/grpc/testing/services.grpc.pb.h"
@@ -120,11 +121,9 @@
 namespace runsc {
 
 // ClientContext allocator
-template <class T>
-static ClientContext* AllocContext(list<ClientContext>* contexts, T deadline) {
+static ClientContext* AllocContext(list<ClientContext>* contexts) {
   contexts->emplace_back();
   auto context = &contexts->back();
-  context->set_deadline(deadline);
   return context;
 }
 
@@ -196,9 +195,6 @@
   // Trim to just what we need
   workers.resize(num_clients + num_servers);
 
-  gpr_timespec deadline =
-      GRPC_TIMEOUT_SECONDS_TO_DEADLINE(warmup_seconds + benchmark_seconds + 20);
-
   // Start servers
   using runsc::ServerData;
   // servers is array rather than std::vector to avoid gcc-4.4 issues
@@ -248,7 +244,7 @@
     ServerArgs args;
     *args.mutable_setup() = server_config;
     servers[i].stream =
-        servers[i].stub->RunServer(runsc::AllocContext(&contexts, deadline));
+        servers[i].stub->RunServer(runsc::AllocContext(&contexts));
     GPR_ASSERT(servers[i].stream->Write(args));
     ServerStatus init_status;
     GPR_ASSERT(servers[i].stream->Read(&init_status));
@@ -304,7 +300,7 @@
     ClientArgs args;
     *args.mutable_setup() = per_client_config;
     clients[i].stream =
-        clients[i].stub->RunClient(runsc::AllocContext(&contexts, deadline));
+        clients[i].stub->RunClient(runsc::AllocContext(&contexts));
     GPR_ASSERT(clients[i].stream->Write(args));
     ClientStatus init_status;
     GPR_ASSERT(clients[i].stream->Read(&init_status));
@@ -342,7 +338,8 @@
   // Use gpr_sleep_until rather than this_thread::sleep_until to support
   // compilers that don't work with this_thread
   gpr_sleep_until(gpr_time_add(
-      start, gpr_time_from_seconds(benchmark_seconds, GPR_TIMESPAN)));
+      start,
+      gpr_time_from_seconds(warmup_seconds + benchmark_seconds, GPR_TIMESPAN)));
 
   // Finish a run
   std::unique_ptr<ScenarioResult> result(new ScenarioResult);
diff --git a/test/cpp/qps/generic_async_streaming_ping_pong_test.cc b/test/cpp/qps/generic_async_streaming_ping_pong_test.cc
index d9166ae..77ed11f 100644
--- a/test/cpp/qps/generic_async_streaming_ping_pong_test.cc
+++ b/test/cpp/qps/generic_async_streaming_ping_pong_test.cc
@@ -43,7 +43,7 @@
 namespace testing {
 
 static const int WARMUP = 5;
-static const int BENCHMARK = 10;
+static const int BENCHMARK = 5;
 
 static void RunGenericAsyncStreamingPingPong() {
   gpr_log(GPR_INFO, "Running Generic Async Streaming Ping Pong");
diff --git a/test/cpp/qps/qps_openloop_test.cc b/test/cpp/qps/qps_openloop_test.cc
index 27f266b..2ae0afb 100644
--- a/test/cpp/qps/qps_openloop_test.cc
+++ b/test/cpp/qps/qps_openloop_test.cc
@@ -44,7 +44,7 @@
 namespace testing {
 
 static const int WARMUP = 5;
-static const int BENCHMARK = 10;
+static const int BENCHMARK = 5;
 
 static void RunQPS() {
   gpr_log(GPR_INFO, "Running QPS test, open-loop");
diff --git a/test/cpp/qps/qps_test.cc b/test/cpp/qps/qps_test.cc
index 27aaf13..b6a2e1e 100644
--- a/test/cpp/qps/qps_test.cc
+++ b/test/cpp/qps/qps_test.cc
@@ -43,7 +43,7 @@
 namespace testing {
 
 static const int WARMUP = 20;
-static const int BENCHMARK = 40;
+static const int BENCHMARK = 20;
 
 static void RunQPS() {
   gpr_log(GPR_INFO, "Running QPS test");
diff --git a/test/cpp/qps/secure_sync_unary_ping_pong_test.cc b/test/cpp/qps/secure_sync_unary_ping_pong_test.cc
index 359310b..946c76f 100644
--- a/test/cpp/qps/secure_sync_unary_ping_pong_test.cc
+++ b/test/cpp/qps/secure_sync_unary_ping_pong_test.cc
@@ -43,7 +43,7 @@
 namespace testing {
 
 static const int WARMUP = 5;
-static const int BENCHMARK = 10;
+static const int BENCHMARK = 5;
 
 static void RunSynchronousUnaryPingPong() {
   gpr_log(GPR_INFO, "Running Synchronous Unary Ping Pong");
diff --git a/test/cpp/qps/server_async.cc b/test/cpp/qps/server_async.cc
index 2024e0b..d7b3f76 100644
--- a/test/cpp/qps/server_async.cc
+++ b/test/cpp/qps/server_async.cc
@@ -130,8 +130,7 @@
     }
   }
   ~AsyncQpsServerTest() {
-    auto deadline = GRPC_TIMEOUT_SECONDS_TO_DEADLINE(10);
-    server_->Shutdown(deadline);
+    server_->Shutdown();
     for (auto ss = shutdown_state_.begin(); ss != shutdown_state_.end(); ++ss) {
       (*ss)->set_shutdown();
     }
diff --git a/test/cpp/qps/sync_streaming_ping_pong_test.cc b/test/cpp/qps/sync_streaming_ping_pong_test.cc
index e02c14c..ee1bbc7 100644
--- a/test/cpp/qps/sync_streaming_ping_pong_test.cc
+++ b/test/cpp/qps/sync_streaming_ping_pong_test.cc
@@ -43,7 +43,7 @@
 namespace testing {
 
 static const int WARMUP = 5;
-static const int BENCHMARK = 10;
+static const int BENCHMARK = 5;
 
 static void RunSynchronousStreamingPingPong() {
   gpr_log(GPR_INFO, "Running Synchronous Streaming Ping Pong");
diff --git a/test/cpp/qps/sync_unary_ping_pong_test.cc b/test/cpp/qps/sync_unary_ping_pong_test.cc
index 9d363c0..4dccfee 100644
--- a/test/cpp/qps/sync_unary_ping_pong_test.cc
+++ b/test/cpp/qps/sync_unary_ping_pong_test.cc
@@ -43,7 +43,7 @@
 namespace testing {
 
 static const int WARMUP = 5;
-static const int BENCHMARK = 10;
+static const int BENCHMARK = 5;
 
 static void RunSynchronousUnaryPingPong() {
   gpr_log(GPR_INFO, "Running Synchronous Unary Ping Pong");
diff --git a/tools/README.md b/tools/README.md
index df4c6ef..cb6c22d 100644
--- a/tools/README.md
+++ b/tools/README.md
@@ -1,13 +1,16 @@
-buildgen: template renderer for our build system.
+buildgen: Template renderer for our build system.
 
-distrib: scripts to distribute language-specific packages.
+distrib: Scripts to distribute language-specific packages.
 
 dockerfile: Docker files to test gRPC.
 
 doxygen: gRPC C/C++ documentation generation via Doxygen.
 
-gce: scripts to help setup testing infrastructure on GCE.
+gce: Scripts to help setup testing infrastructure on GCE.
 
-jenkins: support for running tests on Jenkins.
+gcp: Helper scripts for interacting with various services on GCP (like Google
+container engine, BigQuery etc)
 
-run_tests: scripts to run gRPC tests in parallel.
+jenkins: Support for running tests on Jenkins.
+
+run_tests: Scripts to run gRPC tests in parallel.
diff --git a/tools/distrib/check_copyright.py b/tools/distrib/check_copyright.py
index 99771f9..5badbf4 100755
--- a/tools/distrib/check_copyright.py
+++ b/tools/distrib/check_copyright.py
@@ -105,7 +105,7 @@
      for k, v in LICENSE_PREFIX.iteritems())
 
 if args.precommit:
-  FILE_LIST_COMMAND = 'git diff --name-only HEAD | grep -v ^third_party/'
+  FILE_LIST_COMMAND = 'git status -z | grep -Poz \'(?<=^[MARC][MARCD ] )[^\s]+\''
 else:
   FILE_LIST_COMMAND = 'git ls-tree -r --name-only -r HEAD | grep -v ^third_party/'
 
diff --git a/tools/distrib/check_include_guards.py b/tools/distrib/check_include_guards.py
new file mode 100755
index 0000000..977f40e
--- /dev/null
+++ b/tools/distrib/check_include_guards.py
@@ -0,0 +1,197 @@
+#!/usr/bin/env python2.7
+
+# Copyright 2016, Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import argparse
+import os
+import re
+import sys
+import subprocess
+
+
+def build_valid_guard(fpath):
+  prefix = 'GRPC_' if not fpath.startswith('include/') else ''
+  return prefix + '_'.join(fpath.replace('++', 'XX').replace('.', '_').upper().split('/')[1:])
+
+
+def load(fpath):
+  with open(fpath, 'r') as f:
+    return f.read()
+
+
+def save(fpath, contents):
+  with open(fpath, 'w') as f:
+    f.write(contents)
+
+
+class GuardValidator(object):
+  def __init__(self):
+    self.ifndef_re = re.compile(r'#ifndef ([A-Z][A-Z_1-9]*)')
+    self.define_re = re.compile(r'#define ([A-Z][A-Z_1-9]*)')
+    self.endif_c_re = re.compile(r'#endif /\* ([A-Z][A-Z_1-9]*) \*/')
+    self.endif_cpp_re = re.compile(r'#endif  // ([A-Z][A-Z_1-9]*)')
+    self.failed = False
+
+  def fail(self, fpath, regexp, fcontents, match_txt, correct, fix):
+    cpp_header = 'grpc++' in fpath
+    self.failed = True
+    invalid_guards_msg_template = (
+        '{0}: Missing preprocessor guards (RE {1}). '
+        'Please wrap your code around the following guards:\n'
+        '#ifndef {2}\n'
+        '#define {2}\n'
+        '...\n'
+        '... epic code ...\n'
+        '...\n') + ('#endif  // {2}' if cpp_header else '#endif /* {2} */')
+    if not match_txt:
+      print invalid_guards_msg_template.format(fpath, regexp.pattern,
+                                               build_valid_guard(fpath))
+      return fcontents
+
+    print ('{}: Wrong preprocessor guards (RE {}):'
+           '\n\tFound {}, expected {}').format(
+        fpath, regexp.pattern, match_txt, correct)
+    if fix:
+      print 'Fixing {}...\n'.format(fpath)
+      fixed_fcontents = re.sub(match_txt, correct, fcontents)
+      if fixed_fcontents:
+        self.failed = False
+      return fixed_fcontents
+    else:
+      print
+    return fcontents
+
+  def check(self, fpath, fix):
+    cpp_header = 'grpc++' in fpath
+    valid_guard = build_valid_guard(fpath)
+
+    fcontents = load(fpath)
+
+    match = self.ifndef_re.search(fcontents)
+    if match.lastindex is None:
+      # No ifndef. Request manual addition with hints
+      self.fail(fpath, match.re, match.string, '', '', False)
+      return False  # failed
+
+    # Does the guard end with a '_H'?
+    running_guard = match.group(1)
+    if not running_guard.endswith('_H'):
+      fcontents = self.fail(fpath, match.re, match.string, match.group(1),
+                            valid_guard, fix)
+      if fix: save(fpath, fcontents)
+
+    # Is it the expected one based on the file path?
+    if running_guard != valid_guard:
+      fcontents = self.fail(fpath, match.re, match.string, match.group(1),
+                            valid_guard, fix)
+      if fix: save(fpath, fcontents)
+
+    # Is there a #define? Is it the same as the #ifndef one?
+    match = self.define_re.search(fcontents)
+    if match.lastindex is None:
+      # No define. Request manual addition with hints
+      self.fail(fpath, match.re, match.string, '', '', False)
+      return False  # failed
+
+    # Is the #define guard the same as the #ifndef guard?
+    if match.group(1) != running_guard:
+      fcontents = self.fail(fpath, match.re, match.string, match.group(1),
+                            valid_guard, fix)
+      if fix: save(fpath, fcontents)
+
+    # Is there a properly commented #endif?
+    endif_re = self.endif_cpp_re if cpp_header else self.endif_c_re
+    flines = fcontents.rstrip().splitlines()
+    match = endif_re.search(flines[-1])
+    if not match:
+      # No endif. Check if we have the last line as just '#endif' and if so
+      # replace it with a properly commented one.
+      if flines[-1] == '#endif':
+        flines[-1] = ('#endif' +
+                      ('  // {}\n'.format(valid_guard) if cpp_header
+                       else ' /* {} */\n'.format(valid_guard)))
+        if fix:
+            fcontents = '\n'.join(flines)
+            save(fpath, fcontents)
+      else:
+        # something else is wrong, bail out
+        self.fail(fpath, endif_re, flines[-1], '', '', False)
+    elif match.group(1) != running_guard:
+      # Is the #endif guard the same as the #ifndef and #define guards?
+      fcontents = self.fail(fpath, endif_re, fcontents, match.group(1),
+                            valid_guard, fix)
+      if fix: save(fpath, fcontents)
+
+    return not self.failed  # Did the check succeed? (ie, not failed)
+
+# find our home
+ROOT = os.path.abspath(
+    os.path.join(os.path.dirname(sys.argv[0]), '../..'))
+os.chdir(ROOT)
+
+# parse command line
+argp = argparse.ArgumentParser(description='include guard checker')
+argp.add_argument('-f', '--fix',
+                  default=False,
+                  action='store_true');
+argp.add_argument('--precommit',
+                  default=False,
+                  action='store_true')
+args = argp.parse_args()
+
+KNOWN_BAD = set([
+    'src/core/proto/grpc/lb/v0/load_balancer.pb.h',
+])
+
+
+grep_filter = r"grep -E '^(include|src/core)/.*\.h$'"
+if args.precommit:
+  git_command = 'git diff --name-only HEAD'
+else:
+  git_command = 'git ls-tree -r --name-only -r HEAD'
+
+FILE_LIST_COMMAND = ' | '.join((git_command, grep_filter))
+
+# scan files
+ok = True
+filename_list = []
+try:
+  filename_list = subprocess.check_output(FILE_LIST_COMMAND,
+                                          shell=True).splitlines()
+except subprocess.CalledProcessError:
+  sys.exit(0)
+
+validator = GuardValidator()
+
+for filename in filename_list:
+  if filename in KNOWN_BAD: continue
+  ok = validator.check(filename, args.fix)
+
+sys.exit(0 if ok else 1)
diff --git a/tools/distrib/check_nanopb_output.sh b/tools/distrib/check_nanopb_output.sh
index 5f49ebb..51c4d75 100755
--- a/tools/distrib/check_nanopb_output.sh
+++ b/tools/distrib/check_nanopb_output.sh
@@ -30,8 +30,6 @@
 
 set -ex
 
-apt-get install -y autoconf automake libtool curl python-virtualenv
-
 readonly NANOPB_TMP_OUTPUT="$(mktemp -d)"
 
 # install protoc version 3
diff --git a/tools/distrib/python_wrapper.sh b/tools/distrib/python_wrapper.sh
new file mode 100755
index 0000000..347a715
--- /dev/null
+++ b/tools/distrib/python_wrapper.sh
@@ -0,0 +1,47 @@
+#!/bin/sh
+
+# Copyright 2016, Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+for p in python2.7 python2.6 python2 python not_found ; do 
+
+  python=`which $p || echo not_found`
+
+  if [ -x "$python" ] ; then
+    break
+  fi
+
+done
+
+if [ -x "$python" ] ; then
+  exec $python $@
+else
+  echo "No acceptable version of python found on the system"
+  exit 1
+fi
diff --git a/tools/dockerfile/test/cxx_squeeze_x64/Dockerfile b/tools/dockerfile/test/cxx_wheezy_x64/Dockerfile
similarity index 81%
rename from tools/dockerfile/test/cxx_squeeze_x64/Dockerfile
rename to tools/dockerfile/test/cxx_wheezy_x64/Dockerfile
index b7f95aa..6f330f9 100644
--- a/tools/dockerfile/test/cxx_squeeze_x64/Dockerfile
+++ b/tools/dockerfile/test/cxx_wheezy_x64/Dockerfile
@@ -27,7 +27,7 @@
 # (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 debian:squeeze
+FROM debian:wheezy
 
 # Install Git and basic packages.
 RUN apt-get update && apt-get install -y \
@@ -40,6 +40,7 @@
   gcc \
   gcc-multilib \
   git \
+  golang \
   gyp \
   lcov \
   libc6 \
@@ -62,16 +63,18 @@
 # Build profiling
 RUN apt-get update && apt-get install -y time && apt-get clean
 
+#=================
+# C++ dependencies
+RUN apt-get update && apt-get -y install libgflags-dev libgtest-dev libc++-dev clang && apt-get clean
 
-# libgflags-dev is not available on squeezy
-RUN apt-get update && apt-get -y install libgtest-dev libc++-dev clang && apt-get clean
 
-RUN apt-get update && apt-get -y install python-pip && apt-get clean
-RUN pip install argparse
+RUN apt-get update && apt-get install -y \
+  gcc-4.4 \
+  gcc-4.4-multilib
 
-RUN wget http://openssl.org/source/openssl-1.0.2f.tar.gz
+RUN wget https://openssl.org/source/old/1.0.2/openssl-1.0.2f.tar.gz
 
-ENV POST_GIT_STEP tools/dockerfile/test/cxx_squeeze_x64/post-git-setup.sh
+ENV POST_GIT_STEP tools/dockerfile/test/cxx_wheezy_x64/post-git-setup.sh
 
 # Prepare ccache
 RUN ln -s /usr/bin/ccache /usr/local/bin/gcc
@@ -81,6 +84,10 @@
 RUN ln -s /usr/bin/ccache /usr/local/bin/clang
 RUN ln -s /usr/bin/ccache /usr/local/bin/clang++
 
+#======================
+# Zookeeper dependencies
+# TODO(jtattermusch): is zookeeper still needed?
+RUN apt-get install -y libzookeeper-mt-dev
 
 RUN mkdir /var/local/jenkins
 
diff --git a/tools/dockerfile/test/cxx_squeeze_x64/post-git-setup.sh b/tools/dockerfile/test/cxx_wheezy_x64/post-git-setup.sh
similarity index 100%
rename from tools/dockerfile/test/cxx_squeeze_x64/post-git-setup.sh
rename to tools/dockerfile/test/cxx_wheezy_x64/post-git-setup.sh
diff --git a/tools/dockerfile/test/sanity/Dockerfile b/tools/dockerfile/test/sanity/Dockerfile
index 1935f67..4a69cd8 100644
--- a/tools/dockerfile/test/sanity/Dockerfile
+++ b/tools/dockerfile/test/sanity/Dockerfile
@@ -65,7 +65,13 @@
 
 #========================
 # Sanity test dependencies
-RUN apt-get update && apt-get install -y python-pip
+RUN apt-get update && apt-get install -y \
+      python-pip \
+      autoconf \
+      automake \
+      libtool \
+      curl \
+      python-virtualenv
 RUN pip install simplejson mako
 
 #===================
diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++
index dd5c8ec..253262c 100644
--- a/tools/doxygen/Doxyfile.c++
+++ b/tools/doxygen/Doxyfile.c++
@@ -815,6 +815,7 @@
 include/grpc++/impl/codegen/completion_queue_tag.h \
 include/grpc++/impl/codegen/config.h \
 include/grpc++/impl/codegen/config_protobuf.h \
+include/grpc++/impl/codegen/core_codegen_interface.h \
 include/grpc++/impl/codegen/grpc_library.h \
 include/grpc++/impl/codegen/method_handler_impl.h \
 include/grpc++/impl/codegen/proto_utils.h \
diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal
index a285310..134b16f 100644
--- a/tools/doxygen/Doxyfile.c++.internal
+++ b/tools/doxygen/Doxyfile.c++.internal
@@ -815,6 +815,7 @@
 include/grpc++/impl/codegen/completion_queue_tag.h \
 include/grpc++/impl/codegen/config.h \
 include/grpc++/impl/codegen/config_protobuf.h \
+include/grpc++/impl/codegen/core_codegen_interface.h \
 include/grpc++/impl/codegen/grpc_library.h \
 include/grpc++/impl/codegen/method_handler_impl.h \
 include/grpc++/impl/codegen/proto_utils.h \
@@ -835,9 +836,11 @@
 include/grpc++/impl/codegen/sync_stream.h \
 include/grpc++/impl/codegen/time.h \
 src/cpp/client/secure_credentials.h \
+src/cpp/common/core_codegen.h \
 src/cpp/common/secure_auth_context.h \
 src/cpp/server/secure_server_credentials.h \
 src/cpp/client/create_channel_internal.h \
+src/cpp/common/core_codegen.h \
 src/cpp/common/create_auth_context.h \
 src/cpp/server/dynamic_thread_pool.h \
 src/cpp/server/thread_pool_interface.h \
@@ -854,11 +857,10 @@
 src/cpp/client/credentials.cc \
 src/cpp/client/generic_stub.cc \
 src/cpp/client/insecure_credentials.cc \
-src/cpp/common/call.cc \
 src/cpp/common/channel_arguments.cc \
 src/cpp/common/completion_queue.cc \
+src/cpp/common/core_codegen.cc \
 src/cpp/common/rpc_method.cc \
-src/cpp/proto/proto_utils.cc \
 src/cpp/server/async_generic_service.cc \
 src/cpp/server/create_default_thread_pool.cc \
 src/cpp/server/dynamic_thread_pool.cc \
@@ -872,7 +874,7 @@
 src/cpp/util/status.cc \
 src/cpp/util/string_ref.cc \
 src/cpp/util/time.cc \
-src/cpp/codegen/grpc_library.cc
+src/cpp/codegen/codegen_init.cc
 
 # This tag can be used to specify the character encoding of the source files
 # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
diff --git a/tools/doxygen/Doxyfile.core b/tools/doxygen/Doxyfile.core
index a9b14c8..e326adc 100644
--- a/tools/doxygen/Doxyfile.core
+++ b/tools/doxygen/Doxyfile.core
@@ -761,17 +761,17 @@
 # Note: If this tag is empty the current directory is searched.
 
 INPUT                  = include/grpc/grpc_security.h \
+include/grpc/byte_buffer.h \
+include/grpc/byte_buffer_reader.h \
+include/grpc/compression.h \
+include/grpc/grpc.h \
+include/grpc/status.h \
 include/grpc/impl/codegen/byte_buffer.h \
 include/grpc/impl/codegen/compression_types.h \
 include/grpc/impl/codegen/connectivity_state.h \
 include/grpc/impl/codegen/grpc_types.h \
 include/grpc/impl/codegen/propagation_bits.h \
 include/grpc/impl/codegen/status.h \
-include/grpc/byte_buffer.h \
-include/grpc/byte_buffer_reader.h \
-include/grpc/compression.h \
-include/grpc/grpc.h \
-include/grpc/status.h \
 include/grpc/census.h \
 include/grpc/support/alloc.h \
 include/grpc/support/atm.h \
diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal
index a894eaf..4fcfba3 100644
--- a/tools/doxygen/Doxyfile.core.internal
+++ b/tools/doxygen/Doxyfile.core.internal
@@ -761,21 +761,23 @@
 # Note: If this tag is empty the current directory is searched.
 
 INPUT                  = include/grpc/grpc_security.h \
+include/grpc/byte_buffer.h \
+include/grpc/byte_buffer_reader.h \
+include/grpc/compression.h \
+include/grpc/grpc.h \
+include/grpc/status.h \
 include/grpc/impl/codegen/byte_buffer.h \
 include/grpc/impl/codegen/compression_types.h \
 include/grpc/impl/codegen/connectivity_state.h \
 include/grpc/impl/codegen/grpc_types.h \
 include/grpc/impl/codegen/propagation_bits.h \
 include/grpc/impl/codegen/status.h \
-include/grpc/byte_buffer.h \
-include/grpc/byte_buffer_reader.h \
-include/grpc/compression.h \
-include/grpc/grpc.h \
-include/grpc/status.h \
 include/grpc/census.h \
 src/core/census/grpc_filter.h \
+src/core/census/grpc_plugin.h \
 src/core/channel/channel_args.h \
 src/core/channel/channel_stack.h \
+src/core/channel/channel_stack_builder.h \
 src/core/channel/client_channel.h \
 src/core/channel/client_uchannel.h \
 src/core/channel/compress_filter.h \
@@ -855,9 +857,12 @@
 src/core/surface/call.h \
 src/core/surface/call_test_only.h \
 src/core/surface/channel.h \
+src/core/surface/channel_init.h \
+src/core/surface/channel_stack_type.h \
 src/core/surface/completion_queue.h \
 src/core/surface/event_string.h \
 src/core/surface/init.h \
+src/core/surface/lame_client.h \
 src/core/surface/server.h \
 src/core/surface/surface_trace.h \
 src/core/transport/byte_stream.h \
@@ -911,8 +916,10 @@
 third_party/nanopb/pb_encode.h \
 src/core/census/grpc_context.c \
 src/core/census/grpc_filter.c \
+src/core/census/grpc_plugin.c \
 src/core/channel/channel_args.c \
 src/core/channel/channel_stack.c \
+src/core/channel/channel_stack_builder.c \
 src/core/channel/client_channel.c \
 src/core/channel/client_uchannel.c \
 src/core/channel/compress_filter.c \
@@ -1000,7 +1007,9 @@
 src/core/surface/channel.c \
 src/core/surface/channel_connectivity.c \
 src/core/surface/channel_create.c \
+src/core/surface/channel_init.c \
 src/core/surface/channel_ping.c \
+src/core/surface/channel_stack_type.c \
 src/core/surface/completion_queue.c \
 src/core/surface/event_string.c \
 src/core/surface/init.c \
@@ -1008,7 +1017,6 @@
 src/core/surface/metadata_array.c \
 src/core/surface/server.c \
 src/core/surface/server_chttp2.c \
-src/core/surface/server_create.c \
 src/core/surface/validate_metadata.c \
 src/core/surface/version.c \
 src/core/transport/byte_stream.c \
@@ -1112,6 +1120,7 @@
 include/grpc/impl/codegen/sync_win32.h \
 include/grpc/impl/codegen/time.h \
 src/core/profiling/timers.h \
+src/core/support/backoff.h \
 src/core/support/block_annotate.h \
 src/core/support/env.h \
 src/core/support/load_file.h \
@@ -1126,6 +1135,7 @@
 src/core/profiling/stap_timers.c \
 src/core/support/alloc.c \
 src/core/support/avl.c \
+src/core/support/backoff.c \
 src/core/support/cmdline.c \
 src/core/support/cpu_iphone.c \
 src/core/support/cpu_linux.c \
diff --git a/tools/gce/create_linux_worker.sh b/tools/gce/create_linux_worker.sh
index 2a9e77a..399e3ec 100755
--- a/tools/gce/create_linux_worker.sh
+++ b/tools/gce/create_linux_worker.sh
@@ -37,7 +37,7 @@
 CLOUD_PROJECT=grpc-testing
 ZONE=us-central1-a
 
-INSTANCE_NAME=grpc-jenkins-worker1
+INSTANCE_NAME="${1:-grpc-jenkins-worker1}"
 
 gcloud compute instances create $INSTANCE_NAME \
     --project="$CLOUD_PROJECT" \
diff --git a/tools/jenkins/run_full_interop.sh b/tools/jenkins/run_full_interop.sh
old mode 100644
new mode 100755
diff --git a/tools/openssl/use_openssl.sh b/tools/openssl/use_openssl.sh
index 3098217..9318b34 100755
--- a/tools/openssl/use_openssl.sh
+++ b/tools/openssl/use_openssl.sh
@@ -38,8 +38,8 @@
 # allow openssl to be pre-downloaded
 if [ ! -e third_party/openssl-1.0.2f.tar.gz ]
 then
-  echo "Downloading http://openssl.org/source/openssl-1.0.2f.tar.gz to third_party/openssl-1.0.2f.tar.gz"
-  wget http://openssl.org/source/openssl-1.0.2f.tar.gz -O third_party/openssl-1.0.2f.tar.gz
+  echo "Downloading https://openssl.org/source/old/1.0.2/openssl-1.0.2f.tar.gz to third_party/openssl-1.0.2f.tar.gz"
+  wget https://openssl.org/source/old/1.0.2/openssl-1.0.2f.tar.gz -O third_party/openssl-1.0.2f.tar.gz
 fi
 
 # clean openssl directory
diff --git a/tools/run_tests/configs.json b/tools/run_tests/configs.json
index cbb8ec5..a858170 100644
--- a/tools/run_tests/configs.json
+++ b/tools/run_tests/configs.json
@@ -3,6 +3,29 @@
     "config": "opt"
   }, 
   {
+    "config": "dbg"
+  }, 
+  {
+    "config": "easan", 
+    "environ": {
+      "ASAN_OPTIONS": "detect_leaks=1:color=always", 
+      "LSAN_OPTIONS": "suppressions=tools/lsan_suppressions.txt:report_objects=1"
+    }, 
+    "timeout_multiplier": 3
+  }, 
+  {
+    "config": "asan", 
+    "environ": {
+      "ASAN_OPTIONS": "detect_leaks=1:color=always", 
+      "LSAN_OPTIONS": "suppressions=tools/lsan_suppressions.txt:report_objects=1"
+    }, 
+    "timeout_multiplier": 3
+  }, 
+  {
+    "config": "msan", 
+    "timeout_multiplier": 4
+  }, 
+  {
     "config": "basicprof"
   }, 
   {
@@ -21,17 +44,24 @@
     "timeout_multiplier": 3
   }, 
   {
+    "config": "edbg"
+  }, 
+  {
     "config": "ubsan", 
     "timeout_multiplier": 1.5
   }, 
   {
-    "config": "dbg"
+    "config": "tsan", 
+    "environ": {
+      "TSAN_OPTIONS": "suppressions=tools/tsan_suppressions.txt:halt_on_error=1:second_deadlock_stack=1"
+    }, 
+    "timeout_multiplier": 5
   }, 
   {
     "config": "stapprof"
   }, 
   {
-    "config": "gcov"
+    "config": "mutrace"
   }, 
   {
     "config": "memcheck", 
@@ -43,25 +73,13 @@
     ]
   }, 
   {
-    "config": "asan", 
-    "environ": {
-      "ASAN_OPTIONS": "detect_leaks=1:color=always", 
-      "LSAN_OPTIONS": "suppressions=tools/lsan_suppressions.txt:report_objects=1"
-    }, 
-    "timeout_multiplier": 3
-  }, 
-  {
-    "config": "tsan", 
+    "config": "etsan", 
     "environ": {
       "TSAN_OPTIONS": "suppressions=tools/tsan_suppressions.txt:halt_on_error=1:second_deadlock_stack=1"
     }, 
     "timeout_multiplier": 5
   }, 
   {
-    "config": "msan", 
-    "timeout_multiplier": 4
-  }, 
-  {
-    "config": "mutrace"
+    "config": "gcov"
   }
 ]
diff --git a/tools/run_tests/run_tests.py b/tools/run_tests/run_tests.py
index 99bf5df..dc11c0b 100755
--- a/tools/run_tests/run_tests.py
+++ b/tools/run_tests/run_tests.py
@@ -80,7 +80,7 @@
     self.timeout_multiplier = timeout_multiplier
 
   def job_spec(self, cmdline, hash_targets, timeout_seconds=5*60,
-               shortname=None, environ={}, cpu_cost=1.0):
+               shortname=None, environ={}, cpu_cost=1.0, flaky=False):
     """Construct a jobset.JobSpec for a test under this config
 
        Args:
@@ -102,7 +102,7 @@
                           timeout_seconds=(self.timeout_multiplier * timeout_seconds if timeout_seconds else None),
                           hash_targets=hash_targets
                               if self.allow_hashing else None,
-                          flake_retries=5 if args.allow_flakes else 0,
+                          flake_retries=5 if flaky or args.allow_flakes else 0,
                           timeout_retries=3 if args.allow_flakes else 0)
 
 
@@ -189,6 +189,7 @@
           out.append(self.config.job_spec(cmdline, [binary],
                                           shortname=' '.join(cmdline),
                                           cpu_cost=target['cpu_cost'],
+                                          flaky=target.get('flaky', False),
                                           environ={'GRPC_DEFAULT_SSL_ROOTS_FILE_PATH':
                                                    _ROOT + '/src/core/tsi/test_creds/ca.pem'}))
       elif self.args.regex == '.*' or self.platform == 'windows':
@@ -231,6 +232,9 @@
   def _clang_make_options(self):
     return ['CC=clang', 'CXX=clang++', 'LD=clang', 'LDXX=clang++']
 
+  def _gcc44_make_options(self):
+    return ['CC=gcc-4.4', 'CXX=g++-4.4', 'LD=gcc-4.4', 'LDXX=g++-4.4']
+
   def _compiler_options(self, use_docker, compiler):
     """Returns docker distro and make options to use for given compiler."""
     if _is_use_docker_child():
@@ -241,7 +245,7 @@
     if compiler == 'gcc4.9' or compiler == 'default':
       return ('jessie', [])
     elif compiler == 'gcc4.4':
-      return ('squeeze', [])
+      return ('wheezy', self._gcc44_make_options())
     elif compiler == 'gcc5.3':
       return ('ubuntu1604', [])
     elif compiler == 'clang3.4':
@@ -879,7 +883,7 @@
       sys.exit(1)
   else:
     dockerfile_dir = next(iter(dockerfile_dirs))
-    
+
   child_argv = [ arg for arg in sys.argv if not arg == '--use_docker' ]
   run_tests_cmd = 'python tools/run_tests/run_tests.py %s' % ' '.join(child_argv[1:])
 
diff --git a/tools/run_tests/sanity/sanity_tests.yaml b/tools/run_tests/sanity/sanity_tests.yaml
index 3840f4d..f155c8d 100644
--- a/tools/run_tests/sanity/sanity_tests.yaml
+++ b/tools/run_tests/sanity/sanity_tests.yaml
@@ -8,3 +8,4 @@
 - script: tools/distrib/clang_format_code.sh
 - script: tools/distrib/check_trailing_newlines.sh
 - script: tools/distrib/check_nanopb_output.sh
+- script: tools/distrib/check_include_guards.py
diff --git a/tools/run_tests/sources_and_headers.json b/tools/run_tests/sources_and_headers.json
index d0ee3c4..28647e4 100644
--- a/tools/run_tests/sources_and_headers.json
+++ b/tools/run_tests/sources_and_headers.json
@@ -411,6 +411,20 @@
     ], 
     "headers": [], 
     "language": "c", 
+    "name": "gpr_backoff_test", 
+    "src": [
+      "test/core/support/backoff_test.c"
+    ], 
+    "third_party": false, 
+    "type": "target"
+  }, 
+  {
+    "deps": [
+      "gpr", 
+      "gpr_test_util"
+    ], 
+    "headers": [], 
+    "language": "c", 
     "name": "gpr_cmdline_test", 
     "src": [
       "test/core/support/cmdline_test.c"
@@ -1716,6 +1730,32 @@
   }, 
   {
     "deps": [
+      "grpc++_codegen_lib"
+    ], 
+    "headers": [
+      "src/proto/grpc/testing/control.grpc.pb.h", 
+      "src/proto/grpc/testing/control.pb.h", 
+      "src/proto/grpc/testing/messages.grpc.pb.h", 
+      "src/proto/grpc/testing/messages.pb.h", 
+      "src/proto/grpc/testing/payloads.grpc.pb.h", 
+      "src/proto/grpc/testing/payloads.pb.h", 
+      "src/proto/grpc/testing/perf_db.grpc.pb.h", 
+      "src/proto/grpc/testing/perf_db.pb.h", 
+      "src/proto/grpc/testing/services.grpc.pb.h", 
+      "src/proto/grpc/testing/services.pb.h", 
+      "src/proto/grpc/testing/stats.grpc.pb.h", 
+      "src/proto/grpc/testing/stats.pb.h"
+    ], 
+    "language": "c++", 
+    "name": "codegen_test", 
+    "src": [
+      "test/cpp/codegen/codegen_test.cc"
+    ], 
+    "third_party": false, 
+    "type": "target"
+  }, 
+  {
+    "deps": [
       "gpr", 
       "grpc", 
       "grpc++"
@@ -3162,7 +3202,6 @@
   }, 
   {
     "deps": [
-      "end2end_certs", 
       "end2end_tests", 
       "gpr", 
       "gpr_test_util", 
@@ -3180,7 +3219,6 @@
   }, 
   {
     "deps": [
-      "end2end_certs", 
       "end2end_tests", 
       "gpr", 
       "gpr_test_util", 
@@ -3198,7 +3236,6 @@
   }, 
   {
     "deps": [
-      "end2end_certs", 
       "end2end_tests", 
       "gpr", 
       "gpr_test_util", 
@@ -3216,7 +3253,6 @@
   }, 
   {
     "deps": [
-      "end2end_certs", 
       "end2end_tests", 
       "gpr", 
       "gpr_test_util", 
@@ -3234,7 +3270,6 @@
   }, 
   {
     "deps": [
-      "end2end_certs", 
       "end2end_tests", 
       "gpr", 
       "gpr_test_util", 
@@ -3252,7 +3287,6 @@
   }, 
   {
     "deps": [
-      "end2end_certs", 
       "end2end_tests", 
       "gpr", 
       "gpr_test_util", 
@@ -3270,7 +3304,6 @@
   }, 
   {
     "deps": [
-      "end2end_certs", 
       "end2end_tests", 
       "gpr", 
       "gpr_test_util", 
@@ -3288,7 +3321,23 @@
   }, 
   {
     "deps": [
-      "end2end_certs", 
+      "end2end_tests", 
+      "gpr", 
+      "gpr_test_util", 
+      "grpc", 
+      "grpc_test_util"
+    ], 
+    "headers": [], 
+    "language": "c", 
+    "name": "h2_full+trace_test", 
+    "src": [
+      "test/core/end2end/fixtures/h2_full+trace.c"
+    ], 
+    "third_party": false, 
+    "type": "target"
+  }, 
+  {
+    "deps": [
       "end2end_tests", 
       "gpr", 
       "gpr_test_util", 
@@ -3306,7 +3355,6 @@
   }, 
   {
     "deps": [
-      "end2end_certs", 
       "end2end_tests", 
       "gpr", 
       "gpr_test_util", 
@@ -3324,7 +3372,6 @@
   }, 
   {
     "deps": [
-      "end2end_certs", 
       "end2end_tests", 
       "gpr", 
       "gpr_test_util", 
@@ -3342,7 +3389,6 @@
   }, 
   {
     "deps": [
-      "end2end_certs", 
       "end2end_tests", 
       "gpr", 
       "gpr_test_util", 
@@ -3360,7 +3406,6 @@
   }, 
   {
     "deps": [
-      "end2end_certs", 
       "end2end_tests", 
       "gpr", 
       "gpr_test_util", 
@@ -3378,7 +3423,6 @@
   }, 
   {
     "deps": [
-      "end2end_certs", 
       "end2end_tests", 
       "gpr", 
       "gpr_test_util", 
@@ -3396,7 +3440,6 @@
   }, 
   {
     "deps": [
-      "end2end_certs", 
       "end2end_tests", 
       "gpr", 
       "gpr_test_util", 
@@ -3414,7 +3457,6 @@
   }, 
   {
     "deps": [
-      "end2end_certs", 
       "end2end_tests", 
       "gpr", 
       "gpr_test_util", 
@@ -3432,7 +3474,6 @@
   }, 
   {
     "deps": [
-      "end2end_certs", 
       "end2end_tests", 
       "gpr", 
       "gpr_test_util", 
@@ -3450,7 +3491,6 @@
   }, 
   {
     "deps": [
-      "end2end_certs", 
       "end2end_tests", 
       "gpr", 
       "gpr_test_util", 
@@ -3468,7 +3508,6 @@
   }, 
   {
     "deps": [
-      "end2end_certs", 
       "end2end_tests", 
       "gpr", 
       "gpr_test_util", 
@@ -3596,6 +3635,23 @@
     ], 
     "headers": [], 
     "language": "c", 
+    "name": "h2_full+trace_nosec_test", 
+    "src": [
+      "test/core/end2end/fixtures/h2_full+trace.c"
+    ], 
+    "third_party": false, 
+    "type": "target"
+  }, 
+  {
+    "deps": [
+      "end2end_nosec_tests", 
+      "gpr", 
+      "gpr_test_util", 
+      "grpc_test_util_unsecure", 
+      "grpc_unsecure"
+    ], 
+    "headers": [], 
+    "language": "c", 
     "name": "h2_proxy_nosec_test", 
     "src": [
       "test/core/end2end/fixtures/h2_proxy.c"
@@ -3751,6 +3807,7 @@
       "include/grpc/support/tls_pthread.h", 
       "include/grpc/support/useful.h", 
       "src/core/profiling/timers.h", 
+      "src/core/support/backoff.h", 
       "src/core/support/block_annotate.h", 
       "src/core/support/env.h", 
       "src/core/support/load_file.h", 
@@ -3812,6 +3869,8 @@
       "src/core/profiling/timers.h", 
       "src/core/support/alloc.c", 
       "src/core/support/avl.c", 
+      "src/core/support/backoff.c", 
+      "src/core/support/backoff.h", 
       "src/core/support/block_annotate.h", 
       "src/core/support/cmdline.c", 
       "src/core/support/cpu_iphone.c", 
@@ -3901,10 +3960,12 @@
       "include/grpc/status.h", 
       "src/core/census/aggregation.h", 
       "src/core/census/grpc_filter.h", 
+      "src/core/census/grpc_plugin.h", 
       "src/core/census/mlog.h", 
       "src/core/census/rpc_metric_id.h", 
       "src/core/channel/channel_args.h", 
       "src/core/channel/channel_stack.h", 
+      "src/core/channel/channel_stack_builder.h", 
       "src/core/channel/client_channel.h", 
       "src/core/channel/client_uchannel.h", 
       "src/core/channel/compress_filter.h", 
@@ -3993,9 +4054,12 @@
       "src/core/surface/call.h", 
       "src/core/surface/call_test_only.h", 
       "src/core/surface/channel.h", 
+      "src/core/surface/channel_init.h", 
+      "src/core/surface/channel_stack_type.h", 
       "src/core/surface/completion_queue.h", 
       "src/core/surface/event_string.h", 
       "src/core/surface/init.h", 
+      "src/core/surface/lame_client.h", 
       "src/core/surface/server.h", 
       "src/core/surface/surface_trace.h", 
       "src/core/transport/byte_stream.h", 
@@ -4057,6 +4121,8 @@
       "src/core/census/grpc_context.c", 
       "src/core/census/grpc_filter.c", 
       "src/core/census/grpc_filter.h", 
+      "src/core/census/grpc_plugin.c", 
+      "src/core/census/grpc_plugin.h", 
       "src/core/census/initialize.c", 
       "src/core/census/mlog.c", 
       "src/core/census/mlog.h", 
@@ -4068,6 +4134,8 @@
       "src/core/channel/channel_args.h", 
       "src/core/channel/channel_stack.c", 
       "src/core/channel/channel_stack.h", 
+      "src/core/channel/channel_stack_builder.c", 
+      "src/core/channel/channel_stack_builder.h", 
       "src/core/channel/client_channel.c", 
       "src/core/channel/client_channel.h", 
       "src/core/channel/client_uchannel.c", 
@@ -4259,7 +4327,11 @@
       "src/core/surface/channel.h", 
       "src/core/surface/channel_connectivity.c", 
       "src/core/surface/channel_create.c", 
+      "src/core/surface/channel_init.c", 
+      "src/core/surface/channel_init.h", 
       "src/core/surface/channel_ping.c", 
+      "src/core/surface/channel_stack_type.c", 
+      "src/core/surface/channel_stack_type.h", 
       "src/core/surface/completion_queue.c", 
       "src/core/surface/completion_queue.h", 
       "src/core/surface/event_string.c", 
@@ -4268,12 +4340,12 @@
       "src/core/surface/init.h", 
       "src/core/surface/init_secure.c", 
       "src/core/surface/lame_client.c", 
+      "src/core/surface/lame_client.h", 
       "src/core/surface/metadata_array.c", 
       "src/core/surface/secure_channel_create.c", 
       "src/core/surface/server.c", 
       "src/core/surface/server.h", 
       "src/core/surface/server_chttp2.c", 
-      "src/core/surface/server_create.c", 
       "src/core/surface/surface_trace.h", 
       "src/core/surface/validate_metadata.c", 
       "src/core/surface/version.c", 
@@ -4346,6 +4418,57 @@
     "type": "lib"
   }, 
   {
+    "deps": [], 
+    "headers": [
+      "include/grpc/impl/codegen/alloc.h", 
+      "include/grpc/impl/codegen/atm.h", 
+      "include/grpc/impl/codegen/atm_gcc_atomic.h", 
+      "include/grpc/impl/codegen/atm_gcc_sync.h", 
+      "include/grpc/impl/codegen/atm_win32.h", 
+      "include/grpc/impl/codegen/byte_buffer.h", 
+      "include/grpc/impl/codegen/compression_types.h", 
+      "include/grpc/impl/codegen/connectivity_state.h", 
+      "include/grpc/impl/codegen/grpc_types.h", 
+      "include/grpc/impl/codegen/log.h", 
+      "include/grpc/impl/codegen/port_platform.h", 
+      "include/grpc/impl/codegen/propagation_bits.h", 
+      "include/grpc/impl/codegen/slice.h", 
+      "include/grpc/impl/codegen/slice_buffer.h", 
+      "include/grpc/impl/codegen/status.h", 
+      "include/grpc/impl/codegen/sync.h", 
+      "include/grpc/impl/codegen/sync_generic.h", 
+      "include/grpc/impl/codegen/sync_posix.h", 
+      "include/grpc/impl/codegen/sync_win32.h", 
+      "include/grpc/impl/codegen/time.h"
+    ], 
+    "language": "c", 
+    "name": "grpc_codegen_lib", 
+    "src": [
+      "include/grpc/impl/codegen/alloc.h", 
+      "include/grpc/impl/codegen/atm.h", 
+      "include/grpc/impl/codegen/atm_gcc_atomic.h", 
+      "include/grpc/impl/codegen/atm_gcc_sync.h", 
+      "include/grpc/impl/codegen/atm_win32.h", 
+      "include/grpc/impl/codegen/byte_buffer.h", 
+      "include/grpc/impl/codegen/compression_types.h", 
+      "include/grpc/impl/codegen/connectivity_state.h", 
+      "include/grpc/impl/codegen/grpc_types.h", 
+      "include/grpc/impl/codegen/log.h", 
+      "include/grpc/impl/codegen/port_platform.h", 
+      "include/grpc/impl/codegen/propagation_bits.h", 
+      "include/grpc/impl/codegen/slice.h", 
+      "include/grpc/impl/codegen/slice_buffer.h", 
+      "include/grpc/impl/codegen/status.h", 
+      "include/grpc/impl/codegen/sync.h", 
+      "include/grpc/impl/codegen/sync_generic.h", 
+      "include/grpc/impl/codegen/sync_posix.h", 
+      "include/grpc/impl/codegen/sync_win32.h", 
+      "include/grpc/impl/codegen/time.h"
+    ], 
+    "third_party": false, 
+    "type": "lib"
+  }, 
+  {
     "deps": [
       "gpr", 
       "grpc"
@@ -4372,6 +4495,7 @@
       "test/core/util/grpc_profiler.h", 
       "test/core/util/parse_hexstring.h", 
       "test/core/util/port.h", 
+      "test/core/util/port_server_client.h", 
       "test/core/util/slice_splitter.h"
     ], 
     "language": "c", 
@@ -4395,6 +4519,8 @@
       "test/core/util/parse_hexstring.h", 
       "test/core/util/port.h", 
       "test/core/util/port_posix.c", 
+      "test/core/util/port_server_client.c", 
+      "test/core/util/port_server_client.h", 
       "test/core/util/port_windows.c", 
       "test/core/util/slice_splitter.c", 
       "test/core/util/slice_splitter.h"
@@ -4415,6 +4541,7 @@
       "test/core/util/grpc_profiler.h", 
       "test/core/util/parse_hexstring.h", 
       "test/core/util/port.h", 
+      "test/core/util/port_server_client.h", 
       "test/core/util/slice_splitter.h"
     ], 
     "language": "c", 
@@ -4432,6 +4559,8 @@
       "test/core/util/parse_hexstring.h", 
       "test/core/util/port.h", 
       "test/core/util/port_posix.c", 
+      "test/core/util/port_server_client.c", 
+      "test/core/util/port_server_client.h", 
       "test/core/util/port_windows.c", 
       "test/core/util/slice_splitter.c", 
       "test/core/util/slice_splitter.h"
@@ -4458,10 +4587,12 @@
       "include/grpc/status.h", 
       "src/core/census/aggregation.h", 
       "src/core/census/grpc_filter.h", 
+      "src/core/census/grpc_plugin.h", 
       "src/core/census/mlog.h", 
       "src/core/census/rpc_metric_id.h", 
       "src/core/channel/channel_args.h", 
       "src/core/channel/channel_stack.h", 
+      "src/core/channel/channel_stack_builder.h", 
       "src/core/channel/client_channel.h", 
       "src/core/channel/client_uchannel.h", 
       "src/core/channel/compress_filter.h", 
@@ -4541,9 +4672,12 @@
       "src/core/surface/call.h", 
       "src/core/surface/call_test_only.h", 
       "src/core/surface/channel.h", 
+      "src/core/surface/channel_init.h", 
+      "src/core/surface/channel_stack_type.h", 
       "src/core/surface/completion_queue.h", 
       "src/core/surface/event_string.h", 
       "src/core/surface/init.h", 
+      "src/core/surface/lame_client.h", 
       "src/core/surface/server.h", 
       "src/core/surface/surface_trace.h", 
       "src/core/transport/byte_stream.h", 
@@ -4599,6 +4733,8 @@
       "src/core/census/grpc_context.c", 
       "src/core/census/grpc_filter.c", 
       "src/core/census/grpc_filter.h", 
+      "src/core/census/grpc_plugin.c", 
+      "src/core/census/grpc_plugin.h", 
       "src/core/census/initialize.c", 
       "src/core/census/mlog.c", 
       "src/core/census/mlog.h", 
@@ -4610,6 +4746,8 @@
       "src/core/channel/channel_args.h", 
       "src/core/channel/channel_stack.c", 
       "src/core/channel/channel_stack.h", 
+      "src/core/channel/channel_stack_builder.c", 
+      "src/core/channel/channel_stack_builder.h", 
       "src/core/channel/client_channel.c", 
       "src/core/channel/client_channel.h", 
       "src/core/channel/client_uchannel.c", 
@@ -4776,7 +4914,11 @@
       "src/core/surface/channel.h", 
       "src/core/surface/channel_connectivity.c", 
       "src/core/surface/channel_create.c", 
+      "src/core/surface/channel_init.c", 
+      "src/core/surface/channel_init.h", 
       "src/core/surface/channel_ping.c", 
+      "src/core/surface/channel_stack_type.c", 
+      "src/core/surface/channel_stack_type.h", 
       "src/core/surface/completion_queue.c", 
       "src/core/surface/completion_queue.h", 
       "src/core/surface/event_string.c", 
@@ -4785,11 +4927,11 @@
       "src/core/surface/init.h", 
       "src/core/surface/init_unsecure.c", 
       "src/core/surface/lame_client.c", 
+      "src/core/surface/lame_client.h", 
       "src/core/surface/metadata_array.c", 
       "src/core/surface/server.c", 
       "src/core/surface/server.h", 
       "src/core/surface/server_chttp2.c", 
-      "src/core/surface/server_create.c", 
       "src/core/surface/surface_trace.h", 
       "src/core/surface/validate_metadata.c", 
       "src/core/surface/version.c", 
@@ -4937,6 +5079,7 @@
       "include/grpc++/impl/codegen/completion_queue_tag.h", 
       "include/grpc++/impl/codegen/config.h", 
       "include/grpc++/impl/codegen/config_protobuf.h", 
+      "include/grpc++/impl/codegen/core_codegen_interface.h", 
       "include/grpc++/impl/codegen/grpc_library.h", 
       "include/grpc++/impl/codegen/method_handler_impl.h", 
       "include/grpc++/impl/codegen/proto_utils.h", 
@@ -4992,6 +5135,8 @@
       "include/grpc++/support/time.h", 
       "src/cpp/client/create_channel_internal.h", 
       "src/cpp/client/secure_credentials.h", 
+      "src/cpp/common/core_codegen.h", 
+      "src/cpp/common/core_codegen.h", 
       "src/cpp/common/create_auth_context.h", 
       "src/cpp/common/secure_auth_context.h", 
       "src/cpp/server/dynamic_thread_pool.h", 
@@ -5022,6 +5167,7 @@
       "include/grpc++/impl/codegen/completion_queue_tag.h", 
       "include/grpc++/impl/codegen/config.h", 
       "include/grpc++/impl/codegen/config_protobuf.h", 
+      "include/grpc++/impl/codegen/core_codegen_interface.h", 
       "include/grpc++/impl/codegen/grpc_library.h", 
       "include/grpc++/impl/codegen/method_handler_impl.h", 
       "include/grpc++/impl/codegen/proto_utils.h", 
@@ -5085,18 +5231,19 @@
       "src/cpp/client/insecure_credentials.cc", 
       "src/cpp/client/secure_credentials.cc", 
       "src/cpp/client/secure_credentials.h", 
-      "src/cpp/codegen/grpc_library.cc", 
+      "src/cpp/codegen/codegen_init.cc", 
       "src/cpp/common/auth_property_iterator.cc", 
-      "src/cpp/common/call.cc", 
       "src/cpp/common/channel_arguments.cc", 
       "src/cpp/common/completion_queue.cc", 
+      "src/cpp/common/core_codegen.cc", 
+      "src/cpp/common/core_codegen.h", 
+      "src/cpp/common/core_codegen.h", 
       "src/cpp/common/create_auth_context.h", 
       "src/cpp/common/rpc_method.cc", 
       "src/cpp/common/secure_auth_context.cc", 
       "src/cpp/common/secure_auth_context.h", 
       "src/cpp/common/secure_channel_arguments.cc", 
       "src/cpp/common/secure_create_auth_context.cc", 
-      "src/cpp/proto/proto_utils.cc", 
       "src/cpp/server/async_generic_service.cc", 
       "src/cpp/server/create_default_thread_pool.cc", 
       "src/cpp/server/dynamic_thread_pool.cc", 
@@ -5121,6 +5268,120 @@
   {
     "deps": [], 
     "headers": [
+      "include/grpc++/impl/codegen/async_stream.h", 
+      "include/grpc++/impl/codegen/async_unary_call.h", 
+      "include/grpc++/impl/codegen/call.h", 
+      "include/grpc++/impl/codegen/call_hook.h", 
+      "include/grpc++/impl/codegen/channel_interface.h", 
+      "include/grpc++/impl/codegen/client_context.h", 
+      "include/grpc++/impl/codegen/client_unary_call.h", 
+      "include/grpc++/impl/codegen/completion_queue.h", 
+      "include/grpc++/impl/codegen/completion_queue_tag.h", 
+      "include/grpc++/impl/codegen/config.h", 
+      "include/grpc++/impl/codegen/config_protobuf.h", 
+      "include/grpc++/impl/codegen/core_codegen_interface.h", 
+      "include/grpc++/impl/codegen/grpc_library.h", 
+      "include/grpc++/impl/codegen/method_handler_impl.h", 
+      "include/grpc++/impl/codegen/proto_utils.h", 
+      "include/grpc++/impl/codegen/rpc_method.h", 
+      "include/grpc++/impl/codegen/rpc_service_method.h", 
+      "include/grpc++/impl/codegen/security/auth_context.h", 
+      "include/grpc++/impl/codegen/serialization_traits.h", 
+      "include/grpc++/impl/codegen/server_context.h", 
+      "include/grpc++/impl/codegen/server_interface.h", 
+      "include/grpc++/impl/codegen/service_type.h", 
+      "include/grpc++/impl/codegen/status.h", 
+      "include/grpc++/impl/codegen/status_code_enum.h", 
+      "include/grpc++/impl/codegen/string_ref.h", 
+      "include/grpc++/impl/codegen/stub_options.h", 
+      "include/grpc++/impl/codegen/sync.h", 
+      "include/grpc++/impl/codegen/sync_cxx11.h", 
+      "include/grpc++/impl/codegen/sync_no_cxx11.h", 
+      "include/grpc++/impl/codegen/sync_stream.h", 
+      "include/grpc++/impl/codegen/time.h", 
+      "include/grpc/impl/codegen/alloc.h", 
+      "include/grpc/impl/codegen/atm.h", 
+      "include/grpc/impl/codegen/atm_gcc_atomic.h", 
+      "include/grpc/impl/codegen/atm_gcc_sync.h", 
+      "include/grpc/impl/codegen/atm_win32.h", 
+      "include/grpc/impl/codegen/byte_buffer.h", 
+      "include/grpc/impl/codegen/compression_types.h", 
+      "include/grpc/impl/codegen/connectivity_state.h", 
+      "include/grpc/impl/codegen/grpc_types.h", 
+      "include/grpc/impl/codegen/log.h", 
+      "include/grpc/impl/codegen/port_platform.h", 
+      "include/grpc/impl/codegen/propagation_bits.h", 
+      "include/grpc/impl/codegen/slice.h", 
+      "include/grpc/impl/codegen/slice_buffer.h", 
+      "include/grpc/impl/codegen/status.h", 
+      "include/grpc/impl/codegen/sync.h", 
+      "include/grpc/impl/codegen/sync_generic.h", 
+      "include/grpc/impl/codegen/sync_posix.h", 
+      "include/grpc/impl/codegen/sync_win32.h", 
+      "include/grpc/impl/codegen/time.h"
+    ], 
+    "language": "c++", 
+    "name": "grpc++_codegen_lib", 
+    "src": [
+      "include/grpc++/impl/codegen/async_stream.h", 
+      "include/grpc++/impl/codegen/async_unary_call.h", 
+      "include/grpc++/impl/codegen/call.h", 
+      "include/grpc++/impl/codegen/call_hook.h", 
+      "include/grpc++/impl/codegen/channel_interface.h", 
+      "include/grpc++/impl/codegen/client_context.h", 
+      "include/grpc++/impl/codegen/client_unary_call.h", 
+      "include/grpc++/impl/codegen/completion_queue.h", 
+      "include/grpc++/impl/codegen/completion_queue_tag.h", 
+      "include/grpc++/impl/codegen/config.h", 
+      "include/grpc++/impl/codegen/config_protobuf.h", 
+      "include/grpc++/impl/codegen/core_codegen_interface.h", 
+      "include/grpc++/impl/codegen/grpc_library.h", 
+      "include/grpc++/impl/codegen/method_handler_impl.h", 
+      "include/grpc++/impl/codegen/proto_utils.h", 
+      "include/grpc++/impl/codegen/rpc_method.h", 
+      "include/grpc++/impl/codegen/rpc_service_method.h", 
+      "include/grpc++/impl/codegen/security/auth_context.h", 
+      "include/grpc++/impl/codegen/serialization_traits.h", 
+      "include/grpc++/impl/codegen/server_context.h", 
+      "include/grpc++/impl/codegen/server_interface.h", 
+      "include/grpc++/impl/codegen/service_type.h", 
+      "include/grpc++/impl/codegen/status.h", 
+      "include/grpc++/impl/codegen/status_code_enum.h", 
+      "include/grpc++/impl/codegen/string_ref.h", 
+      "include/grpc++/impl/codegen/stub_options.h", 
+      "include/grpc++/impl/codegen/sync.h", 
+      "include/grpc++/impl/codegen/sync_cxx11.h", 
+      "include/grpc++/impl/codegen/sync_no_cxx11.h", 
+      "include/grpc++/impl/codegen/sync_stream.h", 
+      "include/grpc++/impl/codegen/time.h", 
+      "include/grpc/impl/codegen/alloc.h", 
+      "include/grpc/impl/codegen/atm.h", 
+      "include/grpc/impl/codegen/atm_gcc_atomic.h", 
+      "include/grpc/impl/codegen/atm_gcc_sync.h", 
+      "include/grpc/impl/codegen/atm_win32.h", 
+      "include/grpc/impl/codegen/byte_buffer.h", 
+      "include/grpc/impl/codegen/compression_types.h", 
+      "include/grpc/impl/codegen/connectivity_state.h", 
+      "include/grpc/impl/codegen/grpc_types.h", 
+      "include/grpc/impl/codegen/log.h", 
+      "include/grpc/impl/codegen/port_platform.h", 
+      "include/grpc/impl/codegen/propagation_bits.h", 
+      "include/grpc/impl/codegen/slice.h", 
+      "include/grpc/impl/codegen/slice_buffer.h", 
+      "include/grpc/impl/codegen/status.h", 
+      "include/grpc/impl/codegen/sync.h", 
+      "include/grpc/impl/codegen/sync_generic.h", 
+      "include/grpc/impl/codegen/sync_posix.h", 
+      "include/grpc/impl/codegen/sync_win32.h", 
+      "include/grpc/impl/codegen/time.h", 
+      "src/cpp/codegen/codegen_init.cc"
+    ], 
+    "third_party": false, 
+    "type": "lib"
+  }, 
+  {
+    "deps": [], 
+    "headers": [
       "test/cpp/util/test_config.h"
     ], 
     "language": "c++", 
@@ -5200,6 +5461,7 @@
       "include/grpc++/impl/codegen/completion_queue_tag.h", 
       "include/grpc++/impl/codegen/config.h", 
       "include/grpc++/impl/codegen/config_protobuf.h", 
+      "include/grpc++/impl/codegen/core_codegen_interface.h", 
       "include/grpc++/impl/codegen/grpc_library.h", 
       "include/grpc++/impl/codegen/method_handler_impl.h", 
       "include/grpc++/impl/codegen/proto_utils.h", 
@@ -5254,6 +5516,7 @@
       "include/grpc++/support/sync_stream.h", 
       "include/grpc++/support/time.h", 
       "src/cpp/client/create_channel_internal.h", 
+      "src/cpp/common/core_codegen.h", 
       "src/cpp/common/create_auth_context.h", 
       "src/cpp/server/dynamic_thread_pool.h", 
       "src/cpp/server/thread_pool_interface.h"
@@ -5282,6 +5545,7 @@
       "include/grpc++/impl/codegen/completion_queue_tag.h", 
       "include/grpc++/impl/codegen/config.h", 
       "include/grpc++/impl/codegen/config_protobuf.h", 
+      "include/grpc++/impl/codegen/core_codegen_interface.h", 
       "include/grpc++/impl/codegen/grpc_library.h", 
       "include/grpc++/impl/codegen/method_handler_impl.h", 
       "include/grpc++/impl/codegen/proto_utils.h", 
@@ -5343,14 +5607,14 @@
       "src/cpp/client/credentials.cc", 
       "src/cpp/client/generic_stub.cc", 
       "src/cpp/client/insecure_credentials.cc", 
-      "src/cpp/codegen/grpc_library.cc", 
-      "src/cpp/common/call.cc", 
+      "src/cpp/codegen/codegen_init.cc", 
       "src/cpp/common/channel_arguments.cc", 
       "src/cpp/common/completion_queue.cc", 
+      "src/cpp/common/core_codegen.cc", 
+      "src/cpp/common/core_codegen.h", 
       "src/cpp/common/create_auth_context.h", 
       "src/cpp/common/insecure_create_auth_context.cc", 
       "src/cpp/common/rpc_method.cc", 
-      "src/cpp/proto/proto_utils.cc", 
       "src/cpp/server/async_generic_service.cc", 
       "src/cpp/server/create_default_thread_pool.cc", 
       "src/cpp/server/dynamic_thread_pool.cc", 
@@ -5371,38 +5635,10 @@
     "type": "lib"
   }, 
   {
-    "deps": [], 
+    "deps": [
+      "grpc++_codegen_lib"
+    ], 
     "headers": [
-      "include/grpc++/impl/codegen/async_stream.h", 
-      "include/grpc++/impl/codegen/async_unary_call.h", 
-      "include/grpc++/impl/codegen/call.h", 
-      "include/grpc++/impl/codegen/call_hook.h", 
-      "include/grpc++/impl/codegen/channel_interface.h", 
-      "include/grpc++/impl/codegen/client_context.h", 
-      "include/grpc++/impl/codegen/client_unary_call.h", 
-      "include/grpc++/impl/codegen/completion_queue.h", 
-      "include/grpc++/impl/codegen/completion_queue_tag.h", 
-      "include/grpc++/impl/codegen/config.h", 
-      "include/grpc++/impl/codegen/config_protobuf.h", 
-      "include/grpc++/impl/codegen/grpc_library.h", 
-      "include/grpc++/impl/codegen/method_handler_impl.h", 
-      "include/grpc++/impl/codegen/proto_utils.h", 
-      "include/grpc++/impl/codegen/rpc_method.h", 
-      "include/grpc++/impl/codegen/rpc_service_method.h", 
-      "include/grpc++/impl/codegen/security/auth_context.h", 
-      "include/grpc++/impl/codegen/serialization_traits.h", 
-      "include/grpc++/impl/codegen/server_context.h", 
-      "include/grpc++/impl/codegen/server_interface.h", 
-      "include/grpc++/impl/codegen/service_type.h", 
-      "include/grpc++/impl/codegen/status.h", 
-      "include/grpc++/impl/codegen/status_code_enum.h", 
-      "include/grpc++/impl/codegen/string_ref.h", 
-      "include/grpc++/impl/codegen/stub_options.h", 
-      "include/grpc++/impl/codegen/sync.h", 
-      "include/grpc++/impl/codegen/sync_cxx11.h", 
-      "include/grpc++/impl/codegen/sync_no_cxx11.h", 
-      "include/grpc++/impl/codegen/sync_stream.h", 
-      "include/grpc++/impl/codegen/time.h", 
       "include/grpc++/support/config.h", 
       "include/grpc++/support/config_protobuf.h", 
       "include/grpc/impl/codegen/alloc.h", 
@@ -5410,16 +5646,10 @@
       "include/grpc/impl/codegen/atm_gcc_atomic.h", 
       "include/grpc/impl/codegen/atm_gcc_sync.h", 
       "include/grpc/impl/codegen/atm_win32.h", 
-      "include/grpc/impl/codegen/byte_buffer.h", 
-      "include/grpc/impl/codegen/compression_types.h", 
-      "include/grpc/impl/codegen/connectivity_state.h", 
-      "include/grpc/impl/codegen/grpc_types.h", 
       "include/grpc/impl/codegen/log.h", 
       "include/grpc/impl/codegen/port_platform.h", 
-      "include/grpc/impl/codegen/propagation_bits.h", 
       "include/grpc/impl/codegen/slice.h", 
       "include/grpc/impl/codegen/slice_buffer.h", 
-      "include/grpc/impl/codegen/status.h", 
       "include/grpc/impl/codegen/sync.h", 
       "include/grpc/impl/codegen/sync_generic.h", 
       "include/grpc/impl/codegen/sync_posix.h", 
@@ -5442,36 +5672,6 @@
     "language": "c++", 
     "name": "grpc_plugin_support", 
     "src": [
-      "include/grpc++/impl/codegen/async_stream.h", 
-      "include/grpc++/impl/codegen/async_unary_call.h", 
-      "include/grpc++/impl/codegen/call.h", 
-      "include/grpc++/impl/codegen/call_hook.h", 
-      "include/grpc++/impl/codegen/channel_interface.h", 
-      "include/grpc++/impl/codegen/client_context.h", 
-      "include/grpc++/impl/codegen/client_unary_call.h", 
-      "include/grpc++/impl/codegen/completion_queue.h", 
-      "include/grpc++/impl/codegen/completion_queue_tag.h", 
-      "include/grpc++/impl/codegen/config.h", 
-      "include/grpc++/impl/codegen/config_protobuf.h", 
-      "include/grpc++/impl/codegen/grpc_library.h", 
-      "include/grpc++/impl/codegen/method_handler_impl.h", 
-      "include/grpc++/impl/codegen/proto_utils.h", 
-      "include/grpc++/impl/codegen/rpc_method.h", 
-      "include/grpc++/impl/codegen/rpc_service_method.h", 
-      "include/grpc++/impl/codegen/security/auth_context.h", 
-      "include/grpc++/impl/codegen/serialization_traits.h", 
-      "include/grpc++/impl/codegen/server_context.h", 
-      "include/grpc++/impl/codegen/server_interface.h", 
-      "include/grpc++/impl/codegen/service_type.h", 
-      "include/grpc++/impl/codegen/status.h", 
-      "include/grpc++/impl/codegen/status_code_enum.h", 
-      "include/grpc++/impl/codegen/string_ref.h", 
-      "include/grpc++/impl/codegen/stub_options.h", 
-      "include/grpc++/impl/codegen/sync.h", 
-      "include/grpc++/impl/codegen/sync_cxx11.h", 
-      "include/grpc++/impl/codegen/sync_no_cxx11.h", 
-      "include/grpc++/impl/codegen/sync_stream.h", 
-      "include/grpc++/impl/codegen/time.h", 
       "include/grpc++/support/config.h", 
       "include/grpc++/support/config_protobuf.h", 
       "include/grpc/impl/codegen/alloc.h", 
@@ -5479,16 +5679,10 @@
       "include/grpc/impl/codegen/atm_gcc_atomic.h", 
       "include/grpc/impl/codegen/atm_gcc_sync.h", 
       "include/grpc/impl/codegen/atm_win32.h", 
-      "include/grpc/impl/codegen/byte_buffer.h", 
-      "include/grpc/impl/codegen/compression_types.h", 
-      "include/grpc/impl/codegen/connectivity_state.h", 
-      "include/grpc/impl/codegen/grpc_types.h", 
       "include/grpc/impl/codegen/log.h", 
       "include/grpc/impl/codegen/port_platform.h", 
-      "include/grpc/impl/codegen/propagation_bits.h", 
       "include/grpc/impl/codegen/slice.h", 
       "include/grpc/impl/codegen/slice_buffer.h", 
-      "include/grpc/impl/codegen/status.h", 
       "include/grpc/impl/codegen/sync.h", 
       "include/grpc/impl/codegen/sync_generic.h", 
       "include/grpc/impl/codegen/sync_posix.h", 
@@ -5511,8 +5705,7 @@
       "src/compiler/ruby_generator.h", 
       "src/compiler/ruby_generator_helpers-inl.h", 
       "src/compiler/ruby_generator_map-inl.h", 
-      "src/compiler/ruby_generator_string-inl.h", 
-      "src/cpp/codegen/grpc_library.cc"
+      "src/compiler/ruby_generator_string-inl.h"
     ], 
     "third_party": false, 
     "type": "lib"
@@ -6324,7 +6517,6 @@
   }, 
   {
     "deps": [
-      "end2end_certs", 
       "gpr", 
       "gpr_test_util", 
       "grpc", 
@@ -6435,18 +6627,5 @@
     ], 
     "third_party": false, 
     "type": "lib"
-  }, 
-  {
-    "deps": [], 
-    "headers": [], 
-    "language": "c", 
-    "name": "end2end_certs", 
-    "src": [
-      "test/core/end2end/data/server1_cert.c", 
-      "test/core/end2end/data/server1_key.c", 
-      "test/core/end2end/data/test_root_cert.c"
-    ], 
-    "third_party": false, 
-    "type": "lib"
   }
 ]
diff --git a/tools/run_tests/stress_test/README.md b/tools/run_tests/stress_test/README.md
new file mode 100644
index 0000000..80e4cd5
--- /dev/null
+++ b/tools/run_tests/stress_test/README.md
@@ -0,0 +1,53 @@
+Running Stress tests on Google Container Engine

+=======================================

+

+### **Glossary**:

+* GCP: Google Cloud Platform

+* GCE: Google Compute Engine

+* GKE: Google Container Engine

+* GCP console: https://console.cloud.google.com

+

+### **Setup Instructions**

+#### *On GCP:*

+1. Login to GCP with your Google account (for example, your @gmail account) at https://cloud.google.com. If do not have a Google account, you will have to create an account first.

+2. Enable billing on Google cloud platform. Instructions [here](https://cloud.google.com/container-engine/docs/before-you-begin)  (see the '*Enable billing*' section).

+3. Create a Project from the [GCP console](https://console.cloud.google.com).i.e Click on the project dropdown box on the top right (to the right of the search box) and click '*Create a project*' option.

+4. Enable the Container Engine API. Instructions [here](https://cloud.google.com/container-engine/docs/before-you-begin)  (See the '*Enable the Container Engine API*’ section). Alternatively, you can do the following:

+    - Click on the '*Products & Services*' icon on the top left (i.e the icon with three small horizontal bars) and select '*API Manager*'

+    - Select the '*Container Engine API*' under '*Google Cloud APIs*' on the main page. Note that you might have to click on '*More*' under '*Google Cloud APIs*' to see the '*Container Engine API*' link

+    - Click on the '*Enable*' button. If the API is already enabled, the button's label would be '*Disable*' instead (do NOT click the button if its label is '*Disable*')

+5. Create a Cluster from the GCP console.

+    - Go to the Container Engine section from GCP console i.e: Click on the '*Products & Services*' icon on the top left (i.e the icon with three small horizontal bars) and click on '*Container Engine*'

+    - Click '*Create Container Cluster*' and follow the instructions.

+    - The instructions for 'Name/Zone/MachineType' etc are [here](https://cloud.google.com/container-engine/docs/clusters/operations) (**NOTE**: The page also has instructions to setting up default clusters and configuring `kubectl`. We will be doing that later)

+    - For the cluster size, a smaller size of < 10 GCE instances is good enough for our use cases - assuming that we are planning to run a reasonably small number of stress client instances. For the machine type, something like '2 vCPUs 7.5 GB' (available in the drop down box) should be good enough.

+    - **IMPORTANT**: Before hitting the '*Create*' button, click on '*More*' link just above the '*Create*' button and Select '*Enabled*' for BigQuery , '*Enabled*' for Cloud Platform and '*Read/Write*' for Cloud User Accounts.

+    - Create the cluster by clicking '*Create*' button.

+

+#### *On your machine* (or the machine from which stress tests on GKE are launched):

+1. You need a working gRPC repository on your machine. If you do not have it, clone the grpc repository from github (https://github.com/grpc/grpc) and follow the instructions [here](https://github.com/grpc/grpc/blob/master/INSTALL.md)

+2. Install Docker. Instructions [here](https://docs.docker.com/engine/installation/)

+3. Install Google Cloud SDK. Instructions [here](https://cloud.google.com/sdk/). This installs the `gcloud` tool

+4. Install `kubectl`, Kubernetes command line tool using `gcloud`. i.e

+    - `$ gcloud components update kubectl`

+5. Install Google python client apis:

+    - `‘$ sudo pip install --upgrade google-api-python-client’`

+    -  **Note**: Do `$ sudo apt-get install python-pip` (or `$ easy_install -U pip`) if you do not have pip

+6. Install the `requests` Python package if you don’t have it already by doing `sudo pip install requests`. More details regarding `requests` package are [here](http://docs.python-requests.org/en/master/user/install/)

+7. Set the `gcloud` defaults: See the instructions [here](https://cloud.google.com/container-engine/docs/before-you-begin) under "*Set gcloud defaults*" section)

+    - Make sure you also fetch the cluster credentials for `kubectl` command to use. I.e `$ gcloud container clusters get-credentials CLUSTER_NAME`

+

+### **Launching Stress tests**

+

+The stress tests are launched by the following script (path is relative to GRPC root directory) :

+`tools/run_tests/stress_test/run_stress_tests_on_gke.py`

+

+The script has several parameters and you can find out more details by using the `--help` flag.

+  - `<grpc_root_dir>$ tools/run_tests/stress_test/run_stress_tests_on_gke.py --help`

+

+> **Example**

+> `$ tools/run_tests/stress_test/run_stress_tests_on_gke.py --project_id=sree-gce --test_duration_secs=180 --num_clients=5`

+

+> Launches the 5 instances of stress test clients, 1 instance of stress test server and runs the test for 180 seconds. The test would be run on the default container cluster (that you have set in `gcloud`) in the project `sree-gce`.

+

+> Note: we currently do not have the ability to launch multiple instances of the server. This can be added very easily in future

diff --git a/tools/run_tests/tests.json b/tools/run_tests/tests.json
index ba7c91d..6c6de6a 100644
--- a/tools/run_tests/tests.json
+++ b/tools/run_tests/tests.json
@@ -466,6 +466,27 @@
     "flaky": false, 
     "gtest": false, 
     "language": "c", 
+    "name": "gpr_backoff_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ]
+  }, 
+  {
+    "args": [], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "gtest": false, 
+    "language": "c", 
     "name": "gpr_cmdline_test", 
     "platforms": [
       "linux", 
@@ -1272,7 +1293,7 @@
     ], 
     "cpu_cost": 0.1, 
     "exclude_configs": [], 
-    "flaky": false, 
+    "flaky": true, 
     "gtest": false, 
     "language": "c", 
     "name": "lb_policies_test", 
@@ -2032,6 +2053,27 @@
     "flaky": false, 
     "gtest": true, 
     "language": "c++", 
+    "name": "codegen_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ]
+  }, 
+  {
+    "args": [], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "gtest": true, 
+    "language": "c++", 
     "name": "credentials_test", 
     "platforms": [
       "linux", 
@@ -2274,8 +2316,10 @@
       "mac", 
       "posix"
     ], 
-    "cpu_cost": 10, 
-    "exclude_configs": [], 
+    "cpu_cost": 0.5, 
+    "exclude_configs": [
+      "tsan"
+    ], 
     "flaky": false, 
     "gtest": false, 
     "language": "c++", 
@@ -2294,7 +2338,9 @@
       "posix"
     ], 
     "cpu_cost": 10, 
-    "exclude_configs": [], 
+    "exclude_configs": [
+      "tsan"
+    ], 
     "flaky": false, 
     "gtest": false, 
     "language": "c++", 
@@ -9100,6 +9146,776 @@
     "ci_platforms": [
       "windows", 
       "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+trace_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "binary_metadata"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+trace_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "call_creds"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+trace_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "cancel_after_accept"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+trace_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "cancel_after_client_done"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+trace_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "cancel_after_invoke"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+trace_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "cancel_before_invoke"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+trace_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "cancel_in_a_vacuum"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+trace_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "cancel_with_status"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+trace_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "compressed_payload"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+trace_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "connectivity"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+trace_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "default_host"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+trace_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "disappearing_server"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+trace_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "empty_batch"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+trace_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "graceful_server_shutdown"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+trace_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "high_initial_seqno"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+trace_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "invoke_large_request"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+trace_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "large_metadata"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+trace_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "max_concurrent_streams"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+trace_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "max_message_length"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+trace_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "negative_deadline"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+trace_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "no_op"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+trace_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "payload"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+trace_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "ping"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+trace_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "ping_pong_streaming"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+trace_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "registered_call"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+trace_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "request_with_flags"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+trace_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "request_with_payload"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+trace_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "server_finishes_request"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+trace_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "shutdown_finishes_calls"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+trace_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "shutdown_finishes_tags"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+trace_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "simple_delayed_request"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+trace_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "simple_metadata"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+trace_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "simple_request"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+trace_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "trailing_metadata"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+trace_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "bad_hostname"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
       "posix"
     ], 
     "cpu_cost": 1.0, 
@@ -11137,7 +11953,6 @@
     "ci_platforms": [
       "windows", 
       "linux", 
-      "mac", 
       "posix"
     ], 
     "cpu_cost": 1.0, 
@@ -11159,7 +11974,6 @@
     "ci_platforms": [
       "windows", 
       "linux", 
-      "mac", 
       "posix"
     ], 
     "cpu_cost": 1.0, 
@@ -11181,7 +11995,6 @@
     "ci_platforms": [
       "windows", 
       "linux", 
-      "mac", 
       "posix"
     ], 
     "cpu_cost": 1.0, 
@@ -11203,7 +12016,6 @@
     "ci_platforms": [
       "windows", 
       "linux", 
-      "mac", 
       "posix"
     ], 
     "cpu_cost": 0.1, 
@@ -11225,7 +12037,6 @@
     "ci_platforms": [
       "windows", 
       "linux", 
-      "mac", 
       "posix"
     ], 
     "cpu_cost": 0.1, 
@@ -11247,7 +12058,6 @@
     "ci_platforms": [
       "windows", 
       "linux", 
-      "mac", 
       "posix"
     ], 
     "cpu_cost": 0.1, 
@@ -11269,7 +12079,6 @@
     "ci_platforms": [
       "windows", 
       "linux", 
-      "mac", 
       "posix"
     ], 
     "cpu_cost": 0.1, 
@@ -11291,7 +12100,6 @@
     "ci_platforms": [
       "windows", 
       "linux", 
-      "mac", 
       "posix"
     ], 
     "cpu_cost": 0.1, 
@@ -11313,7 +12121,6 @@
     "ci_platforms": [
       "windows", 
       "linux", 
-      "mac", 
       "posix"
     ], 
     "cpu_cost": 0.1, 
@@ -11335,7 +12142,6 @@
     "ci_platforms": [
       "windows", 
       "linux", 
-      "mac", 
       "posix"
     ], 
     "cpu_cost": 0.1, 
@@ -11357,7 +12163,6 @@
     "ci_platforms": [
       "windows", 
       "linux", 
-      "mac", 
       "posix"
     ], 
     "cpu_cost": 1.0, 
@@ -11379,7 +12184,6 @@
     "ci_platforms": [
       "windows", 
       "linux", 
-      "mac", 
       "posix"
     ], 
     "cpu_cost": 0.1, 
@@ -11401,7 +12205,6 @@
     "ci_platforms": [
       "windows", 
       "linux", 
-      "mac", 
       "posix"
     ], 
     "cpu_cost": 1.0, 
@@ -11423,7 +12226,6 @@
     "ci_platforms": [
       "windows", 
       "linux", 
-      "mac", 
       "posix"
     ], 
     "cpu_cost": 1.0, 
@@ -11445,7 +12247,6 @@
     "ci_platforms": [
       "windows", 
       "linux", 
-      "mac", 
       "posix"
     ], 
     "cpu_cost": 1.0, 
@@ -11467,7 +12268,6 @@
     "ci_platforms": [
       "windows", 
       "linux", 
-      "mac", 
       "posix"
     ], 
     "cpu_cost": 1.0, 
@@ -11489,7 +12289,6 @@
     "ci_platforms": [
       "windows", 
       "linux", 
-      "mac", 
       "posix"
     ], 
     "cpu_cost": 0.1, 
@@ -11511,7 +12310,6 @@
     "ci_platforms": [
       "windows", 
       "linux", 
-      "mac", 
       "posix"
     ], 
     "cpu_cost": 1.0, 
@@ -11533,7 +12331,6 @@
     "ci_platforms": [
       "windows", 
       "linux", 
-      "mac", 
       "posix"
     ], 
     "cpu_cost": 1.0, 
@@ -11555,7 +12352,6 @@
     "ci_platforms": [
       "windows", 
       "linux", 
-      "mac", 
       "posix"
     ], 
     "cpu_cost": 0.1, 
@@ -11577,7 +12373,6 @@
     "ci_platforms": [
       "windows", 
       "linux", 
-      "mac", 
       "posix"
     ], 
     "cpu_cost": 1.0, 
@@ -11599,7 +12394,6 @@
     "ci_platforms": [
       "windows", 
       "linux", 
-      "mac", 
       "posix"
     ], 
     "cpu_cost": 1.0, 
@@ -11621,7 +12415,6 @@
     "ci_platforms": [
       "windows", 
       "linux", 
-      "mac", 
       "posix"
     ], 
     "cpu_cost": 1.0, 
@@ -11643,7 +12436,6 @@
     "ci_platforms": [
       "windows", 
       "linux", 
-      "mac", 
       "posix"
     ], 
     "cpu_cost": 1.0, 
@@ -11665,7 +12457,6 @@
     "ci_platforms": [
       "windows", 
       "linux", 
-      "mac", 
       "posix"
     ], 
     "cpu_cost": 1.0, 
@@ -11687,7 +12478,6 @@
     "ci_platforms": [
       "windows", 
       "linux", 
-      "mac", 
       "posix"
     ], 
     "cpu_cost": 1.0, 
@@ -11709,7 +12499,6 @@
     "ci_platforms": [
       "windows", 
       "linux", 
-      "mac", 
       "posix"
     ], 
     "cpu_cost": 1.0, 
@@ -11731,7 +12520,6 @@
     "ci_platforms": [
       "windows", 
       "linux", 
-      "mac", 
       "posix"
     ], 
     "cpu_cost": 1.0, 
@@ -11753,7 +12541,6 @@
     "ci_platforms": [
       "windows", 
       "linux", 
-      "mac", 
       "posix"
     ], 
     "cpu_cost": 1.0, 
@@ -11775,7 +12562,6 @@
     "ci_platforms": [
       "windows", 
       "linux", 
-      "mac", 
       "posix"
     ], 
     "cpu_cost": 1.0, 
@@ -20378,6 +21164,754 @@
     "ci_platforms": [
       "windows", 
       "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+trace_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "binary_metadata"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+trace_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "cancel_after_accept"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+trace_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "cancel_after_client_done"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+trace_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "cancel_after_invoke"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+trace_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "cancel_before_invoke"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+trace_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "cancel_in_a_vacuum"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+trace_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "cancel_with_status"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+trace_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "compressed_payload"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+trace_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "connectivity"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+trace_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "default_host"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+trace_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "disappearing_server"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+trace_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "empty_batch"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+trace_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "graceful_server_shutdown"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+trace_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "high_initial_seqno"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+trace_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "invoke_large_request"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+trace_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "large_metadata"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+trace_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "max_concurrent_streams"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+trace_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "max_message_length"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+trace_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "negative_deadline"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+trace_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "no_op"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+trace_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "payload"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+trace_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "ping"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+trace_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "ping_pong_streaming"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+trace_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "registered_call"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+trace_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "request_with_flags"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+trace_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "request_with_payload"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+trace_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "server_finishes_request"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+trace_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "shutdown_finishes_calls"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+trace_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "shutdown_finishes_tags"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+trace_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "simple_delayed_request"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+trace_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "simple_metadata"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+trace_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "simple_request"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+trace_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "trailing_metadata"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+trace_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "bad_hostname"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
       "posix"
     ], 
     "cpu_cost": 1.0, 
@@ -21617,7 +23151,6 @@
     "ci_platforms": [
       "windows", 
       "linux", 
-      "mac", 
       "posix"
     ], 
     "cpu_cost": 1.0, 
@@ -21639,7 +23172,6 @@
     "ci_platforms": [
       "windows", 
       "linux", 
-      "mac", 
       "posix"
     ], 
     "cpu_cost": 1.0, 
@@ -21661,7 +23193,6 @@
     "ci_platforms": [
       "windows", 
       "linux", 
-      "mac", 
       "posix"
     ], 
     "cpu_cost": 0.1, 
@@ -21683,7 +23214,6 @@
     "ci_platforms": [
       "windows", 
       "linux", 
-      "mac", 
       "posix"
     ], 
     "cpu_cost": 0.1, 
@@ -21705,7 +23235,6 @@
     "ci_platforms": [
       "windows", 
       "linux", 
-      "mac", 
       "posix"
     ], 
     "cpu_cost": 0.1, 
@@ -21727,7 +23256,6 @@
     "ci_platforms": [
       "windows", 
       "linux", 
-      "mac", 
       "posix"
     ], 
     "cpu_cost": 0.1, 
@@ -21749,7 +23277,6 @@
     "ci_platforms": [
       "windows", 
       "linux", 
-      "mac", 
       "posix"
     ], 
     "cpu_cost": 0.1, 
@@ -21771,7 +23298,6 @@
     "ci_platforms": [
       "windows", 
       "linux", 
-      "mac", 
       "posix"
     ], 
     "cpu_cost": 0.1, 
@@ -21793,7 +23319,6 @@
     "ci_platforms": [
       "windows", 
       "linux", 
-      "mac", 
       "posix"
     ], 
     "cpu_cost": 0.1, 
@@ -21815,7 +23340,6 @@
     "ci_platforms": [
       "windows", 
       "linux", 
-      "mac", 
       "posix"
     ], 
     "cpu_cost": 1.0, 
@@ -21837,7 +23361,6 @@
     "ci_platforms": [
       "windows", 
       "linux", 
-      "mac", 
       "posix"
     ], 
     "cpu_cost": 0.1, 
@@ -21859,7 +23382,6 @@
     "ci_platforms": [
       "windows", 
       "linux", 
-      "mac", 
       "posix"
     ], 
     "cpu_cost": 1.0, 
@@ -21881,7 +23403,6 @@
     "ci_platforms": [
       "windows", 
       "linux", 
-      "mac", 
       "posix"
     ], 
     "cpu_cost": 1.0, 
@@ -21903,7 +23424,6 @@
     "ci_platforms": [
       "windows", 
       "linux", 
-      "mac", 
       "posix"
     ], 
     "cpu_cost": 1.0, 
@@ -21925,7 +23445,6 @@
     "ci_platforms": [
       "windows", 
       "linux", 
-      "mac", 
       "posix"
     ], 
     "cpu_cost": 1.0, 
@@ -21947,7 +23466,6 @@
     "ci_platforms": [
       "windows", 
       "linux", 
-      "mac", 
       "posix"
     ], 
     "cpu_cost": 0.1, 
@@ -21969,7 +23487,6 @@
     "ci_platforms": [
       "windows", 
       "linux", 
-      "mac", 
       "posix"
     ], 
     "cpu_cost": 1.0, 
@@ -21991,7 +23508,6 @@
     "ci_platforms": [
       "windows", 
       "linux", 
-      "mac", 
       "posix"
     ], 
     "cpu_cost": 1.0, 
@@ -22013,7 +23529,6 @@
     "ci_platforms": [
       "windows", 
       "linux", 
-      "mac", 
       "posix"
     ], 
     "cpu_cost": 0.1, 
@@ -22035,7 +23550,6 @@
     "ci_platforms": [
       "windows", 
       "linux", 
-      "mac", 
       "posix"
     ], 
     "cpu_cost": 1.0, 
@@ -22057,7 +23571,6 @@
     "ci_platforms": [
       "windows", 
       "linux", 
-      "mac", 
       "posix"
     ], 
     "cpu_cost": 1.0, 
@@ -22079,7 +23592,6 @@
     "ci_platforms": [
       "windows", 
       "linux", 
-      "mac", 
       "posix"
     ], 
     "cpu_cost": 1.0, 
@@ -22101,7 +23613,6 @@
     "ci_platforms": [
       "windows", 
       "linux", 
-      "mac", 
       "posix"
     ], 
     "cpu_cost": 1.0, 
@@ -22123,7 +23634,6 @@
     "ci_platforms": [
       "windows", 
       "linux", 
-      "mac", 
       "posix"
     ], 
     "cpu_cost": 1.0, 
@@ -22145,7 +23655,6 @@
     "ci_platforms": [
       "windows", 
       "linux", 
-      "mac", 
       "posix"
     ], 
     "cpu_cost": 1.0, 
@@ -22167,7 +23676,6 @@
     "ci_platforms": [
       "windows", 
       "linux", 
-      "mac", 
       "posix"
     ], 
     "cpu_cost": 1.0, 
@@ -22189,7 +23697,6 @@
     "ci_platforms": [
       "windows", 
       "linux", 
-      "mac", 
       "posix"
     ], 
     "cpu_cost": 1.0, 
@@ -22211,7 +23718,6 @@
     "ci_platforms": [
       "windows", 
       "linux", 
-      "mac", 
       "posix"
     ], 
     "cpu_cost": 1.0, 
@@ -22233,7 +23739,6 @@
     "ci_platforms": [
       "windows", 
       "linux", 
-      "mac", 
       "posix"
     ], 
     "cpu_cost": 1.0, 
diff --git a/vsprojects/buildtests_c.sln b/vsprojects/buildtests_c.sln
index 413ed3e..8c64423 100644
--- a/vsprojects/buildtests_c.sln
+++ b/vsprojects/buildtests_c.sln
@@ -100,7 +100,6 @@
         	lib = "True"
 	EndProjectSection
 	ProjectSection(ProjectDependencies) = postProject
-		{80EA2691-C037-6DD3-D3AB-21510BF0E64B} = {80EA2691-C037-6DD3-D3AB-21510BF0E64B}
 		{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B} = {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}
 		{29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9}
 		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
@@ -118,11 +117,6 @@
 		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
 	EndProjectSection
 EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "end2end_certs", "vcxproj\test/end2end\end2end_certs\end2end_certs.vcxproj", "{80EA2691-C037-6DD3-D3AB-21510BF0E64B}"
-	ProjectSection(myProperties) = preProject
-        	lib = "True"
-	EndProjectSection
-EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "alarm_test", "vcxproj\test\alarm_test\alarm_test.vcxproj", "{AFD362D7-0E2A-E700-1F27-9D90F76166DF}"
 	ProjectSection(myProperties) = preProject
         	lib = "False"
@@ -340,6 +334,15 @@
 		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
 	EndProjectSection
 EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gpr_backoff_test", "vcxproj\test\gpr_backoff_test\gpr_backoff_test.vcxproj", "{889F570D-E046-BD52-9E4C-B4CD13DFE2DB}"
+	ProjectSection(myProperties) = preProject
+        	lib = "False"
+	EndProjectSection
+	ProjectSection(ProjectDependencies) = postProject
+		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
+		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
+	EndProjectSection
+EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gpr_cmdline_test", "vcxproj\test\gpr_cmdline_test\gpr_cmdline_test.vcxproj", "{10668A5D-65CD-F530-22D0-747B395B4C26}"
 	ProjectSection(myProperties) = preProject
         	lib = "False"
@@ -1100,7 +1103,6 @@
 	EndProjectSection
 	ProjectSection(ProjectDependencies) = postProject
 		{1F1F9084-2A93-B80E-364F-5754894AFAB4} = {1F1F9084-2A93-B80E-364F-5754894AFAB4}
-		{80EA2691-C037-6DD3-D3AB-21510BF0E64B} = {80EA2691-C037-6DD3-D3AB-21510BF0E64B}
 		{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B} = {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}
 		{29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9}
 		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
@@ -1113,7 +1115,6 @@
 	EndProjectSection
 	ProjectSection(ProjectDependencies) = postProject
 		{1F1F9084-2A93-B80E-364F-5754894AFAB4} = {1F1F9084-2A93-B80E-364F-5754894AFAB4}
-		{80EA2691-C037-6DD3-D3AB-21510BF0E64B} = {80EA2691-C037-6DD3-D3AB-21510BF0E64B}
 		{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B} = {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}
 		{29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9}
 		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
@@ -1126,7 +1127,6 @@
 	EndProjectSection
 	ProjectSection(ProjectDependencies) = postProject
 		{1F1F9084-2A93-B80E-364F-5754894AFAB4} = {1F1F9084-2A93-B80E-364F-5754894AFAB4}
-		{80EA2691-C037-6DD3-D3AB-21510BF0E64B} = {80EA2691-C037-6DD3-D3AB-21510BF0E64B}
 		{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B} = {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}
 		{29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9}
 		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
@@ -1139,7 +1139,18 @@
 	EndProjectSection
 	ProjectSection(ProjectDependencies) = postProject
 		{1F1F9084-2A93-B80E-364F-5754894AFAB4} = {1F1F9084-2A93-B80E-364F-5754894AFAB4}
-		{80EA2691-C037-6DD3-D3AB-21510BF0E64B} = {80EA2691-C037-6DD3-D3AB-21510BF0E64B}
+		{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B} = {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}
+		{29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9}
+		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
+		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "h2_full+trace_test", "vcxproj\test/end2end/fixtures\h2_full+trace_test\h2_full+trace_test.vcxproj", "{16C713C6-062E-F71F-A44C-52DC35494B27}"
+	ProjectSection(myProperties) = preProject
+        	lib = "False"
+	EndProjectSection
+	ProjectSection(ProjectDependencies) = postProject
+		{1F1F9084-2A93-B80E-364F-5754894AFAB4} = {1F1F9084-2A93-B80E-364F-5754894AFAB4}
 		{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B} = {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}
 		{29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9}
 		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
@@ -1152,7 +1163,6 @@
 	EndProjectSection
 	ProjectSection(ProjectDependencies) = postProject
 		{1F1F9084-2A93-B80E-364F-5754894AFAB4} = {1F1F9084-2A93-B80E-364F-5754894AFAB4}
-		{80EA2691-C037-6DD3-D3AB-21510BF0E64B} = {80EA2691-C037-6DD3-D3AB-21510BF0E64B}
 		{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B} = {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}
 		{29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9}
 		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
@@ -1165,7 +1175,6 @@
 	EndProjectSection
 	ProjectSection(ProjectDependencies) = postProject
 		{1F1F9084-2A93-B80E-364F-5754894AFAB4} = {1F1F9084-2A93-B80E-364F-5754894AFAB4}
-		{80EA2691-C037-6DD3-D3AB-21510BF0E64B} = {80EA2691-C037-6DD3-D3AB-21510BF0E64B}
 		{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B} = {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}
 		{29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9}
 		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
@@ -1178,7 +1187,6 @@
 	EndProjectSection
 	ProjectSection(ProjectDependencies) = postProject
 		{1F1F9084-2A93-B80E-364F-5754894AFAB4} = {1F1F9084-2A93-B80E-364F-5754894AFAB4}
-		{80EA2691-C037-6DD3-D3AB-21510BF0E64B} = {80EA2691-C037-6DD3-D3AB-21510BF0E64B}
 		{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B} = {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}
 		{29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9}
 		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
@@ -1191,7 +1199,6 @@
 	EndProjectSection
 	ProjectSection(ProjectDependencies) = postProject
 		{1F1F9084-2A93-B80E-364F-5754894AFAB4} = {1F1F9084-2A93-B80E-364F-5754894AFAB4}
-		{80EA2691-C037-6DD3-D3AB-21510BF0E64B} = {80EA2691-C037-6DD3-D3AB-21510BF0E64B}
 		{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B} = {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}
 		{29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9}
 		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
@@ -1204,7 +1211,6 @@
 	EndProjectSection
 	ProjectSection(ProjectDependencies) = postProject
 		{1F1F9084-2A93-B80E-364F-5754894AFAB4} = {1F1F9084-2A93-B80E-364F-5754894AFAB4}
-		{80EA2691-C037-6DD3-D3AB-21510BF0E64B} = {80EA2691-C037-6DD3-D3AB-21510BF0E64B}
 		{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B} = {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}
 		{29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9}
 		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
@@ -1217,7 +1223,6 @@
 	EndProjectSection
 	ProjectSection(ProjectDependencies) = postProject
 		{1F1F9084-2A93-B80E-364F-5754894AFAB4} = {1F1F9084-2A93-B80E-364F-5754894AFAB4}
-		{80EA2691-C037-6DD3-D3AB-21510BF0E64B} = {80EA2691-C037-6DD3-D3AB-21510BF0E64B}
 		{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B} = {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}
 		{29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9}
 		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
@@ -1230,7 +1235,6 @@
 	EndProjectSection
 	ProjectSection(ProjectDependencies) = postProject
 		{1F1F9084-2A93-B80E-364F-5754894AFAB4} = {1F1F9084-2A93-B80E-364F-5754894AFAB4}
-		{80EA2691-C037-6DD3-D3AB-21510BF0E64B} = {80EA2691-C037-6DD3-D3AB-21510BF0E64B}
 		{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B} = {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}
 		{29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9}
 		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
@@ -1243,7 +1247,6 @@
 	EndProjectSection
 	ProjectSection(ProjectDependencies) = postProject
 		{1F1F9084-2A93-B80E-364F-5754894AFAB4} = {1F1F9084-2A93-B80E-364F-5754894AFAB4}
-		{80EA2691-C037-6DD3-D3AB-21510BF0E64B} = {80EA2691-C037-6DD3-D3AB-21510BF0E64B}
 		{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B} = {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}
 		{29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9}
 		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
@@ -1286,6 +1289,18 @@
 		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
 	EndProjectSection
 EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "h2_full+trace_nosec_test", "vcxproj\test/end2end/fixtures\h2_full+trace_nosec_test\h2_full+trace_nosec_test.vcxproj", "{DFD51943-4906-8051-7D66-6A7D50E0D87E}"
+	ProjectSection(myProperties) = preProject
+        	lib = "False"
+	EndProjectSection
+	ProjectSection(ProjectDependencies) = postProject
+		{47C2CB41-4E9F-58B6-F606-F6FAED5D00ED} = {47C2CB41-4E9F-58B6-F606-F6FAED5D00ED}
+		{0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF} = {0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF}
+		{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5} = {46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}
+		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
+		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
+	EndProjectSection
+EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "h2_proxy_nosec_test", "vcxproj\test/end2end/fixtures\h2_proxy_nosec_test\h2_proxy_nosec_test.vcxproj", "{6EC72045-98CB-8A8D-9788-BC94209E23C8}"
 	ProjectSection(myProperties) = preProject
         	lib = "False"
@@ -1550,22 +1565,6 @@
 		{47C2CB41-4E9F-58B6-F606-F6FAED5D00ED}.Release-DLL|Win32.Build.0 = Release|Win32
 		{47C2CB41-4E9F-58B6-F606-F6FAED5D00ED}.Release-DLL|x64.ActiveCfg = Release|x64
 		{47C2CB41-4E9F-58B6-F606-F6FAED5D00ED}.Release-DLL|x64.Build.0 = Release|x64
-		{80EA2691-C037-6DD3-D3AB-21510BF0E64B}.Debug|Win32.ActiveCfg = Debug|Win32
-		{80EA2691-C037-6DD3-D3AB-21510BF0E64B}.Debug|x64.ActiveCfg = Debug|x64
-		{80EA2691-C037-6DD3-D3AB-21510BF0E64B}.Release|Win32.ActiveCfg = Release|Win32
-		{80EA2691-C037-6DD3-D3AB-21510BF0E64B}.Release|x64.ActiveCfg = Release|x64
-		{80EA2691-C037-6DD3-D3AB-21510BF0E64B}.Debug|Win32.Build.0 = Debug|Win32
-		{80EA2691-C037-6DD3-D3AB-21510BF0E64B}.Debug|x64.Build.0 = Debug|x64
-		{80EA2691-C037-6DD3-D3AB-21510BF0E64B}.Release|Win32.Build.0 = Release|Win32
-		{80EA2691-C037-6DD3-D3AB-21510BF0E64B}.Release|x64.Build.0 = Release|x64
-		{80EA2691-C037-6DD3-D3AB-21510BF0E64B}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
-		{80EA2691-C037-6DD3-D3AB-21510BF0E64B}.Debug-DLL|Win32.Build.0 = Debug|Win32
-		{80EA2691-C037-6DD3-D3AB-21510BF0E64B}.Debug-DLL|x64.ActiveCfg = Debug|x64
-		{80EA2691-C037-6DD3-D3AB-21510BF0E64B}.Debug-DLL|x64.Build.0 = Debug|x64
-		{80EA2691-C037-6DD3-D3AB-21510BF0E64B}.Release-DLL|Win32.ActiveCfg = Release|Win32
-		{80EA2691-C037-6DD3-D3AB-21510BF0E64B}.Release-DLL|Win32.Build.0 = Release|Win32
-		{80EA2691-C037-6DD3-D3AB-21510BF0E64B}.Release-DLL|x64.ActiveCfg = Release|x64
-		{80EA2691-C037-6DD3-D3AB-21510BF0E64B}.Release-DLL|x64.Build.0 = Release|x64
 		{AFD362D7-0E2A-E700-1F27-9D90F76166DF}.Debug|Win32.ActiveCfg = Debug|Win32
 		{AFD362D7-0E2A-E700-1F27-9D90F76166DF}.Debug|x64.ActiveCfg = Debug|x64
 		{AFD362D7-0E2A-E700-1F27-9D90F76166DF}.Release|Win32.ActiveCfg = Release|Win32
@@ -1902,6 +1901,22 @@
 		{144D8CFF-2737-A18A-DCFD-01603533D63F}.Release-DLL|Win32.Build.0 = Release|Win32
 		{144D8CFF-2737-A18A-DCFD-01603533D63F}.Release-DLL|x64.ActiveCfg = Release|x64
 		{144D8CFF-2737-A18A-DCFD-01603533D63F}.Release-DLL|x64.Build.0 = Release|x64
+		{889F570D-E046-BD52-9E4C-B4CD13DFE2DB}.Debug|Win32.ActiveCfg = Debug|Win32
+		{889F570D-E046-BD52-9E4C-B4CD13DFE2DB}.Debug|x64.ActiveCfg = Debug|x64
+		{889F570D-E046-BD52-9E4C-B4CD13DFE2DB}.Release|Win32.ActiveCfg = Release|Win32
+		{889F570D-E046-BD52-9E4C-B4CD13DFE2DB}.Release|x64.ActiveCfg = Release|x64
+		{889F570D-E046-BD52-9E4C-B4CD13DFE2DB}.Debug|Win32.Build.0 = Debug|Win32
+		{889F570D-E046-BD52-9E4C-B4CD13DFE2DB}.Debug|x64.Build.0 = Debug|x64
+		{889F570D-E046-BD52-9E4C-B4CD13DFE2DB}.Release|Win32.Build.0 = Release|Win32
+		{889F570D-E046-BD52-9E4C-B4CD13DFE2DB}.Release|x64.Build.0 = Release|x64
+		{889F570D-E046-BD52-9E4C-B4CD13DFE2DB}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
+		{889F570D-E046-BD52-9E4C-B4CD13DFE2DB}.Debug-DLL|Win32.Build.0 = Debug|Win32
+		{889F570D-E046-BD52-9E4C-B4CD13DFE2DB}.Debug-DLL|x64.ActiveCfg = Debug|x64
+		{889F570D-E046-BD52-9E4C-B4CD13DFE2DB}.Debug-DLL|x64.Build.0 = Debug|x64
+		{889F570D-E046-BD52-9E4C-B4CD13DFE2DB}.Release-DLL|Win32.ActiveCfg = Release|Win32
+		{889F570D-E046-BD52-9E4C-B4CD13DFE2DB}.Release-DLL|Win32.Build.0 = Release|Win32
+		{889F570D-E046-BD52-9E4C-B4CD13DFE2DB}.Release-DLL|x64.ActiveCfg = Release|x64
+		{889F570D-E046-BD52-9E4C-B4CD13DFE2DB}.Release-DLL|x64.Build.0 = Release|x64
 		{10668A5D-65CD-F530-22D0-747B395B4C26}.Debug|Win32.ActiveCfg = Debug|Win32
 		{10668A5D-65CD-F530-22D0-747B395B4C26}.Debug|x64.ActiveCfg = Debug|x64
 		{10668A5D-65CD-F530-22D0-747B395B4C26}.Release|Win32.ActiveCfg = Release|Win32
@@ -3102,6 +3117,22 @@
 		{EEBEFA75-C625-C823-FE96-9AD64887B57D}.Release-DLL|Win32.Build.0 = Release|Win32
 		{EEBEFA75-C625-C823-FE96-9AD64887B57D}.Release-DLL|x64.ActiveCfg = Release|x64
 		{EEBEFA75-C625-C823-FE96-9AD64887B57D}.Release-DLL|x64.Build.0 = Release|x64
+		{16C713C6-062E-F71F-A44C-52DC35494B27}.Debug|Win32.ActiveCfg = Debug|Win32
+		{16C713C6-062E-F71F-A44C-52DC35494B27}.Debug|x64.ActiveCfg = Debug|x64
+		{16C713C6-062E-F71F-A44C-52DC35494B27}.Release|Win32.ActiveCfg = Release|Win32
+		{16C713C6-062E-F71F-A44C-52DC35494B27}.Release|x64.ActiveCfg = Release|x64
+		{16C713C6-062E-F71F-A44C-52DC35494B27}.Debug|Win32.Build.0 = Debug|Win32
+		{16C713C6-062E-F71F-A44C-52DC35494B27}.Debug|x64.Build.0 = Debug|x64
+		{16C713C6-062E-F71F-A44C-52DC35494B27}.Release|Win32.Build.0 = Release|Win32
+		{16C713C6-062E-F71F-A44C-52DC35494B27}.Release|x64.Build.0 = Release|x64
+		{16C713C6-062E-F71F-A44C-52DC35494B27}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
+		{16C713C6-062E-F71F-A44C-52DC35494B27}.Debug-DLL|Win32.Build.0 = Debug|Win32
+		{16C713C6-062E-F71F-A44C-52DC35494B27}.Debug-DLL|x64.ActiveCfg = Debug|x64
+		{16C713C6-062E-F71F-A44C-52DC35494B27}.Debug-DLL|x64.Build.0 = Debug|x64
+		{16C713C6-062E-F71F-A44C-52DC35494B27}.Release-DLL|Win32.ActiveCfg = Release|Win32
+		{16C713C6-062E-F71F-A44C-52DC35494B27}.Release-DLL|Win32.Build.0 = Release|Win32
+		{16C713C6-062E-F71F-A44C-52DC35494B27}.Release-DLL|x64.ActiveCfg = Release|x64
+		{16C713C6-062E-F71F-A44C-52DC35494B27}.Release-DLL|x64.Build.0 = Release|x64
 		{0F761FF3-342A-C429-711F-F76181BAA52D}.Debug|Win32.ActiveCfg = Debug|Win32
 		{0F761FF3-342A-C429-711F-F76181BAA52D}.Debug|x64.ActiveCfg = Debug|x64
 		{0F761FF3-342A-C429-711F-F76181BAA52D}.Release|Win32.ActiveCfg = Release|Win32
@@ -3278,6 +3309,22 @@
 		{345EA50E-BCD4-DAC7-E1C8-DDA6291B75E2}.Release-DLL|Win32.Build.0 = Release|Win32
 		{345EA50E-BCD4-DAC7-E1C8-DDA6291B75E2}.Release-DLL|x64.ActiveCfg = Release|x64
 		{345EA50E-BCD4-DAC7-E1C8-DDA6291B75E2}.Release-DLL|x64.Build.0 = Release|x64
+		{DFD51943-4906-8051-7D66-6A7D50E0D87E}.Debug|Win32.ActiveCfg = Debug|Win32
+		{DFD51943-4906-8051-7D66-6A7D50E0D87E}.Debug|x64.ActiveCfg = Debug|x64
+		{DFD51943-4906-8051-7D66-6A7D50E0D87E}.Release|Win32.ActiveCfg = Release|Win32
+		{DFD51943-4906-8051-7D66-6A7D50E0D87E}.Release|x64.ActiveCfg = Release|x64
+		{DFD51943-4906-8051-7D66-6A7D50E0D87E}.Debug|Win32.Build.0 = Debug|Win32
+		{DFD51943-4906-8051-7D66-6A7D50E0D87E}.Debug|x64.Build.0 = Debug|x64
+		{DFD51943-4906-8051-7D66-6A7D50E0D87E}.Release|Win32.Build.0 = Release|Win32
+		{DFD51943-4906-8051-7D66-6A7D50E0D87E}.Release|x64.Build.0 = Release|x64
+		{DFD51943-4906-8051-7D66-6A7D50E0D87E}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
+		{DFD51943-4906-8051-7D66-6A7D50E0D87E}.Debug-DLL|Win32.Build.0 = Debug|Win32
+		{DFD51943-4906-8051-7D66-6A7D50E0D87E}.Debug-DLL|x64.ActiveCfg = Debug|x64
+		{DFD51943-4906-8051-7D66-6A7D50E0D87E}.Debug-DLL|x64.Build.0 = Debug|x64
+		{DFD51943-4906-8051-7D66-6A7D50E0D87E}.Release-DLL|Win32.ActiveCfg = Release|Win32
+		{DFD51943-4906-8051-7D66-6A7D50E0D87E}.Release-DLL|Win32.Build.0 = Release|Win32
+		{DFD51943-4906-8051-7D66-6A7D50E0D87E}.Release-DLL|x64.ActiveCfg = Release|x64
+		{DFD51943-4906-8051-7D66-6A7D50E0D87E}.Release-DLL|x64.Build.0 = Release|x64
 		{6EC72045-98CB-8A8D-9788-BC94209E23C8}.Debug|Win32.ActiveCfg = Debug|Win32
 		{6EC72045-98CB-8A8D-9788-BC94209E23C8}.Debug|x64.ActiveCfg = Debug|x64
 		{6EC72045-98CB-8A8D-9788-BC94209E23C8}.Release|Win32.ActiveCfg = Release|Win32
diff --git a/vsprojects/grpc_protoc_plugins.sln b/vsprojects/grpc_protoc_plugins.sln
index ef1cbb8..9471aae 100644
--- a/vsprojects/grpc_protoc_plugins.sln
+++ b/vsprojects/grpc_protoc_plugins.sln
@@ -3,10 +3,23 @@
 # Visual Studio 2013
 VisualStudioVersion = 12.0.21005.1
 MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "grpc_codegen_lib", "vcxproj\.\grpc_codegen_lib\grpc_codegen_lib.vcxproj", "{A828FD72-44CE-4EA5-8966-6E4624458D58}"
+	ProjectSection(myProperties) = preProject
+        	lib = "True"
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "grpc++_codegen_lib", "vcxproj\.\grpc++_codegen_lib\grpc++_codegen_lib.vcxproj", "{AAC6AF12-94C8-4A3C-A1BF-DAA4738F4500}"
+	ProjectSection(myProperties) = preProject
+        	lib = "True"
+	EndProjectSection
+EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "grpc_plugin_support", "vcxproj\.\grpc_plugin_support\grpc_plugin_support.vcxproj", "{B6E81D84-2ACB-41B8-8781-493A944C7817}"
 	ProjectSection(myProperties) = preProject
         	lib = "True"
 	EndProjectSection
+	ProjectSection(ProjectDependencies) = postProject
+		{AAC6AF12-94C8-4A3C-A1BF-DAA4738F4500} = {AAC6AF12-94C8-4A3C-A1BF-DAA4738F4500}
+	EndProjectSection
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "grpc_cpp_plugin", "vcxproj\.\grpc_cpp_plugin\grpc_cpp_plugin.vcxproj", "{7E51A25F-AC59-488F-906C-C60FAAE706AA}"
 	ProjectSection(myProperties) = preProject
@@ -56,6 +69,22 @@
 		Release|x64 = Release|x64
 	EndGlobalSection
 	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{A828FD72-44CE-4EA5-8966-6E4624458D58}.Debug|Win32.ActiveCfg = Debug|Win32
+		{A828FD72-44CE-4EA5-8966-6E4624458D58}.Debug|x64.ActiveCfg = Debug|x64
+		{A828FD72-44CE-4EA5-8966-6E4624458D58}.Release|Win32.ActiveCfg = Release|Win32
+		{A828FD72-44CE-4EA5-8966-6E4624458D58}.Release|x64.ActiveCfg = Release|x64
+		{A828FD72-44CE-4EA5-8966-6E4624458D58}.Debug|Win32.Build.0 = Debug|Win32
+		{A828FD72-44CE-4EA5-8966-6E4624458D58}.Debug|x64.Build.0 = Debug|x64
+		{A828FD72-44CE-4EA5-8966-6E4624458D58}.Release|Win32.Build.0 = Release|Win32
+		{A828FD72-44CE-4EA5-8966-6E4624458D58}.Release|x64.Build.0 = Release|x64
+		{AAC6AF12-94C8-4A3C-A1BF-DAA4738F4500}.Debug|Win32.ActiveCfg = Debug|Win32
+		{AAC6AF12-94C8-4A3C-A1BF-DAA4738F4500}.Debug|x64.ActiveCfg = Debug|x64
+		{AAC6AF12-94C8-4A3C-A1BF-DAA4738F4500}.Release|Win32.ActiveCfg = Release|Win32
+		{AAC6AF12-94C8-4A3C-A1BF-DAA4738F4500}.Release|x64.ActiveCfg = Release|x64
+		{AAC6AF12-94C8-4A3C-A1BF-DAA4738F4500}.Debug|Win32.Build.0 = Debug|Win32
+		{AAC6AF12-94C8-4A3C-A1BF-DAA4738F4500}.Debug|x64.Build.0 = Debug|x64
+		{AAC6AF12-94C8-4A3C-A1BF-DAA4738F4500}.Release|Win32.Build.0 = Release|Win32
+		{AAC6AF12-94C8-4A3C-A1BF-DAA4738F4500}.Release|x64.Build.0 = Release|x64
 		{B6E81D84-2ACB-41B8-8781-493A944C7817}.Debug|Win32.ActiveCfg = Debug|Win32
 		{B6E81D84-2ACB-41B8-8781-493A944C7817}.Debug|x64.ActiveCfg = Debug|x64
 		{B6E81D84-2ACB-41B8-8781-493A944C7817}.Release|Win32.ActiveCfg = Release|Win32
diff --git a/vsprojects/vcxproj/gpr/gpr.vcxproj b/vsprojects/vcxproj/gpr/gpr.vcxproj
index dae8e62..9281fa3 100644
--- a/vsprojects/vcxproj/gpr/gpr.vcxproj
+++ b/vsprojects/vcxproj/gpr/gpr.vcxproj
@@ -192,6 +192,7 @@
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="$(SolutionDir)\..\src\core\profiling\timers.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\support\backoff.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\support\block_annotate.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\support\env.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\support\load_file.h" />
@@ -212,6 +213,8 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\support\avl.c">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\support\backoff.c">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\support\cmdline.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\support\cpu_iphone.c">
diff --git a/vsprojects/vcxproj/gpr/gpr.vcxproj.filters b/vsprojects/vcxproj/gpr/gpr.vcxproj.filters
index 055b29f..b85060f 100644
--- a/vsprojects/vcxproj/gpr/gpr.vcxproj.filters
+++ b/vsprojects/vcxproj/gpr/gpr.vcxproj.filters
@@ -13,6 +13,9 @@
     <ClCompile Include="$(SolutionDir)\..\src\core\support\avl.c">
       <Filter>src\core\support</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\support\backoff.c">
+      <Filter>src\core\support</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\support\cmdline.c">
       <Filter>src\core\support</Filter>
     </ClCompile>
@@ -263,6 +266,9 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\profiling\timers.h">
       <Filter>src\core\profiling</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\support\backoff.h">
+      <Filter>src\core\support</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\support\block_annotate.h">
       <Filter>src\core\support</Filter>
     </ClInclude>
diff --git a/vsprojects/vcxproj/grpc++/grpc++.vcxproj b/vsprojects/vcxproj/grpc++/grpc++.vcxproj
index 0b8c345..d29e689 100644
--- a/vsprojects/vcxproj/grpc++/grpc++.vcxproj
+++ b/vsprojects/vcxproj/grpc++/grpc++.vcxproj
@@ -313,6 +313,7 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\completion_queue_tag.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\config.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\config_protobuf.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\core_codegen_interface.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\grpc_library.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\method_handler_impl.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\proto_utils.h" />
@@ -335,9 +336,11 @@
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="$(SolutionDir)\..\src\cpp\client\secure_credentials.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\cpp\common\core_codegen.h" />
     <ClInclude Include="$(SolutionDir)\..\src\cpp\common\secure_auth_context.h" />
     <ClInclude Include="$(SolutionDir)\..\src\cpp\server\secure_server_credentials.h" />
     <ClInclude Include="$(SolutionDir)\..\src\cpp\client\create_channel_internal.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\cpp\common\core_codegen.h" />
     <ClInclude Include="$(SolutionDir)\..\src\cpp\common\create_auth_context.h" />
     <ClInclude Include="$(SolutionDir)\..\src\cpp\server\dynamic_thread_pool.h" />
     <ClInclude Include="$(SolutionDir)\..\src\cpp\server\thread_pool_interface.h" />
@@ -369,15 +372,13 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\client\insecure_credentials.cc">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\cpp\common\call.cc">
-    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\common\channel_arguments.cc">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\common\completion_queue.cc">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\cpp\common\rpc_method.cc">
+    <ClCompile Include="$(SolutionDir)\..\src\cpp\common\core_codegen.cc">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\cpp\proto\proto_utils.cc">
+    <ClCompile Include="$(SolutionDir)\..\src\cpp\common\rpc_method.cc">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\server\async_generic_service.cc">
     </ClCompile>
@@ -405,7 +406,7 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\util\time.cc">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\cpp\codegen\grpc_library.cc">
+    <ClCompile Include="$(SolutionDir)\..\src\cpp\codegen\codegen_init.cc">
     </ClCompile>
   </ItemGroup>
   <ItemGroup>
diff --git a/vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters b/vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters
index 0f3dccf..c9b3bb9 100644
--- a/vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters
@@ -40,20 +40,17 @@
     <ClCompile Include="$(SolutionDir)\..\src\cpp\client\insecure_credentials.cc">
       <Filter>src\cpp\client</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\cpp\common\call.cc">
-      <Filter>src\cpp\common</Filter>
-    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\common\channel_arguments.cc">
       <Filter>src\cpp\common</Filter>
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\common\completion_queue.cc">
       <Filter>src\cpp\common</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\cpp\common\rpc_method.cc">
+    <ClCompile Include="$(SolutionDir)\..\src\cpp\common\core_codegen.cc">
       <Filter>src\cpp\common</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\cpp\proto\proto_utils.cc">
-      <Filter>src\cpp\proto</Filter>
+    <ClCompile Include="$(SolutionDir)\..\src\cpp\common\rpc_method.cc">
+      <Filter>src\cpp\common</Filter>
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\server\async_generic_service.cc">
       <Filter>src\cpp\server</Filter>
@@ -94,7 +91,7 @@
     <ClCompile Include="$(SolutionDir)\..\src\cpp\util\time.cc">
       <Filter>src\cpp\util</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\cpp\codegen\grpc_library.cc">
+    <ClCompile Include="$(SolutionDir)\..\src\cpp\codegen\codegen_init.cc">
       <Filter>src\cpp\codegen</Filter>
     </ClCompile>
   </ItemGroup>
@@ -264,6 +261,9 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\config_protobuf.h">
       <Filter>include\grpc++\impl\codegen</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\core_codegen_interface.h">
+      <Filter>include\grpc++\impl\codegen</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\grpc_library.h">
       <Filter>include\grpc++\impl\codegen</Filter>
     </ClInclude>
@@ -326,6 +326,9 @@
     <ClInclude Include="$(SolutionDir)\..\src\cpp\client\secure_credentials.h">
       <Filter>src\cpp\client</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\cpp\common\core_codegen.h">
+      <Filter>src\cpp\common</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\cpp\common\secure_auth_context.h">
       <Filter>src\cpp\common</Filter>
     </ClInclude>
@@ -335,6 +338,9 @@
     <ClInclude Include="$(SolutionDir)\..\src\cpp\client\create_channel_internal.h">
       <Filter>src\cpp\client</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\cpp\common\core_codegen.h">
+      <Filter>src\cpp\common</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\cpp\common\create_auth_context.h">
       <Filter>src\cpp\common</Filter>
     </ClInclude>
@@ -386,9 +392,6 @@
     <Filter Include="src\cpp\common">
       <UniqueIdentifier>{2336e396-7e0b-8bf9-3b09-adc6ad1f0e5b}</UniqueIdentifier>
     </Filter>
-    <Filter Include="src\cpp\proto">
-      <UniqueIdentifier>{c22e8b9b-d2eb-a2e8-0cb8-3f7e3c902a7b}</UniqueIdentifier>
-    </Filter>
     <Filter Include="src\cpp\server">
       <UniqueIdentifier>{321b0980-74ad-e8ca-f23b-deffa5d6bb8f}</UniqueIdentifier>
     </Filter>
diff --git a/vsprojects/vcxproj/test/end2end/end2end_certs/end2end_certs.vcxproj b/vsprojects/vcxproj/grpc++_codegen_lib/grpc++_codegen_lib.vcxproj
similarity index 61%
copy from vsprojects/vcxproj/test/end2end/end2end_certs/end2end_certs.vcxproj
copy to vsprojects/vcxproj/grpc++_codegen_lib/grpc++_codegen_lib.vcxproj
index 85502ba..de2526b 100644
--- a/vsprojects/vcxproj/test/end2end/end2end_certs/end2end_certs.vcxproj
+++ b/vsprojects/vcxproj/grpc++_codegen_lib/grpc++_codegen_lib.vcxproj
@@ -19,7 +19,7 @@
     </ProjectConfiguration>
   </ItemGroup>
   <PropertyGroup Label="Globals">
-    <ProjectGuid>{80EA2691-C037-6DD3-D3AB-21510BF0E64B}</ProjectGuid>
+    <ProjectGuid>{AAC6AF12-94C8-4A3C-A1BF-DAA4738F4500}</ProjectGuid>
     <IgnoreWarnIntDirInTempDetected>true</IgnoreWarnIntDirInTempDetected>
     <IntDir>$(SolutionDir)IntDir\$(MSBuildProjectName)\</IntDir>
   </PropertyGroup>
@@ -57,10 +57,10 @@
   </ImportGroup>
   <PropertyGroup Label="UserMacros" />
   <PropertyGroup Condition="'$(Configuration)'=='Debug'">
-    <TargetName>end2end_certs</TargetName>
+    <TargetName>grpc++_codegen_lib</TargetName>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)'=='Release'">
-    <TargetName>end2end_certs</TargetName>
+    <TargetName>grpc++_codegen_lib</TargetName>
   </PropertyGroup>
     <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <ClCompile>
@@ -147,11 +147,60 @@
   </ItemDefinitionGroup>
 
   <ItemGroup>
-    <ClCompile Include="$(SolutionDir)\..\test\core\end2end\data\test_root_cert.c">
-    </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\test\core\end2end\data\server1_cert.c">
-    </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\test\core\end2end\data\server1_key.c">
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\alloc.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_atomic.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_sync.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_win32.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\log.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\port_platform.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\slice.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\slice_buffer.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_generic.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_posix.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_win32.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\time.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\byte_buffer.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\compression_types.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\connectivity_state.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\grpc_types.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\propagation_bits.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\status.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\async_stream.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\async_unary_call.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\call.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\call_hook.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\channel_interface.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\client_context.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\client_unary_call.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\completion_queue.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\completion_queue_tag.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\config.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\config_protobuf.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\core_codegen_interface.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\grpc_library.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\method_handler_impl.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\proto_utils.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\rpc_method.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\rpc_service_method.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\security\auth_context.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\serialization_traits.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\server_context.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\server_interface.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\service_type.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\status.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\status_code_enum.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\string_ref.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\stub_options.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\sync.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\sync_cxx11.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\sync_no_cxx11.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\sync_stream.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\time.h" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="$(SolutionDir)\..\src\cpp\codegen\codegen_init.cc">
     </ClCompile>
   </ItemGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
diff --git a/vsprojects/vcxproj/grpc++_codegen_lib/grpc++_codegen_lib.vcxproj.filters b/vsprojects/vcxproj/grpc++_codegen_lib/grpc++_codegen_lib.vcxproj.filters
new file mode 100644
index 0000000..3cc0082
--- /dev/null
+++ b/vsprojects/vcxproj/grpc++_codegen_lib/grpc++_codegen_lib.vcxproj.filters
@@ -0,0 +1,200 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <ClCompile Include="$(SolutionDir)\..\src\cpp\codegen\codegen_init.cc">
+      <Filter>src\cpp\codegen</Filter>
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\alloc.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_atomic.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_sync.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_win32.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\log.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\port_platform.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\slice.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\slice_buffer.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_generic.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_posix.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_win32.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\time.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\byte_buffer.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\compression_types.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\connectivity_state.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\grpc_types.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\propagation_bits.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\status.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\async_stream.h">
+      <Filter>include\grpc++\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\async_unary_call.h">
+      <Filter>include\grpc++\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\call.h">
+      <Filter>include\grpc++\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\call_hook.h">
+      <Filter>include\grpc++\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\channel_interface.h">
+      <Filter>include\grpc++\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\client_context.h">
+      <Filter>include\grpc++\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\client_unary_call.h">
+      <Filter>include\grpc++\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\completion_queue.h">
+      <Filter>include\grpc++\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\completion_queue_tag.h">
+      <Filter>include\grpc++\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\config.h">
+      <Filter>include\grpc++\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\config_protobuf.h">
+      <Filter>include\grpc++\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\core_codegen_interface.h">
+      <Filter>include\grpc++\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\grpc_library.h">
+      <Filter>include\grpc++\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\method_handler_impl.h">
+      <Filter>include\grpc++\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\proto_utils.h">
+      <Filter>include\grpc++\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\rpc_method.h">
+      <Filter>include\grpc++\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\rpc_service_method.h">
+      <Filter>include\grpc++\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\security\auth_context.h">
+      <Filter>include\grpc++\impl\codegen\security</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\serialization_traits.h">
+      <Filter>include\grpc++\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\server_context.h">
+      <Filter>include\grpc++\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\server_interface.h">
+      <Filter>include\grpc++\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\service_type.h">
+      <Filter>include\grpc++\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\status.h">
+      <Filter>include\grpc++\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\status_code_enum.h">
+      <Filter>include\grpc++\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\string_ref.h">
+      <Filter>include\grpc++\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\stub_options.h">
+      <Filter>include\grpc++\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\sync.h">
+      <Filter>include\grpc++\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\sync_cxx11.h">
+      <Filter>include\grpc++\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\sync_no_cxx11.h">
+      <Filter>include\grpc++\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\sync_stream.h">
+      <Filter>include\grpc++\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\time.h">
+      <Filter>include\grpc++\impl\codegen</Filter>
+    </ClInclude>
+  </ItemGroup>
+
+  <ItemGroup>
+    <Filter Include="include">
+      <UniqueIdentifier>{cf409044-341b-37b5-03f3-0b09c3c474c4}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="include\grpc">
+      <UniqueIdentifier>{cddccffd-da89-18ad-da57-0c9d704a4633}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="include\grpc++">
+      <UniqueIdentifier>{cb8cb5ad-cf23-a491-046c-1c0688be53ac}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="include\grpc++\impl">
+      <UniqueIdentifier>{a734ff7f-2489-0c04-3fc6-35e361240cf1}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="include\grpc++\impl\codegen">
+      <UniqueIdentifier>{ffc473f2-ece4-fedf-238f-f161e5c3d5e7}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="include\grpc++\impl\codegen\security">
+      <UniqueIdentifier>{89065a9e-e4a0-e5e4-32e9-51cd4cadab46}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="include\grpc\impl">
+      <UniqueIdentifier>{45ab28cb-74e7-1a53-77c1-bbf2ec383fa2}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="include\grpc\impl\codegen">
+      <UniqueIdentifier>{311586c5-1a08-e1ba-8dd8-d1cbe10156b3}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src">
+      <UniqueIdentifier>{e9bdb195-1cf9-a0f4-231c-fcee59eb54ca}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\cpp">
+      <UniqueIdentifier>{d2e57ea3-c758-0f7c-3bc9-e71dd87bd654}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\cpp\codegen">
+      <UniqueIdentifier>{f93ade18-7c50-7ed9-b8e7-383b11f077c2}</UniqueIdentifier>
+    </Filter>
+  </ItemGroup>
+</Project>
+
diff --git a/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj b/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj
index 2dcadba..3d1aee0 100644
--- a/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj
+++ b/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj
@@ -313,6 +313,7 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\completion_queue_tag.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\config.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\config_protobuf.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\core_codegen_interface.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\grpc_library.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\method_handler_impl.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\proto_utils.h" />
@@ -335,6 +336,7 @@
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="$(SolutionDir)\..\src\cpp\client\create_channel_internal.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\cpp\common\core_codegen.h" />
     <ClInclude Include="$(SolutionDir)\..\src\cpp\common\create_auth_context.h" />
     <ClInclude Include="$(SolutionDir)\..\src\cpp\server\dynamic_thread_pool.h" />
     <ClInclude Include="$(SolutionDir)\..\src\cpp\server\thread_pool_interface.h" />
@@ -356,15 +358,13 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\client\insecure_credentials.cc">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\cpp\common\call.cc">
-    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\common\channel_arguments.cc">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\common\completion_queue.cc">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\cpp\common\rpc_method.cc">
+    <ClCompile Include="$(SolutionDir)\..\src\cpp\common\core_codegen.cc">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\cpp\proto\proto_utils.cc">
+    <ClCompile Include="$(SolutionDir)\..\src\cpp\common\rpc_method.cc">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\server\async_generic_service.cc">
     </ClCompile>
@@ -392,7 +392,7 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\util\time.cc">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\cpp\codegen\grpc_library.cc">
+    <ClCompile Include="$(SolutionDir)\..\src\cpp\codegen\codegen_init.cc">
     </ClCompile>
   </ItemGroup>
   <ItemGroup>
diff --git a/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters b/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters
index 3572c65..70a23bf 100644
--- a/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters
@@ -25,20 +25,17 @@
     <ClCompile Include="$(SolutionDir)\..\src\cpp\client\insecure_credentials.cc">
       <Filter>src\cpp\client</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\cpp\common\call.cc">
-      <Filter>src\cpp\common</Filter>
-    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\common\channel_arguments.cc">
       <Filter>src\cpp\common</Filter>
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\common\completion_queue.cc">
       <Filter>src\cpp\common</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\cpp\common\rpc_method.cc">
+    <ClCompile Include="$(SolutionDir)\..\src\cpp\common\core_codegen.cc">
       <Filter>src\cpp\common</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\cpp\proto\proto_utils.cc">
-      <Filter>src\cpp\proto</Filter>
+    <ClCompile Include="$(SolutionDir)\..\src\cpp\common\rpc_method.cc">
+      <Filter>src\cpp\common</Filter>
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\server\async_generic_service.cc">
       <Filter>src\cpp\server</Filter>
@@ -79,7 +76,7 @@
     <ClCompile Include="$(SolutionDir)\..\src\cpp\util\time.cc">
       <Filter>src\cpp\util</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\cpp\codegen\grpc_library.cc">
+    <ClCompile Include="$(SolutionDir)\..\src\cpp\codegen\codegen_init.cc">
       <Filter>src\cpp\codegen</Filter>
     </ClCompile>
   </ItemGroup>
@@ -249,6 +246,9 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\config_protobuf.h">
       <Filter>include\grpc++\impl\codegen</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\core_codegen_interface.h">
+      <Filter>include\grpc++\impl\codegen</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\grpc_library.h">
       <Filter>include\grpc++\impl\codegen</Filter>
     </ClInclude>
@@ -311,6 +311,9 @@
     <ClInclude Include="$(SolutionDir)\..\src\cpp\client\create_channel_internal.h">
       <Filter>src\cpp\client</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\cpp\common\core_codegen.h">
+      <Filter>src\cpp\common</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\cpp\common\create_auth_context.h">
       <Filter>src\cpp\common</Filter>
     </ClInclude>
@@ -362,9 +365,6 @@
     <Filter Include="src\cpp\common">
       <UniqueIdentifier>{ed8e4daa-825f-fbe5-2a45-846ad9165d3d}</UniqueIdentifier>
     </Filter>
-    <Filter Include="src\cpp\proto">
-      <UniqueIdentifier>{10b51a99-2e57-249e-ce23-3ab8c6b99ffb}</UniqueIdentifier>
-    </Filter>
     <Filter Include="src\cpp\server">
       <UniqueIdentifier>{8a54a279-d14b-4237-0df3-1ffe1ef5a7af}</UniqueIdentifier>
     </Filter>
diff --git a/vsprojects/vcxproj/grpc/grpc.vcxproj b/vsprojects/vcxproj/grpc/grpc.vcxproj
index c2635c3..869acb4 100644
--- a/vsprojects/vcxproj/grpc/grpc.vcxproj
+++ b/vsprojects/vcxproj/grpc/grpc.vcxproj
@@ -268,23 +268,25 @@
 
   <ItemGroup>
     <ClInclude Include="$(SolutionDir)\..\include\grpc\grpc_security.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\byte_buffer.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\byte_buffer_reader.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\compression.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\grpc.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\status.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\byte_buffer.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\compression_types.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\connectivity_state.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\grpc_types.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\propagation_bits.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\status.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\byte_buffer.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\byte_buffer_reader.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\compression.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\grpc.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\status.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\census.h" />
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="$(SolutionDir)\..\src\core\census\grpc_filter.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\census\grpc_plugin.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\channel\channel_args.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\channel\channel_stack.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\channel\channel_stack_builder.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\channel\client_channel.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\channel\client_uchannel.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\channel\compress_filter.h" />
@@ -364,9 +366,12 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\surface\call.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\surface\call_test_only.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\surface\channel.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\surface\channel_init.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\surface\channel_stack_type.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\surface\completion_queue.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\surface\event_string.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\surface\init.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\surface\lame_client.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\surface\server.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\surface\surface_trace.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\transport\byte_stream.h" />
@@ -424,10 +429,14 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\census\grpc_filter.c">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\census\grpc_plugin.c">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\channel\channel_args.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\channel\channel_stack.c">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\channel\channel_stack_builder.c">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\channel\client_channel.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\channel\client_uchannel.c">
@@ -602,8 +611,12 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\surface\channel_create.c">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\surface\channel_init.c">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\surface\channel_ping.c">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\surface\channel_stack_type.c">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\surface\completion_queue.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\surface\event_string.c">
@@ -618,8 +631,6 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\surface\server_chttp2.c">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\surface\server_create.c">
-    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\surface\validate_metadata.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\surface\version.c">
diff --git a/vsprojects/vcxproj/grpc/grpc.vcxproj.filters b/vsprojects/vcxproj/grpc/grpc.vcxproj.filters
index 6dd10d3..44cf627 100644
--- a/vsprojects/vcxproj/grpc/grpc.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc/grpc.vcxproj.filters
@@ -7,12 +7,18 @@
     <ClCompile Include="$(SolutionDir)\..\src\core\census\grpc_filter.c">
       <Filter>src\core\census</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\census\grpc_plugin.c">
+      <Filter>src\core\census</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\channel\channel_args.c">
       <Filter>src\core\channel</Filter>
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\channel\channel_stack.c">
       <Filter>src\core\channel</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\channel\channel_stack_builder.c">
+      <Filter>src\core\channel</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\channel\client_channel.c">
       <Filter>src\core\channel</Filter>
     </ClCompile>
@@ -274,9 +280,15 @@
     <ClCompile Include="$(SolutionDir)\..\src\core\surface\channel_create.c">
       <Filter>src\core\surface</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\surface\channel_init.c">
+      <Filter>src\core\surface</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\surface\channel_ping.c">
       <Filter>src\core\surface</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\surface\channel_stack_type.c">
+      <Filter>src\core\surface</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\surface\completion_queue.c">
       <Filter>src\core\surface</Filter>
     </ClCompile>
@@ -298,9 +310,6 @@
     <ClCompile Include="$(SolutionDir)\..\src\core\surface\server_chttp2.c">
       <Filter>src\core\surface</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\surface\server_create.c">
-      <Filter>src\core\surface</Filter>
-    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\surface\validate_metadata.c">
       <Filter>src\core\surface</Filter>
     </ClCompile>
@@ -486,6 +495,21 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\grpc_security.h">
       <Filter>include\grpc</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\byte_buffer.h">
+      <Filter>include\grpc</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\byte_buffer_reader.h">
+      <Filter>include\grpc</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\compression.h">
+      <Filter>include\grpc</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\grpc.h">
+      <Filter>include\grpc</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\status.h">
+      <Filter>include\grpc</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\byte_buffer.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
@@ -504,21 +528,6 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\status.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\byte_buffer.h">
-      <Filter>include\grpc</Filter>
-    </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\byte_buffer_reader.h">
-      <Filter>include\grpc</Filter>
-    </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\compression.h">
-      <Filter>include\grpc</Filter>
-    </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\grpc.h">
-      <Filter>include\grpc</Filter>
-    </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\status.h">
-      <Filter>include\grpc</Filter>
-    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\include\grpc\census.h">
       <Filter>include\grpc</Filter>
     </ClInclude>
@@ -527,12 +536,18 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\census\grpc_filter.h">
       <Filter>src\core\census</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\census\grpc_plugin.h">
+      <Filter>src\core\census</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\channel\channel_args.h">
       <Filter>src\core\channel</Filter>
     </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\channel\channel_stack.h">
       <Filter>src\core\channel</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\channel\channel_stack_builder.h">
+      <Filter>src\core\channel</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\channel\client_channel.h">
       <Filter>src\core\channel</Filter>
     </ClInclude>
@@ -770,6 +785,12 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\surface\channel.h">
       <Filter>src\core\surface</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\surface\channel_init.h">
+      <Filter>src\core\surface</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\surface\channel_stack_type.h">
+      <Filter>src\core\surface</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\surface\completion_queue.h">
       <Filter>src\core\surface</Filter>
     </ClInclude>
@@ -779,6 +800,9 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\surface\init.h">
       <Filter>src\core\surface</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\surface\lame_client.h">
+      <Filter>src\core\surface</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\surface\server.h">
       <Filter>src\core\surface</Filter>
     </ClInclude>
diff --git a/vsprojects/vcxproj/test/end2end/end2end_certs/end2end_certs.vcxproj b/vsprojects/vcxproj/grpc_codegen_lib/grpc_codegen_lib.vcxproj
similarity index 79%
rename from vsprojects/vcxproj/test/end2end/end2end_certs/end2end_certs.vcxproj
rename to vsprojects/vcxproj/grpc_codegen_lib/grpc_codegen_lib.vcxproj
index 85502ba..a6a5a85 100644
--- a/vsprojects/vcxproj/test/end2end/end2end_certs/end2end_certs.vcxproj
+++ b/vsprojects/vcxproj/grpc_codegen_lib/grpc_codegen_lib.vcxproj
@@ -19,7 +19,7 @@
     </ProjectConfiguration>
   </ItemGroup>
   <PropertyGroup Label="Globals">
-    <ProjectGuid>{80EA2691-C037-6DD3-D3AB-21510BF0E64B}</ProjectGuid>
+    <ProjectGuid>{A828FD72-44CE-4EA5-8966-6E4624458D58}</ProjectGuid>
     <IgnoreWarnIntDirInTempDetected>true</IgnoreWarnIntDirInTempDetected>
     <IntDir>$(SolutionDir)IntDir\$(MSBuildProjectName)\</IntDir>
   </PropertyGroup>
@@ -57,10 +57,10 @@
   </ImportGroup>
   <PropertyGroup Label="UserMacros" />
   <PropertyGroup Condition="'$(Configuration)'=='Debug'">
-    <TargetName>end2end_certs</TargetName>
+    <TargetName>grpc_codegen_lib</TargetName>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)'=='Release'">
-    <TargetName>end2end_certs</TargetName>
+    <TargetName>grpc_codegen_lib</TargetName>
   </PropertyGroup>
     <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
     <ClCompile>
@@ -147,11 +147,29 @@
   </ItemDefinitionGroup>
 
   <ItemGroup>
-    <ClCompile Include="$(SolutionDir)\..\test\core\end2end\data\test_root_cert.c">
-    </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\test\core\end2end\data\server1_cert.c">
-    </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\test\core\end2end\data\server1_key.c">
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\alloc.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_atomic.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_sync.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_win32.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\log.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\port_platform.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\slice.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\slice_buffer.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_generic.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_posix.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_win32.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\time.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\byte_buffer.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\compression_types.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\connectivity_state.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\grpc_types.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\propagation_bits.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\status.h" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="$(SolutionDir)\..\vsprojects\dummy.c">
     </ClCompile>
   </ItemGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
diff --git a/vsprojects/vcxproj/grpc_codegen_lib/grpc_codegen_lib.vcxproj.filters b/vsprojects/vcxproj/grpc_codegen_lib/grpc_codegen_lib.vcxproj.filters
new file mode 100644
index 0000000..be1e623
--- /dev/null
+++ b/vsprojects/vcxproj/grpc_codegen_lib/grpc_codegen_lib.vcxproj.filters
@@ -0,0 +1,81 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\alloc.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_atomic.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_sync.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_win32.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\log.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\port_platform.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\slice.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\slice_buffer.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_generic.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_posix.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_win32.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\time.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\byte_buffer.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\compression_types.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\connectivity_state.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\grpc_types.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\propagation_bits.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\status.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
+  </ItemGroup>
+
+  <ItemGroup>
+    <Filter Include="include">
+      <UniqueIdentifier>{1fe03afe-0c52-a706-2c50-4ea691805d81}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="include\grpc">
+      <UniqueIdentifier>{386f8a29-15ac-1f26-30ee-d9a605a802be}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="include\grpc\impl">
+      <UniqueIdentifier>{9828c5d3-4dc2-f116-97bf-015089243c94}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="include\grpc\impl\codegen">
+      <UniqueIdentifier>{0e88ed03-ed1e-49c0-15d7-69934b433494}</UniqueIdentifier>
+    </Filter>
+  </ItemGroup>
+</Project>
+
diff --git a/vsprojects/vcxproj/grpc_plugin_support/grpc_plugin_support.vcxproj b/vsprojects/vcxproj/grpc_plugin_support/grpc_plugin_support.vcxproj
index a76c883..058ae4f 100644
--- a/vsprojects/vcxproj/grpc_plugin_support/grpc_plugin_support.vcxproj
+++ b/vsprojects/vcxproj/grpc_plugin_support/grpc_plugin_support.vcxproj
@@ -148,42 +148,6 @@
   </ItemDefinitionGroup>
 
   <ItemGroup>
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\async_stream.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\async_unary_call.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\call.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\call_hook.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\channel_interface.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\client_context.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\client_unary_call.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\completion_queue.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\completion_queue_tag.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\config.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\config_protobuf.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\grpc_library.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\method_handler_impl.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\proto_utils.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\rpc_method.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\rpc_service_method.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\security\auth_context.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\serialization_traits.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\server_context.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\server_interface.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\service_type.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\status.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\status_code_enum.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\string_ref.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\stub_options.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\sync.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\sync_cxx11.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\sync_no_cxx11.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\sync_stream.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\time.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\byte_buffer.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\compression_types.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\connectivity_state.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\grpc_types.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\propagation_bits.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\status.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\alloc.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_atomic.h" />
@@ -227,8 +191,11 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\compiler\ruby_generator.cc">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\cpp\codegen\grpc_library.cc">
-    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc++_codegen_lib\grpc++_codegen_lib.vcxproj">
+      <Project>{AAC6AF12-94C8-4A3C-A1BF-DAA4738F4500}</Project>
+    </ProjectReference>
   </ItemGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">
diff --git a/vsprojects/vcxproj/grpc_plugin_support/grpc_plugin_support.vcxproj.filters b/vsprojects/vcxproj/grpc_plugin_support/grpc_plugin_support.vcxproj.filters
index de33d98..b1a63eb 100644
--- a/vsprojects/vcxproj/grpc_plugin_support/grpc_plugin_support.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc_plugin_support/grpc_plugin_support.vcxproj.filters
@@ -16,119 +16,8 @@
     <ClCompile Include="$(SolutionDir)\..\src\compiler\ruby_generator.cc">
       <Filter>src\compiler</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\cpp\codegen\grpc_library.cc">
-      <Filter>src\cpp\codegen</Filter>
-    </ClCompile>
   </ItemGroup>
   <ItemGroup>
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\async_stream.h">
-      <Filter>include\grpc++\impl\codegen</Filter>
-    </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\async_unary_call.h">
-      <Filter>include\grpc++\impl\codegen</Filter>
-    </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\call.h">
-      <Filter>include\grpc++\impl\codegen</Filter>
-    </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\call_hook.h">
-      <Filter>include\grpc++\impl\codegen</Filter>
-    </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\channel_interface.h">
-      <Filter>include\grpc++\impl\codegen</Filter>
-    </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\client_context.h">
-      <Filter>include\grpc++\impl\codegen</Filter>
-    </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\client_unary_call.h">
-      <Filter>include\grpc++\impl\codegen</Filter>
-    </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\completion_queue.h">
-      <Filter>include\grpc++\impl\codegen</Filter>
-    </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\completion_queue_tag.h">
-      <Filter>include\grpc++\impl\codegen</Filter>
-    </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\config.h">
-      <Filter>include\grpc++\impl\codegen</Filter>
-    </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\config_protobuf.h">
-      <Filter>include\grpc++\impl\codegen</Filter>
-    </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\grpc_library.h">
-      <Filter>include\grpc++\impl\codegen</Filter>
-    </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\method_handler_impl.h">
-      <Filter>include\grpc++\impl\codegen</Filter>
-    </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\proto_utils.h">
-      <Filter>include\grpc++\impl\codegen</Filter>
-    </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\rpc_method.h">
-      <Filter>include\grpc++\impl\codegen</Filter>
-    </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\rpc_service_method.h">
-      <Filter>include\grpc++\impl\codegen</Filter>
-    </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\security\auth_context.h">
-      <Filter>include\grpc++\impl\codegen\security</Filter>
-    </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\serialization_traits.h">
-      <Filter>include\grpc++\impl\codegen</Filter>
-    </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\server_context.h">
-      <Filter>include\grpc++\impl\codegen</Filter>
-    </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\server_interface.h">
-      <Filter>include\grpc++\impl\codegen</Filter>
-    </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\service_type.h">
-      <Filter>include\grpc++\impl\codegen</Filter>
-    </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\status.h">
-      <Filter>include\grpc++\impl\codegen</Filter>
-    </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\status_code_enum.h">
-      <Filter>include\grpc++\impl\codegen</Filter>
-    </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\string_ref.h">
-      <Filter>include\grpc++\impl\codegen</Filter>
-    </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\stub_options.h">
-      <Filter>include\grpc++\impl\codegen</Filter>
-    </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\sync.h">
-      <Filter>include\grpc++\impl\codegen</Filter>
-    </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\sync_cxx11.h">
-      <Filter>include\grpc++\impl\codegen</Filter>
-    </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\sync_no_cxx11.h">
-      <Filter>include\grpc++\impl\codegen</Filter>
-    </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\sync_stream.h">
-      <Filter>include\grpc++\impl\codegen</Filter>
-    </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\time.h">
-      <Filter>include\grpc++\impl\codegen</Filter>
-    </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\byte_buffer.h">
-      <Filter>include\grpc\impl\codegen</Filter>
-    </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\compression_types.h">
-      <Filter>include\grpc\impl\codegen</Filter>
-    </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\connectivity_state.h">
-      <Filter>include\grpc\impl\codegen</Filter>
-    </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\grpc_types.h">
-      <Filter>include\grpc\impl\codegen</Filter>
-    </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\propagation_bits.h">
-      <Filter>include\grpc\impl\codegen</Filter>
-    </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\status.h">
-      <Filter>include\grpc\impl\codegen</Filter>
-    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\alloc.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
@@ -230,15 +119,6 @@
     <Filter Include="include\grpc++">
       <UniqueIdentifier>{893c09ee-e315-e763-9d9d-37522ba2f51c}</UniqueIdentifier>
     </Filter>
-    <Filter Include="include\grpc++\impl">
-      <UniqueIdentifier>{3e8c71a4-8a06-a577-2799-2224a1ad1f1b}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="include\grpc++\impl\codegen">
-      <UniqueIdentifier>{ec2a6e26-915b-ba1b-4f59-f361dc01105c}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="include\grpc++\impl\codegen\security">
-      <UniqueIdentifier>{c1593bf9-5ef8-cb28-e46b-543153918a3f}</UniqueIdentifier>
-    </Filter>
     <Filter Include="include\grpc++\support">
       <UniqueIdentifier>{1c34d005-1ffb-8a31-881a-c6bb431cda69}</UniqueIdentifier>
     </Filter>
@@ -254,12 +134,6 @@
     <Filter Include="src\compiler">
       <UniqueIdentifier>{0e6b1e6c-7299-59ce-d757-619bcddd5441}</UniqueIdentifier>
     </Filter>
-    <Filter Include="src\cpp">
-      <UniqueIdentifier>{29d80aab-9e9d-0417-6dfa-59dec47c9883}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="src\cpp\codegen">
-      <UniqueIdentifier>{c0d4a389-f341-8385-4534-fe9d8fb09952}</UniqueIdentifier>
-    </Filter>
   </ItemGroup>
 </Project>
 
diff --git a/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj b/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj
index 5735327..487ffe0 100644
--- a/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj
+++ b/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj
@@ -155,6 +155,7 @@
     <ClInclude Include="$(SolutionDir)\..\test\core\util\grpc_profiler.h" />
     <ClInclude Include="$(SolutionDir)\..\test\core\util\parse_hexstring.h" />
     <ClInclude Include="$(SolutionDir)\..\test\core\util\port.h" />
+    <ClInclude Include="$(SolutionDir)\..\test\core\util\port_server_client.h" />
     <ClInclude Include="$(SolutionDir)\..\test\core\util\slice_splitter.h" />
   </ItemGroup>
   <ItemGroup>
@@ -178,6 +179,8 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\core\util\port_posix.c">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\test\core\util\port_server_client.c">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\core\util\port_windows.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\core\util\slice_splitter.c">
diff --git a/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj.filters b/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj.filters
index 47a689a..68c75e8 100644
--- a/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj.filters
@@ -31,6 +31,9 @@
     <ClCompile Include="$(SolutionDir)\..\test\core\util\port_posix.c">
       <Filter>test\core\util</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\test\core\util\port_server_client.c">
+      <Filter>test\core\util</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\core\util\port_windows.c">
       <Filter>test\core\util</Filter>
     </ClCompile>
@@ -63,6 +66,9 @@
     <ClInclude Include="$(SolutionDir)\..\test\core\util\port.h">
       <Filter>test\core\util</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\test\core\util\port_server_client.h">
+      <Filter>test\core\util</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\test\core\util\slice_splitter.h">
       <Filter>test\core\util</Filter>
     </ClInclude>
diff --git a/vsprojects/vcxproj/grpc_test_util_unsecure/grpc_test_util_unsecure.vcxproj b/vsprojects/vcxproj/grpc_test_util_unsecure/grpc_test_util_unsecure.vcxproj
index 6ff6ec9..2a3c50e 100644
--- a/vsprojects/vcxproj/grpc_test_util_unsecure/grpc_test_util_unsecure.vcxproj
+++ b/vsprojects/vcxproj/grpc_test_util_unsecure/grpc_test_util_unsecure.vcxproj
@@ -153,6 +153,7 @@
     <ClInclude Include="$(SolutionDir)\..\test\core\util\grpc_profiler.h" />
     <ClInclude Include="$(SolutionDir)\..\test\core\util\parse_hexstring.h" />
     <ClInclude Include="$(SolutionDir)\..\test\core\util\port.h" />
+    <ClInclude Include="$(SolutionDir)\..\test\core\util\port_server_client.h" />
     <ClInclude Include="$(SolutionDir)\..\test\core\util\slice_splitter.h" />
   </ItemGroup>
   <ItemGroup>
@@ -168,6 +169,8 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\core\util\port_posix.c">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\test\core\util\port_server_client.c">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\core\util\port_windows.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\core\util\slice_splitter.c">
diff --git a/vsprojects/vcxproj/grpc_test_util_unsecure/grpc_test_util_unsecure.vcxproj.filters b/vsprojects/vcxproj/grpc_test_util_unsecure/grpc_test_util_unsecure.vcxproj.filters
index 3b682ce..cdb19e1 100644
--- a/vsprojects/vcxproj/grpc_test_util_unsecure/grpc_test_util_unsecure.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc_test_util_unsecure/grpc_test_util_unsecure.vcxproj.filters
@@ -19,6 +19,9 @@
     <ClCompile Include="$(SolutionDir)\..\test\core\util\port_posix.c">
       <Filter>test\core\util</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\test\core\util\port_server_client.c">
+      <Filter>test\core\util</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\core\util\port_windows.c">
       <Filter>test\core\util</Filter>
     </ClCompile>
@@ -45,6 +48,9 @@
     <ClInclude Include="$(SolutionDir)\..\test\core\util\port.h">
       <Filter>test\core\util</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\test\core\util\port_server_client.h">
+      <Filter>test\core\util</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\test\core\util\slice_splitter.h">
       <Filter>test\core\util</Filter>
     </ClInclude>
diff --git a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj
index f0d869b..83a48c3 100644
--- a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj
+++ b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj
@@ -273,8 +273,10 @@
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="$(SolutionDir)\..\src\core\census\grpc_filter.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\census\grpc_plugin.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\channel\channel_args.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\channel\channel_stack.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\channel\channel_stack_builder.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\channel\client_channel.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\channel\client_uchannel.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\channel\compress_filter.h" />
@@ -354,9 +356,12 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\surface\call.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\surface\call_test_only.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\surface\channel.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\surface\channel_init.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\surface\channel_stack_type.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\surface\completion_queue.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\surface\event_string.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\surface\init.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\surface\lame_client.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\surface\server.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\surface\surface_trace.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\transport\byte_stream.h" />
@@ -402,10 +407,14 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\census\grpc_filter.c">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\census\grpc_plugin.c">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\channel\channel_args.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\channel\channel_stack.c">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\channel\channel_stack_builder.c">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\channel\client_channel.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\channel\client_uchannel.c">
@@ -580,8 +589,12 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\surface\channel_create.c">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\surface\channel_init.c">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\surface\channel_ping.c">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\surface\channel_stack_type.c">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\surface\completion_queue.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\surface\event_string.c">
@@ -596,8 +609,6 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\surface\server_chttp2.c">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\surface\server_create.c">
-    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\surface\validate_metadata.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\surface\version.c">
diff --git a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters
index 1f24021..7c14e8c 100644
--- a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters
@@ -10,12 +10,18 @@
     <ClCompile Include="$(SolutionDir)\..\src\core\census\grpc_filter.c">
       <Filter>src\core\census</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\census\grpc_plugin.c">
+      <Filter>src\core\census</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\channel\channel_args.c">
       <Filter>src\core\channel</Filter>
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\channel\channel_stack.c">
       <Filter>src\core\channel</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\channel\channel_stack_builder.c">
+      <Filter>src\core\channel</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\channel\client_channel.c">
       <Filter>src\core\channel</Filter>
     </ClCompile>
@@ -277,9 +283,15 @@
     <ClCompile Include="$(SolutionDir)\..\src\core\surface\channel_create.c">
       <Filter>src\core\surface</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\surface\channel_init.c">
+      <Filter>src\core\surface</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\surface\channel_ping.c">
       <Filter>src\core\surface</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\surface\channel_stack_type.c">
+      <Filter>src\core\surface</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\surface\completion_queue.c">
       <Filter>src\core\surface</Filter>
     </ClCompile>
@@ -301,9 +313,6 @@
     <ClCompile Include="$(SolutionDir)\..\src\core\surface\server_chttp2.c">
       <Filter>src\core\surface</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\surface\server_create.c">
-      <Filter>src\core\surface</Filter>
-    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\surface\validate_metadata.c">
       <Filter>src\core\surface</Filter>
     </ClCompile>
@@ -464,12 +473,18 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\census\grpc_filter.h">
       <Filter>src\core\census</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\census\grpc_plugin.h">
+      <Filter>src\core\census</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\channel\channel_args.h">
       <Filter>src\core\channel</Filter>
     </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\channel\channel_stack.h">
       <Filter>src\core\channel</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\channel\channel_stack_builder.h">
+      <Filter>src\core\channel</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\channel\client_channel.h">
       <Filter>src\core\channel</Filter>
     </ClInclude>
@@ -707,6 +722,12 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\surface\channel.h">
       <Filter>src\core\surface</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\surface\channel_init.h">
+      <Filter>src\core\surface</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\surface\channel_stack_type.h">
+      <Filter>src\core\surface</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\surface\completion_queue.h">
       <Filter>src\core\surface</Filter>
     </ClInclude>
@@ -716,6 +737,9 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\surface\init.h">
       <Filter>src\core\surface</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\surface\lame_client.h">
+      <Filter>src\core\surface</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\surface\server.h">
       <Filter>src\core\surface</Filter>
     </ClInclude>
diff --git a/vsprojects/vcxproj/test/codegen_test/codegen_test.vcxproj b/vsprojects/vcxproj/test/codegen_test/codegen_test.vcxproj
new file mode 100644
index 0000000..7ba2a56
--- /dev/null
+++ b/vsprojects/vcxproj/test/codegen_test/codegen_test.vcxproj
@@ -0,0 +1,240 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.props" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\1.0.204.1.props')" />
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{07D92FF8-D0D1-CB1B-51D3-EBA0E5DEBDD7}</ProjectGuid>
+    <IgnoreWarnIntDirInTempDetected>true</IgnoreWarnIntDirInTempDetected>
+    <IntDir>$(SolutionDir)IntDir\$(MSBuildProjectName)\</IntDir>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(VisualStudioVersion)' == '10.0'" Label="Configuration">
+    <PlatformToolset>v100</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(VisualStudioVersion)' == '11.0'" Label="Configuration">
+    <PlatformToolset>v110</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(VisualStudioVersion)' == '12.0'" Label="Configuration">
+    <PlatformToolset>v120</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(VisualStudioVersion)' == '14.0'" Label="Configuration">
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)'=='Debug'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)'=='Release'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="$(SolutionDir)\..\vsprojects\cpptest.props" />
+    <Import Project="$(SolutionDir)\..\vsprojects\global.props" />
+    <Import Project="$(SolutionDir)\..\vsprojects\openssl.props" />
+    <Import Project="$(SolutionDir)\..\vsprojects\protobuf.props" />
+    <Import Project="$(SolutionDir)\..\vsprojects\winsock.props" />
+    <Import Project="$(SolutionDir)\..\vsprojects\zlib.props" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup Condition="'$(Configuration)'=='Debug'">
+    <TargetName>codegen_test</TargetName>
+    <Linkage-grpc_dependencies_zlib>static</Linkage-grpc_dependencies_zlib>
+    <Configuration-grpc_dependencies_zlib>Debug</Configuration-grpc_dependencies_zlib>
+    <Linkage-grpc_dependencies_openssl>static</Linkage-grpc_dependencies_openssl>
+    <Configuration-grpc_dependencies_openssl>Debug</Configuration-grpc_dependencies_openssl>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)'=='Release'">
+    <TargetName>codegen_test</TargetName>
+    <Linkage-grpc_dependencies_zlib>static</Linkage-grpc_dependencies_zlib>
+    <Configuration-grpc_dependencies_zlib>Release</Configuration-grpc_dependencies_zlib>
+    <Linkage-grpc_dependencies_openssl>static</Linkage-grpc_dependencies_openssl>
+    <Configuration-grpc_dependencies_openssl>Release</Configuration-grpc_dependencies_openssl>
+  </PropertyGroup>
+    <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+      <MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
+      <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+
+    <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+      <MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
+      <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+
+    <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>MaxSpeed</Optimization>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <SDLCheck>true</SDLCheck>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+      <MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
+      <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+    </Link>
+  </ItemDefinitionGroup>
+
+    <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>MaxSpeed</Optimization>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <SDLCheck>true</SDLCheck>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+      <MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
+      <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+    </Link>
+  </ItemDefinitionGroup>
+
+  <ItemGroup>
+    <ClCompile Include="$(SolutionDir)\..\src\proto\grpc\testing\control.pb.cc">
+    </ClCompile>
+    <ClInclude Include="$(SolutionDir)\..\src\proto\grpc\testing\control.pb.h">
+    </ClInclude>
+    <ClCompile Include="$(SolutionDir)\..\src\proto\grpc\testing\control.grpc.pb.cc">
+    </ClCompile>
+    <ClInclude Include="$(SolutionDir)\..\src\proto\grpc\testing\control.grpc.pb.h">
+    </ClInclude>
+    <ClCompile Include="$(SolutionDir)\..\src\proto\grpc\testing\messages.pb.cc">
+    </ClCompile>
+    <ClInclude Include="$(SolutionDir)\..\src\proto\grpc\testing\messages.pb.h">
+    </ClInclude>
+    <ClCompile Include="$(SolutionDir)\..\src\proto\grpc\testing\messages.grpc.pb.cc">
+    </ClCompile>
+    <ClInclude Include="$(SolutionDir)\..\src\proto\grpc\testing\messages.grpc.pb.h">
+    </ClInclude>
+    <ClCompile Include="$(SolutionDir)\..\src\proto\grpc\testing\payloads.pb.cc">
+    </ClCompile>
+    <ClInclude Include="$(SolutionDir)\..\src\proto\grpc\testing\payloads.pb.h">
+    </ClInclude>
+    <ClCompile Include="$(SolutionDir)\..\src\proto\grpc\testing\payloads.grpc.pb.cc">
+    </ClCompile>
+    <ClInclude Include="$(SolutionDir)\..\src\proto\grpc\testing\payloads.grpc.pb.h">
+    </ClInclude>
+    <ClCompile Include="$(SolutionDir)\..\src\proto\grpc\testing\perf_db.pb.cc">
+    </ClCompile>
+    <ClInclude Include="$(SolutionDir)\..\src\proto\grpc\testing\perf_db.pb.h">
+    </ClInclude>
+    <ClCompile Include="$(SolutionDir)\..\src\proto\grpc\testing\perf_db.grpc.pb.cc">
+    </ClCompile>
+    <ClInclude Include="$(SolutionDir)\..\src\proto\grpc\testing\perf_db.grpc.pb.h">
+    </ClInclude>
+    <ClCompile Include="$(SolutionDir)\..\src\proto\grpc\testing\services.pb.cc">
+    </ClCompile>
+    <ClInclude Include="$(SolutionDir)\..\src\proto\grpc\testing\services.pb.h">
+    </ClInclude>
+    <ClCompile Include="$(SolutionDir)\..\src\proto\grpc\testing\services.grpc.pb.cc">
+    </ClCompile>
+    <ClInclude Include="$(SolutionDir)\..\src\proto\grpc\testing\services.grpc.pb.h">
+    </ClInclude>
+    <ClCompile Include="$(SolutionDir)\..\src\proto\grpc\testing\stats.pb.cc">
+    </ClCompile>
+    <ClInclude Include="$(SolutionDir)\..\src\proto\grpc\testing\stats.pb.h">
+    </ClInclude>
+    <ClCompile Include="$(SolutionDir)\..\src\proto\grpc\testing\stats.grpc.pb.cc">
+    </ClCompile>
+    <ClInclude Include="$(SolutionDir)\..\src\proto\grpc\testing\stats.grpc.pb.h">
+    </ClInclude>
+    <ClCompile Include="$(SolutionDir)\..\test\cpp\codegen\codegen_test.cc">
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc++_codegen_lib\grpc++_codegen_lib.vcxproj">
+      <Project>{AAC6AF12-94C8-4A3C-A1BF-DAA4738F4500}</Project>
+    </ProjectReference>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="packages.config" />
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  <Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\native\grpc.dependencies.zlib.redist.targets" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\native\grpc.dependencies\grpc.dependencies.zlib.targets')" />
+  <Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.10\build\native\grpc.dependencies.zlib.targets" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.10\build\native\grpc.dependencies\grpc.dependencies.zlib.targets')" />
+  <Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\native\grpc.dependencies.openssl.redist.targets" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\native\grpc.dependencies\grpc.dependencies.openssl.targets')" />
+  <Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.targets" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies\grpc.dependencies.openssl.targets')" />
+  </ImportGroup>
+  <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
+    <PropertyGroup>
+      <ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them.  For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
+    </PropertyGroup>
+    <Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\native\grpc.dependencies.zlib.redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\native\grpc.dependencies.zlib.redist.targets')" />
+    <Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.10\build\native\grpc.dependencies.zlib.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.10\build\native\grpc.dependencies.zlib.targets')" />
+    <Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\native\grpc.dependencies.openssl.redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\native\grpc.dependencies.openssl.redist.targets')" />
+    <Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.props')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.props')" />
+    <Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.targets')" />
+  </Target>
+</Project>
+
diff --git a/vsprojects/vcxproj/test/codegen_test/codegen_test.vcxproj.filters b/vsprojects/vcxproj/test/codegen_test/codegen_test.vcxproj.filters
new file mode 100644
index 0000000..980cf76
--- /dev/null
+++ b/vsprojects/vcxproj/test/codegen_test/codegen_test.vcxproj.filters
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <ClCompile Include="$(SolutionDir)\..\src\proto\grpc\testing\control.proto">
+      <Filter>src\proto\grpc\testing</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\proto\grpc\testing\messages.proto">
+      <Filter>src\proto\grpc\testing</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\proto\grpc\testing\payloads.proto">
+      <Filter>src\proto\grpc\testing</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\proto\grpc\testing\perf_db.proto">
+      <Filter>src\proto\grpc\testing</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\proto\grpc\testing\services.proto">
+      <Filter>src\proto\grpc\testing</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\proto\grpc\testing\stats.proto">
+      <Filter>src\proto\grpc\testing</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\test\cpp\codegen\codegen_test.cc">
+      <Filter>test\cpp\codegen</Filter>
+    </ClCompile>
+  </ItemGroup>
+
+  <ItemGroup>
+    <Filter Include="src">
+      <UniqueIdentifier>{a37f6960-8f92-51ed-9b99-d24970584bb2}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\proto">
+      <UniqueIdentifier>{dc3f4032-f0dc-f8f0-e07a-78c0f628e9f5}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\proto\grpc">
+      <UniqueIdentifier>{250aede7-067f-590b-42d7-15939da4a59d}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\proto\grpc\testing">
+      <UniqueIdentifier>{57f4543e-acd0-a4a0-f3c3-8494e509b2b3}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="test">
+      <UniqueIdentifier>{7337b395-7e96-f49b-0a4f-b8a70be23a57}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="test\cpp">
+      <UniqueIdentifier>{cf9e3404-0ab9-a301-9715-728febcece23}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="test\cpp\codegen">
+      <UniqueIdentifier>{d349ac75-02e7-cb63-92f1-1785a74c0561}</UniqueIdentifier>
+    </Filter>
+  </ItemGroup>
+</Project>
+
diff --git a/vsprojects/vcxproj/test/end2end/end2end_certs/end2end_certs.vcxproj.filters b/vsprojects/vcxproj/test/end2end/end2end_certs/end2end_certs.vcxproj.filters
deleted file mode 100644
index 62b14d1..0000000
--- a/vsprojects/vcxproj/test/end2end/end2end_certs/end2end_certs.vcxproj.filters
+++ /dev/null
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <ItemGroup>
-    <ClCompile Include="$(SolutionDir)\..\test\core\end2end\data\test_root_cert.c">
-      <Filter>test\core\end2end\data</Filter>
-    </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\test\core\end2end\data\server1_cert.c">
-      <Filter>test\core\end2end\data</Filter>
-    </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\test\core\end2end\data\server1_key.c">
-      <Filter>test\core\end2end\data</Filter>
-    </ClCompile>
-  </ItemGroup>
-
-  <ItemGroup>
-    <Filter Include="test">
-      <UniqueIdentifier>{c94707fc-9ae9-9cc3-8743-77776eb9d9cc}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="test\core">
-      <UniqueIdentifier>{f91d3831-d4bb-0981-77a4-16d8c5be07e9}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="test\core\end2end">
-      <UniqueIdentifier>{afbaeee0-7ab8-872c-8c47-3e3e5a8cc5e3}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="test\core\end2end\data">
-      <UniqueIdentifier>{5e4bc33c-7867-c329-d107-009b198f97dc}</UniqueIdentifier>
-    </Filter>
-  </ItemGroup>
-</Project>
-
diff --git a/vsprojects/vcxproj/test/end2end/fixtures/h2_census_test/h2_census_test.vcxproj b/vsprojects/vcxproj/test/end2end/fixtures/h2_census_test/h2_census_test.vcxproj
index 612b5df..2f63ad0 100644
--- a/vsprojects/vcxproj/test/end2end/fixtures/h2_census_test/h2_census_test.vcxproj
+++ b/vsprojects/vcxproj/test/end2end/fixtures/h2_census_test/h2_census_test.vcxproj
@@ -165,9 +165,6 @@
     <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\test/end2end/tests\end2end_tests\end2end_tests.vcxproj">
       <Project>{1F1F9084-2A93-B80E-364F-5754894AFAB4}</Project>
     </ProjectReference>
-    <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\test/end2end\end2end_certs\end2end_certs.vcxproj">
-      <Project>{80EA2691-C037-6DD3-D3AB-21510BF0E64B}</Project>
-    </ProjectReference>
     <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc_test_util\grpc_test_util.vcxproj">
       <Project>{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}</Project>
     </ProjectReference>
diff --git a/vsprojects/vcxproj/test/end2end/fixtures/h2_compress_test/h2_compress_test.vcxproj b/vsprojects/vcxproj/test/end2end/fixtures/h2_compress_test/h2_compress_test.vcxproj
index 4b6fbaa..c9efe0b 100644
--- a/vsprojects/vcxproj/test/end2end/fixtures/h2_compress_test/h2_compress_test.vcxproj
+++ b/vsprojects/vcxproj/test/end2end/fixtures/h2_compress_test/h2_compress_test.vcxproj
@@ -165,9 +165,6 @@
     <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\test/end2end/tests\end2end_tests\end2end_tests.vcxproj">
       <Project>{1F1F9084-2A93-B80E-364F-5754894AFAB4}</Project>
     </ProjectReference>
-    <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\test/end2end\end2end_certs\end2end_certs.vcxproj">
-      <Project>{80EA2691-C037-6DD3-D3AB-21510BF0E64B}</Project>
-    </ProjectReference>
     <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc_test_util\grpc_test_util.vcxproj">
       <Project>{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}</Project>
     </ProjectReference>
diff --git a/vsprojects/vcxproj/test/end2end/fixtures/h2_fakesec_test/h2_fakesec_test.vcxproj b/vsprojects/vcxproj/test/end2end/fixtures/h2_fakesec_test/h2_fakesec_test.vcxproj
index 3406fad..d84176e 100644
--- a/vsprojects/vcxproj/test/end2end/fixtures/h2_fakesec_test/h2_fakesec_test.vcxproj
+++ b/vsprojects/vcxproj/test/end2end/fixtures/h2_fakesec_test/h2_fakesec_test.vcxproj
@@ -165,9 +165,6 @@
     <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\test/end2end/tests\end2end_tests\end2end_tests.vcxproj">
       <Project>{1F1F9084-2A93-B80E-364F-5754894AFAB4}</Project>
     </ProjectReference>
-    <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\test/end2end\end2end_certs\end2end_certs.vcxproj">
-      <Project>{80EA2691-C037-6DD3-D3AB-21510BF0E64B}</Project>
-    </ProjectReference>
     <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc_test_util\grpc_test_util.vcxproj">
       <Project>{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}</Project>
     </ProjectReference>
diff --git a/vsprojects/vcxproj/test/end2end/fixtures/h2_full+trace_nosec_test/h2_full+trace_nosec_test.vcxproj b/vsprojects/vcxproj/test/end2end/fixtures/h2_full+trace_nosec_test/h2_full+trace_nosec_test.vcxproj
new file mode 100644
index 0000000..a59e082
--- /dev/null
+++ b/vsprojects/vcxproj/test/end2end/fixtures/h2_full+trace_nosec_test/h2_full+trace_nosec_test.vcxproj
@@ -0,0 +1,202 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.props" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\1.0.204.1.props')" />
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{DFD51943-4906-8051-7D66-6A7D50E0D87E}</ProjectGuid>
+    <IgnoreWarnIntDirInTempDetected>true</IgnoreWarnIntDirInTempDetected>
+    <IntDir>$(SolutionDir)IntDir\$(MSBuildProjectName)\</IntDir>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(VisualStudioVersion)' == '10.0'" Label="Configuration">
+    <PlatformToolset>v100</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(VisualStudioVersion)' == '11.0'" Label="Configuration">
+    <PlatformToolset>v110</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(VisualStudioVersion)' == '12.0'" Label="Configuration">
+    <PlatformToolset>v120</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(VisualStudioVersion)' == '14.0'" Label="Configuration">
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)'=='Debug'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)'=='Release'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="$(SolutionDir)\..\vsprojects\global.props" />
+    <Import Project="$(SolutionDir)\..\vsprojects\openssl.props" />
+    <Import Project="$(SolutionDir)\..\vsprojects\winsock.props" />
+    <Import Project="$(SolutionDir)\..\vsprojects\zlib.props" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup Condition="'$(Configuration)'=='Debug'">
+    <TargetName>h2_full+trace_nosec_test</TargetName>
+    <Linkage-grpc_dependencies_zlib>static</Linkage-grpc_dependencies_zlib>
+    <Configuration-grpc_dependencies_zlib>Debug</Configuration-grpc_dependencies_zlib>
+    <Linkage-grpc_dependencies_openssl>static</Linkage-grpc_dependencies_openssl>
+    <Configuration-grpc_dependencies_openssl>Debug</Configuration-grpc_dependencies_openssl>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)'=='Release'">
+    <TargetName>h2_full+trace_nosec_test</TargetName>
+    <Linkage-grpc_dependencies_zlib>static</Linkage-grpc_dependencies_zlib>
+    <Configuration-grpc_dependencies_zlib>Release</Configuration-grpc_dependencies_zlib>
+    <Linkage-grpc_dependencies_openssl>static</Linkage-grpc_dependencies_openssl>
+    <Configuration-grpc_dependencies_openssl>Release</Configuration-grpc_dependencies_openssl>
+  </PropertyGroup>
+    <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+      <MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
+      <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+
+    <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+      <MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
+      <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+
+    <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>MaxSpeed</Optimization>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <SDLCheck>true</SDLCheck>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+      <MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
+      <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+    </Link>
+  </ItemDefinitionGroup>
+
+    <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>MaxSpeed</Optimization>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <SDLCheck>true</SDLCheck>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+      <MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
+      <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+    </Link>
+  </ItemDefinitionGroup>
+
+  <ItemGroup>
+    <ClCompile Include="$(SolutionDir)\..\test\core\end2end\fixtures\h2_full+trace.c">
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\test/end2end/tests\end2end_nosec_tests\end2end_nosec_tests.vcxproj">
+      <Project>{47C2CB41-4E9F-58B6-F606-F6FAED5D00ED}</Project>
+    </ProjectReference>
+    <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc_test_util_unsecure\grpc_test_util_unsecure.vcxproj">
+      <Project>{0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF}</Project>
+    </ProjectReference>
+    <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc_unsecure\grpc_unsecure.vcxproj">
+      <Project>{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}</Project>
+    </ProjectReference>
+    <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\gpr_test_util\gpr_test_util.vcxproj">
+      <Project>{EAB0A629-17A9-44DB-B5FF-E91A721FE037}</Project>
+    </ProjectReference>
+    <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\gpr\gpr.vcxproj">
+      <Project>{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}</Project>
+    </ProjectReference>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="packages.config" />
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  <Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\native\grpc.dependencies.zlib.redist.targets" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\native\grpc.dependencies\grpc.dependencies.zlib.targets')" />
+  <Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.10\build\native\grpc.dependencies.zlib.targets" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.10\build\native\grpc.dependencies\grpc.dependencies.zlib.targets')" />
+  <Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\native\grpc.dependencies.openssl.redist.targets" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\native\grpc.dependencies\grpc.dependencies.openssl.targets')" />
+  <Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.targets" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies\grpc.dependencies.openssl.targets')" />
+  </ImportGroup>
+  <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
+    <PropertyGroup>
+      <ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them.  For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
+    </PropertyGroup>
+    <Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\native\grpc.dependencies.zlib.redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\native\grpc.dependencies.zlib.redist.targets')" />
+    <Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.10\build\native\grpc.dependencies.zlib.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.10\build\native\grpc.dependencies.zlib.targets')" />
+    <Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\native\grpc.dependencies.openssl.redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\native\grpc.dependencies.openssl.redist.targets')" />
+    <Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.props')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.props')" />
+    <Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.targets')" />
+  </Target>
+</Project>
+
diff --git a/vsprojects/vcxproj/test/end2end/fixtures/h2_full+trace_nosec_test/h2_full+trace_nosec_test.vcxproj.filters b/vsprojects/vcxproj/test/end2end/fixtures/h2_full+trace_nosec_test/h2_full+trace_nosec_test.vcxproj.filters
new file mode 100644
index 0000000..c9164af
--- /dev/null
+++ b/vsprojects/vcxproj/test/end2end/fixtures/h2_full+trace_nosec_test/h2_full+trace_nosec_test.vcxproj.filters
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <ClCompile Include="$(SolutionDir)\..\test\core\end2end\fixtures\h2_full+trace.c">
+      <Filter>test\core\end2end\fixtures</Filter>
+    </ClCompile>
+  </ItemGroup>
+
+  <ItemGroup>
+    <Filter Include="test">
+      <UniqueIdentifier>{2828a8fc-bcc1-7b1c-4953-0c8eaf9fe643}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="test\core">
+      <UniqueIdentifier>{d8e78fb2-4316-018b-704a-0944fd0c6fd9}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="test\core\end2end">
+      <UniqueIdentifier>{1981c949-24c5-413c-ab03-24eff55e803a}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="test\core\end2end\fixtures">
+      <UniqueIdentifier>{bfc11ba4-7401-55f0-8513-598aa93e7e1a}</UniqueIdentifier>
+    </Filter>
+  </ItemGroup>
+</Project>
+
diff --git a/vsprojects/vcxproj/test/end2end/fixtures/h2_full+trace_test/h2_full+trace_test.vcxproj b/vsprojects/vcxproj/test/end2end/fixtures/h2_full+trace_test/h2_full+trace_test.vcxproj
new file mode 100644
index 0000000..6ca9dfa
--- /dev/null
+++ b/vsprojects/vcxproj/test/end2end/fixtures/h2_full+trace_test/h2_full+trace_test.vcxproj
@@ -0,0 +1,202 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.props" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\1.0.204.1.props')" />
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{16C713C6-062E-F71F-A44C-52DC35494B27}</ProjectGuid>
+    <IgnoreWarnIntDirInTempDetected>true</IgnoreWarnIntDirInTempDetected>
+    <IntDir>$(SolutionDir)IntDir\$(MSBuildProjectName)\</IntDir>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(VisualStudioVersion)' == '10.0'" Label="Configuration">
+    <PlatformToolset>v100</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(VisualStudioVersion)' == '11.0'" Label="Configuration">
+    <PlatformToolset>v110</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(VisualStudioVersion)' == '12.0'" Label="Configuration">
+    <PlatformToolset>v120</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(VisualStudioVersion)' == '14.0'" Label="Configuration">
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)'=='Debug'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)'=='Release'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="$(SolutionDir)\..\vsprojects\global.props" />
+    <Import Project="$(SolutionDir)\..\vsprojects\openssl.props" />
+    <Import Project="$(SolutionDir)\..\vsprojects\winsock.props" />
+    <Import Project="$(SolutionDir)\..\vsprojects\zlib.props" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup Condition="'$(Configuration)'=='Debug'">
+    <TargetName>h2_full+trace_test</TargetName>
+    <Linkage-grpc_dependencies_zlib>static</Linkage-grpc_dependencies_zlib>
+    <Configuration-grpc_dependencies_zlib>Debug</Configuration-grpc_dependencies_zlib>
+    <Linkage-grpc_dependencies_openssl>static</Linkage-grpc_dependencies_openssl>
+    <Configuration-grpc_dependencies_openssl>Debug</Configuration-grpc_dependencies_openssl>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)'=='Release'">
+    <TargetName>h2_full+trace_test</TargetName>
+    <Linkage-grpc_dependencies_zlib>static</Linkage-grpc_dependencies_zlib>
+    <Configuration-grpc_dependencies_zlib>Release</Configuration-grpc_dependencies_zlib>
+    <Linkage-grpc_dependencies_openssl>static</Linkage-grpc_dependencies_openssl>
+    <Configuration-grpc_dependencies_openssl>Release</Configuration-grpc_dependencies_openssl>
+  </PropertyGroup>
+    <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+      <MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
+      <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+
+    <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+      <MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
+      <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+
+    <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>MaxSpeed</Optimization>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <SDLCheck>true</SDLCheck>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+      <MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
+      <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+    </Link>
+  </ItemDefinitionGroup>
+
+    <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>MaxSpeed</Optimization>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <SDLCheck>true</SDLCheck>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+      <MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
+      <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+    </Link>
+  </ItemDefinitionGroup>
+
+  <ItemGroup>
+    <ClCompile Include="$(SolutionDir)\..\test\core\end2end\fixtures\h2_full+trace.c">
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\test/end2end/tests\end2end_tests\end2end_tests.vcxproj">
+      <Project>{1F1F9084-2A93-B80E-364F-5754894AFAB4}</Project>
+    </ProjectReference>
+    <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc_test_util\grpc_test_util.vcxproj">
+      <Project>{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}</Project>
+    </ProjectReference>
+    <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc\grpc.vcxproj">
+      <Project>{29D16885-7228-4C31-81ED-5F9187C7F2A9}</Project>
+    </ProjectReference>
+    <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\gpr_test_util\gpr_test_util.vcxproj">
+      <Project>{EAB0A629-17A9-44DB-B5FF-E91A721FE037}</Project>
+    </ProjectReference>
+    <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\gpr\gpr.vcxproj">
+      <Project>{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}</Project>
+    </ProjectReference>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="packages.config" />
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  <Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\native\grpc.dependencies.zlib.redist.targets" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\native\grpc.dependencies\grpc.dependencies.zlib.targets')" />
+  <Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.10\build\native\grpc.dependencies.zlib.targets" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.10\build\native\grpc.dependencies\grpc.dependencies.zlib.targets')" />
+  <Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\native\grpc.dependencies.openssl.redist.targets" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\native\grpc.dependencies\grpc.dependencies.openssl.targets')" />
+  <Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.targets" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies\grpc.dependencies.openssl.targets')" />
+  </ImportGroup>
+  <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
+    <PropertyGroup>
+      <ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them.  For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
+    </PropertyGroup>
+    <Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\native\grpc.dependencies.zlib.redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\native\grpc.dependencies.zlib.redist.targets')" />
+    <Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.10\build\native\grpc.dependencies.zlib.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.10\build\native\grpc.dependencies.zlib.targets')" />
+    <Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\native\grpc.dependencies.openssl.redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\native\grpc.dependencies.openssl.redist.targets')" />
+    <Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.props')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.props')" />
+    <Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.targets')" />
+  </Target>
+</Project>
+
diff --git a/vsprojects/vcxproj/test/end2end/fixtures/h2_full+trace_test/h2_full+trace_test.vcxproj.filters b/vsprojects/vcxproj/test/end2end/fixtures/h2_full+trace_test/h2_full+trace_test.vcxproj.filters
new file mode 100644
index 0000000..87e8e72
--- /dev/null
+++ b/vsprojects/vcxproj/test/end2end/fixtures/h2_full+trace_test/h2_full+trace_test.vcxproj.filters
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <ClCompile Include="$(SolutionDir)\..\test\core\end2end\fixtures\h2_full+trace.c">
+      <Filter>test\core\end2end\fixtures</Filter>
+    </ClCompile>
+  </ItemGroup>
+
+  <ItemGroup>
+    <Filter Include="test">
+      <UniqueIdentifier>{00848213-d356-89b0-1d05-8131961dc959}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="test\core">
+      <UniqueIdentifier>{863a91b6-f5f9-5326-129a-10003d7af98f}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="test\core\end2end">
+      <UniqueIdentifier>{2733ff09-adc7-fd49-696f-5f72df2f44e2}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="test\core\end2end\fixtures">
+      <UniqueIdentifier>{62aa4eaf-c183-f2af-9ef9-a88ee802702c}</UniqueIdentifier>
+    </Filter>
+  </ItemGroup>
+</Project>
+
diff --git a/vsprojects/vcxproj/test/end2end/fixtures/h2_full_test/h2_full_test.vcxproj b/vsprojects/vcxproj/test/end2end/fixtures/h2_full_test/h2_full_test.vcxproj
index 96bd436..4ac31f1 100644
--- a/vsprojects/vcxproj/test/end2end/fixtures/h2_full_test/h2_full_test.vcxproj
+++ b/vsprojects/vcxproj/test/end2end/fixtures/h2_full_test/h2_full_test.vcxproj
@@ -165,9 +165,6 @@
     <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\test/end2end/tests\end2end_tests\end2end_tests.vcxproj">
       <Project>{1F1F9084-2A93-B80E-364F-5754894AFAB4}</Project>
     </ProjectReference>
-    <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\test/end2end\end2end_certs\end2end_certs.vcxproj">
-      <Project>{80EA2691-C037-6DD3-D3AB-21510BF0E64B}</Project>
-    </ProjectReference>
     <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc_test_util\grpc_test_util.vcxproj">
       <Project>{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}</Project>
     </ProjectReference>
diff --git a/vsprojects/vcxproj/test/end2end/fixtures/h2_oauth2_test/h2_oauth2_test.vcxproj b/vsprojects/vcxproj/test/end2end/fixtures/h2_oauth2_test/h2_oauth2_test.vcxproj
index f89d32c..67cc3c8 100644
--- a/vsprojects/vcxproj/test/end2end/fixtures/h2_oauth2_test/h2_oauth2_test.vcxproj
+++ b/vsprojects/vcxproj/test/end2end/fixtures/h2_oauth2_test/h2_oauth2_test.vcxproj
@@ -165,9 +165,6 @@
     <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\test/end2end/tests\end2end_tests\end2end_tests.vcxproj">
       <Project>{1F1F9084-2A93-B80E-364F-5754894AFAB4}</Project>
     </ProjectReference>
-    <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\test/end2end\end2end_certs\end2end_certs.vcxproj">
-      <Project>{80EA2691-C037-6DD3-D3AB-21510BF0E64B}</Project>
-    </ProjectReference>
     <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc_test_util\grpc_test_util.vcxproj">
       <Project>{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}</Project>
     </ProjectReference>
diff --git a/vsprojects/vcxproj/test/end2end/fixtures/h2_proxy_test/h2_proxy_test.vcxproj b/vsprojects/vcxproj/test/end2end/fixtures/h2_proxy_test/h2_proxy_test.vcxproj
index 8f56454..f159dfb 100644
--- a/vsprojects/vcxproj/test/end2end/fixtures/h2_proxy_test/h2_proxy_test.vcxproj
+++ b/vsprojects/vcxproj/test/end2end/fixtures/h2_proxy_test/h2_proxy_test.vcxproj
@@ -165,9 +165,6 @@
     <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\test/end2end/tests\end2end_tests\end2end_tests.vcxproj">
       <Project>{1F1F9084-2A93-B80E-364F-5754894AFAB4}</Project>
     </ProjectReference>
-    <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\test/end2end\end2end_certs\end2end_certs.vcxproj">
-      <Project>{80EA2691-C037-6DD3-D3AB-21510BF0E64B}</Project>
-    </ProjectReference>
     <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc_test_util\grpc_test_util.vcxproj">
       <Project>{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}</Project>
     </ProjectReference>
diff --git a/vsprojects/vcxproj/test/end2end/fixtures/h2_sockpair+trace_test/h2_sockpair+trace_test.vcxproj b/vsprojects/vcxproj/test/end2end/fixtures/h2_sockpair+trace_test/h2_sockpair+trace_test.vcxproj
index 44427fb..134913d 100644
--- a/vsprojects/vcxproj/test/end2end/fixtures/h2_sockpair+trace_test/h2_sockpair+trace_test.vcxproj
+++ b/vsprojects/vcxproj/test/end2end/fixtures/h2_sockpair+trace_test/h2_sockpair+trace_test.vcxproj
@@ -165,9 +165,6 @@
     <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\test/end2end/tests\end2end_tests\end2end_tests.vcxproj">
       <Project>{1F1F9084-2A93-B80E-364F-5754894AFAB4}</Project>
     </ProjectReference>
-    <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\test/end2end\end2end_certs\end2end_certs.vcxproj">
-      <Project>{80EA2691-C037-6DD3-D3AB-21510BF0E64B}</Project>
-    </ProjectReference>
     <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc_test_util\grpc_test_util.vcxproj">
       <Project>{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}</Project>
     </ProjectReference>
diff --git a/vsprojects/vcxproj/test/end2end/fixtures/h2_sockpair_1byte_test/h2_sockpair_1byte_test.vcxproj b/vsprojects/vcxproj/test/end2end/fixtures/h2_sockpair_1byte_test/h2_sockpair_1byte_test.vcxproj
index 5f4e43f..67c5486 100644
--- a/vsprojects/vcxproj/test/end2end/fixtures/h2_sockpair_1byte_test/h2_sockpair_1byte_test.vcxproj
+++ b/vsprojects/vcxproj/test/end2end/fixtures/h2_sockpair_1byte_test/h2_sockpair_1byte_test.vcxproj
@@ -165,9 +165,6 @@
     <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\test/end2end/tests\end2end_tests\end2end_tests.vcxproj">
       <Project>{1F1F9084-2A93-B80E-364F-5754894AFAB4}</Project>
     </ProjectReference>
-    <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\test/end2end\end2end_certs\end2end_certs.vcxproj">
-      <Project>{80EA2691-C037-6DD3-D3AB-21510BF0E64B}</Project>
-    </ProjectReference>
     <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc_test_util\grpc_test_util.vcxproj">
       <Project>{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}</Project>
     </ProjectReference>
diff --git a/vsprojects/vcxproj/test/end2end/fixtures/h2_sockpair_test/h2_sockpair_test.vcxproj b/vsprojects/vcxproj/test/end2end/fixtures/h2_sockpair_test/h2_sockpair_test.vcxproj
index 96359174..515ea02 100644
--- a/vsprojects/vcxproj/test/end2end/fixtures/h2_sockpair_test/h2_sockpair_test.vcxproj
+++ b/vsprojects/vcxproj/test/end2end/fixtures/h2_sockpair_test/h2_sockpair_test.vcxproj
@@ -165,9 +165,6 @@
     <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\test/end2end/tests\end2end_tests\end2end_tests.vcxproj">
       <Project>{1F1F9084-2A93-B80E-364F-5754894AFAB4}</Project>
     </ProjectReference>
-    <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\test/end2end\end2end_certs\end2end_certs.vcxproj">
-      <Project>{80EA2691-C037-6DD3-D3AB-21510BF0E64B}</Project>
-    </ProjectReference>
     <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc_test_util\grpc_test_util.vcxproj">
       <Project>{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}</Project>
     </ProjectReference>
diff --git a/vsprojects/vcxproj/test/end2end/fixtures/h2_ssl_proxy_test/h2_ssl_proxy_test.vcxproj b/vsprojects/vcxproj/test/end2end/fixtures/h2_ssl_proxy_test/h2_ssl_proxy_test.vcxproj
index 0693d65..c3463b9 100644
--- a/vsprojects/vcxproj/test/end2end/fixtures/h2_ssl_proxy_test/h2_ssl_proxy_test.vcxproj
+++ b/vsprojects/vcxproj/test/end2end/fixtures/h2_ssl_proxy_test/h2_ssl_proxy_test.vcxproj
@@ -165,9 +165,6 @@
     <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\test/end2end/tests\end2end_tests\end2end_tests.vcxproj">
       <Project>{1F1F9084-2A93-B80E-364F-5754894AFAB4}</Project>
     </ProjectReference>
-    <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\test/end2end\end2end_certs\end2end_certs.vcxproj">
-      <Project>{80EA2691-C037-6DD3-D3AB-21510BF0E64B}</Project>
-    </ProjectReference>
     <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc_test_util\grpc_test_util.vcxproj">
       <Project>{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}</Project>
     </ProjectReference>
diff --git a/vsprojects/vcxproj/test/end2end/fixtures/h2_ssl_test/h2_ssl_test.vcxproj b/vsprojects/vcxproj/test/end2end/fixtures/h2_ssl_test/h2_ssl_test.vcxproj
index 64e0c1b..217e415 100644
--- a/vsprojects/vcxproj/test/end2end/fixtures/h2_ssl_test/h2_ssl_test.vcxproj
+++ b/vsprojects/vcxproj/test/end2end/fixtures/h2_ssl_test/h2_ssl_test.vcxproj
@@ -165,9 +165,6 @@
     <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\test/end2end/tests\end2end_tests\end2end_tests.vcxproj">
       <Project>{1F1F9084-2A93-B80E-364F-5754894AFAB4}</Project>
     </ProjectReference>
-    <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\test/end2end\end2end_certs\end2end_certs.vcxproj">
-      <Project>{80EA2691-C037-6DD3-D3AB-21510BF0E64B}</Project>
-    </ProjectReference>
     <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc_test_util\grpc_test_util.vcxproj">
       <Project>{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}</Project>
     </ProjectReference>
diff --git a/vsprojects/vcxproj/test/end2end/fixtures/h2_uchannel_test/h2_uchannel_test.vcxproj b/vsprojects/vcxproj/test/end2end/fixtures/h2_uchannel_test/h2_uchannel_test.vcxproj
index bcf0f34..1564608 100644
--- a/vsprojects/vcxproj/test/end2end/fixtures/h2_uchannel_test/h2_uchannel_test.vcxproj
+++ b/vsprojects/vcxproj/test/end2end/fixtures/h2_uchannel_test/h2_uchannel_test.vcxproj
@@ -165,9 +165,6 @@
     <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\test/end2end/tests\end2end_tests\end2end_tests.vcxproj">
       <Project>{1F1F9084-2A93-B80E-364F-5754894AFAB4}</Project>
     </ProjectReference>
-    <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\test/end2end\end2end_certs\end2end_certs.vcxproj">
-      <Project>{80EA2691-C037-6DD3-D3AB-21510BF0E64B}</Project>
-    </ProjectReference>
     <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc_test_util\grpc_test_util.vcxproj">
       <Project>{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}</Project>
     </ProjectReference>
diff --git a/vsprojects/vcxproj/test/end2end/tests/end2end_tests/end2end_tests.vcxproj b/vsprojects/vcxproj/test/end2end/tests/end2end_tests/end2end_tests.vcxproj
index 9d7bdc5..f3b311b 100644
--- a/vsprojects/vcxproj/test/end2end/tests/end2end_tests/end2end_tests.vcxproj
+++ b/vsprojects/vcxproj/test/end2end/tests/end2end_tests/end2end_tests.vcxproj
@@ -227,9 +227,6 @@
     </ClCompile>
   </ItemGroup>
   <ItemGroup>
-    <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\test/end2end\end2end_certs\end2end_certs.vcxproj">
-      <Project>{80EA2691-C037-6DD3-D3AB-21510BF0E64B}</Project>
-    </ProjectReference>
     <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc_test_util\grpc_test_util.vcxproj">
       <Project>{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}</Project>
     </ProjectReference>
diff --git a/vsprojects/vcxproj/test/gpr_backoff_test/gpr_backoff_test.vcxproj b/vsprojects/vcxproj/test/gpr_backoff_test/gpr_backoff_test.vcxproj
new file mode 100644
index 0000000..6aa292e
--- /dev/null
+++ b/vsprojects/vcxproj/test/gpr_backoff_test/gpr_backoff_test.vcxproj
@@ -0,0 +1,193 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.props" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\1.0.204.1.props')" />
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{889F570D-E046-BD52-9E4C-B4CD13DFE2DB}</ProjectGuid>
+    <IgnoreWarnIntDirInTempDetected>true</IgnoreWarnIntDirInTempDetected>
+    <IntDir>$(SolutionDir)IntDir\$(MSBuildProjectName)\</IntDir>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(VisualStudioVersion)' == '10.0'" Label="Configuration">
+    <PlatformToolset>v100</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(VisualStudioVersion)' == '11.0'" Label="Configuration">
+    <PlatformToolset>v110</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(VisualStudioVersion)' == '12.0'" Label="Configuration">
+    <PlatformToolset>v120</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(VisualStudioVersion)' == '14.0'" Label="Configuration">
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)'=='Debug'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)'=='Release'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="$(SolutionDir)\..\vsprojects\global.props" />
+    <Import Project="$(SolutionDir)\..\vsprojects\openssl.props" />
+    <Import Project="$(SolutionDir)\..\vsprojects\winsock.props" />
+    <Import Project="$(SolutionDir)\..\vsprojects\zlib.props" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup Condition="'$(Configuration)'=='Debug'">
+    <TargetName>gpr_backoff_test</TargetName>
+    <Linkage-grpc_dependencies_zlib>static</Linkage-grpc_dependencies_zlib>
+    <Configuration-grpc_dependencies_zlib>Debug</Configuration-grpc_dependencies_zlib>
+    <Linkage-grpc_dependencies_openssl>static</Linkage-grpc_dependencies_openssl>
+    <Configuration-grpc_dependencies_openssl>Debug</Configuration-grpc_dependencies_openssl>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)'=='Release'">
+    <TargetName>gpr_backoff_test</TargetName>
+    <Linkage-grpc_dependencies_zlib>static</Linkage-grpc_dependencies_zlib>
+    <Configuration-grpc_dependencies_zlib>Release</Configuration-grpc_dependencies_zlib>
+    <Linkage-grpc_dependencies_openssl>static</Linkage-grpc_dependencies_openssl>
+    <Configuration-grpc_dependencies_openssl>Release</Configuration-grpc_dependencies_openssl>
+  </PropertyGroup>
+    <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+      <MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
+      <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+
+    <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+      <MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
+      <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+
+    <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>MaxSpeed</Optimization>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <SDLCheck>true</SDLCheck>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+      <MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
+      <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+    </Link>
+  </ItemDefinitionGroup>
+
+    <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>MaxSpeed</Optimization>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <SDLCheck>true</SDLCheck>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+      <MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
+      <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+    </Link>
+  </ItemDefinitionGroup>
+
+  <ItemGroup>
+    <ClCompile Include="$(SolutionDir)\..\test\core\support\backoff_test.c">
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\gpr_test_util\gpr_test_util.vcxproj">
+      <Project>{EAB0A629-17A9-44DB-B5FF-E91A721FE037}</Project>
+    </ProjectReference>
+    <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\gpr\gpr.vcxproj">
+      <Project>{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}</Project>
+    </ProjectReference>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="packages.config" />
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  <Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\native\grpc.dependencies.zlib.redist.targets" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\native\grpc.dependencies\grpc.dependencies.zlib.targets')" />
+  <Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.10\build\native\grpc.dependencies.zlib.targets" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.10\build\native\grpc.dependencies\grpc.dependencies.zlib.targets')" />
+  <Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\native\grpc.dependencies.openssl.redist.targets" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\native\grpc.dependencies\grpc.dependencies.openssl.targets')" />
+  <Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.targets" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies\grpc.dependencies.openssl.targets')" />
+  </ImportGroup>
+  <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
+    <PropertyGroup>
+      <ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them.  For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
+    </PropertyGroup>
+    <Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\native\grpc.dependencies.zlib.redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\native\grpc.dependencies.zlib.redist.targets')" />
+    <Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.10\build\native\grpc.dependencies.zlib.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.10\build\native\grpc.dependencies.zlib.targets')" />
+    <Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\native\grpc.dependencies.openssl.redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\native\grpc.dependencies.openssl.redist.targets')" />
+    <Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.props')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.props')" />
+    <Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.targets')" />
+  </Target>
+</Project>
+
diff --git a/vsprojects/vcxproj/test/gpr_backoff_test/gpr_backoff_test.vcxproj.filters b/vsprojects/vcxproj/test/gpr_backoff_test/gpr_backoff_test.vcxproj.filters
new file mode 100644
index 0000000..eb3c1bb
--- /dev/null
+++ b/vsprojects/vcxproj/test/gpr_backoff_test/gpr_backoff_test.vcxproj.filters
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <ClCompile Include="$(SolutionDir)\..\test\core\support\backoff_test.c">
+      <Filter>test\core\support</Filter>
+    </ClCompile>
+  </ItemGroup>
+
+  <ItemGroup>
+    <Filter Include="test">
+      <UniqueIdentifier>{4b7f1d25-d344-0bcb-63d8-2ba959874ea8}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="test\core">
+      <UniqueIdentifier>{2bd2fba5-8799-2c78-469f-ec3ba6b01da8}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="test\core\support">
+      <UniqueIdentifier>{2ef0cfa7-fe3d-2b82-7d0e-f9e293e8f98c}</UniqueIdentifier>
+    </Filter>
+  </ItemGroup>
+</Project>
+