Merge remote-tracking branch 'upstream/master' into call_holder_add_pollent
diff --git a/BUILD b/BUILD
index 7612007..cd334b2 100644
--- a/BUILD
+++ b/BUILD
@@ -52,6 +52,7 @@
     "src/core/lib/support/block_annotate.h",
     "src/core/lib/support/env.h",
     "src/core/lib/support/murmur_hash.h",
+    "src/core/lib/support/percent_encoding.h",
     "src/core/lib/support/stack_lockfree.h",
     "src/core/lib/support/string.h",
     "src/core/lib/support/string_windows.h",
@@ -79,6 +80,7 @@
     "src/core/lib/support/log_posix.c",
     "src/core/lib/support/log_windows.c",
     "src/core/lib/support/murmur_hash.c",
+    "src/core/lib/support/percent_encoding.c",
     "src/core/lib/support/slice.c",
     "src/core/lib/support/slice_buffer.c",
     "src/core/lib/support/stack_lockfree.c",
@@ -133,20 +135,17 @@
     "include/grpc/support/tls_msvc.h",
     "include/grpc/support/tls_pthread.h",
     "include/grpc/support/useful.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_windows.h",
-    "include/grpc/impl/codegen/log.h",
+    "include/grpc/impl/codegen/gpr_types.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_windows.h",
-    "include/grpc/impl/codegen/time.h",
   ],
   includes = [
     "include",
@@ -512,27 +511,23 @@
     "include/grpc/grpc_posix.h",
     "include/grpc/grpc_security_constants.h",
     "include/grpc/status.h",
-    "include/grpc/impl/codegen/byte_buffer.h",
     "include/grpc/impl/codegen/byte_buffer_reader.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",
     "include/grpc/impl/codegen/atm_gcc_sync.h",
     "include/grpc/impl/codegen/atm_windows.h",
-    "include/grpc/impl/codegen/log.h",
+    "include/grpc/impl/codegen/gpr_types.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_windows.h",
-    "include/grpc/impl/codegen/time.h",
     "include/grpc/grpc_security.h",
     "include/grpc/census.h",
   ],
@@ -869,27 +864,23 @@
     "include/grpc/grpc_posix.h",
     "include/grpc/grpc_security_constants.h",
     "include/grpc/status.h",
-    "include/grpc/impl/codegen/byte_buffer.h",
     "include/grpc/impl/codegen/byte_buffer_reader.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",
     "include/grpc/impl/codegen/atm_gcc_sync.h",
     "include/grpc/impl/codegen/atm_windows.h",
-    "include/grpc/impl/codegen/log.h",
+    "include/grpc/impl/codegen/gpr_types.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_windows.h",
-    "include/grpc/impl/codegen/time.h",
     "include/grpc/grpc_cronet.h",
     "include/grpc/grpc_security.h",
   ],
@@ -1206,27 +1197,23 @@
     "include/grpc/grpc_posix.h",
     "include/grpc/grpc_security_constants.h",
     "include/grpc/status.h",
-    "include/grpc/impl/codegen/byte_buffer.h",
     "include/grpc/impl/codegen/byte_buffer_reader.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",
     "include/grpc/impl/codegen/atm_gcc_sync.h",
     "include/grpc/impl/codegen/atm_windows.h",
-    "include/grpc/impl/codegen/log.h",
+    "include/grpc/impl/codegen/gpr_types.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_windows.h",
-    "include/grpc/impl/codegen/time.h",
     "include/grpc/census.h",
   ],
   includes = [
@@ -1335,39 +1322,39 @@
     "src/core/lib/transport/timeout_encoding.h",
     "src/core/lib/transport/transport.h",
     "src/core/lib/transport/transport_impl.h",
+    "src/cpp/client/insecure_credentials.cc",
     "src/cpp/client/secure_credentials.cc",
     "src/cpp/common/auth_property_iterator.cc",
     "src/cpp/common/secure_auth_context.cc",
     "src/cpp/common/secure_channel_arguments.cc",
     "src/cpp/common/secure_create_auth_context.cc",
+    "src/cpp/server/insecure_server_credentials.cc",
     "src/cpp/server/secure_server_credentials.cc",
-    "src/cpp/client/channel.cc",
+    "src/cpp/client/channel_cc.cc",
     "src/cpp/client/client_context.cc",
     "src/cpp/client/create_channel.cc",
     "src/cpp/client/create_channel_internal.cc",
     "src/cpp/client/create_channel_posix.cc",
-    "src/cpp/client/credentials.cc",
+    "src/cpp/client/credentials_cc.cc",
     "src/cpp/client/generic_stub.cc",
-    "src/cpp/client/insecure_credentials.cc",
     "src/cpp/common/channel_arguments.cc",
     "src/cpp/common/channel_filter.cc",
-    "src/cpp/common/completion_queue.cc",
+    "src/cpp/common/completion_queue_cc.cc",
     "src/cpp/common/core_codegen.cc",
     "src/cpp/common/rpc_method.cc",
     "src/cpp/server/async_generic_service.cc",
     "src/cpp/server/create_default_thread_pool.cc",
     "src/cpp/server/dynamic_thread_pool.cc",
-    "src/cpp/server/insecure_server_credentials.cc",
-    "src/cpp/server/server.cc",
     "src/cpp/server/server_builder.cc",
+    "src/cpp/server/server_cc.cc",
     "src/cpp/server/server_context.cc",
     "src/cpp/server/server_credentials.cc",
     "src/cpp/server/server_posix.cc",
-    "src/cpp/util/byte_buffer.cc",
-    "src/cpp/util/slice.cc",
+    "src/cpp/util/byte_buffer_cc.cc",
+    "src/cpp/util/slice_cc.cc",
     "src/cpp/util/status.cc",
     "src/cpp/util/string_ref.cc",
-    "src/cpp/util/time.cc",
+    "src/cpp/util/time_cc.cc",
     "src/core/lib/channel/channel_args.c",
     "src/core/lib/channel/channel_stack.c",
     "src/core/lib/channel/channel_stack_builder.c",
@@ -1514,27 +1501,23 @@
     "include/grpc/grpc_posix.h",
     "include/grpc/grpc_security_constants.h",
     "include/grpc/status.h",
-    "include/grpc/impl/codegen/byte_buffer.h",
     "include/grpc/impl/codegen/byte_buffer_reader.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",
     "include/grpc/impl/codegen/atm_gcc_sync.h",
     "include/grpc/impl/codegen/atm_windows.h",
-    "include/grpc/impl/codegen/log.h",
+    "include/grpc/impl/codegen/gpr_types.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_windows.h",
-    "include/grpc/impl/codegen/time.h",
     "include/grpc++/impl/codegen/async_stream.h",
     "include/grpc++/impl/codegen/async_unary_call.h",
     "include/grpc++/impl/codegen/call.h",
@@ -1624,27 +1607,23 @@
     "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/byte_buffer_reader.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",
     "include/grpc/impl/codegen/atm_gcc_sync.h",
     "include/grpc/impl/codegen/atm_windows.h",
-    "include/grpc/impl/codegen/log.h",
+    "include/grpc/impl/codegen/gpr_types.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_windows.h",
-    "include/grpc/impl/codegen/time.h",
     "include/grpc++/impl/codegen/config_protobuf.h",
   ],
   includes = [
@@ -1745,34 +1724,34 @@
     "src/core/lib/transport/timeout_encoding.h",
     "src/core/lib/transport/transport.h",
     "src/core/lib/transport/transport_impl.h",
+    "src/cpp/client/insecure_credentials.cc",
     "src/cpp/common/insecure_create_auth_context.cc",
-    "src/cpp/client/channel.cc",
+    "src/cpp/server/insecure_server_credentials.cc",
+    "src/cpp/client/channel_cc.cc",
     "src/cpp/client/client_context.cc",
     "src/cpp/client/create_channel.cc",
     "src/cpp/client/create_channel_internal.cc",
     "src/cpp/client/create_channel_posix.cc",
-    "src/cpp/client/credentials.cc",
+    "src/cpp/client/credentials_cc.cc",
     "src/cpp/client/generic_stub.cc",
-    "src/cpp/client/insecure_credentials.cc",
     "src/cpp/common/channel_arguments.cc",
     "src/cpp/common/channel_filter.cc",
-    "src/cpp/common/completion_queue.cc",
+    "src/cpp/common/completion_queue_cc.cc",
     "src/cpp/common/core_codegen.cc",
     "src/cpp/common/rpc_method.cc",
     "src/cpp/server/async_generic_service.cc",
     "src/cpp/server/create_default_thread_pool.cc",
     "src/cpp/server/dynamic_thread_pool.cc",
-    "src/cpp/server/insecure_server_credentials.cc",
-    "src/cpp/server/server.cc",
     "src/cpp/server/server_builder.cc",
+    "src/cpp/server/server_cc.cc",
     "src/cpp/server/server_context.cc",
     "src/cpp/server/server_credentials.cc",
     "src/cpp/server/server_posix.cc",
-    "src/cpp/util/byte_buffer.cc",
-    "src/cpp/util/slice.cc",
+    "src/cpp/util/byte_buffer_cc.cc",
+    "src/cpp/util/slice_cc.cc",
     "src/cpp/util/status.cc",
     "src/cpp/util/string_ref.cc",
-    "src/cpp/util/time.cc",
+    "src/cpp/util/time_cc.cc",
     "src/core/lib/channel/channel_args.c",
     "src/core/lib/channel/channel_stack.c",
     "src/core/lib/channel/channel_stack_builder.c",
@@ -1919,27 +1898,23 @@
     "include/grpc/grpc_posix.h",
     "include/grpc/grpc_security_constants.h",
     "include/grpc/status.h",
-    "include/grpc/impl/codegen/byte_buffer.h",
     "include/grpc/impl/codegen/byte_buffer_reader.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",
     "include/grpc/impl/codegen/atm_gcc_sync.h",
     "include/grpc/impl/codegen/atm_windows.h",
-    "include/grpc/impl/codegen/log.h",
+    "include/grpc/impl/codegen/gpr_types.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_windows.h",
-    "include/grpc/impl/codegen/time.h",
     "include/grpc++/impl/codegen/async_stream.h",
     "include/grpc++/impl/codegen/async_unary_call.h",
     "include/grpc++/impl/codegen/call.h",
@@ -2067,6 +2042,7 @@
     "src/core/lib/support/log_posix.c",
     "src/core/lib/support/log_windows.c",
     "src/core/lib/support/murmur_hash.c",
+    "src/core/lib/support/percent_encoding.c",
     "src/core/lib/support/slice.c",
     "src/core/lib/support/slice_buffer.c",
     "src/core/lib/support/stack_lockfree.c",
@@ -2121,25 +2097,23 @@
     "include/grpc/support/tls_msvc.h",
     "include/grpc/support/tls_pthread.h",
     "include/grpc/support/useful.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_windows.h",
-    "include/grpc/impl/codegen/log.h",
+    "include/grpc/impl/codegen/gpr_types.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_windows.h",
-    "include/grpc/impl/codegen/time.h",
     "src/core/lib/profiling/timers.h",
     "src/core/lib/support/backoff.h",
     "src/core/lib/support/block_annotate.h",
     "src/core/lib/support/env.h",
     "src/core/lib/support/murmur_hash.h",
+    "src/core/lib/support/percent_encoding.h",
     "src/core/lib/support/stack_lockfree.h",
     "src/core/lib/support/string.h",
     "src/core/lib/support/string_windows.h",
@@ -2356,27 +2330,23 @@
     "include/grpc/grpc_posix.h",
     "include/grpc/grpc_security_constants.h",
     "include/grpc/status.h",
-    "include/grpc/impl/codegen/byte_buffer.h",
     "include/grpc/impl/codegen/byte_buffer_reader.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",
     "include/grpc/impl/codegen/atm_gcc_sync.h",
     "include/grpc/impl/codegen/atm_windows.h",
-    "include/grpc/impl/codegen/log.h",
+    "include/grpc/impl/codegen/gpr_types.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_windows.h",
-    "include/grpc/impl/codegen/time.h",
     "include/grpc/grpc_security.h",
     "include/grpc/census.h",
     "src/core/lib/channel/channel_args.h",
diff --git a/CMakeLists.txt b/CMakeLists.txt
index b339aaa..2b24c9a 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -192,6 +192,7 @@
   src/core/lib/support/log_posix.c
   src/core/lib/support/log_windows.c
   src/core/lib/support/murmur_hash.c
+  src/core/lib/support/percent_encoding.c
   src/core/lib/support/slice.c
   src/core/lib/support/slice_buffer.c
   src/core/lib/support/stack_lockfree.c
@@ -257,20 +258,17 @@
   include/grpc/support/tls_msvc.h
   include/grpc/support/tls_pthread.h
   include/grpc/support/useful.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_windows.h
-  include/grpc/impl/codegen/log.h
+  include/grpc/impl/codegen/gpr_types.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_windows.h
-  include/grpc/impl/codegen/time.h
 )
   string(REPLACE "include/" "" _path ${_hdr})
   get_filename_component(_path ${_path} PATH)
@@ -506,27 +504,23 @@
   include/grpc/grpc_posix.h
   include/grpc/grpc_security_constants.h
   include/grpc/status.h
-  include/grpc/impl/codegen/byte_buffer.h
   include/grpc/impl/codegen/byte_buffer_reader.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
   include/grpc/impl/codegen/atm_gcc_sync.h
   include/grpc/impl/codegen/atm_windows.h
-  include/grpc/impl/codegen/log.h
+  include/grpc/impl/codegen/gpr_types.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_windows.h
-  include/grpc/impl/codegen/time.h
   include/grpc/grpc_security.h
   include/grpc/census.h
 )
@@ -736,27 +730,23 @@
   include/grpc/grpc_posix.h
   include/grpc/grpc_security_constants.h
   include/grpc/status.h
-  include/grpc/impl/codegen/byte_buffer.h
   include/grpc/impl/codegen/byte_buffer_reader.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
   include/grpc/impl/codegen/atm_gcc_sync.h
   include/grpc/impl/codegen/atm_windows.h
-  include/grpc/impl/codegen/log.h
+  include/grpc/impl/codegen/gpr_types.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_windows.h
-  include/grpc/impl/codegen/time.h
   include/grpc/grpc_cronet.h
   include/grpc/grpc_security.h
 )
@@ -963,27 +953,23 @@
   include/grpc/grpc_posix.h
   include/grpc/grpc_security_constants.h
   include/grpc/status.h
-  include/grpc/impl/codegen/byte_buffer.h
   include/grpc/impl/codegen/byte_buffer_reader.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
   include/grpc/impl/codegen/atm_gcc_sync.h
   include/grpc/impl/codegen/atm_windows.h
-  include/grpc/impl/codegen/log.h
+  include/grpc/impl/codegen/gpr_types.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_windows.h
-  include/grpc/impl/codegen/time.h
   include/grpc/census.h
 )
   string(REPLACE "include/" "" _path ${_hdr})
@@ -1004,39 +990,39 @@
 
   
 add_library(grpc++
+  src/cpp/client/insecure_credentials.cc
   src/cpp/client/secure_credentials.cc
   src/cpp/common/auth_property_iterator.cc
   src/cpp/common/secure_auth_context.cc
   src/cpp/common/secure_channel_arguments.cc
   src/cpp/common/secure_create_auth_context.cc
+  src/cpp/server/insecure_server_credentials.cc
   src/cpp/server/secure_server_credentials.cc
-  src/cpp/client/channel.cc
+  src/cpp/client/channel_cc.cc
   src/cpp/client/client_context.cc
   src/cpp/client/create_channel.cc
   src/cpp/client/create_channel_internal.cc
   src/cpp/client/create_channel_posix.cc
-  src/cpp/client/credentials.cc
+  src/cpp/client/credentials_cc.cc
   src/cpp/client/generic_stub.cc
-  src/cpp/client/insecure_credentials.cc
   src/cpp/common/channel_arguments.cc
   src/cpp/common/channel_filter.cc
-  src/cpp/common/completion_queue.cc
+  src/cpp/common/completion_queue_cc.cc
   src/cpp/common/core_codegen.cc
   src/cpp/common/rpc_method.cc
   src/cpp/server/async_generic_service.cc
   src/cpp/server/create_default_thread_pool.cc
   src/cpp/server/dynamic_thread_pool.cc
-  src/cpp/server/insecure_server_credentials.cc
-  src/cpp/server/server.cc
   src/cpp/server/server_builder.cc
+  src/cpp/server/server_cc.cc
   src/cpp/server/server_context.cc
   src/cpp/server/server_credentials.cc
   src/cpp/server/server_posix.cc
-  src/cpp/util/byte_buffer.cc
-  src/cpp/util/slice.cc
+  src/cpp/util/byte_buffer_cc.cc
+  src/cpp/util/slice_cc.cc
   src/cpp/util/status.cc
   src/cpp/util/string_ref.cc
-  src/cpp/util/time.cc
+  src/cpp/util/time_cc.cc
   src/core/lib/channel/channel_args.c
   src/core/lib/channel/channel_stack.c
   src/core/lib/channel/channel_stack_builder.c
@@ -1201,27 +1187,23 @@
   include/grpc/grpc_posix.h
   include/grpc/grpc_security_constants.h
   include/grpc/status.h
-  include/grpc/impl/codegen/byte_buffer.h
   include/grpc/impl/codegen/byte_buffer_reader.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
   include/grpc/impl/codegen/atm_gcc_sync.h
   include/grpc/impl/codegen/atm_windows.h
-  include/grpc/impl/codegen/log.h
+  include/grpc/impl/codegen/gpr_types.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_windows.h
-  include/grpc/impl/codegen/time.h
   include/grpc++/impl/codegen/async_stream.h
   include/grpc++/impl/codegen/async_unary_call.h
   include/grpc++/impl/codegen/call.h
@@ -1325,27 +1307,23 @@
   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/byte_buffer_reader.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
   include/grpc/impl/codegen/atm_gcc_sync.h
   include/grpc/impl/codegen/atm_windows.h
-  include/grpc/impl/codegen/log.h
+  include/grpc/impl/codegen/gpr_types.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_windows.h
-  include/grpc/impl/codegen/time.h
   include/grpc++/impl/codegen/config_protobuf.h
 )
   string(REPLACE "include/" "" _path ${_hdr})
@@ -1366,34 +1344,34 @@
 
   
 add_library(grpc++_unsecure
+  src/cpp/client/insecure_credentials.cc
   src/cpp/common/insecure_create_auth_context.cc
-  src/cpp/client/channel.cc
+  src/cpp/server/insecure_server_credentials.cc
+  src/cpp/client/channel_cc.cc
   src/cpp/client/client_context.cc
   src/cpp/client/create_channel.cc
   src/cpp/client/create_channel_internal.cc
   src/cpp/client/create_channel_posix.cc
-  src/cpp/client/credentials.cc
+  src/cpp/client/credentials_cc.cc
   src/cpp/client/generic_stub.cc
-  src/cpp/client/insecure_credentials.cc
   src/cpp/common/channel_arguments.cc
   src/cpp/common/channel_filter.cc
-  src/cpp/common/completion_queue.cc
+  src/cpp/common/completion_queue_cc.cc
   src/cpp/common/core_codegen.cc
   src/cpp/common/rpc_method.cc
   src/cpp/server/async_generic_service.cc
   src/cpp/server/create_default_thread_pool.cc
   src/cpp/server/dynamic_thread_pool.cc
-  src/cpp/server/insecure_server_credentials.cc
-  src/cpp/server/server.cc
   src/cpp/server/server_builder.cc
+  src/cpp/server/server_cc.cc
   src/cpp/server/server_context.cc
   src/cpp/server/server_credentials.cc
   src/cpp/server/server_posix.cc
-  src/cpp/util/byte_buffer.cc
-  src/cpp/util/slice.cc
+  src/cpp/util/byte_buffer_cc.cc
+  src/cpp/util/slice_cc.cc
   src/cpp/util/status.cc
   src/cpp/util/string_ref.cc
-  src/cpp/util/time.cc
+  src/cpp/util/time_cc.cc
   src/core/lib/channel/channel_args.c
   src/core/lib/channel/channel_stack.c
   src/core/lib/channel/channel_stack_builder.c
@@ -1557,27 +1535,23 @@
   include/grpc/grpc_posix.h
   include/grpc/grpc_security_constants.h
   include/grpc/status.h
-  include/grpc/impl/codegen/byte_buffer.h
   include/grpc/impl/codegen/byte_buffer_reader.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
   include/grpc/impl/codegen/atm_gcc_sync.h
   include/grpc/impl/codegen/atm_windows.h
-  include/grpc/impl/codegen/log.h
+  include/grpc/impl/codegen/gpr_types.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_windows.h
-  include/grpc/impl/codegen/time.h
   include/grpc++/impl/codegen/async_stream.h
   include/grpc++/impl/codegen/async_unary_call.h
   include/grpc++/impl/codegen/call.h
@@ -1750,6 +1724,30 @@
 endif()
 
 
+add_executable(gen_percent_encoding_tables
+  tools/codegen/core/gen_percent_encoding_tables.c
+)
+
+target_include_directories(gen_percent_encoding_tables
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+  PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+  PRIVATE ${BORINGSSL_ROOT_DIR}/include
+  PRIVATE ${PROTOBUF_ROOT_DIR}/src
+  PRIVATE ${ZLIB_ROOT_DIR}
+  PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib
+)
+
+
+
+if (gRPC_INSTALL)
+  install(TARGETS gen_percent_encoding_tables EXPORT gRPCTargets
+    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+    ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
+  )
+endif()
+
+
 add_executable(grpc_create_jwt
   test/core/security/create_jwt.c
 )
diff --git a/INSTALL.md b/INSTALL.md
index 7bdb9b2..6861455 100644
--- a/INSTALL.md
+++ b/INSTALL.md
@@ -9,7 +9,7 @@
  * [Java](https://github.com/grpc/grpc-java)
  * [Node](src/node): `npm install grpc`
  * [Objective-C](src/objective-c)
- * [PHP](src/php): `pecl install grpc-beta`
+ * [PHP](src/php): `pecl install grpc`
  * [Python](src/python/grpcio): `pip install grpcio`
  * [Ruby](src/ruby): `gem install grpc`
 
diff --git a/Makefile b/Makefile
index 2dc401a..af4d4f4 100644
--- a/Makefile
+++ b/Makefile
@@ -930,6 +930,7 @@
 fling_test: $(BINDIR)/$(CONFIG)/fling_test
 gen_hpack_tables: $(BINDIR)/$(CONFIG)/gen_hpack_tables
 gen_legal_metadata_characters: $(BINDIR)/$(CONFIG)/gen_legal_metadata_characters
+gen_percent_encoding_tables: $(BINDIR)/$(CONFIG)/gen_percent_encoding_tables
 goaway_server_test: $(BINDIR)/$(CONFIG)/goaway_server_test
 gpr_avl_test: $(BINDIR)/$(CONFIG)/gpr_avl_test
 gpr_backoff_test: $(BINDIR)/$(CONFIG)/gpr_backoff_test
@@ -939,6 +940,7 @@
 gpr_histogram_test: $(BINDIR)/$(CONFIG)/gpr_histogram_test
 gpr_host_port_test: $(BINDIR)/$(CONFIG)/gpr_host_port_test
 gpr_log_test: $(BINDIR)/$(CONFIG)/gpr_log_test
+gpr_percent_encoding_test: $(BINDIR)/$(CONFIG)/gpr_percent_encoding_test
 gpr_slice_buffer_test: $(BINDIR)/$(CONFIG)/gpr_slice_buffer_test
 gpr_slice_test: $(BINDIR)/$(CONFIG)/gpr_slice_test
 gpr_stack_lockfree_test: $(BINDIR)/$(CONFIG)/gpr_stack_lockfree_test
@@ -993,6 +995,8 @@
 nanopb_fuzzer_response_test: $(BINDIR)/$(CONFIG)/nanopb_fuzzer_response_test
 nanopb_fuzzer_serverlist_test: $(BINDIR)/$(CONFIG)/nanopb_fuzzer_serverlist_test
 no_server_test: $(BINDIR)/$(CONFIG)/no_server_test
+percent_decode_fuzzer: $(BINDIR)/$(CONFIG)/percent_decode_fuzzer
+percent_encode_fuzzer: $(BINDIR)/$(CONFIG)/percent_encode_fuzzer
 resolve_address_test: $(BINDIR)/$(CONFIG)/resolve_address_test
 secure_channel_create_test: $(BINDIR)/$(CONFIG)/secure_channel_create_test
 secure_endpoint_test: $(BINDIR)/$(CONFIG)/secure_endpoint_test
@@ -1118,9 +1122,7 @@
 simple_request_bad_client_test: $(BINDIR)/$(CONFIG)/simple_request_bad_client_test
 unknown_frame_bad_client_test: $(BINDIR)/$(CONFIG)/unknown_frame_bad_client_test
 window_overflow_bad_client_test: $(BINDIR)/$(CONFIG)/window_overflow_bad_client_test
-bad_ssl_alpn_server: $(BINDIR)/$(CONFIG)/bad_ssl_alpn_server
 bad_ssl_cert_server: $(BINDIR)/$(CONFIG)/bad_ssl_cert_server
-bad_ssl_alpn_test: $(BINDIR)/$(CONFIG)/bad_ssl_alpn_test
 bad_ssl_cert_test: $(BINDIR)/$(CONFIG)/bad_ssl_cert_test
 h2_census_test: $(BINDIR)/$(CONFIG)/h2_census_test
 h2_compress_test: $(BINDIR)/$(CONFIG)/h2_compress_test
@@ -1159,6 +1161,8 @@
 json_fuzzer_test_one_entry: $(BINDIR)/$(CONFIG)/json_fuzzer_test_one_entry
 nanopb_fuzzer_response_test_one_entry: $(BINDIR)/$(CONFIG)/nanopb_fuzzer_response_test_one_entry
 nanopb_fuzzer_serverlist_test_one_entry: $(BINDIR)/$(CONFIG)/nanopb_fuzzer_serverlist_test_one_entry
+percent_decode_fuzzer_one_entry: $(BINDIR)/$(CONFIG)/percent_decode_fuzzer_one_entry
+percent_encode_fuzzer_one_entry: $(BINDIR)/$(CONFIG)/percent_encode_fuzzer_one_entry
 server_fuzzer_one_entry: $(BINDIR)/$(CONFIG)/server_fuzzer_one_entry
 uri_fuzzer_test_one_entry: $(BINDIR)/$(CONFIG)/uri_fuzzer_test_one_entry
 
@@ -1258,6 +1262,7 @@
   $(BINDIR)/$(CONFIG)/gpr_histogram_test \
   $(BINDIR)/$(CONFIG)/gpr_host_port_test \
   $(BINDIR)/$(CONFIG)/gpr_log_test \
+  $(BINDIR)/$(CONFIG)/gpr_percent_encoding_test \
   $(BINDIR)/$(CONFIG)/gpr_slice_buffer_test \
   $(BINDIR)/$(CONFIG)/gpr_slice_test \
   $(BINDIR)/$(CONFIG)/gpr_stack_lockfree_test \
@@ -1335,9 +1340,7 @@
   $(BINDIR)/$(CONFIG)/simple_request_bad_client_test \
   $(BINDIR)/$(CONFIG)/unknown_frame_bad_client_test \
   $(BINDIR)/$(CONFIG)/window_overflow_bad_client_test \
-  $(BINDIR)/$(CONFIG)/bad_ssl_alpn_server \
   $(BINDIR)/$(CONFIG)/bad_ssl_cert_server \
-  $(BINDIR)/$(CONFIG)/bad_ssl_alpn_test \
   $(BINDIR)/$(CONFIG)/bad_ssl_cert_test \
   $(BINDIR)/$(CONFIG)/h2_census_test \
   $(BINDIR)/$(CONFIG)/h2_compress_test \
@@ -1376,6 +1379,8 @@
   $(BINDIR)/$(CONFIG)/json_fuzzer_test_one_entry \
   $(BINDIR)/$(CONFIG)/nanopb_fuzzer_response_test_one_entry \
   $(BINDIR)/$(CONFIG)/nanopb_fuzzer_serverlist_test_one_entry \
+  $(BINDIR)/$(CONFIG)/percent_decode_fuzzer_one_entry \
+  $(BINDIR)/$(CONFIG)/percent_encode_fuzzer_one_entry \
   $(BINDIR)/$(CONFIG)/server_fuzzer_one_entry \
   $(BINDIR)/$(CONFIG)/uri_fuzzer_test_one_entry \
 
@@ -1592,6 +1597,8 @@
 	$(Q) $(BINDIR)/$(CONFIG)/gpr_host_port_test || ( echo test gpr_host_port_test failed ; exit 1 )
 	$(E) "[RUN]     Testing gpr_log_test"
 	$(Q) $(BINDIR)/$(CONFIG)/gpr_log_test || ( echo test gpr_log_test failed ; exit 1 )
+	$(E) "[RUN]     Testing gpr_percent_encoding_test"
+	$(Q) $(BINDIR)/$(CONFIG)/gpr_percent_encoding_test || ( echo test gpr_percent_encoding_test failed ; exit 1 )
 	$(E) "[RUN]     Testing gpr_slice_buffer_test"
 	$(Q) $(BINDIR)/$(CONFIG)/gpr_slice_buffer_test || ( echo test gpr_slice_buffer_test failed ; exit 1 )
 	$(E) "[RUN]     Testing gpr_slice_test"
@@ -1732,8 +1739,6 @@
 	$(Q) $(BINDIR)/$(CONFIG)/unknown_frame_bad_client_test || ( echo test unknown_frame_bad_client_test failed ; exit 1 )
 	$(E) "[RUN]     Testing window_overflow_bad_client_test"
 	$(Q) $(BINDIR)/$(CONFIG)/window_overflow_bad_client_test || ( echo test window_overflow_bad_client_test failed ; exit 1 )
-	$(E) "[RUN]     Testing bad_ssl_alpn_test"
-	$(Q) $(BINDIR)/$(CONFIG)/bad_ssl_alpn_test || ( echo test bad_ssl_alpn_test failed ; exit 1 )
 	$(E) "[RUN]     Testing bad_ssl_cert_test"
 	$(Q) $(BINDIR)/$(CONFIG)/bad_ssl_cert_test || ( echo test bad_ssl_cert_test failed ; exit 1 )
 
@@ -1825,7 +1830,7 @@
 tools: tools_c tools_cxx
 
 
-tools_c: privatelibs_c $(BINDIR)/$(CONFIG)/gen_hpack_tables $(BINDIR)/$(CONFIG)/gen_legal_metadata_characters $(BINDIR)/$(CONFIG)/grpc_create_jwt $(BINDIR)/$(CONFIG)/grpc_print_google_default_creds_token $(BINDIR)/$(CONFIG)/grpc_verify_jwt
+tools_c: privatelibs_c $(BINDIR)/$(CONFIG)/gen_hpack_tables $(BINDIR)/$(CONFIG)/gen_legal_metadata_characters $(BINDIR)/$(CONFIG)/gen_percent_encoding_tables $(BINDIR)/$(CONFIG)/grpc_create_jwt $(BINDIR)/$(CONFIG)/grpc_print_google_default_creds_token $(BINDIR)/$(CONFIG)/grpc_verify_jwt
 
 tools_cxx: privatelibs_cxx
 
@@ -2374,6 +2379,7 @@
     src/core/lib/support/log_posix.c \
     src/core/lib/support/log_windows.c \
     src/core/lib/support/murmur_hash.c \
+    src/core/lib/support/percent_encoding.c \
     src/core/lib/support/slice.c \
     src/core/lib/support/slice_buffer.c \
     src/core/lib/support/stack_lockfree.c \
@@ -2428,20 +2434,17 @@
     include/grpc/support/tls_msvc.h \
     include/grpc/support/tls_pthread.h \
     include/grpc/support/useful.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_windows.h \
-    include/grpc/impl/codegen/log.h \
+    include/grpc/impl/codegen/gpr_types.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_windows.h \
-    include/grpc/impl/codegen/time.h \
 
 LIBGPR_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGPR_SRC))))
 
@@ -2705,27 +2708,23 @@
     include/grpc/grpc_posix.h \
     include/grpc/grpc_security_constants.h \
     include/grpc/status.h \
-    include/grpc/impl/codegen/byte_buffer.h \
     include/grpc/impl/codegen/byte_buffer_reader.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 \
     include/grpc/impl/codegen/atm_gcc_sync.h \
     include/grpc/impl/codegen/atm_windows.h \
-    include/grpc/impl/codegen/log.h \
+    include/grpc/impl/codegen/gpr_types.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_windows.h \
-    include/grpc/impl/codegen/time.h \
     include/grpc/grpc_security.h \
     include/grpc/census.h \
 
@@ -2954,27 +2953,23 @@
     include/grpc/grpc_posix.h \
     include/grpc/grpc_security_constants.h \
     include/grpc/status.h \
-    include/grpc/impl/codegen/byte_buffer.h \
     include/grpc/impl/codegen/byte_buffer_reader.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 \
     include/grpc/impl/codegen/atm_gcc_sync.h \
     include/grpc/impl/codegen/atm_windows.h \
-    include/grpc/impl/codegen/log.h \
+    include/grpc/impl/codegen/gpr_types.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_windows.h \
-    include/grpc/impl/codegen/time.h \
     include/grpc/grpc_cronet.h \
     include/grpc/grpc_security.h \
 
@@ -3146,27 +3141,23 @@
     include/grpc/grpc_posix.h \
     include/grpc/grpc_security_constants.h \
     include/grpc/status.h \
-    include/grpc/impl/codegen/byte_buffer.h \
     include/grpc/impl/codegen/byte_buffer_reader.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 \
     include/grpc/impl/codegen/atm_gcc_sync.h \
     include/grpc/impl/codegen/atm_windows.h \
-    include/grpc/impl/codegen/log.h \
+    include/grpc/impl/codegen/gpr_types.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_windows.h \
-    include/grpc/impl/codegen/time.h \
 
 LIBGRPC_TEST_UTIL_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC_TEST_UTIL_SRC))))
 
@@ -3409,27 +3400,23 @@
     include/grpc/grpc_posix.h \
     include/grpc/grpc_security_constants.h \
     include/grpc/status.h \
-    include/grpc/impl/codegen/byte_buffer.h \
     include/grpc/impl/codegen/byte_buffer_reader.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 \
     include/grpc/impl/codegen/atm_gcc_sync.h \
     include/grpc/impl/codegen/atm_windows.h \
-    include/grpc/impl/codegen/log.h \
+    include/grpc/impl/codegen/gpr_types.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_windows.h \
-    include/grpc/impl/codegen/time.h \
     include/grpc/census.h \
 
 LIBGRPC_UNSECURE_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC_UNSECURE_SRC))))
@@ -3548,39 +3535,39 @@
 
 
 LIBGRPC++_SRC = \
+    src/cpp/client/insecure_credentials.cc \
     src/cpp/client/secure_credentials.cc \
     src/cpp/common/auth_property_iterator.cc \
     src/cpp/common/secure_auth_context.cc \
     src/cpp/common/secure_channel_arguments.cc \
     src/cpp/common/secure_create_auth_context.cc \
+    src/cpp/server/insecure_server_credentials.cc \
     src/cpp/server/secure_server_credentials.cc \
-    src/cpp/client/channel.cc \
+    src/cpp/client/channel_cc.cc \
     src/cpp/client/client_context.cc \
     src/cpp/client/create_channel.cc \
     src/cpp/client/create_channel_internal.cc \
     src/cpp/client/create_channel_posix.cc \
-    src/cpp/client/credentials.cc \
+    src/cpp/client/credentials_cc.cc \
     src/cpp/client/generic_stub.cc \
-    src/cpp/client/insecure_credentials.cc \
     src/cpp/common/channel_arguments.cc \
     src/cpp/common/channel_filter.cc \
-    src/cpp/common/completion_queue.cc \
+    src/cpp/common/completion_queue_cc.cc \
     src/cpp/common/core_codegen.cc \
     src/cpp/common/rpc_method.cc \
     src/cpp/server/async_generic_service.cc \
     src/cpp/server/create_default_thread_pool.cc \
     src/cpp/server/dynamic_thread_pool.cc \
-    src/cpp/server/insecure_server_credentials.cc \
-    src/cpp/server/server.cc \
     src/cpp/server/server_builder.cc \
+    src/cpp/server/server_cc.cc \
     src/cpp/server/server_context.cc \
     src/cpp/server/server_credentials.cc \
     src/cpp/server/server_posix.cc \
-    src/cpp/util/byte_buffer.cc \
-    src/cpp/util/slice.cc \
+    src/cpp/util/byte_buffer_cc.cc \
+    src/cpp/util/slice_cc.cc \
     src/cpp/util/status.cc \
     src/cpp/util/string_ref.cc \
-    src/cpp/util/time.cc \
+    src/cpp/util/time_cc.cc \
     src/core/lib/channel/channel_args.c \
     src/core/lib/channel/channel_stack.c \
     src/core/lib/channel/channel_stack_builder.c \
@@ -3727,27 +3714,23 @@
     include/grpc/grpc_posix.h \
     include/grpc/grpc_security_constants.h \
     include/grpc/status.h \
-    include/grpc/impl/codegen/byte_buffer.h \
     include/grpc/impl/codegen/byte_buffer_reader.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 \
     include/grpc/impl/codegen/atm_gcc_sync.h \
     include/grpc/impl/codegen/atm_windows.h \
-    include/grpc/impl/codegen/log.h \
+    include/grpc/impl/codegen/gpr_types.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_windows.h \
-    include/grpc/impl/codegen/time.h \
     include/grpc++/impl/codegen/async_stream.h \
     include/grpc++/impl/codegen/async_unary_call.h \
     include/grpc++/impl/codegen/call.h \
@@ -3883,27 +3866,23 @@
     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/byte_buffer_reader.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 \
     include/grpc/impl/codegen/atm_gcc_sync.h \
     include/grpc/impl/codegen/atm_windows.h \
-    include/grpc/impl/codegen/log.h \
+    include/grpc/impl/codegen/gpr_types.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_windows.h \
-    include/grpc/impl/codegen/time.h \
     include/grpc++/impl/codegen/config_protobuf.h \
 
 LIBGRPC++_REFLECTION_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC++_REFLECTION_SRC))))
@@ -4019,7 +3998,7 @@
 
 
 LIBGRPC++_TEST_CONFIG_SRC = \
-    test/cpp/util/test_config.cc \
+    test/cpp/util/test_config_cc.cc \
 
 PUBLIC_HEADERS_CXX += \
 
@@ -4110,27 +4089,23 @@
     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/byte_buffer_reader.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 \
     include/grpc/impl/codegen/atm_gcc_sync.h \
     include/grpc/impl/codegen/atm_windows.h \
-    include/grpc/impl/codegen/log.h \
+    include/grpc/impl/codegen/gpr_types.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_windows.h \
-    include/grpc/impl/codegen/time.h \
     include/grpc++/impl/codegen/proto_utils.h \
     include/grpc++/impl/codegen/config_protobuf.h \
     include/grpc++/impl/codegen/thrift_serializer.h \
@@ -4188,34 +4163,34 @@
 
 
 LIBGRPC++_UNSECURE_SRC = \
+    src/cpp/client/insecure_credentials.cc \
     src/cpp/common/insecure_create_auth_context.cc \
-    src/cpp/client/channel.cc \
+    src/cpp/server/insecure_server_credentials.cc \
+    src/cpp/client/channel_cc.cc \
     src/cpp/client/client_context.cc \
     src/cpp/client/create_channel.cc \
     src/cpp/client/create_channel_internal.cc \
     src/cpp/client/create_channel_posix.cc \
-    src/cpp/client/credentials.cc \
+    src/cpp/client/credentials_cc.cc \
     src/cpp/client/generic_stub.cc \
-    src/cpp/client/insecure_credentials.cc \
     src/cpp/common/channel_arguments.cc \
     src/cpp/common/channel_filter.cc \
-    src/cpp/common/completion_queue.cc \
+    src/cpp/common/completion_queue_cc.cc \
     src/cpp/common/core_codegen.cc \
     src/cpp/common/rpc_method.cc \
     src/cpp/server/async_generic_service.cc \
     src/cpp/server/create_default_thread_pool.cc \
     src/cpp/server/dynamic_thread_pool.cc \
-    src/cpp/server/insecure_server_credentials.cc \
-    src/cpp/server/server.cc \
     src/cpp/server/server_builder.cc \
+    src/cpp/server/server_cc.cc \
     src/cpp/server/server_context.cc \
     src/cpp/server/server_credentials.cc \
     src/cpp/server/server_posix.cc \
-    src/cpp/util/byte_buffer.cc \
-    src/cpp/util/slice.cc \
+    src/cpp/util/byte_buffer_cc.cc \
+    src/cpp/util/slice_cc.cc \
     src/cpp/util/status.cc \
     src/cpp/util/string_ref.cc \
-    src/cpp/util/time.cc \
+    src/cpp/util/time_cc.cc \
     src/core/lib/channel/channel_args.c \
     src/core/lib/channel/channel_stack.c \
     src/core/lib/channel/channel_stack_builder.c \
@@ -4362,27 +4337,23 @@
     include/grpc/grpc_posix.h \
     include/grpc/grpc_security_constants.h \
     include/grpc/status.h \
-    include/grpc/impl/codegen/byte_buffer.h \
     include/grpc/impl/codegen/byte_buffer_reader.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 \
     include/grpc/impl/codegen/atm_gcc_sync.h \
     include/grpc/impl/codegen/atm_windows.h \
-    include/grpc/impl/codegen/log.h \
+    include/grpc/impl/codegen/gpr_types.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_windows.h \
-    include/grpc/impl/codegen/time.h \
     include/grpc++/impl/codegen/async_stream.h \
     include/grpc++/impl/codegen/async_unary_call.h \
     include/grpc++/impl/codegen/call.h \
@@ -6780,6 +6751,7 @@
     test/core/end2end/tests/server_finishes_request.c \
     test/core/end2end/tests/shutdown_finishes_calls.c \
     test/core/end2end/tests/shutdown_finishes_tags.c \
+    test/core/end2end/tests/simple_cacheable_request.c \
     test/core/end2end/tests/simple_delayed_request.c \
     test/core/end2end/tests/simple_metadata.c \
     test/core/end2end/tests/simple_request.c \
@@ -6861,6 +6833,7 @@
     test/core/end2end/tests/server_finishes_request.c \
     test/core/end2end/tests/shutdown_finishes_calls.c \
     test/core/end2end/tests/shutdown_finishes_tags.c \
+    test/core/end2end/tests/simple_cacheable_request.c \
     test/core/end2end/tests/simple_delayed_request.c \
     test/core/end2end/tests/simple_metadata.c \
     test/core/end2end/tests/simple_request.c \
@@ -7885,6 +7858,38 @@
 endif
 
 
+GEN_PERCENT_ENCODING_TABLES_SRC = \
+    tools/codegen/core/gen_percent_encoding_tables.c \
+
+GEN_PERCENT_ENCODING_TABLES_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(GEN_PERCENT_ENCODING_TABLES_SRC))))
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure targets if you don't have OpenSSL.
+
+$(BINDIR)/$(CONFIG)/gen_percent_encoding_tables: openssl_dep_error
+
+else
+
+
+
+$(BINDIR)/$(CONFIG)/gen_percent_encoding_tables: $(GEN_PERCENT_ENCODING_TABLES_OBJS)
+	$(E) "[LD]      Linking $@"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(LD) $(LDFLAGS) $(GEN_PERCENT_ENCODING_TABLES_OBJS) $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/gen_percent_encoding_tables
+
+endif
+
+$(OBJDIR)/$(CONFIG)/tools/codegen/core/gen_percent_encoding_tables.o: 
+
+deps_gen_percent_encoding_tables: $(GEN_PERCENT_ENCODING_TABLES_OBJS:.o=.dep)
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(GEN_PERCENT_ENCODING_TABLES_OBJS:.o=.dep)
+endif
+endif
+
+
 GOAWAY_SERVER_TEST_SRC = \
     test/core/end2end/goaway_server_test.c \
 
@@ -8173,6 +8178,38 @@
 endif
 
 
+GPR_PERCENT_ENCODING_TEST_SRC = \
+    test/core/support/percent_encoding_test.c \
+
+GPR_PERCENT_ENCODING_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(GPR_PERCENT_ENCODING_TEST_SRC))))
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure targets if you don't have OpenSSL.
+
+$(BINDIR)/$(CONFIG)/gpr_percent_encoding_test: openssl_dep_error
+
+else
+
+
+
+$(BINDIR)/$(CONFIG)/gpr_percent_encoding_test: $(GPR_PERCENT_ENCODING_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+	$(E) "[LD]      Linking $@"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(LD) $(LDFLAGS) $(GPR_PERCENT_ENCODING_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/gpr_percent_encoding_test
+
+endif
+
+$(OBJDIR)/$(CONFIG)/test/core/support/percent_encoding_test.o:  $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+deps_gpr_percent_encoding_test: $(GPR_PERCENT_ENCODING_TEST_OBJS:.o=.dep)
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(GPR_PERCENT_ENCODING_TEST_OBJS:.o=.dep)
+endif
+endif
+
+
 GPR_SLICE_BUFFER_TEST_SRC = \
     test/core/support/slice_buffer_test.c \
 
@@ -9901,6 +9938,70 @@
 endif
 
 
+PERCENT_DECODE_FUZZER_SRC = \
+    test/core/support/percent_decode_fuzzer.c \
+
+PERCENT_DECODE_FUZZER_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(PERCENT_DECODE_FUZZER_SRC))))
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure targets if you don't have OpenSSL.
+
+$(BINDIR)/$(CONFIG)/percent_decode_fuzzer: openssl_dep_error
+
+else
+
+
+
+$(BINDIR)/$(CONFIG)/percent_decode_fuzzer: $(PERCENT_DECODE_FUZZER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+	$(E) "[LD]      Linking $@"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(LDXX) $(LDFLAGS) $(PERCENT_DECODE_FUZZER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -lFuzzer -o $(BINDIR)/$(CONFIG)/percent_decode_fuzzer
+
+endif
+
+$(OBJDIR)/$(CONFIG)/test/core/support/percent_decode_fuzzer.o:  $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+deps_percent_decode_fuzzer: $(PERCENT_DECODE_FUZZER_OBJS:.o=.dep)
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(PERCENT_DECODE_FUZZER_OBJS:.o=.dep)
+endif
+endif
+
+
+PERCENT_ENCODE_FUZZER_SRC = \
+    test/core/support/percent_encode_fuzzer.c \
+
+PERCENT_ENCODE_FUZZER_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(PERCENT_ENCODE_FUZZER_SRC))))
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure targets if you don't have OpenSSL.
+
+$(BINDIR)/$(CONFIG)/percent_encode_fuzzer: openssl_dep_error
+
+else
+
+
+
+$(BINDIR)/$(CONFIG)/percent_encode_fuzzer: $(PERCENT_ENCODE_FUZZER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+	$(E) "[LD]      Linking $@"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(LDXX) $(LDFLAGS) $(PERCENT_ENCODE_FUZZER_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -lFuzzer -o $(BINDIR)/$(CONFIG)/percent_encode_fuzzer
+
+endif
+
+$(OBJDIR)/$(CONFIG)/test/core/support/percent_encode_fuzzer.o:  $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+deps_percent_encode_fuzzer: $(PERCENT_ENCODE_FUZZER_OBJS:.o=.dep)
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(PERCENT_ENCODE_FUZZER_OBJS:.o=.dep)
+endif
+endif
+
+
 RESOLVE_ADDRESS_TEST_SRC = \
     test/core/iomgr/resolve_address_test.c \
 
@@ -14182,38 +14283,6 @@
 endif
 
 
-BAD_SSL_ALPN_SERVER_SRC = \
-    test/core/bad_ssl/servers/alpn.c \
-
-BAD_SSL_ALPN_SERVER_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BAD_SSL_ALPN_SERVER_SRC))))
-ifeq ($(NO_SECURE),true)
-
-# You can't build secure targets if you don't have OpenSSL.
-
-$(BINDIR)/$(CONFIG)/bad_ssl_alpn_server: openssl_dep_error
-
-else
-
-
-
-$(BINDIR)/$(CONFIG)/bad_ssl_alpn_server: $(BAD_SSL_ALPN_SERVER_OBJS) $(LIBDIR)/$(CONFIG)/libbad_ssl_test_server.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) $(BAD_SSL_ALPN_SERVER_OBJS) $(LIBDIR)/$(CONFIG)/libbad_ssl_test_server.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)/bad_ssl_alpn_server
-
-endif
-
-$(OBJDIR)/$(CONFIG)/test/core/bad_ssl/servers/alpn.o:  $(LIBDIR)/$(CONFIG)/libbad_ssl_test_server.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
-
-deps_bad_ssl_alpn_server: $(BAD_SSL_ALPN_SERVER_OBJS:.o=.dep)
-
-ifneq ($(NO_SECURE),true)
-ifneq ($(NO_DEPS),true)
--include $(BAD_SSL_ALPN_SERVER_OBJS:.o=.dep)
-endif
-endif
-
-
 BAD_SSL_CERT_SERVER_SRC = \
     test/core/bad_ssl/servers/cert.c \
 
@@ -14246,38 +14315,6 @@
 endif
 
 
-BAD_SSL_ALPN_TEST_SRC = \
-    test/core/bad_ssl/bad_ssl_test.c \
-
-BAD_SSL_ALPN_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(BAD_SSL_ALPN_TEST_SRC))))
-ifeq ($(NO_SECURE),true)
-
-# You can't build secure targets if you don't have OpenSSL.
-
-$(BINDIR)/$(CONFIG)/bad_ssl_alpn_test: openssl_dep_error
-
-else
-
-
-
-$(BINDIR)/$(CONFIG)/bad_ssl_alpn_test: $(BAD_SSL_ALPN_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
-	$(E) "[LD]      Linking $@"
-	$(Q) mkdir -p `dirname $@`
-	$(Q) $(LD) $(LDFLAGS) $(BAD_SSL_ALPN_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/bad_ssl_alpn_test
-
-endif
-
-$(OBJDIR)/$(CONFIG)/test/core/bad_ssl/bad_ssl_test.o:  $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
-
-deps_bad_ssl_alpn_test: $(BAD_SSL_ALPN_TEST_OBJS:.o=.dep)
-
-ifneq ($(NO_SECURE),true)
-ifneq ($(NO_DEPS),true)
--include $(BAD_SSL_ALPN_TEST_OBJS:.o=.dep)
-endif
-endif
-
-
 BAD_SSL_CERT_TEST_SRC = \
     test/core/bad_ssl/bad_ssl_test.c \
 
@@ -15374,6 +15411,76 @@
 endif
 
 
+PERCENT_DECODE_FUZZER_ONE_ENTRY_SRC = \
+    test/core/support/percent_decode_fuzzer.c \
+    test/core/util/one_corpus_entry_fuzzer.c \
+
+PERCENT_DECODE_FUZZER_ONE_ENTRY_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(PERCENT_DECODE_FUZZER_ONE_ENTRY_SRC))))
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure targets if you don't have OpenSSL.
+
+$(BINDIR)/$(CONFIG)/percent_decode_fuzzer_one_entry: openssl_dep_error
+
+else
+
+
+
+$(BINDIR)/$(CONFIG)/percent_decode_fuzzer_one_entry: $(PERCENT_DECODE_FUZZER_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+	$(E) "[LD]      Linking $@"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(LD) $(LDFLAGS) $(PERCENT_DECODE_FUZZER_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/percent_decode_fuzzer_one_entry
+
+endif
+
+$(OBJDIR)/$(CONFIG)/test/core/support/percent_decode_fuzzer.o:  $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+$(OBJDIR)/$(CONFIG)/test/core/util/one_corpus_entry_fuzzer.o:  $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+deps_percent_decode_fuzzer_one_entry: $(PERCENT_DECODE_FUZZER_ONE_ENTRY_OBJS:.o=.dep)
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(PERCENT_DECODE_FUZZER_ONE_ENTRY_OBJS:.o=.dep)
+endif
+endif
+
+
+PERCENT_ENCODE_FUZZER_ONE_ENTRY_SRC = \
+    test/core/support/percent_encode_fuzzer.c \
+    test/core/util/one_corpus_entry_fuzzer.c \
+
+PERCENT_ENCODE_FUZZER_ONE_ENTRY_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(PERCENT_ENCODE_FUZZER_ONE_ENTRY_SRC))))
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure targets if you don't have OpenSSL.
+
+$(BINDIR)/$(CONFIG)/percent_encode_fuzzer_one_entry: openssl_dep_error
+
+else
+
+
+
+$(BINDIR)/$(CONFIG)/percent_encode_fuzzer_one_entry: $(PERCENT_ENCODE_FUZZER_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+	$(E) "[LD]      Linking $@"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(LD) $(LDFLAGS) $(PERCENT_ENCODE_FUZZER_ONE_ENTRY_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/percent_encode_fuzzer_one_entry
+
+endif
+
+$(OBJDIR)/$(CONFIG)/test/core/support/percent_encode_fuzzer.o:  $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+$(OBJDIR)/$(CONFIG)/test/core/util/one_corpus_entry_fuzzer.o:  $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+deps_percent_encode_fuzzer_one_entry: $(PERCENT_ENCODE_FUZZER_ONE_ENTRY_OBJS:.o=.dep)
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(PERCENT_ENCODE_FUZZER_ONE_ENTRY_OBJS:.o=.dep)
+endif
+endif
+
+
 SERVER_FUZZER_ONE_ENTRY_SRC = \
     test/core/end2end/fuzzers/server_fuzzer.c \
     test/core/util/one_corpus_entry_fuzzer.c \
@@ -15536,7 +15643,7 @@
 test/cpp/util/proto_reflection_descriptor_database.cc: $(OPENSSL_DEP)
 test/cpp/util/string_ref_helper.cc: $(OPENSSL_DEP)
 test/cpp/util/subprocess.cc: $(OPENSSL_DEP)
-test/cpp/util/test_config.cc: $(OPENSSL_DEP)
+test/cpp/util/test_config_cc.cc: $(OPENSSL_DEP)
 test/cpp/util/test_credentials_provider.cc: $(OPENSSL_DEP)
 endif
 
diff --git a/Rakefile b/Rakefile
index 5b6f101..cfd4181 100755
--- a/Rakefile
+++ b/Rakefile
@@ -100,13 +100,15 @@
 task 'gem:native' do
   verbose = ENV['V'] || '0'
 
+  grpc_config = ENV['GRPC_CONFIG'] || 'opt'
+
   if RUBY_PLATFORM =~ /darwin/
     FileUtils.touch 'grpc_c.32.ruby'
     FileUtils.touch 'grpc_c.64.ruby'
-    system "rake cross native gem RUBY_CC_VERSION=2.3.0:2.2.2:2.1.5:2.0.0 V=#{verbose}"
+    system "rake cross native gem RUBY_CC_VERSION=2.3.0:2.2.2:2.1.5:2.0.0 V=#{verbose} GRPC_CONFIG=#{grpc_config}"
   else
     Rake::Task['dlls'].execute
-    docker_for_windows "bundle && rake cross native gem RUBY_CC_VERSION=2.3.0:2.2.2:2.1.5:2.0.0 V=#{verbose}"
+    docker_for_windows "bundle && rake cross native gem RUBY_CC_VERSION=2.3.0:2.2.2:2.1.5:2.0.0 V=#{verbose} GRPC_CONFIG=#{grpc_config}"
   end
 end
 
diff --git a/binding.gyp b/binding.gyp
index c2c8bcf..7cc8a58 100644
--- a/binding.gyp
+++ b/binding.gyp
@@ -516,6 +516,7 @@
         'src/core/lib/support/log_posix.c',
         'src/core/lib/support/log_windows.c',
         'src/core/lib/support/murmur_hash.c',
+        'src/core/lib/support/percent_encoding.c',
         'src/core/lib/support/slice.c',
         'src/core/lib/support/slice_buffer.c',
         'src/core/lib/support/stack_lockfree.c',
diff --git a/build.yaml b/build.yaml
index d757846..cd115c7 100644
--- a/build.yaml
+++ b/build.yaml
@@ -83,6 +83,7 @@
   - src/core/lib/support/block_annotate.h
   - src/core/lib/support/env.h
   - src/core/lib/support/murmur_hash.h
+  - src/core/lib/support/percent_encoding.h
   - src/core/lib/support/stack_lockfree.h
   - src/core/lib/support/string.h
   - src/core/lib/support/string_windows.h
@@ -111,6 +112,7 @@
   - src/core/lib/support/log_posix.c
   - src/core/lib/support/log_windows.c
   - src/core/lib/support/murmur_hash.c
+  - src/core/lib/support/percent_encoding.c
   - src/core/lib/support/slice.c
   - src/core/lib/support/slice_buffer.c
   - src/core/lib/support/stack_lockfree.c
@@ -139,20 +141,17 @@
   - gpr_codegen
 - name: gpr_codegen
   public_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_windows.h
-  - include/grpc/impl/codegen/log.h
+  - include/grpc/impl/codegen/gpr_types.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_windows.h
-  - include/grpc/impl/codegen/time.h
 - name: grpc_base
   public_headers:
   - include/grpc/byte_buffer.h
@@ -378,7 +377,6 @@
   - grpc_base
 - name: grpc_codegen
   public_headers:
-  - include/grpc/impl/codegen/byte_buffer.h
   - include/grpc/impl/codegen/byte_buffer_reader.h
   - include/grpc/impl/codegen/compression_types.h
   - include/grpc/impl/codegen/connectivity_state.h
@@ -702,33 +700,31 @@
   - src/cpp/server/dynamic_thread_pool.h
   - src/cpp/server/thread_pool_interface.h
   src:
-  - src/cpp/client/channel.cc
+  - src/cpp/client/channel_cc.cc
   - src/cpp/client/client_context.cc
   - src/cpp/client/create_channel.cc
   - src/cpp/client/create_channel_internal.cc
   - src/cpp/client/create_channel_posix.cc
-  - src/cpp/client/credentials.cc
+  - src/cpp/client/credentials_cc.cc
   - src/cpp/client/generic_stub.cc
-  - src/cpp/client/insecure_credentials.cc
   - src/cpp/common/channel_arguments.cc
   - src/cpp/common/channel_filter.cc
-  - src/cpp/common/completion_queue.cc
+  - src/cpp/common/completion_queue_cc.cc
   - src/cpp/common/core_codegen.cc
   - src/cpp/common/rpc_method.cc
   - src/cpp/server/async_generic_service.cc
   - src/cpp/server/create_default_thread_pool.cc
   - src/cpp/server/dynamic_thread_pool.cc
-  - src/cpp/server/insecure_server_credentials.cc
-  - src/cpp/server/server.cc
   - src/cpp/server/server_builder.cc
+  - src/cpp/server/server_cc.cc
   - src/cpp/server/server_context.cc
   - src/cpp/server/server_credentials.cc
   - src/cpp/server/server_posix.cc
-  - src/cpp/util/byte_buffer.cc
-  - src/cpp/util/slice.cc
+  - src/cpp/util/byte_buffer_cc.cc
+  - src/cpp/util/slice_cc.cc
   - src/cpp/util/status.cc
   - src/cpp/util/string_ref.cc
-  - src/cpp/util/time.cc
+  - src/cpp/util/time_cc.cc
   uses:
   - grpc_base
   - grpc++_codegen_base
@@ -973,11 +969,13 @@
   - src/cpp/common/secure_auth_context.h
   - src/cpp/server/secure_server_credentials.h
   src:
+  - src/cpp/client/insecure_credentials.cc
   - src/cpp/client/secure_credentials.cc
   - src/cpp/common/auth_property_iterator.cc
   - src/cpp/common/secure_auth_context.cc
   - src/cpp/common/secure_channel_arguments.cc
   - src/cpp/common/secure_create_auth_context.cc
+  - src/cpp/server/insecure_server_credentials.cc
   - src/cpp/server/secure_server_credentials.cc
   deps:
   - grpc
@@ -1014,7 +1012,7 @@
   headers:
   - test/cpp/util/test_config.h
   src:
-  - test/cpp/util/test_config.cc
+  - test/cpp/util/test_config_cc.cc
 - name: grpc++_test_util
   build: private
   language: c++
@@ -1048,7 +1046,9 @@
   build: all
   language: c++
   src:
+  - src/cpp/client/insecure_credentials.cc
   - src/cpp/common/insecure_create_auth_context.cc
+  - src/cpp/server/insecure_server_credentials.cc
   deps:
   - gpr
   - grpc_unsecure
@@ -1576,6 +1576,12 @@
   src:
   - tools/codegen/core/gen_legal_metadata_characters.c
   deps: []
+- name: gen_percent_encoding_tables
+  build: tool
+  language: c
+  src:
+  - tools/codegen/core/gen_percent_encoding_tables.c
+  deps: []
 - name: goaway_server_test
   cpu_cost: 0.1
   build: test
@@ -1655,6 +1661,14 @@
   deps:
   - gpr_test_util
   - gpr
+- name: gpr_percent_encoding_test
+  build: test
+  language: c
+  src:
+  - test/core/support/percent_encoding_test.c
+  deps:
+  - gpr_test_util
+  - gpr
 - name: gpr_slice_buffer_test
   build: test
   language: c
@@ -2216,6 +2230,32 @@
   - grpc
   - gpr_test_util
   - gpr
+- name: percent_decode_fuzzer
+  build: fuzzer
+  language: c
+  src:
+  - test/core/support/percent_decode_fuzzer.c
+  deps:
+  - grpc_test_util
+  - grpc
+  - gpr_test_util
+  - gpr
+  corpus_dirs:
+  - test/core/support/percent_decode_corpus
+  maxlen: 32
+- name: percent_encode_fuzzer
+  build: fuzzer
+  language: c
+  src:
+  - test/core/support/percent_encode_fuzzer.c
+  deps:
+  - grpc_test_util
+  - grpc
+  - gpr_test_util
+  - gpr
+  corpus_dirs:
+  - test/core/support/percent_encode_corpus
+  maxlen: 32
 - name: resolve_address_test
   build: test
   language: c
diff --git a/config.m4 b/config.m4
index fe22620..5384585 100644
--- a/config.m4
+++ b/config.m4
@@ -57,6 +57,7 @@
     src/core/lib/support/log_posix.c \
     src/core/lib/support/log_windows.c \
     src/core/lib/support/murmur_hash.c \
+    src/core/lib/support/percent_encoding.c \
     src/core/lib/support/slice.c \
     src/core/lib/support/slice_buffer.c \
     src/core/lib/support/stack_lockfree.c \
diff --git a/doc/http-grpc-status-mapping.md b/doc/http-grpc-status-mapping.md
new file mode 100644
index 0000000..928fe54
--- /dev/null
+++ b/doc/http-grpc-status-mapping.md
@@ -0,0 +1,30 @@
+# HTTP to gRPC Status Code Mapping
+
+Since intermediaries are a common part of HTTP infrastructure some responses to
+gRPC requests may be received that do not include the grpc-status header. In
+some cases mapping error codes from an intermediary allows the gRPC client to
+behave more appropriately to the error situation without overloading the
+semantics of either error code.
+
+This table is to be used _only_ for clients that received a response that did
+not include grpc-status. If grpc-status was provided, it _must_ be used. Servers
+_must not_ use this table to determine an HTTP status code to use; the mappings
+are neither symmetric nor 1-to-1.
+
+| HTTP Status Code           | gRPC Status Code   |
+|----------------------------|--------------------|
+| 400 Bad Request            | INTERNAL           |
+| 401 Unauthorized           | UNAUTHENTICATED    |
+| 403 Forbidden              | PERMISSION\_DENIED |
+| 404 Not Found              | UNIMPLEMENTED      |
+| 429 Too Many Requests      | UNAVAILABLE        |
+| 502 Bad Gateway            | UNAVAILABLE        |
+| 503 Service Unavailable    | UNAVAILABLE        |
+| 504 Gateway Timeout        | UNAVAILABLE        |
+| _All other codes_          | UNKNOWN            |
+
+Technically, 1xx should have the entire header skipped and a subsequent header
+be read. See RFC 7540 §8.1.
+
+200 is UNKNOWN because there should be a grpc-status in case of truly OK
+response.
diff --git a/etc/README.md b/etc/README.md
new file mode 100644
index 0000000..87af44f
--- /dev/null
+++ b/etc/README.md
@@ -0,0 +1,4 @@
+The roots.pem file is periodically generated from:
+https://hg.mozilla.org/mozilla-central/raw-file/tip/security/nss/lib/ckfw/builtins/certdata.txt
+using
+https://github.com/agl/extract-nss-root-certs
diff --git a/examples/csharp/.nuget/packages.config b/examples/csharp/.nuget/packages.config
deleted file mode 100644
index b143730..0000000
--- a/examples/csharp/.nuget/packages.config
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<packages>
-  <package id="Grpc.Tools" version="0.6.0" />
-</packages>
\ No newline at end of file
diff --git a/examples/csharp/helloworld-from-cli/Greeter/project.json b/examples/csharp/helloworld-from-cli/Greeter/project.json
index 8774941..40fba7c 100644
--- a/examples/csharp/helloworld-from-cli/Greeter/project.json
+++ b/examples/csharp/helloworld-from-cli/Greeter/project.json
@@ -5,8 +5,8 @@
     "debugType": "portable",
   },
   "dependencies": {
-    "Google.Protobuf": "3.0.0-beta3",
-    "Grpc": "1.0.0-pre1",
+    "Google.Protobuf": "3.0.0",
+    "Grpc": "1.0.0",
   },
   "frameworks": {
     "net45": {
diff --git a/examples/csharp/helloworld-from-cli/GreeterClient/project.json b/examples/csharp/helloworld-from-cli/GreeterClient/project.json
index c2bf694..74962a9 100644
--- a/examples/csharp/helloworld-from-cli/GreeterClient/project.json
+++ b/examples/csharp/helloworld-from-cli/GreeterClient/project.json
@@ -6,8 +6,8 @@
     "emitEntryPoint": "true"
   },
   "dependencies": {
-    "Google.Protobuf": "3.0.0-beta3",
-    "Grpc": "1.0.0-pre1",
+    "Google.Protobuf": "3.0.0",
+    "Grpc": "1.0.0",
     "Greeter": {
       "target": "project"
     }
diff --git a/examples/csharp/helloworld-from-cli/GreeterServer/project.json b/examples/csharp/helloworld-from-cli/GreeterServer/project.json
index 29a1067..33af254 100644
--- a/examples/csharp/helloworld-from-cli/GreeterServer/project.json
+++ b/examples/csharp/helloworld-from-cli/GreeterServer/project.json
@@ -6,8 +6,8 @@
     "emitEntryPoint": "true"
   },
   "dependencies": {
-    "Google.Protobuf": "3.0.0-beta3",
-    "Grpc": "1.0.0-pre1",
+    "Google.Protobuf": "3.0.0",
+    "Grpc": "1.0.0",
     "Greeter": {
       "target": "project"
     }
diff --git a/examples/csharp/helloworld/Greeter/Greeter.csproj b/examples/csharp/helloworld/Greeter/Greeter.csproj
index 20b85db..54a41d1 100644
--- a/examples/csharp/helloworld/Greeter/Greeter.csproj
+++ b/examples/csharp/helloworld/Greeter/Greeter.csproj
@@ -33,16 +33,16 @@
   <ItemGroup>
     <Reference Include="Google.Protobuf, Version=3.0.0.0, Culture=neutral, PublicKeyToken=a7d26565bac4d604, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\Google.Protobuf.3.0.0-beta3\lib\portable-net45+netcore45+wpa81+wp8\Google.Protobuf.dll</HintPath>
+      <HintPath>..\packages\Google.Protobuf.3.0.0\lib\net45\Google.Protobuf.dll</HintPath>
     </Reference>
     <Reference Include="Grpc.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d754f35622e28bad, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\Grpc.Core.0.15.0\lib\net45\Grpc.Core.dll</HintPath>
+      <HintPath>..\packages\Grpc.Core.1.0.0\lib\net45\Grpc.Core.dll</HintPath>
     </Reference>
     <Reference Include="System" />
     <Reference Include="System.Interactive.Async, Version=1.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\Ix-Async.1.2.5\lib\net45\System.Interactive.Async.dll</HintPath>
+      <HintPath>..\packages\System.Interactive.Async.3.0.0\lib\net45\System.Interactive.Async.dll</HintPath>
     </Reference>
   </ItemGroup>
   <ItemGroup>
@@ -61,11 +61,11 @@
     <None Include="packages.config" />
   </ItemGroup>
   <ItemGroup />
-  <Import Project="..\packages\Grpc.Core.0.15.0\build\net45\Grpc.Core.targets" Condition="Exists('..\packages\Grpc.Core.0.15.0\build\net45\Grpc.Core.targets')" />
+  <Import Project="..\packages\Grpc.Core.1.0.0\build\net45\Grpc.Core.targets" Condition="Exists('..\packages\Grpc.Core.1.0.0\build\net45\Grpc.Core.targets')" />
   <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('..\packages\Grpc.Core.0.15.0\build\net45\Grpc.Core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Grpc.Core.0.15.0\build\net45\Grpc.Core.targets'))" />
+    <Error Condition="!Exists('..\packages\Grpc.Core.1.0.0\build\net45\Grpc.Core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Grpc.Core.1.0.0\build\net45\Grpc.Core.targets'))" />
   </Target>
-</Project>
\ No newline at end of file
+</Project>
diff --git a/examples/csharp/helloworld/Greeter/packages.config b/examples/csharp/helloworld/Greeter/packages.config
index c94bb87..46f7dda 100644
--- a/examples/csharp/helloworld/Greeter/packages.config
+++ b/examples/csharp/helloworld/Greeter/packages.config
@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="utf-8"?>
 <packages>
-  <package id="Google.Protobuf" version="3.0.0-beta3" targetFramework="net45" />
-  <package id="Grpc" version="0.15.0" targetFramework="net45" />
-  <package id="Grpc.Core" version="0.15.0" targetFramework="net45" />
-  <package id="Ix-Async" version="1.2.5" targetFramework="net45" />
-  <package id="Grpc.Tools" version="0.15.0" targetFramework="net45" />
-</packages>
\ No newline at end of file
+  <package id="Google.Protobuf" version="3.0.0" targetFramework="net45" />
+  <package id="Grpc" version="1.0.0" targetFramework="net45" />
+  <package id="Grpc.Core" version="1.0.0" targetFramework="net45" />
+  <package id="System.Interactive.Async" version="3.0.0" targetFramework="net45" />
+  <package id="Grpc.Tools" version="1.0.0" targetFramework="net45" />
+</packages>
diff --git a/examples/csharp/helloworld/GreeterClient/GreeterClient.csproj b/examples/csharp/helloworld/GreeterClient/GreeterClient.csproj
index 2b38ce2..43d85e1 100644
--- a/examples/csharp/helloworld/GreeterClient/GreeterClient.csproj
+++ b/examples/csharp/helloworld/GreeterClient/GreeterClient.csproj
@@ -33,16 +33,16 @@
   <ItemGroup>
     <Reference Include="Google.Protobuf, Version=3.0.0.0, Culture=neutral, PublicKeyToken=a7d26565bac4d604, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\Google.Protobuf.3.0.0-beta3\lib\portable-net45+netcore45+wpa81+wp8\Google.Protobuf.dll</HintPath>
+      <HintPath>..\packages\Google.Protobuf.3.0.0\lib\net45\Google.Protobuf.dll</HintPath>
     </Reference>
     <Reference Include="Grpc.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d754f35622e28bad, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\Grpc.Core.0.15.0\lib\net45\Grpc.Core.dll</HintPath>
+      <HintPath>..\packages\Grpc.Core.1.0.0\lib\net45\Grpc.Core.dll</HintPath>
     </Reference>
     <Reference Include="System" />
     <Reference Include="System.Interactive.Async, Version=1.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\Ix-Async.1.2.5\lib\net45\System.Interactive.Async.dll</HintPath>
+      <HintPath>..\packages\System.Interactive.Async.3.0.0\lib\net45\System.Interactive.Async.dll</HintPath>
     </Reference>
   </ItemGroup>
   <ItemGroup>
@@ -59,11 +59,11 @@
   <ItemGroup>
     <None Include="packages.config" />
   </ItemGroup>
-  <Import Project="..\packages\Grpc.Core.0.15.0\build\net45\Grpc.Core.targets" Condition="Exists('..\packages\Grpc.Core.0.15.0\build\net45\Grpc.Core.targets')" />
+  <Import Project="..\packages\Grpc.Core.1.0.0\build\net45\Grpc.Core.targets" Condition="Exists('..\packages\Grpc.Core.1.0.0\build\net45\Grpc.Core.targets')" />
   <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('..\packages\Grpc.Core.0.15.0\build\net45\Grpc.Core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Grpc.Core.0.15.0\build\net45\Grpc.Core.targets'))" />
+    <Error Condition="!Exists('..\packages\Grpc.Core.1.0.0\build\net45\Grpc.Core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Grpc.Core.1.0.0\build\net45\Grpc.Core.targets'))" />
   </Target>
-</Project>
\ No newline at end of file
+</Project>
diff --git a/examples/csharp/helloworld/GreeterClient/packages.config b/examples/csharp/helloworld/GreeterClient/packages.config
index ff9d6bb..9f55097 100644
--- a/examples/csharp/helloworld/GreeterClient/packages.config
+++ b/examples/csharp/helloworld/GreeterClient/packages.config
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <packages>
-  <package id="Google.Protobuf" version="3.0.0-beta3" targetFramework="net45" />
-  <package id="Grpc" version="0.15.0" targetFramework="net45" />
-  <package id="Grpc.Core" version="0.15.0" targetFramework="net45" />
-  <package id="Ix-Async" version="1.2.5" targetFramework="net45" />
-</packages>
\ No newline at end of file
+  <package id="Google.Protobuf" version="3.0.0" targetFramework="net45" />
+  <package id="Grpc" version="1.0.0" targetFramework="net45" />
+  <package id="Grpc.Core" version="1.0.0" targetFramework="net45" />
+  <package id="System.Interactive.Async" version="3.0.0" targetFramework="net45" />
+</packages>
diff --git a/examples/csharp/helloworld/GreeterServer/GreeterServer.csproj b/examples/csharp/helloworld/GreeterServer/GreeterServer.csproj
index 43c6336..5a3457f 100644
--- a/examples/csharp/helloworld/GreeterServer/GreeterServer.csproj
+++ b/examples/csharp/helloworld/GreeterServer/GreeterServer.csproj
@@ -33,16 +33,16 @@
   <ItemGroup>
     <Reference Include="Google.Protobuf, Version=3.0.0.0, Culture=neutral, PublicKeyToken=a7d26565bac4d604, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\Google.Protobuf.3.0.0-beta3\lib\portable-net45+netcore45+wpa81+wp8\Google.Protobuf.dll</HintPath>
+      <HintPath>..\packages\Google.Protobuf.3.0.0\lib\net45\Google.Protobuf.dll</HintPath>
     </Reference>
     <Reference Include="Grpc.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d754f35622e28bad, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\Grpc.Core.0.15.0\lib\net45\Grpc.Core.dll</HintPath>
+      <HintPath>..\packages\Grpc.Core.1.0.0\lib\net45\Grpc.Core.dll</HintPath>
     </Reference>
     <Reference Include="System" />
     <Reference Include="System.Interactive.Async, Version=1.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\Ix-Async.1.2.5\lib\net45\System.Interactive.Async.dll</HintPath>
+      <HintPath>..\packages\System.Interactive.Async.3.0.0\lib\net45\System.Interactive.Async.dll</HintPath>
     </Reference>
   </ItemGroup>
   <ItemGroup>
@@ -59,11 +59,11 @@
   <ItemGroup>
     <None Include="packages.config" />
   </ItemGroup>
-  <Import Project="..\packages\Grpc.Core.0.15.0\build\net45\Grpc.Core.targets" Condition="Exists('..\packages\Grpc.Core.0.15.0\build\net45\Grpc.Core.targets')" />
+  <Import Project="..\packages\Grpc.Core.1.0.0\build\net45\Grpc.Core.targets" Condition="Exists('..\packages\Grpc.Core.1.0.0\build\net45\Grpc.Core.targets')" />
   <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('..\packages\Grpc.Core.0.15.0\build\net45\Grpc.Core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Grpc.Core.0.15.0\build\net45\Grpc.Core.targets'))" />
+    <Error Condition="!Exists('..\packages\Grpc.Core.1.0.0\build\net45\Grpc.Core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Grpc.Core.1.0.0\build\net45\Grpc.Core.targets'))" />
   </Target>
-</Project>
\ No newline at end of file
+</Project>
diff --git a/examples/csharp/helloworld/GreeterServer/packages.config b/examples/csharp/helloworld/GreeterServer/packages.config
index ff9d6bb..9f55097 100644
--- a/examples/csharp/helloworld/GreeterServer/packages.config
+++ b/examples/csharp/helloworld/GreeterServer/packages.config
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <packages>
-  <package id="Google.Protobuf" version="3.0.0-beta3" targetFramework="net45" />
-  <package id="Grpc" version="0.15.0" targetFramework="net45" />
-  <package id="Grpc.Core" version="0.15.0" targetFramework="net45" />
-  <package id="Ix-Async" version="1.2.5" targetFramework="net45" />
-</packages>
\ No newline at end of file
+  <package id="Google.Protobuf" version="3.0.0" targetFramework="net45" />
+  <package id="Grpc" version="1.0.0" targetFramework="net45" />
+  <package id="Grpc.Core" version="1.0.0" targetFramework="net45" />
+  <package id="System.Interactive.Async" version="3.0.0" targetFramework="net45" />
+</packages>
diff --git a/examples/csharp/helloworld/generate_protos.bat b/examples/csharp/helloworld/generate_protos.bat
index a952bb4..28b7395 100644
--- a/examples/csharp/helloworld/generate_protos.bat
+++ b/examples/csharp/helloworld/generate_protos.bat
@@ -34,8 +34,8 @@
 @rem enter this directory
 cd /d %~dp0
 
-set TOOLS_PATH=packages\Grpc.Tools.0.15.0\tools\windows_x86
+set TOOLS_PATH=packages\Grpc.Tools.1.0.0\tools\windows_x86
 
 %TOOLS_PATH%\protoc.exe -I../../protos --csharp_out Greeter  ../../protos/helloworld.proto --grpc_out Greeter --plugin=protoc-gen-grpc=%TOOLS_PATH%\grpc_csharp_plugin.exe
 
-endlocal
\ No newline at end of file
+endlocal
diff --git a/examples/csharp/route_guide/RouteGuide/RouteGuide.csproj b/examples/csharp/route_guide/RouteGuide/RouteGuide.csproj
index 942d94f..02bca2f 100644
--- a/examples/csharp/route_guide/RouteGuide/RouteGuide.csproj
+++ b/examples/csharp/route_guide/RouteGuide/RouteGuide.csproj
@@ -33,11 +33,11 @@
   <ItemGroup>
     <Reference Include="Google.Protobuf, Version=3.0.0.0, Culture=neutral, PublicKeyToken=a7d26565bac4d604, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\Google.Protobuf.3.0.0-beta3\lib\portable-net45+netcore45+wpa81+wp8\Google.Protobuf.dll</HintPath>
+      <HintPath>..\packages\Google.Protobuf.3.0.0\lib\net45\Google.Protobuf.dll</HintPath>
     </Reference>
     <Reference Include="Grpc.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d754f35622e28bad, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\Grpc.Core.0.15.0\lib\net45\Grpc.Core.dll</HintPath>
+      <HintPath>..\packages\Grpc.Core.1.0.0\lib\net45\Grpc.Core.dll</HintPath>
     </Reference>
     <Reference Include="Newtonsoft.Json, Version=7.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
@@ -52,7 +52,7 @@
     <Reference Include="System.Xml" />
     <Reference Include="System.Interactive.Async, Version=1.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\Ix-Async.1.2.5\lib\net45\System.Interactive.Async.dll</HintPath>
+      <HintPath>..\packages\System.Interactive.Async.3.0.0\lib\net45\System.Interactive.Async.dll</HintPath>
     </Reference>
   </ItemGroup>
   <ItemGroup>
@@ -74,12 +74,12 @@
     </None>
   </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
-  <Import Project="..\packages\Grpc.Core.0.15.0\build\net45\Grpc.Core.targets" Condition="Exists('..\packages\Grpc.Core.0.15.0\build\net45\Grpc.Core.targets')" />
+  <Import Project="..\packages\Grpc.Core.1.0.0\build\net45\Grpc.Core.targets" Condition="Exists('..\packages\Grpc.Core.1.0.0\build\net45\Grpc.Core.targets')" />
   <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('..\packages\Grpc.Core.0.15.0\build\net45\Grpc.Core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Grpc.Core.0.15.0\build\net45\Grpc.Core.targets'))" />
+    <Error Condition="!Exists('..\packages\Grpc.Core.1.0.0\build\net45\Grpc.Core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Grpc.Core.1.0.0\build\net45\Grpc.Core.targets'))" />
   </Target>
   <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
        Other similar extension points exist, see Microsoft.Common.targets.
@@ -88,4 +88,4 @@
   <Target Name="AfterBuild">
   </Target>
   -->
-</Project>
\ No newline at end of file
+</Project>
diff --git a/examples/csharp/route_guide/RouteGuide/packages.config b/examples/csharp/route_guide/RouteGuide/packages.config
index b962a72..4e8d3f2 100644
--- a/examples/csharp/route_guide/RouteGuide/packages.config
+++ b/examples/csharp/route_guide/RouteGuide/packages.config
@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="utf-8"?>
 <packages>
-  <package id="Google.Protobuf" version="3.0.0-beta3" targetFramework="net45" />
-  <package id="Grpc" version="0.15.0" targetFramework="net45" />
-  <package id="Grpc.Core" version="0.15.0" targetFramework="net45" />
-  <package id="Ix-Async" version="1.2.5" targetFramework="net45" />
+  <package id="Google.Protobuf" version="3.0.0" targetFramework="net45" />
+  <package id="Grpc" version="1.0.0" targetFramework="net45" />
+  <package id="Grpc.Core" version="1.0.0" targetFramework="net45" />
+  <package id="System.Interactive.Async" version="3.0.0" targetFramework="net45" />
   <package id="Newtonsoft.Json" version="7.0.1" targetFramework="net45" />
-</packages>
\ No newline at end of file
+</packages>
diff --git a/examples/csharp/route_guide/RouteGuideClient/RouteGuideClient.csproj b/examples/csharp/route_guide/RouteGuideClient/RouteGuideClient.csproj
index 6f5c0a5..4792c52 100644
--- a/examples/csharp/route_guide/RouteGuideClient/RouteGuideClient.csproj
+++ b/examples/csharp/route_guide/RouteGuideClient/RouteGuideClient.csproj
@@ -35,11 +35,11 @@
   <ItemGroup>
     <Reference Include="Google.Protobuf, Version=3.0.0.0, Culture=neutral, PublicKeyToken=a7d26565bac4d604, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\Google.Protobuf.3.0.0-beta3\lib\portable-net45+netcore45+wpa81+wp8\Google.Protobuf.dll</HintPath>
+      <HintPath>..\packages\Google.Protobuf.3.0.0\lib\net45\Google.Protobuf.dll</HintPath>
     </Reference>
     <Reference Include="Grpc.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d754f35622e28bad, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\Grpc.Core.0.15.0\lib\net45\Grpc.Core.dll</HintPath>
+      <HintPath>..\packages\Grpc.Core.1.0.0\lib\net45\Grpc.Core.dll</HintPath>
     </Reference>
     <Reference Include="Newtonsoft.Json, Version=7.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
@@ -49,7 +49,7 @@
     <Reference Include="System.Core" />
     <Reference Include="System.Interactive.Async, Version=1.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\Ix-Async.1.2.5\lib\net45\System.Interactive.Async.dll</HintPath>
+      <HintPath>..\packages\System.Interactive.Async.3.0.0\lib\net45\System.Interactive.Async.dll</HintPath>
     </Reference>
     <Reference Include="System.Xml.Linq" />
     <Reference Include="System.Data.DataSetExtensions" />
@@ -71,12 +71,12 @@
     </ProjectReference>
   </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
-  <Import Project="..\packages\Grpc.Core.0.15.0\build\net45\Grpc.Core.targets" Condition="Exists('..\packages\Grpc.Core.0.15.0\build\net45\Grpc.Core.targets')" />
+  <Import Project="..\packages\Grpc.Core.1.0.0\build\net45\Grpc.Core.targets" Condition="Exists('..\packages\Grpc.Core.1.0.0\build\net45\Grpc.Core.targets')" />
   <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('..\packages\Grpc.Core.0.15.0\build\net45\Grpc.Core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Grpc.Core.0.15.0\build\net45\Grpc.Core.targets'))" />
+    <Error Condition="!Exists('..\packages\Grpc.Core.1.0.0\build\net45\Grpc.Core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Grpc.Core.1.0.0\build\net45\Grpc.Core.targets'))" />
   </Target>
   <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
        Other similar extension points exist, see Microsoft.Common.targets.
@@ -85,4 +85,4 @@
   <Target Name="AfterBuild">
   </Target>
   -->
-</Project>
\ No newline at end of file
+</Project>
diff --git a/examples/csharp/route_guide/RouteGuideClient/packages.config b/examples/csharp/route_guide/RouteGuideClient/packages.config
index b962a72..4e8d3f2 100644
--- a/examples/csharp/route_guide/RouteGuideClient/packages.config
+++ b/examples/csharp/route_guide/RouteGuideClient/packages.config
@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="utf-8"?>
 <packages>
-  <package id="Google.Protobuf" version="3.0.0-beta3" targetFramework="net45" />
-  <package id="Grpc" version="0.15.0" targetFramework="net45" />
-  <package id="Grpc.Core" version="0.15.0" targetFramework="net45" />
-  <package id="Ix-Async" version="1.2.5" targetFramework="net45" />
+  <package id="Google.Protobuf" version="3.0.0" targetFramework="net45" />
+  <package id="Grpc" version="1.0.0" targetFramework="net45" />
+  <package id="Grpc.Core" version="1.0.0" targetFramework="net45" />
+  <package id="System.Interactive.Async" version="3.0.0" targetFramework="net45" />
   <package id="Newtonsoft.Json" version="7.0.1" targetFramework="net45" />
-</packages>
\ No newline at end of file
+</packages>
diff --git a/examples/csharp/route_guide/RouteGuideServer/RouteGuideServer.csproj b/examples/csharp/route_guide/RouteGuideServer/RouteGuideServer.csproj
index 4ffc5cc..b35e576 100644
--- a/examples/csharp/route_guide/RouteGuideServer/RouteGuideServer.csproj
+++ b/examples/csharp/route_guide/RouteGuideServer/RouteGuideServer.csproj
@@ -35,11 +35,11 @@
   <ItemGroup>
     <Reference Include="Google.Protobuf, Version=3.0.0.0, Culture=neutral, PublicKeyToken=a7d26565bac4d604, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\Google.Protobuf.3.0.0-beta3\lib\portable-net45+netcore45+wpa81+wp8\Google.Protobuf.dll</HintPath>
+      <HintPath>..\packages\Google.Protobuf.3.0.0\lib\net45\Google.Protobuf.dll</HintPath>
     </Reference>
     <Reference Include="Grpc.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d754f35622e28bad, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\Grpc.Core.0.15.0\lib\net45\Grpc.Core.dll</HintPath>
+      <HintPath>..\packages\Grpc.Core.1.0.0\lib\net45\Grpc.Core.dll</HintPath>
     </Reference>
     <Reference Include="Newtonsoft.Json, Version=7.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
@@ -54,7 +54,7 @@
     <Reference Include="System.Xml" />
     <Reference Include="System.Interactive.Async, Version=1.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
       <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\Ix-Async.1.2.5\lib\net45\System.Interactive.Async.dll</HintPath>
+      <HintPath>..\packages\System.Interactive.Async.3.0.0\lib\net45\System.Interactive.Async.dll</HintPath>
     </Reference>
   </ItemGroup>
   <ItemGroup>
@@ -72,12 +72,12 @@
     </ProjectReference>
   </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
-  <Import Project="..\packages\Grpc.Core.0.15.0\build\net45\Grpc.Core.targets" Condition="Exists('..\packages\Grpc.Core.0.15.0\build\net45\Grpc.Core.targets')" />
+  <Import Project="..\packages\Grpc.Core.1.0.0\build\net45\Grpc.Core.targets" Condition="Exists('..\packages\Grpc.Core.1.0.0\build\net45\Grpc.Core.targets')" />
   <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('..\packages\Grpc.Core.0.15.0\build\net45\Grpc.Core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Grpc.Core.0.15.0\build\net45\Grpc.Core.targets'))" />
+    <Error Condition="!Exists('..\packages\Grpc.Core.1.0.0\build\net45\Grpc.Core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Grpc.Core.1.0.0\build\net45\Grpc.Core.targets'))" />
   </Target>
   <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
        Other similar extension points exist, see Microsoft.Common.targets.
@@ -86,4 +86,4 @@
   <Target Name="AfterBuild">
   </Target>
   -->
-</Project>
\ No newline at end of file
+</Project>
diff --git a/examples/csharp/route_guide/RouteGuideServer/packages.config b/examples/csharp/route_guide/RouteGuideServer/packages.config
index 916fe4c..a742eb2 100644
--- a/examples/csharp/route_guide/RouteGuideServer/packages.config
+++ b/examples/csharp/route_guide/RouteGuideServer/packages.config
@@ -1,9 +1,9 @@
 <?xml version="1.0" encoding="utf-8"?>
 <packages>
-  <package id="Google.Protobuf" version="3.0.0-beta3" targetFramework="net45" />
-  <package id="Grpc" version="0.15.0" targetFramework="net45" />
-  <package id="Grpc.Core" version="0.15.0" targetFramework="net45" />
-  <package id="Ix-Async" version="1.2.5" targetFramework="net45" />
+  <package id="Google.Protobuf" version="3.0.0" targetFramework="net45" />
+  <package id="Grpc" version="1.0.0" targetFramework="net45" />
+  <package id="Grpc.Core" version="1.0.0" targetFramework="net45" />
+  <package id="System.Interactive.Async" version="3.0.0" targetFramework="net45" />
   <package id="Newtonsoft.Json" version="7.0.1" targetFramework="net45" />
-  <package id="Grpc.Tools" version="0.15.0" targetFramework="net45" />
-</packages>
\ No newline at end of file
+  <package id="Grpc.Tools" version="1.0.0" targetFramework="net45" />
+</packages>
diff --git a/examples/csharp/route_guide/generate_protos.bat b/examples/csharp/route_guide/generate_protos.bat
index dbdbd1f..69f5e0f 100644
--- a/examples/csharp/route_guide/generate_protos.bat
+++ b/examples/csharp/route_guide/generate_protos.bat
@@ -34,8 +34,8 @@
 @rem enter this directory
 cd /d %~dp0
 
-set TOOLS_PATH=packages\Grpc.Tools.0.15.0\tools\windows_x86
+set TOOLS_PATH=packages\Grpc.Tools.1.0.0\tools\windows_x86
 
 %TOOLS_PATH%\protoc.exe -I../../protos --csharp_out RouteGuide  ../../protos/route_guide.proto --grpc_out RouteGuide --plugin=protoc-gen-grpc=%TOOLS_PATH%\grpc_csharp_plugin.exe
 
-endlocal
\ No newline at end of file
+endlocal
diff --git a/examples/node/README.md b/examples/node/README.md
index b92ca38..f29236c 100644
--- a/examples/node/README.md
+++ b/examples/node/README.md
@@ -39,7 +39,7 @@
    $ # from this directory
    $ node ./dynamic_codegen/greeter_client.js
    $ # OR
-   $ node ./dynamic_codegen/greeter_client.js
+   $ node ./static_codegen/greeter_client.js
    ```
 
 TUTORIAL
diff --git a/examples/python/README.md b/examples/python/README.md
index 9992baa..d801d0d 100644
--- a/examples/python/README.md
+++ b/examples/python/README.md
@@ -1,56 +1 @@
-gRPC in 3 minutes (Python)
-========================
-
-Background
--------------
-For this sample, we've already generated the server and client stubs from
-[helloworld.proto][] and we'll be using a specific reference platform.
-
-
-Install gRPC:
-```sh
-  $ pip install grpcio
-```
-Or, to install it system wide:
-```sh
-  $ sudo pip install grpcio
-```
-
-If you're on Windows, make sure you installed the `pip.exe` component when you
-installed Python. Invoke as above but with `pip.exe` instead of `pip` (you may
-also need to invoke from a `cmd.exe` ran as administrator):
-```sh
-  $ pip.exe install grpcio
-```
-
-Download the example
-```sh
-  $ # Clone the repository to get the example code:
-  $ git clone https://github.com/grpc/grpc
-  $ # Navigate to the "hello, world" Python example:
-  $ cd grpc/examples/python/helloworld
-  ```
-
-Try it!
--------
-
-- Run the server
-
-  ```sh
-  $ python2.7 greeter_server.py &
-  ```
-
-- Run the client
-
-  ```sh
-  $ python2.7 greeter_client.py
-  ```
-
-Tutorial
---------
-
-You can find a more detailed tutorial in [gRPC Basics: Python][]
-
-[helloworld.proto]:../protos/helloworld.proto
-[Install gRPC Python]:../../src/python#installation
-[gRPC Basics: Python]:http://www.grpc.io/docs/tutorials/basic/python.html
+[This code's documentation lives on the grpc.io site.](http://www.grpc.io/docs/quickstart/python.html)
diff --git a/examples/python/helloworld/README.md b/examples/python/helloworld/README.md
index e889863..d801d0d 100644
--- a/examples/python/helloworld/README.md
+++ b/examples/python/helloworld/README.md
@@ -1 +1 @@
-[This code's documentation lives on the grpc.io site.](http://www.grpc.io/docs)
+[This code's documentation lives on the grpc.io site.](http://www.grpc.io/docs/quickstart/python.html)
diff --git a/examples/python/multiplex/README.md b/examples/python/multiplex/README.md
index bad3a42..5931be3 100644
--- a/examples/python/multiplex/README.md
+++ b/examples/python/multiplex/README.md
@@ -1 +1,3 @@
 An example showing two stubs sharing a channel and two servicers sharing a server.
+
+More complete documentation lives at [grpc.io](http://www.grpc.io/docs/tutorials/basic/python.html).
diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec
index fe58303..1fd96bb 100644
--- a/gRPC-Core.podspec
+++ b/gRPC-Core.podspec
@@ -144,20 +144,17 @@
                       'include/grpc/support/tls_msvc.h',
                       'include/grpc/support/tls_pthread.h',
                       'include/grpc/support/useful.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_windows.h',
-                      'include/grpc/impl/codegen/log.h',
+                      'include/grpc/impl/codegen/gpr_types.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_windows.h',
-                      'include/grpc/impl/codegen/time.h',
                       'include/grpc/byte_buffer.h',
                       'include/grpc/byte_buffer_reader.h',
                       'include/grpc/compression.h',
@@ -165,27 +162,23 @@
                       'include/grpc/grpc_posix.h',
                       'include/grpc/grpc_security_constants.h',
                       'include/grpc/status.h',
-                      'include/grpc/impl/codegen/byte_buffer.h',
                       'include/grpc/impl/codegen/byte_buffer_reader.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',
                       'include/grpc/impl/codegen/atm_gcc_sync.h',
                       'include/grpc/impl/codegen/atm_windows.h',
-                      'include/grpc/impl/codegen/log.h',
+                      'include/grpc/impl/codegen/gpr_types.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_windows.h',
-                      'include/grpc/impl/codegen/time.h',
                       'include/grpc/grpc_security.h',
                       'include/grpc/census.h'
   end
@@ -201,6 +194,7 @@
                       'src/core/lib/support/block_annotate.h',
                       'src/core/lib/support/env.h',
                       'src/core/lib/support/murmur_hash.h',
+                      'src/core/lib/support/percent_encoding.h',
                       'src/core/lib/support/stack_lockfree.h',
                       'src/core/lib/support/string.h',
                       'src/core/lib/support/string_windows.h',
@@ -228,6 +222,7 @@
                       'src/core/lib/support/log_posix.c',
                       'src/core/lib/support/log_windows.c',
                       'src/core/lib/support/murmur_hash.c',
+                      'src/core/lib/support/percent_encoding.c',
                       'src/core/lib/support/slice.c',
                       'src/core/lib/support/slice_buffer.c',
                       'src/core/lib/support/stack_lockfree.c',
@@ -607,6 +602,7 @@
                               'src/core/lib/support/block_annotate.h',
                               'src/core/lib/support/env.h',
                               'src/core/lib/support/murmur_hash.h',
+                              'src/core/lib/support/percent_encoding.h',
                               'src/core/lib/support/stack_lockfree.h',
                               'src/core/lib/support/string.h',
                               'src/core/lib/support/string_windows.h',
diff --git a/grpc.def b/grpc.def
index d6ddd33..6e905a2 100644
--- a/grpc.def
+++ b/grpc.def
@@ -1,4 +1,14 @@
 EXPORTS
+    grpc_raw_byte_buffer_create
+    grpc_raw_compressed_byte_buffer_create
+    grpc_byte_buffer_copy
+    grpc_byte_buffer_length
+    grpc_byte_buffer_destroy
+    grpc_byte_buffer_reader_init
+    grpc_byte_buffer_reader_destroy
+    grpc_byte_buffer_reader_next
+    grpc_byte_buffer_reader_readall
+    grpc_raw_byte_buffer_from_reader
     census_initialize
     census_shutdown
     census_supported
@@ -126,94 +136,6 @@
     gpr_free_aligned
     gpr_set_allocation_functions
     gpr_get_allocation_functions
-    grpc_raw_byte_buffer_create
-    grpc_raw_compressed_byte_buffer_create
-    grpc_byte_buffer_copy
-    grpc_byte_buffer_length
-    grpc_byte_buffer_destroy
-    grpc_byte_buffer_reader_init
-    grpc_byte_buffer_reader_destroy
-    grpc_byte_buffer_reader_next
-    grpc_byte_buffer_reader_readall
-    grpc_raw_byte_buffer_from_reader
-    gpr_log
-    gpr_log_message
-    gpr_set_log_verbosity
-    gpr_log_verbosity_init
-    gpr_set_log_function
-    gpr_slice_ref
-    gpr_slice_unref
-    gpr_slice_new
-    gpr_slice_new_with_user_data
-    gpr_slice_new_with_len
-    gpr_slice_malloc
-    gpr_slice_from_copied_string
-    gpr_slice_from_copied_buffer
-    gpr_slice_from_static_string
-    gpr_slice_sub
-    gpr_slice_sub_no_ref
-    gpr_slice_split_tail
-    gpr_slice_split_head
-    gpr_empty_slice
-    gpr_slice_cmp
-    gpr_slice_str_cmp
-    gpr_slice_buffer_init
-    gpr_slice_buffer_destroy
-    gpr_slice_buffer_add
-    gpr_slice_buffer_add_indexed
-    gpr_slice_buffer_addn
-    gpr_slice_buffer_tiny_add
-    gpr_slice_buffer_pop
-    gpr_slice_buffer_reset_and_unref
-    gpr_slice_buffer_swap
-    gpr_slice_buffer_move_into
-    gpr_slice_buffer_trim_end
-    gpr_slice_buffer_move_first
-    gpr_slice_buffer_take_first
-    gpr_mu_init
-    gpr_mu_destroy
-    gpr_mu_lock
-    gpr_mu_unlock
-    gpr_mu_trylock
-    gpr_cv_init
-    gpr_cv_destroy
-    gpr_cv_wait
-    gpr_cv_signal
-    gpr_cv_broadcast
-    gpr_once_init
-    gpr_event_init
-    gpr_event_set
-    gpr_event_get
-    gpr_event_wait
-    gpr_ref_init
-    gpr_ref
-    gpr_ref_non_zero
-    gpr_refn
-    gpr_unref
-    gpr_stats_init
-    gpr_stats_inc
-    gpr_stats_read
-    gpr_time_0
-    gpr_inf_future
-    gpr_inf_past
-    gpr_time_init
-    gpr_now
-    gpr_convert_clock_type
-    gpr_time_cmp
-    gpr_time_max
-    gpr_time_min
-    gpr_time_add
-    gpr_time_sub
-    gpr_time_from_micros
-    gpr_time_from_nanos
-    gpr_time_from_millis
-    gpr_time_from_seconds
-    gpr_time_from_minutes
-    gpr_time_from_hours
-    gpr_time_to_millis
-    gpr_time_similar
-    gpr_sleep_until
-    gpr_timespec_to_micros
     gpr_avl_create
     gpr_avl_ref
     gpr_avl_unref
@@ -250,7 +172,41 @@
     gpr_histogram_merge_contents
     gpr_join_host_port
     gpr_split_host_port
+    gpr_log
+    gpr_log_message
+    gpr_set_log_verbosity
+    gpr_log_verbosity_init
+    gpr_set_log_function
     gpr_format_message
+    gpr_slice_ref
+    gpr_slice_unref
+    gpr_slice_new
+    gpr_slice_new_with_user_data
+    gpr_slice_new_with_len
+    gpr_slice_malloc
+    gpr_slice_from_copied_string
+    gpr_slice_from_copied_buffer
+    gpr_slice_from_static_string
+    gpr_slice_sub
+    gpr_slice_sub_no_ref
+    gpr_slice_split_tail
+    gpr_slice_split_head
+    gpr_empty_slice
+    gpr_slice_cmp
+    gpr_slice_str_cmp
+    gpr_slice_buffer_init
+    gpr_slice_buffer_destroy
+    gpr_slice_buffer_add
+    gpr_slice_buffer_add_indexed
+    gpr_slice_buffer_addn
+    gpr_slice_buffer_tiny_add
+    gpr_slice_buffer_pop
+    gpr_slice_buffer_reset_and_unref
+    gpr_slice_buffer_swap
+    gpr_slice_buffer_move_into
+    gpr_slice_buffer_trim_end
+    gpr_slice_buffer_move_first
+    gpr_slice_buffer_take_first
     gpr_strdup
     gpr_asprintf
     gpr_subprocess_binary_extension
@@ -258,6 +214,29 @@
     gpr_subprocess_destroy
     gpr_subprocess_join
     gpr_subprocess_interrupt
+    gpr_mu_init
+    gpr_mu_destroy
+    gpr_mu_lock
+    gpr_mu_unlock
+    gpr_mu_trylock
+    gpr_cv_init
+    gpr_cv_destroy
+    gpr_cv_wait
+    gpr_cv_signal
+    gpr_cv_broadcast
+    gpr_once_init
+    gpr_event_init
+    gpr_event_set
+    gpr_event_get
+    gpr_event_wait
+    gpr_ref_init
+    gpr_ref
+    gpr_ref_non_zero
+    gpr_refn
+    gpr_unref
+    gpr_stats_init
+    gpr_stats_inc
+    gpr_stats_read
     gpr_thd_new
     gpr_thd_options_default
     gpr_thd_options_set_detached
@@ -266,3 +245,24 @@
     gpr_thd_options_is_joinable
     gpr_thd_currentid
     gpr_thd_join
+    gpr_time_0
+    gpr_inf_future
+    gpr_inf_past
+    gpr_time_init
+    gpr_now
+    gpr_convert_clock_type
+    gpr_time_cmp
+    gpr_time_max
+    gpr_time_min
+    gpr_time_add
+    gpr_time_sub
+    gpr_time_from_micros
+    gpr_time_from_nanos
+    gpr_time_from_millis
+    gpr_time_from_seconds
+    gpr_time_from_minutes
+    gpr_time_from_hours
+    gpr_time_to_millis
+    gpr_time_similar
+    gpr_sleep_until
+    gpr_timespec_to_micros
diff --git a/grpc.gemspec b/grpc.gemspec
index f505b11..7f608e0 100755
--- a/grpc.gemspec
+++ b/grpc.gemspec
@@ -29,6 +29,7 @@
 
   s.add_dependency 'google-protobuf', '~> 3.0'
   s.add_dependency 'googleauth',      '~> 0.5.1'
+  s.add_dependency 'concurrent-ruby'
 
   s.add_development_dependency 'bundler',            '~> 1.9'
   s.add_development_dependency 'facter',             '~> 2.4'
@@ -71,25 +72,23 @@
   s.files += %w( include/grpc/support/tls_msvc.h )
   s.files += %w( include/grpc/support/tls_pthread.h )
   s.files += %w( include/grpc/support/useful.h )
-  s.files += %w( include/grpc/impl/codegen/alloc.h )
   s.files += %w( include/grpc/impl/codegen/atm.h )
   s.files += %w( include/grpc/impl/codegen/atm_gcc_atomic.h )
   s.files += %w( include/grpc/impl/codegen/atm_gcc_sync.h )
   s.files += %w( include/grpc/impl/codegen/atm_windows.h )
-  s.files += %w( include/grpc/impl/codegen/log.h )
+  s.files += %w( include/grpc/impl/codegen/gpr_types.h )
   s.files += %w( include/grpc/impl/codegen/port_platform.h )
   s.files += %w( include/grpc/impl/codegen/slice.h )
-  s.files += %w( include/grpc/impl/codegen/slice_buffer.h )
   s.files += %w( include/grpc/impl/codegen/sync.h )
   s.files += %w( include/grpc/impl/codegen/sync_generic.h )
   s.files += %w( include/grpc/impl/codegen/sync_posix.h )
   s.files += %w( include/grpc/impl/codegen/sync_windows.h )
-  s.files += %w( include/grpc/impl/codegen/time.h )
   s.files += %w( src/core/lib/profiling/timers.h )
   s.files += %w( src/core/lib/support/backoff.h )
   s.files += %w( src/core/lib/support/block_annotate.h )
   s.files += %w( src/core/lib/support/env.h )
   s.files += %w( src/core/lib/support/murmur_hash.h )
+  s.files += %w( src/core/lib/support/percent_encoding.h )
   s.files += %w( src/core/lib/support/stack_lockfree.h )
   s.files += %w( src/core/lib/support/string.h )
   s.files += %w( src/core/lib/support/string_windows.h )
@@ -117,6 +116,7 @@
   s.files += %w( src/core/lib/support/log_posix.c )
   s.files += %w( src/core/lib/support/log_windows.c )
   s.files += %w( src/core/lib/support/murmur_hash.c )
+  s.files += %w( src/core/lib/support/percent_encoding.c )
   s.files += %w( src/core/lib/support/slice.c )
   s.files += %w( src/core/lib/support/slice_buffer.c )
   s.files += %w( src/core/lib/support/stack_lockfree.c )
@@ -148,27 +148,23 @@
   s.files += %w( include/grpc/grpc_posix.h )
   s.files += %w( include/grpc/grpc_security_constants.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/byte_buffer_reader.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/impl/codegen/alloc.h )
   s.files += %w( include/grpc/impl/codegen/atm.h )
   s.files += %w( include/grpc/impl/codegen/atm_gcc_atomic.h )
   s.files += %w( include/grpc/impl/codegen/atm_gcc_sync.h )
   s.files += %w( include/grpc/impl/codegen/atm_windows.h )
-  s.files += %w( include/grpc/impl/codegen/log.h )
+  s.files += %w( include/grpc/impl/codegen/gpr_types.h )
   s.files += %w( include/grpc/impl/codegen/port_platform.h )
   s.files += %w( include/grpc/impl/codegen/slice.h )
-  s.files += %w( include/grpc/impl/codegen/slice_buffer.h )
   s.files += %w( include/grpc/impl/codegen/sync.h )
   s.files += %w( include/grpc/impl/codegen/sync_generic.h )
   s.files += %w( include/grpc/impl/codegen/sync_posix.h )
   s.files += %w( include/grpc/impl/codegen/sync_windows.h )
-  s.files += %w( include/grpc/impl/codegen/time.h )
   s.files += %w( include/grpc/grpc_security.h )
   s.files += %w( include/grpc/census.h )
   s.files += %w( src/core/lib/channel/channel_args.h )
diff --git a/include/grpc++/ext/reflection.grpc.pb.h b/include/grpc++/ext/reflection.grpc.pb.h
index 0b4ef86..064117e 100644
--- a/include/grpc++/ext/reflection.grpc.pb.h
+++ b/include/grpc++/ext/reflection.grpc.pb.h
@@ -74,6 +74,7 @@
 
 #include <grpc++/impl/codegen/async_stream.h>
 #include <grpc++/impl/codegen/async_unary_call.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/service_type.h>
@@ -174,6 +175,7 @@
       return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
     }
   };
+  typedef Service StreamedUnaryService;
 };
 
 }  // namespace v1alpha
diff --git a/include/grpc++/impl/codegen/async_unary_call.h b/include/grpc++/impl/codegen/async_unary_call.h
index 5ceab73..87c94d6 100644
--- a/include/grpc++/impl/codegen/async_unary_call.h
+++ b/include/grpc++/impl/codegen/async_unary_call.h
@@ -40,7 +40,6 @@
 #include <grpc++/impl/codegen/server_context.h>
 #include <grpc++/impl/codegen/service_type.h>
 #include <grpc++/impl/codegen/status.h>
-#include <grpc/impl/codegen/log.h>
 
 namespace grpc {
 
diff --git a/include/grpc++/impl/codegen/call.h b/include/grpc++/impl/codegen/call.h
index dfac177..4221357 100644
--- a/include/grpc++/impl/codegen/call.h
+++ b/include/grpc++/impl/codegen/call.h
@@ -48,7 +48,6 @@
 #include <grpc++/impl/codegen/status.h>
 #include <grpc++/impl/codegen/string_ref.h>
 
-#include <grpc/impl/codegen/alloc.h>
 #include <grpc/impl/codegen/compression_types.h>
 #include <grpc/impl/codegen/grpc_types.h>
 
@@ -662,10 +661,10 @@
     call_hook_->PerformOpsOnCall(ops, this);
   }
 
-  grpc_call* call() { return call_; }
-  CompletionQueue* cq() { return cq_; }
+  grpc_call* call() const { return call_; }
+  CompletionQueue* cq() const { return cq_; }
 
-  int max_message_size() { return max_message_size_; }
+  int max_message_size() const { return max_message_size_; }
 
  private:
   CallHook* call_hook_;
diff --git a/include/grpc++/impl/codegen/client_context.h b/include/grpc++/impl/codegen/client_context.h
index d77ca4c..387d807 100644
--- a/include/grpc++/impl/codegen/client_context.h
+++ b/include/grpc++/impl/codegen/client_context.h
@@ -62,9 +62,7 @@
 #include <grpc++/impl/codegen/sync.h>
 #include <grpc++/impl/codegen/time.h>
 #include <grpc/impl/codegen/compression_types.h>
-#include <grpc/impl/codegen/log.h>
 #include <grpc/impl/codegen/propagation_bits.h>
-#include <grpc/impl/codegen/time.h>
 
 struct census_context;
 struct grpc_call;
@@ -225,6 +223,9 @@
   /// EXPERIMENTAL: Set this request to be idempotent
   void set_idempotent(bool idempotent) { idempotent_ = idempotent; }
 
+  /// EXPERIMENTAL: Set this request to be cacheable
+  void set_cacheable(bool cacheable) { cacheable_ = cacheable; }
+
   /// EXPERIMENTAL: Trigger fail-fast or not on this request
   void set_fail_fast(bool fail_fast) { fail_fast_ = fail_fast; }
 
@@ -346,7 +347,8 @@
 
   uint32_t initial_metadata_flags() const {
     return (idempotent_ ? GRPC_INITIAL_METADATA_IDEMPOTENT_REQUEST : 0) |
-           (fail_fast_ ? 0 : GRPC_INITIAL_METADATA_IGNORE_CONNECTIVITY);
+           (fail_fast_ ? 0 : GRPC_INITIAL_METADATA_IGNORE_CONNECTIVITY) |
+           (cacheable_ ? GRPC_INITIAL_METADATA_CACHEABLE_REQUEST : 0);
   }
 
   grpc::string authority() { return authority_; }
@@ -354,6 +356,7 @@
   bool initial_metadata_received_;
   bool fail_fast_;
   bool idempotent_;
+  bool cacheable_;
   std::shared_ptr<Channel> channel_;
   grpc::mutex mu_;
   grpc_call* call_;
diff --git a/include/grpc++/impl/codegen/completion_queue.h b/include/grpc++/impl/codegen/completion_queue.h
index 03009e0..29bc97f 100644
--- a/include/grpc++/impl/codegen/completion_queue.h
+++ b/include/grpc++/impl/codegen/completion_queue.h
@@ -52,7 +52,6 @@
 #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;
 
@@ -68,8 +67,10 @@
 class ServerReader;
 template <class W>
 class ServerWriter;
+namespace internal {
 template <class W, class R>
-class ServerReaderWriter;
+class ServerReaderWriterBody;
+}
 template <class ServiceType, class RequestType, class ResponseType>
 class RpcMethodHandler;
 template <class ServiceType, class RequestType, class ResponseType>
@@ -178,15 +179,15 @@
   template <class W>
   friend class ::grpc::ServerWriter;
   template <class W, class R>
-  friend class ::grpc::ServerReaderWriter;
+  friend class ::grpc::internal::ServerReaderWriterBody;
   template <class ServiceType, class RequestType, class ResponseType>
   friend class RpcMethodHandler;
   template <class ServiceType, class RequestType, class ResponseType>
   friend class ClientStreamingHandler;
   template <class ServiceType, class RequestType, class ResponseType>
   friend class ServerStreamingHandler;
-  template <class ServiceType, class RequestType, class ResponseType>
-  friend class BidiStreamingHandler;
+  template <class Streamer, bool WriteNeeded>
+  friend class TemplatedBidiStreamingHandler;
   friend class UnknownMethodHandler;
   friend class ::grpc::Server;
   friend class ::grpc::ServerContext;
@@ -217,7 +218,7 @@
   /// Performs a single polling pluck on \a tag.
   /// \warning Must not be mixed with calls to \a Next.
   void TryPluck(CompletionQueueTag* tag) {
-    auto deadline = gpr_time_0(GPR_CLOCK_REALTIME);
+    auto deadline = g_core_codegen_interface->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;
diff --git a/include/grpc++/impl/codegen/core_codegen.h b/include/grpc++/impl/codegen/core_codegen.h
index 2586b94..0ce009e 100644
--- a/include/grpc++/impl/codegen/core_codegen.h
+++ b/include/grpc++/impl/codegen/core_codegen.h
@@ -55,6 +55,17 @@
   void* gpr_malloc(size_t size) GRPC_OVERRIDE;
   void gpr_free(void* p) GRPC_OVERRIDE;
 
+  void gpr_mu_init(gpr_mu* mu) GRPC_OVERRIDE;
+  void gpr_mu_destroy(gpr_mu* mu) GRPC_OVERRIDE;
+  void gpr_mu_lock(gpr_mu* mu) GRPC_OVERRIDE;
+  void gpr_mu_unlock(gpr_mu* mu) GRPC_OVERRIDE;
+  void gpr_cv_init(gpr_cv* cv) GRPC_OVERRIDE;
+  void gpr_cv_destroy(gpr_cv* cv) GRPC_OVERRIDE;
+  int gpr_cv_wait(gpr_cv* cv, gpr_mu* mu,
+                  gpr_timespec abs_deadline) GRPC_OVERRIDE;
+  void gpr_cv_signal(gpr_cv* cv) GRPC_OVERRIDE;
+  void gpr_cv_broadcast(gpr_cv* cv) GRPC_OVERRIDE;
+
   void grpc_byte_buffer_destroy(grpc_byte_buffer* bb) GRPC_OVERRIDE;
 
   int grpc_byte_buffer_reader_init(grpc_byte_buffer_reader* reader,
@@ -78,6 +89,7 @@
   void grpc_metadata_array_destroy(grpc_metadata_array* array) GRPC_OVERRIDE;
 
   gpr_timespec gpr_inf_future(gpr_clock_type type) GRPC_OVERRIDE;
+  gpr_timespec gpr_time_0(gpr_clock_type type) GRPC_OVERRIDE;
 
   virtual const Status& ok() GRPC_OVERRIDE;
   virtual const Status& cancelled() GRPC_OVERRIDE;
diff --git a/include/grpc++/impl/codegen/core_codegen_interface.h b/include/grpc++/impl/codegen/core_codegen_interface.h
index f9a8f9b..68851f1 100644
--- a/include/grpc++/impl/codegen/core_codegen_interface.h
+++ b/include/grpc++/impl/codegen/core_codegen_interface.h
@@ -36,7 +36,13 @@
 
 #include <grpc++/impl/codegen/config.h>
 #include <grpc++/impl/codegen/status.h>
+#include <grpc/impl/codegen/byte_buffer_reader.h>
 #include <grpc/impl/codegen/grpc_types.h>
+#include <grpc/impl/codegen/sync.h>
+
+extern "C" {
+struct grpc_byte_buffer;
+}
 
 namespace grpc {
 
@@ -63,6 +69,17 @@
   virtual void* gpr_malloc(size_t size) = 0;
   virtual void gpr_free(void* p) = 0;
 
+  virtual void gpr_mu_init(gpr_mu* mu) = 0;
+  virtual void gpr_mu_destroy(gpr_mu* mu) = 0;
+  virtual void gpr_mu_lock(gpr_mu* mu) = 0;
+  virtual void gpr_mu_unlock(gpr_mu* mu) = 0;
+  virtual void gpr_cv_init(gpr_cv* cv) = 0;
+  virtual void gpr_cv_destroy(gpr_cv* cv) = 0;
+  virtual int gpr_cv_wait(gpr_cv* cv, gpr_mu* mu,
+                          gpr_timespec abs_deadline) = 0;
+  virtual void gpr_cv_signal(gpr_cv* cv) = 0;
+  virtual void gpr_cv_broadcast(gpr_cv* cv) = 0;
+
   virtual void grpc_byte_buffer_destroy(grpc_byte_buffer* bb) = 0;
 
   virtual int grpc_byte_buffer_reader_init(grpc_byte_buffer_reader* reader,
@@ -89,6 +106,7 @@
   virtual const Status& cancelled() = 0;
 
   virtual gpr_timespec gpr_inf_future(gpr_clock_type type) = 0;
+  virtual gpr_timespec gpr_time_0(gpr_clock_type type) = 0;
 };
 
 extern CoreCodegenInterface* g_core_codegen_interface;
diff --git a/include/grpc++/impl/codegen/grpc_library.h b/include/grpc++/impl/codegen/grpc_library.h
index 3cdc6f3..2b11aff 100644
--- a/include/grpc++/impl/codegen/grpc_library.h
+++ b/include/grpc++/impl/codegen/grpc_library.h
@@ -35,7 +35,6 @@
 #define GRPCXX_IMPL_CODEGEN_GRPC_LIBRARY_H
 
 #include <grpc++/impl/codegen/core_codegen_interface.h>
-#include <grpc/impl/codegen/log.h>
 
 namespace grpc {
 
diff --git a/include/grpc++/impl/codegen/method_handler_impl.h b/include/grpc++/impl/codegen/method_handler_impl.h
index 2f4be64..d989263 100644
--- a/include/grpc++/impl/codegen/method_handler_impl.h
+++ b/include/grpc++/impl/codegen/method_handler_impl.h
@@ -167,20 +167,22 @@
 };
 
 // A wrapper class of an application provided bidi-streaming handler.
-template <class ServiceType, class RequestType, class ResponseType>
-class BidiStreamingHandler : public MethodHandler {
+// This also applies to server-streamed implementation of a unary method
+// with the additional requirement that such methods must have done a
+// write for status to be ok
+// Since this is used by more than 1 class, the service is not passed in.
+// Instead, it is expected to be an implicitly-captured argument of func
+// (through bind or something along those lines)
+template <class Streamer, bool WriteNeeded>
+class TemplatedBidiStreamingHandler : public MethodHandler {
  public:
-  BidiStreamingHandler(
-      std::function<Status(ServiceType*, ServerContext*,
-                           ServerReaderWriter<ResponseType, RequestType>*)>
-          func,
-      ServiceType* service)
-      : func_(func), service_(service) {}
+  TemplatedBidiStreamingHandler(
+      std::function<Status(ServerContext*, Streamer*)> func)
+      : func_(func), write_needed_(WriteNeeded) {}
 
   void RunHandler(const HandlerParameter& param) GRPC_FINAL {
-    ServerReaderWriter<ResponseType, RequestType> stream(param.call,
-                                                         param.server_context);
-    Status status = func_(service_, param.server_context, &stream);
+    Streamer stream(param.call, param.server_context);
+    Status status = func_(param.server_context, &stream);
 
     CallOpSet<CallOpSendInitialMetadata, CallOpServerSendStatus> ops;
     if (!param.server_context->sent_initial_metadata_) {
@@ -189,6 +191,12 @@
       if (param.server_context->compression_level_set()) {
         ops.set_compression_level(param.server_context->compression_level());
       }
+      if (write_needed_ && status.ok()) {
+        // If we needed a write but never did one, we need to mark the
+        // status as a fail
+        status = Status(StatusCode::INTERNAL,
+                        "Service did not provide response message");
+      }
     }
     ops.ServerSendStatus(param.server_context->trailing_metadata_, status);
     param.call->PerformOps(&ops);
@@ -196,10 +204,36 @@
   }
 
  private:
-  std::function<Status(ServiceType*, ServerContext*,
-                       ServerReaderWriter<ResponseType, RequestType>*)>
-      func_;
-  ServiceType* service_;
+  std::function<Status(ServerContext*, Streamer*)> func_;
+  const bool write_needed_;
+};
+
+template <class ServiceType, class RequestType, class ResponseType>
+class BidiStreamingHandler
+    : public TemplatedBidiStreamingHandler<
+          ServerReaderWriter<ResponseType, RequestType>, false> {
+ public:
+  BidiStreamingHandler(
+      std::function<Status(ServiceType*, ServerContext*,
+                           ServerReaderWriter<ResponseType, RequestType>*)>
+          func,
+      ServiceType* service)
+      : TemplatedBidiStreamingHandler<
+            ServerReaderWriter<ResponseType, RequestType>, false>(std::bind(
+            func, service, std::placeholders::_1, std::placeholders::_2)) {}
+};
+
+template <class RequestType, class ResponseType>
+class StreamedUnaryHandler
+    : public TemplatedBidiStreamingHandler<
+          ServerUnaryStreamer<RequestType, ResponseType>, true> {
+ public:
+  explicit StreamedUnaryHandler(
+      std::function<Status(ServerContext*,
+                           ServerUnaryStreamer<RequestType, ResponseType>*)>
+          func)
+      : TemplatedBidiStreamingHandler<
+            ServerUnaryStreamer<RequestType, ResponseType>, true>(func) {}
 };
 
 // Handle unknown method by returning UNIMPLEMENTED error.
diff --git a/include/grpc++/impl/codegen/proto_utils.h b/include/grpc++/impl/codegen/proto_utils.h
index d4599c5..d2e0f6f 100644
--- a/include/grpc++/impl/codegen/proto_utils.h
+++ b/include/grpc++/impl/codegen/proto_utils.h
@@ -40,9 +40,8 @@
 #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/byte_buffer_reader.h>
-#include <grpc/impl/codegen/log.h>
+#include <grpc/impl/codegen/grpc_types.h>
 #include <grpc/impl/codegen/slice.h>
 
 namespace grpc {
diff --git a/include/grpc++/impl/codegen/rpc_method.h b/include/grpc++/impl/codegen/rpc_method.h
index 39cb4f7..4897428 100644
--- a/include/grpc++/impl/codegen/rpc_method.h
+++ b/include/grpc++/impl/codegen/rpc_method.h
@@ -60,11 +60,12 @@
 
   const char* name() const { return name_; }
   RpcType method_type() const { return method_type_; }
+  void SetMethodType(RpcType type) { method_type_ = type; }
   void* channel_tag() const { return channel_tag_; }
 
  private:
   const char* const name_;
-  const RpcType method_type_;
+  RpcType method_type_;
   void* const channel_tag_;
 };
 
diff --git a/include/grpc++/impl/codegen/rpc_service_method.h b/include/grpc++/impl/codegen/rpc_service_method.h
index 8b1f026..88da096 100644
--- a/include/grpc++/impl/codegen/rpc_service_method.h
+++ b/include/grpc++/impl/codegen/rpc_service_method.h
@@ -43,7 +43,10 @@
 #include <grpc++/impl/codegen/config.h>
 #include <grpc++/impl/codegen/rpc_method.h>
 #include <grpc++/impl/codegen/status.h>
-#include <grpc/impl/codegen/byte_buffer.h>
+
+extern "C" {
+struct grpc_byte_buffer;
+}
 
 namespace grpc {
 class ServerContext;
@@ -82,6 +85,7 @@
   // if MethodHandler is nullptr, then this is an async method
   MethodHandler* handler() const { return handler_.get(); }
   void ResetHandler() { handler_.reset(); }
+  void SetHandler(MethodHandler* handler) { handler_.reset(handler); }
 
  private:
   void* server_tag_;
diff --git a/include/grpc++/impl/codegen/server_context.h b/include/grpc++/impl/codegen/server_context.h
index c9d1f4d..bce8d2c 100644
--- a/include/grpc++/impl/codegen/server_context.h
+++ b/include/grpc++/impl/codegen/server_context.h
@@ -43,7 +43,6 @@
 #include <grpc++/impl/codegen/string_ref.h>
 #include <grpc++/impl/codegen/time.h>
 #include <grpc/impl/codegen/compression_types.h>
-#include <grpc/impl/codegen/time.h>
 
 struct gpr_timespec;
 struct grpc_metadata;
@@ -65,8 +64,10 @@
 class ServerReader;
 template <class W>
 class ServerWriter;
+namespace internal {
 template <class W, class R>
-class ServerReaderWriter;
+class ServerReaderWriterBody;
+}
 template <class ServiceType, class RequestType, class ResponseType>
 class RpcMethodHandler;
 template <class ServiceType, class RequestType, class ResponseType>
@@ -187,15 +188,15 @@
   template <class W>
   friend class ::grpc::ServerWriter;
   template <class W, class R>
-  friend class ::grpc::ServerReaderWriter;
+  friend class ::grpc::internal::ServerReaderWriterBody;
   template <class ServiceType, class RequestType, class ResponseType>
   friend class RpcMethodHandler;
   template <class ServiceType, class RequestType, class ResponseType>
   friend class ClientStreamingHandler;
   template <class ServiceType, class RequestType, class ResponseType>
   friend class ServerStreamingHandler;
-  template <class ServiceType, class RequestType, class ResponseType>
-  friend class BidiStreamingHandler;
+  template <class Streamer, bool WriteNeeded>
+  friend class TemplatedBidiStreamingHandler;
   friend class UnknownMethodHandler;
   friend class ::grpc::ClientContext;
 
diff --git a/include/grpc++/impl/codegen/server_interface.h b/include/grpc++/impl/codegen/server_interface.h
index 3a3e052..1f1b714 100644
--- a/include/grpc++/impl/codegen/server_interface.h
+++ b/include/grpc++/impl/codegen/server_interface.h
@@ -52,6 +52,8 @@
 class Service;
 class ThreadPoolInterface;
 
+extern CoreCodegenInterface* g_core_codegen_interface;
+
 /// Models a gRPC server.
 ///
 /// Servers are configured and started via \a grpc::ServerBuilder.
@@ -78,7 +80,10 @@
   /// All completion queue associated with the server (for example, for async
   /// serving) must be shutdown *after* this method has returned:
   /// See \a ServerBuilder::AddCompletionQueue for details.
-  void Shutdown() { ShutdownInternal(gpr_inf_future(GPR_CLOCK_MONOTONIC)); }
+  void Shutdown() {
+    ShutdownInternal(
+        g_core_codegen_interface->gpr_inf_future(GPR_CLOCK_MONOTONIC));
+  }
 
   /// Block waiting for all work to complete.
   ///
diff --git a/include/grpc++/impl/codegen/service_type.h b/include/grpc++/impl/codegen/service_type.h
index c19dfc7..72b2225 100644
--- a/include/grpc++/impl/codegen/service_type.h
+++ b/include/grpc++/impl/codegen/service_type.h
@@ -147,6 +147,17 @@
     methods_[index].reset();
   }
 
+  void MarkMethodStreamedUnary(int index,
+                               MethodHandler* streamed_unary_method) {
+    GPR_CODEGEN_ASSERT(methods_[index] && methods_[index]->handler() &&
+                       "Cannot mark an async or generic method Streamed Unary");
+    methods_[index]->SetHandler(streamed_unary_method);
+
+    // From the server's point of view, streamed unary is a special
+    // case of BIDI_STREAMING that has 1 read and 1 write, in that order.
+    methods_[index]->SetMethodType(::grpc::RpcMethod::BIDI_STREAMING);
+  }
+
  private:
   friend class Server;
   friend class ServerInterface;
diff --git a/include/grpc++/impl/codegen/sync_no_cxx11.h b/include/grpc++/impl/codegen/sync_no_cxx11.h
index 55c059e..87a6594 100644
--- a/include/grpc++/impl/codegen/sync_no_cxx11.h
+++ b/include/grpc++/impl/codegen/sync_no_cxx11.h
@@ -34,18 +34,20 @@
 #ifndef GRPCXX_IMPL_CODEGEN_SYNC_NO_CXX11_H
 #define GRPCXX_IMPL_CODEGEN_SYNC_NO_CXX11_H
 
-#include <grpc/impl/codegen/sync.h>
+#include <grpc++/impl/codegen/core_codegen_interface.h>
 
 namespace grpc {
 
+extern CoreCodegenInterface *g_core_codegen_interface;
+
 template <class mutex>
 class lock_guard;
 class condition_variable;
 
 class mutex {
  public:
-  mutex() { gpr_mu_init(&mu_); }
-  ~mutex() { gpr_mu_destroy(&mu_); }
+  mutex() { g_core_codegen_interface->gpr_mu_init(&mu_); }
+  ~mutex() { g_core_codegen_interface->gpr_mu_destroy(&mu_); }
 
  private:
   ::gpr_mu mu_;
@@ -57,16 +59,18 @@
 template <class mutex>
 class lock_guard {
  public:
-  lock_guard(mutex &mu) : mu_(mu), locked(true) { gpr_mu_lock(&mu.mu_); }
+  lock_guard(mutex &mu) : mu_(mu), locked(true) {
+    g_core_codegen_interface->gpr_mu_lock(&mu.mu_);
+  }
   ~lock_guard() { unlock_internal(); }
 
  protected:
   void lock_internal() {
-    if (!locked) gpr_mu_lock(&mu_.mu_);
+    if (!locked) g_core_codegen_interface->gpr_mu_lock(&mu_.mu_);
     locked = true;
   }
   void unlock_internal() {
-    if (locked) gpr_mu_unlock(&mu_.mu_);
+    if (locked) g_core_codegen_interface->gpr_mu_unlock(&mu_.mu_);
     locked = false;
   }
 
@@ -86,15 +90,17 @@
 
 class condition_variable {
  public:
-  condition_variable() { gpr_cv_init(&cv_); }
-  ~condition_variable() { gpr_cv_destroy(&cv_); }
+  condition_variable() { g_core_codegen_interface->gpr_cv_init(&cv_); }
+  ~condition_variable() { g_core_codegen_interface->gpr_cv_destroy(&cv_); }
   void wait(lock_guard<mutex> &mu) {
     mu.locked = false;
-    gpr_cv_wait(&cv_, &mu.mu_.mu_, gpr_inf_future(GPR_CLOCK_REALTIME));
+    g_core_codegen_interface->gpr_cv_wait(
+        &cv_, &mu.mu_.mu_,
+        g_core_codegen_interface->gpr_inf_future(GPR_CLOCK_REALTIME));
     mu.locked = true;
   }
-  void notify_one() { gpr_cv_signal(&cv_); }
-  void notify_all() { gpr_cv_broadcast(&cv_); }
+  void notify_one() { g_core_codegen_interface->gpr_cv_signal(&cv_); }
+  void notify_all() { g_core_codegen_interface->gpr_cv_broadcast(&cv_); }
 
  private:
   gpr_cv cv_;
diff --git a/include/grpc++/impl/codegen/sync_stream.h b/include/grpc++/impl/codegen/sync_stream.h
index 7601cea..aba1298 100644
--- a/include/grpc++/impl/codegen/sync_stream.h
+++ b/include/grpc++/impl/codegen/sync_stream.h
@@ -42,7 +42,6 @@
 #include <grpc++/impl/codegen/server_context.h>
 #include <grpc++/impl/codegen/service_type.h>
 #include <grpc++/impl/codegen/status.h>
-#include <grpc/impl/codegen/log.h>
 
 namespace grpc {
 
@@ -79,6 +78,9 @@
  public:
   virtual ~ReaderInterface() {}
 
+  /// Upper bound on the next message size available for reading on this stream
+  virtual bool NextMessageSize(uint32_t* sz) = 0;
+
   /// Blocking read a message and parse to \a msg. Returns \a true on success.
   /// This is thread-safe with respect to \a Write or \WritesDone methods on
   /// the same stream. It should not be called concurrently with another \a
@@ -157,6 +159,11 @@
     cq_.Pluck(&ops);  /// status ignored
   }
 
+  bool NextMessageSize(uint32_t* sz) GRPC_OVERRIDE {
+    *sz = call_.max_message_size();
+    return true;
+  }
+
   bool Read(R* msg) GRPC_OVERRIDE {
     CallOpSet<CallOpRecvInitialMetadata, CallOpRecvMessage<R>> ops;
     if (!context_->initial_metadata_received_) {
@@ -302,6 +309,11 @@
     cq_.Pluck(&ops);  // status ignored
   }
 
+  bool NextMessageSize(uint32_t* sz) GRPC_OVERRIDE {
+    *sz = call_.max_message_size();
+    return true;
+  }
+
   bool Read(R* msg) GRPC_OVERRIDE {
     CallOpSet<CallOpRecvInitialMetadata, CallOpRecvMessage<R>> ops;
     if (!context_->initial_metadata_received_) {
@@ -369,6 +381,11 @@
     call_->cq()->Pluck(&ops);
   }
 
+  bool NextMessageSize(uint32_t* sz) GRPC_OVERRIDE {
+    *sz = call_->max_message_size();
+    return true;
+  }
+
   bool Read(R* msg) GRPC_OVERRIDE {
     CallOpSet<CallOpRecvMessage<R>> ops;
     ops.RecvMessage(msg);
@@ -434,12 +451,15 @@
                                     public WriterInterface<W>,
                                     public ReaderInterface<R> {};
 
+// Actual implementation of bi-directional streaming
+namespace internal {
 template <class W, class R>
-class ServerReaderWriter GRPC_FINAL : public ServerReaderWriterInterface<W, R> {
+class ServerReaderWriterBody GRPC_FINAL {
  public:
-  ServerReaderWriter(Call* call, ServerContext* ctx) : call_(call), ctx_(ctx) {}
+  ServerReaderWriterBody(Call* call, ServerContext* ctx)
+      : call_(call), ctx_(ctx) {}
 
-  void SendInitialMetadata() GRPC_OVERRIDE {
+  void SendInitialMetadata() {
     GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_);
 
     CallOpSet<CallOpSendInitialMetadata> ops;
@@ -453,15 +473,19 @@
     call_->cq()->Pluck(&ops);
   }
 
-  bool Read(R* msg) GRPC_OVERRIDE {
+  bool NextMessageSize(uint32_t* sz) {
+    *sz = call_->max_message_size();
+    return true;
+  }
+
+  bool Read(R* msg) {
     CallOpSet<CallOpRecvMessage<R>> ops;
     ops.RecvMessage(msg);
     call_->PerformOps(&ops);
     return call_->cq()->Pluck(&ops) && ops.got_message;
   }
 
-  using WriterInterface<W>::Write;
-  bool Write(const W& msg, const WriteOptions& options) GRPC_OVERRIDE {
+  bool Write(const W& msg, const WriteOptions& options) {
     CallOpSet<CallOpSendInitialMetadata, CallOpSendMessage> ops;
     if (!ops.SendMessage(msg, options).ok()) {
       return false;
@@ -482,6 +506,76 @@
   Call* const call_;
   ServerContext* const ctx_;
 };
+}
+
+// class to represent the user API for a bidirectional streaming call
+template <class W, class R>
+class ServerReaderWriter GRPC_FINAL : public ServerReaderWriterInterface<W, R> {
+ public:
+  ServerReaderWriter(Call* call, ServerContext* ctx) : body_(call, ctx) {}
+
+  void SendInitialMetadata() GRPC_OVERRIDE { body_.SendInitialMetadata(); }
+
+  bool NextMessageSize(uint32_t* sz) GRPC_OVERRIDE {
+    return body_.NextMessageSize(sz);
+  }
+
+  bool Read(R* msg) GRPC_OVERRIDE { return body_.Read(msg); }
+
+  using WriterInterface<W>::Write;
+  bool Write(const W& msg, const WriteOptions& options) GRPC_OVERRIDE {
+    return body_.Write(msg, options);
+  }
+
+ private:
+  internal::ServerReaderWriterBody<W, R> body_;
+};
+
+/// A class to represent a flow-controlled unary call. This is something
+/// of a hybrid between conventional unary and streaming. This is invoked
+/// through a unary call on the client side, but the server responds to it
+/// as though it were a single-ping-pong streaming call. The server can use
+/// the \a NextMessageSize method to determine an upper-bound on the size of
+/// the message.
+/// A key difference relative to streaming: ServerUnaryStreamer
+///  must have exactly 1 Read and exactly 1 Write, in that order, to function
+/// correctly. Otherwise, the RPC is in error.
+template <class RequestType, class ResponseType>
+class ServerUnaryStreamer GRPC_FINAL
+    : public ServerReaderWriterInterface<ResponseType, RequestType> {
+ public:
+  ServerUnaryStreamer(Call* call, ServerContext* ctx)
+      : body_(call, ctx), read_done_(false), write_done_(false) {}
+
+  void SendInitialMetadata() GRPC_OVERRIDE { body_.SendInitialMetadata(); }
+
+  bool NextMessageSize(uint32_t* sz) GRPC_OVERRIDE {
+    return body_.NextMessageSize(sz);
+  }
+
+  bool Read(RequestType* request) GRPC_OVERRIDE {
+    if (read_done_) {
+      return false;
+    }
+    read_done_ = true;
+    return body_.Read(request);
+  }
+
+  using WriterInterface<ResponseType>::Write;
+  bool Write(const ResponseType& response,
+             const WriteOptions& options) GRPC_OVERRIDE {
+    if (write_done_ || !read_done_) {
+      return false;
+    }
+    write_done_ = true;
+    return body_.Write(response, options);
+  }
+
+ private:
+  internal::ServerReaderWriterBody<ResponseType, RequestType> body_;
+  bool read_done_;
+  bool write_done_;
+};
 
 }  // namespace grpc
 
diff --git a/include/grpc++/impl/codegen/thrift_serializer.h b/include/grpc++/impl/codegen/thrift_serializer.h
index 7308a15..fd324a9 100644
--- a/include/grpc++/impl/codegen/thrift_serializer.h
+++ b/include/grpc++/impl/codegen/thrift_serializer.h
@@ -34,10 +34,8 @@
 #ifndef GRPCXX_IMPL_CODEGEN_THRIFT_SERIALIZER_H
 #define GRPCXX_IMPL_CODEGEN_THRIFT_SERIALIZER_H
 
-#include <grpc/impl/codegen/byte_buffer.h>
 #include <grpc/impl/codegen/byte_buffer_reader.h>
 #include <grpc/impl/codegen/slice.h>
-#include <grpc/impl/codegen/slice_buffer.h>
 #include <thrift/protocol/TBinaryProtocol.h>
 #include <thrift/protocol/TCompactProtocol.h>
 #include <thrift/protocol/TProtocolException.h>
@@ -216,4 +214,4 @@
 }  // namespace thrift
 }  // namespace apache
 
-#endif
\ No newline at end of file
+#endif
diff --git a/include/grpc++/impl/codegen/thrift_utils.h b/include/grpc++/impl/codegen/thrift_utils.h
index 7d19b24..be558c5 100644
--- a/include/grpc++/impl/codegen/thrift_utils.h
+++ b/include/grpc++/impl/codegen/thrift_utils.h
@@ -40,10 +40,8 @@
 #include <grpc++/impl/codegen/status.h>
 #include <grpc++/impl/codegen/status_code_enum.h>
 #include <grpc++/impl/codegen/thrift_serializer.h>
-#include <grpc/impl/codegen/byte_buffer.h>
 #include <grpc/impl/codegen/byte_buffer_reader.h>
 #include <grpc/impl/codegen/slice.h>
-#include <grpc/impl/codegen/slice_buffer.h>
 #include <cstdint>
 #include <cstdlib>
 
diff --git a/include/grpc++/impl/codegen/time.h b/include/grpc++/impl/codegen/time.h
index d9b19bc..87c5112 100644
--- a/include/grpc++/impl/codegen/time.h
+++ b/include/grpc++/impl/codegen/time.h
@@ -35,7 +35,7 @@
 #define GRPCXX_IMPL_CODEGEN_TIME_H
 
 #include <grpc++/impl/codegen/config.h>
-#include <grpc/impl/codegen/time.h>
+#include <grpc/impl/codegen/grpc_types.h>
 
 namespace grpc {
 
@@ -79,7 +79,7 @@
 
 #include <chrono>
 
-#include <grpc/impl/codegen/time.h>
+#include <grpc/impl/codegen/grpc_types.h>
 
 namespace grpc {
 
diff --git a/include/grpc/byte_buffer.h b/include/grpc/byte_buffer.h
index c3a3943..f25c1d5 100644
--- a/include/grpc/byte_buffer.h
+++ b/include/grpc/byte_buffer.h
@@ -34,6 +34,69 @@
 #ifndef GRPC_BYTE_BUFFER_H
 #define GRPC_BYTE_BUFFER_H
 
-#include <grpc/impl/codegen/byte_buffer.h>
+#include <grpc/impl/codegen/grpc_types.h>
+#include <grpc/support/slice_buffer.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Returns a RAW byte buffer instance over the given slices (up to \a nslices).
+ *
+ * Increases the reference count for all \a slices processed. The user is
+ * responsible for invoking grpc_byte_buffer_destroy on the returned instance.*/
+GRPCAPI grpc_byte_buffer *grpc_raw_byte_buffer_create(gpr_slice *slices,
+                                                      size_t nslices);
+
+/** Returns a *compressed* RAW byte buffer instance over the given slices (up to
+ * \a nslices). The \a compression argument defines the compression algorithm
+ * used to generate the data in \a slices.
+ *
+ * Increases the reference count for all \a slices processed. The user is
+ * responsible for invoking grpc_byte_buffer_destroy on the returned instance.*/
+GRPCAPI grpc_byte_buffer *grpc_raw_compressed_byte_buffer_create(
+    gpr_slice *slices, size_t nslices, grpc_compression_algorithm compression);
+
+/** Copies input byte buffer \a bb.
+ *
+ * Increases the reference count of all the source slices. The user is
+ * responsible for calling grpc_byte_buffer_destroy over the returned copy. */
+GRPCAPI grpc_byte_buffer *grpc_byte_buffer_copy(grpc_byte_buffer *bb);
+
+/** Returns the size of the given byte buffer, in bytes. */
+GRPCAPI size_t grpc_byte_buffer_length(grpc_byte_buffer *bb);
+
+/** Destroys \a byte_buffer deallocating all its memory. */
+GRPCAPI void grpc_byte_buffer_destroy(grpc_byte_buffer *byte_buffer);
+
+/** Reader for byte buffers. Iterates over slices in the byte buffer */
+struct grpc_byte_buffer_reader;
+typedef struct grpc_byte_buffer_reader grpc_byte_buffer_reader;
+
+/** Initialize \a reader to read over \a buffer.
+ * Returns 1 upon success, 0 otherwise. */
+GRPCAPI int grpc_byte_buffer_reader_init(grpc_byte_buffer_reader *reader,
+                                         grpc_byte_buffer *buffer);
+
+/** Cleanup and destroy \a reader */
+GRPCAPI void grpc_byte_buffer_reader_destroy(grpc_byte_buffer_reader *reader);
+
+/** Updates \a slice with the next piece of data from from \a reader and returns
+ * 1. Returns 0 at the end of the stream. Caller is responsible for calling
+ * gpr_slice_unref on the result. */
+GRPCAPI int grpc_byte_buffer_reader_next(grpc_byte_buffer_reader *reader,
+                                         gpr_slice *slice);
+
+/** Merge all data from \a reader into single slice */
+GRPCAPI gpr_slice
+grpc_byte_buffer_reader_readall(grpc_byte_buffer_reader *reader);
+
+/** Returns a RAW byte buffer instance from the output of \a reader. */
+GRPCAPI grpc_byte_buffer *grpc_raw_byte_buffer_from_reader(
+    grpc_byte_buffer_reader *reader);
+
+#ifdef __cplusplus
+}
+#endif
 
 #endif /* GRPC_BYTE_BUFFER_H */
diff --git a/include/grpc/compression.h b/include/grpc/compression.h
index 22bcf0e..5f285cd 100644
--- a/include/grpc/compression.h
+++ b/include/grpc/compression.h
@@ -36,9 +36,10 @@
 
 #include <stdlib.h>
 
-#include <grpc/impl/codegen/compression_types.h>
 #include <grpc/impl/codegen/port_platform.h>
 
+#include <grpc/impl/codegen/compression_types.h>
+
 #ifdef __cplusplus
 extern "C" {
 #endif
diff --git a/include/grpc/impl/codegen/alloc.h b/include/grpc/impl/codegen/alloc.h
deleted file mode 100644
index 683c755..0000000
--- a/include/grpc/impl/codegen/alloc.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- *
- * Copyright 2015, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#ifndef GRPC_IMPL_CODEGEN_ALLOC_H
-#define GRPC_IMPL_CODEGEN_ALLOC_H
-
-#include <stddef.h>
-
-#include <grpc/impl/codegen/port_platform.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef struct gpr_allocation_functions {
-  void *(*malloc_fn)(size_t size);
-  void *(*realloc_fn)(void *ptr, size_t size);
-  void (*free_fn)(void *ptr);
-} gpr_allocation_functions;
-
-/* malloc, never returns NULL */
-GPRAPI void *gpr_malloc(size_t size);
-/* free */
-GPRAPI void gpr_free(void *ptr);
-/* realloc, never returns NULL */
-GPRAPI void *gpr_realloc(void *p, size_t size);
-/* aligned malloc, never returns NULL, will align to 1 << alignment_log */
-GPRAPI void *gpr_malloc_aligned(size_t size, size_t alignment_log);
-/* free memory allocated by gpr_malloc_aligned */
-GPRAPI void gpr_free_aligned(void *ptr);
-
-/** Request the family of allocation functions in \a functions be used. NOTE
- * that this request will be honored in a *best effort* basis and that no
- * guarantees are made about the default functions (eg, malloc) being called. */
-GPRAPI void gpr_set_allocation_functions(gpr_allocation_functions functions);
-
-/** Return the family of allocation functions currently in effect. */
-GPRAPI gpr_allocation_functions gpr_get_allocation_functions();
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* GRPC_IMPL_CODEGEN_ALLOC_H */
diff --git a/include/grpc/impl/codegen/byte_buffer.h b/include/grpc/impl/codegen/byte_buffer.h
deleted file mode 100644
index fe1e215..0000000
--- a/include/grpc/impl/codegen/byte_buffer.h
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- *
- * 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 GRPC_IMPL_CODEGEN_BYTE_BUFFER_H
-#define GRPC_IMPL_CODEGEN_BYTE_BUFFER_H
-
-#include <grpc/impl/codegen/compression_types.h>
-#include <grpc/impl/codegen/slice_buffer.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef enum {
-  GRPC_BB_RAW
-  /* Future types may include GRPC_BB_PROTOBUF, etc. */
-} grpc_byte_buffer_type;
-
-struct grpc_byte_buffer {
-  void *reserved;
-  grpc_byte_buffer_type type;
-  union {
-    struct {
-      void *reserved[8];
-    } reserved;
-    struct {
-      grpc_compression_algorithm compression;
-      gpr_slice_buffer slice_buffer;
-    } raw;
-  } data;
-};
-typedef struct grpc_byte_buffer grpc_byte_buffer;
-
-/** Returns a RAW byte buffer instance over the given slices (up to \a nslices).
- *
- * Increases the reference count for all \a slices processed. The user is
- * responsible for invoking grpc_byte_buffer_destroy on the returned instance.*/
-GRPCAPI grpc_byte_buffer *grpc_raw_byte_buffer_create(gpr_slice *slices,
-                                                      size_t nslices);
-
-/** Returns a *compressed* RAW byte buffer instance over the given slices (up to
- * \a nslices). The \a compression argument defines the compression algorithm
- * used to generate the data in \a slices.
- *
- * Increases the reference count for all \a slices processed. The user is
- * responsible for invoking grpc_byte_buffer_destroy on the returned instance.*/
-GRPCAPI grpc_byte_buffer *grpc_raw_compressed_byte_buffer_create(
-    gpr_slice *slices, size_t nslices, grpc_compression_algorithm compression);
-
-/** Copies input byte buffer \a bb.
- *
- * Increases the reference count of all the source slices. The user is
- * responsible for calling grpc_byte_buffer_destroy over the returned copy. */
-GRPCAPI grpc_byte_buffer *grpc_byte_buffer_copy(grpc_byte_buffer *bb);
-
-/** Returns the size of the given byte buffer, in bytes. */
-GRPCAPI size_t grpc_byte_buffer_length(grpc_byte_buffer *bb);
-
-/** Destroys \a byte_buffer deallocating all its memory. */
-GRPCAPI void grpc_byte_buffer_destroy(grpc_byte_buffer *byte_buffer);
-
-/** Reader for byte buffers. Iterates over slices in the byte buffer */
-struct grpc_byte_buffer_reader;
-typedef struct grpc_byte_buffer_reader grpc_byte_buffer_reader;
-
-/** Initialize \a reader to read over \a buffer.
- * Returns 1 upon success, 0 otherwise. */
-GRPCAPI int grpc_byte_buffer_reader_init(grpc_byte_buffer_reader *reader,
-                                         grpc_byte_buffer *buffer);
-
-/** Cleanup and destroy \a reader */
-GRPCAPI void grpc_byte_buffer_reader_destroy(grpc_byte_buffer_reader *reader);
-
-/** Updates \a slice with the next piece of data from from \a reader and returns
- * 1. Returns 0 at the end of the stream. Caller is responsible for calling
- * gpr_slice_unref on the result. */
-GRPCAPI int grpc_byte_buffer_reader_next(grpc_byte_buffer_reader *reader,
-                                         gpr_slice *slice);
-
-/** Merge all data from \a reader into single slice */
-GRPCAPI gpr_slice
-grpc_byte_buffer_reader_readall(grpc_byte_buffer_reader *reader);
-
-/** Returns a RAW byte buffer instance from the output of \a reader. */
-GRPCAPI grpc_byte_buffer *grpc_raw_byte_buffer_from_reader(
-    grpc_byte_buffer_reader *reader);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* GRPC_IMPL_CODEGEN_BYTE_BUFFER_H */
diff --git a/include/grpc/impl/codegen/byte_buffer_reader.h b/include/grpc/impl/codegen/byte_buffer_reader.h
index 10c3829..85a4864 100644
--- a/include/grpc/impl/codegen/byte_buffer_reader.h
+++ b/include/grpc/impl/codegen/byte_buffer_reader.h
@@ -34,15 +34,15 @@
 #ifndef GRPC_IMPL_CODEGEN_BYTE_BUFFER_READER_H
 #define GRPC_IMPL_CODEGEN_BYTE_BUFFER_READER_H
 
-#include <grpc/impl/codegen/byte_buffer.h>
-
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+struct grpc_byte_buffer;
+
 struct grpc_byte_buffer_reader {
-  grpc_byte_buffer *buffer_in;
-  grpc_byte_buffer *buffer_out;
+  struct grpc_byte_buffer *buffer_in;
+  struct grpc_byte_buffer *buffer_out;
   /* Different current objects correspond to different types of byte buffers */
   union {
     /* Index into a slice buffer's array of slices */
diff --git a/include/grpc/impl/codegen/compression_types.h b/include/grpc/impl/codegen/compression_types.h
index 3034182..170d99f 100644
--- a/include/grpc/impl/codegen/compression_types.h
+++ b/include/grpc/impl/codegen/compression_types.h
@@ -34,8 +34,8 @@
 #ifndef GRPC_IMPL_CODEGEN_COMPRESSION_TYPES_H
 #define GRPC_IMPL_CODEGEN_COMPRESSION_TYPES_H
 
-#include <grpc/impl/codegen/port_platform.h>
 #include <stdbool.h>
+#include <stdint.h>
 
 #ifdef __cplusplus
 extern "C" {
diff --git a/include/grpc/impl/codegen/gpr_types.h b/include/grpc/impl/codegen/gpr_types.h
new file mode 100644
index 0000000..c8f0815
--- /dev/null
+++ b/include/grpc/impl/codegen/gpr_types.h
@@ -0,0 +1,140 @@
+/*
+ *
+ * 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_IMPL_CODEGEN_GPR_TYPES_H
+#define GRPC_IMPL_CODEGEN_GPR_TYPES_H
+
+#include <grpc/impl/codegen/port_platform.h>
+
+#include <stddef.h>
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* The clocks we support. */
+typedef enum {
+  /* Monotonic clock. Epoch undefined. Always moves forwards. */
+  GPR_CLOCK_MONOTONIC = 0,
+  /* Realtime clock. May jump forwards or backwards. Settable by
+     the system administrator. Has its epoch at 0:00:00 UTC 1 Jan 1970. */
+  GPR_CLOCK_REALTIME,
+  /* CPU cycle time obtained by rdtsc instruction on x86 platforms. Epoch
+     undefined. Degrades to GPR_CLOCK_REALTIME on other platforms. */
+  GPR_CLOCK_PRECISE,
+  /* Unmeasurable clock type: no base, created by taking the difference
+     between two times */
+  GPR_TIMESPAN
+} gpr_clock_type;
+
+/* Analogous to struct timespec. On some machines, absolute times may be in
+ * local time. */
+typedef struct gpr_timespec {
+  int64_t tv_sec;
+  int32_t tv_nsec;
+  /** Against which clock was this time measured? (or GPR_TIMESPAN if
+      this is a relative time meaure) */
+  gpr_clock_type clock_type;
+} gpr_timespec;
+
+/* Slice API
+
+   A slice represents a contiguous reference counted array of bytes.
+   It is cheap to take references to a slice, and it is cheap to create a
+   slice pointing to a subset of another slice.
+
+   The data-structure for slices is exposed here to allow non-gpr code to
+   build slices from whatever data they have available.
+
+   When defining interfaces that handle slices, care should be taken to define
+   reference ownership semantics (who should call unref?) and mutability
+   constraints (is the callee allowed to modify the slice?) */
+
+/* Reference count container for gpr_slice. Contains function pointers to
+   increment and decrement reference counts. Implementations should cleanup
+   when the reference count drops to zero.
+   Typically client code should not touch this, and use gpr_slice_malloc,
+   gpr_slice_new, or gpr_slice_new_with_len instead. */
+typedef struct gpr_slice_refcount {
+  void (*ref)(void *);
+  void (*unref)(void *);
+} gpr_slice_refcount;
+
+#define GPR_SLICE_INLINED_SIZE (sizeof(size_t) + sizeof(uint8_t *) - 1)
+
+/* A gpr_slice s, if initialized, represents the byte range
+   s.bytes[0..s.length-1].
+
+   It can have an associated ref count which has a destruction routine to be run
+   when the ref count reaches zero (see gpr_slice_new() and grp_slice_unref()).
+   Multiple gpr_slice values may share a ref count.
+
+   If the slice does not have a refcount, it represents an inlined small piece
+   of data that is copied by value. */
+typedef struct gpr_slice {
+  struct gpr_slice_refcount *refcount;
+  union {
+    struct {
+      uint8_t *bytes;
+      size_t length;
+    } refcounted;
+    struct {
+      uint8_t length;
+      uint8_t bytes[GPR_SLICE_INLINED_SIZE];
+    } inlined;
+  } data;
+} gpr_slice;
+
+#define GRPC_SLICE_BUFFER_INLINE_ELEMENTS 8
+
+/* Represents an expandable array of slices, to be interpreted as a
+   single item. */
+typedef struct {
+  /* slices in the array */
+  gpr_slice *slices;
+  /* the number of slices in the array */
+  size_t count;
+  /* the number of slices allocated in the array */
+  size_t capacity;
+  /* the combined length of all slices in the array */
+  size_t length;
+  /* inlined elements to avoid allocations */
+  gpr_slice inlined[GRPC_SLICE_BUFFER_INLINE_ELEMENTS];
+} gpr_slice_buffer;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GRPC_IMPL_CODEGEN_GPR_TYPES_H */
diff --git a/include/grpc/impl/codegen/grpc_types.h b/include/grpc/impl/codegen/grpc_types.h
index b3372d7..b2c4840 100644
--- a/include/grpc/impl/codegen/grpc_types.h
+++ b/include/grpc/impl/codegen/grpc_types.h
@@ -34,15 +34,37 @@
 #ifndef GRPC_IMPL_CODEGEN_GRPC_TYPES_H
 #define GRPC_IMPL_CODEGEN_GRPC_TYPES_H
 
-#include <grpc/impl/codegen/byte_buffer.h>
+#include <grpc/impl/codegen/gpr_types.h>
+
+#include <grpc/impl/codegen/compression_types.h>
 #include <grpc/impl/codegen/status.h>
 
 #include <stddef.h>
+#include <stdint.h>
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+typedef enum {
+  GRPC_BB_RAW
+  /* Future types may include GRPC_BB_PROTOBUF, etc. */
+} grpc_byte_buffer_type;
+
+typedef struct grpc_byte_buffer {
+  void *reserved;
+  grpc_byte_buffer_type type;
+  union {
+    struct {
+      void *reserved[8];
+    } reserved;
+    struct {
+      grpc_compression_algorithm compression;
+      gpr_slice_buffer slice_buffer;
+    } raw;
+  } data;
+} grpc_byte_buffer;
+
 /** Completion Queues enable notification of the completion of asynchronous
     actions. */
 typedef struct grpc_completion_queue grpc_completion_queue;
@@ -142,6 +164,11 @@
 /** How much memory to use for hpack encoding. Int valued, bytes. */
 #define GRPC_ARG_HTTP2_HPACK_TABLE_SIZE_ENCODER \
   "grpc.http2.hpack_table_size.encoder"
+/** How big a frame are we willing to receive via HTTP2.
+    Min 16384, max 16777215.
+    Larger values give lower CPU usage for large messages, but more head of line
+    blocking for small messages. */
+#define GRPC_ARG_HTTP2_MAX_FRAME_SIZE "grpc.http2.max_frame_size"
 /** Default authority to pass if none specified on call construction. A string.
  * */
 #define GRPC_ARG_DEFAULT_AUTHORITY "grpc.default_authority"
@@ -331,6 +358,8 @@
   GRPC_OP_RECV_CLOSE_ON_SERVER
 } grpc_op_type;
 
+struct grpc_byte_buffer;
+
 /** Operation data: one field for each op type (except SEND_CLOSE_FROM_CLIENT
    which has no arguments) */
 typedef struct grpc_op {
@@ -355,7 +384,7 @@
         grpc_compression_level level;
       } maybe_compression_level;
     } send_initial_metadata;
-    grpc_byte_buffer *send_message;
+    struct grpc_byte_buffer *send_message;
     struct {
       size_t trailing_metadata_count;
       grpc_metadata *trailing_metadata;
@@ -371,7 +400,7 @@
     /** ownership of the byte buffer is moved to the caller; the caller must
         call grpc_byte_buffer_destroy on this value, or reuse it in a future op.
        */
-    grpc_byte_buffer **recv_message;
+    struct grpc_byte_buffer **recv_message;
     struct {
       /** ownership of the array is with the caller, but ownership of the
           elements stays with the call object (ie key, value members are owned
diff --git a/include/grpc/impl/codegen/log.h b/include/grpc/impl/codegen/log.h
deleted file mode 100644
index e5010c2..0000000
--- a/include/grpc/impl/codegen/log.h
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- *
- * Copyright 2015, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#ifndef GRPC_IMPL_CODEGEN_LOG_H
-#define GRPC_IMPL_CODEGEN_LOG_H
-
-#include <inttypes.h>
-#include <stdarg.h>
-#include <stdlib.h> /* for abort() */
-
-#include <grpc/impl/codegen/port_platform.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* GPR log API.
-
-   Usage (within grpc):
-
-   int argument1 = 3;
-   char* argument2 = "hello";
-   gpr_log(GPR_DEBUG, "format string %d", argument1);
-   gpr_log(GPR_INFO, "hello world");
-   gpr_log(GPR_ERROR, "%d %s!!", argument1, argument2); */
-
-/* The severity of a log message - use the #defines below when calling into
-   gpr_log to additionally supply file and line data */
-typedef enum gpr_log_severity {
-  GPR_LOG_SEVERITY_DEBUG,
-  GPR_LOG_SEVERITY_INFO,
-  GPR_LOG_SEVERITY_ERROR
-} gpr_log_severity;
-
-#define GPR_LOG_VERBOSITY_UNSET -1
-
-/* Returns a string representation of the log severity */
-const char *gpr_log_severity_string(gpr_log_severity severity);
-
-/* Macros to build log contexts at various severity levels */
-#define GPR_DEBUG __FILE__, __LINE__, GPR_LOG_SEVERITY_DEBUG
-#define GPR_INFO __FILE__, __LINE__, GPR_LOG_SEVERITY_INFO
-#define GPR_ERROR __FILE__, __LINE__, GPR_LOG_SEVERITY_ERROR
-
-/* Log a message. It's advised to use GPR_xxx above to generate the context
- * for each message */
-GPRAPI void gpr_log(const char *file, int line, gpr_log_severity severity,
-                    const char *format, ...) GPRC_PRINT_FORMAT_CHECK(4, 5);
-
-GPRAPI void gpr_log_message(const char *file, int line,
-                            gpr_log_severity severity, const char *message);
-
-/* Set global log verbosity */
-GPRAPI void gpr_set_log_verbosity(gpr_log_severity min_severity_to_print);
-
-GPRAPI void gpr_log_verbosity_init();
-
-/* Log overrides: applications can use this API to intercept logging calls
-   and use their own implementations */
-
-typedef struct {
-  const char *file;
-  int line;
-  gpr_log_severity severity;
-  const char *message;
-} gpr_log_func_args;
-
-typedef void (*gpr_log_func)(gpr_log_func_args *args);
-GPRAPI void gpr_set_log_function(gpr_log_func func);
-
-/* abort() the process if x is zero, having written a line to the log.
-
-   Intended for internal invariants.  If the error can be recovered from,
-   without the possibility of corruption, or might best be reflected via
-   an exception in a higher-level language, consider returning error code.  */
-#define GPR_ASSERT(x)                                 \
-  do {                                                \
-    if (!(x)) {                                       \
-      gpr_log(GPR_ERROR, "assertion failed: %s", #x); \
-      abort();                                        \
-    }                                                 \
-  } while (0)
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* GRPC_IMPL_CODEGEN_LOG_H */
diff --git a/include/grpc/impl/codegen/port_platform.h b/include/grpc/impl/codegen/port_platform.h
index 7c67bad..f97e386 100644
--- a/include/grpc/impl/codegen/port_platform.h
+++ b/include/grpc/impl/codegen/port_platform.h
@@ -234,6 +234,7 @@
 #define GPR_ARCH_32 1
 #endif /* _LP64 */
 #elif defined(__APPLE__)
+#include <Availability.h>
 #include <TargetConditionals.h>
 #ifndef _BSD_SOURCE
 #define _BSD_SOURCE
@@ -246,8 +247,18 @@
 #define GPR_PTHREAD_TLS 1
 #else /* TARGET_OS_IPHONE */
 #define GPR_PLATFORM_STRING "osx"
+#ifdef __MAC_OS_X_VERSION_MIN_REQUIRED
+#if __MAC_OS_X_VERSION_MIN_REQUIRED < __MAC_10_7
+#define GPR_CPU_IPHONE 1
+#define GPR_PTHREAD_TLS 1
+#else /* __MAC_OS_X_VERSION_MIN_REQUIRED < __MAC_10_7 */
 #define GPR_CPU_POSIX 1
 #define GPR_GCC_TLS 1
+#endif
+#else /* __MAC_OS_X_VERSION_MIN_REQUIRED */
+#define GPR_CPU_POSIX 1
+#define GPR_GCC_TLS 1
+#endif
 #define GPR_POSIX_CRASH_HANDLER 1
 #endif
 #define GPR_GCC_ATOMIC 1
diff --git a/include/grpc/impl/codegen/slice.h b/include/grpc/impl/codegen/slice.h
index dfc0a77..a2637ee 100644
--- a/include/grpc/impl/codegen/slice.h
+++ b/include/grpc/impl/codegen/slice.h
@@ -34,62 +34,8 @@
 #ifndef GRPC_IMPL_CODEGEN_SLICE_H
 #define GRPC_IMPL_CODEGEN_SLICE_H
 
-#include <grpc/impl/codegen/sync.h>
-
 #include <stddef.h>
 
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Slice API
-
-   A slice represents a contiguous reference counted array of bytes.
-   It is cheap to take references to a slice, and it is cheap to create a
-   slice pointing to a subset of another slice.
-
-   The data-structure for slices is exposed here to allow non-gpr code to
-   build slices from whatever data they have available.
-
-   When defining interfaces that handle slices, care should be taken to define
-   reference ownership semantics (who should call unref?) and mutability
-   constraints (is the callee allowed to modify the slice?) */
-
-/* Reference count container for gpr_slice. Contains function pointers to
-   increment and decrement reference counts. Implementations should cleanup
-   when the reference count drops to zero.
-   Typically client code should not touch this, and use gpr_slice_malloc,
-   gpr_slice_new, or gpr_slice_new_with_len instead. */
-typedef struct gpr_slice_refcount {
-  void (*ref)(void *);
-  void (*unref)(void *);
-} gpr_slice_refcount;
-
-#define GPR_SLICE_INLINED_SIZE (sizeof(size_t) + sizeof(uint8_t *) - 1)
-
-/* A gpr_slice s, if initialized, represents the byte range
-   s.bytes[0..s.length-1].
-
-   It can have an associated ref count which has a destruction routine to be run
-   when the ref count reaches zero (see gpr_slice_new() and grp_slice_unref()).
-   Multiple gpr_slice values may share a ref count.
-
-   If the slice does not have a refcount, it represents an inlined small piece
-   of data that is copied by value. */
-typedef struct gpr_slice {
-  struct gpr_slice_refcount *refcount;
-  union {
-    struct {
-      uint8_t *bytes;
-      size_t length;
-    } refcounted;
-    struct {
-      uint8_t length;
-      uint8_t bytes[GPR_SLICE_INLINED_SIZE];
-    } inlined;
-  } data;
-} gpr_slice;
-
 #define GPR_SLICE_START_PTR(slice)                  \
   ((slice).refcount ? (slice).data.refcounted.bytes \
                     : (slice).data.inlined.bytes)
@@ -103,88 +49,4 @@
   GPR_SLICE_START_PTR(slice) + GPR_SLICE_LENGTH(slice)
 #define GPR_SLICE_IS_EMPTY(slice) (GPR_SLICE_LENGTH(slice) == 0)
 
-/* Increment the refcount of s. Requires slice is initialized.
-   Returns s. */
-GPRAPI gpr_slice gpr_slice_ref(gpr_slice s);
-
-/* Decrement the ref count of s.  If the ref count of s reaches zero, all
-   slices sharing the ref count are destroyed, and considered no longer
-   initialized.  If s is ultimately derived from a call to gpr_slice_new(start,
-   len, dest) where dest!=NULL , then (*dest)(start) is called, else if s is
-   ultimately derived from a call to gpr_slice_new_with_len(start, len, dest)
-   where dest!=NULL , then (*dest)(start, len).  Requires s initialized.  */
-GPRAPI void gpr_slice_unref(gpr_slice s);
-
-/* Create a slice pointing at some data. Calls malloc to allocate a refcount
-   for the object, and arranges that destroy will be called with the pointer
-   passed in at destruction. */
-GPRAPI gpr_slice gpr_slice_new(void *p, size_t len, void (*destroy)(void *));
-
-/* Equivalent to gpr_slice_new, but with a separate pointer that is
-   passed to the destroy function.  This function can be useful when
-   the data is part of a larger structure that must be destroyed when
-   the data is no longer needed. */
-GPRAPI gpr_slice gpr_slice_new_with_user_data(void *p, size_t len,
-                                              void (*destroy)(void *),
-                                              void *user_data);
-
-/* Equivalent to gpr_slice_new, but with a two argument destroy function that
-   also takes the slice length. */
-GPRAPI gpr_slice gpr_slice_new_with_len(void *p, size_t len,
-                                        void (*destroy)(void *, size_t));
-
-/* Equivalent to gpr_slice_new(malloc(len), len, free), but saves one malloc()
-   call.
-   Aborts if malloc() fails. */
-GPRAPI gpr_slice gpr_slice_malloc(size_t length);
-
-/* Create a slice by copying a string.
-   Does not preserve null terminators.
-   Equivalent to:
-     size_t len = strlen(source);
-     gpr_slice slice = gpr_slice_malloc(len);
-     memcpy(slice->data, source, len); */
-GPRAPI gpr_slice gpr_slice_from_copied_string(const char *source);
-
-/* Create a slice by copying a buffer.
-   Equivalent to:
-     gpr_slice slice = gpr_slice_malloc(len);
-     memcpy(slice->data, source, len); */
-GPRAPI gpr_slice gpr_slice_from_copied_buffer(const char *source, size_t len);
-
-/* Create a slice pointing to constant memory */
-GPRAPI gpr_slice gpr_slice_from_static_string(const char *source);
-
-/* Return a result slice derived from s, which shares a ref count with s, where
-   result.data==s.data+begin, and result.length==end-begin.
-   The ref count of s is increased by one.
-   Requires s initialized, begin <= end, begin <= s.length, and
-   end <= source->length. */
-GPRAPI gpr_slice gpr_slice_sub(gpr_slice s, size_t begin, size_t end);
-
-/* The same as gpr_slice_sub, but without altering the ref count */
-GPRAPI gpr_slice gpr_slice_sub_no_ref(gpr_slice s, size_t begin, size_t end);
-
-/* Splits s into two: modifies s to be s[0:split], and returns a new slice,
-   sharing a refcount with s, that contains s[split:s.length].
-   Requires s intialized, split <= s.length */
-GPRAPI gpr_slice gpr_slice_split_tail(gpr_slice *s, size_t split);
-
-/* Splits s into two: modifies s to be s[split:s.length], and returns a new
-   slice, sharing a refcount with s, that contains s[0:split].
-   Requires s intialized, split <= s.length */
-GPRAPI gpr_slice gpr_slice_split_head(gpr_slice *s, size_t split);
-
-GPRAPI gpr_slice gpr_empty_slice(void);
-
-/* Returns <0 if a < b, ==0 if a == b, >0 if a > b
-   The order is arbitrary, and is not guaranteed to be stable across different
-   versions of the API. */
-GPRAPI int gpr_slice_cmp(gpr_slice a, gpr_slice b);
-GPRAPI int gpr_slice_str_cmp(gpr_slice a, const char *b);
-
-#ifdef __cplusplus
-}
-#endif
-
 #endif /* GRPC_IMPL_CODEGEN_SLICE_H */
diff --git a/include/grpc/impl/codegen/slice_buffer.h b/include/grpc/impl/codegen/slice_buffer.h
deleted file mode 100644
index 7858021..0000000
--- a/include/grpc/impl/codegen/slice_buffer.h
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- *
- * Copyright 2015, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#ifndef GRPC_IMPL_CODEGEN_SLICE_BUFFER_H
-#define GRPC_IMPL_CODEGEN_SLICE_BUFFER_H
-
-#include <grpc/impl/codegen/slice.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define GRPC_SLICE_BUFFER_INLINE_ELEMENTS 8
-
-/* Represents an expandable array of slices, to be interpreted as a
-   single item. */
-typedef struct {
-  /* slices in the array */
-  gpr_slice *slices;
-  /* the number of slices in the array */
-  size_t count;
-  /* the number of slices allocated in the array */
-  size_t capacity;
-  /* the combined length of all slices in the array */
-  size_t length;
-  /* inlined elements to avoid allocations */
-  gpr_slice inlined[GRPC_SLICE_BUFFER_INLINE_ELEMENTS];
-} gpr_slice_buffer;
-
-/* initialize a slice buffer */
-GPRAPI void gpr_slice_buffer_init(gpr_slice_buffer *sb);
-/* destroy a slice buffer - unrefs any held elements */
-GPRAPI void gpr_slice_buffer_destroy(gpr_slice_buffer *sb);
-/* Add an element to a slice buffer - takes ownership of the slice.
-   This function is allowed to concatenate the passed in slice to the end of
-   some other slice if desired by the slice buffer. */
-GPRAPI void gpr_slice_buffer_add(gpr_slice_buffer *sb, gpr_slice slice);
-/* add an element to a slice buffer - takes ownership of the slice and returns
-   the index of the slice.
-   Guarantees that the slice will not be concatenated at the end of another
-   slice (i.e. the data for this slice will begin at the first byte of the
-   slice at the returned index in sb->slices)
-   The implementation MAY decide to concatenate data at the end of a small
-   slice added in this fashion. */
-GPRAPI size_t gpr_slice_buffer_add_indexed(gpr_slice_buffer *sb,
-                                           gpr_slice slice);
-GPRAPI void gpr_slice_buffer_addn(gpr_slice_buffer *sb, gpr_slice *slices,
-                                  size_t n);
-/* add a very small (less than 8 bytes) amount of data to the end of a slice
-   buffer: returns a pointer into which to add the data */
-GPRAPI uint8_t *gpr_slice_buffer_tiny_add(gpr_slice_buffer *sb, size_t len);
-/* pop the last buffer, but don't unref it */
-GPRAPI void gpr_slice_buffer_pop(gpr_slice_buffer *sb);
-/* clear a slice buffer, unref all elements */
-GPRAPI void gpr_slice_buffer_reset_and_unref(gpr_slice_buffer *sb);
-/* swap the contents of two slice buffers */
-GPRAPI void gpr_slice_buffer_swap(gpr_slice_buffer *a, gpr_slice_buffer *b);
-/* move all of the elements of src into dst */
-GPRAPI void gpr_slice_buffer_move_into(gpr_slice_buffer *src,
-                                       gpr_slice_buffer *dst);
-/* remove n bytes from the end of a slice buffer */
-GPRAPI void gpr_slice_buffer_trim_end(gpr_slice_buffer *src, size_t n,
-                                      gpr_slice_buffer *garbage);
-/* move the first n bytes of src into dst */
-GPRAPI void gpr_slice_buffer_move_first(gpr_slice_buffer *src, size_t n,
-                                        gpr_slice_buffer *dst);
-/* take the first slice in the slice buffer */
-GPRAPI gpr_slice gpr_slice_buffer_take_first(gpr_slice_buffer *src);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* GRPC_IMPL_CODEGEN_SLICE_BUFFER_H */
diff --git a/include/grpc/impl/codegen/sync.h b/include/grpc/impl/codegen/sync.h
index 5542482..96aec0c 100644
--- a/include/grpc/impl/codegen/sync.h
+++ b/include/grpc/impl/codegen/sync.h
@@ -64,257 +64,4 @@
 #error Unable to determine platform for sync
 #endif
 
-#include <grpc/impl/codegen/time.h> /* for gpr_timespec */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* --- Mutex interface ---
-
-   At most one thread may hold an exclusive lock on a mutex at any given time.
-   Actions taken by a thread that holds a mutex exclusively happen after
-   actions taken by all previous holders of the mutex.  Variables of type
-   gpr_mu are uninitialized when first declared.  */
-
-/* Initialize *mu.  Requires:  *mu uninitialized.  */
-GPRAPI void gpr_mu_init(gpr_mu *mu);
-
-/* Cause *mu no longer to be initialized, freeing any memory in use.  Requires:
-   *mu initialized; no other concurrent operation on *mu.  */
-GPRAPI void gpr_mu_destroy(gpr_mu *mu);
-
-/* Wait until no thread has a lock on *mu, cause the calling thread to own an
-   exclusive lock on *mu, then return.  May block indefinitely or crash if the
-   calling thread has a lock on *mu.  Requires:  *mu initialized.  */
-GPRAPI void gpr_mu_lock(gpr_mu *mu);
-
-/* Release an exclusive lock on *mu held by the calling thread.  Requires:  *mu
-   initialized; the calling thread holds an exclusive lock on *mu.  */
-GPRAPI void gpr_mu_unlock(gpr_mu *mu);
-
-/* Without blocking, attempt to acquire an exclusive lock on *mu for the
-   calling thread, then return non-zero iff success.  Fail, if any thread holds
-   the lock; succeeds with high probability if no thread holds the lock.
-   Requires:  *mu initialized.  */
-GPRAPI int gpr_mu_trylock(gpr_mu *mu);
-
-/* --- Condition variable interface ---
-
-   A while-loop should be used with gpr_cv_wait() when waiting for conditions
-   to become true.  See the example below.  Variables of type gpr_cv are
-   uninitialized when first declared.  */
-
-/* Initialize *cv.  Requires:  *cv uninitialized.  */
-GPRAPI void gpr_cv_init(gpr_cv *cv);
-
-/* Cause *cv no longer to be initialized, freeing any memory in use.  Requires:
-   *cv initialized; no other concurrent operation on *cv.*/
-GPRAPI void gpr_cv_destroy(gpr_cv *cv);
-
-/* Atomically release *mu and wait on *cv.  When the calling thread is woken
-   from *cv or the deadline abs_deadline is exceeded, execute gpr_mu_lock(mu)
-   and return whether the deadline was exceeded.  Use
-   abs_deadline==gpr_inf_future for no deadline.  abs_deadline can be either
-   an absolute deadline, or a GPR_TIMESPAN.  May return even when not
-   woken explicitly.  Requires:  *mu and *cv initialized; the calling thread
-   holds an exclusive lock on *mu.  */
-GPRAPI int gpr_cv_wait(gpr_cv *cv, gpr_mu *mu, gpr_timespec abs_deadline);
-
-/* If any threads are waiting on *cv, wake at least one.
-   Clients may treat this as an optimization of gpr_cv_broadcast()
-   for use in the case where waking more than one waiter is not useful.
-   Requires:  *cv initialized.  */
-GPRAPI void gpr_cv_signal(gpr_cv *cv);
-
-/* Wake all threads waiting on *cv.  Requires:  *cv initialized.  */
-GPRAPI void gpr_cv_broadcast(gpr_cv *cv);
-
-/* --- One-time initialization ---
-
-   gpr_once must be declared with static storage class, and initialized with
-   GPR_ONCE_INIT.  e.g.,
-     static gpr_once once_var = GPR_ONCE_INIT;     */
-
-/* Ensure that (*init_routine)() has been called exactly once (for the
-   specified gpr_once instance) and then return.
-   If multiple threads call gpr_once() on the same gpr_once instance, one of
-   them will call (*init_routine)(), and the others will block until that call
-   finishes.*/
-GPRAPI void gpr_once_init(gpr_once *once, void (*init_routine)(void));
-
-/* --- One-time event notification ---
-
-  These operations act on a gpr_event, which should be initialized with
-  gpr_ev_init(), or with GPR_EVENT_INIT if static, e.g.,
-       static gpr_event event_var = GPR_EVENT_INIT;
-  It requires no destruction.  */
-
-/* Initialize *ev. */
-GPRAPI void gpr_event_init(gpr_event *ev);
-
-/* Set *ev so that gpr_event_get() and gpr_event_wait() will return value.
-   Requires:  *ev initialized; value != NULL; no prior or concurrent calls to
-   gpr_event_set(ev, ...) since initialization.  */
-GPRAPI void gpr_event_set(gpr_event *ev, void *value);
-
-/* Return the value set by gpr_event_set(ev, ...), or NULL if no such call has
-   completed.  If the result is non-NULL, all operations that occurred prior to
-   the gpr_event_set(ev, ...) set will be visible after this call returns.
-   Requires:  *ev initialized.  This operation is faster than acquiring a mutex
-   on most platforms.  */
-GPRAPI void *gpr_event_get(gpr_event *ev);
-
-/* Wait until *ev is set by gpr_event_set(ev, ...), or abs_deadline is
-   exceeded, then return gpr_event_get(ev).  Requires:  *ev initialized.  Use
-   abs_deadline==gpr_inf_future for no deadline.  When the event has been
-   signalled before the call, this operation is faster than acquiring a mutex
-   on most platforms.  */
-GPRAPI void *gpr_event_wait(gpr_event *ev, gpr_timespec abs_deadline);
-
-/* --- Reference counting ---
-
-   These calls act on the type gpr_refcount.  It requires no destruction.  */
-
-/* Initialize *r to value n.  */
-GPRAPI void gpr_ref_init(gpr_refcount *r, int n);
-
-/* Increment the reference count *r.  Requires *r initialized. */
-GPRAPI void gpr_ref(gpr_refcount *r);
-
-/* Increment the reference count *r.  Requires *r initialized.
-   Crashes if refcount is zero */
-GPRAPI void gpr_ref_non_zero(gpr_refcount *r);
-
-/* Increment the reference count *r by n.  Requires *r initialized, n > 0. */
-GPRAPI void gpr_refn(gpr_refcount *r, int n);
-
-/* Decrement the reference count *r and return non-zero iff it has reached
-   zero. .  Requires *r initialized. */
-GPRAPI int gpr_unref(gpr_refcount *r);
-
-/* --- Stats counters ---
-
-   These calls act on the integral type gpr_stats_counter.  It requires no
-   destruction.  Static instances may be initialized with
-       gpr_stats_counter c = GPR_STATS_INIT;
-   Beware:  These operations do not imply memory barriers.  Do not use them to
-   synchronize other events.  */
-
-/* Initialize *c to the value n. */
-GPRAPI void gpr_stats_init(gpr_stats_counter *c, intptr_t n);
-
-/* *c += inc.  Requires: *c initialized. */
-GPRAPI void gpr_stats_inc(gpr_stats_counter *c, intptr_t inc);
-
-/* Return *c.  Requires: *c initialized. */
-GPRAPI intptr_t gpr_stats_read(const gpr_stats_counter *c);
-
-/* ==================Example use of interface===================
-   A producer-consumer queue of up to N integers,
-   illustrating the use of the calls in this interface. */
-#if 0
-
-#define N 4
-
-   typedef struct queue {
-     gpr_cv non_empty;  /* Signalled when length becomes non-zero. */
-     gpr_cv non_full;   /* Signalled when length becomes non-N. */
-     gpr_mu mu;         /* Protects all fields below.
-                            (That is, except during initialization or
-                            destruction, the fields below should be accessed
-                            only by a thread that holds mu.) */
-     int head;           /* Index of head of queue 0..N-1. */
-     int length;         /* Number of valid elements in queue 0..N. */
-     int elem[N];        /* elem[head .. head+length-1] are queue elements. */
-   } queue;
-
-   /* Initialize *q. */
-   void queue_init(queue *q) {
-     gpr_mu_init(&q->mu);
-     gpr_cv_init(&q->non_empty);
-     gpr_cv_init(&q->non_full);
-     q->head = 0;
-     q->length = 0;
-   }
-
-   /* Free storage associated with *q. */
-   void queue_destroy(queue *q) {
-     gpr_mu_destroy(&q->mu);
-     gpr_cv_destroy(&q->non_empty);
-     gpr_cv_destroy(&q->non_full);
-   }
-
-   /* Wait until there is room in *q, then append x to *q. */
-   void queue_append(queue *q, int x) {
-     gpr_mu_lock(&q->mu);
-     /* To wait for a predicate without a deadline, loop on the negation of the
-        predicate, and use gpr_cv_wait(..., gpr_inf_future) inside the loop
-        to release the lock, wait, and reacquire on each iteration.  Code that
-        makes the condition true should use gpr_cv_broadcast() on the
-        corresponding condition variable.  The predicate must be on state
-        protected by the lock.  */
-     while (q->length == N) {
-       gpr_cv_wait(&q->non_full, &q->mu, gpr_inf_future);
-     }
-     if (q->length == 0) {  /* Wake threads blocked in queue_remove(). */
-       /* It's normal to use gpr_cv_broadcast() or gpr_signal() while
-          holding the lock. */
-       gpr_cv_broadcast(&q->non_empty);
-     }
-     q->elem[(q->head + q->length) % N] = x;
-     q->length++;
-     gpr_mu_unlock(&q->mu);
-   }
-
-   /* If it can be done without blocking, append x to *q and return non-zero.
-      Otherwise return 0. */
-   int queue_try_append(queue *q, int x) {
-     int result = 0;
-     if (gpr_mu_trylock(&q->mu)) {
-       if (q->length != N) {
-         if (q->length == 0) {  /* Wake threads blocked in queue_remove(). */
-           gpr_cv_broadcast(&q->non_empty);
-         }
-         q->elem[(q->head + q->length) % N] = x;
-         q->length++;
-         result = 1;
-       }
-       gpr_mu_unlock(&q->mu);
-     }
-     return result;
-   }
-
-   /* Wait until the *q is non-empty or deadline abs_deadline passes.  If the
-      queue is non-empty, remove its head entry, place it in *head, and return
-      non-zero.  Otherwise return 0.  */
-   int queue_remove(queue *q, int *head, gpr_timespec abs_deadline) {
-     int result = 0;
-     gpr_mu_lock(&q->mu);
-     /* To wait for a predicate with a deadline, loop on the negation of the
-        predicate or until gpr_cv_wait() returns true.  Code that makes
-        the condition true should use gpr_cv_broadcast() on the corresponding
-        condition variable.  The predicate must be on state protected by the
-        lock. */
-     while (q->length == 0 &&
-            !gpr_cv_wait(&q->non_empty, &q->mu, abs_deadline)) {
-     }
-     if (q->length != 0) {    /* Queue is non-empty. */
-       result = 1;
-       if (q->length == N) {  /* Wake threads blocked in queue_append(). */
-         gpr_cv_broadcast(&q->non_full);
-       }
-       *head = q->elem[q->head];
-       q->head = (q->head + 1) % N;
-       q->length--;
-     } /* else deadline exceeded */
-     gpr_mu_unlock(&q->mu);
-     return result;
-   }
-#endif /* 0 */
-
-#ifdef __cplusplus
-}
-#endif
-
 #endif /* GRPC_IMPL_CODEGEN_SYNC_H */
diff --git a/include/grpc/impl/codegen/time.h b/include/grpc/impl/codegen/time.h
deleted file mode 100644
index 381e267..0000000
--- a/include/grpc/impl/codegen/time.h
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- *
- * Copyright 2015, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#ifndef GRPC_IMPL_CODEGEN_TIME_H
-#define GRPC_IMPL_CODEGEN_TIME_H
-/* Time support.
-   We use gpr_timespec, which is analogous to struct timespec.  On some
-   machines, absolute times may be in local time.  */
-
-#include <grpc/impl/codegen/port_platform.h>
-#include <stddef.h>
-#include <time.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* The clocks we support. */
-typedef enum {
-  /* Monotonic clock. Epoch undefined. Always moves forwards. */
-  GPR_CLOCK_MONOTONIC = 0,
-  /* Realtime clock. May jump forwards or backwards. Settable by
-     the system administrator. Has its epoch at 0:00:00 UTC 1 Jan 1970. */
-  GPR_CLOCK_REALTIME,
-  /* CPU cycle time obtained by rdtsc instruction on x86 platforms. Epoch
-     undefined. Degrades to GPR_CLOCK_REALTIME on other platforms. */
-  GPR_CLOCK_PRECISE,
-  /* Unmeasurable clock type: no base, created by taking the difference
-     between two times */
-  GPR_TIMESPAN
-} gpr_clock_type;
-
-typedef struct gpr_timespec {
-  int64_t tv_sec;
-  int32_t tv_nsec;
-  /** Against which clock was this time measured? (or GPR_TIMESPAN if
-      this is a relative time meaure) */
-  gpr_clock_type clock_type;
-} gpr_timespec;
-
-/* Time constants. */
-GPRAPI gpr_timespec
-gpr_time_0(gpr_clock_type type); /* The zero time interval. */
-GPRAPI gpr_timespec gpr_inf_future(gpr_clock_type type); /* The far future */
-GPRAPI gpr_timespec gpr_inf_past(gpr_clock_type type);   /* The far past. */
-
-#define GPR_MS_PER_SEC 1000
-#define GPR_US_PER_SEC 1000000
-#define GPR_NS_PER_SEC 1000000000
-#define GPR_NS_PER_MS 1000000
-#define GPR_NS_PER_US 1000
-#define GPR_US_PER_MS 1000
-
-/* initialize time subsystem */
-GPRAPI void gpr_time_init(void);
-
-/* Return the current time measured from the given clocks epoch. */
-GPRAPI gpr_timespec gpr_now(gpr_clock_type clock);
-
-/* Convert a timespec from one clock to another */
-GPRAPI gpr_timespec gpr_convert_clock_type(gpr_timespec t,
-                                           gpr_clock_type target_clock);
-
-/* Return -ve, 0, or +ve according to whether a < b, a == b, or a > b
-   respectively.  */
-GPRAPI int gpr_time_cmp(gpr_timespec a, gpr_timespec b);
-
-GPRAPI gpr_timespec gpr_time_max(gpr_timespec a, gpr_timespec b);
-GPRAPI gpr_timespec gpr_time_min(gpr_timespec a, gpr_timespec b);
-
-/* Add and subtract times.  Calculations saturate at infinities. */
-GPRAPI gpr_timespec gpr_time_add(gpr_timespec a, gpr_timespec b);
-GPRAPI gpr_timespec gpr_time_sub(gpr_timespec a, gpr_timespec b);
-
-/* Return a timespec representing a given number of time units. INT64_MIN is
-   interpreted as gpr_inf_past, and INT64_MAX as gpr_inf_future.  */
-GPRAPI gpr_timespec gpr_time_from_micros(int64_t x, gpr_clock_type clock_type);
-GPRAPI gpr_timespec gpr_time_from_nanos(int64_t x, gpr_clock_type clock_type);
-GPRAPI gpr_timespec gpr_time_from_millis(int64_t x, gpr_clock_type clock_type);
-GPRAPI gpr_timespec gpr_time_from_seconds(int64_t x, gpr_clock_type clock_type);
-GPRAPI gpr_timespec gpr_time_from_minutes(int64_t x, gpr_clock_type clock_type);
-GPRAPI gpr_timespec gpr_time_from_hours(int64_t x, gpr_clock_type clock_type);
-
-GPRAPI int32_t gpr_time_to_millis(gpr_timespec timespec);
-
-/* Return 1 if two times are equal or within threshold of each other,
-   0 otherwise */
-GPRAPI int gpr_time_similar(gpr_timespec a, gpr_timespec b,
-                            gpr_timespec threshold);
-
-/* Sleep until at least 'until' - an absolute timeout */
-GPRAPI void gpr_sleep_until(gpr_timespec until);
-
-GPRAPI double gpr_timespec_to_micros(gpr_timespec t);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* GRPC_IMPL_CODEGEN_TIME_H */
diff --git a/include/grpc/module.modulemap b/include/grpc/module.modulemap
index 02fb2f3..51bfef2 100644
--- a/include/grpc/module.modulemap
+++ b/include/grpc/module.modulemap
@@ -4,8 +4,6 @@
   header "byte_buffer_reader.h"
   header "grpc_security.h"
   header "grpc_security_constants.h"
-  header "impl/codegen/alloc.h"
-  header "impl/codegen/byte_buffer_reader.h"
   header "support/alloc.h"
   header "support/port_platform.h"
   header "support/string_util.h"
diff --git a/include/grpc/support/alloc.h b/include/grpc/support/alloc.h
index 8d03af8..327a9ff 100644
--- a/include/grpc/support/alloc.h
+++ b/include/grpc/support/alloc.h
@@ -34,6 +34,41 @@
 #ifndef GRPC_SUPPORT_ALLOC_H
 #define GRPC_SUPPORT_ALLOC_H
 
-#include <grpc/impl/codegen/alloc.h>
+#include <stddef.h>
+
+#include <grpc/impl/codegen/port_platform.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct gpr_allocation_functions {
+  void *(*malloc_fn)(size_t size);
+  void *(*realloc_fn)(void *ptr, size_t size);
+  void (*free_fn)(void *ptr);
+} gpr_allocation_functions;
+
+/* malloc, never returns NULL */
+GPRAPI void *gpr_malloc(size_t size);
+/* free */
+GPRAPI void gpr_free(void *ptr);
+/* realloc, never returns NULL */
+GPRAPI void *gpr_realloc(void *p, size_t size);
+/* aligned malloc, never returns NULL, will align to 1 << alignment_log */
+GPRAPI void *gpr_malloc_aligned(size_t size, size_t alignment_log);
+/* free memory allocated by gpr_malloc_aligned */
+GPRAPI void gpr_free_aligned(void *ptr);
+
+/** Request the family of allocation functions in \a functions be used. NOTE
+ * that this request will be honored in a *best effort* basis and that no
+ * guarantees are made about the default functions (eg, malloc) being called. */
+GPRAPI void gpr_set_allocation_functions(gpr_allocation_functions functions);
+
+/** Return the family of allocation functions currently in effect. */
+GPRAPI gpr_allocation_functions gpr_get_allocation_functions();
+
+#ifdef __cplusplus
+}
+#endif
 
 #endif /* GRPC_SUPPORT_ALLOC_H */
diff --git a/include/grpc/support/log.h b/include/grpc/support/log.h
index 3fdba04..5acf17f 100644
--- a/include/grpc/support/log.h
+++ b/include/grpc/support/log.h
@@ -34,6 +34,85 @@
 #ifndef GRPC_SUPPORT_LOG_H
 #define GRPC_SUPPORT_LOG_H
 
-#include <grpc/impl/codegen/log.h>
+#include <inttypes.h>
+#include <stdarg.h>
+#include <stdlib.h> /* for abort() */
+
+#include <grpc/impl/codegen/port_platform.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* GPR log API.
+
+   Usage (within grpc):
+
+   int argument1 = 3;
+   char* argument2 = "hello";
+   gpr_log(GPR_DEBUG, "format string %d", argument1);
+   gpr_log(GPR_INFO, "hello world");
+   gpr_log(GPR_ERROR, "%d %s!!", argument1, argument2); */
+
+/* The severity of a log message - use the #defines below when calling into
+   gpr_log to additionally supply file and line data */
+typedef enum gpr_log_severity {
+  GPR_LOG_SEVERITY_DEBUG,
+  GPR_LOG_SEVERITY_INFO,
+  GPR_LOG_SEVERITY_ERROR
+} gpr_log_severity;
+
+#define GPR_LOG_VERBOSITY_UNSET -1
+
+/* Returns a string representation of the log severity */
+const char *gpr_log_severity_string(gpr_log_severity severity);
+
+/* Macros to build log contexts at various severity levels */
+#define GPR_DEBUG __FILE__, __LINE__, GPR_LOG_SEVERITY_DEBUG
+#define GPR_INFO __FILE__, __LINE__, GPR_LOG_SEVERITY_INFO
+#define GPR_ERROR __FILE__, __LINE__, GPR_LOG_SEVERITY_ERROR
+
+/* Log a message. It's advised to use GPR_xxx above to generate the context
+ * for each message */
+GPRAPI void gpr_log(const char *file, int line, gpr_log_severity severity,
+                    const char *format, ...) GPRC_PRINT_FORMAT_CHECK(4, 5);
+
+GPRAPI void gpr_log_message(const char *file, int line,
+                            gpr_log_severity severity, const char *message);
+
+/* Set global log verbosity */
+GPRAPI void gpr_set_log_verbosity(gpr_log_severity min_severity_to_print);
+
+GPRAPI void gpr_log_verbosity_init();
+
+/* Log overrides: applications can use this API to intercept logging calls
+   and use their own implementations */
+
+typedef struct {
+  const char *file;
+  int line;
+  gpr_log_severity severity;
+  const char *message;
+} gpr_log_func_args;
+
+typedef void (*gpr_log_func)(gpr_log_func_args *args);
+GPRAPI void gpr_set_log_function(gpr_log_func func);
+
+/* abort() the process if x is zero, having written a line to the log.
+
+   Intended for internal invariants.  If the error can be recovered from,
+   without the possibility of corruption, or might best be reflected via
+   an exception in a higher-level language, consider returning error code.  */
+#define GPR_ASSERT(x)                                 \
+  do {                                                \
+    if (!(x)) {                                       \
+      gpr_log(GPR_ERROR, "assertion failed: %s", #x); \
+      abort();                                        \
+    }                                                 \
+  } while (0)
+
+#ifdef __cplusplus
+}
+#endif
 
 #endif /* GRPC_SUPPORT_LOG_H */
diff --git a/include/grpc/support/slice.h b/include/grpc/support/slice.h
index b45db03..b31fe6c 100644
--- a/include/grpc/support/slice.h
+++ b/include/grpc/support/slice.h
@@ -35,5 +35,94 @@
 #define GRPC_SUPPORT_SLICE_H
 
 #include <grpc/impl/codegen/slice.h>
+#include <grpc/support/sync.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Increment the refcount of s. Requires slice is initialized.
+   Returns s. */
+GPRAPI gpr_slice gpr_slice_ref(gpr_slice s);
+
+/* Decrement the ref count of s.  If the ref count of s reaches zero, all
+   slices sharing the ref count are destroyed, and considered no longer
+   initialized.  If s is ultimately derived from a call to gpr_slice_new(start,
+   len, dest) where dest!=NULL , then (*dest)(start) is called, else if s is
+   ultimately derived from a call to gpr_slice_new_with_len(start, len, dest)
+   where dest!=NULL , then (*dest)(start, len).  Requires s initialized.  */
+GPRAPI void gpr_slice_unref(gpr_slice s);
+
+/* Create a slice pointing at some data. Calls malloc to allocate a refcount
+   for the object, and arranges that destroy will be called with the pointer
+   passed in at destruction. */
+GPRAPI gpr_slice gpr_slice_new(void *p, size_t len, void (*destroy)(void *));
+
+/* Equivalent to gpr_slice_new, but with a separate pointer that is
+   passed to the destroy function.  This function can be useful when
+   the data is part of a larger structure that must be destroyed when
+   the data is no longer needed. */
+GPRAPI gpr_slice gpr_slice_new_with_user_data(void *p, size_t len,
+                                              void (*destroy)(void *),
+                                              void *user_data);
+
+/* Equivalent to gpr_slice_new, but with a two argument destroy function that
+   also takes the slice length. */
+GPRAPI gpr_slice gpr_slice_new_with_len(void *p, size_t len,
+                                        void (*destroy)(void *, size_t));
+
+/* Equivalent to gpr_slice_new(malloc(len), len, free), but saves one malloc()
+   call.
+   Aborts if malloc() fails. */
+GPRAPI gpr_slice gpr_slice_malloc(size_t length);
+
+/* Create a slice by copying a string.
+   Does not preserve null terminators.
+   Equivalent to:
+     size_t len = strlen(source);
+     gpr_slice slice = gpr_slice_malloc(len);
+     memcpy(slice->data, source, len); */
+GPRAPI gpr_slice gpr_slice_from_copied_string(const char *source);
+
+/* Create a slice by copying a buffer.
+   Equivalent to:
+     gpr_slice slice = gpr_slice_malloc(len);
+     memcpy(slice->data, source, len); */
+GPRAPI gpr_slice gpr_slice_from_copied_buffer(const char *source, size_t len);
+
+/* Create a slice pointing to constant memory */
+GPRAPI gpr_slice gpr_slice_from_static_string(const char *source);
+
+/* Return a result slice derived from s, which shares a ref count with s, where
+   result.data==s.data+begin, and result.length==end-begin.
+   The ref count of s is increased by one.
+   Requires s initialized, begin <= end, begin <= s.length, and
+   end <= source->length. */
+GPRAPI gpr_slice gpr_slice_sub(gpr_slice s, size_t begin, size_t end);
+
+/* The same as gpr_slice_sub, but without altering the ref count */
+GPRAPI gpr_slice gpr_slice_sub_no_ref(gpr_slice s, size_t begin, size_t end);
+
+/* Splits s into two: modifies s to be s[0:split], and returns a new slice,
+   sharing a refcount with s, that contains s[split:s.length].
+   Requires s intialized, split <= s.length */
+GPRAPI gpr_slice gpr_slice_split_tail(gpr_slice *s, size_t split);
+
+/* Splits s into two: modifies s to be s[split:s.length], and returns a new
+   slice, sharing a refcount with s, that contains s[0:split].
+   Requires s intialized, split <= s.length */
+GPRAPI gpr_slice gpr_slice_split_head(gpr_slice *s, size_t split);
+
+GPRAPI gpr_slice gpr_empty_slice(void);
+
+/* Returns <0 if a < b, ==0 if a == b, >0 if a > b
+   The order is arbitrary, and is not guaranteed to be stable across different
+   versions of the API. */
+GPRAPI int gpr_slice_cmp(gpr_slice a, gpr_slice b);
+GPRAPI int gpr_slice_str_cmp(gpr_slice a, const char *b);
+
+#ifdef __cplusplus
+}
+#endif
 
 #endif /* GRPC_SUPPORT_SLICE_H */
diff --git a/include/grpc/support/slice_buffer.h b/include/grpc/support/slice_buffer.h
index cf7a89f..3920432 100644
--- a/include/grpc/support/slice_buffer.h
+++ b/include/grpc/support/slice_buffer.h
@@ -34,6 +34,54 @@
 #ifndef GRPC_SUPPORT_SLICE_BUFFER_H
 #define GRPC_SUPPORT_SLICE_BUFFER_H
 
-#include <grpc/impl/codegen/slice_buffer.h>
+#include <grpc/support/slice.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* initialize a slice buffer */
+GPRAPI void gpr_slice_buffer_init(gpr_slice_buffer *sb);
+/* destroy a slice buffer - unrefs any held elements */
+GPRAPI void gpr_slice_buffer_destroy(gpr_slice_buffer *sb);
+/* Add an element to a slice buffer - takes ownership of the slice.
+   This function is allowed to concatenate the passed in slice to the end of
+   some other slice if desired by the slice buffer. */
+GPRAPI void gpr_slice_buffer_add(gpr_slice_buffer *sb, gpr_slice slice);
+/* add an element to a slice buffer - takes ownership of the slice and returns
+   the index of the slice.
+   Guarantees that the slice will not be concatenated at the end of another
+   slice (i.e. the data for this slice will begin at the first byte of the
+   slice at the returned index in sb->slices)
+   The implementation MAY decide to concatenate data at the end of a small
+   slice added in this fashion. */
+GPRAPI size_t gpr_slice_buffer_add_indexed(gpr_slice_buffer *sb,
+                                           gpr_slice slice);
+GPRAPI void gpr_slice_buffer_addn(gpr_slice_buffer *sb, gpr_slice *slices,
+                                  size_t n);
+/* add a very small (less than 8 bytes) amount of data to the end of a slice
+   buffer: returns a pointer into which to add the data */
+GPRAPI uint8_t *gpr_slice_buffer_tiny_add(gpr_slice_buffer *sb, size_t len);
+/* pop the last buffer, but don't unref it */
+GPRAPI void gpr_slice_buffer_pop(gpr_slice_buffer *sb);
+/* clear a slice buffer, unref all elements */
+GPRAPI void gpr_slice_buffer_reset_and_unref(gpr_slice_buffer *sb);
+/* swap the contents of two slice buffers */
+GPRAPI void gpr_slice_buffer_swap(gpr_slice_buffer *a, gpr_slice_buffer *b);
+/* move all of the elements of src into dst */
+GPRAPI void gpr_slice_buffer_move_into(gpr_slice_buffer *src,
+                                       gpr_slice_buffer *dst);
+/* remove n bytes from the end of a slice buffer */
+GPRAPI void gpr_slice_buffer_trim_end(gpr_slice_buffer *src, size_t n,
+                                      gpr_slice_buffer *garbage);
+/* move the first n bytes of src into dst */
+GPRAPI void gpr_slice_buffer_move_first(gpr_slice_buffer *src, size_t n,
+                                        gpr_slice_buffer *dst);
+/* take the first slice in the slice buffer */
+GPRAPI gpr_slice gpr_slice_buffer_take_first(gpr_slice_buffer *src);
+
+#ifdef __cplusplus
+}
+#endif
 
 #endif /* GRPC_SUPPORT_SLICE_BUFFER_H */
diff --git a/include/grpc/support/sync.h b/include/grpc/support/sync.h
index a014580..a7bbb38 100644
--- a/include/grpc/support/sync.h
+++ b/include/grpc/support/sync.h
@@ -34,6 +34,258 @@
 #ifndef GRPC_SUPPORT_SYNC_H
 #define GRPC_SUPPORT_SYNC_H
 
+#include <grpc/impl/codegen/gpr_types.h> /* for gpr_timespec */
 #include <grpc/impl/codegen/sync.h>
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* --- Mutex interface ---
+
+   At most one thread may hold an exclusive lock on a mutex at any given time.
+   Actions taken by a thread that holds a mutex exclusively happen after
+   actions taken by all previous holders of the mutex.  Variables of type
+   gpr_mu are uninitialized when first declared.  */
+
+/* Initialize *mu.  Requires:  *mu uninitialized.  */
+GPRAPI void gpr_mu_init(gpr_mu *mu);
+
+/* Cause *mu no longer to be initialized, freeing any memory in use.  Requires:
+   *mu initialized; no other concurrent operation on *mu.  */
+GPRAPI void gpr_mu_destroy(gpr_mu *mu);
+
+/* Wait until no thread has a lock on *mu, cause the calling thread to own an
+   exclusive lock on *mu, then return.  May block indefinitely or crash if the
+   calling thread has a lock on *mu.  Requires:  *mu initialized.  */
+GPRAPI void gpr_mu_lock(gpr_mu *mu);
+
+/* Release an exclusive lock on *mu held by the calling thread.  Requires:  *mu
+   initialized; the calling thread holds an exclusive lock on *mu.  */
+GPRAPI void gpr_mu_unlock(gpr_mu *mu);
+
+/* Without blocking, attempt to acquire an exclusive lock on *mu for the
+   calling thread, then return non-zero iff success.  Fail, if any thread holds
+   the lock; succeeds with high probability if no thread holds the lock.
+   Requires:  *mu initialized.  */
+GPRAPI int gpr_mu_trylock(gpr_mu *mu);
+
+/* --- Condition variable interface ---
+
+   A while-loop should be used with gpr_cv_wait() when waiting for conditions
+   to become true.  See the example below.  Variables of type gpr_cv are
+   uninitialized when first declared.  */
+
+/* Initialize *cv.  Requires:  *cv uninitialized.  */
+GPRAPI void gpr_cv_init(gpr_cv *cv);
+
+/* Cause *cv no longer to be initialized, freeing any memory in use.  Requires:
+   *cv initialized; no other concurrent operation on *cv.*/
+GPRAPI void gpr_cv_destroy(gpr_cv *cv);
+
+/* Atomically release *mu and wait on *cv.  When the calling thread is woken
+   from *cv or the deadline abs_deadline is exceeded, execute gpr_mu_lock(mu)
+   and return whether the deadline was exceeded.  Use
+   abs_deadline==gpr_inf_future for no deadline.  abs_deadline can be either
+   an absolute deadline, or a GPR_TIMESPAN.  May return even when not
+   woken explicitly.  Requires:  *mu and *cv initialized; the calling thread
+   holds an exclusive lock on *mu.  */
+GPRAPI int gpr_cv_wait(gpr_cv *cv, gpr_mu *mu, gpr_timespec abs_deadline);
+
+/* If any threads are waiting on *cv, wake at least one.
+   Clients may treat this as an optimization of gpr_cv_broadcast()
+   for use in the case where waking more than one waiter is not useful.
+   Requires:  *cv initialized.  */
+GPRAPI void gpr_cv_signal(gpr_cv *cv);
+
+/* Wake all threads waiting on *cv.  Requires:  *cv initialized.  */
+GPRAPI void gpr_cv_broadcast(gpr_cv *cv);
+
+/* --- One-time initialization ---
+
+   gpr_once must be declared with static storage class, and initialized with
+   GPR_ONCE_INIT.  e.g.,
+     static gpr_once once_var = GPR_ONCE_INIT;     */
+
+/* Ensure that (*init_routine)() has been called exactly once (for the
+   specified gpr_once instance) and then return.
+   If multiple threads call gpr_once() on the same gpr_once instance, one of
+   them will call (*init_routine)(), and the others will block until that call
+   finishes.*/
+GPRAPI void gpr_once_init(gpr_once *once, void (*init_routine)(void));
+
+/* --- One-time event notification ---
+
+  These operations act on a gpr_event, which should be initialized with
+  gpr_ev_init(), or with GPR_EVENT_INIT if static, e.g.,
+       static gpr_event event_var = GPR_EVENT_INIT;
+  It requires no destruction.  */
+
+/* Initialize *ev. */
+GPRAPI void gpr_event_init(gpr_event *ev);
+
+/* Set *ev so that gpr_event_get() and gpr_event_wait() will return value.
+   Requires:  *ev initialized; value != NULL; no prior or concurrent calls to
+   gpr_event_set(ev, ...) since initialization.  */
+GPRAPI void gpr_event_set(gpr_event *ev, void *value);
+
+/* Return the value set by gpr_event_set(ev, ...), or NULL if no such call has
+   completed.  If the result is non-NULL, all operations that occurred prior to
+   the gpr_event_set(ev, ...) set will be visible after this call returns.
+   Requires:  *ev initialized.  This operation is faster than acquiring a mutex
+   on most platforms.  */
+GPRAPI void *gpr_event_get(gpr_event *ev);
+
+/* Wait until *ev is set by gpr_event_set(ev, ...), or abs_deadline is
+   exceeded, then return gpr_event_get(ev).  Requires:  *ev initialized.  Use
+   abs_deadline==gpr_inf_future for no deadline.  When the event has been
+   signalled before the call, this operation is faster than acquiring a mutex
+   on most platforms.  */
+GPRAPI void *gpr_event_wait(gpr_event *ev, gpr_timespec abs_deadline);
+
+/* --- Reference counting ---
+
+   These calls act on the type gpr_refcount.  It requires no destruction.  */
+
+/* Initialize *r to value n.  */
+GPRAPI void gpr_ref_init(gpr_refcount *r, int n);
+
+/* Increment the reference count *r.  Requires *r initialized. */
+GPRAPI void gpr_ref(gpr_refcount *r);
+
+/* Increment the reference count *r.  Requires *r initialized.
+   Crashes if refcount is zero */
+GPRAPI void gpr_ref_non_zero(gpr_refcount *r);
+
+/* Increment the reference count *r by n.  Requires *r initialized, n > 0. */
+GPRAPI void gpr_refn(gpr_refcount *r, int n);
+
+/* Decrement the reference count *r and return non-zero iff it has reached
+   zero. .  Requires *r initialized. */
+GPRAPI int gpr_unref(gpr_refcount *r);
+
+/* --- Stats counters ---
+
+   These calls act on the integral type gpr_stats_counter.  It requires no
+   destruction.  Static instances may be initialized with
+       gpr_stats_counter c = GPR_STATS_INIT;
+   Beware:  These operations do not imply memory barriers.  Do not use them to
+   synchronize other events.  */
+
+/* Initialize *c to the value n. */
+GPRAPI void gpr_stats_init(gpr_stats_counter *c, intptr_t n);
+
+/* *c += inc.  Requires: *c initialized. */
+GPRAPI void gpr_stats_inc(gpr_stats_counter *c, intptr_t inc);
+
+/* Return *c.  Requires: *c initialized. */
+GPRAPI intptr_t gpr_stats_read(const gpr_stats_counter *c);
+
+/* ==================Example use of interface===================
+   A producer-consumer queue of up to N integers,
+   illustrating the use of the calls in this interface. */
+#if 0
+
+#define N 4
+
+   typedef struct queue {
+     gpr_cv non_empty;  /* Signalled when length becomes non-zero. */
+     gpr_cv non_full;   /* Signalled when length becomes non-N. */
+     gpr_mu mu;         /* Protects all fields below.
+                            (That is, except during initialization or
+                            destruction, the fields below should be accessed
+                            only by a thread that holds mu.) */
+     int head;           /* Index of head of queue 0..N-1. */
+     int length;         /* Number of valid elements in queue 0..N. */
+     int elem[N];        /* elem[head .. head+length-1] are queue elements. */
+   } queue;
+
+   /* Initialize *q. */
+   void queue_init(queue *q) {
+     gpr_mu_init(&q->mu);
+     gpr_cv_init(&q->non_empty);
+     gpr_cv_init(&q->non_full);
+     q->head = 0;
+     q->length = 0;
+   }
+
+   /* Free storage associated with *q. */
+   void queue_destroy(queue *q) {
+     gpr_mu_destroy(&q->mu);
+     gpr_cv_destroy(&q->non_empty);
+     gpr_cv_destroy(&q->non_full);
+   }
+
+   /* Wait until there is room in *q, then append x to *q. */
+   void queue_append(queue *q, int x) {
+     gpr_mu_lock(&q->mu);
+     /* To wait for a predicate without a deadline, loop on the negation of the
+        predicate, and use gpr_cv_wait(..., gpr_inf_future) inside the loop
+        to release the lock, wait, and reacquire on each iteration.  Code that
+        makes the condition true should use gpr_cv_broadcast() on the
+        corresponding condition variable.  The predicate must be on state
+        protected by the lock.  */
+     while (q->length == N) {
+       gpr_cv_wait(&q->non_full, &q->mu, gpr_inf_future);
+     }
+     if (q->length == 0) {  /* Wake threads blocked in queue_remove(). */
+       /* It's normal to use gpr_cv_broadcast() or gpr_signal() while
+          holding the lock. */
+       gpr_cv_broadcast(&q->non_empty);
+     }
+     q->elem[(q->head + q->length) % N] = x;
+     q->length++;
+     gpr_mu_unlock(&q->mu);
+   }
+
+   /* If it can be done without blocking, append x to *q and return non-zero.
+      Otherwise return 0. */
+   int queue_try_append(queue *q, int x) {
+     int result = 0;
+     if (gpr_mu_trylock(&q->mu)) {
+       if (q->length != N) {
+         if (q->length == 0) {  /* Wake threads blocked in queue_remove(). */
+           gpr_cv_broadcast(&q->non_empty);
+         }
+         q->elem[(q->head + q->length) % N] = x;
+         q->length++;
+         result = 1;
+       }
+       gpr_mu_unlock(&q->mu);
+     }
+     return result;
+   }
+
+   /* Wait until the *q is non-empty or deadline abs_deadline passes.  If the
+      queue is non-empty, remove its head entry, place it in *head, and return
+      non-zero.  Otherwise return 0.  */
+   int queue_remove(queue *q, int *head, gpr_timespec abs_deadline) {
+     int result = 0;
+     gpr_mu_lock(&q->mu);
+     /* To wait for a predicate with a deadline, loop on the negation of the
+        predicate or until gpr_cv_wait() returns true.  Code that makes
+        the condition true should use gpr_cv_broadcast() on the corresponding
+        condition variable.  The predicate must be on state protected by the
+        lock. */
+     while (q->length == 0 &&
+            !gpr_cv_wait(&q->non_empty, &q->mu, abs_deadline)) {
+     }
+     if (q->length != 0) {    /* Queue is non-empty. */
+       result = 1;
+       if (q->length == N) {  /* Wake threads blocked in queue_append(). */
+         gpr_cv_broadcast(&q->non_full);
+       }
+       *head = q->elem[q->head];
+       q->head = (q->head + 1) % N;
+       q->length--;
+     } /* else deadline exceeded */
+     gpr_mu_unlock(&q->mu);
+     return result;
+   }
+#endif /* 0 */
+
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* GRPC_SUPPORT_SYNC_H */
diff --git a/include/grpc/support/time.h b/include/grpc/support/time.h
index b3f2f8c..66bcfca 100644
--- a/include/grpc/support/time.h
+++ b/include/grpc/support/time.h
@@ -34,6 +34,72 @@
 #ifndef GRPC_SUPPORT_TIME_H
 #define GRPC_SUPPORT_TIME_H
 
-#include <grpc/impl/codegen/time.h>
+#include <grpc/impl/codegen/gpr_types.h>
+
+#include <stddef.h>
+#include <time.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Time constants. */
+GPRAPI gpr_timespec
+gpr_time_0(gpr_clock_type type); /* The zero time interval. */
+GPRAPI gpr_timespec gpr_inf_future(gpr_clock_type type); /* The far future */
+GPRAPI gpr_timespec gpr_inf_past(gpr_clock_type type);   /* The far past. */
+
+#define GPR_MS_PER_SEC 1000
+#define GPR_US_PER_SEC 1000000
+#define GPR_NS_PER_SEC 1000000000
+#define GPR_NS_PER_MS 1000000
+#define GPR_NS_PER_US 1000
+#define GPR_US_PER_MS 1000
+
+/* initialize time subsystem */
+GPRAPI void gpr_time_init(void);
+
+/* Return the current time measured from the given clocks epoch. */
+GPRAPI gpr_timespec gpr_now(gpr_clock_type clock);
+
+/* Convert a timespec from one clock to another */
+GPRAPI gpr_timespec gpr_convert_clock_type(gpr_timespec t,
+                                           gpr_clock_type target_clock);
+
+/* Return -ve, 0, or +ve according to whether a < b, a == b, or a > b
+   respectively.  */
+GPRAPI int gpr_time_cmp(gpr_timespec a, gpr_timespec b);
+
+GPRAPI gpr_timespec gpr_time_max(gpr_timespec a, gpr_timespec b);
+GPRAPI gpr_timespec gpr_time_min(gpr_timespec a, gpr_timespec b);
+
+/* Add and subtract times.  Calculations saturate at infinities. */
+GPRAPI gpr_timespec gpr_time_add(gpr_timespec a, gpr_timespec b);
+GPRAPI gpr_timespec gpr_time_sub(gpr_timespec a, gpr_timespec b);
+
+/* Return a timespec representing a given number of time units. INT64_MIN is
+   interpreted as gpr_inf_past, and INT64_MAX as gpr_inf_future.  */
+GPRAPI gpr_timespec gpr_time_from_micros(int64_t x, gpr_clock_type clock_type);
+GPRAPI gpr_timespec gpr_time_from_nanos(int64_t x, gpr_clock_type clock_type);
+GPRAPI gpr_timespec gpr_time_from_millis(int64_t x, gpr_clock_type clock_type);
+GPRAPI gpr_timespec gpr_time_from_seconds(int64_t x, gpr_clock_type clock_type);
+GPRAPI gpr_timespec gpr_time_from_minutes(int64_t x, gpr_clock_type clock_type);
+GPRAPI gpr_timespec gpr_time_from_hours(int64_t x, gpr_clock_type clock_type);
+
+GPRAPI int32_t gpr_time_to_millis(gpr_timespec timespec);
+
+/* Return 1 if two times are equal or within threshold of each other,
+   0 otherwise */
+GPRAPI int gpr_time_similar(gpr_timespec a, gpr_timespec b,
+                            gpr_timespec threshold);
+
+/* Sleep until at least 'until' - an absolute timeout */
+GPRAPI void gpr_sleep_until(gpr_timespec until);
+
+GPRAPI double gpr_timespec_to_micros(gpr_timespec t);
+
+#ifdef __cplusplus
+}
+#endif
 
 #endif /* GRPC_SUPPORT_TIME_H */
diff --git a/package.xml b/package.xml
index 613b5c6..8262ef6 100644
--- a/package.xml
+++ b/package.xml
@@ -79,25 +79,23 @@
     <file baseinstalldir="/" name="include/grpc/support/tls_msvc.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/support/tls_pthread.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/support/useful.h" role="src" />
-    <file baseinstalldir="/" name="include/grpc/impl/codegen/alloc.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/impl/codegen/atm.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/impl/codegen/atm_gcc_atomic.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/impl/codegen/atm_gcc_sync.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/impl/codegen/atm_windows.h" role="src" />
-    <file baseinstalldir="/" name="include/grpc/impl/codegen/log.h" role="src" />
+    <file baseinstalldir="/" name="include/grpc/impl/codegen/gpr_types.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/impl/codegen/port_platform.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/impl/codegen/slice.h" role="src" />
-    <file baseinstalldir="/" name="include/grpc/impl/codegen/slice_buffer.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/impl/codegen/sync.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/impl/codegen/sync_generic.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/impl/codegen/sync_posix.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/impl/codegen/sync_windows.h" role="src" />
-    <file baseinstalldir="/" name="include/grpc/impl/codegen/time.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/profiling/timers.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/support/backoff.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/support/block_annotate.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/support/env.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/support/murmur_hash.h" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/support/percent_encoding.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/support/stack_lockfree.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/support/string.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/support/string_windows.h" role="src" />
@@ -125,6 +123,7 @@
     <file baseinstalldir="/" name="src/core/lib/support/log_posix.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/support/log_windows.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/support/murmur_hash.c" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/support/percent_encoding.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/support/slice.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/support/slice_buffer.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/support/stack_lockfree.c" role="src" />
@@ -156,27 +155,23 @@
     <file baseinstalldir="/" name="include/grpc/grpc_posix.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/grpc_security_constants.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/byte_buffer_reader.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/impl/codegen/alloc.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/impl/codegen/atm.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/impl/codegen/atm_gcc_atomic.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/impl/codegen/atm_gcc_sync.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/impl/codegen/atm_windows.h" role="src" />
-    <file baseinstalldir="/" name="include/grpc/impl/codegen/log.h" role="src" />
+    <file baseinstalldir="/" name="include/grpc/impl/codegen/gpr_types.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/impl/codegen/port_platform.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/impl/codegen/slice.h" role="src" />
-    <file baseinstalldir="/" name="include/grpc/impl/codegen/slice_buffer.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/impl/codegen/sync.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/impl/codegen/sync_generic.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/impl/codegen/sync_posix.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/impl/codegen/sync_windows.h" role="src" />
-    <file baseinstalldir="/" name="include/grpc/impl/codegen/time.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/grpc_security.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/census.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/channel/channel_args.h" role="src" />
diff --git a/setup.py b/setup.py
index f728095..7a65698 100644
--- a/setup.py
+++ b/setup.py
@@ -198,12 +198,14 @@
 INSTALL_REQUIRES = (
     'six>=1.5.2',
     'enum34>=1.0.4',
-    'futures>=2.2.0',
     # TODO(atash): eventually split the grpcio package into a metapackage
     # depending on protobuf and the runtime component (independent of protobuf)
     'protobuf>=3.0.0',
 )
 
+if not PY3:
+  INSTALL_REQUIRES += ('futures>=2.2.0',)
+
 SETUP_REQUIRES = INSTALL_REQUIRES + (
     'sphinx>=1.3',
     'sphinx_rtd_theme>=0.1.8',
diff --git a/src/compiler/cpp_generator.cc b/src/compiler/cpp_generator.cc
index c386115..d0c35ea 100644
--- a/src/compiler/cpp_generator.cc
+++ b/src/compiler/cpp_generator.cc
@@ -130,6 +130,7 @@
     static const char *headers_strs[] = {
         "grpc++/impl/codegen/async_stream.h",
         "grpc++/impl/codegen/async_unary_call.h",
+        "grpc++/impl/codegen/method_handler_impl.h",
         "grpc++/impl/codegen/proto_utils.h",
         "grpc++/impl/codegen/rpc_method.h",
         "grpc++/impl/codegen/service_type.h",
@@ -604,6 +605,57 @@
   printer->Print(*vars, "};\n");
 }
 
+void PrintHeaderServerMethodStreamedUnary(
+    Printer *printer, const Method *method,
+    std::map<grpc::string, grpc::string> *vars) {
+  (*vars)["Method"] = method->name();
+  (*vars)["Request"] = method->input_type_name();
+  (*vars)["Response"] = method->output_type_name();
+  if (method->NoStreaming()) {
+    printer->Print(*vars, "template <class BaseClass>\n");
+    printer->Print(*vars,
+                   "class WithStreamedUnaryMethod_$Method$ : "
+                   "public BaseClass {\n");
+    printer->Print(
+        " private:\n"
+        "  void BaseClassMustBeDerivedFromService(const Service *service) "
+        "{}\n");
+    printer->Print(" public:\n");
+    printer->Indent();
+    printer->Print(*vars,
+                   "WithStreamedUnaryMethod_$Method$() {\n"
+                   "  ::grpc::Service::MarkMethodStreamedUnary($Idx$,\n"
+                   "    new ::grpc::StreamedUnaryHandler< $Request$, "
+                   "$Response$>(std::bind"
+                   "(&WithStreamedUnaryMethod_$Method$<BaseClass>::"
+                   "Streamed$Method$, this, std::placeholders::_1, "
+                   "std::placeholders::_2)));\n"
+                   "}\n");
+    printer->Print(*vars,
+                   "~WithStreamedUnaryMethod_$Method$() GRPC_OVERRIDE {\n"
+                   "  BaseClassMustBeDerivedFromService(this);\n"
+                   "}\n");
+    printer->Print(
+        *vars,
+        "// disable regular version of this method\n"
+        "::grpc::Status $Method$("
+        "::grpc::ServerContext* context, const $Request$* request, "
+        "$Response$* response) GRPC_FINAL GRPC_OVERRIDE {\n"
+        "  abort();\n"
+        "  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, \"\");\n"
+        "}\n");
+    printer->Print(*vars,
+                   "// replace default version of method with streamed unary\n"
+                   "virtual ::grpc::Status Streamed$Method$("
+                   "::grpc::ServerContext* context, "
+                   "::grpc::ServerUnaryStreamer< "
+                   "$Request$,$Response$>* server_unary_streamer)"
+                   " = 0;\n");
+    printer->Outdent();
+    printer->Print(*vars, "};\n");
+  }
+}
+
 void PrintHeaderServerMethodGeneric(
     Printer *printer, const Method *method,
     std::map<grpc::string, grpc::string> *vars) {
@@ -770,6 +822,28 @@
     PrintHeaderServerMethodGeneric(printer, service->method(i).get(), vars);
   }
 
+  // Server side - Streamed Unary
+  for (int i = 0; i < service->method_count(); ++i) {
+    (*vars)["Idx"] = as_string(i);
+    PrintHeaderServerMethodStreamedUnary(printer, service->method(i).get(),
+                                         vars);
+  }
+
+  printer->Print("typedef ");
+  for (int i = 0; i < service->method_count(); ++i) {
+    (*vars)["method_name"] = service->method(i).get()->name();
+    if (service->method(i)->NoStreaming()) {
+      printer->Print(*vars, "WithStreamedUnaryMethod_$method_name$<");
+    }
+  }
+  printer->Print("Service");
+  for (int i = 0; i < service->method_count(); ++i) {
+    if (service->method(i)->NoStreaming()) {
+      printer->Print(" >");
+    }
+  }
+  printer->Print(" StreamedUnaryService;\n");
+
   printer->Outdent();
   printer->Print("};\n");
   printer->Print(service->GetTrailingComments().c_str());
@@ -1080,6 +1154,9 @@
     (*vars)["Idx"] = as_string(i);
     if (method->NoStreaming()) {
       (*vars)["StreamingType"] = "NORMAL_RPC";
+      // NOTE: There is no reason to consider streamed-unary as a separate
+      // category here since this part is setting up the client-side stub
+      // and this appears as a NORMAL_RPC from the client-side.
     } else if (method->ClientOnlyStreaming()) {
       (*vars)["StreamingType"] = "CLIENT_STREAMING";
     } else if (method->ServerOnlyStreaming()) {
diff --git a/src/core/ext/client_config/client_channel.c b/src/core/ext/client_config/client_channel.c
index dfa9746..42050d7 100644
--- a/src/core/ext/client_config/client_channel.c
+++ b/src/core/ext/client_config/client_channel.c
@@ -394,6 +394,8 @@
   grpc_closure next_step;
 
   grpc_call_stack *owning_call;
+
+  grpc_linked_mdelem lb_token_mdelem;
 } call_data;
 
 static void add_waiting_locked(call_data *calld, grpc_transport_stream_op *op) {
@@ -572,9 +574,11 @@
     int r;
     GRPC_LB_POLICY_REF(lb_policy, "pick_subchannel");
     gpr_mu_unlock(&chand->mu);
-    r = grpc_lb_policy_pick(exec_ctx, lb_policy, initial_metadata,
-                            initial_metadata_flags, connected_subchannel,
-                            on_ready);
+    const grpc_lb_policy_pick_args inputs = {calld->pollent, initial_metadata,
+                                             initial_metadata_flags,
+                                             &calld->lb_token_mdelem};
+    r = grpc_lb_policy_pick(exec_ctx, lb_policy, &inputs, connected_subchannel,
+                            NULL, on_ready);
     GRPC_LB_POLICY_UNREF(exec_ctx, lb_policy, "pick_subchannel");
     GPR_TIMER_END("pick_subchannel", 0);
     return r;
diff --git a/src/core/ext/client_config/lb_policy.c b/src/core/ext/client_config/lb_policy.c
index 0e02de0..903563e 100644
--- a/src/core/ext/client_config/lb_policy.c
+++ b/src/core/ext/client_config/lb_policy.c
@@ -100,12 +100,11 @@
 }
 
 int grpc_lb_policy_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy,
-                        grpc_metadata_batch *initial_metadata,
-                        uint32_t initial_metadata_flags,
-                        grpc_connected_subchannel **target,
+                        const grpc_lb_policy_pick_args *pick_args,
+                        grpc_connected_subchannel **target, void **user_data,
                         grpc_closure *on_complete) {
-  return policy->vtable->pick(exec_ctx, policy, initial_metadata,
-                              initial_metadata_flags, target, on_complete);
+  return policy->vtable->pick(exec_ctx, policy, pick_args, target, user_data,
+                              on_complete);
 }
 
 void grpc_lb_policy_cancel_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy,
diff --git a/src/core/ext/client_config/lb_policy.h b/src/core/ext/client_config/lb_policy.h
index a244b06..ef412b7 100644
--- a/src/core/ext/client_config/lb_policy.h
+++ b/src/core/ext/client_config/lb_policy.h
@@ -52,22 +52,38 @@
   grpc_pollset_set *interested_parties;
 };
 
+/** Extra arguments for an LB pick */
+typedef struct grpc_lb_policy_pick_args {
+  /** Parties interested in the pick's progress */
+  grpc_polling_entity *pollent;
+  /** Initial metadata associated with the picking call. */
+  grpc_metadata_batch *initial_metadata;
+  /** See \a GRPC_INITIAL_METADATA_* in grpc_types.h */
+  uint32_t initial_metadata_flags;
+  /** Storage for LB token in \a initial_metadata, or NULL if not used */
+  grpc_linked_mdelem *lb_token_mdelem_storage;
+} grpc_lb_policy_pick_args;
+
 struct grpc_lb_policy_vtable {
   void (*destroy)(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy);
-
   void (*shutdown)(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy);
 
-  /** implement grpc_lb_policy_pick */
+  /** \see grpc_lb_policy_pick */
   int (*pick)(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy,
-              grpc_metadata_batch *initial_metadata,
-              uint32_t initial_metadata_flags,
-              grpc_connected_subchannel **target, grpc_closure *on_complete);
+              const grpc_lb_policy_pick_args *pick_args,
+              grpc_connected_subchannel **target, void **user_data,
+              grpc_closure *on_complete);
+
+  /** \see grpc_lb_policy_cancel_pick */
   void (*cancel_pick)(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy,
                       grpc_connected_subchannel **target);
+
+  /** \see grpc_lb_policy_cancel_picks */
   void (*cancel_picks)(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy,
                        uint32_t initial_metadata_flags_mask,
                        uint32_t initial_metadata_flags_eq);
 
+  /** \see grpc_lb_policy_ping_one */
   void (*ping_one)(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy,
                    grpc_closure *closure);
 
@@ -81,8 +97,7 @@
 
   /** call notify when the connectivity state of a channel changes from *state.
       Updates *state with the new state of the policy. Calling with a NULL \a
-      state cancels the subscription.
-      */
+      state cancels the subscription.  */
   void (*notify_on_state_change)(grpc_exec_ctx *exec_ctx,
                                  grpc_lb_policy *policy,
                                  grpc_connectivity_state *state,
@@ -122,26 +137,35 @@
 void grpc_lb_policy_init(grpc_lb_policy *policy,
                          const grpc_lb_policy_vtable *vtable);
 
-/** Given initial metadata in \a initial_metadata, find an appropriate
-    target for this rpc, and 'return' it by calling \a on_complete after setting
-    \a target.
-    Picking can be asynchronous. Any IO should be done under the \a
-    interested_parties \a grpc_pollset_set in the \a grpc_lb_policy struct. */
+/** Find an appropriate target for this call, based on \a pick_args.
+    Picking can be synchronous or asynchronous. In the synchronous case, when a
+    pick is readily available, it'll be returned in \a target and a non-zero
+    value will be returned.
+    In the asynchronous case, zero is returned and \a on_complete will be called
+    once \a target and \a user_data have been set. Any IO should be done under
+    the \a interested_parties \a grpc_pollset_set in the \a grpc_lb_policy
+    struct. The opaque \a user_data output argument corresponds to information
+    that may need be propagated from the LB policy. It may be NULL. Errors are
+    signaled receiving a NULL \a *target. */
 int grpc_lb_policy_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy,
-                        grpc_metadata_batch *initial_metadata,
-                        uint32_t initial_metadata_flags,
-                        grpc_connected_subchannel **target,
+                        const grpc_lb_policy_pick_args *pick_args,
+                        grpc_connected_subchannel **target, void **user_data,
                         grpc_closure *on_complete);
 
+/** Perform a connected subchannel ping (see \a grpc_connected_subchannel_ping)
+    against one of the connected subchannels managed by \a policy. */
 void grpc_lb_policy_ping_one(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy,
                              grpc_closure *closure);
 
+/** Cancel picks for \a target.
+    The \a on_complete callback of the pending picks will be invoked with \a
+    *target set to NULL. */
 void grpc_lb_policy_cancel_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy,
                                 grpc_connected_subchannel **target);
 
-/** Cancel all pending picks which have:
-    (initial_metadata_flags & initial_metadata_flags_mask) ==
-         initial_metadata_flags_eq */
+/** Cancel all pending picks for which their \a initial_metadata_flags (as given
+    in the call to \a grpc_lb_policy_pick) matches \a initial_metadata_flags_eq
+    when AND'd with \a initial_metadata_flags_mask */
 void grpc_lb_policy_cancel_picks(grpc_exec_ctx *exec_ctx,
                                  grpc_lb_policy *policy,
                                  uint32_t initial_metadata_flags_mask,
diff --git a/src/core/ext/client_config/lb_policy_factory.h b/src/core/ext/client_config/lb_policy_factory.h
index da1de35..7191ca7 100644
--- a/src/core/ext/client_config/lb_policy_factory.h
+++ b/src/core/ext/client_config/lb_policy_factory.h
@@ -47,8 +47,19 @@
   const grpc_lb_policy_factory_vtable *vtable;
 };
 
+/** A resolved address alongside any LB related information associated with it.
+ * \a user_data, if not NULL, contains opaque data meant to be consumed by the
+ * gRPC LB policy. Note that no all LB policies support \a user_data as input.
+ * Those who don't will simply ignore it and will correspondingly return NULL in
+ * their namesake pick() output argument. */
+typedef struct grpc_lb_address {
+  grpc_resolved_address *resolved_address;
+  void *user_data;
+} grpc_lb_address;
+
 typedef struct grpc_lb_policy_args {
-  grpc_resolved_addresses *addresses;
+  grpc_lb_address *addresses;
+  size_t num_addresses;
   grpc_client_channel_factory *client_channel_factory;
 } grpc_lb_policy_args;
 
diff --git a/src/core/ext/lb_policy/grpclb/grpclb.c b/src/core/ext/lb_policy/grpclb/grpclb.c
index a9e329e..b44ca1b 100644
--- a/src/core/ext/lb_policy/grpclb/grpclb.c
+++ b/src/core/ext/lb_policy/grpclb/grpclb.c
@@ -76,9 +76,9 @@
  *    operations in progress over the old RR instance. This is done by
  *    decreasing the reference count on the old policy. The moment no more
  *    references are held on the old RR policy, it'll be destroyed and \a
- *    rr_connectivity_changed notified with a \a GRPC_CHANNEL_SHUTDOWN state.
- *    At this point we can transition to a new RR instance safely, which is done
- *    once again via \a rr_handover().
+ *    glb_rr_connectivity_changed notified with a \a GRPC_CHANNEL_SHUTDOWN
+ *    state. At this point we can transition to a new RR instance safely, which
+ *    is done once again via \a rr_handover().
  *
  *
  * Once a RR policy instance is in place (and getting updated as described),
@@ -96,6 +96,8 @@
  * - Implement LB service forwarding (point 2c. in the doc's diagram).
  */
 
+#include <errno.h>
+
 #include <string.h>
 
 #include <grpc/byte_buffer_reader.h>
@@ -109,18 +111,57 @@
 #include "src/core/ext/client_config/parse_address.h"
 #include "src/core/ext/lb_policy/grpclb/grpclb.h"
 #include "src/core/ext/lb_policy/grpclb/load_balancer_api.h"
+#include "src/core/lib/iomgr/sockaddr.h"
 #include "src/core/lib/iomgr/sockaddr_utils.h"
 #include "src/core/lib/support/string.h"
 #include "src/core/lib/surface/call.h"
 #include "src/core/lib/surface/channel.h"
+#include "src/core/lib/transport/static_metadata.h"
 
 int grpc_lb_glb_trace = 0;
 
+static void lb_addrs_destroy(grpc_lb_address *lb_addresses,
+                             size_t num_addresses) {
+  /* free "resolved" addresses memblock */
+  gpr_free(lb_addresses->resolved_address);
+  for (size_t i = 0; i < num_addresses; ++i) {
+    if (lb_addresses[i].user_data != NULL) {
+      GRPC_MDELEM_UNREF(lb_addresses[i].user_data);
+    }
+  }
+  gpr_free(lb_addresses);
+}
+
+/* add lb_token of selected subchannel (address) to the call's initial
+ * metadata */
+static void initial_metadata_add_lb_token(
+    grpc_metadata_batch *initial_metadata,
+    grpc_linked_mdelem *lb_token_mdelem_storage, grpc_mdelem *lb_token) {
+  GPR_ASSERT(lb_token_mdelem_storage != NULL);
+  GPR_ASSERT(lb_token != NULL);
+  grpc_metadata_batch_add_tail(initial_metadata, lb_token_mdelem_storage,
+                               lb_token);
+}
+
 typedef struct wrapped_rr_closure_arg {
   /* the original closure. Usually a on_complete/notify cb for pick() and ping()
    * calls against the internal RR instance, respectively. */
   grpc_closure *wrapped_closure;
 
+  /* the pick's initial metadata, kept in order to append the LB token for the
+   * pick */
+  grpc_metadata_batch *initial_metadata;
+
+  /* the picked target, used to determine which LB token to add to the pick's
+   * initial metadata */
+  grpc_connected_subchannel **target;
+
+  /* the LB token associated with the pick */
+  grpc_mdelem *lb_token;
+
+  /* storage for the lb token initial metadata mdelem */
+  grpc_linked_mdelem *lb_token_mdelem_storage;
+
   /* The RR instance related to the closure */
   grpc_lb_policy *rr_policy;
 
@@ -143,6 +184,11 @@
     GRPC_LB_POLICY_UNREF(exec_ctx, wc_arg->rr_policy, "wrapped_rr_closure");
   }
   GPR_ASSERT(wc_arg->wrapped_closure != NULL);
+
+  initial_metadata_add_lb_token(wc_arg->initial_metadata,
+                                wc_arg->lb_token_mdelem_storage,
+                                GRPC_MDELEM_REF(wc_arg->lb_token));
+
   grpc_exec_ctx_sched(exec_ctx, wc_arg->wrapped_closure, error, NULL);
   gpr_free(wc_arg->owning_pending_node);
 }
@@ -161,6 +207,9 @@
   /* the initial metadata for the pick. See grpc_lb_policy_pick() */
   grpc_metadata_batch *initial_metadata;
 
+  /* storage for the lb token initial metadata mdelem */
+  grpc_linked_mdelem *lb_token_mdelem_storage;
+
   /* bitmask passed to pick() and used for selective cancelling. See
    * grpc_lb_policy_cancel_picks() */
   uint32_t initial_metadata_flags;
@@ -178,8 +227,7 @@
 } pending_pick;
 
 static void add_pending_pick(pending_pick **root,
-                             grpc_metadata_batch *initial_metadata,
-                             uint32_t initial_metadata_flags,
+                             const grpc_lb_policy_pick_args *pick_args,
                              grpc_connected_subchannel **target,
                              grpc_closure *on_complete) {
   pending_pick *pp = gpr_malloc(sizeof(*pp));
@@ -187,9 +235,13 @@
   memset(&pp->wrapped_on_complete_arg, 0, sizeof(wrapped_rr_closure_arg));
   pp->next = *root;
   pp->target = target;
-  pp->initial_metadata = initial_metadata;
-  pp->initial_metadata_flags = initial_metadata_flags;
+  pp->initial_metadata = pick_args->initial_metadata;
+  pp->initial_metadata_flags = pick_args->initial_metadata_flags;
+  pp->lb_token_mdelem_storage = pick_args->lb_token_mdelem_storage;
   pp->wrapped_on_complete_arg.wrapped_closure = on_complete;
+  pp->wrapped_on_complete_arg.initial_metadata = pick_args->initial_metadata;
+  pp->wrapped_on_complete_arg.lb_token_mdelem_storage =
+      pick_args->lb_token_mdelem_storage;
   grpc_closure_init(&pp->wrapped_on_complete, wrapped_rr_closure,
                     &pp->wrapped_on_complete_arg);
   *root = pp;
@@ -248,6 +300,12 @@
    * response has arrived. */
   grpc_grpclb_serverlist *serverlist;
 
+  /** total number of valid addresses received in \a serverlist */
+  size_t num_ok_serverlist_addresses;
+
+  /** LB addresses from \a serverlist, \a num_ok_serverlist_addresses of them */
+  grpc_lb_address *lb_addresses;
+
   /** list of picks that are waiting on RR's policy connectivity */
   pending_pick *pending_picks;
 
@@ -275,58 +333,142 @@
   glb_lb_policy *glb_policy;
 };
 
+static bool is_server_valid(const grpc_grpclb_server *server, size_t idx,
+                            bool log) {
+  const grpc_grpclb_ip_address *ip = &server->ip_address;
+  if (server->port >> 16 != 0) {
+    if (log) {
+      gpr_log(GPR_ERROR,
+              "Invalid port '%d' at index %zu of serverlist. Ignoring.",
+              server->port, idx);
+    }
+    return false;
+  }
+
+  if (ip->size != 4 && ip->size != 16) {
+    if (log) {
+      gpr_log(GPR_ERROR,
+              "Expected IP to be 4 or 16 bytes, got %d at index %zu of "
+              "serverlist. Ignoring",
+              ip->size, idx);
+    }
+    return false;
+  }
+  return true;
+}
+
+/* populate \a addresses according to \a serverlist. Returns the number of
+ * addresses successfully parsed and added to \a addresses */
+static size_t process_serverlist(const grpc_grpclb_serverlist *serverlist,
+                                 grpc_lb_address **lb_addresses) {
+  size_t num_valid = 0;
+  /* first pass: count how many are valid in order to allocate the necessary
+   * memory in a single block */
+  for (size_t i = 0; i < serverlist->num_servers; ++i) {
+    if (is_server_valid(serverlist->servers[i], i, true)) ++num_valid;
+  }
+  if (num_valid == 0) {
+    return 0;
+  }
+
+  /* allocate the memory block for the "resolved" addresses. */
+  grpc_resolved_address *r_addrs_memblock =
+      gpr_malloc(sizeof(grpc_resolved_address) * num_valid);
+  memset(r_addrs_memblock, 0, sizeof(grpc_resolved_address) * num_valid);
+  grpc_lb_address *lb_addrs = gpr_malloc(sizeof(grpc_lb_address) * num_valid);
+  memset(lb_addrs, 0, sizeof(grpc_lb_address) * num_valid);
+
+  /* second pass: actually populate the addresses and LB tokens (aka user data
+   * to the outside world) to be read by the RR policy during its creation.
+   * Given that the validity tests are very cheap, they are performed again
+   * instead of marking the valid ones during the first pass, as this would
+   * incurr in an allocation due to the arbitrary number of server */
+  size_t addr_idx = 0;
+  for (size_t sl_idx = 0; sl_idx < serverlist->num_servers; ++sl_idx) {
+    GPR_ASSERT(addr_idx < num_valid);
+    const grpc_grpclb_server *server = serverlist->servers[sl_idx];
+    if (!is_server_valid(serverlist->servers[sl_idx], sl_idx, false)) continue;
+    grpc_lb_address *const lb_addr = &lb_addrs[addr_idx];
+
+    /* address processing */
+    const uint16_t netorder_port = htons((uint16_t)server->port);
+    /* the addresses are given in binary format (a in(6)_addr struct) in
+     * server->ip_address.bytes. */
+    const grpc_grpclb_ip_address *ip = &server->ip_address;
+
+    lb_addr->resolved_address = &r_addrs_memblock[addr_idx];
+    struct sockaddr_storage *sa =
+        (struct sockaddr_storage *)lb_addr->resolved_address->addr;
+    size_t *sa_len = &lb_addr->resolved_address->len;
+    *sa_len = 0;
+    if (ip->size == 4) {
+      struct sockaddr_in *addr4 = (struct sockaddr_in *)sa;
+      *sa_len = sizeof(struct sockaddr_in);
+      memset(addr4, 0, *sa_len);
+      addr4->sin_family = AF_INET;
+      memcpy(&addr4->sin_addr, ip->bytes, ip->size);
+      addr4->sin_port = netorder_port;
+    } else if (ip->size == 16) {
+      struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)sa;
+      *sa_len = sizeof(struct sockaddr_in6);
+      memset(addr6, 0, *sa_len);
+      addr6->sin6_family = AF_INET;
+      memcpy(&addr6->sin6_addr, ip->bytes, ip->size);
+      addr6->sin6_port = netorder_port;
+    }
+    GPR_ASSERT(*sa_len > 0);
+
+    /* lb token processing */
+    if (server->has_load_balance_token) {
+      const size_t lb_token_size =
+          GPR_ARRAY_SIZE(server->load_balance_token) - 1;
+      grpc_mdstr *lb_token_mdstr = grpc_mdstr_from_buffer(
+          (uint8_t *)server->load_balance_token, lb_token_size);
+      lb_addr->user_data = grpc_mdelem_from_metadata_strings(
+          GRPC_MDSTR_LOAD_REPORTING_INITIAL, lb_token_mdstr);
+    } else {
+      gpr_log(GPR_ERROR,
+              "Missing LB token for backend address '%s'. The empty token will "
+              "be used instead",
+              grpc_sockaddr_to_uri((struct sockaddr *)sa));
+      lb_addr->user_data = GRPC_MDELEM_LOAD_REPORTING_INITIAL_EMPTY;
+    }
+    ++addr_idx;
+  }
+  GPR_ASSERT(addr_idx == num_valid);
+  *lb_addresses = lb_addrs;
+  return num_valid;
+}
+
 static grpc_lb_policy *create_rr(grpc_exec_ctx *exec_ctx,
                                  const grpc_grpclb_serverlist *serverlist,
                                  glb_lb_policy *glb_policy) {
-  /* TODO(dgq): support mixed ip version */
   GPR_ASSERT(serverlist != NULL && serverlist->num_servers > 0);
-  char **host_ports = gpr_malloc(sizeof(char *) * serverlist->num_servers);
-  for (size_t i = 0; i < serverlist->num_servers; ++i) {
-    gpr_join_host_port(&host_ports[i], serverlist->servers[i]->ip_address,
-                       serverlist->servers[i]->port);
-  }
-
-  size_t uri_path_len;
-  char *concat_ipports = gpr_strjoin_sep(
-      (const char **)host_ports, serverlist->num_servers, ",", &uri_path_len);
 
   grpc_lb_policy_args args;
+  memset(&args, 0, sizeof(args));
   args.client_channel_factory = glb_policy->cc_factory;
-  args.addresses = gpr_malloc(sizeof(grpc_resolved_addresses));
-  args.addresses->naddrs = serverlist->num_servers;
-  args.addresses->addrs =
-      gpr_malloc(sizeof(grpc_resolved_address) * args.addresses->naddrs);
-  size_t out_addrs_idx = 0;
-  for (size_t i = 0; i < serverlist->num_servers; ++i) {
-    grpc_uri uri;
-    struct sockaddr_storage sa;
-    size_t sa_len;
-    uri.path = host_ports[i];
-    if (parse_ipv4(&uri, &sa, &sa_len)) { /* TODO(dgq): add support for ipv6 */
-      memcpy(args.addresses->addrs[out_addrs_idx].addr, &sa, sa_len);
-      args.addresses->addrs[out_addrs_idx].len = sa_len;
-      ++out_addrs_idx;
-    } else {
-      gpr_log(GPR_ERROR, "Invalid LB service address '%s', ignoring.",
-              host_ports[i]);
-    }
-  }
+  const size_t num_ok_addresses =
+      process_serverlist(serverlist, &args.addresses);
+  args.num_addresses = num_ok_addresses;
 
   grpc_lb_policy *rr = grpc_lb_policy_create(exec_ctx, "round_robin", &args);
 
-  gpr_free(concat_ipports);
-  for (size_t i = 0; i < serverlist->num_servers; i++) {
-    gpr_free(host_ports[i]);
+  if (glb_policy->lb_addresses != NULL) {
+    /* dispose of the previous version */
+    lb_addrs_destroy(glb_policy->lb_addresses,
+                     glb_policy->num_ok_serverlist_addresses);
   }
-  gpr_free(host_ports);
-  gpr_free(args.addresses->addrs);
-  gpr_free(args.addresses);
+  glb_policy->num_ok_serverlist_addresses = num_ok_addresses;
+  glb_policy->lb_addresses = args.addresses;
+
   return rr;
 }
 
 static void rr_handover(grpc_exec_ctx *exec_ctx, glb_lb_policy *glb_policy,
                         grpc_error *error) {
-  GRPC_ERROR_REF(error);
+  GPR_ASSERT(glb_policy->serverlist != NULL &&
+             glb_policy->serverlist->num_servers > 0);
   glb_policy->rr_policy =
       create_rr(exec_ctx, glb_policy->serverlist, glb_policy);
 
@@ -344,8 +486,8 @@
       exec_ctx, glb_policy->rr_policy, &glb_policy->rr_connectivity->state,
       &glb_policy->rr_connectivity->on_change);
   grpc_connectivity_state_set(exec_ctx, &glb_policy->state_tracker,
-                              glb_policy->rr_connectivity->state, error,
-                              "rr_handover");
+                              glb_policy->rr_connectivity->state,
+                              GRPC_ERROR_REF(error), "rr_handover");
   grpc_lb_policy_exit_idle(exec_ctx, glb_policy->rr_policy);
 
   /* flush pending ops */
@@ -358,8 +500,11 @@
       gpr_log(GPR_INFO, "Pending pick about to PICK from 0x%" PRIxPTR "",
               (intptr_t)glb_policy->rr_policy);
     }
-    grpc_lb_policy_pick(exec_ctx, glb_policy->rr_policy, pp->initial_metadata,
-                        pp->initial_metadata_flags, pp->target,
+    const grpc_lb_policy_pick_args pick_args = {
+        pp->pollent, pp->initial_metadata, pp->initial_metadata_flags,
+        pp->lb_token_mdelem_storage};
+    grpc_lb_policy_pick(exec_ctx, glb_policy->rr_policy, &pick_args, pp->target,
+                        (void **)&pp->wrapped_on_complete_arg.lb_token,
                         &pp->wrapped_on_complete);
     pp->wrapped_on_complete_arg.owning_pending_node = pp;
   }
@@ -377,13 +522,13 @@
                             &pping->wrapped_notify);
     pping->wrapped_notify_arg.owning_pending_node = pping;
   }
-  GRPC_ERROR_UNREF(error);
 }
 
-static void rr_connectivity_changed(grpc_exec_ctx *exec_ctx, void *arg,
-                                    grpc_error *error) {
+static void glb_rr_connectivity_changed(grpc_exec_ctx *exec_ctx, void *arg,
+                                        grpc_error *error) {
   rr_connectivity_data *rr_conn_data = arg;
   glb_lb_policy *glb_policy = rr_conn_data->glb_policy;
+
   if (rr_conn_data->state == GRPC_CHANNEL_SHUTDOWN) {
     if (glb_policy->serverlist != NULL) {
       /* a RR policy is shutting down but there's a serverlist available ->
@@ -397,8 +542,8 @@
     if (error == GRPC_ERROR_NONE) {
       /* RR not shutting down. Mimic the RR's policy state */
       grpc_connectivity_state_set(exec_ctx, &glb_policy->state_tracker,
-                                  rr_conn_data->state, error,
-                                  "rr_connectivity_changed");
+                                  rr_conn_data->state, GRPC_ERROR_REF(error),
+                                  "glb_rr_connectivity_changed");
       /* resubscribe */
       grpc_lb_policy_notify_on_state_change(exec_ctx, glb_policy->rr_policy,
                                             &rr_conn_data->state,
@@ -407,7 +552,6 @@
       gpr_free(rr_conn_data);
     }
   }
-  GRPC_ERROR_UNREF(error);
 }
 
 static grpc_lb_policy *glb_create(grpc_exec_ctx *exec_ctx,
@@ -417,31 +561,43 @@
   memset(glb_policy, 0, sizeof(*glb_policy));
 
   /* All input addresses in args->addresses come from a resolver that claims
-   * they are LB services. It's the resolver's responsibility to make sure this
+   * they are LB services. It's the resolver's responsibility to make sure
+   * this
    * policy is only instantiated and used in that case.
    *
    * Create a client channel over them to communicate with a LB service */
   glb_policy->cc_factory = args->client_channel_factory;
   GPR_ASSERT(glb_policy->cc_factory != NULL);
-  if (args->addresses->naddrs == 0) {
+  if (args->num_addresses == 0) {
     return NULL;
   }
 
-  /* construct a target from the args->addresses, in the form
+  if (args->addresses[0].user_data != NULL) {
+    gpr_log(GPR_ERROR,
+            "This LB policy doesn't support user data. It will be ignored");
+  }
+
+  /* construct a target from the addresses in args, given in the form
    * ipvX://ip1:port1,ip2:port2,...
    * TODO(dgq): support mixed ip version */
-  char **addr_strs = gpr_malloc(sizeof(char *) * args->addresses->naddrs);
-  addr_strs[0] =
-      grpc_sockaddr_to_uri((const struct sockaddr *)&args->addresses->addrs[0]);
-  for (size_t i = 1; i < args->addresses->naddrs; i++) {
-    GPR_ASSERT(grpc_sockaddr_to_string(
-                   &addr_strs[i],
-                   (const struct sockaddr *)&args->addresses->addrs[i],
-                   true) == 0);
+  char **addr_strs = gpr_malloc(sizeof(char *) * args->num_addresses);
+  addr_strs[0] = grpc_sockaddr_to_uri(
+      (const struct sockaddr *)&args->addresses[0].resolved_address->addr);
+  for (size_t i = 1; i < args->num_addresses; i++) {
+    if (args->addresses[i].user_data != NULL) {
+      gpr_log(GPR_ERROR,
+              "This LB policy doesn't support user data. It will be ignored");
+    }
+
+    GPR_ASSERT(
+        grpc_sockaddr_to_string(
+            &addr_strs[i],
+            (const struct sockaddr *)&args->addresses[i].resolved_address->addr,
+            true) == 0);
   }
   size_t uri_path_len;
   char *target_uri_str = gpr_strjoin_sep(
-      (const char **)addr_strs, args->addresses->naddrs, ",", &uri_path_len);
+      (const char **)addr_strs, args->num_addresses, ",", &uri_path_len);
 
   /* will pick using pick_first */
   glb_policy->lb_channel = grpc_client_channel_factory_create_channel(
@@ -449,7 +605,7 @@
       GRPC_CLIENT_CHANNEL_TYPE_LOAD_BALANCING, NULL);
 
   gpr_free(target_uri_str);
-  for (size_t i = 0; i < args->addresses->naddrs; i++) {
+  for (size_t i = 0; i < args->num_addresses; i++) {
     gpr_free(addr_strs[i]);
   }
   gpr_free(addr_strs);
@@ -462,7 +618,7 @@
   rr_connectivity_data *rr_connectivity =
       gpr_malloc(sizeof(rr_connectivity_data));
   memset(rr_connectivity, 0, sizeof(rr_connectivity_data));
-  grpc_closure_init(&rr_connectivity->on_change, rr_connectivity_changed,
+  grpc_closure_init(&rr_connectivity->on_change, glb_rr_connectivity_changed,
                     rr_connectivity);
   rr_connectivity->glb_policy = glb_policy;
   glb_policy->rr_connectivity = rr_connectivity;
@@ -485,6 +641,9 @@
     grpc_grpclb_destroy_serverlist(glb_policy->serverlist);
   }
   gpr_mu_destroy(&glb_policy->mu);
+
+  lb_addrs_destroy(glb_policy->lb_addresses,
+                   glb_policy->num_ok_serverlist_addresses);
   gpr_free(glb_policy);
 }
 
@@ -543,7 +702,6 @@
       *target = NULL;
       grpc_exec_ctx_sched(exec_ctx, &pp->wrapped_on_complete,
                           GRPC_ERROR_CANCELLED, NULL);
-      gpr_free(pp);
     } else {
       pp->next = glb_policy->pending_picks;
       glb_policy->pending_picks = pp;
@@ -571,7 +729,6 @@
         initial_metadata_flags_eq) {
       grpc_exec_ctx_sched(exec_ctx, &pp->wrapped_on_complete,
                           GRPC_ERROR_CANCELLED, NULL);
-      gpr_free(pp);
     } else {
       pp->next = glb_policy->pending_picks;
       glb_policy->pending_picks = pp;
@@ -598,11 +755,21 @@
 }
 
 static int glb_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol,
-                    grpc_metadata_batch *initial_metadata,
-                    uint32_t initial_metadata_flags,
-                    grpc_connected_subchannel **target,
+                    const grpc_lb_policy_pick_args *pick_args,
+                    grpc_connected_subchannel **target, void **user_data,
                     grpc_closure *on_complete) {
   glb_lb_policy *glb_policy = (glb_lb_policy *)pol;
+
+  if (pick_args->lb_token_mdelem_storage == NULL) {
+    *target = NULL;
+    grpc_exec_ctx_sched(
+        exec_ctx, on_complete,
+        GRPC_ERROR_CREATE("No mdelem storage for the LB token. Load reporting "
+                          "won't work without it. Failing"),
+        NULL);
+    return 1;
+  }
+
   gpr_mu_lock(&glb_policy->mu);
   int r;
 
@@ -615,26 +782,34 @@
     memset(&glb_policy->wc_arg, 0, sizeof(wrapped_rr_closure_arg));
     glb_policy->wc_arg.rr_policy = glb_policy->rr_policy;
     glb_policy->wc_arg.wrapped_closure = on_complete;
+    glb_policy->wc_arg.lb_token_mdelem_storage =
+        pick_args->lb_token_mdelem_storage;
+    glb_policy->wc_arg.initial_metadata = pick_args->initial_metadata;
+    glb_policy->wc_arg.owning_pending_node = NULL;
     grpc_closure_init(&glb_policy->wrapped_on_complete, wrapped_rr_closure,
                       &glb_policy->wc_arg);
-    r = grpc_lb_policy_pick(exec_ctx, glb_policy->rr_policy, initial_metadata,
-                            initial_metadata_flags, target,
+
+    r = grpc_lb_policy_pick(exec_ctx, glb_policy->rr_policy, pick_args, target,
+                            (void **)&glb_policy->wc_arg.lb_token,
                             &glb_policy->wrapped_on_complete);
     if (r != 0) {
-      /* the call to grpc_lb_policy_pick has been sychronous. Unreffing the RR
-       * policy and notify the original callback */
-      glb_policy->wc_arg.wrapped_closure = NULL;
+      /* synchronous grpc_lb_policy_pick call. Unref the RR policy. */
       if (grpc_lb_glb_trace) {
         gpr_log(GPR_INFO, "Unreffing RR (0x%" PRIxPTR ")",
                 (intptr_t)glb_policy->wc_arg.rr_policy);
       }
       GRPC_LB_POLICY_UNREF(exec_ctx, glb_policy->wc_arg.rr_policy, "glb_pick");
-      grpc_exec_ctx_sched(exec_ctx, glb_policy->wc_arg.wrapped_closure,
-                          GRPC_ERROR_NONE, NULL);
+
+      /* add the load reporting initial metadata */
+      initial_metadata_add_lb_token(
+          pick_args->initial_metadata, pick_args->lb_token_mdelem_storage,
+          GRPC_MDELEM_REF(glb_policy->wc_arg.lb_token));
     }
   } else {
-    add_pending_pick(&glb_policy->pending_picks, initial_metadata,
-                     initial_metadata_flags, target, on_complete);
+    grpc_polling_entity_add_to_pollset_set(exec_ctx, pick_args->pollent,
+                                           glb_policy->base.interested_parties);
+    add_pending_pick(&glb_policy->pending_picks, pick_args, target,
+                     on_complete);
 
     if (!glb_policy->started_picking) {
       start_picking(exec_ctx, glb_policy);
@@ -694,9 +869,6 @@
   /* called once initial metadata's been sent */
   grpc_closure md_sent;
 
-  /* called once initial metadata's been received */
-  grpc_closure md_rcvd;
-
   /* called once the LoadBalanceRequest has been sent to the LB server. See
    * src/proto/grpc/.../load_balancer.proto */
   grpc_closure req_sent;
@@ -733,7 +905,6 @@
 } lb_client_data;
 
 static void md_sent_cb(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error);
-static void md_recv_cb(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error);
 static void req_sent_cb(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error);
 static void res_recv_cb(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error);
 static void close_sent_cb(grpc_exec_ctx *exec_ctx, void *arg,
@@ -748,7 +919,6 @@
   gpr_mu_init(&lb_client->mu);
   grpc_closure_init(&lb_client->md_sent, md_sent_cb, lb_client);
 
-  grpc_closure_init(&lb_client->md_rcvd, md_recv_cb, lb_client);
   grpc_closure_init(&lb_client->req_sent, req_sent_cb, lb_client);
   grpc_closure_init(&lb_client->res_rcvd, res_recv_cb, lb_client);
   grpc_closure_init(&lb_client->close_sent, close_sent_cb, lb_client);
@@ -847,23 +1017,6 @@
   grpc_op ops[1];
   memset(ops, 0, sizeof(ops));
   grpc_op *op = ops;
-  op->op = GRPC_OP_RECV_INITIAL_METADATA;
-  op->data.recv_initial_metadata = &lb_client->initial_metadata_recv;
-  op->flags = 0;
-  op->reserved = NULL;
-  op++;
-  grpc_call_error call_error = grpc_call_start_batch_and_execute(
-      exec_ctx, lb_client->lb_call, ops, (size_t)(op - ops),
-      &lb_client->md_rcvd);
-  GPR_ASSERT(GRPC_CALL_OK == call_error);
-}
-
-static void md_recv_cb(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {
-  lb_client_data *lb_client = arg;
-  GPR_ASSERT(lb_client->lb_call);
-  grpc_op ops[1];
-  memset(ops, 0, sizeof(ops));
-  grpc_op *op = ops;
 
   op->op = GRPC_OP_SEND_MESSAGE;
   op->data.send_message = lb_client->request_payload;
@@ -878,11 +1031,18 @@
 
 static void req_sent_cb(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {
   lb_client_data *lb_client = arg;
+  GPR_ASSERT(lb_client->lb_call);
 
-  grpc_op ops[1];
+  grpc_op ops[2];
   memset(ops, 0, sizeof(ops));
   grpc_op *op = ops;
 
+  op->op = GRPC_OP_RECV_INITIAL_METADATA;
+  op->data.recv_initial_metadata = &lb_client->initial_metadata_recv;
+  op->flags = 0;
+  op->reserved = NULL;
+  op++;
+
   op->op = GRPC_OP_RECV_MESSAGE;
   op->data.recv_message = &lb_client->response_payload;
   op->flags = 0;
@@ -901,8 +1061,7 @@
   grpc_op *op = ops;
   if (lb_client->response_payload != NULL) {
     /* Received data from the LB server. Look inside
-     * lb_client->response_payload, for
-     * a serverlist. */
+     * lb_client->response_payload, for a serverlist. */
     grpc_byte_buffer_reader bbr;
     grpc_byte_buffer_reader_init(&bbr, lb_client->response_payload);
     gpr_slice response_slice = grpc_byte_buffer_reader_readall(&bbr);
@@ -939,7 +1098,7 @@
         } else {
           /* unref the RR policy, eventually leading to its substitution with a
            * new one constructed from the received serverlist (see
-           * rr_connectivity_changed) */
+           * glb_rr_connectivity_changed) */
           GRPC_LB_POLICY_UNREF(exec_ctx, lb_client->glb_policy->rr_policy,
                                "serverlist_received");
         }
@@ -1002,8 +1161,8 @@
             lb_client->status, lb_client->status_details,
             lb_client->status_details_capacity);
   }
-  /* TODO(dgq): deal with stream termination properly (fire up another one? fail
-   * the original call?) */
+  /* TODO(dgq): deal with stream termination properly (fire up another one?
+   * fail the original call?) */
 }
 
 /* Code wiring the policy with the rest of the core */
diff --git a/src/core/ext/lb_policy/grpclb/load_balancer_api.c b/src/core/ext/lb_policy/grpclb/load_balancer_api.c
index f4720a1..a888100 100644
--- a/src/core/ext/lb_policy/grpclb/load_balancer_api.c
+++ b/src/core/ext/lb_policy/grpclb/load_balancer_api.c
@@ -57,6 +57,7 @@
   if (dec_arg->first_pass) { /* count how many server do we have */
     grpc_grpclb_server server;
     if (!pb_decode(stream, grpc_lb_v1_Server_fields, &server)) {
+      gpr_log(GPR_ERROR, "nanopb error: %s", PB_GET_ERROR(stream));
       return false;
     }
     dec_arg->num_servers++;
@@ -69,6 +70,7 @@
           gpr_malloc(sizeof(grpc_grpclb_server *) * dec_arg->num_servers);
     }
     if (!pb_decode(stream, grpc_lb_v1_Server_fields, server)) {
+      gpr_log(GPR_ERROR, "nanopb error: %s", PB_GET_ERROR(stream));
       return false;
     }
     dec_arg->servers[dec_arg->decoding_idx++] = server;
@@ -118,6 +120,7 @@
   grpc_grpclb_response res;
   memset(&res, 0, sizeof(grpc_grpclb_response));
   if (!pb_decode(&stream, grpc_lb_v1_LoadBalanceResponse_fields, &res)) {
+    gpr_log(GPR_ERROR, "nanopb error: %s", PB_GET_ERROR(&stream));
     return NULL;
   }
   grpc_grpclb_initial_response *initial_res =
@@ -145,6 +148,7 @@
   arg.first_pass = true;
   status = pb_decode(&stream, grpc_lb_v1_LoadBalanceResponse_fields, &res);
   if (!status) {
+    gpr_log(GPR_ERROR, "nanopb error: %s", PB_GET_ERROR(&stream));
     return NULL;
   }
 
@@ -152,6 +156,7 @@
   status =
       pb_decode(&stream_at_start, grpc_lb_v1_LoadBalanceResponse_fields, &res);
   if (!status) {
+    gpr_log(GPR_ERROR, "nanopb error: %s", PB_GET_ERROR(&stream));
     return NULL;
   }
 
diff --git a/src/core/ext/lb_policy/grpclb/load_balancer_api.h b/src/core/ext/lb_policy/grpclb/load_balancer_api.h
index 9726c87..c1e73d0 100644
--- a/src/core/ext/lb_policy/grpclb/load_balancer_api.h
+++ b/src/core/ext/lb_policy/grpclb/load_balancer_api.h
@@ -45,6 +45,7 @@
 
 #define GRPC_GRPCLB_SERVICE_NAME_MAX_LENGTH 128
 
+typedef grpc_lb_v1_Server_ip_address_t grpc_grpclb_ip_address;
 typedef grpc_lb_v1_LoadBalanceRequest grpc_grpclb_request;
 typedef grpc_lb_v1_InitialLoadBalanceResponse grpc_grpclb_initial_response;
 typedef grpc_lb_v1_Server grpc_grpclb_server;
diff --git a/src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c b/src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c
index 52e11c4..2676714 100644
--- a/src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c
+++ b/src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c
@@ -31,10 +31,11 @@
  *
  */
 /* Automatically generated nanopb constant definitions */
-/* Generated by nanopb-0.3.5-dev */
+/* Generated by nanopb-0.3.7-dev */
 
 #include "src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h"
 
+/* @@protoc_insertion_point(includes) */
 #if PB_PROTO_HEADER_VERSION != 30
 #error Regenerate this file with the current version of nanopb generator.
 #endif
@@ -72,7 +73,7 @@
 };
 
 const pb_field_t grpc_lb_v1_InitialLoadBalanceResponse_fields[3] = {
-    PB_FIELD(  2, STRING  , OPTIONAL, STATIC  , FIRST, grpc_lb_v1_InitialLoadBalanceResponse, load_balancer_delegate, load_balancer_delegate, 0),
+    PB_FIELD(  1, STRING  , OPTIONAL, STATIC  , FIRST, grpc_lb_v1_InitialLoadBalanceResponse, load_balancer_delegate, load_balancer_delegate, 0),
     PB_FIELD(  3, MESSAGE , OPTIONAL, STATIC  , OTHER, grpc_lb_v1_InitialLoadBalanceResponse, client_stats_report_interval, load_balancer_delegate, &grpc_lb_v1_Duration_fields),
     PB_LAST_FIELD
 };
@@ -84,7 +85,7 @@
 };
 
 const pb_field_t grpc_lb_v1_Server_fields[5] = {
-    PB_FIELD(  1, STRING  , OPTIONAL, STATIC  , FIRST, grpc_lb_v1_Server, ip_address, ip_address, 0),
+    PB_FIELD(  1, BYTES   , OPTIONAL, STATIC  , FIRST, grpc_lb_v1_Server, ip_address, ip_address, 0),
     PB_FIELD(  2, INT32   , OPTIONAL, STATIC  , OTHER, grpc_lb_v1_Server, port, ip_address, 0),
     PB_FIELD(  3, STRING  , OPTIONAL, STATIC  , OTHER, grpc_lb_v1_Server, load_balance_token, port, 0),
     PB_FIELD(  4, BOOL    , OPTIONAL, STATIC  , OTHER, grpc_lb_v1_Server, drop_request, load_balance_token, 0),
@@ -116,3 +117,4 @@
 #endif
 
 
+/* @@protoc_insertion_point(eof) */
diff --git a/src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h b/src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h
index 46fe588..4f1031e 100644
--- a/src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h
+++ b/src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h
@@ -31,11 +31,12 @@
  *
  */
 /* Automatically generated nanopb header */
-/* Generated by nanopb-0.3.5-dev */
+/* Generated by nanopb-0.3.7-dev */
 
-#ifndef GRPC_CORE_EXT_LB_POLICY_GRPCLB_PROTO_GRPC_LB_V1_LOAD_BALANCER_PB_H
-#define GRPC_CORE_EXT_LB_POLICY_GRPCLB_PROTO_GRPC_LB_V1_LOAD_BALANCER_PB_H
+#ifndef PB_GRPC_LB_V1_LOAD_BALANCER_PB_H_INCLUDED
+#define PB_GRPC_LB_V1_LOAD_BALANCER_PB_H_INCLUDED
 #include "third_party/nanopb/pb.h"
+/* @@protoc_insertion_point(includes) */
 #if PB_PROTO_HEADER_VERSION != 30
 #error Regenerate this file with the current version of nanopb generator.
 #endif
@@ -52,6 +53,7 @@
     int64_t client_rpc_errors;
     bool has_dropped_requests;
     int64_t dropped_requests;
+/* @@protoc_insertion_point(struct:grpc_lb_v1_ClientStats) */
 } grpc_lb_v1_ClientStats;
 
 typedef struct _grpc_lb_v1_Duration {
@@ -59,22 +61,26 @@
     int64_t seconds;
     bool has_nanos;
     int32_t nanos;
+/* @@protoc_insertion_point(struct:grpc_lb_v1_Duration) */
 } grpc_lb_v1_Duration;
 
 typedef struct _grpc_lb_v1_InitialLoadBalanceRequest {
     bool has_name;
     char name[128];
+/* @@protoc_insertion_point(struct:grpc_lb_v1_InitialLoadBalanceRequest) */
 } grpc_lb_v1_InitialLoadBalanceRequest;
 
+typedef PB_BYTES_ARRAY_T(16) grpc_lb_v1_Server_ip_address_t;
 typedef struct _grpc_lb_v1_Server {
     bool has_ip_address;
-    char ip_address[46];
+    grpc_lb_v1_Server_ip_address_t ip_address;
     bool has_port;
     int32_t port;
     bool has_load_balance_token;
-    char load_balance_token[64];
+    char load_balance_token[65];
     bool has_drop_request;
     bool drop_request;
+/* @@protoc_insertion_point(struct:grpc_lb_v1_Server) */
 } grpc_lb_v1_Server;
 
 typedef struct _grpc_lb_v1_InitialLoadBalanceResponse {
@@ -82,6 +88,7 @@
     char load_balancer_delegate[64];
     bool has_client_stats_report_interval;
     grpc_lb_v1_Duration client_stats_report_interval;
+/* @@protoc_insertion_point(struct:grpc_lb_v1_InitialLoadBalanceResponse) */
 } grpc_lb_v1_InitialLoadBalanceResponse;
 
 typedef struct _grpc_lb_v1_LoadBalanceRequest {
@@ -89,12 +96,14 @@
     grpc_lb_v1_InitialLoadBalanceRequest initial_request;
     bool has_client_stats;
     grpc_lb_v1_ClientStats client_stats;
+/* @@protoc_insertion_point(struct:grpc_lb_v1_LoadBalanceRequest) */
 } grpc_lb_v1_LoadBalanceRequest;
 
 typedef struct _grpc_lb_v1_ServerList {
     pb_callback_t servers;
     bool has_expiration_interval;
     grpc_lb_v1_Duration expiration_interval;
+/* @@protoc_insertion_point(struct:grpc_lb_v1_ServerList) */
 } grpc_lb_v1_ServerList;
 
 typedef struct _grpc_lb_v1_LoadBalanceResponse {
@@ -102,6 +111,7 @@
     grpc_lb_v1_InitialLoadBalanceResponse initial_response;
     bool has_server_list;
     grpc_lb_v1_ServerList server_list;
+/* @@protoc_insertion_point(struct:grpc_lb_v1_LoadBalanceResponse) */
 } grpc_lb_v1_LoadBalanceResponse;
 
 /* Default values for struct fields */
@@ -114,7 +124,7 @@
 #define grpc_lb_v1_LoadBalanceResponse_init_default {false, grpc_lb_v1_InitialLoadBalanceResponse_init_default, false, grpc_lb_v1_ServerList_init_default}
 #define grpc_lb_v1_InitialLoadBalanceResponse_init_default {false, "", false, grpc_lb_v1_Duration_init_default}
 #define grpc_lb_v1_ServerList_init_default       {{{NULL}, NULL}, false, grpc_lb_v1_Duration_init_default}
-#define grpc_lb_v1_Server_init_default           {false, "", false, 0, false, "", false, 0}
+#define grpc_lb_v1_Server_init_default           {false, {0, {0}}, false, 0, false, "", false, 0}
 #define grpc_lb_v1_Duration_init_zero            {false, 0, false, 0}
 #define grpc_lb_v1_LoadBalanceRequest_init_zero  {false, grpc_lb_v1_InitialLoadBalanceRequest_init_zero, false, grpc_lb_v1_ClientStats_init_zero}
 #define grpc_lb_v1_InitialLoadBalanceRequest_init_zero {false, ""}
@@ -122,7 +132,7 @@
 #define grpc_lb_v1_LoadBalanceResponse_init_zero {false, grpc_lb_v1_InitialLoadBalanceResponse_init_zero, false, grpc_lb_v1_ServerList_init_zero}
 #define grpc_lb_v1_InitialLoadBalanceResponse_init_zero {false, "", false, grpc_lb_v1_Duration_init_zero}
 #define grpc_lb_v1_ServerList_init_zero          {{{NULL}, NULL}, false, grpc_lb_v1_Duration_init_zero}
-#define grpc_lb_v1_Server_init_zero              {false, "", false, 0, false, "", false, 0}
+#define grpc_lb_v1_Server_init_zero              {false, {0, {0}}, false, 0, false, "", false, 0}
 
 /* Field tags (for use in manual encoding/decoding) */
 #define grpc_lb_v1_ClientStats_total_requests_tag 1
@@ -135,7 +145,7 @@
 #define grpc_lb_v1_Server_port_tag               2
 #define grpc_lb_v1_Server_load_balance_token_tag 3
 #define grpc_lb_v1_Server_drop_request_tag       4
-#define grpc_lb_v1_InitialLoadBalanceResponse_load_balancer_delegate_tag 2
+#define grpc_lb_v1_InitialLoadBalanceResponse_load_balancer_delegate_tag 1
 #define grpc_lb_v1_InitialLoadBalanceResponse_client_stats_report_interval_tag 3
 #define grpc_lb_v1_LoadBalanceRequest_initial_request_tag 1
 #define grpc_lb_v1_LoadBalanceRequest_client_stats_tag 2
@@ -161,7 +171,8 @@
 #define grpc_lb_v1_ClientStats_size              33
 #define grpc_lb_v1_LoadBalanceResponse_size      (98 + grpc_lb_v1_ServerList_size)
 #define grpc_lb_v1_InitialLoadBalanceResponse_size 90
-#define grpc_lb_v1_Server_size                   127
+/* grpc_lb_v1_ServerList_size depends on runtime parameters */
+#define grpc_lb_v1_Server_size                   98
 
 /* Message IDs (where set with "msgid" option) */
 #ifdef PB_MSGID
@@ -174,5 +185,6 @@
 #ifdef __cplusplus
 } /* extern "C" */
 #endif
+/* @@protoc_insertion_point(eof) */
 
 #endif
diff --git a/src/core/ext/lb_policy/pick_first/pick_first.c b/src/core/ext/lb_policy/pick_first/pick_first.c
index a1a438c..201a2ea 100644
--- a/src/core/ext/lb_policy/pick_first/pick_first.c
+++ b/src/core/ext/lb_policy/pick_first/pick_first.c
@@ -192,9 +192,8 @@
 }
 
 static int pf_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol,
-                   grpc_metadata_batch *initial_metadata,
-                   uint32_t initial_metadata_flags,
-                   grpc_connected_subchannel **target,
+                   const grpc_lb_policy_pick_args *pick_args,
+                   grpc_connected_subchannel **target, void **user_data,
                    grpc_closure *on_complete) {
   pick_first_lb_policy *p = (pick_first_lb_policy *)pol;
   pending_pick *pp;
@@ -220,7 +219,7 @@
     pp = gpr_malloc(sizeof(*pp));
     pp->next = p->pending_picks;
     pp->target = target;
-    pp->initial_metadata_flags = initial_metadata_flags;
+    pp->initial_metadata_flags = pick_args->initial_metadata_flags;
     pp->on_complete = on_complete;
     p->pending_picks = pp;
     gpr_mu_unlock(&p->mu);
@@ -430,20 +429,25 @@
   GPR_ASSERT(args->addresses != NULL);
   GPR_ASSERT(args->client_channel_factory != NULL);
 
-  if (args->addresses->naddrs == 0) return NULL;
+  if (args->num_addresses == 0) return NULL;
 
   pick_first_lb_policy *p = gpr_malloc(sizeof(*p));
   memset(p, 0, sizeof(*p));
 
-  p->subchannels =
-      gpr_malloc(sizeof(grpc_subchannel *) * args->addresses->naddrs);
-  memset(p->subchannels, 0, sizeof(*p->subchannels) * args->addresses->naddrs);
+  p->subchannels = gpr_malloc(sizeof(grpc_subchannel *) * args->num_addresses);
+  memset(p->subchannels, 0, sizeof(*p->subchannels) * args->num_addresses);
   grpc_subchannel_args sc_args;
   size_t subchannel_idx = 0;
-  for (size_t i = 0; i < args->addresses->naddrs; i++) {
+  for (size_t i = 0; i < args->num_addresses; i++) {
+    if (args->addresses[i].user_data != NULL) {
+      gpr_log(GPR_ERROR,
+              "This LB policy doesn't support user data. It will be ignored");
+    }
+
     memset(&sc_args, 0, sizeof(grpc_subchannel_args));
-    sc_args.addr = (struct sockaddr *)(args->addresses->addrs[i].addr);
-    sc_args.addr_len = (size_t)args->addresses->addrs[i].len;
+    sc_args.addr =
+        (struct sockaddr *)(args->addresses[i].resolved_address->addr);
+    sc_args.addr_len = (size_t)args->addresses[i].resolved_address->len;
 
     grpc_subchannel *subchannel = grpc_client_channel_factory_create_subchannel(
         exec_ctx, args->client_channel_factory, &sc_args);
diff --git a/src/core/ext/lb_policy/round_robin/round_robin.c b/src/core/ext/lb_policy/round_robin/round_robin.c
index 9b557f4..f8a375f 100644
--- a/src/core/ext/lb_policy/round_robin/round_robin.c
+++ b/src/core/ext/lb_policy/round_robin/round_robin.c
@@ -66,6 +66,7 @@
 #include "src/core/ext/client_config/lb_policy_registry.h"
 #include "src/core/lib/debug/trace.h"
 #include "src/core/lib/transport/connectivity_state.h"
+#include "src/core/lib/transport/static_metadata.h"
 
 typedef struct round_robin_lb_policy round_robin_lb_policy;
 
@@ -76,14 +77,29 @@
  * Once a pick is available, \a target is updated and \a on_complete called. */
 typedef struct pending_pick {
   struct pending_pick *next;
+
+  /* output argument where to store the pick()ed user_data. It'll be NULL if no
+   * such data is present or there's an error (the definite test for errors is
+   * \a target being NULL). */
+  void **user_data;
+
+  /* bitmask passed to pick() and used for selective cancelling. See
+   * grpc_lb_policy_cancel_picks() */
   uint32_t initial_metadata_flags;
+
+  /* output argument where to store the pick()ed connected subchannel, or NULL
+   * upon error. */
   grpc_connected_subchannel **target;
+
+  /* to be invoked once the pick() has completed (regardless of success) */
   grpc_closure *on_complete;
 } pending_pick;
 
 /** List of subchannels in a connectivity READY state */
 typedef struct ready_list {
   grpc_subchannel *subchannel;
+  /* references namesake entry in subchannel_data */
+  void *user_data;
   struct ready_list *next;
   struct ready_list *prev;
 } ready_list;
@@ -101,12 +117,21 @@
   ready_list *ready_list_node;
   /** last observed connectivity */
   grpc_connectivity_state connectivity_state;
+  /** the subchannel's target user data */
+  void *user_data;
 } subchannel_data;
 
 struct round_robin_lb_policy {
   /** base policy: must be first */
   grpc_lb_policy base;
 
+  /** total number of addresses received at creation time */
+  size_t num_addresses;
+  /** array holding the borrowed and opaque pointers to incoming user data, one
+   * per incoming address.  These individual pointers will be returned as-is in
+   * successful picks. */
+  void **user_data_pointers;
+
   /** all our subchannels */
   size_t num_subchannels;
   subchannel_data **subchannels;
@@ -165,16 +190,19 @@
 
   if (grpc_lb_round_robin_trace) {
     gpr_log(GPR_DEBUG, "[READYLIST] ADVANCED LAST PICK. NOW AT NODE %p (SC %p)",
-            p->ready_list_last_pick, p->ready_list_last_pick->subchannel);
+            (void *)p->ready_list_last_pick,
+            (void *)p->ready_list_last_pick->subchannel);
   }
 }
 
 /** Prepends (relative to the root at p->ready_list) the connected subchannel \a
  * csc to the list of ready subchannels. */
 static ready_list *add_connected_sc_locked(round_robin_lb_policy *p,
-                                           grpc_subchannel *sc) {
+                                           subchannel_data *sd) {
   ready_list *new_elem = gpr_malloc(sizeof(ready_list));
-  new_elem->subchannel = sc;
+  memset(new_elem, 0, sizeof(ready_list));
+  new_elem->subchannel = sd->subchannel;
+  new_elem->user_data = sd->user_data;
   if (p->ready_list.prev == NULL) {
     /* first element */
     new_elem->next = &p->ready_list;
@@ -188,7 +216,8 @@
     p->ready_list.prev = new_elem;
   }
   if (grpc_lb_round_robin_trace) {
-    gpr_log(GPR_DEBUG, "[READYLIST] ADDING NODE %p (SC %p)", new_elem, sc);
+    gpr_log(GPR_DEBUG, "[READYLIST] ADDING NODE %p (Conn. SC %p)",
+            (void *)new_elem, (void *)sd->subchannel);
   }
   return new_elem;
 }
@@ -215,8 +244,8 @@
   }
 
   if (grpc_lb_round_robin_trace) {
-    gpr_log(GPR_DEBUG, "[READYLIST] REMOVED NODE %p (SC %p)", node,
-            node->subchannel);
+    gpr_log(GPR_DEBUG, "[READYLIST] REMOVED NODE %p (SC %p)", (void *)node,
+            (void *)node->subchannel);
   }
 
   node->next = NULL;
@@ -228,9 +257,8 @@
 
 static void rr_destroy(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol) {
   round_robin_lb_policy *p = (round_robin_lb_policy *)pol;
-  size_t i;
   ready_list *elem;
-  for (i = 0; i < p->num_subchannels; i++) {
+  for (size_t i = 0; i < p->num_subchannels; i++) {
     subchannel_data *sd = p->subchannels[i];
     GRPC_SUBCHANNEL_UNREF(exec_ctx, sd->subchannel, "round_robin");
     gpr_free(sd);
@@ -250,6 +278,8 @@
     gpr_free(elem);
     elem = tmp;
   }
+
+  gpr_free(p->user_data_pointers);
   gpr_free(p);
 }
 
@@ -332,7 +362,7 @@
   p->started_picking = 1;
 
   if (grpc_lb_round_robin_trace) {
-    gpr_log(GPR_DEBUG, "LB_POLICY: p=%p num_subchannels=%" PRIuPTR, p,
+    gpr_log(GPR_DEBUG, "LB_POLICY: p=%p num_subchannels=%" PRIuPTR, (void *)p,
             p->num_subchannels);
   }
 
@@ -356,26 +386,28 @@
 }
 
 static int rr_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol,
-                   grpc_metadata_batch *initial_metadata,
-                   uint32_t initial_metadata_flags,
-                   grpc_connected_subchannel **target,
+                   const grpc_lb_policy_pick_args *pick_args,
+                   grpc_connected_subchannel **target, void **user_data,
                    grpc_closure *on_complete) {
   round_robin_lb_policy *p = (round_robin_lb_policy *)pol;
   pending_pick *pp;
   ready_list *selected;
   gpr_mu_lock(&p->mu);
   if ((selected = peek_next_connected_locked(p))) {
+    /* readily available, report right away */
     gpr_mu_unlock(&p->mu);
     *target = grpc_subchannel_get_connected_subchannel(selected->subchannel);
+    *user_data = selected->user_data;
     if (grpc_lb_round_robin_trace) {
       gpr_log(GPR_DEBUG,
-              "[RR PICK] TARGET <-- CONNECTED SUBCHANNEL %p (NODE %p)", *target,
-              selected);
+              "[RR PICK] TARGET <-- CONNECTED SUBCHANNEL %p (NODE %p)",
+              (void *)*target, (void *)selected);
     }
     /* only advance the last picked pointer if the selection was used */
     advance_last_picked_locked(p);
     return 1;
   } else {
+    /* no pick currently available. Save for later in list of pending picks */
     if (!p->started_picking) {
       start_picking(exec_ctx, p);
     }
@@ -383,7 +415,8 @@
     pp->next = p->pending_picks;
     pp->target = target;
     pp->on_complete = on_complete;
-    pp->initial_metadata_flags = initial_metadata_flags;
+    pp->initial_metadata_flags = pick_args->initial_metadata_flags;
+    pp->user_data = user_data;
     p->pending_picks = pp;
     gpr_mu_unlock(&p->mu);
     return 0;
@@ -412,7 +445,7 @@
                                     "connecting_ready");
         /* add the newly connected subchannel to the list of connected ones.
          * Note that it goes to the "end of the line". */
-        sd->ready_list_node = add_connected_sc_locked(p, sd->subchannel);
+        sd->ready_list_node = add_connected_sc_locked(p, sd);
         /* at this point we know there's at least one suitable subchannel. Go
          * ahead and pick one and notify the pending suitors in
          * p->pending_picks. This preemtively replicates rr_pick()'s actions. */
@@ -424,12 +457,14 @@
         }
         while ((pp = p->pending_picks)) {
           p->pending_picks = pp->next;
+
           *pp->target =
               grpc_subchannel_get_connected_subchannel(selected->subchannel);
+          *pp->user_data = selected->user_data;
           if (grpc_lb_round_robin_trace) {
             gpr_log(GPR_DEBUG,
                     "[RR CONN CHANGED] TARGET <-- SUBCHANNEL %p (NODE %p)",
-                    selected->subchannel, selected);
+                    (void *)selected->subchannel, (void *)selected);
           }
           grpc_exec_ctx_sched(exec_ctx, pp->on_complete, GRPC_ERROR_NONE, NULL);
           gpr_free(pp);
@@ -559,20 +594,25 @@
                                           grpc_lb_policy_args *args) {
   GPR_ASSERT(args->addresses != NULL);
   GPR_ASSERT(args->client_channel_factory != NULL);
+  if (args->num_addresses == 0) return NULL;
 
   round_robin_lb_policy *p = gpr_malloc(sizeof(*p));
   memset(p, 0, sizeof(*p));
 
-  p->subchannels =
-      gpr_malloc(sizeof(*p->subchannels) * args->addresses->naddrs);
-  memset(p->subchannels, 0, sizeof(*p->subchannels) * args->addresses->naddrs);
+  p->num_addresses = args->num_addresses;
+  p->subchannels = gpr_malloc(sizeof(subchannel_data) * p->num_addresses);
+  memset(p->subchannels, 0, sizeof(*p->subchannels) * p->num_addresses);
+  p->user_data_pointers = gpr_malloc(sizeof(void *) * p->num_addresses);
+  memset(p->user_data_pointers, 0, sizeof(void *) * p->num_addresses);
 
   grpc_subchannel_args sc_args;
   size_t subchannel_idx = 0;
-  for (size_t i = 0; i < args->addresses->naddrs; i++) {
+  for (size_t i = 0; i < p->num_addresses; i++) {
     memset(&sc_args, 0, sizeof(grpc_subchannel_args));
-    sc_args.addr = (struct sockaddr *)(args->addresses->addrs[i].addr);
-    sc_args.addr_len = (size_t)args->addresses->addrs[i].len;
+    sc_args.addr = (struct sockaddr *)args->addresses[i].resolved_address->addr;
+    sc_args.addr_len = args->addresses[i].resolved_address->len;
+
+    p->user_data_pointers[i] = args->addresses[i].user_data;
 
     grpc_subchannel *subchannel = grpc_client_channel_factory_create_subchannel(
         exec_ctx, args->client_channel_factory, &sc_args);
@@ -584,12 +624,14 @@
       sd->policy = p;
       sd->index = subchannel_idx;
       sd->subchannel = subchannel;
+      sd->user_data = p->user_data_pointers[i];
       ++subchannel_idx;
       grpc_closure_init(&sd->connectivity_changed_closure,
                         rr_connectivity_changed, sd);
     }
   }
   if (subchannel_idx == 0) {
+    /* couldn't create any subchannel. Bail out */
     gpr_free(p->subchannels);
     gpr_free(p);
     return NULL;
diff --git a/src/core/ext/resolver/dns/native/dns_resolver.c b/src/core/ext/resolver/dns/native/dns_resolver.c
index 79682e7..32e9de6 100644
--- a/src/core/ext/resolver/dns/native/dns_resolver.c
+++ b/src/core/ext/resolver/dns/native/dns_resolver.c
@@ -175,10 +175,18 @@
     grpc_lb_policy_args lb_policy_args;
     result = grpc_resolver_result_create();
     memset(&lb_policy_args, 0, sizeof(lb_policy_args));
-    lb_policy_args.addresses = addresses;
+    lb_policy_args.num_addresses = addresses->naddrs;
+    lb_policy_args.addresses =
+        gpr_malloc(sizeof(grpc_lb_address) * lb_policy_args.num_addresses);
+    memset(lb_policy_args.addresses, 0,
+           sizeof(grpc_lb_address) * lb_policy_args.num_addresses);
+    for (size_t i = 0; i < addresses->naddrs; ++i) {
+      lb_policy_args.addresses[i].resolved_address = &r->addresses->addrs[i];
+    }
     lb_policy_args.client_channel_factory = r->client_channel_factory;
     lb_policy =
         grpc_lb_policy_create(exec_ctx, r->lb_policy_name, &lb_policy_args);
+    gpr_free(lb_policy_args.addresses);
     if (lb_policy != NULL) {
       grpc_resolver_result_set_lb_policy(result, lb_policy);
       GRPC_LB_POLICY_UNREF(exec_ctx, lb_policy, "construction");
diff --git a/src/core/ext/resolver/sockaddr/sockaddr_resolver.c b/src/core/ext/resolver/sockaddr/sockaddr_resolver.c
index 3807522..4252852 100644
--- a/src/core/ext/resolver/sockaddr/sockaddr_resolver.c
+++ b/src/core/ext/resolver/sockaddr/sockaddr_resolver.c
@@ -125,10 +125,18 @@
     grpc_resolver_result *result = grpc_resolver_result_create();
     grpc_lb_policy_args lb_policy_args;
     memset(&lb_policy_args, 0, sizeof(lb_policy_args));
-    lb_policy_args.addresses = r->addresses;
+    lb_policy_args.num_addresses = r->addresses->naddrs;
+    lb_policy_args.addresses =
+        gpr_malloc(sizeof(grpc_lb_address) * lb_policy_args.num_addresses);
+    memset(lb_policy_args.addresses, 0,
+           sizeof(grpc_lb_address) * lb_policy_args.num_addresses);
+    for (size_t i = 0; i < lb_policy_args.num_addresses; ++i) {
+      lb_policy_args.addresses[i].resolved_address = &r->addresses->addrs[i];
+    }
     lb_policy_args.client_channel_factory = r->client_channel_factory;
     grpc_lb_policy *lb_policy =
         grpc_lb_policy_create(exec_ctx, r->lb_policy_name, &lb_policy_args);
+    gpr_free(lb_policy_args.addresses);
     grpc_resolver_result_set_lb_policy(result, lb_policy);
     GRPC_LB_POLICY_UNREF(exec_ctx, lb_policy, "sockaddr");
     r->published = 1;
diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c
index 0e8dfb7..00999e3 100644
--- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c
+++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c
@@ -408,6 +408,19 @@
           push_setting(exec_ctx, t, GRPC_CHTTP2_SETTINGS_MAX_HEADER_LIST_SIZE,
                        (uint32_t)channel_args->args[i].value.integer);
         }
+      } else if (0 == strcmp(channel_args->args[i].key,
+                             GRPC_ARG_HTTP2_MAX_FRAME_SIZE)) {
+        if (channel_args->args[i].type != GRPC_ARG_INTEGER) {
+          gpr_log(GPR_ERROR, "%s: must be an integer",
+                  GRPC_ARG_HTTP2_MAX_FRAME_SIZE);
+        } else if (channel_args->args[i].value.integer < 16384 ||
+                   channel_args->args[i].value.integer > 16777215) {
+          gpr_log(GPR_ERROR, "%s: must be between 16384 and 16777215",
+                  GRPC_ARG_HTTP2_MAX_FRAME_SIZE);
+        } else {
+          push_setting(exec_ctx, t, GRPC_CHTTP2_SETTINGS_MAX_FRAME_SIZE,
+                       (uint32_t)channel_args->args[i].value.integer);
+        }
       }
     }
   }
diff --git a/src/core/ext/transport/chttp2/transport/frame.h b/src/core/ext/transport/chttp2/transport/frame.h
index 7776609..507aae4 100644
--- a/src/core/ext/transport/chttp2/transport/frame.h
+++ b/src/core/ext/transport/chttp2/transport/frame.h
@@ -52,8 +52,6 @@
 #define GRPC_CHTTP2_FRAME_GOAWAY 7
 #define GRPC_CHTTP2_FRAME_WINDOW_UPDATE 8
 
-#define GRPC_CHTTP2_MAX_PAYLOAD_LENGTH ((1 << 14) - 1)
-
 #define GRPC_CHTTP2_DATA_FLAG_END_STREAM 1
 #define GRPC_CHTTP2_FLAG_ACK 1
 #define GRPC_CHTTP2_DATA_FLAG_END_HEADERS 4
diff --git a/src/core/ext/transport/chttp2/transport/hpack_encoder.c b/src/core/ext/transport/chttp2/transport/hpack_encoder.c
index 2cb8205..581471b 100644
--- a/src/core/ext/transport/chttp2/transport/hpack_encoder.c
+++ b/src/core/ext/transport/chttp2/transport/hpack_encoder.c
@@ -78,6 +78,8 @@
   uint32_t stream_id;
   gpr_slice_buffer *output;
   grpc_transport_one_way_stats *stats;
+  /* maximum size of a frame */
+  size_t max_frame_size;
 } framer_state;
 
 /* fills p (which is expected to be 9 bytes long) with a data frame header */
@@ -123,7 +125,7 @@
    needed */
 static void ensure_space(framer_state *st, size_t need_bytes) {
   if (st->output->length - st->output_length_at_start_of_frame + need_bytes <=
-      GRPC_CHTTP2_MAX_PAYLOAD_LENGTH) {
+      st->max_frame_size) {
     return;
   }
   finish_frame(st, 0, 0);
@@ -149,8 +151,8 @@
   size_t len = GPR_SLICE_LENGTH(slice);
   size_t remaining;
   if (len == 0) return;
-  remaining = GRPC_CHTTP2_MAX_PAYLOAD_LENGTH +
-              st->output_length_at_start_of_frame - st->output->length;
+  remaining = st->max_frame_size + st->output_length_at_start_of_frame -
+              st->output->length;
   if (len <= remaining) {
     st->stats->header_bytes += len;
     gpr_slice_buffer_add(st->output, slice);
@@ -542,6 +544,7 @@
 void grpc_chttp2_encode_header(grpc_chttp2_hpack_compressor *c,
                                uint32_t stream_id,
                                grpc_metadata_batch *metadata, int is_eof,
+                               size_t max_frame_size,
                                grpc_transport_one_way_stats *stats,
                                gpr_slice_buffer *outbuf) {
   framer_state st;
@@ -555,6 +558,7 @@
   st.output = outbuf;
   st.is_first_frame = 1;
   st.stats = stats;
+  st.max_frame_size = max_frame_size;
 
   /* Encode a metadata batch; store the returned values, representing
      a metadata element that needs to be unreffed back into the metadata
diff --git a/src/core/ext/transport/chttp2/transport/hpack_encoder.h b/src/core/ext/transport/chttp2/transport/hpack_encoder.h
index 0f7b0b0..4c3a931 100644
--- a/src/core/ext/transport/chttp2/transport/hpack_encoder.h
+++ b/src/core/ext/transport/chttp2/transport/hpack_encoder.h
@@ -91,6 +91,7 @@
 
 void grpc_chttp2_encode_header(grpc_chttp2_hpack_compressor *c, uint32_t id,
                                grpc_metadata_batch *metadata, int is_eof,
+                               size_t max_frame_size,
                                grpc_transport_one_way_stats *stats,
                                gpr_slice_buffer *outbuf);
 
diff --git a/src/core/ext/transport/chttp2/transport/internal.h b/src/core/ext/transport/chttp2/transport/internal.h
index e1dcf52..d67c014 100644
--- a/src/core/ext/transport/chttp2/transport/internal.h
+++ b/src/core/ext/transport/chttp2/transport/internal.h
@@ -223,6 +223,8 @@
   uint8_t is_client;
   /** callback for when writing is done */
   grpc_closure done_cb;
+  /** maximum frame size */
+  uint32_t max_frame_size;
 } grpc_chttp2_transport_writing;
 
 struct grpc_chttp2_transport_parsing {
diff --git a/src/core/ext/transport/chttp2/transport/writing.c b/src/core/ext/transport/chttp2/transport/writing.c
index 8f7a1f5..311b26e 100644
--- a/src/core/ext/transport/chttp2/transport/writing.c
+++ b/src/core/ext/transport/chttp2/transport/writing.c
@@ -51,6 +51,10 @@
 
   GPR_TIMER_BEGIN("grpc_chttp2_unlocking_check_writes", 0);
 
+  transport_writing->max_frame_size =
+      transport_global->settings[GRPC_ACKED_SETTINGS]
+                                [GRPC_CHTTP2_SETTINGS_MAX_FRAME_SIZE];
+
   /* simple writes are queued to qbuf, and flushed here */
   gpr_slice_buffer_swap(&transport_global->qbuf, &transport_writing->outbuf);
   GPR_ASSERT(transport_global->qbuf.count == 0);
@@ -206,14 +210,15 @@
   while (
       grpc_chttp2_list_pop_writing_stream(transport_writing, &stream_writing)) {
     uint32_t max_outgoing =
-        (uint32_t)GPR_MIN(GRPC_CHTTP2_MAX_PAYLOAD_LENGTH,
+        (uint32_t)GPR_MIN(transport_writing->max_frame_size,
                           GPR_MIN(stream_writing->outgoing_window,
                                   transport_writing->outgoing_window));
     /* send initial metadata if it's available */
     if (stream_writing->send_initial_metadata != NULL) {
       grpc_chttp2_encode_header(
           &transport_writing->hpack_compressor, stream_writing->id,
-          stream_writing->send_initial_metadata, 0, &stream_writing->stats,
+          stream_writing->send_initial_metadata, 0,
+          transport_writing->max_frame_size, &stream_writing->stats,
           &transport_writing->outbuf);
       stream_writing->send_initial_metadata = NULL;
       stream_writing->sent_initial_metadata = 1;
@@ -303,7 +308,8 @@
       } else {
         grpc_chttp2_encode_header(
             &transport_writing->hpack_compressor, stream_writing->id,
-            stream_writing->send_trailing_metadata, 1, &stream_writing->stats,
+            stream_writing->send_trailing_metadata, 1,
+            transport_writing->max_frame_size, &stream_writing->stats,
             &transport_writing->outbuf);
       }
       if (!transport_writing->is_client && !stream_writing->read_closed) {
diff --git a/src/core/ext/transport/cronet/transport/cronet_transport.c b/src/core/ext/transport/cronet/transport/cronet_transport.c
index 029c150..366690a 100644
--- a/src/core/ext/transport/cronet/transport/cronet_transport.c
+++ b/src/core/ext/transport/cronet/transport/cronet_transport.c
@@ -294,7 +294,7 @@
 /*
   Cycle through ops and try to take next action. Break when either
   an action with callback is taken, or no action is possible.
-  This can be executed from the Cronet network thread via cronet callback
+  This can get executed from the Cronet network thread via cronet callback
   or on the application supplied thread via the perform_stream_op function.
 */
 static void execute_from_storage(stream_obj *s) {
@@ -329,6 +329,7 @@
 static void on_failed(cronet_bidirectional_stream *stream, int net_error) {
   CRONET_LOG(GPR_DEBUG, "on_failed(%p, %d)", stream, net_error);
   stream_obj *s = (stream_obj *)stream->annotation;
+  gpr_mu_lock(&s->mu);
   cronet_bidirectional_stream_destroy(s->cbs);
   s->state.state_callback_received[OP_FAILED] = true;
   s->cbs = NULL;
@@ -340,6 +341,7 @@
     gpr_free(s->state.ws.write_buffer);
     s->state.ws.write_buffer = NULL;
   }
+  gpr_mu_unlock(&s->mu);
   execute_from_storage(s);
 }
 
@@ -349,6 +351,7 @@
 static void on_canceled(cronet_bidirectional_stream *stream) {
   CRONET_LOG(GPR_DEBUG, "on_canceled(%p)", stream);
   stream_obj *s = (stream_obj *)stream->annotation;
+  gpr_mu_lock(&s->mu);
   cronet_bidirectional_stream_destroy(s->cbs);
   s->state.state_callback_received[OP_CANCELED] = true;
   s->cbs = NULL;
@@ -360,6 +363,7 @@
     gpr_free(s->state.ws.write_buffer);
     s->state.ws.write_buffer = NULL;
   }
+  gpr_mu_unlock(&s->mu);
   execute_from_storage(s);
 }
 
@@ -369,9 +373,11 @@
 static void on_succeeded(cronet_bidirectional_stream *stream) {
   CRONET_LOG(GPR_DEBUG, "on_succeeded(%p)", stream);
   stream_obj *s = (stream_obj *)stream->annotation;
+  gpr_mu_lock(&s->mu);
   cronet_bidirectional_stream_destroy(s->cbs);
   s->state.state_callback_received[OP_SUCCEEDED] = true;
   s->cbs = NULL;
+  gpr_mu_unlock(&s->mu);
   execute_from_storage(s);
 }
 
@@ -381,6 +387,7 @@
 static void on_request_headers_sent(cronet_bidirectional_stream *stream) {
   CRONET_LOG(GPR_DEBUG, "W: on_request_headers_sent(%p)", stream);
   stream_obj *s = (stream_obj *)stream->annotation;
+  gpr_mu_lock(&s->mu);
   s->state.state_op_done[OP_SEND_INITIAL_METADATA] = true;
   s->state.state_callback_received[OP_SEND_INITIAL_METADATA] = true;
   /* Free the memory allocated for headers */
@@ -388,6 +395,7 @@
     gpr_free(s->header_array.headers);
     s->header_array.headers = NULL;
   }
+  gpr_mu_unlock(&s->mu);
   execute_from_storage(s);
 }
 
@@ -401,6 +409,7 @@
   CRONET_LOG(GPR_DEBUG, "R: on_response_headers_received(%p, %p, %s)", stream,
              headers, negotiated_protocol);
   stream_obj *s = (stream_obj *)stream->annotation;
+  gpr_mu_lock(&s->mu);
   memset(&s->state.rs.initial_metadata, 0,
          sizeof(s->state.rs.initial_metadata));
   grpc_chttp2_incoming_metadata_buffer_init(&s->state.rs.initial_metadata);
@@ -412,6 +421,7 @@
             grpc_mdstr_from_string(headers->headers[i].value)));
   }
   s->state.state_callback_received[OP_RECV_INITIAL_METADATA] = true;
+  gpr_mu_unlock(&s->mu);
   execute_from_storage(s);
 }
 
@@ -422,11 +432,13 @@
                                const char *data) {
   stream_obj *s = (stream_obj *)stream->annotation;
   CRONET_LOG(GPR_DEBUG, "W: on_write_completed(%p, %s)", stream, data);
+  gpr_mu_lock(&s->mu);
   if (s->state.ws.write_buffer) {
     gpr_free(s->state.ws.write_buffer);
     s->state.ws.write_buffer = NULL;
   }
   s->state.state_callback_received[OP_SEND_MESSAGE] = true;
+  gpr_mu_unlock(&s->mu);
   execute_from_storage(s);
 }
 
@@ -438,6 +450,7 @@
   stream_obj *s = (stream_obj *)stream->annotation;
   CRONET_LOG(GPR_DEBUG, "R: on_read_completed(%p, %p, %d)", stream, data,
              count);
+  gpr_mu_lock(&s->mu);
   s->state.state_callback_received[OP_RECV_MESSAGE] = true;
   if (count > 0) {
     s->state.rs.received_bytes += count;
@@ -448,11 +461,14 @@
       cronet_bidirectional_stream_read(
           s->cbs, s->state.rs.read_buffer + s->state.rs.received_bytes,
           s->state.rs.remaining_bytes);
+      gpr_mu_unlock(&s->mu);
     } else {
+      gpr_mu_unlock(&s->mu);
       execute_from_storage(s);
     }
   } else {
     s->state.rs.read_stream_closed = true;
+    gpr_mu_unlock(&s->mu);
     execute_from_storage(s);
   }
 }
@@ -466,6 +482,7 @@
   CRONET_LOG(GPR_DEBUG, "R: on_response_trailers_received(%p,%p)", stream,
              trailers);
   stream_obj *s = (stream_obj *)stream->annotation;
+  gpr_mu_lock(&s->mu);
   memset(&s->state.rs.trailing_metadata, 0,
          sizeof(s->state.rs.trailing_metadata));
   s->state.rs.trailing_metadata_valid = false;
@@ -481,6 +498,7 @@
     s->state.rs.trailing_metadata_valid = true;
   }
   s->state.state_callback_received[OP_RECV_TRAILING_METADATA] = true;
+  gpr_mu_unlock(&s->mu);
   execute_from_storage(s);
 }
 
@@ -757,14 +775,15 @@
              op_can_be_run(stream_op, stream_state, &oas->state,
                            OP_RECV_INITIAL_METADATA)) {
     CRONET_LOG(GPR_DEBUG, "running: %p  OP_RECV_INITIAL_METADATA", oas);
-    if (!stream_state->state_op_done[OP_CANCEL_ERROR]) {
+    if (stream_state->state_op_done[OP_CANCEL_ERROR] ||
+        stream_state->state_callback_received[OP_FAILED]) {
+      grpc_exec_ctx_sched(exec_ctx, stream_op->recv_initial_metadata_ready,
+                          GRPC_ERROR_CANCELLED, NULL);
+    } else {
       grpc_chttp2_incoming_metadata_buffer_publish(
           &oas->s->state.rs.initial_metadata, stream_op->recv_initial_metadata);
       grpc_exec_ctx_sched(exec_ctx, stream_op->recv_initial_metadata_ready,
                           GRPC_ERROR_NONE, NULL);
-    } else {
-      grpc_exec_ctx_sched(exec_ctx, stream_op->recv_initial_metadata_ready,
-                          GRPC_ERROR_CANCELLED, NULL);
     }
     stream_state->state_op_done[OP_RECV_INITIAL_METADATA] = true;
     result = ACTION_TAKEN_NO_CALLBACK;
@@ -772,32 +791,40 @@
              op_can_be_run(stream_op, stream_state, &oas->state,
                            OP_SEND_MESSAGE)) {
     CRONET_LOG(GPR_DEBUG, "running: %p  OP_SEND_MESSAGE", oas);
-    gpr_slice_buffer write_slice_buffer;
-    gpr_slice slice;
-    gpr_slice_buffer_init(&write_slice_buffer);
-    grpc_byte_stream_next(NULL, stream_op->send_message, &slice,
-                          stream_op->send_message->length, NULL);
-    /* Check that compression flag is OFF. We don't support compression yet. */
-    if (stream_op->send_message->flags != 0) {
-      gpr_log(GPR_ERROR, "Compression is not supported");
-      GPR_ASSERT(stream_op->send_message->flags == 0);
-    }
-    gpr_slice_buffer_add(&write_slice_buffer, slice);
-    if (write_slice_buffer.count != 1) {
-      /* Empty request not handled yet */
-      gpr_log(GPR_ERROR, "Empty request is not supported");
-      GPR_ASSERT(write_slice_buffer.count == 1);
-    }
-    if (write_slice_buffer.count > 0) {
-      size_t write_buffer_size;
-      create_grpc_frame(&write_slice_buffer, &stream_state->ws.write_buffer,
-                        &write_buffer_size);
-      CRONET_LOG(GPR_DEBUG, "cronet_bidirectional_stream_write (%p, %p)",
-                 s->cbs, stream_state->ws.write_buffer);
-      stream_state->state_callback_received[OP_SEND_MESSAGE] = false;
-      cronet_bidirectional_stream_write(s->cbs, stream_state->ws.write_buffer,
-                                        (int)write_buffer_size, false);
-      result = ACTION_TAKEN_WITH_CALLBACK;
+    if (stream_state->state_callback_received[OP_FAILED]) {
+      result = NO_ACTION_POSSIBLE;
+      CRONET_LOG(GPR_DEBUG, "Stream is either cancelled or failed.");
+    } else {
+      gpr_slice_buffer write_slice_buffer;
+      gpr_slice slice;
+      gpr_slice_buffer_init(&write_slice_buffer);
+      grpc_byte_stream_next(NULL, stream_op->send_message, &slice,
+                            stream_op->send_message->length, NULL);
+      /* Check that compression flag is OFF. We don't support compression yet.
+       */
+      if (stream_op->send_message->flags != 0) {
+        gpr_log(GPR_ERROR, "Compression is not supported");
+        GPR_ASSERT(stream_op->send_message->flags == 0);
+      }
+      gpr_slice_buffer_add(&write_slice_buffer, slice);
+      if (write_slice_buffer.count != 1) {
+        /* Empty request not handled yet */
+        gpr_log(GPR_ERROR, "Empty request is not supported");
+        GPR_ASSERT(write_slice_buffer.count == 1);
+      }
+      if (write_slice_buffer.count > 0) {
+        size_t write_buffer_size;
+        create_grpc_frame(&write_slice_buffer, &stream_state->ws.write_buffer,
+                          &write_buffer_size);
+        CRONET_LOG(GPR_DEBUG, "cronet_bidirectional_stream_write (%p, %p)",
+                   s->cbs, stream_state->ws.write_buffer);
+        stream_state->state_callback_received[OP_SEND_MESSAGE] = false;
+        cronet_bidirectional_stream_write(s->cbs, stream_state->ws.write_buffer,
+                                          (int)write_buffer_size, false);
+        result = ACTION_TAKEN_WITH_CALLBACK;
+      } else {
+        result = NO_ACTION_POSSIBLE;
+      }
     }
     stream_state->state_op_done[OP_SEND_MESSAGE] = true;
     oas->state.state_op_done[OP_SEND_MESSAGE] = true;
@@ -805,7 +832,9 @@
              op_can_be_run(stream_op, stream_state, &oas->state,
                            OP_RECV_MESSAGE)) {
     CRONET_LOG(GPR_DEBUG, "running: %p  OP_RECV_MESSAGE", oas);
-    if (stream_state->state_op_done[OP_CANCEL_ERROR]) {
+    if (stream_state->state_op_done[OP_CANCEL_ERROR] ||
+        stream_state->state_callback_received[OP_FAILED]) {
+      CRONET_LOG(GPR_DEBUG, "Stream is either cancelled or failed.");
       grpc_exec_ctx_sched(exec_ctx, stream_op->recv_message_ready,
                           GRPC_ERROR_CANCELLED, NULL);
       stream_state->state_op_done[OP_RECV_MESSAGE] = true;
@@ -861,8 +890,10 @@
             true; /* Indicates that at least one read request has been made */
         cronet_bidirectional_stream_read(s->cbs, stream_state->rs.read_buffer,
                                          stream_state->rs.remaining_bytes);
+        result = ACTION_TAKEN_WITH_CALLBACK;
+      } else {
+        result = NO_ACTION_POSSIBLE;
       }
-      result = ACTION_TAKEN_WITH_CALLBACK;
     } else if (stream_state->rs.remaining_bytes == 0) {
       CRONET_LOG(GPR_DEBUG, "read operation complete");
       gpr_slice read_data_slice =
@@ -903,11 +934,17 @@
              op_can_be_run(stream_op, stream_state, &oas->state,
                            OP_SEND_TRAILING_METADATA)) {
     CRONET_LOG(GPR_DEBUG, "running: %p  OP_SEND_TRAILING_METADATA", oas);
-    CRONET_LOG(GPR_DEBUG, "cronet_bidirectional_stream_write (%p, 0)", s->cbs);
-    stream_state->state_callback_received[OP_SEND_MESSAGE] = false;
-    cronet_bidirectional_stream_write(s->cbs, "", 0, true);
+    if (stream_state->state_callback_received[OP_FAILED]) {
+      result = NO_ACTION_POSSIBLE;
+      CRONET_LOG(GPR_DEBUG, "Stream is either cancelled or failed.");
+    } else {
+      CRONET_LOG(GPR_DEBUG, "cronet_bidirectional_stream_write (%p, 0)",
+                 s->cbs);
+      stream_state->state_callback_received[OP_SEND_MESSAGE] = false;
+      cronet_bidirectional_stream_write(s->cbs, "", 0, true);
+      result = ACTION_TAKEN_WITH_CALLBACK;
+    }
     stream_state->state_op_done[OP_SEND_TRAILING_METADATA] = true;
-    result = ACTION_TAKEN_WITH_CALLBACK;
   } else if (stream_op->cancel_error &&
              op_can_be_run(stream_op, stream_state, &oas->state,
                            OP_CANCEL_ERROR)) {
diff --git a/src/core/lib/channel/handshaker.c b/src/core/lib/channel/handshaker.c
index c0979f5..8f9fb17 100644
--- a/src/core/lib/channel/handshaker.c
+++ b/src/core/lib/channel/handshaker.c
@@ -33,8 +33,8 @@
 
 #include <string.h>
 
-#include <grpc/impl/codegen/alloc.h>
-#include <grpc/impl/codegen/log.h>
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
 
 #include "src/core/lib/channel/channel_args.h"
 #include "src/core/lib/channel/handshaker.h"
diff --git a/src/core/lib/channel/handshaker.h b/src/core/lib/channel/handshaker.h
index b276f60..d574b46 100644
--- a/src/core/lib/channel/handshaker.h
+++ b/src/core/lib/channel/handshaker.h
@@ -35,8 +35,6 @@
 #define GRPC_CORE_LIB_CHANNEL_HANDSHAKER_H
 
 #include <grpc/impl/codegen/grpc_types.h>
-#include <grpc/impl/codegen/time.h>
-#include <grpc/support/slice_buffer.h>
 
 #include "src/core/lib/iomgr/closure.h"
 #include "src/core/lib/iomgr/endpoint.h"
diff --git a/src/core/lib/channel/http_client_filter.c b/src/core/lib/channel/http_client_filter.c
index ef68cc8..edcc741 100644
--- a/src/core/lib/channel/http_client_filter.c
+++ b/src/core/lib/channel/http_client_filter.c
@@ -233,7 +233,6 @@
     if (method == GRPC_MDELEM_METHOD_GET) {
       /* allocate memory to hold the entire payload */
       calld->payload_bytes = gpr_malloc(op->send_message->length);
-      GPR_ASSERT(calld->payload_bytes);
 
       /* read slices of send_message and copy into payload_bytes */
       calld->send_op = *op;
diff --git a/src/core/lib/security/credentials/jwt/json_token.c b/src/core/lib/security/credentials/jwt/json_token.c
index 354c131..192a5f4 100644
--- a/src/core/lib/security/credentials/jwt/json_token.c
+++ b/src/core/lib/security/credentials/jwt/json_token.c
@@ -38,6 +38,7 @@
 #include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
 #include <grpc/support/string_util.h>
+#include <grpc/support/time.h>
 
 #include "src/core/lib/security/util/b64.h"
 #include "src/core/lib/security/util/json_util.h"
diff --git a/src/core/lib/support/percent_encoding.c b/src/core/lib/support/percent_encoding.c
new file mode 100644
index 0000000..3c19f26
--- /dev/null
+++ b/src/core/lib/support/percent_encoding.c
@@ -0,0 +1,180 @@
+/*
+ *
+ * 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/lib/support/percent_encoding.h"
+
+#include <grpc/support/log.h>
+
+const uint8_t gpr_url_percent_encoding_unreserved_bytes[256 / 8] = {
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0xff, 0x03, 0xfe, 0xff, 0xff,
+    0x87, 0xfe, 0xff, 0xff, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+const uint8_t gpr_compatible_percent_encoding_unreserved_bytes[256 / 8] = {
+    0x00, 0x00, 0x00, 0x00, 0xdf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+    0xff, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+
+static bool is_unreserved_character(uint8_t c,
+                                    const uint8_t *unreserved_bytes) {
+  return ((unreserved_bytes[c / 8] >> (c % 8)) & 1) != 0;
+}
+
+gpr_slice gpr_percent_encode_slice(gpr_slice slice,
+                                   const uint8_t *unreserved_bytes) {
+  static const uint8_t hex[] = "0123456789ABCDEF";
+
+  // first pass: count the number of bytes needed to output this string
+  size_t output_length = 0;
+  const uint8_t *slice_start = GPR_SLICE_START_PTR(slice);
+  const uint8_t *slice_end = GPR_SLICE_END_PTR(slice);
+  const uint8_t *p;
+  bool any_reserved_bytes = false;
+  for (p = slice_start; p < slice_end; p++) {
+    bool unres = is_unreserved_character(*p, unreserved_bytes);
+    output_length += unres ? 1 : 3;
+    any_reserved_bytes |= !unres;
+  }
+  // no unreserved bytes: return the string unmodified
+  if (!any_reserved_bytes) {
+    return gpr_slice_ref(slice);
+  }
+  // second pass: actually encode
+  gpr_slice out = gpr_slice_malloc(output_length);
+  uint8_t *q = GPR_SLICE_START_PTR(out);
+  for (p = slice_start; p < slice_end; p++) {
+    if (is_unreserved_character(*p, unreserved_bytes)) {
+      *q++ = *p;
+    } else {
+      *q++ = '%';
+      *q++ = hex[*p >> 4];
+      *q++ = hex[*p & 15];
+    }
+  }
+  GPR_ASSERT(q == GPR_SLICE_END_PTR(out));
+  return out;
+}
+
+static bool valid_hex(const uint8_t *p, const uint8_t *end) {
+  if (p >= end) return false;
+  return (*p >= '0' && *p <= '9') || (*p >= 'a' && *p <= 'f') ||
+         (*p >= 'A' && *p <= 'F');
+}
+
+static uint8_t dehex(uint8_t c) {
+  if (c >= '0' && c <= '9') return (uint8_t)(c - '0');
+  if (c >= 'A' && c <= 'F') return (uint8_t)(c - 'A' + 10);
+  if (c >= 'a' && c <= 'f') return (uint8_t)(c - 'a' + 10);
+  GPR_UNREACHABLE_CODE(return 255);
+}
+
+bool gpr_strict_percent_decode_slice(gpr_slice slice_in,
+                                     const uint8_t *unreserved_bytes,
+                                     gpr_slice *slice_out) {
+  const uint8_t *p = GPR_SLICE_START_PTR(slice_in);
+  const uint8_t *in_end = GPR_SLICE_END_PTR(slice_in);
+  size_t out_length = 0;
+  bool any_percent_encoded_stuff = false;
+  while (p != in_end) {
+    if (*p == '%') {
+      if (!valid_hex(++p, in_end)) return false;
+      if (!valid_hex(++p, in_end)) return false;
+      p++;
+      out_length++;
+      any_percent_encoded_stuff = true;
+    } else if (is_unreserved_character(*p, unreserved_bytes)) {
+      p++;
+      out_length++;
+    } else {
+      return false;
+    }
+  }
+  if (!any_percent_encoded_stuff) {
+    *slice_out = gpr_slice_ref(slice_in);
+    return true;
+  }
+  p = GPR_SLICE_START_PTR(slice_in);
+  *slice_out = gpr_slice_malloc(out_length);
+  uint8_t *q = GPR_SLICE_START_PTR(*slice_out);
+  while (p != in_end) {
+    if (*p == '%') {
+      *q++ = (uint8_t)(dehex(p[1]) << 4) | (dehex(p[2]));
+      p += 3;
+    } else {
+      *q++ = *p++;
+    }
+  }
+  GPR_ASSERT(q == GPR_SLICE_END_PTR(*slice_out));
+  return true;
+}
+
+gpr_slice gpr_permissive_percent_decode_slice(gpr_slice slice_in) {
+  const uint8_t *p = GPR_SLICE_START_PTR(slice_in);
+  const uint8_t *in_end = GPR_SLICE_END_PTR(slice_in);
+  size_t out_length = 0;
+  bool any_percent_encoded_stuff = false;
+  while (p != in_end) {
+    if (*p == '%') {
+      if (!valid_hex(p + 1, in_end) || !valid_hex(p + 2, in_end)) {
+        p++;
+        out_length++;
+      } else {
+        p += 3;
+        out_length++;
+        any_percent_encoded_stuff = true;
+      }
+    } else {
+      p++;
+      out_length++;
+    }
+  }
+  if (!any_percent_encoded_stuff) {
+    return gpr_slice_ref(slice_in);
+  }
+  p = GPR_SLICE_START_PTR(slice_in);
+  gpr_slice out = gpr_slice_malloc(out_length);
+  uint8_t *q = GPR_SLICE_START_PTR(out);
+  while (p != in_end) {
+    if (*p == '%') {
+      if (!valid_hex(p + 1, in_end) || !valid_hex(p + 2, in_end)) {
+        *q++ = *p++;
+      } else {
+        *q++ = (uint8_t)(dehex(p[1]) << 4) | (dehex(p[2]));
+        p += 3;
+      }
+    } else {
+      *q++ = *p++;
+    }
+  }
+  GPR_ASSERT(q == GPR_SLICE_END_PTR(out));
+  return out;
+}
diff --git a/src/core/lib/support/percent_encoding.h b/src/core/lib/support/percent_encoding.h
new file mode 100644
index 0000000..000bf14
--- /dev/null
+++ b/src/core/lib/support/percent_encoding.h
@@ -0,0 +1,78 @@
+/*
+ *
+ * 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_LIB_SUPPORT_PERCENT_ENCODING_H
+#define GRPC_CORE_LIB_SUPPORT_PERCENT_ENCODING_H
+
+/* Percent encoding and decoding of slices.
+   Transforms arbitrary strings into safe-for-transmission strings by using
+   variants of percent encoding (RFC 3986).
+   Two major variants are supplied: one that strictly matches URL encoding,
+     and another which applies percent encoding only to non-http2 header
+     bytes (the 'compatible' variant) */
+
+#include <stdbool.h>
+
+#include <grpc/support/slice.h>
+
+/* URL percent encoding spec bitfield (usabel as 'unreserved_bytes' in
+   gpr_percent_encode_slice, gpr_strict_percent_decode_slice).
+   Flags [A-Za-z0-9-_.~] as unreserved bytes for the percent encoding routines
+   */
+extern const uint8_t gpr_url_percent_encoding_unreserved_bytes[256 / 8];
+/* URL percent encoding spec bitfield (usabel as 'unreserved_bytes' in
+   gpr_percent_encode_slice, gpr_strict_percent_decode_slice).
+   Flags ascii7 non-control characters excluding '%' as unreserved bytes for the
+   percent encoding routines */
+extern const uint8_t gpr_compatible_percent_encoding_unreserved_bytes[256 / 8];
+
+/* Percent-encode a slice, returning the new slice (this cannot fail):
+   unreserved_bytes is a bitfield indicating which bytes are considered
+   unreserved and thus do not need percent encoding */
+gpr_slice gpr_percent_encode_slice(gpr_slice slice,
+                                   const uint8_t *unreserved_bytes);
+/* Percent-decode a slice, strictly.
+   If the input is legal (contains no unreserved bytes, and legal % encodings),
+   returns true and sets *slice_out to the decoded slice.
+   If the input is not legal, returns false and leaves *slice_out untouched.
+   unreserved_bytes is a bitfield indicating which bytes are considered
+   unreserved and thus do not need percent encoding */
+bool gpr_strict_percent_decode_slice(gpr_slice slice_in,
+                                     const uint8_t *unreserved_bytes,
+                                     gpr_slice *slice_out);
+/* Percent-decode a slice, permissively.
+   If a % triplet can not be decoded, pass it through verbatim.
+   This cannot fail. */
+gpr_slice gpr_permissive_percent_decode_slice(gpr_slice slice_in);
+
+#endif /* GRPC_CORE_LIB_SUPPORT_PERCENT_ENCODING_H */
diff --git a/src/core/lib/support/time_posix.c b/src/core/lib/support/time_posix.c
index 1154207..a69c501 100644
--- a/src/core/lib/support/time_posix.c
+++ b/src/core/lib/support/time_posix.c
@@ -127,7 +127,7 @@
       now.tv_nsec = now_tv.tv_usec * 1000;
       break;
     case GPR_CLOCK_MONOTONIC:
-      now_dbl = (mach_absolute_time() - g_time_start) * g_time_scale;
+      now_dbl = ((double)(mach_absolute_time() - g_time_start)) * g_time_scale;
       now.tv_sec = (int64_t)(now_dbl * 1e-9);
       now.tv_nsec = (int32_t)(now_dbl - ((double)now.tv_sec) * 1e9);
       break;
diff --git a/src/core/lib/transport/metadata.c b/src/core/lib/transport/metadata.c
index 0677f29..4b40c27 100644
--- a/src/core/lib/transport/metadata.c
+++ b/src/core/lib/transport/metadata.c
@@ -278,7 +278,7 @@
                           internal_metadata *md DEBUG_ARGS) {
 #ifdef GRPC_METADATA_REFCOUNT_DEBUG
   gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG,
-          "ELM   REF:%p:%d->%d: '%s' = '%s'", md,
+          "ELM   REF:%p:%zu->%zu: '%s' = '%s'", (void *)md,
           gpr_atm_no_barrier_load(&md->refcnt),
           gpr_atm_no_barrier_load(&md->refcnt) + 1,
           grpc_mdstr_as_c_string((grpc_mdstr *)md->key),
@@ -566,7 +566,7 @@
   shard->elems[idx] = md;
   gpr_mu_init(&md->mu_user_data);
 #ifdef GRPC_METADATA_REFCOUNT_DEBUG
-  gpr_log(GPR_DEBUG, "ELM   NEW:%p:%d: '%s' = '%s'", md,
+  gpr_log(GPR_DEBUG, "ELM   NEW:%p:%zu: '%s' = '%s'", (void *)md,
           gpr_atm_no_barrier_load(&md->refcnt),
           grpc_mdstr_as_c_string((grpc_mdstr *)md->key),
           grpc_mdstr_as_c_string((grpc_mdstr *)md->value));
@@ -639,7 +639,7 @@
   if (is_mdelem_static(gmd)) return gmd;
 #ifdef GRPC_METADATA_REFCOUNT_DEBUG
   gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG,
-          "ELM   REF:%p:%d->%d: '%s' = '%s'", md,
+          "ELM   REF:%p:%zu->%zu: '%s' = '%s'", (void *)md,
           gpr_atm_no_barrier_load(&md->refcnt),
           gpr_atm_no_barrier_load(&md->refcnt) + 1,
           grpc_mdstr_as_c_string((grpc_mdstr *)md->key),
@@ -649,7 +649,7 @@
      this function - meaning that no adjustment to mdtab_free is necessary,
      simplifying the logic here to be just an atomic increment */
   /* use C assert to have this removed in opt builds */
-  assert(gpr_atm_no_barrier_load(&md->refcnt) >= 1);
+  GPR_ASSERT(gpr_atm_no_barrier_load(&md->refcnt) >= 1);
   gpr_atm_no_barrier_fetch_add(&md->refcnt, 1);
   return gmd;
 }
@@ -660,14 +660,16 @@
   if (is_mdelem_static(gmd)) return;
 #ifdef GRPC_METADATA_REFCOUNT_DEBUG
   gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG,
-          "ELM UNREF:%p:%d->%d: '%s' = '%s'", md,
+          "ELM UNREF:%p:%zu->%zu: '%s' = '%s'", (void *)md,
           gpr_atm_no_barrier_load(&md->refcnt),
           gpr_atm_no_barrier_load(&md->refcnt) - 1,
           grpc_mdstr_as_c_string((grpc_mdstr *)md->key),
           grpc_mdstr_as_c_string((grpc_mdstr *)md->value));
 #endif
   uint32_t hash = GRPC_MDSTR_KV_HASH(md->key->hash, md->value->hash);
-  if (1 == gpr_atm_full_fetch_add(&md->refcnt, -1)) {
+  const gpr_atm prev_refcount = gpr_atm_full_fetch_add(&md->refcnt, -1);
+  GPR_ASSERT(prev_refcount >= 1);
+  if (1 == prev_refcount) {
     /* once the refcount hits zero, some other thread can come along and
        free md at any time: it's unsafe from this point on to access it */
     mdtab_shard *shard =
@@ -676,10 +678,12 @@
   }
 }
 
-const char *grpc_mdstr_as_c_string(grpc_mdstr *s) {
+const char *grpc_mdstr_as_c_string(const grpc_mdstr *s) {
   return (const char *)GPR_SLICE_START_PTR(s->slice);
 }
 
+size_t grpc_mdstr_length(const grpc_mdstr *s) { return GRPC_MDSTR_LENGTH(s); }
+
 grpc_mdstr *grpc_mdstr_ref(grpc_mdstr *gs DEBUG_ARGS) {
   internal_string *s = (internal_string *)gs;
   if (is_mdstr_static(gs)) return gs;
diff --git a/src/core/lib/transport/metadata.h b/src/core/lib/transport/metadata.h
index 2b0921c..71eff0a 100644
--- a/src/core/lib/transport/metadata.h
+++ b/src/core/lib/transport/metadata.h
@@ -147,7 +147,7 @@
 
 /* Recover a char* from a grpc_mdstr. The returned string is null terminated.
    Does not promise that the returned string has no embedded nulls however. */
-const char *grpc_mdstr_as_c_string(grpc_mdstr *s);
+const char *grpc_mdstr_as_c_string(const grpc_mdstr *s);
 
 #define GRPC_MDSTR_LENGTH(s) (GPR_SLICE_LENGTH(s->slice))
 
diff --git a/src/cpp/client/channel.cc b/src/cpp/client/channel_cc.cc
similarity index 100%
rename from src/cpp/client/channel.cc
rename to src/cpp/client/channel_cc.cc
diff --git a/src/cpp/client/client_context.cc b/src/cpp/client/client_context.cc
index 0ba77a5..5b6aaa7 100644
--- a/src/cpp/client/client_context.cc
+++ b/src/cpp/client/client_context.cc
@@ -36,6 +36,7 @@
 #include <grpc/compression.h>
 #include <grpc/grpc.h>
 #include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
 #include <grpc/support/string_util.h>
 
 #include <grpc++/security/credentials.h>
@@ -60,6 +61,7 @@
     : initial_metadata_received_(false),
       fail_fast_(true),
       idempotent_(false),
+      cacheable_(false),
       call_(nullptr),
       call_canceled_(false),
       deadline_(gpr_inf_future(GPR_CLOCK_REALTIME)),
diff --git a/src/cpp/client/credentials.cc b/src/cpp/client/credentials_cc.cc
similarity index 100%
rename from src/cpp/client/credentials.cc
rename to src/cpp/client/credentials_cc.cc
diff --git a/src/cpp/common/channel_filter.h b/src/cpp/common/channel_filter.h
index ec2af63..6f5af3d 100644
--- a/src/cpp/common/channel_filter.h
+++ b/src/cpp/common/channel_filter.h
@@ -36,7 +36,7 @@
 
 #include <grpc++/impl/codegen/config.h>
 #include <grpc/grpc.h>
-#include <grpc/impl/codegen/alloc.h>
+#include <grpc/support/alloc.h>
 
 #include <functional>
 #include <vector>
diff --git a/src/cpp/common/completion_queue.cc b/src/cpp/common/completion_queue_cc.cc
similarity index 100%
rename from src/cpp/common/completion_queue.cc
rename to src/cpp/common/completion_queue_cc.cc
diff --git a/src/cpp/common/core_codegen.cc b/src/cpp/common/core_codegen.cc
index 3d6780b..ce02202 100644
--- a/src/cpp/common/core_codegen.cc
+++ b/src/cpp/common/core_codegen.cc
@@ -39,15 +39,19 @@
 #include <grpc/byte_buffer.h>
 #include <grpc/byte_buffer_reader.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/alloc.h>
+#include <grpc/support/log.h>
 #include <grpc/support/port_platform.h>
 #include <grpc/support/slice.h>
 #include <grpc/support/slice_buffer.h>
+#include <grpc/support/sync.h>
 
 #include "src/core/lib/profiling/timers.h"
 
+extern "C" {
+struct grpc_byte_buffer;
+}
+
 namespace grpc {
 
 grpc_completion_queue* CoreCodegen::grpc_completion_queue_create(
@@ -70,6 +74,19 @@
 
 void CoreCodegen::gpr_free(void* p) { return ::gpr_free(p); }
 
+void CoreCodegen::gpr_mu_init(gpr_mu* mu) { ::gpr_mu_init(mu); };
+void CoreCodegen::gpr_mu_destroy(gpr_mu* mu) { ::gpr_mu_destroy(mu); }
+void CoreCodegen::gpr_mu_lock(gpr_mu* mu) { ::gpr_mu_lock(mu); }
+void CoreCodegen::gpr_mu_unlock(gpr_mu* mu) { ::gpr_mu_unlock(mu); }
+void CoreCodegen::gpr_cv_init(gpr_cv* cv) { ::gpr_cv_init(cv); }
+void CoreCodegen::gpr_cv_destroy(gpr_cv* cv) { ::gpr_cv_destroy(cv); }
+int CoreCodegen::gpr_cv_wait(gpr_cv* cv, gpr_mu* mu,
+                             gpr_timespec abs_deadline) {
+  return ::gpr_cv_wait(cv, mu, abs_deadline);
+}
+void CoreCodegen::gpr_cv_signal(gpr_cv* cv) { ::gpr_cv_signal(cv); }
+void CoreCodegen::gpr_cv_broadcast(gpr_cv* cv) { ::gpr_cv_broadcast(cv); }
+
 void CoreCodegen::grpc_byte_buffer_destroy(grpc_byte_buffer* bb) {
   ::grpc_byte_buffer_destroy(bb);
 }
@@ -128,6 +145,10 @@
   return ::gpr_inf_future(type);
 }
 
+gpr_timespec CoreCodegen::gpr_time_0(gpr_clock_type type) {
+  return ::gpr_time_0(type);
+}
+
 void CoreCodegen::assert_fail(const char* failed_assertion) {
   gpr_log(GPR_ERROR, "assertion failed: %s", failed_assertion);
   abort();
diff --git a/src/cpp/server/server.cc b/src/cpp/server/server_cc.cc
similarity index 100%
rename from src/cpp/server/server.cc
rename to src/cpp/server/server_cc.cc
diff --git a/src/cpp/util/byte_buffer.cc b/src/cpp/util/byte_buffer_cc.cc
similarity index 100%
rename from src/cpp/util/byte_buffer.cc
rename to src/cpp/util/byte_buffer_cc.cc
diff --git a/src/cpp/util/slice.cc b/src/cpp/util/slice_cc.cc
similarity index 100%
rename from src/cpp/util/slice.cc
rename to src/cpp/util/slice_cc.cc
diff --git a/src/cpp/util/time.cc b/src/cpp/util/time_cc.cc
similarity index 100%
rename from src/cpp/util/time.cc
rename to src/cpp/util/time_cc.cc
diff --git a/src/csharp/Grpc.Auth/Grpc.Auth.csproj b/src/csharp/Grpc.Auth/Grpc.Auth.csproj
index 7a69553..a44aaf1 100644
--- a/src/csharp/Grpc.Auth/Grpc.Auth.csproj
+++ b/src/csharp/Grpc.Auth/Grpc.Auth.csproj
@@ -49,14 +49,26 @@
     <Reference Include="Newtonsoft.Json">
       <HintPath>..\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
     </Reference>
+    <Reference Include="log4net">
+      <HintPath>..\packages\log4net.2.0.3\lib\net40-full\log4net.dll</HintPath>
+    </Reference>
     <Reference Include="Google.Apis.Core">
-      <HintPath>..\packages\Google.Apis.Core.1.15.0\lib\net45\Google.Apis.Core.dll</HintPath>
+      <HintPath>..\packages\Google.Apis.Core.1.16.0\lib\net45\Google.Apis.Core.dll</HintPath>
+    </Reference>
+    <Reference Include="Zlib.Portable">
+      <HintPath>..\packages\Zlib.Portable.Signed.1.11.0\lib\portable-net4+sl5+wp8+win8+wpa81+MonoTouch+MonoAndroid\Zlib.Portable.dll</HintPath>
+    </Reference>
+    <Reference Include="Google.Apis">
+      <HintPath>..\packages\Google.Apis.1.16.0\lib\net45\Google.Apis.dll</HintPath>
+    </Reference>
+    <Reference Include="Google.Apis.PlatformServices">
+      <HintPath>..\packages\Google.Apis.1.16.0\lib\net45\Google.Apis.PlatformServices.dll</HintPath>
     </Reference>
     <Reference Include="Google.Apis.Auth">
-      <HintPath>..\packages\Google.Apis.Auth.1.15.0\lib\net45\Google.Apis.Auth.dll</HintPath>
+      <HintPath>..\packages\Google.Apis.Auth.1.16.0\lib\net45\Google.Apis.Auth.dll</HintPath>
     </Reference>
     <Reference Include="Google.Apis.Auth.PlatformServices">
-      <HintPath>..\packages\Google.Apis.Auth.1.15.0\lib\net45\Google.Apis.Auth.PlatformServices.dll</HintPath>
+      <HintPath>..\packages\Google.Apis.Auth.1.16.0\lib\net45\Google.Apis.Auth.PlatformServices.dll</HintPath>
     </Reference>
   </ItemGroup>
   <ItemGroup>
diff --git a/src/csharp/Grpc.Auth/packages.config b/src/csharp/Grpc.Auth/packages.config
index 738d3e6..11c6375 100644
--- a/src/csharp/Grpc.Auth/packages.config
+++ b/src/csharp/Grpc.Auth/packages.config
@@ -1,7 +1,10 @@
 <?xml version="1.0" encoding="utf-8"?>
 <packages>
   <package id="BouncyCastle" version="1.7.0" targetFramework="net45" />
-  <package id="Google.Apis.Auth" version="1.15.0" targetFramework="net45" />
-  <package id="Google.Apis.Core" version="1.15.0" targetFramework="net45" />
+  <package id="Google.Apis" version="1.16.0" targetFramework="net45" />
+  <package id="Google.Apis.Auth" version="1.16.0" targetFramework="net45" />
+  <package id="Google.Apis.Core" version="1.16.0" targetFramework="net45" />
+  <package id="log4net" version="2.0.3" targetFramework="net45" />
   <package id="Newtonsoft.Json" version="7.0.1" targetFramework="net45" />
+  <package id="Zlib.Portable.Signed" version="1.11.0" targetFramework="net45" />
 </packages>
\ No newline at end of file
diff --git a/src/csharp/Grpc.Auth/project.json b/src/csharp/Grpc.Auth/project.json
index 30f0944..595e29f 100644
--- a/src/csharp/Grpc.Auth/project.json
+++ b/src/csharp/Grpc.Auth/project.json
@@ -23,18 +23,13 @@
   },
   "dependencies": {
     "Grpc.Core": "1.1.0-dev",
-    "Google.Apis.Auth": "1.15.0"
+    "Google.Apis.Auth": "1.16.0"
   },
   "frameworks": {
     "net45": { },
     "netstandard1.5": {
-      "imports": [
-        "portable-net45"
-      ],
       "dependencies": {
-        "Microsoft.NETCore.Portable.Compatibility": "1.0.1",
-        "NETStandard.Library": "1.6.0",
-        "System.Threading.Tasks": "4.0.11"
+        "NETStandard.Library": "1.6.0"
       }
     }
   }
diff --git a/src/csharp/Grpc.Core.Tests/project.json b/src/csharp/Grpc.Core.Tests/project.json
index 014e226..faf28dc 100644
--- a/src/csharp/Grpc.Core.Tests/project.json
+++ b/src/csharp/Grpc.Core.Tests/project.json
@@ -42,11 +42,6 @@
       }
     }
   },
-  "runtimes": {
-    "win7-x64": { },
-    "debian.8-x64": { },
-    "osx.10.11-x64": { }
-  },
 
   "dependencies": {
     "Grpc.Core": {
@@ -66,8 +61,10 @@
         "portable-net45"
       ],
       "dependencies": {
-        "Microsoft.NETCore.App": "1.0.0",
-        "NETStandard.Library": "1.6.0"
+        "Microsoft.NETCore.App": {
+          "type": "platform",
+          "version": "1.0.0"
+        }
       }
     }
   },
diff --git a/src/csharp/Grpc.Core/GrpcEnvironment.cs b/src/csharp/Grpc.Core/GrpcEnvironment.cs
index 574e900..3ed2df2 100644
--- a/src/csharp/Grpc.Core/GrpcEnvironment.cs
+++ b/src/csharp/Grpc.Core/GrpcEnvironment.cs
@@ -351,11 +351,11 @@
                 {
                     if (!hooksRegistered)
                     {
-                        // TODO(jtattermusch): register shutdownhooks for CoreCLR as well
-#if !NETSTANDARD1_5
-
-                        AppDomain.CurrentDomain.ProcessExit += ShutdownHookHandler;
-                        AppDomain.CurrentDomain.DomainUnload += ShutdownHookHandler;
+#if NETSTANDARD1_5
+                        System.Runtime.Loader.AssemblyLoadContext.Default.Unloading += (assemblyLoadContext) => { HandleShutdown(); };
+#else
+                        AppDomain.CurrentDomain.ProcessExit += (sender, eventArgs) => { HandleShutdown(); };
+                        AppDomain.CurrentDomain.DomainUnload += (sender, eventArgs) => { HandleShutdown(); };
 #endif
                     }
                     hooksRegistered = true;
@@ -363,9 +363,9 @@
             }
 
             /// <summary>
-            /// Handler for AppDomain.DomainUnload and AppDomain.ProcessExit hooks.
+            /// Handler for AppDomain.DomainUnload, AppDomain.ProcessExit and AssemblyLoadContext.Unloading hooks.
             /// </summary>
-            private static void ShutdownHookHandler(object sender, EventArgs e)
+            private static void HandleShutdown()
             {
                 Task.WaitAll(GrpcEnvironment.ShutdownChannelsAsync(), GrpcEnvironment.KillServersAsync());
             }
diff --git a/src/csharp/Grpc.Core/Internal/NativeExtension.cs b/src/csharp/Grpc.Core/Internal/NativeExtension.cs
index 509baf7..61d8b57 100644
--- a/src/csharp/Grpc.Core/Internal/NativeExtension.cs
+++ b/src/csharp/Grpc.Core/Internal/NativeExtension.cs
@@ -100,19 +100,19 @@
 
             // With old-style VS projects, the native libraries get copied using a .targets rule to the build output folder
             // alongside the compiled assembly.
-            // With dotnet cli projects, the native libraries (just the required ones) are similarly copied to the built output folder,
-            // through the magic of Microsoft.NETCore.Platforms.
+            // With dotnet cli projects targeting net45 framework, the native libraries (just the required ones)
+            // are similarly copied to the built output folder, through the magic of Microsoft.NETCore.Platforms.
             var classicPath = Path.Combine(assemblyDirectory, GetNativeLibraryFilename());
 
-            // DNX-style project.json projects will use Grpc.Core assembly directly in the location where it got restored
+            // With dotnet cli project targeting netcoreapp1.0, projects will use Grpc.Core assembly directly in the location where it got restored
             // by nuget. We locate the native libraries based on known structure of Grpc.Core nuget package.
+            // When "dotnet publish" is used, the runtimes directory is copied next to the published assemblies.
+            string runtimesDirectory = string.Format("runtimes/{0}/native", GetPlatformString());
+            var netCorePublishedAppStylePath = Path.Combine(assemblyDirectory, runtimesDirectory, GetNativeLibraryFilename());
+            var netCoreAppStylePath = Path.Combine(assemblyDirectory, "../..", runtimesDirectory, GetNativeLibraryFilename());
 
-            // TODO: Support .NET Core applications, which act slightly differently. We may be okay if "dotnet publish"
-            // is used, but "dotnet run" leaves the native libraries in-package, while copying assemblies.
-            string platform = GetPlatformString();
-            string relativeDirectory = string.Format("../../runtimes/{0}/native", platform);
-            var dnxStylePath = Path.Combine(assemblyDirectory, relativeDirectory, GetNativeLibraryFilename());
-            string[] paths = new[] { classicPath, dnxStylePath };
+            // Look for all native library in all possible locations in given order.
+            string[] paths = new[] { classicPath, netCorePublishedAppStylePath, netCoreAppStylePath};
             return new UnmanagedLibrary(paths);
         }
 
diff --git a/src/csharp/Grpc.Core/project.json b/src/csharp/Grpc.Core/project.json
index f7e21a2..aa1e4cc 100644
--- a/src/csharp/Grpc.Core/project.json
+++ b/src/csharp/Grpc.Core/project.json
@@ -36,11 +36,9 @@
   "frameworks": {
     "net45": { },
     "netstandard1.5": {
-      "imports": [
-        "portable-net45"
-      ],
       "dependencies": {
         "NETStandard.Library": "1.6.0",
+        "System.Runtime.Loader": "4.0.0",
         "System.Threading.Thread": "4.0.0"
       }
     }
diff --git a/src/csharp/Grpc.Examples.MathClient/project.json b/src/csharp/Grpc.Examples.MathClient/project.json
index ad31947..628f532 100644
--- a/src/csharp/Grpc.Examples.MathClient/project.json
+++ b/src/csharp/Grpc.Examples.MathClient/project.json
@@ -42,11 +42,6 @@
       }
     }
   },
-  "runtimes": {
-    "win7-x64": { },
-    "debian.8-x64": { },
-    "osx.10.11-x64": { }
-  },
 
   "dependencies": {
     "Grpc.Examples": {
@@ -56,12 +51,11 @@
   "frameworks": {
     "net45": { },
     "netcoreapp1.0": {
-      "imports": [
-        "portable-net45"
-      ],
       "dependencies": {
-        "Microsoft.NETCore.App": "1.0.0",
-        "NETStandard.Library": "1.6.0"
+        "Microsoft.NETCore.App": {
+          "type": "platform",
+          "version": "1.0.0"
+        }
       }
     }
   }
diff --git a/src/csharp/Grpc.Examples.MathServer/project.json b/src/csharp/Grpc.Examples.MathServer/project.json
index ad31947..628f532 100644
--- a/src/csharp/Grpc.Examples.MathServer/project.json
+++ b/src/csharp/Grpc.Examples.MathServer/project.json
@@ -42,11 +42,6 @@
       }
     }
   },
-  "runtimes": {
-    "win7-x64": { },
-    "debian.8-x64": { },
-    "osx.10.11-x64": { }
-  },
 
   "dependencies": {
     "Grpc.Examples": {
@@ -56,12 +51,11 @@
   "frameworks": {
     "net45": { },
     "netcoreapp1.0": {
-      "imports": [
-        "portable-net45"
-      ],
       "dependencies": {
-        "Microsoft.NETCore.App": "1.0.0",
-        "NETStandard.Library": "1.6.0"
+        "Microsoft.NETCore.App": {
+          "type": "platform",
+          "version": "1.0.0"
+        }
       }
     }
   }
diff --git a/src/csharp/Grpc.Examples.Tests/Grpc.Examples.Tests.csproj b/src/csharp/Grpc.Examples.Tests/Grpc.Examples.Tests.csproj
index c8801a9..a114d96 100644
--- a/src/csharp/Grpc.Examples.Tests/Grpc.Examples.Tests.csproj
+++ b/src/csharp/Grpc.Examples.Tests/Grpc.Examples.Tests.csproj
@@ -36,9 +36,6 @@
   </PropertyGroup>
   <ItemGroup>
     <Reference Include="System" />
-    <Reference Include="Google.Protobuf">
-      <HintPath>..\packages\Google.Protobuf.3.0.0-beta3\lib\portable-net45+netcore45+wpa81+wp8\Google.Protobuf.dll</HintPath>
-    </Reference>
     <Reference Include="nunit.framework">
       <HintPath>..\packages\NUnit.3.2.0\lib\net45\nunit.framework.dll</HintPath>
     </Reference>
@@ -48,6 +45,9 @@
     <Reference Include="nunitlite">
       <HintPath>..\packages\NUnitLite.3.2.0\lib\net45\nunitlite.dll</HintPath>
     </Reference>
+    <Reference Include="Google.Protobuf">
+      <HintPath>..\packages\Google.Protobuf.3.0.0\lib\net45\Google.Protobuf.dll</HintPath>
+    </Reference>
   </ItemGroup>
   <ItemGroup>
     <Compile Include="..\Grpc.Core\Version.cs">
diff --git a/src/csharp/Grpc.Examples.Tests/packages.config b/src/csharp/Grpc.Examples.Tests/packages.config
index cc473eb..f14517d 100644
--- a/src/csharp/Grpc.Examples.Tests/packages.config
+++ b/src/csharp/Grpc.Examples.Tests/packages.config
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <packages>
-  <package id="Google.Protobuf" version="3.0.0-beta3" targetFramework="net45" />
-  <package id="System.Interactive.Async" version="3.0.0" targetFramework="net45" />
+  <package id="Google.Protobuf" version="3.0.0" targetFramework="net45" />
   <package id="NUnit" version="3.2.0" targetFramework="net45" />
   <package id="NUnitLite" version="3.2.0" targetFramework="net45" />
+  <package id="System.Interactive.Async" version="3.0.0" targetFramework="net45" />
 </packages>
\ No newline at end of file
diff --git a/src/csharp/Grpc.Examples.Tests/project.json b/src/csharp/Grpc.Examples.Tests/project.json
index 1cd1848..0109617 100644
--- a/src/csharp/Grpc.Examples.Tests/project.json
+++ b/src/csharp/Grpc.Examples.Tests/project.json
@@ -42,11 +42,6 @@
       }
     }
   },
-  "runtimes": {
-    "win7-x64": { },
-    "debian.8-x64": { },
-    "osx.10.11-x64": { }
-  },
 
   "dependencies": {
     "Grpc.Examples": {
@@ -62,8 +57,10 @@
         "portable-net45"
       ],
       "dependencies": {
-        "Microsoft.NETCore.App": "1.0.0",
-        "NETStandard.Library": "1.6.0"
+        "Microsoft.NETCore.App": {
+          "type": "platform",
+          "version": "1.0.0"
+        }
       }
     }
   }
diff --git a/src/csharp/Grpc.Examples/Grpc.Examples.csproj b/src/csharp/Grpc.Examples/Grpc.Examples.csproj
index 4521649..dcbef5fc 100644
--- a/src/csharp/Grpc.Examples/Grpc.Examples.csproj
+++ b/src/csharp/Grpc.Examples/Grpc.Examples.csproj
@@ -37,10 +37,6 @@
     <AssemblyOriginatorKeyFile>..\keys\Grpc.snk</AssemblyOriginatorKeyFile>
   </PropertyGroup>
   <ItemGroup>
-    <Reference Include="Google.Protobuf, Version=3.0.0.0, Culture=neutral, PublicKeyToken=a7d26565bac4d604, processorArchitecture=MSIL">
-      <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\Google.Protobuf.3.0.0-beta3\lib\portable-net45+netcore45+wpa81+wp8\Google.Protobuf.dll</HintPath>
-    </Reference>
     <Reference Include="nunit.framework">
       <HintPath>..\packages\NUnit.3.2.0\lib\net45\nunit.framework.dll</HintPath>
     </Reference>
@@ -50,6 +46,9 @@
       <SpecificVersion>False</SpecificVersion>
       <HintPath>..\packages\System.Interactive.Async.3.0.0\lib\net45\System.Interactive.Async.dll</HintPath>
     </Reference>
+    <Reference Include="Google.Protobuf">
+      <HintPath>..\packages\Google.Protobuf.3.0.0\lib\net45\Google.Protobuf.dll</HintPath>
+    </Reference>
   </ItemGroup>
   <ItemGroup>
     <Compile Include="..\Grpc.Core\Version.cs">
diff --git a/src/csharp/Grpc.Examples/packages.config b/src/csharp/Grpc.Examples/packages.config
index 8985ae4..d17347f 100644
--- a/src/csharp/Grpc.Examples/packages.config
+++ b/src/csharp/Grpc.Examples/packages.config
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <packages>
-  <package id="Google.Protobuf" version="3.0.0-beta3" targetFramework="net45" />
-  <package id="System.Interactive.Async" version="3.0.0" targetFramework="net45" />
+  <package id="Google.Protobuf" version="3.0.0" targetFramework="net45" />
   <package id="NUnit" version="3.2.0" targetFramework="net45" />
+  <package id="System.Interactive.Async" version="3.0.0" targetFramework="net45" />
 </packages>
\ No newline at end of file
diff --git a/src/csharp/Grpc.Examples/project.json b/src/csharp/Grpc.Examples/project.json
index 98bd5d8..21a730c 100644
--- a/src/csharp/Grpc.Examples/project.json
+++ b/src/csharp/Grpc.Examples/project.json
@@ -1,17 +1,12 @@
 {
   "buildOptions": {
   },
-  "runtimes": {
-    "win7-x64": { },
-    "debian.8-x64": { },
-    "osx.10.11-x64": { }
-  },
 
   "dependencies": {
     "Grpc.Core": {
       "target": "project"
     },
-    "Google.Protobuf": "3.0.0-beta3"
+    "Google.Protobuf": "3.0.0"
   },
   "frameworks": {
     "net45": {
@@ -21,12 +16,11 @@
       }
     },
     "netcoreapp1.0": {
-      "imports": [
-        "portable-net45"
-      ],
       "dependencies": {
-        "Microsoft.NETCore.App": "1.0.0",
-        "NETStandard.Library": "1.6.0"
+        "Microsoft.NETCore.App": {
+          "type": "platform",
+          "version": "1.0.0"
+        }
       }
     }
   }
diff --git a/src/csharp/Grpc.HealthCheck.Tests/Grpc.HealthCheck.Tests.csproj b/src/csharp/Grpc.HealthCheck.Tests/Grpc.HealthCheck.Tests.csproj
index aefacfb..93c3b3a 100644
--- a/src/csharp/Grpc.HealthCheck.Tests/Grpc.HealthCheck.Tests.csproj
+++ b/src/csharp/Grpc.HealthCheck.Tests/Grpc.HealthCheck.Tests.csproj
@@ -44,15 +44,15 @@
     <Reference Include="Microsoft.CSharp" />
     <Reference Include="System.Data" />
     <Reference Include="System.Xml" />
-    <Reference Include="Google.Protobuf">
-      <HintPath>..\packages\Google.Protobuf.3.0.0-beta3\lib\portable-net45+netcore45+wpa81+wp8\Google.Protobuf.dll</HintPath>
-    </Reference>
     <Reference Include="nunit.framework">
       <HintPath>..\packages\NUnit.3.2.0\lib\net45\nunit.framework.dll</HintPath>
     </Reference>
     <Reference Include="nunitlite">
       <HintPath>..\packages\NUnitLite.3.2.0\lib\net45\nunitlite.dll</HintPath>
     </Reference>
+    <Reference Include="Google.Protobuf">
+      <HintPath>..\packages\Google.Protobuf.3.0.0\lib\net45\Google.Protobuf.dll</HintPath>
+    </Reference>
   </ItemGroup>
   <ItemGroup>
     <Compile Include="..\Grpc.Core\Version.cs">
diff --git a/src/csharp/Grpc.HealthCheck.Tests/packages.config b/src/csharp/Grpc.HealthCheck.Tests/packages.config
index 2bcfec8..e796d6b 100644
--- a/src/csharp/Grpc.HealthCheck.Tests/packages.config
+++ b/src/csharp/Grpc.HealthCheck.Tests/packages.config
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <packages>
-  <package id="Google.Protobuf" version="3.0.0-beta3" targetFramework="net45" />
+  <package id="Google.Protobuf" version="3.0.0" targetFramework="net45" />
   <package id="NUnit" version="3.2.0" targetFramework="net45" />
   <package id="NUnitLite" version="3.2.0" targetFramework="net45" />
 </packages>
\ No newline at end of file
diff --git a/src/csharp/Grpc.HealthCheck.Tests/project.json b/src/csharp/Grpc.HealthCheck.Tests/project.json
index faa4400..66dcd79 100644
--- a/src/csharp/Grpc.HealthCheck.Tests/project.json
+++ b/src/csharp/Grpc.HealthCheck.Tests/project.json
@@ -42,11 +42,6 @@
       }
     }
   },
-  "runtimes": {
-    "win7-x64": { },
-    "debian.8-x64": { },
-    "osx.10.11-x64": { }
-  },
 
   "dependencies": {
     "Grpc.HealthCheck": {
@@ -62,8 +57,10 @@
         "portable-net45"
       ],
       "dependencies": {
-        "Microsoft.NETCore.App": "1.0.0",
-        "NETStandard.Library": "1.6.0"
+        "Microsoft.NETCore.App": {
+          "type": "platform",
+          "version": "1.0.0"
+        }
       }
     }
   }
diff --git a/src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.csproj b/src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.csproj
index e13416c..54a2984 100644
--- a/src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.csproj
+++ b/src/csharp/Grpc.HealthCheck/Grpc.HealthCheck.csproj
@@ -38,10 +38,6 @@
     <AssemblyOriginatorKeyFile>..\keys\Grpc.snk</AssemblyOriginatorKeyFile>
   </PropertyGroup>
   <ItemGroup>
-    <Reference Include="Google.Protobuf, Version=3.0.0.0, Culture=neutral, PublicKeyToken=a7d26565bac4d604, processorArchitecture=MSIL">
-      <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\Google.Protobuf.3.0.0-beta3\lib\portable-net45+netcore45+wpa81+wp8\Google.Protobuf.dll</HintPath>
-    </Reference>
     <Reference Include="System" />
     <Reference Include="System.Core" />
     <Reference Include="System.Interactive.Async, Version=1.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
@@ -53,6 +49,9 @@
     <Reference Include="Microsoft.CSharp" />
     <Reference Include="System.Data" />
     <Reference Include="System.Xml" />
+    <Reference Include="Google.Protobuf">
+      <HintPath>..\packages\Google.Protobuf.3.0.0\lib\net45\Google.Protobuf.dll</HintPath>
+    </Reference>
   </ItemGroup>
   <ItemGroup>
     <Compile Include="..\Grpc.Core\Version.cs">
diff --git a/src/csharp/Grpc.HealthCheck/packages.config b/src/csharp/Grpc.HealthCheck/packages.config
index 063094f..f8e353b 100644
--- a/src/csharp/Grpc.HealthCheck/packages.config
+++ b/src/csharp/Grpc.HealthCheck/packages.config
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
 <packages>
-  <package id="Google.Protobuf" version="3.0.0-beta3" targetFramework="net45" />
+  <package id="Google.Protobuf" version="3.0.0" targetFramework="net45" />
   <package id="System.Interactive.Async" version="3.0.0" targetFramework="net45" />
 </packages>
\ No newline at end of file
diff --git a/src/csharp/Grpc.HealthCheck/project.json b/src/csharp/Grpc.HealthCheck/project.json
index 7c062a7..9d63122 100644
--- a/src/csharp/Grpc.HealthCheck/project.json
+++ b/src/csharp/Grpc.HealthCheck/project.json
@@ -23,7 +23,7 @@
   },
   "dependencies": {
     "Grpc.Core": "1.1.0-dev",
-    "Google.Protobuf": "3.0.0-beta3"
+    "Google.Protobuf": "3.0.0"
   },
   "frameworks": {
     "net45": {
@@ -33,9 +33,6 @@
       }
     },
     "netstandard1.5": {
-      "imports": [
-        "portable-net45"
-      ],
       "dependencies": {
         "NETStandard.Library": "1.6.0"
       }
diff --git a/src/csharp/Grpc.IntegrationTesting.Client/Grpc.IntegrationTesting.Client.csproj b/src/csharp/Grpc.IntegrationTesting.Client/Grpc.IntegrationTesting.Client.csproj
index 6816b5c..ae58073 100644
--- a/src/csharp/Grpc.IntegrationTesting.Client/Grpc.IntegrationTesting.Client.csproj
+++ b/src/csharp/Grpc.IntegrationTesting.Client/Grpc.IntegrationTesting.Client.csproj
@@ -49,14 +49,26 @@
     <Reference Include="Newtonsoft.Json">
       <HintPath>..\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
     </Reference>
+    <Reference Include="log4net">
+      <HintPath>..\packages\log4net.2.0.3\lib\net40-full\log4net.dll</HintPath>
+    </Reference>
     <Reference Include="Google.Apis.Core">
-      <HintPath>..\packages\Google.Apis.Core.1.15.0\lib\net45\Google.Apis.Core.dll</HintPath>
+      <HintPath>..\packages\Google.Apis.Core.1.16.0\lib\net45\Google.Apis.Core.dll</HintPath>
+    </Reference>
+    <Reference Include="Zlib.Portable">
+      <HintPath>..\packages\Zlib.Portable.Signed.1.11.0\lib\portable-net4+sl5+wp8+win8+wpa81+MonoTouch+MonoAndroid\Zlib.Portable.dll</HintPath>
+    </Reference>
+    <Reference Include="Google.Apis">
+      <HintPath>..\packages\Google.Apis.1.16.0\lib\net45\Google.Apis.dll</HintPath>
+    </Reference>
+    <Reference Include="Google.Apis.PlatformServices">
+      <HintPath>..\packages\Google.Apis.1.16.0\lib\net45\Google.Apis.PlatformServices.dll</HintPath>
     </Reference>
     <Reference Include="Google.Apis.Auth">
-      <HintPath>..\packages\Google.Apis.Auth.1.15.0\lib\net45\Google.Apis.Auth.dll</HintPath>
+      <HintPath>..\packages\Google.Apis.Auth.1.16.0\lib\net45\Google.Apis.Auth.dll</HintPath>
     </Reference>
     <Reference Include="Google.Apis.Auth.PlatformServices">
-      <HintPath>..\packages\Google.Apis.Auth.1.15.0\lib\net45\Google.Apis.Auth.PlatformServices.dll</HintPath>
+      <HintPath>..\packages\Google.Apis.Auth.1.16.0\lib\net45\Google.Apis.Auth.PlatformServices.dll</HintPath>
     </Reference>
   </ItemGroup>
   <ItemGroup>
diff --git a/src/csharp/Grpc.IntegrationTesting.Client/packages.config b/src/csharp/Grpc.IntegrationTesting.Client/packages.config
index 738d3e6..11c6375 100644
--- a/src/csharp/Grpc.IntegrationTesting.Client/packages.config
+++ b/src/csharp/Grpc.IntegrationTesting.Client/packages.config
@@ -1,7 +1,10 @@
 <?xml version="1.0" encoding="utf-8"?>
 <packages>
   <package id="BouncyCastle" version="1.7.0" targetFramework="net45" />
-  <package id="Google.Apis.Auth" version="1.15.0" targetFramework="net45" />
-  <package id="Google.Apis.Core" version="1.15.0" targetFramework="net45" />
+  <package id="Google.Apis" version="1.16.0" targetFramework="net45" />
+  <package id="Google.Apis.Auth" version="1.16.0" targetFramework="net45" />
+  <package id="Google.Apis.Core" version="1.16.0" targetFramework="net45" />
+  <package id="log4net" version="2.0.3" targetFramework="net45" />
   <package id="Newtonsoft.Json" version="7.0.1" targetFramework="net45" />
+  <package id="Zlib.Portable.Signed" version="1.11.0" targetFramework="net45" />
 </packages>
\ No newline at end of file
diff --git a/src/csharp/Grpc.IntegrationTesting.Client/project.json b/src/csharp/Grpc.IntegrationTesting.Client/project.json
index 2879507..1b900c8 100644
--- a/src/csharp/Grpc.IntegrationTesting.Client/project.json
+++ b/src/csharp/Grpc.IntegrationTesting.Client/project.json
@@ -13,8 +13,10 @@
           "includeFiles": [ "../Grpc.Core/Version.cs" ]
         },
         "copyToOutput": {
-          "include": "data/*",
           "mappings": {
+            "data/ca.pem": "../Grpc.IntegrationTesting/data/ca.pem",
+            "data/server1.key": "../Grpc.IntegrationTesting/data/server1.key",
+            "data/server1.pem": "../Grpc.IntegrationTesting/data/server1.pem",
             "grpc_csharp_ext.x64.dll": "../../../vsprojects/x64/Debug/grpc_csharp_ext.dll",
             "grpc_csharp_ext.x86.dll": "../../../vsprojects/Debug/grpc_csharp_ext.dll",
             "libgrpc_csharp_ext.x64.so": "../../../libs/dbg/libgrpc_csharp_ext.so",
@@ -33,8 +35,10 @@
           "includeFiles": [ "../Grpc.Core/Version.cs" ]
         },
         "copyToOutput": {
-          "include": "data/*",
           "mappings": {
+            "data/ca.pem": "../Grpc.IntegrationTesting/data/ca.pem",
+            "data/server1.key": "../Grpc.IntegrationTesting/data/server1.key",
+            "data/server1.pem": "../Grpc.IntegrationTesting/data/server1.pem",
             "grpc_csharp_ext.x64.dll": "../../../vsprojects/x64/Release/grpc_csharp_ext.dll",
             "grpc_csharp_ext.x86.dll": "../../../vsprojects/Release/grpc_csharp_ext.dll",
             "libgrpc_csharp_ext.x64.so": "../../../libs/opt/libgrpc_csharp_ext.so",
@@ -44,11 +48,6 @@
       }
     }
   },
-  "runtimes": {
-    "win7-x64": { },
-    "debian.8-x64": { },
-    "osx.10.11-x64": { }
-  },
 
   "dependencies": {
     "Grpc.IntegrationTesting": {
@@ -59,12 +58,13 @@
     "net45": { },
     "netcoreapp1.0": {
       "imports": [
-        "portable-net45",
-        "net45"
+        "portable-net45"
       ],
       "dependencies": {
-        "Microsoft.NETCore.App": "1.0.0",
-        "NETStandard.Library": "1.6.0"
+        "Microsoft.NETCore.App": {
+          "type": "platform",
+          "version": "1.0.0"
+        }
       }
     }
   }
diff --git a/src/csharp/Grpc.IntegrationTesting.QpsWorker/project.json b/src/csharp/Grpc.IntegrationTesting.QpsWorker/project.json
index 2879507..1b900c8 100644
--- a/src/csharp/Grpc.IntegrationTesting.QpsWorker/project.json
+++ b/src/csharp/Grpc.IntegrationTesting.QpsWorker/project.json
@@ -13,8 +13,10 @@
           "includeFiles": [ "../Grpc.Core/Version.cs" ]
         },
         "copyToOutput": {
-          "include": "data/*",
           "mappings": {
+            "data/ca.pem": "../Grpc.IntegrationTesting/data/ca.pem",
+            "data/server1.key": "../Grpc.IntegrationTesting/data/server1.key",
+            "data/server1.pem": "../Grpc.IntegrationTesting/data/server1.pem",
             "grpc_csharp_ext.x64.dll": "../../../vsprojects/x64/Debug/grpc_csharp_ext.dll",
             "grpc_csharp_ext.x86.dll": "../../../vsprojects/Debug/grpc_csharp_ext.dll",
             "libgrpc_csharp_ext.x64.so": "../../../libs/dbg/libgrpc_csharp_ext.so",
@@ -33,8 +35,10 @@
           "includeFiles": [ "../Grpc.Core/Version.cs" ]
         },
         "copyToOutput": {
-          "include": "data/*",
           "mappings": {
+            "data/ca.pem": "../Grpc.IntegrationTesting/data/ca.pem",
+            "data/server1.key": "../Grpc.IntegrationTesting/data/server1.key",
+            "data/server1.pem": "../Grpc.IntegrationTesting/data/server1.pem",
             "grpc_csharp_ext.x64.dll": "../../../vsprojects/x64/Release/grpc_csharp_ext.dll",
             "grpc_csharp_ext.x86.dll": "../../../vsprojects/Release/grpc_csharp_ext.dll",
             "libgrpc_csharp_ext.x64.so": "../../../libs/opt/libgrpc_csharp_ext.so",
@@ -44,11 +48,6 @@
       }
     }
   },
-  "runtimes": {
-    "win7-x64": { },
-    "debian.8-x64": { },
-    "osx.10.11-x64": { }
-  },
 
   "dependencies": {
     "Grpc.IntegrationTesting": {
@@ -59,12 +58,13 @@
     "net45": { },
     "netcoreapp1.0": {
       "imports": [
-        "portable-net45",
-        "net45"
+        "portable-net45"
       ],
       "dependencies": {
-        "Microsoft.NETCore.App": "1.0.0",
-        "NETStandard.Library": "1.6.0"
+        "Microsoft.NETCore.App": {
+          "type": "platform",
+          "version": "1.0.0"
+        }
       }
     }
   }
diff --git a/src/csharp/Grpc.IntegrationTesting.Server/Grpc.IntegrationTesting.Server.csproj b/src/csharp/Grpc.IntegrationTesting.Server/Grpc.IntegrationTesting.Server.csproj
index 987387c..d5c40ba 100644
--- a/src/csharp/Grpc.IntegrationTesting.Server/Grpc.IntegrationTesting.Server.csproj
+++ b/src/csharp/Grpc.IntegrationTesting.Server/Grpc.IntegrationTesting.Server.csproj
@@ -49,14 +49,26 @@
     <Reference Include="Newtonsoft.Json">
       <HintPath>..\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
     </Reference>
+    <Reference Include="log4net">
+      <HintPath>..\packages\log4net.2.0.3\lib\net40-full\log4net.dll</HintPath>
+    </Reference>
     <Reference Include="Google.Apis.Core">
-      <HintPath>..\packages\Google.Apis.Core.1.15.0\lib\net45\Google.Apis.Core.dll</HintPath>
+      <HintPath>..\packages\Google.Apis.Core.1.16.0\lib\net45\Google.Apis.Core.dll</HintPath>
+    </Reference>
+    <Reference Include="Zlib.Portable">
+      <HintPath>..\packages\Zlib.Portable.Signed.1.11.0\lib\portable-net4+sl5+wp8+win8+wpa81+MonoTouch+MonoAndroid\Zlib.Portable.dll</HintPath>
+    </Reference>
+    <Reference Include="Google.Apis">
+      <HintPath>..\packages\Google.Apis.1.16.0\lib\net45\Google.Apis.dll</HintPath>
+    </Reference>
+    <Reference Include="Google.Apis.PlatformServices">
+      <HintPath>..\packages\Google.Apis.1.16.0\lib\net45\Google.Apis.PlatformServices.dll</HintPath>
     </Reference>
     <Reference Include="Google.Apis.Auth">
-      <HintPath>..\packages\Google.Apis.Auth.1.15.0\lib\net45\Google.Apis.Auth.dll</HintPath>
+      <HintPath>..\packages\Google.Apis.Auth.1.16.0\lib\net45\Google.Apis.Auth.dll</HintPath>
     </Reference>
     <Reference Include="Google.Apis.Auth.PlatformServices">
-      <HintPath>..\packages\Google.Apis.Auth.1.15.0\lib\net45\Google.Apis.Auth.PlatformServices.dll</HintPath>
+      <HintPath>..\packages\Google.Apis.Auth.1.16.0\lib\net45\Google.Apis.Auth.PlatformServices.dll</HintPath>
     </Reference>
   </ItemGroup>
   <ItemGroup>
diff --git a/src/csharp/Grpc.IntegrationTesting.Server/packages.config b/src/csharp/Grpc.IntegrationTesting.Server/packages.config
index 738d3e6..11c6375 100644
--- a/src/csharp/Grpc.IntegrationTesting.Server/packages.config
+++ b/src/csharp/Grpc.IntegrationTesting.Server/packages.config
@@ -1,7 +1,10 @@
 <?xml version="1.0" encoding="utf-8"?>
 <packages>
   <package id="BouncyCastle" version="1.7.0" targetFramework="net45" />
-  <package id="Google.Apis.Auth" version="1.15.0" targetFramework="net45" />
-  <package id="Google.Apis.Core" version="1.15.0" targetFramework="net45" />
+  <package id="Google.Apis" version="1.16.0" targetFramework="net45" />
+  <package id="Google.Apis.Auth" version="1.16.0" targetFramework="net45" />
+  <package id="Google.Apis.Core" version="1.16.0" targetFramework="net45" />
+  <package id="log4net" version="2.0.3" targetFramework="net45" />
   <package id="Newtonsoft.Json" version="7.0.1" targetFramework="net45" />
+  <package id="Zlib.Portable.Signed" version="1.11.0" targetFramework="net45" />
 </packages>
\ No newline at end of file
diff --git a/src/csharp/Grpc.IntegrationTesting.Server/project.json b/src/csharp/Grpc.IntegrationTesting.Server/project.json
index 2879507..1b900c8 100644
--- a/src/csharp/Grpc.IntegrationTesting.Server/project.json
+++ b/src/csharp/Grpc.IntegrationTesting.Server/project.json
@@ -13,8 +13,10 @@
           "includeFiles": [ "../Grpc.Core/Version.cs" ]
         },
         "copyToOutput": {
-          "include": "data/*",
           "mappings": {
+            "data/ca.pem": "../Grpc.IntegrationTesting/data/ca.pem",
+            "data/server1.key": "../Grpc.IntegrationTesting/data/server1.key",
+            "data/server1.pem": "../Grpc.IntegrationTesting/data/server1.pem",
             "grpc_csharp_ext.x64.dll": "../../../vsprojects/x64/Debug/grpc_csharp_ext.dll",
             "grpc_csharp_ext.x86.dll": "../../../vsprojects/Debug/grpc_csharp_ext.dll",
             "libgrpc_csharp_ext.x64.so": "../../../libs/dbg/libgrpc_csharp_ext.so",
@@ -33,8 +35,10 @@
           "includeFiles": [ "../Grpc.Core/Version.cs" ]
         },
         "copyToOutput": {
-          "include": "data/*",
           "mappings": {
+            "data/ca.pem": "../Grpc.IntegrationTesting/data/ca.pem",
+            "data/server1.key": "../Grpc.IntegrationTesting/data/server1.key",
+            "data/server1.pem": "../Grpc.IntegrationTesting/data/server1.pem",
             "grpc_csharp_ext.x64.dll": "../../../vsprojects/x64/Release/grpc_csharp_ext.dll",
             "grpc_csharp_ext.x86.dll": "../../../vsprojects/Release/grpc_csharp_ext.dll",
             "libgrpc_csharp_ext.x64.so": "../../../libs/opt/libgrpc_csharp_ext.so",
@@ -44,11 +48,6 @@
       }
     }
   },
-  "runtimes": {
-    "win7-x64": { },
-    "debian.8-x64": { },
-    "osx.10.11-x64": { }
-  },
 
   "dependencies": {
     "Grpc.IntegrationTesting": {
@@ -59,12 +58,13 @@
     "net45": { },
     "netcoreapp1.0": {
       "imports": [
-        "portable-net45",
-        "net45"
+        "portable-net45"
       ],
       "dependencies": {
-        "Microsoft.NETCore.App": "1.0.0",
-        "NETStandard.Library": "1.6.0"
+        "Microsoft.NETCore.App": {
+          "type": "platform",
+          "version": "1.0.0"
+        }
       }
     }
   }
diff --git a/src/csharp/Grpc.IntegrationTesting.StressClient/project.json b/src/csharp/Grpc.IntegrationTesting.StressClient/project.json
index 2879507..1b900c8 100644
--- a/src/csharp/Grpc.IntegrationTesting.StressClient/project.json
+++ b/src/csharp/Grpc.IntegrationTesting.StressClient/project.json
@@ -13,8 +13,10 @@
           "includeFiles": [ "../Grpc.Core/Version.cs" ]
         },
         "copyToOutput": {
-          "include": "data/*",
           "mappings": {
+            "data/ca.pem": "../Grpc.IntegrationTesting/data/ca.pem",
+            "data/server1.key": "../Grpc.IntegrationTesting/data/server1.key",
+            "data/server1.pem": "../Grpc.IntegrationTesting/data/server1.pem",
             "grpc_csharp_ext.x64.dll": "../../../vsprojects/x64/Debug/grpc_csharp_ext.dll",
             "grpc_csharp_ext.x86.dll": "../../../vsprojects/Debug/grpc_csharp_ext.dll",
             "libgrpc_csharp_ext.x64.so": "../../../libs/dbg/libgrpc_csharp_ext.so",
@@ -33,8 +35,10 @@
           "includeFiles": [ "../Grpc.Core/Version.cs" ]
         },
         "copyToOutput": {
-          "include": "data/*",
           "mappings": {
+            "data/ca.pem": "../Grpc.IntegrationTesting/data/ca.pem",
+            "data/server1.key": "../Grpc.IntegrationTesting/data/server1.key",
+            "data/server1.pem": "../Grpc.IntegrationTesting/data/server1.pem",
             "grpc_csharp_ext.x64.dll": "../../../vsprojects/x64/Release/grpc_csharp_ext.dll",
             "grpc_csharp_ext.x86.dll": "../../../vsprojects/Release/grpc_csharp_ext.dll",
             "libgrpc_csharp_ext.x64.so": "../../../libs/opt/libgrpc_csharp_ext.so",
@@ -44,11 +48,6 @@
       }
     }
   },
-  "runtimes": {
-    "win7-x64": { },
-    "debian.8-x64": { },
-    "osx.10.11-x64": { }
-  },
 
   "dependencies": {
     "Grpc.IntegrationTesting": {
@@ -59,12 +58,13 @@
     "net45": { },
     "netcoreapp1.0": {
       "imports": [
-        "portable-net45",
-        "net45"
+        "portable-net45"
       ],
       "dependencies": {
-        "Microsoft.NETCore.App": "1.0.0",
-        "NETStandard.Library": "1.6.0"
+        "Microsoft.NETCore.App": {
+          "type": "platform",
+          "version": "1.0.0"
+        }
       }
     }
   }
diff --git a/src/csharp/Grpc.IntegrationTesting/GeneratedClientTest.cs b/src/csharp/Grpc.IntegrationTesting/GeneratedClientTest.cs
index c17ede7..ac6c8d0 100644
--- a/src/csharp/Grpc.IntegrationTesting/GeneratedClientTest.cs
+++ b/src/csharp/Grpc.IntegrationTesting/GeneratedClientTest.cs
@@ -48,8 +48,6 @@
     {
         TestService.TestServiceClient unimplementedClient = new UnimplementedTestServiceClient();
 
-        // TODO: replace Moq by some mocking library with CoreCLR support.
-#if !NETCOREAPP1_0
         [Test]
         public void ExpandedParamOverloadCanBeMocked()
         {
@@ -72,7 +70,6 @@
 
             Assert.AreSame(expected, mockClient.Object.UnaryCall(new SimpleRequest(), new CallOptions()));
         }
-#endif
 
         [Test]
         public void DefaultMethodStubThrows_UnaryCall()
diff --git a/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj b/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj
index e030b21..afd85fb 100644
--- a/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj
+++ b/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj
@@ -38,9 +38,6 @@
     <AssemblyOriginatorKeyFile>..\keys\Grpc.snk</AssemblyOriginatorKeyFile>
   </PropertyGroup>
   <ItemGroup>
-    <Reference Include="Moq">
-      <HintPath>..\packages\Moq.4.2.1510.2205\lib\net40\Moq.dll</HintPath>
-    </Reference>
     <Reference Include="System" />
     <Reference Include="System.Net" />
     <Reference Include="System.Net.Http" />
@@ -48,9 +45,6 @@
     <Reference Include="BouncyCastle.Crypto">
       <HintPath>..\packages\BouncyCastle.1.7.0\lib\Net40-Client\BouncyCastle.Crypto.dll</HintPath>
     </Reference>
-    <Reference Include="Google.Protobuf">
-      <HintPath>..\packages\Google.Protobuf.3.0.0-beta3\lib\portable-net45+netcore45+wpa81+wp8\Google.Protobuf.dll</HintPath>
-    </Reference>
     <Reference Include="Newtonsoft.Json">
       <HintPath>..\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
     </Reference>
@@ -63,18 +57,39 @@
     <Reference Include="nunitlite">
       <HintPath>..\packages\NUnitLite.3.2.0\lib\net45\nunitlite.dll</HintPath>
     </Reference>
-    <Reference Include="Google.Apis.Core">
-      <HintPath>..\packages\Google.Apis.Core.1.15.0\lib\net45\Google.Apis.Core.dll</HintPath>
-    </Reference>
-    <Reference Include="Google.Apis.Auth">
-      <HintPath>..\packages\Google.Apis.Auth.1.15.0\lib\net45\Google.Apis.Auth.dll</HintPath>
-    </Reference>
-    <Reference Include="Google.Apis.Auth.PlatformServices">
-      <HintPath>..\packages\Google.Apis.Auth.1.15.0\lib\net45\Google.Apis.Auth.PlatformServices.dll</HintPath>
-    </Reference>
     <Reference Include="CommandLineParser.Unofficial">
       <HintPath>..\packages\CommandLineParser.Unofficial.2.0.275\lib\net45\CommandLineParser.Unofficial.dll</HintPath>
     </Reference>
+    <Reference Include="log4net">
+      <HintPath>..\packages\log4net.2.0.3\lib\net40-full\log4net.dll</HintPath>
+    </Reference>
+    <Reference Include="Google.Apis.Core">
+      <HintPath>..\packages\Google.Apis.Core.1.16.0\lib\net45\Google.Apis.Core.dll</HintPath>
+    </Reference>
+    <Reference Include="Zlib.Portable">
+      <HintPath>..\packages\Zlib.Portable.Signed.1.11.0\lib\portable-net4+sl5+wp8+win8+wpa81+MonoTouch+MonoAndroid\Zlib.Portable.dll</HintPath>
+    </Reference>
+    <Reference Include="Google.Apis">
+      <HintPath>..\packages\Google.Apis.1.16.0\lib\net45\Google.Apis.dll</HintPath>
+    </Reference>
+    <Reference Include="Google.Apis.PlatformServices">
+      <HintPath>..\packages\Google.Apis.1.16.0\lib\net45\Google.Apis.PlatformServices.dll</HintPath>
+    </Reference>
+    <Reference Include="Google.Apis.Auth">
+      <HintPath>..\packages\Google.Apis.Auth.1.16.0\lib\net45\Google.Apis.Auth.dll</HintPath>
+    </Reference>
+    <Reference Include="Google.Apis.Auth.PlatformServices">
+      <HintPath>..\packages\Google.Apis.Auth.1.16.0\lib\net45\Google.Apis.Auth.PlatformServices.dll</HintPath>
+    </Reference>
+    <Reference Include="Google.Protobuf">
+      <HintPath>..\packages\Google.Protobuf.3.0.0\lib\net45\Google.Protobuf.dll</HintPath>
+    </Reference>
+    <Reference Include="Castle.Core">
+      <HintPath>..\packages\Castle.Core.3.3.3\lib\net45\Castle.Core.dll</HintPath>
+    </Reference>
+    <Reference Include="Moq">
+      <HintPath>..\packages\Moq.4.6.38-alpha\lib\net45\Moq.dll</HintPath>
+    </Reference>
   </ItemGroup>
   <ItemGroup>
     <Compile Include="..\Grpc.Core\Version.cs">
diff --git a/src/csharp/Grpc.IntegrationTesting/packages.config b/src/csharp/Grpc.IntegrationTesting/packages.config
index 8bf9dd4..a39fb3a 100644
--- a/src/csharp/Grpc.IntegrationTesting/packages.config
+++ b/src/csharp/Grpc.IntegrationTesting/packages.config
@@ -1,13 +1,17 @@
 <?xml version="1.0" encoding="utf-8"?>
 <packages>
   <package id="BouncyCastle" version="1.7.0" targetFramework="net45" />
+  <package id="Castle.Core" version="3.3.3" targetFramework="net45" />
   <package id="CommandLineParser.Unofficial" version="2.0.275" targetFramework="net45" />
-  <package id="Google.Apis.Auth" version="1.15.0" targetFramework="net45" />
-  <package id="Google.Apis.Core" version="1.15.0" targetFramework="net45" />
-  <package id="Google.Protobuf" version="3.0.0-beta3" targetFramework="net45" />
-  <package id="System.Interactive.Async" version="3.0.0" targetFramework="net45" />
-  <package id="Moq" version="4.2.1510.2205" targetFramework="net45" />
+  <package id="Google.Apis" version="1.16.0" targetFramework="net45" />
+  <package id="Google.Apis.Auth" version="1.16.0" targetFramework="net45" />
+  <package id="Google.Apis.Core" version="1.16.0" targetFramework="net45" />
+  <package id="Google.Protobuf" version="3.0.0" targetFramework="net45" />
+  <package id="log4net" version="2.0.3" targetFramework="net45" />
+  <package id="Moq" version="4.6.38-alpha" targetFramework="net45" />
   <package id="Newtonsoft.Json" version="7.0.1" targetFramework="net45" />
   <package id="NUnit" version="3.2.0" targetFramework="net45" />
   <package id="NUnitLite" version="3.2.0" targetFramework="net45" />
+  <package id="System.Interactive.Async" version="3.0.0" targetFramework="net45" />
+  <package id="Zlib.Portable.Signed" version="1.11.0" targetFramework="net45" />
 </packages>
\ No newline at end of file
diff --git a/src/csharp/Grpc.IntegrationTesting/project.json b/src/csharp/Grpc.IntegrationTesting/project.json
index 9d70651..0225abb 100644
--- a/src/csharp/Grpc.IntegrationTesting/project.json
+++ b/src/csharp/Grpc.IntegrationTesting/project.json
@@ -13,8 +13,10 @@
           "includeFiles": [ "../Grpc.Core/Version.cs" ]
         },
         "copyToOutput": {
-          "include": "data/*",
           "mappings": {
+            "data/ca.pem": "../Grpc.IntegrationTesting/data/ca.pem",
+            "data/server1.key": "../Grpc.IntegrationTesting/data/server1.key",
+            "data/server1.pem": "../Grpc.IntegrationTesting/data/server1.pem",
             "grpc_csharp_ext.x64.dll": "../../../vsprojects/x64/Debug/grpc_csharp_ext.dll",
             "grpc_csharp_ext.x86.dll": "../../../vsprojects/Debug/grpc_csharp_ext.dll",
             "libgrpc_csharp_ext.x64.so": "../../../libs/dbg/libgrpc_csharp_ext.so",
@@ -33,8 +35,10 @@
           "includeFiles": [ "../Grpc.Core/Version.cs" ]
         },
         "copyToOutput": {
-          "include": "data/*",
           "mappings": {
+            "data/ca.pem": "../Grpc.IntegrationTesting/data/ca.pem",
+            "data/server1.key": "../Grpc.IntegrationTesting/data/server1.key",
+            "data/server1.pem": "../Grpc.IntegrationTesting/data/server1.pem",
             "grpc_csharp_ext.x64.dll": "../../../vsprojects/x64/Release/grpc_csharp_ext.dll",
             "grpc_csharp_ext.x86.dll": "../../../vsprojects/Release/grpc_csharp_ext.dll",
             "libgrpc_csharp_ext.x64.so": "../../../libs/opt/libgrpc_csharp_ext.so",
@@ -44,11 +48,6 @@
       }
     }
   },
-  "runtimes": {
-    "win7-x64": { },
-    "debian.8-x64": { },
-    "osx.10.11-x64": { }
-  },
 
   "dependencies": {
     "Grpc.Auth": {
@@ -57,16 +56,14 @@
     "Grpc.Core": {
       "target": "project"
     },
-    "Google.Protobuf": "3.0.0-beta3",
+    "Google.Protobuf": "3.0.0",
     "CommandLineParser.Unofficial": "2.0.275",
+    "Moq": "4.6.38-alpha",
     "NUnit": "3.2.0",
     "NUnitLite": "3.2.0-*"
   },
   "frameworks": {
     "net45": {
-      "dependencies": {
-        "Moq": "4.2.1510.2205"
-      },
       "frameworkAssemblies": {
         "System.Runtime": "",
         "System.IO": ""
@@ -74,12 +71,13 @@
     },
     "netcoreapp1.0": {
       "imports": [
-        "portable-net45",
-        "net45"
+        "portable-net45"
       ],
       "dependencies": {
-        "Microsoft.NETCore.App": "1.0.0",
-        "NETStandard.Library": "1.6.0",
+        "Microsoft.NETCore.App": {
+          "type": "platform",
+          "version": "1.0.0"
+        },
         "System.Linq.Expressions": "4.1.0"
       }
     }
diff --git a/src/csharp/Grpc.Tools.nuspec b/src/csharp/Grpc.Tools.nuspec
index 31d1bed..0c937ab 100644
--- a/src/csharp/Grpc.Tools.nuspec
+++ b/src/csharp/Grpc.Tools.nuspec
@@ -16,17 +16,18 @@
     <tags>gRPC RPC Protocol HTTP/2</tags>
   </metadata>
   <files>
-    <file src="protoc_plugins\windows_x86\protoc.exe" target="tools\windows_x86\protoc.exe" />
-    <file src="protoc_plugins\windows_x86\grpc_csharp_plugin.exe" target="tools\windows_x86\grpc_csharp_plugin.exe" />
-    <file src="protoc_plugins\windows_x64\protoc.exe" target="tools\windows_x64\protoc.exe" />
-    <file src="protoc_plugins\windows_x64\grpc_csharp_plugin.exe" target="tools\windows_x64\grpc_csharp_plugin.exe" />
-    <file src="protoc_plugins\linux_x86\protoc" target="tools\linux_x86\protoc" />
-    <file src="protoc_plugins\linux_x86\grpc_csharp_plugin" target="tools\linux_x86\grpc_csharp_plugin" />
-    <file src="protoc_plugins\linux_x64\protoc" target="tools\linux_x64\protoc" />
-    <file src="protoc_plugins\linux_x64\grpc_csharp_plugin" target="tools\linux_x64\grpc_csharp_plugin" />
-    <file src="protoc_plugins\macosx_x86\protoc" target="tools\macosx_x86\protoc" />
-    <file src="protoc_plugins\macosx_x86\grpc_csharp_plugin" target="tools\macosx_x86\grpc_csharp_plugin" />
-    <file src="protoc_plugins\macosx_x64\protoc" target="tools\macosx_x64\protoc" />
-    <file src="protoc_plugins\macosx_x64\grpc_csharp_plugin" target="tools\macosx_x64\grpc_csharp_plugin" />
+    <!-- forward slashes in src path enable building on Linux -->
+    <file src="protoc_plugins/windows_x86/protoc.exe" target="tools\windows_x86\protoc.exe" />
+    <file src="protoc_plugins/windows_x86/grpc_csharp_plugin.exe" target="tools\windows_x86\grpc_csharp_plugin.exe" />
+    <file src="protoc_plugins/windows_x64/protoc.exe" target="tools\windows_x64\protoc.exe" />
+    <file src="protoc_plugins/windows_x64/grpc_csharp_plugin.exe" target="tools\windows_x64\grpc_csharp_plugin.exe" />
+    <file src="protoc_plugins/linux_x86/protoc" target="tools\linux_x86\protoc" />
+    <file src="protoc_plugins/linux_x86/grpc_csharp_plugin" target="tools\linux_x86\grpc_csharp_plugin" />
+    <file src="protoc_plugins/linux_x64/protoc" target="tools\linux_x64\protoc" />
+    <file src="protoc_plugins/linux_x64/grpc_csharp_plugin" target="tools\linux_x64\grpc_csharp_plugin" />
+    <file src="protoc_plugins/macosx_x86/protoc" target="tools\macosx_x86\protoc" />
+    <file src="protoc_plugins/macosx_x86/grpc_csharp_plugin" target="tools\macosx_x86\grpc_csharp_plugin" />
+    <file src="protoc_plugins/macosx_x64/protoc" target="tools\macosx_x64\protoc" />
+    <file src="protoc_plugins/macosx_x64/grpc_csharp_plugin" target="tools\macosx_x64\grpc_csharp_plugin" />
   </files>
 </package>
diff --git a/src/csharp/build_packages.bat b/src/csharp/build_packages.bat
index b92189c..c0036df 100644
--- a/src/csharp/build_packages.bat
+++ b/src/csharp/build_packages.bat
@@ -29,6 +29,10 @@
 
 @rem Builds gRPC NuGet packages
 
+@rem This way of building nuget packages is now obsolete. C# nuget packages
+@rem with CoreCLR support are now being built using the dotnet cli
+@rem in build_packages_dotnetcli.sh
+
 @rem Current package versions
 set VERSION=1.1.0-dev
 set PROTOBUF_VERSION=3.0.0
@@ -77,8 +81,8 @@
 xcopy /Y /I *.nupkg ..\..\artifacts\
 
 @rem create a zipfile with the artifacts as well
-powershell -Command "Add-Type -Assembly 'System.IO.Compression.FileSystem'; [System.IO.Compression.ZipFile]::CreateFromDirectory('..\..\artifacts', 'csharp_nugets.zip');"
-xcopy /Y /I csharp_nugets.zip ..\..\artifacts\
+powershell -Command "Add-Type -Assembly 'System.IO.Compression.FileSystem'; [System.IO.Compression.ZipFile]::CreateFromDirectory('..\..\artifacts', 'csharp_nugets_obsolete.zip');"
+xcopy /Y /I csharp_nugets_obsolete.zip ..\..\artifacts\
 
 goto :EOF
 
diff --git a/tools/run_tests/build_package_csharp_coreclr.sh b/src/csharp/build_packages_dotnetcli.sh
similarity index 66%
rename from tools/run_tests/build_package_csharp_coreclr.sh
rename to src/csharp/build_packages_dotnetcli.sh
index e1c363d..3c127f3 100755
--- a/tools/run_tests/build_package_csharp_coreclr.sh
+++ b/src/csharp/build_packages_dotnetcli.sh
@@ -30,19 +30,19 @@
 
 set -ex
 
-cd $(dirname $0)/../..
+cd $(dirname $0)
 
-mkdir -p artifacts/
-
-cd src/csharp
-
-# IMPORTANT: NuGet packages generated by dotnet CLI are considered experimental.
-# The official nugets are generated by src/csharp/build_packages.bat
+mkdir -p ../../artifacts/
 
 mkdir -p nativelibs/windows_x86 nativelibs/windows_x64 \
     nativelibs/linux_x86 nativelibs/linux_x64 \
     nativelibs/macosx_x86 nativelibs/macosx_x64
 
+mkdir -p protoc_plugins/windows_x86 protoc_plugins/windows_x64 \
+    protoc_plugins/linux_x86 protoc_plugins/linux_x64 \
+    protoc_plugins/macosx_x86 protoc_plugins/macosx_x64
+
+# Collect the artifacts built by the previous build step if running on Jenkins
 cp $EXTERNAL_GIT_ROOT/architecture=x86,language=csharp,platform=windows/artifacts/* nativelibs/windows_x86 || true
 cp $EXTERNAL_GIT_ROOT/architecture=x64,language=csharp,platform=windows/artifacts/* nativelibs/windows_x64 || true
 cp $EXTERNAL_GIT_ROOT/architecture=x86,language=csharp,platform=linux/artifacts/* nativelibs/linux_x86 || true
@@ -50,10 +50,21 @@
 cp $EXTERNAL_GIT_ROOT/architecture=x86,language=csharp,platform=macos/artifacts/* nativelibs/macosx_x86 || true
 cp $EXTERNAL_GIT_ROOT/architecture=x64,language=csharp,platform=macos/artifacts/* nativelibs/macosx_x64 || true
 
+# Collect protoc artifacts built by the previous build step
+cp $EXTERNAL_GIT_ROOT/architecture=x86,language=protoc,platform=windows/artifacts/* protoc_plugins/windows_x86 || true
+cp $EXTERNAL_GIT_ROOT/architecture=x64,language=protoc,platform=windows/artifacts/* protoc_plugins/windows_x64 || true
+cp $EXTERNAL_GIT_ROOT/architecture=x86,language=protoc,platform=linux/artifacts/* protoc_plugins/linux_x86 || true
+cp $EXTERNAL_GIT_ROOT/architecture=x64,language=protoc,platform=linux/artifacts/* protoc_plugins/linux_x64 || true
+cp $EXTERNAL_GIT_ROOT/architecture=x86,language=protoc,platform=macos/artifacts/* protoc_plugins/macosx_x86 || true
+cp $EXTERNAL_GIT_ROOT/architecture=x64,language=protoc,platform=macos/artifacts/* protoc_plugins/macosx_x64 || true
+
 dotnet restore .
 
 dotnet pack --configuration Release Grpc.Core/project.json --output ../../artifacts
 dotnet pack --configuration Release Grpc.Auth/project.json --output ../../artifacts
 dotnet pack --configuration Release Grpc.HealthCheck/project.json --output ../../artifacts
 
-tar -czf ../../artifacts/csharp_nugets_experimental.tar.gz ../../artifacts/*.nupkg
+nuget pack Grpc.nuspec -Version "1.1.0-dev" -OutputDirectory ../../artifacts
+nuget pack Grpc.Tools.nuspec -Version "1.1.0-dev" -OutputDirectory ../../artifacts
+
+(cd ../../artifacts && zip csharp_nugets_dotnetcli.zip *.nupkg)
diff --git a/src/csharp/ext/grpc_csharp_ext.c b/src/csharp/ext/grpc_csharp_ext.c
index 3d0947c..068bf70 100644
--- a/src/csharp/ext/grpc_csharp_ext.c
+++ b/src/csharp/ext/grpc_csharp_ext.c
@@ -255,8 +255,10 @@
   }
 
   GPR_ASSERT(grpc_byte_buffer_reader_init(&reader, ctx->recv_message));
+  intptr_t result = (intptr_t)grpc_byte_buffer_length(reader.buffer_out);
+  grpc_byte_buffer_reader_destroy(&reader);
 
-  return (intptr_t)grpc_byte_buffer_length(reader.buffer_out);
+  return result;
 }
 
 /*
@@ -279,6 +281,8 @@
     offset += len;
     gpr_slice_unref(slice);
   }
+
+  grpc_byte_buffer_reader_destroy(&reader);
 }
 
 GPR_EXPORT grpc_status_code GPR_CALLTYPE
diff --git a/src/node/README.md b/src/node/README.md
index 15d4c6d..9eafce9 100644
--- a/src/node/README.md
+++ b/src/node/README.md
@@ -39,7 +39,7 @@
 To run the test suite, simply run `npm test` in the install location.
 
 ## API
-This library internally uses [ProtoBuf.js](https://github.com/dcodeIO/ProtoBuf.js), and some structures it exports match those exported by that library
+This library internally uses [ProtoBuf.js](https://github.com/dcodeIO/ProtoBuf.js), and some structures it exports match those exported by that library.
 
 If you require this module, you will get an object with the following members
 
@@ -63,7 +63,7 @@
 Returns the same structure that `load` returns, but takes a reflection object from `ProtoBuf.js` instead of a file name.
 
 ```javascript
-function Server([serverOpions])
+function Server([serverOptions])
 ```
 
 Constructs a server to which service/implementation pairs can be added.
diff --git a/src/objective-c/GRPCClient/GRPCCall.m b/src/objective-c/GRPCClient/GRPCCall.m
index 05a1d10..eecda4c 100644
--- a/src/objective-c/GRPCClient/GRPCCall.m
+++ b/src/objective-c/GRPCClient/GRPCCall.m
@@ -103,6 +103,11 @@
 
 @synthesize state = _state;
 
+// TODO(jcanizales): If grpc_init is idempotent, this should be changed from load to initialize.
++ (void)load {
+  grpc_init();
+}
+
 - (instancetype)init {
   return [self initWithHost:nil path:nil requestsWriter:nil];
 }
diff --git a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m
index 97f6b89..1339429 100644
--- a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m
+++ b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m
@@ -245,11 +245,6 @@
   }
 
   if (self = [super init]) {
-    static dispatch_once_t initialization;
-    dispatch_once(&initialization, ^{
-      grpc_init();
-    });
-
     // Each completion queue consumes one thread. There's a trade to be made between creating and
     // consuming too many threads and having contention of multiple calls in a single completion
     // queue. Currently we use a singleton queue.
diff --git a/src/php/ext/grpc/call.c b/src/php/ext/grpc/call.c
index 31c59fe..3a49ea8 100644
--- a/src/php/ext/grpc/call.c
+++ b/src/php/ext/grpc/call.c
@@ -69,8 +69,8 @@
   }
 PHP_GRPC_FREE_WRAPPED_FUNC_END()
 
-/* Initializes an instance of wrapped_grpc_call to be associated with an object
- * of a class specified by class_type */
+/* Initializes an instance of wrapped_grpc_call to be associated with an
+ * object of a class specified by class_type */
 php_grpc_zend_object create_wrapped_grpc_call(zend_class_entry *class_type
                                               TSRMLS_DC) {
   PHP_GRPC_ALLOC_CLASS_OBJECT(wrapped_grpc_call);
@@ -195,10 +195,11 @@
 
 /**
  * Constructs a new instance of the Call class.
- * @param Channel $channel The channel to associate the call with. Must not be
- *     closed.
+ * @param Channel $channel_obj The channel to associate the call with.
+ *                             Must not be closed.
  * @param string $method The method to call
- * @param Timeval $absolute_deadline The deadline for completing the call
+ * @param Timeval $deadline_obj The deadline for completing the call
+ * @param string $host_override The host is set by user (optional)
  */
 PHP_METHOD(Call, __construct) {
   zval *channel_obj;
@@ -237,7 +238,7 @@
 
 /**
  * Start a batch of RPC actions.
- * @param array batch Array of actions to take
+ * @param array $array Array of actions to take
  * @return object Object with results of all actions
  */
 PHP_METHOD(Call, startBatch) {
@@ -515,8 +516,9 @@
 }
 
 /**
- * Cancel the call. This will cause the call to end with STATUS_CANCELLED if it
- * has not already ended with another status.
+ * Cancel the call. This will cause the call to end with STATUS_CANCELLED
+ * if it has not already ended with another status.
+ * @return void
  */
 PHP_METHOD(Call, cancel) {
   wrapped_grpc_call *call = Z_WRAPPED_GRPC_CALL_P(getThis());
@@ -525,8 +527,8 @@
 
 /**
  * Set the CallCredentials for this call.
- * @param CallCredentials creds_obj The CallCredentials object
- * @param int The error code
+ * @param CallCredentials $creds_obj The CallCredentials object
+ * @return int The error code
  */
 PHP_METHOD(Call, setCredentials) {
   zval *creds_obj;
diff --git a/src/php/ext/grpc/call_credentials.c b/src/php/ext/grpc/call_credentials.c
index 25c92c9..3aafc3a 100644
--- a/src/php/ext/grpc/call_credentials.c
+++ b/src/php/ext/grpc/call_credentials.c
@@ -87,8 +87,8 @@
 
 /**
  * Create composite credentials from two existing credentials.
- * @param CallCredentials cred1 The first credential
- * @param CallCredentials cred2 The second credential
+ * @param CallCredentials $cred1_obj The first credential
+ * @param CallCredentials $cred2_obj The second credential
  * @return CallCredentials The new composite credentials object
  */
 PHP_METHOD(CallCredentials, createComposite) {
@@ -119,7 +119,7 @@
 
 /**
  * Create a call credentials object from the plugin API
- * @param function callback The callback function
+ * @param function $fci The callback function
  * @return CallCredentials The new call credentials object
  */
 PHP_METHOD(CallCredentials, createFromPlugin) {
diff --git a/src/php/ext/grpc/channel.c b/src/php/ext/grpc/channel.c
index b5a2c9f..4ce4f30 100644
--- a/src/php/ext/grpc/channel.c
+++ b/src/php/ext/grpc/channel.c
@@ -125,7 +125,7 @@
  * "credentials" key mapping to a ChannelCredentials object, a secure channel
  * will be created with those credentials.
  * @param string $target The hostname to associate with this channel
- * @param array $args The arguments to pass to the Channel (optional)
+ * @param array $args_array The arguments to pass to the Channel
  */
 PHP_METHOD(Channel, __construct) {
   wrapped_grpc_channel *channel = Z_WRAPPED_GRPC_CHANNEL_P(getThis());
@@ -182,7 +182,7 @@
 
 /**
  * Get the connectivity state of the channel
- * @param bool (optional) try to connect on the channel
+ * @param bool $try_to_connect Try to connect on the channel (optional)
  * @return long The grpc connectivity state
  */
 PHP_METHOD(Channel, getConnectivityState) {
@@ -202,8 +202,8 @@
 
 /**
  * Watch the connectivity state of the channel until it changed
- * @param long The previous connectivity state of the channel
- * @param Timeval The deadline this function should wait until
+ * @param long $last_state The previous connectivity state of the channel
+ * @param Timeval $deadline_obj The deadline this function should wait until
  * @return bool If the connectivity state changes from last_state
  *              before deadline
  */
@@ -233,6 +233,7 @@
 
 /**
  * Close the channel
+ * @return void
  */
 PHP_METHOD(Channel, close) {
   wrapped_grpc_channel *channel = Z_WRAPPED_GRPC_CHANNEL_P(getThis());
diff --git a/src/php/ext/grpc/channel_credentials.c b/src/php/ext/grpc/channel_credentials.c
index 0b356aa..a32c4a4 100644
--- a/src/php/ext/grpc/channel_credentials.c
+++ b/src/php/ext/grpc/channel_credentials.c
@@ -97,7 +97,7 @@
 
 /**
  * Set default roots pem.
- * @param string pem_roots PEM encoding of the server root certificates
+ * @param string $pem_roots PEM encoding of the server root certificates
  * @return void
  */
 PHP_METHOD(ChannelCredentials, setDefaultRootsPem) {
@@ -129,11 +129,11 @@
 
 /**
  * Create SSL credentials.
- * @param string pem_root_certs PEM encoding of the server root certificates
- * @param string pem_private_key PEM encoding of the client's private key
- *     (optional)
- * @param string pem_cert_chain PEM encoding of the client's certificate chain
- *     (optional)
+ * @param string $pem_root_certs PEM encoding of the server root certificates
+ * @param string $pem_key_cert_pair.private_key PEM encoding of the client's
+ *                                              private key (optional)
+ * @param string $pem_key_cert_pair.cert_chain PEM encoding of the client's
+ *                                             certificate chain (optional)
  * @return ChannelCredentials The new SSL credentials object
  */
 PHP_METHOD(ChannelCredentials, createSsl) {
@@ -168,8 +168,8 @@
 
 /**
  * Create composite credentials from two existing credentials.
- * @param ChannelCredentials cred1 The first credential
- * @param CallCredentials cred2 The second credential
+ * @param ChannelCredentials $cred1_obj The first credential
+ * @param CallCredentials $cred2_obj The second credential
  * @return ChannelCredentials The new composite credentials object
  */
 PHP_METHOD(ChannelCredentials, createComposite) {
diff --git a/src/php/ext/grpc/server.c b/src/php/ext/grpc/server.c
index fc20c42..2217a4f 100644
--- a/src/php/ext/grpc/server.c
+++ b/src/php/ext/grpc/server.c
@@ -72,8 +72,8 @@
   }
 PHP_GRPC_FREE_WRAPPED_FUNC_END()
 
-/* Initializes an instance of wrapped_grpc_call to be associated with an object
- * of a class specified by class_type */
+/* Initializes an instance of wrapped_grpc_call to be associated with an
+ * object of a class specified by class_type */
 php_grpc_zend_object create_wrapped_grpc_server(zend_class_entry *class_type
                                                 TSRMLS_DC) {
   PHP_GRPC_ALLOC_CLASS_OBJECT(wrapped_grpc_server);
@@ -84,7 +84,7 @@
 
 /**
  * Constructs a new instance of the Server class
- * @param array $args The arguments to pass to the server (optional)
+ * @param array $args_array The arguments to pass to the server (optional)
  */
 PHP_METHOD(Server, __construct) {
   wrapped_grpc_server *server = Z_WRAPPED_GRPC_SERVER_P(getThis());
@@ -116,7 +116,7 @@
  * Request a call on a server. Creates a single GRPC_SERVER_RPC_NEW event.
  * @param long $tag_new The tag to associate with the new request
  * @param long $tag_cancel The tag to use if the call is cancelled
- * @return Void
+ * @return void
  */
 PHP_METHOD(Server, requestCall) {
   grpc_call_error error_code;
@@ -180,7 +180,7 @@
 /**
  * Add a http2 over tcp listener.
  * @param string $addr The address to add
- * @return true on success, false on failure
+ * @return bool True on success, false on failure
  */
 PHP_METHOD(Server, addHttp2Port) {
   const char *addr;
@@ -197,6 +197,12 @@
   RETURN_LONG(grpc_server_add_insecure_http2_port(server->wrapped, addr));
 }
 
+/**
+ * Add a secure http2 over tcp listener.
+ * @param string $addr The address to add
+ * @param ServerCredentials The ServerCredentials object
+ * @return bool True on success, false on failure
+ */
 PHP_METHOD(Server, addSecureHttp2Port) {
   const char *addr;
   php_grpc_int addr_len;
@@ -220,7 +226,7 @@
 
 /**
  * Start a server - tells all listeners to start listening
- * @return Void
+ * @return void
  */
 PHP_METHOD(Server, start) {
   wrapped_grpc_server *server = Z_WRAPPED_GRPC_SERVER_P(getThis());
diff --git a/src/php/ext/grpc/server_credentials.c b/src/php/ext/grpc/server_credentials.c
index b05896a..1610c8e 100644
--- a/src/php/ext/grpc/server_credentials.c
+++ b/src/php/ext/grpc/server_credentials.c
@@ -61,8 +61,8 @@
   }
 PHP_GRPC_FREE_WRAPPED_FUNC_END()
 
-/* Initializes an instace of wrapped_grpc_server_credentials to be associated
- * with an object of a class specified by class_type */
+/* Initializes an instace of wrapped_grpc_server_credentials to be
+ * associated with an object of a class specified by class_type */
 php_grpc_zend_object create_wrapped_grpc_server_credentials(
     zend_class_entry *class_type TSRMLS_DC) {
   PHP_GRPC_ALLOC_CLASS_OBJECT(wrapped_grpc_server_credentials);
diff --git a/src/php/ext/grpc/timeval.c b/src/php/ext/grpc/timeval.c
index e145d96..945231b 100644
--- a/src/php/ext/grpc/timeval.c
+++ b/src/php/ext/grpc/timeval.c
@@ -80,7 +80,7 @@
 
 /**
  * Constructs a new instance of the Timeval class
- * @param long $usec The number of microseconds in the interval
+ * @param long $microseconds The number of microseconds in the interval
  */
 PHP_METHOD(Timeval, __construct) {
   wrapped_grpc_timeval *timeval = Z_WRAPPED_GRPC_TIMEVAL_P(getThis());
@@ -100,7 +100,7 @@
 /**
  * Adds another Timeval to this one and returns the sum. Calculations saturate
  * at infinities.
- * @param Timeval $other The other Timeval object to add
+ * @param Timeval $other_obj The other Timeval object to add
  * @return Timeval A new Timeval object containing the sum
  */
 PHP_METHOD(Timeval, add) {
@@ -126,8 +126,8 @@
 /**
  * Subtracts another Timeval from this one and returns the difference.
  * Calculations saturate at infinities.
- * @param Timeval $other The other Timeval object to subtract
- * @param Timeval A new Timeval object containing the sum
+ * @param Timeval $other_obj The other Timeval object to subtract
+ * @return Timeval A new Timeval object containing the diff 
  */
 PHP_METHOD(Timeval, subtract) {
   zval *other_obj;
@@ -150,10 +150,10 @@
 }
 
 /**
- * Return negative, 0, or positive according to whether a < b, a == b, or a > b
- * respectively.
- * @param Timeval $a The first time to compare
- * @param Timeval $b The second time to compare
+ * Return negative, 0, or positive according to whether a < b, a == b,
+ * or a > b respectively.
+ * @param Timeval $a_obj The first time to compare
+ * @param Timeval $b_obj The second time to compare
  * @return long
  */
 PHP_METHOD(Timeval, compare) {
@@ -176,9 +176,9 @@
 
 /**
  * Checks whether the two times are within $threshold of each other
- * @param Timeval $a The first time to compare
- * @param Timeval $b The second time to compare
- * @param Timeval $threshold The threshold to check against
+ * @param Timeval $a_obj The first time to compare
+ * @param Timeval $b_obj The second time to compare
+ * @param Timeval $thresh_obj The threshold to check against
  * @return bool True if $a and $b are within $threshold, False otherwise
  */
 PHP_METHOD(Timeval, similar) {
diff --git a/src/php/lib/Grpc/BaseStub.php b/src/php/lib/Grpc/BaseStub.php
index 2fec1bd..d850eeb 100644
--- a/src/php/lib/Grpc/BaseStub.php
+++ b/src/php/lib/Grpc/BaseStub.php
@@ -41,6 +41,7 @@
 class BaseStub
 {
     private $hostname;
+    private $hostname_override;
     private $channel;
 
     // a callback function
@@ -75,6 +76,9 @@
         } else {
             $opts['grpc.primary_user_agent'] = '';
         }
+        if (!empty($opts['grpc.ssl_target_name_override'])) {
+            $this->hostname_override = $opts['grpc.ssl_target_name_override'];
+        }
         $opts['grpc.primary_user_agent'] .=
             'grpc-php/'.$package_config['version'];
         if (!array_key_exists('credentials', $opts)) {
@@ -173,7 +177,12 @@
         }
         $service_name = substr($method, 0, $last_slash_idx);
 
-        return 'https://'.$this->hostname.$service_name;
+        if ($this->hostname_override) {
+            $hostname = $this->hostname_override;
+        } else {
+            $hostname = $this->hostname;
+        }
+        return 'https://'.$hostname.$service_name;
     }
 
     /**
diff --git a/src/php/tests/interop/interop_client.php b/src/php/tests/interop/interop_client.php
index c94ba61..94ceeda 100755
--- a/src/php/tests/interop/interop_client.php
+++ b/src/php/tests/interop/interop_client.php
@@ -108,7 +108,7 @@
     $request->setFillUsername($fillUsername);
     $request->setFillOauthScope($fillOauthScope);
 
-    $options = false;
+    $options = [];
     if ($callback) {
         $options['call_credentials_callback'] = $callback;
     }
diff --git a/src/proto/grpc/lb/v1/load_balancer.options b/src/proto/grpc/lb/v1/load_balancer.options
index d903669..a9398d5 100644
--- a/src/proto/grpc/lb/v1/load_balancer.options
+++ b/src/proto/grpc/lb/v1/load_balancer.options
@@ -1,6 +1,6 @@
 grpc.lb.v1.InitialLoadBalanceRequest.name max_size:128
 grpc.lb.v1.InitialLoadBalanceResponse.client_config max_size:64
 grpc.lb.v1.InitialLoadBalanceResponse.load_balancer_delegate max_size:64
-grpc.lb.v1.Server.ip_address max_size:46
-grpc.lb.v1.Server.load_balance_token max_size:64
+grpc.lb.v1.Server.ip_address max_size:16
+grpc.lb.v1.Server.load_balance_token max_size:65
 load_balancer.proto no_unions:true
diff --git a/src/proto/grpc/lb/v1/load_balancer.proto b/src/proto/grpc/lb/v1/load_balancer.proto
index 1bcad0b..b4a33f3 100644
--- a/src/proto/grpc/lb/v1/load_balancer.proto
+++ b/src/proto/grpc/lb/v1/load_balancer.proto
@@ -32,7 +32,6 @@
 package grpc.lb.v1;
 
 message Duration {
-
   // Signed seconds of the span of time. Must be from -315,576,000,000
   // to +315,576,000,000 inclusive.
   int64 seconds = 1;
@@ -93,16 +92,11 @@
 }
 
 message InitialLoadBalanceResponse {
-  oneof initial_response_type {
-    // TODO(zhangkun83): ClientConfig not yet defined
-    //ClientConfig client_config = 1;
-
-    // This is an application layer redirect that indicates the client should
-    // use the specified server for load balancing. When this field is set in
-    // the response, the client should open a separate connection to the
-    // load_balancer_delegate and call the BalanceLoad method.
-    string load_balancer_delegate = 2;
-  }
+  // This is an application layer redirect that indicates the client should use
+  // the specified server for load balancing. When this field is non-empty in
+  // the response, the client should open a separate connection to the
+  // load_balancer_delegate and call the BalanceLoad method.
+  string load_balancer_delegate = 1;
 
   // This interval defines how often the client should send the client stats
   // to the load balancer. Stats should only be reported when the duration is
@@ -125,14 +119,17 @@
 }
 
 message Server {
-  // A resolved address and port for the server. The IP address string may
+  // A resolved address for the server, serialized in network-byte-order. It may
   // either be an IPv4 or IPv6 address.
-  string ip_address = 1;
+  bytes ip_address = 1;
+
+  // A resolved port number for the server.
   int32 port = 2;
 
-  // An opaque token that is passed from the client to the server in metadata.
-  // The server may expect this token to indicate that the request from the
-  // client was load balanced.
+  // An opaque but printable token given to the frontend for each pick. All
+  // frontend requests for that pick must include the token in its initial
+  // metadata. The token is used by the backend to verify the request and to
+  // allow the backend to report load to the gRPC LB system.
   string load_balance_token = 3;
 
   // Indicates whether this particular request should be dropped by the client
diff --git a/src/proto/grpc/testing/echo.proto b/src/proto/grpc/testing/echo.proto
index c596aab..ca60a41 100644
--- a/src/proto/grpc/testing/echo.proto
+++ b/src/proto/grpc/testing/echo.proto
@@ -42,7 +42,7 @@
   rpc Unimplemented(EchoRequest) returns (EchoResponse);
 }
 
-service UnimplementedService {
+service UnimplementedEchoService {
   rpc Unimplemented(EchoRequest) returns (EchoResponse);
 }
 
diff --git a/src/python/grpcio/commands.py b/src/python/grpcio/commands.py
index d36ac23..ea3b6f3 100644
--- a/src/python/grpcio/commands.py
+++ b/src/python/grpcio/commands.py
@@ -53,6 +53,7 @@
 GRPC_STEM = os.path.abspath(PYTHON_STEM + '../../../../')
 PROTO_STEM = os.path.join(GRPC_STEM, 'src', 'proto')
 PROTO_GEN_STEM = os.path.join(GRPC_STEM, 'src', 'python', 'gens')
+CYTHON_STEM = os.path.join(PYTHON_STEM, 'grpc', '_cython')
 
 CONF_PY_ADDENDUM = """
 extensions.append('sphinx.ext.napoleon')
@@ -244,7 +245,7 @@
     extensions,
     include_path=[
       include_dir for extension in extensions for include_dir in extension.include_dirs
-    ],
+    ] + [CYTHON_STEM],
     compiler_directives=cython_compiler_directives
   )
 
diff --git a/src/python/grpcio/grpc/__init__.py b/src/python/grpcio/grpc/__init__.py
index 513839d..faf3ab5 100644
--- a/src/python/grpcio/grpc/__init__.py
+++ b/src/python/grpcio/grpc/__init__.py
@@ -1078,7 +1078,7 @@
 
   Args:
     access_token: A string to place directly in the http request
-      authorization header, ie "Authorization: Bearer <access_token>".
+      authorization header, ie "authorization: Bearer <access_token>".
 
   Returns:
     A CallCredentials.
@@ -1193,7 +1193,7 @@
 
 
 def secure_channel(target, credentials, options=None):
-  """Creates an insecure Channel to a server.
+  """Creates a secure Channel to a server.
 
   Args:
     target: The target to which to connect.
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/security.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/security.pyx.pxi
index 23cee7b..20fc1c5 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/security.pyx.pxi
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/security.pyx.pxi
@@ -35,7 +35,7 @@
 cdef grpc_ssl_roots_override_result ssl_roots_override_callback(
     char **pem_root_certs) with gil:
   temporary_pem_root_certs = pkg_resources.resource_string(
-      'grpc._cython', '_credentials/roots.pem')
+      __name__.rstrip('.cygrpc'), '_credentials/roots.pem')
   pem_root_certs[0] = <char *>gpr_malloc(len(temporary_pem_root_certs) + 1)
   memcpy(
       pem_root_certs[0], <char *>temporary_pem_root_certs,
diff --git a/src/python/grpcio/grpc/_cython/cygrpc.pxd b/src/python/grpcio/grpc/_cython/cygrpc.pxd
index 9779534..2645463 100644
--- a/src/python/grpcio/grpc/_cython/cygrpc.pxd
+++ b/src/python/grpcio/grpc/_cython/cygrpc.pxd
@@ -27,12 +27,12 @@
 # (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/_cython/_cygrpc/grpc.pxi"
+include "_cygrpc/grpc.pxi"
 
-include "grpc/_cython/_cygrpc/call.pxd.pxi"
-include "grpc/_cython/_cygrpc/channel.pxd.pxi"
-include "grpc/_cython/_cygrpc/credentials.pxd.pxi"
-include "grpc/_cython/_cygrpc/completion_queue.pxd.pxi"
-include "grpc/_cython/_cygrpc/records.pxd.pxi"
-include "grpc/_cython/_cygrpc/security.pxd.pxi"
-include "grpc/_cython/_cygrpc/server.pxd.pxi"
+include "_cygrpc/call.pxd.pxi"
+include "_cygrpc/channel.pxd.pxi"
+include "_cygrpc/credentials.pxd.pxi"
+include "_cygrpc/completion_queue.pxd.pxi"
+include "_cygrpc/records.pxd.pxi"
+include "_cygrpc/security.pxd.pxi"
+include "_cygrpc/server.pxd.pxi"
diff --git a/src/python/grpcio/grpc/_cython/cygrpc.pyx b/src/python/grpcio/grpc/_cython/cygrpc.pyx
index 0808999..e1bd046 100644
--- a/src/python/grpcio/grpc/_cython/cygrpc.pyx
+++ b/src/python/grpcio/grpc/_cython/cygrpc.pyx
@@ -35,14 +35,14 @@
 
 # TODO(atash): figure out why the coverage tool gets confused about the Cython
 # coverage plugin when the following files don't have a '.pxi' suffix.
-include "grpc/_cython/_cygrpc/grpc_string.pyx.pxi"
-include "grpc/_cython/_cygrpc/call.pyx.pxi"
-include "grpc/_cython/_cygrpc/channel.pyx.pxi"
-include "grpc/_cython/_cygrpc/credentials.pyx.pxi"
-include "grpc/_cython/_cygrpc/completion_queue.pyx.pxi"
-include "grpc/_cython/_cygrpc/records.pyx.pxi"
-include "grpc/_cython/_cygrpc/security.pyx.pxi"
-include "grpc/_cython/_cygrpc/server.pyx.pxi"
+include "_cygrpc/grpc_string.pyx.pxi"
+include "_cygrpc/call.pyx.pxi"
+include "_cygrpc/channel.pyx.pxi"
+include "_cygrpc/credentials.pyx.pxi"
+include "_cygrpc/completion_queue.pyx.pxi"
+include "_cygrpc/records.pyx.pxi"
+include "_cygrpc/security.pyx.pxi"
+include "_cygrpc/server.pyx.pxi"
 
 #
 # initialize gRPC
diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py
index 725134c..be7f30c 100644
--- a/src/python/grpcio/grpc_core_dependencies.py
+++ b/src/python/grpcio/grpc_core_dependencies.py
@@ -51,6 +51,7 @@
   'src/core/lib/support/log_posix.c',
   'src/core/lib/support/log_windows.c',
   'src/core/lib/support/murmur_hash.c',
+  'src/core/lib/support/percent_encoding.c',
   'src/core/lib/support/slice.c',
   'src/core/lib/support/slice_buffer.c',
   'src/core/lib/support/stack_lockfree.c',
diff --git a/src/python/grpcio_tests/setup.py b/src/python/grpcio_tests/setup.py
index 3524355..7384206 100644
--- a/src/python/grpcio_tests/setup.py
+++ b/src/python/grpcio_tests/setup.py
@@ -31,13 +31,9 @@
 
 import os
 import os.path
-import shutil
 import sys
 
-from distutils import core as _core
-from distutils import extension as _extension
 import setuptools
-from setuptools.command import egg_info
 
 import grpc.tools.command
 
diff --git a/src/ruby/ext/grpc/extconf.rb b/src/ruby/ext/grpc/extconf.rb
index 6d65db8..66c54aa 100644
--- a/src/ruby/ext/grpc/extconf.rb
+++ b/src/ruby/ext/grpc/extconf.rb
@@ -91,6 +91,10 @@
   $LDFLAGS << ' -fprofile-arcs -ftest-coverage -rdynamic'
 end
 
+if grpc_config == 'dbg'
+  $CFLAGS << ' -O0'
+end
+
 $LDFLAGS << ' -Wl,-wrap,memcpy' if RUBY_PLATFORM =~ /linux/
 $LDFLAGS << ' -static' if windows
 
diff --git a/src/ruby/ext/grpc/rb_compression_options.c b/src/ruby/ext/grpc/rb_compression_options.c
index 0a3a215..c5668fd 100644
--- a/src/ruby/ext/grpc/rb_compression_options.c
+++ b/src/ruby/ext/grpc/rb_compression_options.c
@@ -38,7 +38,7 @@
 
 #include <grpc/compression.h>
 #include <grpc/grpc.h>
-#include <grpc/impl/codegen/alloc.h>
+#include <grpc/support/alloc.h>
 #include <grpc/impl/codegen/compression_types.h>
 #include <grpc/impl/codegen/grpc_types.h>
 #include <string.h>
diff --git a/src/ruby/ext/grpc/rb_grpc_imports.generated.c b/src/ruby/ext/grpc/rb_grpc_imports.generated.c
index 9caaf7b..a6cad0d 100644
--- a/src/ruby/ext/grpc/rb_grpc_imports.generated.c
+++ b/src/ruby/ext/grpc/rb_grpc_imports.generated.c
@@ -37,6 +37,16 @@
 
 #include "rb_grpc_imports.generated.h"
 
+grpc_raw_byte_buffer_create_type grpc_raw_byte_buffer_create_import;
+grpc_raw_compressed_byte_buffer_create_type grpc_raw_compressed_byte_buffer_create_import;
+grpc_byte_buffer_copy_type grpc_byte_buffer_copy_import;
+grpc_byte_buffer_length_type grpc_byte_buffer_length_import;
+grpc_byte_buffer_destroy_type grpc_byte_buffer_destroy_import;
+grpc_byte_buffer_reader_init_type grpc_byte_buffer_reader_init_import;
+grpc_byte_buffer_reader_destroy_type grpc_byte_buffer_reader_destroy_import;
+grpc_byte_buffer_reader_next_type grpc_byte_buffer_reader_next_import;
+grpc_byte_buffer_reader_readall_type grpc_byte_buffer_reader_readall_import;
+grpc_raw_byte_buffer_from_reader_type grpc_raw_byte_buffer_from_reader_import;
 census_initialize_type census_initialize_import;
 census_shutdown_type census_shutdown_import;
 census_supported_type census_supported_import;
@@ -164,94 +174,6 @@
 gpr_free_aligned_type gpr_free_aligned_import;
 gpr_set_allocation_functions_type gpr_set_allocation_functions_import;
 gpr_get_allocation_functions_type gpr_get_allocation_functions_import;
-grpc_raw_byte_buffer_create_type grpc_raw_byte_buffer_create_import;
-grpc_raw_compressed_byte_buffer_create_type grpc_raw_compressed_byte_buffer_create_import;
-grpc_byte_buffer_copy_type grpc_byte_buffer_copy_import;
-grpc_byte_buffer_length_type grpc_byte_buffer_length_import;
-grpc_byte_buffer_destroy_type grpc_byte_buffer_destroy_import;
-grpc_byte_buffer_reader_init_type grpc_byte_buffer_reader_init_import;
-grpc_byte_buffer_reader_destroy_type grpc_byte_buffer_reader_destroy_import;
-grpc_byte_buffer_reader_next_type grpc_byte_buffer_reader_next_import;
-grpc_byte_buffer_reader_readall_type grpc_byte_buffer_reader_readall_import;
-grpc_raw_byte_buffer_from_reader_type grpc_raw_byte_buffer_from_reader_import;
-gpr_log_type gpr_log_import;
-gpr_log_message_type gpr_log_message_import;
-gpr_set_log_verbosity_type gpr_set_log_verbosity_import;
-gpr_log_verbosity_init_type gpr_log_verbosity_init_import;
-gpr_set_log_function_type gpr_set_log_function_import;
-gpr_slice_ref_type gpr_slice_ref_import;
-gpr_slice_unref_type gpr_slice_unref_import;
-gpr_slice_new_type gpr_slice_new_import;
-gpr_slice_new_with_user_data_type gpr_slice_new_with_user_data_import;
-gpr_slice_new_with_len_type gpr_slice_new_with_len_import;
-gpr_slice_malloc_type gpr_slice_malloc_import;
-gpr_slice_from_copied_string_type gpr_slice_from_copied_string_import;
-gpr_slice_from_copied_buffer_type gpr_slice_from_copied_buffer_import;
-gpr_slice_from_static_string_type gpr_slice_from_static_string_import;
-gpr_slice_sub_type gpr_slice_sub_import;
-gpr_slice_sub_no_ref_type gpr_slice_sub_no_ref_import;
-gpr_slice_split_tail_type gpr_slice_split_tail_import;
-gpr_slice_split_head_type gpr_slice_split_head_import;
-gpr_empty_slice_type gpr_empty_slice_import;
-gpr_slice_cmp_type gpr_slice_cmp_import;
-gpr_slice_str_cmp_type gpr_slice_str_cmp_import;
-gpr_slice_buffer_init_type gpr_slice_buffer_init_import;
-gpr_slice_buffer_destroy_type gpr_slice_buffer_destroy_import;
-gpr_slice_buffer_add_type gpr_slice_buffer_add_import;
-gpr_slice_buffer_add_indexed_type gpr_slice_buffer_add_indexed_import;
-gpr_slice_buffer_addn_type gpr_slice_buffer_addn_import;
-gpr_slice_buffer_tiny_add_type gpr_slice_buffer_tiny_add_import;
-gpr_slice_buffer_pop_type gpr_slice_buffer_pop_import;
-gpr_slice_buffer_reset_and_unref_type gpr_slice_buffer_reset_and_unref_import;
-gpr_slice_buffer_swap_type gpr_slice_buffer_swap_import;
-gpr_slice_buffer_move_into_type gpr_slice_buffer_move_into_import;
-gpr_slice_buffer_trim_end_type gpr_slice_buffer_trim_end_import;
-gpr_slice_buffer_move_first_type gpr_slice_buffer_move_first_import;
-gpr_slice_buffer_take_first_type gpr_slice_buffer_take_first_import;
-gpr_mu_init_type gpr_mu_init_import;
-gpr_mu_destroy_type gpr_mu_destroy_import;
-gpr_mu_lock_type gpr_mu_lock_import;
-gpr_mu_unlock_type gpr_mu_unlock_import;
-gpr_mu_trylock_type gpr_mu_trylock_import;
-gpr_cv_init_type gpr_cv_init_import;
-gpr_cv_destroy_type gpr_cv_destroy_import;
-gpr_cv_wait_type gpr_cv_wait_import;
-gpr_cv_signal_type gpr_cv_signal_import;
-gpr_cv_broadcast_type gpr_cv_broadcast_import;
-gpr_once_init_type gpr_once_init_import;
-gpr_event_init_type gpr_event_init_import;
-gpr_event_set_type gpr_event_set_import;
-gpr_event_get_type gpr_event_get_import;
-gpr_event_wait_type gpr_event_wait_import;
-gpr_ref_init_type gpr_ref_init_import;
-gpr_ref_type gpr_ref_import;
-gpr_ref_non_zero_type gpr_ref_non_zero_import;
-gpr_refn_type gpr_refn_import;
-gpr_unref_type gpr_unref_import;
-gpr_stats_init_type gpr_stats_init_import;
-gpr_stats_inc_type gpr_stats_inc_import;
-gpr_stats_read_type gpr_stats_read_import;
-gpr_time_0_type gpr_time_0_import;
-gpr_inf_future_type gpr_inf_future_import;
-gpr_inf_past_type gpr_inf_past_import;
-gpr_time_init_type gpr_time_init_import;
-gpr_now_type gpr_now_import;
-gpr_convert_clock_type_type gpr_convert_clock_type_import;
-gpr_time_cmp_type gpr_time_cmp_import;
-gpr_time_max_type gpr_time_max_import;
-gpr_time_min_type gpr_time_min_import;
-gpr_time_add_type gpr_time_add_import;
-gpr_time_sub_type gpr_time_sub_import;
-gpr_time_from_micros_type gpr_time_from_micros_import;
-gpr_time_from_nanos_type gpr_time_from_nanos_import;
-gpr_time_from_millis_type gpr_time_from_millis_import;
-gpr_time_from_seconds_type gpr_time_from_seconds_import;
-gpr_time_from_minutes_type gpr_time_from_minutes_import;
-gpr_time_from_hours_type gpr_time_from_hours_import;
-gpr_time_to_millis_type gpr_time_to_millis_import;
-gpr_time_similar_type gpr_time_similar_import;
-gpr_sleep_until_type gpr_sleep_until_import;
-gpr_timespec_to_micros_type gpr_timespec_to_micros_import;
 gpr_avl_create_type gpr_avl_create_import;
 gpr_avl_ref_type gpr_avl_ref_import;
 gpr_avl_unref_type gpr_avl_unref_import;
@@ -288,7 +210,41 @@
 gpr_histogram_merge_contents_type gpr_histogram_merge_contents_import;
 gpr_join_host_port_type gpr_join_host_port_import;
 gpr_split_host_port_type gpr_split_host_port_import;
+gpr_log_type gpr_log_import;
+gpr_log_message_type gpr_log_message_import;
+gpr_set_log_verbosity_type gpr_set_log_verbosity_import;
+gpr_log_verbosity_init_type gpr_log_verbosity_init_import;
+gpr_set_log_function_type gpr_set_log_function_import;
 gpr_format_message_type gpr_format_message_import;
+gpr_slice_ref_type gpr_slice_ref_import;
+gpr_slice_unref_type gpr_slice_unref_import;
+gpr_slice_new_type gpr_slice_new_import;
+gpr_slice_new_with_user_data_type gpr_slice_new_with_user_data_import;
+gpr_slice_new_with_len_type gpr_slice_new_with_len_import;
+gpr_slice_malloc_type gpr_slice_malloc_import;
+gpr_slice_from_copied_string_type gpr_slice_from_copied_string_import;
+gpr_slice_from_copied_buffer_type gpr_slice_from_copied_buffer_import;
+gpr_slice_from_static_string_type gpr_slice_from_static_string_import;
+gpr_slice_sub_type gpr_slice_sub_import;
+gpr_slice_sub_no_ref_type gpr_slice_sub_no_ref_import;
+gpr_slice_split_tail_type gpr_slice_split_tail_import;
+gpr_slice_split_head_type gpr_slice_split_head_import;
+gpr_empty_slice_type gpr_empty_slice_import;
+gpr_slice_cmp_type gpr_slice_cmp_import;
+gpr_slice_str_cmp_type gpr_slice_str_cmp_import;
+gpr_slice_buffer_init_type gpr_slice_buffer_init_import;
+gpr_slice_buffer_destroy_type gpr_slice_buffer_destroy_import;
+gpr_slice_buffer_add_type gpr_slice_buffer_add_import;
+gpr_slice_buffer_add_indexed_type gpr_slice_buffer_add_indexed_import;
+gpr_slice_buffer_addn_type gpr_slice_buffer_addn_import;
+gpr_slice_buffer_tiny_add_type gpr_slice_buffer_tiny_add_import;
+gpr_slice_buffer_pop_type gpr_slice_buffer_pop_import;
+gpr_slice_buffer_reset_and_unref_type gpr_slice_buffer_reset_and_unref_import;
+gpr_slice_buffer_swap_type gpr_slice_buffer_swap_import;
+gpr_slice_buffer_move_into_type gpr_slice_buffer_move_into_import;
+gpr_slice_buffer_trim_end_type gpr_slice_buffer_trim_end_import;
+gpr_slice_buffer_move_first_type gpr_slice_buffer_move_first_import;
+gpr_slice_buffer_take_first_type gpr_slice_buffer_take_first_import;
 gpr_strdup_type gpr_strdup_import;
 gpr_asprintf_type gpr_asprintf_import;
 gpr_subprocess_binary_extension_type gpr_subprocess_binary_extension_import;
@@ -296,6 +252,29 @@
 gpr_subprocess_destroy_type gpr_subprocess_destroy_import;
 gpr_subprocess_join_type gpr_subprocess_join_import;
 gpr_subprocess_interrupt_type gpr_subprocess_interrupt_import;
+gpr_mu_init_type gpr_mu_init_import;
+gpr_mu_destroy_type gpr_mu_destroy_import;
+gpr_mu_lock_type gpr_mu_lock_import;
+gpr_mu_unlock_type gpr_mu_unlock_import;
+gpr_mu_trylock_type gpr_mu_trylock_import;
+gpr_cv_init_type gpr_cv_init_import;
+gpr_cv_destroy_type gpr_cv_destroy_import;
+gpr_cv_wait_type gpr_cv_wait_import;
+gpr_cv_signal_type gpr_cv_signal_import;
+gpr_cv_broadcast_type gpr_cv_broadcast_import;
+gpr_once_init_type gpr_once_init_import;
+gpr_event_init_type gpr_event_init_import;
+gpr_event_set_type gpr_event_set_import;
+gpr_event_get_type gpr_event_get_import;
+gpr_event_wait_type gpr_event_wait_import;
+gpr_ref_init_type gpr_ref_init_import;
+gpr_ref_type gpr_ref_import;
+gpr_ref_non_zero_type gpr_ref_non_zero_import;
+gpr_refn_type gpr_refn_import;
+gpr_unref_type gpr_unref_import;
+gpr_stats_init_type gpr_stats_init_import;
+gpr_stats_inc_type gpr_stats_inc_import;
+gpr_stats_read_type gpr_stats_read_import;
 gpr_thd_new_type gpr_thd_new_import;
 gpr_thd_options_default_type gpr_thd_options_default_import;
 gpr_thd_options_set_detached_type gpr_thd_options_set_detached_import;
@@ -304,8 +283,39 @@
 gpr_thd_options_is_joinable_type gpr_thd_options_is_joinable_import;
 gpr_thd_currentid_type gpr_thd_currentid_import;
 gpr_thd_join_type gpr_thd_join_import;
+gpr_time_0_type gpr_time_0_import;
+gpr_inf_future_type gpr_inf_future_import;
+gpr_inf_past_type gpr_inf_past_import;
+gpr_time_init_type gpr_time_init_import;
+gpr_now_type gpr_now_import;
+gpr_convert_clock_type_type gpr_convert_clock_type_import;
+gpr_time_cmp_type gpr_time_cmp_import;
+gpr_time_max_type gpr_time_max_import;
+gpr_time_min_type gpr_time_min_import;
+gpr_time_add_type gpr_time_add_import;
+gpr_time_sub_type gpr_time_sub_import;
+gpr_time_from_micros_type gpr_time_from_micros_import;
+gpr_time_from_nanos_type gpr_time_from_nanos_import;
+gpr_time_from_millis_type gpr_time_from_millis_import;
+gpr_time_from_seconds_type gpr_time_from_seconds_import;
+gpr_time_from_minutes_type gpr_time_from_minutes_import;
+gpr_time_from_hours_type gpr_time_from_hours_import;
+gpr_time_to_millis_type gpr_time_to_millis_import;
+gpr_time_similar_type gpr_time_similar_import;
+gpr_sleep_until_type gpr_sleep_until_import;
+gpr_timespec_to_micros_type gpr_timespec_to_micros_import;
 
 void grpc_rb_load_imports(HMODULE library) {
+  grpc_raw_byte_buffer_create_import = (grpc_raw_byte_buffer_create_type) GetProcAddress(library, "grpc_raw_byte_buffer_create");
+  grpc_raw_compressed_byte_buffer_create_import = (grpc_raw_compressed_byte_buffer_create_type) GetProcAddress(library, "grpc_raw_compressed_byte_buffer_create");
+  grpc_byte_buffer_copy_import = (grpc_byte_buffer_copy_type) GetProcAddress(library, "grpc_byte_buffer_copy");
+  grpc_byte_buffer_length_import = (grpc_byte_buffer_length_type) GetProcAddress(library, "grpc_byte_buffer_length");
+  grpc_byte_buffer_destroy_import = (grpc_byte_buffer_destroy_type) GetProcAddress(library, "grpc_byte_buffer_destroy");
+  grpc_byte_buffer_reader_init_import = (grpc_byte_buffer_reader_init_type) GetProcAddress(library, "grpc_byte_buffer_reader_init");
+  grpc_byte_buffer_reader_destroy_import = (grpc_byte_buffer_reader_destroy_type) GetProcAddress(library, "grpc_byte_buffer_reader_destroy");
+  grpc_byte_buffer_reader_next_import = (grpc_byte_buffer_reader_next_type) GetProcAddress(library, "grpc_byte_buffer_reader_next");
+  grpc_byte_buffer_reader_readall_import = (grpc_byte_buffer_reader_readall_type) GetProcAddress(library, "grpc_byte_buffer_reader_readall");
+  grpc_raw_byte_buffer_from_reader_import = (grpc_raw_byte_buffer_from_reader_type) GetProcAddress(library, "grpc_raw_byte_buffer_from_reader");
   census_initialize_import = (census_initialize_type) GetProcAddress(library, "census_initialize");
   census_shutdown_import = (census_shutdown_type) GetProcAddress(library, "census_shutdown");
   census_supported_import = (census_supported_type) GetProcAddress(library, "census_supported");
@@ -433,94 +443,6 @@
   gpr_free_aligned_import = (gpr_free_aligned_type) GetProcAddress(library, "gpr_free_aligned");
   gpr_set_allocation_functions_import = (gpr_set_allocation_functions_type) GetProcAddress(library, "gpr_set_allocation_functions");
   gpr_get_allocation_functions_import = (gpr_get_allocation_functions_type) GetProcAddress(library, "gpr_get_allocation_functions");
-  grpc_raw_byte_buffer_create_import = (grpc_raw_byte_buffer_create_type) GetProcAddress(library, "grpc_raw_byte_buffer_create");
-  grpc_raw_compressed_byte_buffer_create_import = (grpc_raw_compressed_byte_buffer_create_type) GetProcAddress(library, "grpc_raw_compressed_byte_buffer_create");
-  grpc_byte_buffer_copy_import = (grpc_byte_buffer_copy_type) GetProcAddress(library, "grpc_byte_buffer_copy");
-  grpc_byte_buffer_length_import = (grpc_byte_buffer_length_type) GetProcAddress(library, "grpc_byte_buffer_length");
-  grpc_byte_buffer_destroy_import = (grpc_byte_buffer_destroy_type) GetProcAddress(library, "grpc_byte_buffer_destroy");
-  grpc_byte_buffer_reader_init_import = (grpc_byte_buffer_reader_init_type) GetProcAddress(library, "grpc_byte_buffer_reader_init");
-  grpc_byte_buffer_reader_destroy_import = (grpc_byte_buffer_reader_destroy_type) GetProcAddress(library, "grpc_byte_buffer_reader_destroy");
-  grpc_byte_buffer_reader_next_import = (grpc_byte_buffer_reader_next_type) GetProcAddress(library, "grpc_byte_buffer_reader_next");
-  grpc_byte_buffer_reader_readall_import = (grpc_byte_buffer_reader_readall_type) GetProcAddress(library, "grpc_byte_buffer_reader_readall");
-  grpc_raw_byte_buffer_from_reader_import = (grpc_raw_byte_buffer_from_reader_type) GetProcAddress(library, "grpc_raw_byte_buffer_from_reader");
-  gpr_log_import = (gpr_log_type) GetProcAddress(library, "gpr_log");
-  gpr_log_message_import = (gpr_log_message_type) GetProcAddress(library, "gpr_log_message");
-  gpr_set_log_verbosity_import = (gpr_set_log_verbosity_type) GetProcAddress(library, "gpr_set_log_verbosity");
-  gpr_log_verbosity_init_import = (gpr_log_verbosity_init_type) GetProcAddress(library, "gpr_log_verbosity_init");
-  gpr_set_log_function_import = (gpr_set_log_function_type) GetProcAddress(library, "gpr_set_log_function");
-  gpr_slice_ref_import = (gpr_slice_ref_type) GetProcAddress(library, "gpr_slice_ref");
-  gpr_slice_unref_import = (gpr_slice_unref_type) GetProcAddress(library, "gpr_slice_unref");
-  gpr_slice_new_import = (gpr_slice_new_type) GetProcAddress(library, "gpr_slice_new");
-  gpr_slice_new_with_user_data_import = (gpr_slice_new_with_user_data_type) GetProcAddress(library, "gpr_slice_new_with_user_data");
-  gpr_slice_new_with_len_import = (gpr_slice_new_with_len_type) GetProcAddress(library, "gpr_slice_new_with_len");
-  gpr_slice_malloc_import = (gpr_slice_malloc_type) GetProcAddress(library, "gpr_slice_malloc");
-  gpr_slice_from_copied_string_import = (gpr_slice_from_copied_string_type) GetProcAddress(library, "gpr_slice_from_copied_string");
-  gpr_slice_from_copied_buffer_import = (gpr_slice_from_copied_buffer_type) GetProcAddress(library, "gpr_slice_from_copied_buffer");
-  gpr_slice_from_static_string_import = (gpr_slice_from_static_string_type) GetProcAddress(library, "gpr_slice_from_static_string");
-  gpr_slice_sub_import = (gpr_slice_sub_type) GetProcAddress(library, "gpr_slice_sub");
-  gpr_slice_sub_no_ref_import = (gpr_slice_sub_no_ref_type) GetProcAddress(library, "gpr_slice_sub_no_ref");
-  gpr_slice_split_tail_import = (gpr_slice_split_tail_type) GetProcAddress(library, "gpr_slice_split_tail");
-  gpr_slice_split_head_import = (gpr_slice_split_head_type) GetProcAddress(library, "gpr_slice_split_head");
-  gpr_empty_slice_import = (gpr_empty_slice_type) GetProcAddress(library, "gpr_empty_slice");
-  gpr_slice_cmp_import = (gpr_slice_cmp_type) GetProcAddress(library, "gpr_slice_cmp");
-  gpr_slice_str_cmp_import = (gpr_slice_str_cmp_type) GetProcAddress(library, "gpr_slice_str_cmp");
-  gpr_slice_buffer_init_import = (gpr_slice_buffer_init_type) GetProcAddress(library, "gpr_slice_buffer_init");
-  gpr_slice_buffer_destroy_import = (gpr_slice_buffer_destroy_type) GetProcAddress(library, "gpr_slice_buffer_destroy");
-  gpr_slice_buffer_add_import = (gpr_slice_buffer_add_type) GetProcAddress(library, "gpr_slice_buffer_add");
-  gpr_slice_buffer_add_indexed_import = (gpr_slice_buffer_add_indexed_type) GetProcAddress(library, "gpr_slice_buffer_add_indexed");
-  gpr_slice_buffer_addn_import = (gpr_slice_buffer_addn_type) GetProcAddress(library, "gpr_slice_buffer_addn");
-  gpr_slice_buffer_tiny_add_import = (gpr_slice_buffer_tiny_add_type) GetProcAddress(library, "gpr_slice_buffer_tiny_add");
-  gpr_slice_buffer_pop_import = (gpr_slice_buffer_pop_type) GetProcAddress(library, "gpr_slice_buffer_pop");
-  gpr_slice_buffer_reset_and_unref_import = (gpr_slice_buffer_reset_and_unref_type) GetProcAddress(library, "gpr_slice_buffer_reset_and_unref");
-  gpr_slice_buffer_swap_import = (gpr_slice_buffer_swap_type) GetProcAddress(library, "gpr_slice_buffer_swap");
-  gpr_slice_buffer_move_into_import = (gpr_slice_buffer_move_into_type) GetProcAddress(library, "gpr_slice_buffer_move_into");
-  gpr_slice_buffer_trim_end_import = (gpr_slice_buffer_trim_end_type) GetProcAddress(library, "gpr_slice_buffer_trim_end");
-  gpr_slice_buffer_move_first_import = (gpr_slice_buffer_move_first_type) GetProcAddress(library, "gpr_slice_buffer_move_first");
-  gpr_slice_buffer_take_first_import = (gpr_slice_buffer_take_first_type) GetProcAddress(library, "gpr_slice_buffer_take_first");
-  gpr_mu_init_import = (gpr_mu_init_type) GetProcAddress(library, "gpr_mu_init");
-  gpr_mu_destroy_import = (gpr_mu_destroy_type) GetProcAddress(library, "gpr_mu_destroy");
-  gpr_mu_lock_import = (gpr_mu_lock_type) GetProcAddress(library, "gpr_mu_lock");
-  gpr_mu_unlock_import = (gpr_mu_unlock_type) GetProcAddress(library, "gpr_mu_unlock");
-  gpr_mu_trylock_import = (gpr_mu_trylock_type) GetProcAddress(library, "gpr_mu_trylock");
-  gpr_cv_init_import = (gpr_cv_init_type) GetProcAddress(library, "gpr_cv_init");
-  gpr_cv_destroy_import = (gpr_cv_destroy_type) GetProcAddress(library, "gpr_cv_destroy");
-  gpr_cv_wait_import = (gpr_cv_wait_type) GetProcAddress(library, "gpr_cv_wait");
-  gpr_cv_signal_import = (gpr_cv_signal_type) GetProcAddress(library, "gpr_cv_signal");
-  gpr_cv_broadcast_import = (gpr_cv_broadcast_type) GetProcAddress(library, "gpr_cv_broadcast");
-  gpr_once_init_import = (gpr_once_init_type) GetProcAddress(library, "gpr_once_init");
-  gpr_event_init_import = (gpr_event_init_type) GetProcAddress(library, "gpr_event_init");
-  gpr_event_set_import = (gpr_event_set_type) GetProcAddress(library, "gpr_event_set");
-  gpr_event_get_import = (gpr_event_get_type) GetProcAddress(library, "gpr_event_get");
-  gpr_event_wait_import = (gpr_event_wait_type) GetProcAddress(library, "gpr_event_wait");
-  gpr_ref_init_import = (gpr_ref_init_type) GetProcAddress(library, "gpr_ref_init");
-  gpr_ref_import = (gpr_ref_type) GetProcAddress(library, "gpr_ref");
-  gpr_ref_non_zero_import = (gpr_ref_non_zero_type) GetProcAddress(library, "gpr_ref_non_zero");
-  gpr_refn_import = (gpr_refn_type) GetProcAddress(library, "gpr_refn");
-  gpr_unref_import = (gpr_unref_type) GetProcAddress(library, "gpr_unref");
-  gpr_stats_init_import = (gpr_stats_init_type) GetProcAddress(library, "gpr_stats_init");
-  gpr_stats_inc_import = (gpr_stats_inc_type) GetProcAddress(library, "gpr_stats_inc");
-  gpr_stats_read_import = (gpr_stats_read_type) GetProcAddress(library, "gpr_stats_read");
-  gpr_time_0_import = (gpr_time_0_type) GetProcAddress(library, "gpr_time_0");
-  gpr_inf_future_import = (gpr_inf_future_type) GetProcAddress(library, "gpr_inf_future");
-  gpr_inf_past_import = (gpr_inf_past_type) GetProcAddress(library, "gpr_inf_past");
-  gpr_time_init_import = (gpr_time_init_type) GetProcAddress(library, "gpr_time_init");
-  gpr_now_import = (gpr_now_type) GetProcAddress(library, "gpr_now");
-  gpr_convert_clock_type_import = (gpr_convert_clock_type_type) GetProcAddress(library, "gpr_convert_clock_type");
-  gpr_time_cmp_import = (gpr_time_cmp_type) GetProcAddress(library, "gpr_time_cmp");
-  gpr_time_max_import = (gpr_time_max_type) GetProcAddress(library, "gpr_time_max");
-  gpr_time_min_import = (gpr_time_min_type) GetProcAddress(library, "gpr_time_min");
-  gpr_time_add_import = (gpr_time_add_type) GetProcAddress(library, "gpr_time_add");
-  gpr_time_sub_import = (gpr_time_sub_type) GetProcAddress(library, "gpr_time_sub");
-  gpr_time_from_micros_import = (gpr_time_from_micros_type) GetProcAddress(library, "gpr_time_from_micros");
-  gpr_time_from_nanos_import = (gpr_time_from_nanos_type) GetProcAddress(library, "gpr_time_from_nanos");
-  gpr_time_from_millis_import = (gpr_time_from_millis_type) GetProcAddress(library, "gpr_time_from_millis");
-  gpr_time_from_seconds_import = (gpr_time_from_seconds_type) GetProcAddress(library, "gpr_time_from_seconds");
-  gpr_time_from_minutes_import = (gpr_time_from_minutes_type) GetProcAddress(library, "gpr_time_from_minutes");
-  gpr_time_from_hours_import = (gpr_time_from_hours_type) GetProcAddress(library, "gpr_time_from_hours");
-  gpr_time_to_millis_import = (gpr_time_to_millis_type) GetProcAddress(library, "gpr_time_to_millis");
-  gpr_time_similar_import = (gpr_time_similar_type) GetProcAddress(library, "gpr_time_similar");
-  gpr_sleep_until_import = (gpr_sleep_until_type) GetProcAddress(library, "gpr_sleep_until");
-  gpr_timespec_to_micros_import = (gpr_timespec_to_micros_type) GetProcAddress(library, "gpr_timespec_to_micros");
   gpr_avl_create_import = (gpr_avl_create_type) GetProcAddress(library, "gpr_avl_create");
   gpr_avl_ref_import = (gpr_avl_ref_type) GetProcAddress(library, "gpr_avl_ref");
   gpr_avl_unref_import = (gpr_avl_unref_type) GetProcAddress(library, "gpr_avl_unref");
@@ -557,7 +479,41 @@
   gpr_histogram_merge_contents_import = (gpr_histogram_merge_contents_type) GetProcAddress(library, "gpr_histogram_merge_contents");
   gpr_join_host_port_import = (gpr_join_host_port_type) GetProcAddress(library, "gpr_join_host_port");
   gpr_split_host_port_import = (gpr_split_host_port_type) GetProcAddress(library, "gpr_split_host_port");
+  gpr_log_import = (gpr_log_type) GetProcAddress(library, "gpr_log");
+  gpr_log_message_import = (gpr_log_message_type) GetProcAddress(library, "gpr_log_message");
+  gpr_set_log_verbosity_import = (gpr_set_log_verbosity_type) GetProcAddress(library, "gpr_set_log_verbosity");
+  gpr_log_verbosity_init_import = (gpr_log_verbosity_init_type) GetProcAddress(library, "gpr_log_verbosity_init");
+  gpr_set_log_function_import = (gpr_set_log_function_type) GetProcAddress(library, "gpr_set_log_function");
   gpr_format_message_import = (gpr_format_message_type) GetProcAddress(library, "gpr_format_message");
+  gpr_slice_ref_import = (gpr_slice_ref_type) GetProcAddress(library, "gpr_slice_ref");
+  gpr_slice_unref_import = (gpr_slice_unref_type) GetProcAddress(library, "gpr_slice_unref");
+  gpr_slice_new_import = (gpr_slice_new_type) GetProcAddress(library, "gpr_slice_new");
+  gpr_slice_new_with_user_data_import = (gpr_slice_new_with_user_data_type) GetProcAddress(library, "gpr_slice_new_with_user_data");
+  gpr_slice_new_with_len_import = (gpr_slice_new_with_len_type) GetProcAddress(library, "gpr_slice_new_with_len");
+  gpr_slice_malloc_import = (gpr_slice_malloc_type) GetProcAddress(library, "gpr_slice_malloc");
+  gpr_slice_from_copied_string_import = (gpr_slice_from_copied_string_type) GetProcAddress(library, "gpr_slice_from_copied_string");
+  gpr_slice_from_copied_buffer_import = (gpr_slice_from_copied_buffer_type) GetProcAddress(library, "gpr_slice_from_copied_buffer");
+  gpr_slice_from_static_string_import = (gpr_slice_from_static_string_type) GetProcAddress(library, "gpr_slice_from_static_string");
+  gpr_slice_sub_import = (gpr_slice_sub_type) GetProcAddress(library, "gpr_slice_sub");
+  gpr_slice_sub_no_ref_import = (gpr_slice_sub_no_ref_type) GetProcAddress(library, "gpr_slice_sub_no_ref");
+  gpr_slice_split_tail_import = (gpr_slice_split_tail_type) GetProcAddress(library, "gpr_slice_split_tail");
+  gpr_slice_split_head_import = (gpr_slice_split_head_type) GetProcAddress(library, "gpr_slice_split_head");
+  gpr_empty_slice_import = (gpr_empty_slice_type) GetProcAddress(library, "gpr_empty_slice");
+  gpr_slice_cmp_import = (gpr_slice_cmp_type) GetProcAddress(library, "gpr_slice_cmp");
+  gpr_slice_str_cmp_import = (gpr_slice_str_cmp_type) GetProcAddress(library, "gpr_slice_str_cmp");
+  gpr_slice_buffer_init_import = (gpr_slice_buffer_init_type) GetProcAddress(library, "gpr_slice_buffer_init");
+  gpr_slice_buffer_destroy_import = (gpr_slice_buffer_destroy_type) GetProcAddress(library, "gpr_slice_buffer_destroy");
+  gpr_slice_buffer_add_import = (gpr_slice_buffer_add_type) GetProcAddress(library, "gpr_slice_buffer_add");
+  gpr_slice_buffer_add_indexed_import = (gpr_slice_buffer_add_indexed_type) GetProcAddress(library, "gpr_slice_buffer_add_indexed");
+  gpr_slice_buffer_addn_import = (gpr_slice_buffer_addn_type) GetProcAddress(library, "gpr_slice_buffer_addn");
+  gpr_slice_buffer_tiny_add_import = (gpr_slice_buffer_tiny_add_type) GetProcAddress(library, "gpr_slice_buffer_tiny_add");
+  gpr_slice_buffer_pop_import = (gpr_slice_buffer_pop_type) GetProcAddress(library, "gpr_slice_buffer_pop");
+  gpr_slice_buffer_reset_and_unref_import = (gpr_slice_buffer_reset_and_unref_type) GetProcAddress(library, "gpr_slice_buffer_reset_and_unref");
+  gpr_slice_buffer_swap_import = (gpr_slice_buffer_swap_type) GetProcAddress(library, "gpr_slice_buffer_swap");
+  gpr_slice_buffer_move_into_import = (gpr_slice_buffer_move_into_type) GetProcAddress(library, "gpr_slice_buffer_move_into");
+  gpr_slice_buffer_trim_end_import = (gpr_slice_buffer_trim_end_type) GetProcAddress(library, "gpr_slice_buffer_trim_end");
+  gpr_slice_buffer_move_first_import = (gpr_slice_buffer_move_first_type) GetProcAddress(library, "gpr_slice_buffer_move_first");
+  gpr_slice_buffer_take_first_import = (gpr_slice_buffer_take_first_type) GetProcAddress(library, "gpr_slice_buffer_take_first");
   gpr_strdup_import = (gpr_strdup_type) GetProcAddress(library, "gpr_strdup");
   gpr_asprintf_import = (gpr_asprintf_type) GetProcAddress(library, "gpr_asprintf");
   gpr_subprocess_binary_extension_import = (gpr_subprocess_binary_extension_type) GetProcAddress(library, "gpr_subprocess_binary_extension");
@@ -565,6 +521,29 @@
   gpr_subprocess_destroy_import = (gpr_subprocess_destroy_type) GetProcAddress(library, "gpr_subprocess_destroy");
   gpr_subprocess_join_import = (gpr_subprocess_join_type) GetProcAddress(library, "gpr_subprocess_join");
   gpr_subprocess_interrupt_import = (gpr_subprocess_interrupt_type) GetProcAddress(library, "gpr_subprocess_interrupt");
+  gpr_mu_init_import = (gpr_mu_init_type) GetProcAddress(library, "gpr_mu_init");
+  gpr_mu_destroy_import = (gpr_mu_destroy_type) GetProcAddress(library, "gpr_mu_destroy");
+  gpr_mu_lock_import = (gpr_mu_lock_type) GetProcAddress(library, "gpr_mu_lock");
+  gpr_mu_unlock_import = (gpr_mu_unlock_type) GetProcAddress(library, "gpr_mu_unlock");
+  gpr_mu_trylock_import = (gpr_mu_trylock_type) GetProcAddress(library, "gpr_mu_trylock");
+  gpr_cv_init_import = (gpr_cv_init_type) GetProcAddress(library, "gpr_cv_init");
+  gpr_cv_destroy_import = (gpr_cv_destroy_type) GetProcAddress(library, "gpr_cv_destroy");
+  gpr_cv_wait_import = (gpr_cv_wait_type) GetProcAddress(library, "gpr_cv_wait");
+  gpr_cv_signal_import = (gpr_cv_signal_type) GetProcAddress(library, "gpr_cv_signal");
+  gpr_cv_broadcast_import = (gpr_cv_broadcast_type) GetProcAddress(library, "gpr_cv_broadcast");
+  gpr_once_init_import = (gpr_once_init_type) GetProcAddress(library, "gpr_once_init");
+  gpr_event_init_import = (gpr_event_init_type) GetProcAddress(library, "gpr_event_init");
+  gpr_event_set_import = (gpr_event_set_type) GetProcAddress(library, "gpr_event_set");
+  gpr_event_get_import = (gpr_event_get_type) GetProcAddress(library, "gpr_event_get");
+  gpr_event_wait_import = (gpr_event_wait_type) GetProcAddress(library, "gpr_event_wait");
+  gpr_ref_init_import = (gpr_ref_init_type) GetProcAddress(library, "gpr_ref_init");
+  gpr_ref_import = (gpr_ref_type) GetProcAddress(library, "gpr_ref");
+  gpr_ref_non_zero_import = (gpr_ref_non_zero_type) GetProcAddress(library, "gpr_ref_non_zero");
+  gpr_refn_import = (gpr_refn_type) GetProcAddress(library, "gpr_refn");
+  gpr_unref_import = (gpr_unref_type) GetProcAddress(library, "gpr_unref");
+  gpr_stats_init_import = (gpr_stats_init_type) GetProcAddress(library, "gpr_stats_init");
+  gpr_stats_inc_import = (gpr_stats_inc_type) GetProcAddress(library, "gpr_stats_inc");
+  gpr_stats_read_import = (gpr_stats_read_type) GetProcAddress(library, "gpr_stats_read");
   gpr_thd_new_import = (gpr_thd_new_type) GetProcAddress(library, "gpr_thd_new");
   gpr_thd_options_default_import = (gpr_thd_options_default_type) GetProcAddress(library, "gpr_thd_options_default");
   gpr_thd_options_set_detached_import = (gpr_thd_options_set_detached_type) GetProcAddress(library, "gpr_thd_options_set_detached");
@@ -573,6 +552,27 @@
   gpr_thd_options_is_joinable_import = (gpr_thd_options_is_joinable_type) GetProcAddress(library, "gpr_thd_options_is_joinable");
   gpr_thd_currentid_import = (gpr_thd_currentid_type) GetProcAddress(library, "gpr_thd_currentid");
   gpr_thd_join_import = (gpr_thd_join_type) GetProcAddress(library, "gpr_thd_join");
+  gpr_time_0_import = (gpr_time_0_type) GetProcAddress(library, "gpr_time_0");
+  gpr_inf_future_import = (gpr_inf_future_type) GetProcAddress(library, "gpr_inf_future");
+  gpr_inf_past_import = (gpr_inf_past_type) GetProcAddress(library, "gpr_inf_past");
+  gpr_time_init_import = (gpr_time_init_type) GetProcAddress(library, "gpr_time_init");
+  gpr_now_import = (gpr_now_type) GetProcAddress(library, "gpr_now");
+  gpr_convert_clock_type_import = (gpr_convert_clock_type_type) GetProcAddress(library, "gpr_convert_clock_type");
+  gpr_time_cmp_import = (gpr_time_cmp_type) GetProcAddress(library, "gpr_time_cmp");
+  gpr_time_max_import = (gpr_time_max_type) GetProcAddress(library, "gpr_time_max");
+  gpr_time_min_import = (gpr_time_min_type) GetProcAddress(library, "gpr_time_min");
+  gpr_time_add_import = (gpr_time_add_type) GetProcAddress(library, "gpr_time_add");
+  gpr_time_sub_import = (gpr_time_sub_type) GetProcAddress(library, "gpr_time_sub");
+  gpr_time_from_micros_import = (gpr_time_from_micros_type) GetProcAddress(library, "gpr_time_from_micros");
+  gpr_time_from_nanos_import = (gpr_time_from_nanos_type) GetProcAddress(library, "gpr_time_from_nanos");
+  gpr_time_from_millis_import = (gpr_time_from_millis_type) GetProcAddress(library, "gpr_time_from_millis");
+  gpr_time_from_seconds_import = (gpr_time_from_seconds_type) GetProcAddress(library, "gpr_time_from_seconds");
+  gpr_time_from_minutes_import = (gpr_time_from_minutes_type) GetProcAddress(library, "gpr_time_from_minutes");
+  gpr_time_from_hours_import = (gpr_time_from_hours_type) GetProcAddress(library, "gpr_time_from_hours");
+  gpr_time_to_millis_import = (gpr_time_to_millis_type) GetProcAddress(library, "gpr_time_to_millis");
+  gpr_time_similar_import = (gpr_time_similar_type) GetProcAddress(library, "gpr_time_similar");
+  gpr_sleep_until_import = (gpr_sleep_until_type) GetProcAddress(library, "gpr_sleep_until");
+  gpr_timespec_to_micros_import = (gpr_timespec_to_micros_type) GetProcAddress(library, "gpr_timespec_to_micros");
 }
 
 #endif /* GPR_WINDOWS */
diff --git a/src/ruby/ext/grpc/rb_grpc_imports.generated.h b/src/ruby/ext/grpc/rb_grpc_imports.generated.h
index a2f5b86..b87abfd 100644
--- a/src/ruby/ext/grpc/rb_grpc_imports.generated.h
+++ b/src/ruby/ext/grpc/rb_grpc_imports.generated.h
@@ -40,28 +40,58 @@
 
 #include <windows.h>
 
+#include <grpc/byte_buffer.h>
 #include <grpc/census.h>
 #include <grpc/compression.h>
 #include <grpc/grpc.h>
 #include <grpc/grpc_posix.h>
 #include <grpc/grpc_security.h>
-#include <grpc/impl/codegen/alloc.h>
-#include <grpc/impl/codegen/byte_buffer.h>
-#include <grpc/impl/codegen/log.h>
-#include <grpc/impl/codegen/slice.h>
-#include <grpc/impl/codegen/slice_buffer.h>
-#include <grpc/impl/codegen/sync.h>
-#include <grpc/impl/codegen/time.h>
+#include <grpc/support/alloc.h>
 #include <grpc/support/avl.h>
 #include <grpc/support/cmdline.h>
 #include <grpc/support/cpu.h>
 #include <grpc/support/histogram.h>
 #include <grpc/support/host_port.h>
+#include <grpc/support/log.h>
 #include <grpc/support/log_windows.h>
+#include <grpc/support/slice.h>
+#include <grpc/support/slice_buffer.h>
 #include <grpc/support/string_util.h>
 #include <grpc/support/subprocess.h>
+#include <grpc/support/sync.h>
 #include <grpc/support/thd.h>
+#include <grpc/support/time.h>
 
+typedef grpc_byte_buffer *(*grpc_raw_byte_buffer_create_type)(gpr_slice *slices, size_t nslices);
+extern grpc_raw_byte_buffer_create_type grpc_raw_byte_buffer_create_import;
+#define grpc_raw_byte_buffer_create grpc_raw_byte_buffer_create_import
+typedef grpc_byte_buffer *(*grpc_raw_compressed_byte_buffer_create_type)(gpr_slice *slices, size_t nslices, grpc_compression_algorithm compression);
+extern grpc_raw_compressed_byte_buffer_create_type grpc_raw_compressed_byte_buffer_create_import;
+#define grpc_raw_compressed_byte_buffer_create grpc_raw_compressed_byte_buffer_create_import
+typedef grpc_byte_buffer *(*grpc_byte_buffer_copy_type)(grpc_byte_buffer *bb);
+extern grpc_byte_buffer_copy_type grpc_byte_buffer_copy_import;
+#define grpc_byte_buffer_copy grpc_byte_buffer_copy_import
+typedef size_t(*grpc_byte_buffer_length_type)(grpc_byte_buffer *bb);
+extern grpc_byte_buffer_length_type grpc_byte_buffer_length_import;
+#define grpc_byte_buffer_length grpc_byte_buffer_length_import
+typedef void(*grpc_byte_buffer_destroy_type)(grpc_byte_buffer *byte_buffer);
+extern grpc_byte_buffer_destroy_type grpc_byte_buffer_destroy_import;
+#define grpc_byte_buffer_destroy grpc_byte_buffer_destroy_import
+typedef int(*grpc_byte_buffer_reader_init_type)(grpc_byte_buffer_reader *reader, grpc_byte_buffer *buffer);
+extern grpc_byte_buffer_reader_init_type grpc_byte_buffer_reader_init_import;
+#define grpc_byte_buffer_reader_init grpc_byte_buffer_reader_init_import
+typedef void(*grpc_byte_buffer_reader_destroy_type)(grpc_byte_buffer_reader *reader);
+extern grpc_byte_buffer_reader_destroy_type grpc_byte_buffer_reader_destroy_import;
+#define grpc_byte_buffer_reader_destroy grpc_byte_buffer_reader_destroy_import
+typedef int(*grpc_byte_buffer_reader_next_type)(grpc_byte_buffer_reader *reader, gpr_slice *slice);
+extern grpc_byte_buffer_reader_next_type grpc_byte_buffer_reader_next_import;
+#define grpc_byte_buffer_reader_next grpc_byte_buffer_reader_next_import
+typedef gpr_slice(*grpc_byte_buffer_reader_readall_type)(grpc_byte_buffer_reader *reader);
+extern grpc_byte_buffer_reader_readall_type grpc_byte_buffer_reader_readall_import;
+#define grpc_byte_buffer_reader_readall grpc_byte_buffer_reader_readall_import
+typedef grpc_byte_buffer *(*grpc_raw_byte_buffer_from_reader_type)(grpc_byte_buffer_reader *reader);
+extern grpc_raw_byte_buffer_from_reader_type grpc_raw_byte_buffer_from_reader_import;
+#define grpc_raw_byte_buffer_from_reader grpc_raw_byte_buffer_from_reader_import
 typedef int(*census_initialize_type)(int features);
 extern census_initialize_type census_initialize_import;
 #define census_initialize census_initialize_import
@@ -443,270 +473,6 @@
 typedef gpr_allocation_functions(*gpr_get_allocation_functions_type)();
 extern gpr_get_allocation_functions_type gpr_get_allocation_functions_import;
 #define gpr_get_allocation_functions gpr_get_allocation_functions_import
-typedef grpc_byte_buffer *(*grpc_raw_byte_buffer_create_type)(gpr_slice *slices, size_t nslices);
-extern grpc_raw_byte_buffer_create_type grpc_raw_byte_buffer_create_import;
-#define grpc_raw_byte_buffer_create grpc_raw_byte_buffer_create_import
-typedef grpc_byte_buffer *(*grpc_raw_compressed_byte_buffer_create_type)(gpr_slice *slices, size_t nslices, grpc_compression_algorithm compression);
-extern grpc_raw_compressed_byte_buffer_create_type grpc_raw_compressed_byte_buffer_create_import;
-#define grpc_raw_compressed_byte_buffer_create grpc_raw_compressed_byte_buffer_create_import
-typedef grpc_byte_buffer *(*grpc_byte_buffer_copy_type)(grpc_byte_buffer *bb);
-extern grpc_byte_buffer_copy_type grpc_byte_buffer_copy_import;
-#define grpc_byte_buffer_copy grpc_byte_buffer_copy_import
-typedef size_t(*grpc_byte_buffer_length_type)(grpc_byte_buffer *bb);
-extern grpc_byte_buffer_length_type grpc_byte_buffer_length_import;
-#define grpc_byte_buffer_length grpc_byte_buffer_length_import
-typedef void(*grpc_byte_buffer_destroy_type)(grpc_byte_buffer *byte_buffer);
-extern grpc_byte_buffer_destroy_type grpc_byte_buffer_destroy_import;
-#define grpc_byte_buffer_destroy grpc_byte_buffer_destroy_import
-typedef int(*grpc_byte_buffer_reader_init_type)(grpc_byte_buffer_reader *reader, grpc_byte_buffer *buffer);
-extern grpc_byte_buffer_reader_init_type grpc_byte_buffer_reader_init_import;
-#define grpc_byte_buffer_reader_init grpc_byte_buffer_reader_init_import
-typedef void(*grpc_byte_buffer_reader_destroy_type)(grpc_byte_buffer_reader *reader);
-extern grpc_byte_buffer_reader_destroy_type grpc_byte_buffer_reader_destroy_import;
-#define grpc_byte_buffer_reader_destroy grpc_byte_buffer_reader_destroy_import
-typedef int(*grpc_byte_buffer_reader_next_type)(grpc_byte_buffer_reader *reader, gpr_slice *slice);
-extern grpc_byte_buffer_reader_next_type grpc_byte_buffer_reader_next_import;
-#define grpc_byte_buffer_reader_next grpc_byte_buffer_reader_next_import
-typedef gpr_slice(*grpc_byte_buffer_reader_readall_type)(grpc_byte_buffer_reader *reader);
-extern grpc_byte_buffer_reader_readall_type grpc_byte_buffer_reader_readall_import;
-#define grpc_byte_buffer_reader_readall grpc_byte_buffer_reader_readall_import
-typedef grpc_byte_buffer *(*grpc_raw_byte_buffer_from_reader_type)(grpc_byte_buffer_reader *reader);
-extern grpc_raw_byte_buffer_from_reader_type grpc_raw_byte_buffer_from_reader_import;
-#define grpc_raw_byte_buffer_from_reader grpc_raw_byte_buffer_from_reader_import
-typedef void(*gpr_log_type)(const char *file, int line, gpr_log_severity severity, const char *format, ...) GPRC_PRINT_FORMAT_CHECK(4, 5);
-extern gpr_log_type gpr_log_import;
-#define gpr_log gpr_log_import
-typedef void(*gpr_log_message_type)(const char *file, int line, gpr_log_severity severity, const char *message);
-extern gpr_log_message_type gpr_log_message_import;
-#define gpr_log_message gpr_log_message_import
-typedef void(*gpr_set_log_verbosity_type)(gpr_log_severity min_severity_to_print);
-extern gpr_set_log_verbosity_type gpr_set_log_verbosity_import;
-#define gpr_set_log_verbosity gpr_set_log_verbosity_import
-typedef void(*gpr_log_verbosity_init_type)();
-extern gpr_log_verbosity_init_type gpr_log_verbosity_init_import;
-#define gpr_log_verbosity_init gpr_log_verbosity_init_import
-typedef void(*gpr_set_log_function_type)(gpr_log_func func);
-extern gpr_set_log_function_type gpr_set_log_function_import;
-#define gpr_set_log_function gpr_set_log_function_import
-typedef gpr_slice(*gpr_slice_ref_type)(gpr_slice s);
-extern gpr_slice_ref_type gpr_slice_ref_import;
-#define gpr_slice_ref gpr_slice_ref_import
-typedef void(*gpr_slice_unref_type)(gpr_slice s);
-extern gpr_slice_unref_type gpr_slice_unref_import;
-#define gpr_slice_unref gpr_slice_unref_import
-typedef gpr_slice(*gpr_slice_new_type)(void *p, size_t len, void (*destroy)(void *));
-extern gpr_slice_new_type gpr_slice_new_import;
-#define gpr_slice_new gpr_slice_new_import
-typedef gpr_slice(*gpr_slice_new_with_user_data_type)(void *p, size_t len, void (*destroy)(void *), void *user_data);
-extern gpr_slice_new_with_user_data_type gpr_slice_new_with_user_data_import;
-#define gpr_slice_new_with_user_data gpr_slice_new_with_user_data_import
-typedef gpr_slice(*gpr_slice_new_with_len_type)(void *p, size_t len, void (*destroy)(void *, size_t));
-extern gpr_slice_new_with_len_type gpr_slice_new_with_len_import;
-#define gpr_slice_new_with_len gpr_slice_new_with_len_import
-typedef gpr_slice(*gpr_slice_malloc_type)(size_t length);
-extern gpr_slice_malloc_type gpr_slice_malloc_import;
-#define gpr_slice_malloc gpr_slice_malloc_import
-typedef gpr_slice(*gpr_slice_from_copied_string_type)(const char *source);
-extern gpr_slice_from_copied_string_type gpr_slice_from_copied_string_import;
-#define gpr_slice_from_copied_string gpr_slice_from_copied_string_import
-typedef gpr_slice(*gpr_slice_from_copied_buffer_type)(const char *source, size_t len);
-extern gpr_slice_from_copied_buffer_type gpr_slice_from_copied_buffer_import;
-#define gpr_slice_from_copied_buffer gpr_slice_from_copied_buffer_import
-typedef gpr_slice(*gpr_slice_from_static_string_type)(const char *source);
-extern gpr_slice_from_static_string_type gpr_slice_from_static_string_import;
-#define gpr_slice_from_static_string gpr_slice_from_static_string_import
-typedef gpr_slice(*gpr_slice_sub_type)(gpr_slice s, size_t begin, size_t end);
-extern gpr_slice_sub_type gpr_slice_sub_import;
-#define gpr_slice_sub gpr_slice_sub_import
-typedef gpr_slice(*gpr_slice_sub_no_ref_type)(gpr_slice s, size_t begin, size_t end);
-extern gpr_slice_sub_no_ref_type gpr_slice_sub_no_ref_import;
-#define gpr_slice_sub_no_ref gpr_slice_sub_no_ref_import
-typedef gpr_slice(*gpr_slice_split_tail_type)(gpr_slice *s, size_t split);
-extern gpr_slice_split_tail_type gpr_slice_split_tail_import;
-#define gpr_slice_split_tail gpr_slice_split_tail_import
-typedef gpr_slice(*gpr_slice_split_head_type)(gpr_slice *s, size_t split);
-extern gpr_slice_split_head_type gpr_slice_split_head_import;
-#define gpr_slice_split_head gpr_slice_split_head_import
-typedef gpr_slice(*gpr_empty_slice_type)(void);
-extern gpr_empty_slice_type gpr_empty_slice_import;
-#define gpr_empty_slice gpr_empty_slice_import
-typedef int(*gpr_slice_cmp_type)(gpr_slice a, gpr_slice b);
-extern gpr_slice_cmp_type gpr_slice_cmp_import;
-#define gpr_slice_cmp gpr_slice_cmp_import
-typedef int(*gpr_slice_str_cmp_type)(gpr_slice a, const char *b);
-extern gpr_slice_str_cmp_type gpr_slice_str_cmp_import;
-#define gpr_slice_str_cmp gpr_slice_str_cmp_import
-typedef void(*gpr_slice_buffer_init_type)(gpr_slice_buffer *sb);
-extern gpr_slice_buffer_init_type gpr_slice_buffer_init_import;
-#define gpr_slice_buffer_init gpr_slice_buffer_init_import
-typedef void(*gpr_slice_buffer_destroy_type)(gpr_slice_buffer *sb);
-extern gpr_slice_buffer_destroy_type gpr_slice_buffer_destroy_import;
-#define gpr_slice_buffer_destroy gpr_slice_buffer_destroy_import
-typedef void(*gpr_slice_buffer_add_type)(gpr_slice_buffer *sb, gpr_slice slice);
-extern gpr_slice_buffer_add_type gpr_slice_buffer_add_import;
-#define gpr_slice_buffer_add gpr_slice_buffer_add_import
-typedef size_t(*gpr_slice_buffer_add_indexed_type)(gpr_slice_buffer *sb, gpr_slice slice);
-extern gpr_slice_buffer_add_indexed_type gpr_slice_buffer_add_indexed_import;
-#define gpr_slice_buffer_add_indexed gpr_slice_buffer_add_indexed_import
-typedef void(*gpr_slice_buffer_addn_type)(gpr_slice_buffer *sb, gpr_slice *slices, size_t n);
-extern gpr_slice_buffer_addn_type gpr_slice_buffer_addn_import;
-#define gpr_slice_buffer_addn gpr_slice_buffer_addn_import
-typedef uint8_t *(*gpr_slice_buffer_tiny_add_type)(gpr_slice_buffer *sb, size_t len);
-extern gpr_slice_buffer_tiny_add_type gpr_slice_buffer_tiny_add_import;
-#define gpr_slice_buffer_tiny_add gpr_slice_buffer_tiny_add_import
-typedef void(*gpr_slice_buffer_pop_type)(gpr_slice_buffer *sb);
-extern gpr_slice_buffer_pop_type gpr_slice_buffer_pop_import;
-#define gpr_slice_buffer_pop gpr_slice_buffer_pop_import
-typedef void(*gpr_slice_buffer_reset_and_unref_type)(gpr_slice_buffer *sb);
-extern gpr_slice_buffer_reset_and_unref_type gpr_slice_buffer_reset_and_unref_import;
-#define gpr_slice_buffer_reset_and_unref gpr_slice_buffer_reset_and_unref_import
-typedef void(*gpr_slice_buffer_swap_type)(gpr_slice_buffer *a, gpr_slice_buffer *b);
-extern gpr_slice_buffer_swap_type gpr_slice_buffer_swap_import;
-#define gpr_slice_buffer_swap gpr_slice_buffer_swap_import
-typedef void(*gpr_slice_buffer_move_into_type)(gpr_slice_buffer *src, gpr_slice_buffer *dst);
-extern gpr_slice_buffer_move_into_type gpr_slice_buffer_move_into_import;
-#define gpr_slice_buffer_move_into gpr_slice_buffer_move_into_import
-typedef void(*gpr_slice_buffer_trim_end_type)(gpr_slice_buffer *src, size_t n, gpr_slice_buffer *garbage);
-extern gpr_slice_buffer_trim_end_type gpr_slice_buffer_trim_end_import;
-#define gpr_slice_buffer_trim_end gpr_slice_buffer_trim_end_import
-typedef void(*gpr_slice_buffer_move_first_type)(gpr_slice_buffer *src, size_t n, gpr_slice_buffer *dst);
-extern gpr_slice_buffer_move_first_type gpr_slice_buffer_move_first_import;
-#define gpr_slice_buffer_move_first gpr_slice_buffer_move_first_import
-typedef gpr_slice(*gpr_slice_buffer_take_first_type)(gpr_slice_buffer *src);
-extern gpr_slice_buffer_take_first_type gpr_slice_buffer_take_first_import;
-#define gpr_slice_buffer_take_first gpr_slice_buffer_take_first_import
-typedef void(*gpr_mu_init_type)(gpr_mu *mu);
-extern gpr_mu_init_type gpr_mu_init_import;
-#define gpr_mu_init gpr_mu_init_import
-typedef void(*gpr_mu_destroy_type)(gpr_mu *mu);
-extern gpr_mu_destroy_type gpr_mu_destroy_import;
-#define gpr_mu_destroy gpr_mu_destroy_import
-typedef void(*gpr_mu_lock_type)(gpr_mu *mu);
-extern gpr_mu_lock_type gpr_mu_lock_import;
-#define gpr_mu_lock gpr_mu_lock_import
-typedef void(*gpr_mu_unlock_type)(gpr_mu *mu);
-extern gpr_mu_unlock_type gpr_mu_unlock_import;
-#define gpr_mu_unlock gpr_mu_unlock_import
-typedef int(*gpr_mu_trylock_type)(gpr_mu *mu);
-extern gpr_mu_trylock_type gpr_mu_trylock_import;
-#define gpr_mu_trylock gpr_mu_trylock_import
-typedef void(*gpr_cv_init_type)(gpr_cv *cv);
-extern gpr_cv_init_type gpr_cv_init_import;
-#define gpr_cv_init gpr_cv_init_import
-typedef void(*gpr_cv_destroy_type)(gpr_cv *cv);
-extern gpr_cv_destroy_type gpr_cv_destroy_import;
-#define gpr_cv_destroy gpr_cv_destroy_import
-typedef int(*gpr_cv_wait_type)(gpr_cv *cv, gpr_mu *mu, gpr_timespec abs_deadline);
-extern gpr_cv_wait_type gpr_cv_wait_import;
-#define gpr_cv_wait gpr_cv_wait_import
-typedef void(*gpr_cv_signal_type)(gpr_cv *cv);
-extern gpr_cv_signal_type gpr_cv_signal_import;
-#define gpr_cv_signal gpr_cv_signal_import
-typedef void(*gpr_cv_broadcast_type)(gpr_cv *cv);
-extern gpr_cv_broadcast_type gpr_cv_broadcast_import;
-#define gpr_cv_broadcast gpr_cv_broadcast_import
-typedef void(*gpr_once_init_type)(gpr_once *once, void (*init_routine)(void));
-extern gpr_once_init_type gpr_once_init_import;
-#define gpr_once_init gpr_once_init_import
-typedef void(*gpr_event_init_type)(gpr_event *ev);
-extern gpr_event_init_type gpr_event_init_import;
-#define gpr_event_init gpr_event_init_import
-typedef void(*gpr_event_set_type)(gpr_event *ev, void *value);
-extern gpr_event_set_type gpr_event_set_import;
-#define gpr_event_set gpr_event_set_import
-typedef void *(*gpr_event_get_type)(gpr_event *ev);
-extern gpr_event_get_type gpr_event_get_import;
-#define gpr_event_get gpr_event_get_import
-typedef void *(*gpr_event_wait_type)(gpr_event *ev, gpr_timespec abs_deadline);
-extern gpr_event_wait_type gpr_event_wait_import;
-#define gpr_event_wait gpr_event_wait_import
-typedef void(*gpr_ref_init_type)(gpr_refcount *r, int n);
-extern gpr_ref_init_type gpr_ref_init_import;
-#define gpr_ref_init gpr_ref_init_import
-typedef void(*gpr_ref_type)(gpr_refcount *r);
-extern gpr_ref_type gpr_ref_import;
-#define gpr_ref gpr_ref_import
-typedef void(*gpr_ref_non_zero_type)(gpr_refcount *r);
-extern gpr_ref_non_zero_type gpr_ref_non_zero_import;
-#define gpr_ref_non_zero gpr_ref_non_zero_import
-typedef void(*gpr_refn_type)(gpr_refcount *r, int n);
-extern gpr_refn_type gpr_refn_import;
-#define gpr_refn gpr_refn_import
-typedef int(*gpr_unref_type)(gpr_refcount *r);
-extern gpr_unref_type gpr_unref_import;
-#define gpr_unref gpr_unref_import
-typedef void(*gpr_stats_init_type)(gpr_stats_counter *c, intptr_t n);
-extern gpr_stats_init_type gpr_stats_init_import;
-#define gpr_stats_init gpr_stats_init_import
-typedef void(*gpr_stats_inc_type)(gpr_stats_counter *c, intptr_t inc);
-extern gpr_stats_inc_type gpr_stats_inc_import;
-#define gpr_stats_inc gpr_stats_inc_import
-typedef intptr_t(*gpr_stats_read_type)(const gpr_stats_counter *c);
-extern gpr_stats_read_type gpr_stats_read_import;
-#define gpr_stats_read gpr_stats_read_import
-typedef gpr_timespec(*gpr_time_0_type)(gpr_clock_type type);
-extern gpr_time_0_type gpr_time_0_import;
-#define gpr_time_0 gpr_time_0_import
-typedef gpr_timespec(*gpr_inf_future_type)(gpr_clock_type type);
-extern gpr_inf_future_type gpr_inf_future_import;
-#define gpr_inf_future gpr_inf_future_import
-typedef gpr_timespec(*gpr_inf_past_type)(gpr_clock_type type);
-extern gpr_inf_past_type gpr_inf_past_import;
-#define gpr_inf_past gpr_inf_past_import
-typedef void(*gpr_time_init_type)(void);
-extern gpr_time_init_type gpr_time_init_import;
-#define gpr_time_init gpr_time_init_import
-typedef gpr_timespec(*gpr_now_type)(gpr_clock_type clock);
-extern gpr_now_type gpr_now_import;
-#define gpr_now gpr_now_import
-typedef gpr_timespec(*gpr_convert_clock_type_type)(gpr_timespec t, gpr_clock_type target_clock);
-extern gpr_convert_clock_type_type gpr_convert_clock_type_import;
-#define gpr_convert_clock_type gpr_convert_clock_type_import
-typedef int(*gpr_time_cmp_type)(gpr_timespec a, gpr_timespec b);
-extern gpr_time_cmp_type gpr_time_cmp_import;
-#define gpr_time_cmp gpr_time_cmp_import
-typedef gpr_timespec(*gpr_time_max_type)(gpr_timespec a, gpr_timespec b);
-extern gpr_time_max_type gpr_time_max_import;
-#define gpr_time_max gpr_time_max_import
-typedef gpr_timespec(*gpr_time_min_type)(gpr_timespec a, gpr_timespec b);
-extern gpr_time_min_type gpr_time_min_import;
-#define gpr_time_min gpr_time_min_import
-typedef gpr_timespec(*gpr_time_add_type)(gpr_timespec a, gpr_timespec b);
-extern gpr_time_add_type gpr_time_add_import;
-#define gpr_time_add gpr_time_add_import
-typedef gpr_timespec(*gpr_time_sub_type)(gpr_timespec a, gpr_timespec b);
-extern gpr_time_sub_type gpr_time_sub_import;
-#define gpr_time_sub gpr_time_sub_import
-typedef gpr_timespec(*gpr_time_from_micros_type)(int64_t x, gpr_clock_type clock_type);
-extern gpr_time_from_micros_type gpr_time_from_micros_import;
-#define gpr_time_from_micros gpr_time_from_micros_import
-typedef gpr_timespec(*gpr_time_from_nanos_type)(int64_t x, gpr_clock_type clock_type);
-extern gpr_time_from_nanos_type gpr_time_from_nanos_import;
-#define gpr_time_from_nanos gpr_time_from_nanos_import
-typedef gpr_timespec(*gpr_time_from_millis_type)(int64_t x, gpr_clock_type clock_type);
-extern gpr_time_from_millis_type gpr_time_from_millis_import;
-#define gpr_time_from_millis gpr_time_from_millis_import
-typedef gpr_timespec(*gpr_time_from_seconds_type)(int64_t x, gpr_clock_type clock_type);
-extern gpr_time_from_seconds_type gpr_time_from_seconds_import;
-#define gpr_time_from_seconds gpr_time_from_seconds_import
-typedef gpr_timespec(*gpr_time_from_minutes_type)(int64_t x, gpr_clock_type clock_type);
-extern gpr_time_from_minutes_type gpr_time_from_minutes_import;
-#define gpr_time_from_minutes gpr_time_from_minutes_import
-typedef gpr_timespec(*gpr_time_from_hours_type)(int64_t x, gpr_clock_type clock_type);
-extern gpr_time_from_hours_type gpr_time_from_hours_import;
-#define gpr_time_from_hours gpr_time_from_hours_import
-typedef int32_t(*gpr_time_to_millis_type)(gpr_timespec timespec);
-extern gpr_time_to_millis_type gpr_time_to_millis_import;
-#define gpr_time_to_millis gpr_time_to_millis_import
-typedef int(*gpr_time_similar_type)(gpr_timespec a, gpr_timespec b, gpr_timespec threshold);
-extern gpr_time_similar_type gpr_time_similar_import;
-#define gpr_time_similar gpr_time_similar_import
-typedef void(*gpr_sleep_until_type)(gpr_timespec until);
-extern gpr_sleep_until_type gpr_sleep_until_import;
-#define gpr_sleep_until gpr_sleep_until_import
-typedef double(*gpr_timespec_to_micros_type)(gpr_timespec t);
-extern gpr_timespec_to_micros_type gpr_timespec_to_micros_import;
-#define gpr_timespec_to_micros gpr_timespec_to_micros_import
 typedef gpr_avl(*gpr_avl_create_type)(const gpr_avl_vtable *vtable);
 extern gpr_avl_create_type gpr_avl_create_import;
 #define gpr_avl_create gpr_avl_create_import
@@ -815,9 +581,111 @@
 typedef int(*gpr_split_host_port_type)(const char *name, char **host, char **port);
 extern gpr_split_host_port_type gpr_split_host_port_import;
 #define gpr_split_host_port gpr_split_host_port_import
+typedef void(*gpr_log_type)(const char *file, int line, gpr_log_severity severity, const char *format, ...) GPRC_PRINT_FORMAT_CHECK(4, 5);
+extern gpr_log_type gpr_log_import;
+#define gpr_log gpr_log_import
+typedef void(*gpr_log_message_type)(const char *file, int line, gpr_log_severity severity, const char *message);
+extern gpr_log_message_type gpr_log_message_import;
+#define gpr_log_message gpr_log_message_import
+typedef void(*gpr_set_log_verbosity_type)(gpr_log_severity min_severity_to_print);
+extern gpr_set_log_verbosity_type gpr_set_log_verbosity_import;
+#define gpr_set_log_verbosity gpr_set_log_verbosity_import
+typedef void(*gpr_log_verbosity_init_type)();
+extern gpr_log_verbosity_init_type gpr_log_verbosity_init_import;
+#define gpr_log_verbosity_init gpr_log_verbosity_init_import
+typedef void(*gpr_set_log_function_type)(gpr_log_func func);
+extern gpr_set_log_function_type gpr_set_log_function_import;
+#define gpr_set_log_function gpr_set_log_function_import
 typedef char *(*gpr_format_message_type)(int messageid);
 extern gpr_format_message_type gpr_format_message_import;
 #define gpr_format_message gpr_format_message_import
+typedef gpr_slice(*gpr_slice_ref_type)(gpr_slice s);
+extern gpr_slice_ref_type gpr_slice_ref_import;
+#define gpr_slice_ref gpr_slice_ref_import
+typedef void(*gpr_slice_unref_type)(gpr_slice s);
+extern gpr_slice_unref_type gpr_slice_unref_import;
+#define gpr_slice_unref gpr_slice_unref_import
+typedef gpr_slice(*gpr_slice_new_type)(void *p, size_t len, void (*destroy)(void *));
+extern gpr_slice_new_type gpr_slice_new_import;
+#define gpr_slice_new gpr_slice_new_import
+typedef gpr_slice(*gpr_slice_new_with_user_data_type)(void *p, size_t len, void (*destroy)(void *), void *user_data);
+extern gpr_slice_new_with_user_data_type gpr_slice_new_with_user_data_import;
+#define gpr_slice_new_with_user_data gpr_slice_new_with_user_data_import
+typedef gpr_slice(*gpr_slice_new_with_len_type)(void *p, size_t len, void (*destroy)(void *, size_t));
+extern gpr_slice_new_with_len_type gpr_slice_new_with_len_import;
+#define gpr_slice_new_with_len gpr_slice_new_with_len_import
+typedef gpr_slice(*gpr_slice_malloc_type)(size_t length);
+extern gpr_slice_malloc_type gpr_slice_malloc_import;
+#define gpr_slice_malloc gpr_slice_malloc_import
+typedef gpr_slice(*gpr_slice_from_copied_string_type)(const char *source);
+extern gpr_slice_from_copied_string_type gpr_slice_from_copied_string_import;
+#define gpr_slice_from_copied_string gpr_slice_from_copied_string_import
+typedef gpr_slice(*gpr_slice_from_copied_buffer_type)(const char *source, size_t len);
+extern gpr_slice_from_copied_buffer_type gpr_slice_from_copied_buffer_import;
+#define gpr_slice_from_copied_buffer gpr_slice_from_copied_buffer_import
+typedef gpr_slice(*gpr_slice_from_static_string_type)(const char *source);
+extern gpr_slice_from_static_string_type gpr_slice_from_static_string_import;
+#define gpr_slice_from_static_string gpr_slice_from_static_string_import
+typedef gpr_slice(*gpr_slice_sub_type)(gpr_slice s, size_t begin, size_t end);
+extern gpr_slice_sub_type gpr_slice_sub_import;
+#define gpr_slice_sub gpr_slice_sub_import
+typedef gpr_slice(*gpr_slice_sub_no_ref_type)(gpr_slice s, size_t begin, size_t end);
+extern gpr_slice_sub_no_ref_type gpr_slice_sub_no_ref_import;
+#define gpr_slice_sub_no_ref gpr_slice_sub_no_ref_import
+typedef gpr_slice(*gpr_slice_split_tail_type)(gpr_slice *s, size_t split);
+extern gpr_slice_split_tail_type gpr_slice_split_tail_import;
+#define gpr_slice_split_tail gpr_slice_split_tail_import
+typedef gpr_slice(*gpr_slice_split_head_type)(gpr_slice *s, size_t split);
+extern gpr_slice_split_head_type gpr_slice_split_head_import;
+#define gpr_slice_split_head gpr_slice_split_head_import
+typedef gpr_slice(*gpr_empty_slice_type)(void);
+extern gpr_empty_slice_type gpr_empty_slice_import;
+#define gpr_empty_slice gpr_empty_slice_import
+typedef int(*gpr_slice_cmp_type)(gpr_slice a, gpr_slice b);
+extern gpr_slice_cmp_type gpr_slice_cmp_import;
+#define gpr_slice_cmp gpr_slice_cmp_import
+typedef int(*gpr_slice_str_cmp_type)(gpr_slice a, const char *b);
+extern gpr_slice_str_cmp_type gpr_slice_str_cmp_import;
+#define gpr_slice_str_cmp gpr_slice_str_cmp_import
+typedef void(*gpr_slice_buffer_init_type)(gpr_slice_buffer *sb);
+extern gpr_slice_buffer_init_type gpr_slice_buffer_init_import;
+#define gpr_slice_buffer_init gpr_slice_buffer_init_import
+typedef void(*gpr_slice_buffer_destroy_type)(gpr_slice_buffer *sb);
+extern gpr_slice_buffer_destroy_type gpr_slice_buffer_destroy_import;
+#define gpr_slice_buffer_destroy gpr_slice_buffer_destroy_import
+typedef void(*gpr_slice_buffer_add_type)(gpr_slice_buffer *sb, gpr_slice slice);
+extern gpr_slice_buffer_add_type gpr_slice_buffer_add_import;
+#define gpr_slice_buffer_add gpr_slice_buffer_add_import
+typedef size_t(*gpr_slice_buffer_add_indexed_type)(gpr_slice_buffer *sb, gpr_slice slice);
+extern gpr_slice_buffer_add_indexed_type gpr_slice_buffer_add_indexed_import;
+#define gpr_slice_buffer_add_indexed gpr_slice_buffer_add_indexed_import
+typedef void(*gpr_slice_buffer_addn_type)(gpr_slice_buffer *sb, gpr_slice *slices, size_t n);
+extern gpr_slice_buffer_addn_type gpr_slice_buffer_addn_import;
+#define gpr_slice_buffer_addn gpr_slice_buffer_addn_import
+typedef uint8_t *(*gpr_slice_buffer_tiny_add_type)(gpr_slice_buffer *sb, size_t len);
+extern gpr_slice_buffer_tiny_add_type gpr_slice_buffer_tiny_add_import;
+#define gpr_slice_buffer_tiny_add gpr_slice_buffer_tiny_add_import
+typedef void(*gpr_slice_buffer_pop_type)(gpr_slice_buffer *sb);
+extern gpr_slice_buffer_pop_type gpr_slice_buffer_pop_import;
+#define gpr_slice_buffer_pop gpr_slice_buffer_pop_import
+typedef void(*gpr_slice_buffer_reset_and_unref_type)(gpr_slice_buffer *sb);
+extern gpr_slice_buffer_reset_and_unref_type gpr_slice_buffer_reset_and_unref_import;
+#define gpr_slice_buffer_reset_and_unref gpr_slice_buffer_reset_and_unref_import
+typedef void(*gpr_slice_buffer_swap_type)(gpr_slice_buffer *a, gpr_slice_buffer *b);
+extern gpr_slice_buffer_swap_type gpr_slice_buffer_swap_import;
+#define gpr_slice_buffer_swap gpr_slice_buffer_swap_import
+typedef void(*gpr_slice_buffer_move_into_type)(gpr_slice_buffer *src, gpr_slice_buffer *dst);
+extern gpr_slice_buffer_move_into_type gpr_slice_buffer_move_into_import;
+#define gpr_slice_buffer_move_into gpr_slice_buffer_move_into_import
+typedef void(*gpr_slice_buffer_trim_end_type)(gpr_slice_buffer *src, size_t n, gpr_slice_buffer *garbage);
+extern gpr_slice_buffer_trim_end_type gpr_slice_buffer_trim_end_import;
+#define gpr_slice_buffer_trim_end gpr_slice_buffer_trim_end_import
+typedef void(*gpr_slice_buffer_move_first_type)(gpr_slice_buffer *src, size_t n, gpr_slice_buffer *dst);
+extern gpr_slice_buffer_move_first_type gpr_slice_buffer_move_first_import;
+#define gpr_slice_buffer_move_first gpr_slice_buffer_move_first_import
+typedef gpr_slice(*gpr_slice_buffer_take_first_type)(gpr_slice_buffer *src);
+extern gpr_slice_buffer_take_first_type gpr_slice_buffer_take_first_import;
+#define gpr_slice_buffer_take_first gpr_slice_buffer_take_first_import
 typedef char *(*gpr_strdup_type)(const char *src);
 extern gpr_strdup_type gpr_strdup_import;
 #define gpr_strdup gpr_strdup_import
@@ -839,6 +707,75 @@
 typedef void(*gpr_subprocess_interrupt_type)(gpr_subprocess *p);
 extern gpr_subprocess_interrupt_type gpr_subprocess_interrupt_import;
 #define gpr_subprocess_interrupt gpr_subprocess_interrupt_import
+typedef void(*gpr_mu_init_type)(gpr_mu *mu);
+extern gpr_mu_init_type gpr_mu_init_import;
+#define gpr_mu_init gpr_mu_init_import
+typedef void(*gpr_mu_destroy_type)(gpr_mu *mu);
+extern gpr_mu_destroy_type gpr_mu_destroy_import;
+#define gpr_mu_destroy gpr_mu_destroy_import
+typedef void(*gpr_mu_lock_type)(gpr_mu *mu);
+extern gpr_mu_lock_type gpr_mu_lock_import;
+#define gpr_mu_lock gpr_mu_lock_import
+typedef void(*gpr_mu_unlock_type)(gpr_mu *mu);
+extern gpr_mu_unlock_type gpr_mu_unlock_import;
+#define gpr_mu_unlock gpr_mu_unlock_import
+typedef int(*gpr_mu_trylock_type)(gpr_mu *mu);
+extern gpr_mu_trylock_type gpr_mu_trylock_import;
+#define gpr_mu_trylock gpr_mu_trylock_import
+typedef void(*gpr_cv_init_type)(gpr_cv *cv);
+extern gpr_cv_init_type gpr_cv_init_import;
+#define gpr_cv_init gpr_cv_init_import
+typedef void(*gpr_cv_destroy_type)(gpr_cv *cv);
+extern gpr_cv_destroy_type gpr_cv_destroy_import;
+#define gpr_cv_destroy gpr_cv_destroy_import
+typedef int(*gpr_cv_wait_type)(gpr_cv *cv, gpr_mu *mu, gpr_timespec abs_deadline);
+extern gpr_cv_wait_type gpr_cv_wait_import;
+#define gpr_cv_wait gpr_cv_wait_import
+typedef void(*gpr_cv_signal_type)(gpr_cv *cv);
+extern gpr_cv_signal_type gpr_cv_signal_import;
+#define gpr_cv_signal gpr_cv_signal_import
+typedef void(*gpr_cv_broadcast_type)(gpr_cv *cv);
+extern gpr_cv_broadcast_type gpr_cv_broadcast_import;
+#define gpr_cv_broadcast gpr_cv_broadcast_import
+typedef void(*gpr_once_init_type)(gpr_once *once, void (*init_routine)(void));
+extern gpr_once_init_type gpr_once_init_import;
+#define gpr_once_init gpr_once_init_import
+typedef void(*gpr_event_init_type)(gpr_event *ev);
+extern gpr_event_init_type gpr_event_init_import;
+#define gpr_event_init gpr_event_init_import
+typedef void(*gpr_event_set_type)(gpr_event *ev, void *value);
+extern gpr_event_set_type gpr_event_set_import;
+#define gpr_event_set gpr_event_set_import
+typedef void *(*gpr_event_get_type)(gpr_event *ev);
+extern gpr_event_get_type gpr_event_get_import;
+#define gpr_event_get gpr_event_get_import
+typedef void *(*gpr_event_wait_type)(gpr_event *ev, gpr_timespec abs_deadline);
+extern gpr_event_wait_type gpr_event_wait_import;
+#define gpr_event_wait gpr_event_wait_import
+typedef void(*gpr_ref_init_type)(gpr_refcount *r, int n);
+extern gpr_ref_init_type gpr_ref_init_import;
+#define gpr_ref_init gpr_ref_init_import
+typedef void(*gpr_ref_type)(gpr_refcount *r);
+extern gpr_ref_type gpr_ref_import;
+#define gpr_ref gpr_ref_import
+typedef void(*gpr_ref_non_zero_type)(gpr_refcount *r);
+extern gpr_ref_non_zero_type gpr_ref_non_zero_import;
+#define gpr_ref_non_zero gpr_ref_non_zero_import
+typedef void(*gpr_refn_type)(gpr_refcount *r, int n);
+extern gpr_refn_type gpr_refn_import;
+#define gpr_refn gpr_refn_import
+typedef int(*gpr_unref_type)(gpr_refcount *r);
+extern gpr_unref_type gpr_unref_import;
+#define gpr_unref gpr_unref_import
+typedef void(*gpr_stats_init_type)(gpr_stats_counter *c, intptr_t n);
+extern gpr_stats_init_type gpr_stats_init_import;
+#define gpr_stats_init gpr_stats_init_import
+typedef void(*gpr_stats_inc_type)(gpr_stats_counter *c, intptr_t inc);
+extern gpr_stats_inc_type gpr_stats_inc_import;
+#define gpr_stats_inc gpr_stats_inc_import
+typedef intptr_t(*gpr_stats_read_type)(const gpr_stats_counter *c);
+extern gpr_stats_read_type gpr_stats_read_import;
+#define gpr_stats_read gpr_stats_read_import
 typedef int(*gpr_thd_new_type)(gpr_thd_id *t, void (*thd_body)(void *arg), void *arg, const gpr_thd_options *options);
 extern gpr_thd_new_type gpr_thd_new_import;
 #define gpr_thd_new gpr_thd_new_import
@@ -863,6 +800,69 @@
 typedef void(*gpr_thd_join_type)(gpr_thd_id t);
 extern gpr_thd_join_type gpr_thd_join_import;
 #define gpr_thd_join gpr_thd_join_import
+typedef gpr_timespec(*gpr_time_0_type)(gpr_clock_type type);
+extern gpr_time_0_type gpr_time_0_import;
+#define gpr_time_0 gpr_time_0_import
+typedef gpr_timespec(*gpr_inf_future_type)(gpr_clock_type type);
+extern gpr_inf_future_type gpr_inf_future_import;
+#define gpr_inf_future gpr_inf_future_import
+typedef gpr_timespec(*gpr_inf_past_type)(gpr_clock_type type);
+extern gpr_inf_past_type gpr_inf_past_import;
+#define gpr_inf_past gpr_inf_past_import
+typedef void(*gpr_time_init_type)(void);
+extern gpr_time_init_type gpr_time_init_import;
+#define gpr_time_init gpr_time_init_import
+typedef gpr_timespec(*gpr_now_type)(gpr_clock_type clock);
+extern gpr_now_type gpr_now_import;
+#define gpr_now gpr_now_import
+typedef gpr_timespec(*gpr_convert_clock_type_type)(gpr_timespec t, gpr_clock_type target_clock);
+extern gpr_convert_clock_type_type gpr_convert_clock_type_import;
+#define gpr_convert_clock_type gpr_convert_clock_type_import
+typedef int(*gpr_time_cmp_type)(gpr_timespec a, gpr_timespec b);
+extern gpr_time_cmp_type gpr_time_cmp_import;
+#define gpr_time_cmp gpr_time_cmp_import
+typedef gpr_timespec(*gpr_time_max_type)(gpr_timespec a, gpr_timespec b);
+extern gpr_time_max_type gpr_time_max_import;
+#define gpr_time_max gpr_time_max_import
+typedef gpr_timespec(*gpr_time_min_type)(gpr_timespec a, gpr_timespec b);
+extern gpr_time_min_type gpr_time_min_import;
+#define gpr_time_min gpr_time_min_import
+typedef gpr_timespec(*gpr_time_add_type)(gpr_timespec a, gpr_timespec b);
+extern gpr_time_add_type gpr_time_add_import;
+#define gpr_time_add gpr_time_add_import
+typedef gpr_timespec(*gpr_time_sub_type)(gpr_timespec a, gpr_timespec b);
+extern gpr_time_sub_type gpr_time_sub_import;
+#define gpr_time_sub gpr_time_sub_import
+typedef gpr_timespec(*gpr_time_from_micros_type)(int64_t x, gpr_clock_type clock_type);
+extern gpr_time_from_micros_type gpr_time_from_micros_import;
+#define gpr_time_from_micros gpr_time_from_micros_import
+typedef gpr_timespec(*gpr_time_from_nanos_type)(int64_t x, gpr_clock_type clock_type);
+extern gpr_time_from_nanos_type gpr_time_from_nanos_import;
+#define gpr_time_from_nanos gpr_time_from_nanos_import
+typedef gpr_timespec(*gpr_time_from_millis_type)(int64_t x, gpr_clock_type clock_type);
+extern gpr_time_from_millis_type gpr_time_from_millis_import;
+#define gpr_time_from_millis gpr_time_from_millis_import
+typedef gpr_timespec(*gpr_time_from_seconds_type)(int64_t x, gpr_clock_type clock_type);
+extern gpr_time_from_seconds_type gpr_time_from_seconds_import;
+#define gpr_time_from_seconds gpr_time_from_seconds_import
+typedef gpr_timespec(*gpr_time_from_minutes_type)(int64_t x, gpr_clock_type clock_type);
+extern gpr_time_from_minutes_type gpr_time_from_minutes_import;
+#define gpr_time_from_minutes gpr_time_from_minutes_import
+typedef gpr_timespec(*gpr_time_from_hours_type)(int64_t x, gpr_clock_type clock_type);
+extern gpr_time_from_hours_type gpr_time_from_hours_import;
+#define gpr_time_from_hours gpr_time_from_hours_import
+typedef int32_t(*gpr_time_to_millis_type)(gpr_timespec timespec);
+extern gpr_time_to_millis_type gpr_time_to_millis_import;
+#define gpr_time_to_millis gpr_time_to_millis_import
+typedef int(*gpr_time_similar_type)(gpr_timespec a, gpr_timespec b, gpr_timespec threshold);
+extern gpr_time_similar_type gpr_time_similar_import;
+#define gpr_time_similar gpr_time_similar_import
+typedef void(*gpr_sleep_until_type)(gpr_timespec until);
+extern gpr_sleep_until_type gpr_sleep_until_import;
+#define gpr_sleep_until gpr_sleep_until_import
+typedef double(*gpr_timespec_to_micros_type)(gpr_timespec t);
+extern gpr_timespec_to_micros_type gpr_timespec_to_micros_import;
+#define gpr_timespec_to_micros gpr_timespec_to_micros_import
 
 void grpc_rb_load_imports(HMODULE library);
 
diff --git a/src/ruby/lib/grpc/generic/rpc_server.rb b/src/ruby/lib/grpc/generic/rpc_server.rb
index 8ea798d..da0f650 100644
--- a/src/ruby/lib/grpc/generic/rpc_server.rb
+++ b/src/ruby/lib/grpc/generic/rpc_server.rb
@@ -31,113 +31,10 @@
 require_relative 'active_call'
 require_relative 'service'
 require 'thread'
+require 'concurrent'
 
 # GRPC contains the General RPC module.
 module GRPC
-  # Pool is a simple thread pool.
-  class Pool
-    # Default keep alive period is 1s
-    DEFAULT_KEEP_ALIVE = 1
-
-    def initialize(size, keep_alive: DEFAULT_KEEP_ALIVE)
-      fail 'pool size must be positive' unless size > 0
-      @jobs = Queue.new
-      @size = size
-      @stopped = false
-      @stop_mutex = Mutex.new # needs to be held when accessing @stopped
-      @stop_cond = ConditionVariable.new
-      @workers = []
-      @keep_alive = keep_alive
-    end
-
-    # Returns the number of jobs waiting
-    def jobs_waiting
-      @jobs.size
-    end
-
-    # Runs the given block on the queue with the provided args.
-    #
-    # @param args the args passed blk when it is called
-    # @param blk the block to call
-    def schedule(*args, &blk)
-      return if blk.nil?
-      @stop_mutex.synchronize do
-        if @stopped
-          GRPC.logger.warn('did not schedule job, already stopped')
-          return
-        end
-        GRPC.logger.info('schedule another job')
-        @jobs << [blk, args]
-      end
-    end
-
-    # Starts running the jobs in the thread pool.
-    def start
-      @stop_mutex.synchronize do
-        fail 'already stopped' if @stopped
-      end
-      until @workers.size == @size.to_i
-        next_thread = Thread.new do
-          catch(:exit) do  # allows { throw :exit } to kill a thread
-            loop_execute_jobs
-          end
-          remove_current_thread
-        end
-        @workers << next_thread
-      end
-    end
-
-    # Stops the jobs in the pool
-    def stop
-      GRPC.logger.info('stopping, will wait for all the workers to exit')
-      @workers.size.times { schedule { throw :exit } }
-      @stop_mutex.synchronize do  # wait @keep_alive for works to stop
-        @stopped = true
-        @stop_cond.wait(@stop_mutex, @keep_alive) if @workers.size > 0
-      end
-      forcibly_stop_workers
-      GRPC.logger.info('stopped, all workers are shutdown')
-    end
-
-    protected
-
-    # Forcibly shutdown any threads that are still alive.
-    def forcibly_stop_workers
-      return unless @workers.size > 0
-      GRPC.logger.info("forcibly terminating #{@workers.size} worker(s)")
-      @workers.each do |t|
-        next unless t.alive?
-        begin
-          t.exit
-        rescue StandardError => e
-          GRPC.logger.warn('error while terminating a worker')
-          GRPC.logger.warn(e)
-        end
-      end
-    end
-
-    # removes the threads from workers, and signal when all the
-    # threads are complete.
-    def remove_current_thread
-      @stop_mutex.synchronize do
-        @workers.delete(Thread.current)
-        @stop_cond.signal if @workers.size.zero?
-      end
-    end
-
-    def loop_execute_jobs
-      loop do
-        begin
-          blk, args = @jobs.pop
-          blk.call(*args)
-        rescue StandardError => e
-          GRPC.logger.warn('Error in worker thread')
-          GRPC.logger.warn(e)
-        end
-      end
-    end
-  end
-
   # RpcServer hosts a number of services and makes them available on the
   # network.
   class RpcServer
@@ -147,11 +44,14 @@
 
     def_delegators :@server, :add_http2_port
 
-    # Default thread pool size is 3
-    DEFAULT_POOL_SIZE = 3
+    # Default max size of the thread pool size is 100
+    DEFAULT_MAX_POOL_SIZE = 100
 
-    # Default max_waiting_requests size is 20
-    DEFAULT_MAX_WAITING_REQUESTS = 20
+    # Default minimum size of the thread pool is 5
+    DEFAULT_MIN_POOL_SIZE = 5
+
+    # Default max_waiting_requests size is 60
+    DEFAULT_MAX_WAITING_REQUESTS = 60
 
     # Default poll period is 1s
     DEFAULT_POLL_PERIOD = 1
@@ -174,8 +74,8 @@
     # There are some specific keyword args used to configure the RpcServer
     # instance.
     #
-    # * pool_size: the size of the thread pool the server uses to run its
-    # threads
+    # * pool_size: the maximum size of the thread pool that the server's
+    # thread pool can reach.
     #
     # * max_waiting_requests: the maximum number of requests that are not
     # being handled to allow. When this limit is exceeded, the server responds
@@ -191,7 +91,8 @@
     #
     # * server_args:
     # A server arguments hash to be passed down to the underlying core server
-    def initialize(pool_size:DEFAULT_POOL_SIZE,
+    def initialize(pool_size:DEFAULT_MAX_POOL_SIZE,
+                   min_pool_size:DEFAULT_MIN_POOL_SIZE,
                    max_waiting_requests:DEFAULT_MAX_WAITING_REQUESTS,
                    poll_period:DEFAULT_POLL_PERIOD,
                    connect_md_proc:nil,
@@ -199,8 +100,12 @@
       @connect_md_proc = RpcServer.setup_connect_md_proc(connect_md_proc)
       @max_waiting_requests = max_waiting_requests
       @poll_period = poll_period
-      @pool_size = pool_size
-      @pool = Pool.new(@pool_size)
+
+      @pool = Concurrent::ThreadPoolExecutor.new(
+        min_threads: [min_pool_size, pool_size].min,
+        max_threads: pool_size,
+        max_queue: max_waiting_requests,
+        fallback_policy: :discard)
       @run_cond = ConditionVariable.new
       @run_mutex = Mutex.new
       # running_state can take 4 values: :not_started, :running, :stopping, and
@@ -221,7 +126,8 @@
       end
       deadline = from_relative_time(@poll_period)
       @server.close(deadline)
-      @pool.stop
+      @pool.shutdown
+      @pool.wait_for_termination
     end
 
     def running_state
@@ -318,7 +224,6 @@
     def run
       @run_mutex.synchronize do
         fail 'cannot run without registering services' if rpc_descs.size.zero?
-        @pool.start
         @server.start
         transition_running_state(:running)
         @run_cond.broadcast
@@ -330,9 +235,11 @@
 
     # Sends RESOURCE_EXHAUSTED if there are too many unprocessed jobs
     def available?(an_rpc)
-      jobs_count, max = @pool.jobs_waiting, @max_waiting_requests
+      jobs_count, max = @pool.queue_length, @pool.max_queue
       GRPC.logger.info("waiting: #{jobs_count}, max: #{max}")
-      return an_rpc if @pool.jobs_waiting <= @max_waiting_requests
+
+      # remaining capacity for ThreadPoolExecutors is -1 if unbounded
+      return an_rpc if @pool.remaining_capacity != 0
       GRPC.logger.warn("NOT AVAILABLE: too many jobs_waiting: #{an_rpc}")
       noop = proc { |x| x }
 
@@ -368,7 +275,7 @@
           break if (!an_rpc.nil?) && an_rpc.call.nil?
           active_call = new_active_server_call(an_rpc)
           unless active_call.nil?
-            @pool.schedule(active_call) do |ac|
+            @pool.post(active_call) do |ac|
               c, mth = ac
               begin
                 rpc_descs[mth].run_server_method(c, rpc_handlers[mth])
diff --git a/src/ruby/lib/grpc/grpc.rb b/src/ruby/lib/grpc/grpc.rb
index b60a828..f46710d 100644
--- a/src/ruby/lib/grpc/grpc.rb
+++ b/src/ruby/lib/grpc/grpc.rb
@@ -28,7 +28,12 @@
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 begin
-  require_relative "#{RUBY_VERSION.sub(/\.\d$/, '')}/grpc_c"
-rescue LoadError
-  require_relative 'grpc_c'
+  ruby_version_dirname = /(\d+\.\d+)/.match(RUBY_VERSION).to_s
+  distrib_lib_dir = File.expand_path(ruby_version_dirname,
+                                     File.dirname(__FILE__))
+  if File.directory?(distrib_lib_dir)
+    require_relative "#{distrib_lib_dir}/grpc_c"
+  else
+    require_relative 'grpc_c'
+  end
 end
diff --git a/src/ruby/spec/generic/rpc_server_pool_spec.rb b/src/ruby/spec/generic/rpc_server_pool_spec.rb
deleted file mode 100644
index b67008d..0000000
--- a/src/ruby/spec/generic/rpc_server_pool_spec.rb
+++ /dev/null
@@ -1,138 +0,0 @@
-# Copyright 2015, Google Inc.
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-#
-#     * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-#     * Redistributions in binary form must reproduce the above
-# copyright notice, this list of conditions and the following disclaimer
-# in the documentation and/or other materials provided with the
-# distribution.
-#     * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-require 'grpc'
-
-describe GRPC::Pool do
-  Pool = GRPC::Pool
-
-  describe '#new' do
-    it 'raises if a non-positive size is used' do
-      expect { Pool.new(0) }.to raise_error
-      expect { Pool.new(-1) }.to raise_error
-      expect { Pool.new(Object.new) }.to raise_error
-    end
-
-    it 'is constructed OK with a positive size' do
-      expect { Pool.new(1) }.not_to raise_error
-    end
-  end
-
-  describe '#jobs_waiting' do
-    it 'at start, it is zero' do
-      p = Pool.new(1)
-      expect(p.jobs_waiting).to be(0)
-    end
-
-    it 'it increases, with each scheduled job if the pool is not running' do
-      p = Pool.new(1)
-      job = proc {}
-      expect(p.jobs_waiting).to be(0)
-      5.times do |i|
-        p.schedule(&job)
-        expect(p.jobs_waiting).to be(i + 1)
-      end
-    end
-
-    it 'it decreases as jobs are run' do
-      p = Pool.new(1)
-      job = proc {}
-      expect(p.jobs_waiting).to be(0)
-      3.times do
-        p.schedule(&job)
-      end
-      p.start
-      sleep 2
-      expect(p.jobs_waiting).to be(0)
-    end
-  end
-
-  describe '#schedule' do
-    it 'return if the pool is already stopped' do
-      p = Pool.new(1)
-      p.stop
-      job = proc {}
-      expect { p.schedule(&job) }.to_not raise_error
-    end
-
-    it 'adds jobs that get run by the pool' do
-      p = Pool.new(1)
-      p.start
-      o, q = Object.new, Queue.new
-      job = proc { q.push(o) }
-      p.schedule(&job)
-      expect(q.pop).to be(o)
-      p.stop
-    end
-  end
-
-  describe '#stop' do
-    it 'works when there are no scheduled tasks' do
-      p = Pool.new(1)
-      expect { p.stop }.not_to raise_error
-    end
-
-    it 'stops jobs when there are long running jobs' do
-      p = Pool.new(1)
-      p.start
-      o, q = Object.new, Queue.new
-      job = proc do
-        sleep(5)  # long running
-        q.push(o)
-      end
-      p.schedule(&job)
-      sleep(1)  # should ensure the long job gets scheduled
-      expect { p.stop }.not_to raise_error
-    end
-  end
-
-  describe '#start' do
-    it 'runs pre-scheduled jobs' do
-      p = Pool.new(2)
-      o, q = Object.new, Queue.new
-      n = 5  # arbitrary
-      n.times { p.schedule(o, &q.method(:push)) }
-      p.start
-      n.times { expect(q.pop).to be(o) }
-      p.stop
-    end
-
-    it 'runs jobs as they are scheduled ' do
-      p = Pool.new(2)
-      o, q = Object.new, Queue.new
-      p.start
-      n = 5  # arbitrary
-      n.times do
-        p.schedule(o, &q.method(:push))
-        expect(q.pop).to be(o)
-      end
-      p.stop
-    end
-  end
-end
diff --git a/src/ruby/spec/generic/rpc_server_spec.rb b/src/ruby/spec/generic/rpc_server_spec.rb
index 31157cf..d362e48 100644
--- a/src/ruby/spec/generic/rpc_server_spec.rb
+++ b/src/ruby/spec/generic/rpc_server_spec.rb
@@ -395,9 +395,9 @@
       it 'should return RESOURCE_EXHAUSTED on too many jobs', server: true do
         opts = {
           server_args: { a_channel_arg: 'an_arg' },
-          pool_size: 1,
+          pool_size: 2,
           poll_period: 1,
-          max_waiting_requests: 0
+          max_waiting_requests: 1
         }
         alt_srv = RpcServer.new(**opts)
         alt_srv.handle(SlowService)
@@ -406,24 +406,23 @@
         t = Thread.new { alt_srv.run }
         alt_srv.wait_till_running
         req = EchoMsg.new
-        n = 5  # arbitrary, use as many to ensure the server pool is exceeded
+        n = 20 # arbitrary, use as many to ensure the server pool is exceeded
         threads = []
-        one_failed_as_unavailable = false
+        bad_status_code = nil
         n.times do
           threads << Thread.new do
             stub = SlowStub.new(alt_host, :this_channel_is_insecure)
             begin
               stub.an_rpc(req)
             rescue GRPC::BadStatus => e
-              one_failed_as_unavailable =
-                e.code == StatusCodes::RESOURCE_EXHAUSTED
+              bad_status_code = e.code
             end
           end
         end
         threads.each(&:join)
         alt_srv.stop
         t.join
-        expect(one_failed_as_unavailable).to be(true)
+        expect(bad_status_code).to be(StatusCodes::RESOURCE_EXHAUSTED)
       end
     end
 
diff --git a/templates/grpc.gemspec.template b/templates/grpc.gemspec.template
index f95adaf..75a6054 100644
--- a/templates/grpc.gemspec.template
+++ b/templates/grpc.gemspec.template
@@ -31,6 +31,7 @@
 
     s.add_dependency 'google-protobuf', '~> 3.0'
     s.add_dependency 'googleauth',      '~> 0.5.1'
+    s.add_dependency 'concurrent-ruby'
 
     s.add_development_dependency 'bundler',            '~> 1.9'
     s.add_development_dependency 'facter',             '~> 2.4'
diff --git a/templates/src/csharp/Grpc.Auth/project.json.template b/templates/src/csharp/Grpc.Auth/project.json.template
index 19d4b42..939a0c8 100644
--- a/templates/src/csharp/Grpc.Auth/project.json.template
+++ b/templates/src/csharp/Grpc.Auth/project.json.template
@@ -25,18 +25,13 @@
     },
     "dependencies": {
       "Grpc.Core": "${settings.csharp_version}",
-      "Google.Apis.Auth": "1.15.0"
+      "Google.Apis.Auth": "1.16.0"
     },
     "frameworks": {
       "net45": { },
       "netstandard1.5": {
-        "imports": [
-          "portable-net45"
-        ],
         "dependencies": {
-          "Microsoft.NETCore.Portable.Compatibility": "1.0.1",
-          "NETStandard.Library": "1.6.0",
-          "System.Threading.Tasks": "4.0.11"
+          "NETStandard.Library": "1.6.0"
         }
       }
     }
diff --git a/templates/src/csharp/Grpc.Core.Tests/project.json.template b/templates/src/csharp/Grpc.Core.Tests/project.json.template
index 3452d6b..8a3e075 100644
--- a/templates/src/csharp/Grpc.Core.Tests/project.json.template
+++ b/templates/src/csharp/Grpc.Core.Tests/project.json.template
@@ -20,8 +20,10 @@
           "portable-net45"
         ],
         "dependencies": {
-          "Microsoft.NETCore.App": "1.0.0",
-          "NETStandard.Library": "1.6.0"
+          "Microsoft.NETCore.App": {
+            "type": "platform",
+            "version": "1.0.0"
+          }
         }
       }
     },
diff --git a/templates/src/csharp/Grpc.Core/project.json.template b/templates/src/csharp/Grpc.Core/project.json.template
index e6f8290..fcbef53 100644
--- a/templates/src/csharp/Grpc.Core/project.json.template
+++ b/templates/src/csharp/Grpc.Core/project.json.template
@@ -38,11 +38,9 @@
     "frameworks": {
       "net45": { },
       "netstandard1.5": {
-        "imports": [
-          "portable-net45"
-        ],
         "dependencies": {
           "NETStandard.Library": "1.6.0",
+          "System.Runtime.Loader": "4.0.0",
           "System.Threading.Thread": "4.0.0"
         }
       }
diff --git a/templates/src/csharp/Grpc.Examples.MathClient/project.json.template b/templates/src/csharp/Grpc.Examples.MathClient/project.json.template
index 67151db..ae4ea2a 100644
--- a/templates/src/csharp/Grpc.Examples.MathClient/project.json.template
+++ b/templates/src/csharp/Grpc.Examples.MathClient/project.json.template
@@ -10,12 +10,11 @@
     "frameworks": {
       "net45": { },
       "netcoreapp1.0": {
-        "imports": [
-          "portable-net45"
-        ],
         "dependencies": {
-          "Microsoft.NETCore.App": "1.0.0",
-          "NETStandard.Library": "1.6.0"
+          "Microsoft.NETCore.App": {
+            "type": "platform",
+            "version": "1.0.0"
+          }
         }
       }
     }
diff --git a/templates/src/csharp/Grpc.Examples.MathServer/project.json.template b/templates/src/csharp/Grpc.Examples.MathServer/project.json.template
index 67151db..ae4ea2a 100644
--- a/templates/src/csharp/Grpc.Examples.MathServer/project.json.template
+++ b/templates/src/csharp/Grpc.Examples.MathServer/project.json.template
@@ -10,12 +10,11 @@
     "frameworks": {
       "net45": { },
       "netcoreapp1.0": {
-        "imports": [
-          "portable-net45"
-        ],
         "dependencies": {
-          "Microsoft.NETCore.App": "1.0.0",
-          "NETStandard.Library": "1.6.0"
+          "Microsoft.NETCore.App": {
+            "type": "platform",
+            "version": "1.0.0"
+          }
         }
       }
     }
diff --git a/templates/src/csharp/Grpc.Examples.Tests/project.json.template b/templates/src/csharp/Grpc.Examples.Tests/project.json.template
index af13cb5..0a9eb7c 100644
--- a/templates/src/csharp/Grpc.Examples.Tests/project.json.template
+++ b/templates/src/csharp/Grpc.Examples.Tests/project.json.template
@@ -16,8 +16,10 @@
           "portable-net45"
         ],
         "dependencies": {
-          "Microsoft.NETCore.App": "1.0.0",
-          "NETStandard.Library": "1.6.0"
+          "Microsoft.NETCore.App": {
+            "type": "platform",
+            "version": "1.0.0"
+          }
         }
       }
     }
diff --git a/templates/src/csharp/Grpc.Examples/project.json.template b/templates/src/csharp/Grpc.Examples/project.json.template
index 117f842..b8a8314 100644
--- a/templates/src/csharp/Grpc.Examples/project.json.template
+++ b/templates/src/csharp/Grpc.Examples/project.json.template
@@ -6,7 +6,7 @@
       "Grpc.Core": {
         "target": "project"
       },
-      "Google.Protobuf": "3.0.0-beta3"
+      "Google.Protobuf": "3.0.0"
     },
     "frameworks": {
       "net45": {
@@ -16,12 +16,11 @@
         }
       },
       "netcoreapp1.0": {
-        "imports": [
-          "portable-net45"
-        ],
         "dependencies": {
-          "Microsoft.NETCore.App": "1.0.0",
-          "NETStandard.Library": "1.6.0"
+          "Microsoft.NETCore.App": {
+            "type": "platform",
+            "version": "1.0.0"
+          }
         }
       }
     }
diff --git a/templates/src/csharp/Grpc.HealthCheck.Tests/project.json.template b/templates/src/csharp/Grpc.HealthCheck.Tests/project.json.template
index 417b773..c63da96 100644
--- a/templates/src/csharp/Grpc.HealthCheck.Tests/project.json.template
+++ b/templates/src/csharp/Grpc.HealthCheck.Tests/project.json.template
@@ -16,8 +16,10 @@
           "portable-net45"
         ],
         "dependencies": {
-          "Microsoft.NETCore.App": "1.0.0",
-          "NETStandard.Library": "1.6.0"
+          "Microsoft.NETCore.App": {
+            "type": "platform",
+            "version": "1.0.0"
+          }
         }
       }
     }
diff --git a/templates/src/csharp/Grpc.HealthCheck/project.json.template b/templates/src/csharp/Grpc.HealthCheck/project.json.template
index cd2da00..46307dd 100644
--- a/templates/src/csharp/Grpc.HealthCheck/project.json.template
+++ b/templates/src/csharp/Grpc.HealthCheck/project.json.template
@@ -25,7 +25,7 @@
     },
     "dependencies": {
       "Grpc.Core": "${settings.csharp_version}",
-      "Google.Protobuf": "3.0.0-beta3"
+      "Google.Protobuf": "3.0.0"
     },
     "frameworks": {
       "net45": {
@@ -35,9 +35,6 @@
         }
       },
       "netstandard1.5": {
-        "imports": [
-          "portable-net45"
-        ],
         "dependencies": {
           "NETStandard.Library": "1.6.0"
         }
diff --git a/templates/src/csharp/Grpc.IntegrationTesting.Client/project.json.template b/templates/src/csharp/Grpc.IntegrationTesting.Client/project.json.template
index 93151f2..83b8a9b 100644
--- a/templates/src/csharp/Grpc.IntegrationTesting.Client/project.json.template
+++ b/templates/src/csharp/Grpc.IntegrationTesting.Client/project.json.template
@@ -11,12 +11,13 @@
       "net45": { },
       "netcoreapp1.0": {
         "imports": [
-          "portable-net45",
-          "net45"
+          "portable-net45"
         ],
         "dependencies": {
-          "Microsoft.NETCore.App": "1.0.0",
-          "NETStandard.Library": "1.6.0"
+          "Microsoft.NETCore.App": {
+            "type": "platform",
+            "version": "1.0.0"
+          }
         }
       }
     }
diff --git a/templates/src/csharp/Grpc.IntegrationTesting.QpsWorker/project.json.template b/templates/src/csharp/Grpc.IntegrationTesting.QpsWorker/project.json.template
index 93151f2..83b8a9b 100644
--- a/templates/src/csharp/Grpc.IntegrationTesting.QpsWorker/project.json.template
+++ b/templates/src/csharp/Grpc.IntegrationTesting.QpsWorker/project.json.template
@@ -11,12 +11,13 @@
       "net45": { },
       "netcoreapp1.0": {
         "imports": [
-          "portable-net45",
-          "net45"
+          "portable-net45"
         ],
         "dependencies": {
-          "Microsoft.NETCore.App": "1.0.0",
-          "NETStandard.Library": "1.6.0"
+          "Microsoft.NETCore.App": {
+            "type": "platform",
+            "version": "1.0.0"
+          }
         }
       }
     }
diff --git a/templates/src/csharp/Grpc.IntegrationTesting.Server/project.json.template b/templates/src/csharp/Grpc.IntegrationTesting.Server/project.json.template
index 93151f2..83b8a9b 100644
--- a/templates/src/csharp/Grpc.IntegrationTesting.Server/project.json.template
+++ b/templates/src/csharp/Grpc.IntegrationTesting.Server/project.json.template
@@ -11,12 +11,13 @@
       "net45": { },
       "netcoreapp1.0": {
         "imports": [
-          "portable-net45",
-          "net45"
+          "portable-net45"
         ],
         "dependencies": {
-          "Microsoft.NETCore.App": "1.0.0",
-          "NETStandard.Library": "1.6.0"
+          "Microsoft.NETCore.App": {
+            "type": "platform",
+            "version": "1.0.0"
+          }
         }
       }
     }
diff --git a/templates/src/csharp/Grpc.IntegrationTesting.StressClient/project.json.template b/templates/src/csharp/Grpc.IntegrationTesting.StressClient/project.json.template
index 93151f2..83b8a9b 100644
--- a/templates/src/csharp/Grpc.IntegrationTesting.StressClient/project.json.template
+++ b/templates/src/csharp/Grpc.IntegrationTesting.StressClient/project.json.template
@@ -11,12 +11,13 @@
       "net45": { },
       "netcoreapp1.0": {
         "imports": [
-          "portable-net45",
-          "net45"
+          "portable-net45"
         ],
         "dependencies": {
-          "Microsoft.NETCore.App": "1.0.0",
-          "NETStandard.Library": "1.6.0"
+          "Microsoft.NETCore.App": {
+            "type": "platform",
+            "version": "1.0.0"
+          }
         }
       }
     }
diff --git a/templates/src/csharp/Grpc.IntegrationTesting/project.json.template b/templates/src/csharp/Grpc.IntegrationTesting/project.json.template
index 1cb5ca4..3ce94e5 100644
--- a/templates/src/csharp/Grpc.IntegrationTesting/project.json.template
+++ b/templates/src/csharp/Grpc.IntegrationTesting/project.json.template
@@ -9,16 +9,14 @@
       "Grpc.Core": {
         "target": "project"
       },
-      "Google.Protobuf": "3.0.0-beta3",
+      "Google.Protobuf": "3.0.0",
       "CommandLineParser.Unofficial": "2.0.275",
+      "Moq": "4.6.38-alpha",
       "NUnit": "3.2.0",
       "NUnitLite": "3.2.0-*"
     },
     "frameworks": {
       "net45": {
-        "dependencies": {
-          "Moq": "4.2.1510.2205"
-        },
         "frameworkAssemblies": {
           "System.Runtime": "",
           "System.IO": ""
@@ -26,12 +24,13 @@
       },
       "netcoreapp1.0": {
         "imports": [
-          "portable-net45",
-          "net45"
+          "portable-net45"
         ],
         "dependencies": {
-          "Microsoft.NETCore.App": "1.0.0",
-          "NETStandard.Library": "1.6.0",
+          "Microsoft.NETCore.App": {
+            "type": "platform",
+            "version": "1.0.0"
+          },
           "System.Linq.Expressions": "4.1.0"
         }
       }
diff --git a/templates/src/csharp/build_options.include b/templates/src/csharp/build_options.include
index 8597ae3..bda2d76 100644
--- a/templates/src/csharp/build_options.include
+++ b/templates/src/csharp/build_options.include
@@ -16,10 +16,12 @@
           "includeFiles": [ "../Grpc.Core/Version.cs" ]
         },
         "copyToOutput": {
-          % if includeData:
-          "include": "data/*",
-          % endif
           "mappings": {
+            % if includeData:
+            "data/ca.pem": "../Grpc.IntegrationTesting/data/ca.pem",
+            "data/server1.key": "../Grpc.IntegrationTesting/data/server1.key",
+            "data/server1.pem": "../Grpc.IntegrationTesting/data/server1.pem",
+            % endif
             "grpc_csharp_ext.x64.dll": "../../../vsprojects/x64/Debug/grpc_csharp_ext.dll",
             "grpc_csharp_ext.x86.dll": "../../../vsprojects/Debug/grpc_csharp_ext.dll",
             "libgrpc_csharp_ext.x64.so": "../../../libs/dbg/libgrpc_csharp_ext.so",
@@ -38,10 +40,12 @@
           "includeFiles": [ "../Grpc.Core/Version.cs" ]
         },
         "copyToOutput": {
-          % if includeData:
-          "include": "data/*",
-          % endif
           "mappings": {
+            % if includeData:
+            "data/ca.pem": "../Grpc.IntegrationTesting/data/ca.pem",
+            "data/server1.key": "../Grpc.IntegrationTesting/data/server1.key",
+            "data/server1.pem": "../Grpc.IntegrationTesting/data/server1.pem",
+            % endif
             "grpc_csharp_ext.x64.dll": "../../../vsprojects/x64/Release/grpc_csharp_ext.dll",
             "grpc_csharp_ext.x86.dll": "../../../vsprojects/Release/grpc_csharp_ext.dll",
             "libgrpc_csharp_ext.x64.so": "../../../libs/opt/libgrpc_csharp_ext.so",
@@ -52,8 +56,3 @@
     }
   },
   %endif
-  "runtimes": {
-    "win7-x64": { },
-    "debian.8-x64": { },
-    "osx.10.11-x64": { }
-  },
diff --git a/templates/src/csharp/build_packages.bat.template b/templates/src/csharp/build_packages.bat.template
index 5cbd8e3..87c4b5a 100644
--- a/templates/src/csharp/build_packages.bat.template
+++ b/templates/src/csharp/build_packages.bat.template
@@ -31,6 +31,10 @@
   
   @rem Builds gRPC NuGet packages
   
+  @rem This way of building nuget packages is now obsolete. C# nuget packages
+  @rem with CoreCLR support are now being built using the dotnet cli
+  @rem in build_packages_dotnetcli.sh
+  
   @rem Current package versions
   set VERSION=${settings.csharp_version}
   set PROTOBUF_VERSION=3.0.0
@@ -79,8 +83,8 @@
   xcopy /Y /I *.nupkg ..\..\artifacts${"\\"}
   
   @rem create a zipfile with the artifacts as well
-  powershell -Command "Add-Type -Assembly 'System.IO.Compression.FileSystem'; [System.IO.Compression.ZipFile]::CreateFromDirectory('..\..\artifacts', 'csharp_nugets.zip');"
-  xcopy /Y /I csharp_nugets.zip ..\..\artifacts${"\\"}
+  powershell -Command "Add-Type -Assembly 'System.IO.Compression.FileSystem'; [System.IO.Compression.ZipFile]::CreateFromDirectory('..\..\artifacts', 'csharp_nugets_obsolete.zip');"
+  xcopy /Y /I csharp_nugets_obsolete.zip ..\..\artifacts${"\\"}
   
   goto :EOF
   
diff --git a/templates/src/csharp/build_packages_dotnetcli.sh.template b/templates/src/csharp/build_packages_dotnetcli.sh.template
new file mode 100755
index 0000000..99b049a
--- /dev/null
+++ b/templates/src/csharp/build_packages_dotnetcli.sh.template
@@ -0,0 +1,72 @@
+%YAML 1.2
+--- |
+  #!/bin/bash
+  # 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.
+  
+  set -ex
+  
+  cd $(dirname $0)
+  
+  mkdir -p ../../artifacts/
+  
+  mkdir -p nativelibs/windows_x86 nativelibs/windows_x64 ${"\\"}
+      nativelibs/linux_x86 nativelibs/linux_x64 ${"\\"}
+      nativelibs/macosx_x86 nativelibs/macosx_x64
+  
+  mkdir -p protoc_plugins/windows_x86 protoc_plugins/windows_x64 ${"\\"}
+      protoc_plugins/linux_x86 protoc_plugins/linux_x64 ${"\\"}
+      protoc_plugins/macosx_x86 protoc_plugins/macosx_x64
+  
+  # Collect the artifacts built by the previous build step if running on Jenkins
+  cp $EXTERNAL_GIT_ROOT/architecture=x86,language=csharp,platform=windows/artifacts/* nativelibs/windows_x86 || true
+  cp $EXTERNAL_GIT_ROOT/architecture=x64,language=csharp,platform=windows/artifacts/* nativelibs/windows_x64 || true
+  cp $EXTERNAL_GIT_ROOT/architecture=x86,language=csharp,platform=linux/artifacts/* nativelibs/linux_x86 || true
+  cp $EXTERNAL_GIT_ROOT/architecture=x64,language=csharp,platform=linux/artifacts/* nativelibs/linux_x64 || true
+  cp $EXTERNAL_GIT_ROOT/architecture=x86,language=csharp,platform=macos/artifacts/* nativelibs/macosx_x86 || true
+  cp $EXTERNAL_GIT_ROOT/architecture=x64,language=csharp,platform=macos/artifacts/* nativelibs/macosx_x64 || true
+  
+  # Collect protoc artifacts built by the previous build step
+  cp $EXTERNAL_GIT_ROOT/architecture=x86,language=protoc,platform=windows/artifacts/* protoc_plugins/windows_x86 || true
+  cp $EXTERNAL_GIT_ROOT/architecture=x64,language=protoc,platform=windows/artifacts/* protoc_plugins/windows_x64 || true
+  cp $EXTERNAL_GIT_ROOT/architecture=x86,language=protoc,platform=linux/artifacts/* protoc_plugins/linux_x86 || true
+  cp $EXTERNAL_GIT_ROOT/architecture=x64,language=protoc,platform=linux/artifacts/* protoc_plugins/linux_x64 || true
+  cp $EXTERNAL_GIT_ROOT/architecture=x86,language=protoc,platform=macos/artifacts/* protoc_plugins/macosx_x86 || true
+  cp $EXTERNAL_GIT_ROOT/architecture=x64,language=protoc,platform=macos/artifacts/* protoc_plugins/macosx_x64 || true
+  
+  dotnet restore .
+  
+  dotnet pack --configuration Release Grpc.Core/project.json --output ../../artifacts
+  dotnet pack --configuration Release Grpc.Auth/project.json --output ../../artifacts
+  dotnet pack --configuration Release Grpc.HealthCheck/project.json --output ../../artifacts
+  
+  nuget pack Grpc.nuspec -Version "${settings.csharp_version}" -OutputDirectory ../../artifacts
+  nuget pack Grpc.Tools.nuspec -Version "${settings.csharp_version}" -OutputDirectory ../../artifacts
+  
+  (cd ../../artifacts && zip csharp_nugets_dotnetcli.zip *.nupkg)
diff --git a/templates/tools/dockerfile/csharp_dotnetcli_deps.include b/templates/tools/dockerfile/csharp_dotnetcli_deps.include
new file mode 100644
index 0000000..430f3fa
--- /dev/null
+++ b/templates/tools/dockerfile/csharp_dotnetcli_deps.include
@@ -0,0 +1,13 @@
+# Install dotnet SDK based on https://www.microsoft.com/net/core#debian
+RUN apt-get update && apt-get install -y curl libunwind8 gettext
+RUN curl -sSL -o dotnet.tar.gz https://go.microsoft.com/fwlink/?LinkID=809130
+RUN mkdir -p /opt/dotnet && tar zxf dotnet.tar.gz -C /opt/dotnet
+RUN ln -s /opt/dotnet/dotnet /usr/local/bin
+
+# Trigger the population of the local package cache
+ENV NUGET_XMLDOC_MODE skip
+RUN mkdir warmup ${'\\'}
+    && cd warmup ${'\\'}
+    && dotnet new ${'\\'}
+    && cd .. ${'\\'}
+    && rm -rf warmup
diff --git a/templates/tools/dockerfile/interoptest/grpc_interop_csharpcoreclr/Dockerfile.template b/templates/tools/dockerfile/interoptest/grpc_interop_csharpcoreclr/Dockerfile.template
new file mode 100644
index 0000000..092f04d
--- /dev/null
+++ b/templates/tools/dockerfile/interoptest/grpc_interop_csharpcoreclr/Dockerfile.template
@@ -0,0 +1,41 @@
+%YAML 1.2
+--- |
+  # Copyright 2015, Google Inc.
+  # All rights reserved.
+  #
+  # Redistribution and use in source and binary forms, with or without
+  # modification, are permitted provided that the following conditions are
+  # met:
+  #
+  #     * Redistributions of source code must retain the above copyright
+  # notice, this list of conditions and the following disclaimer.
+  #     * Redistributions in binary form must reproduce the above
+  # copyright notice, this list of conditions and the following disclaimer
+  # in the documentation and/or other materials provided with the
+  # distribution.
+  #     * Neither the name of Google Inc. nor the names of its
+  # contributors may be used to endorse or promote products derived from
+  # this software without specific prior written permission.
+  #
+  # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+  # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+  # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+  # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+  # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+  # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+  # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+  # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+  # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+  # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+  
+  FROM debian:jessie
+  
+  <%include file="../../apt_get_basic.include"/>
+  <%include file="../../python_deps.include"/>
+  <%include file="../../csharp_deps.include"/>
+  <%include file="../../csharp_dotnetcli_deps.include"/>
+  <%include file="../../run_tests_addons.include"/>
+  # Define the default command.
+  CMD ["bash"]
+  
diff --git a/templates/tools/dockerfile/test/csharp_coreclr_x64/Dockerfile.template b/templates/tools/dockerfile/test/csharp_coreclr_x64/Dockerfile.template
index 24dad48..092f04d 100644
--- a/templates/tools/dockerfile/test/csharp_coreclr_x64/Dockerfile.template
+++ b/templates/tools/dockerfile/test/csharp_coreclr_x64/Dockerfile.template
@@ -34,21 +34,7 @@
   <%include file="../../apt_get_basic.include"/>
   <%include file="../../python_deps.include"/>
   <%include file="../../csharp_deps.include"/>
-  
-  # Install dotnet SDK based on https://www.microsoft.com/net/core#debian
-  RUN apt-get update && apt-get install -y curl libunwind8 gettext
-  RUN curl -sSL -o dotnet.tar.gz https://go.microsoft.com/fwlink/?LinkID=809130
-  RUN mkdir -p /opt/dotnet && tar zxf dotnet.tar.gz -C /opt/dotnet
-  RUN ln -s /opt/dotnet/dotnet /usr/local/bin
-  
-  # Trigger the population of the local package cache
-  ENV NUGET_XMLDOC_MODE skip
-  RUN mkdir warmup ${'\\'}
-      && cd warmup ${'\\'}
-      && dotnet new ${'\\'}
-      && cd .. ${'\\'}
-      && rm -rf warmup
-  
+  <%include file="../../csharp_dotnetcli_deps.include"/>
   <%include file="../../run_tests_addons.include"/>
   # Define the default command.
   CMD ["bash"]
diff --git a/test/core/bad_ssl/gen_build_yaml.py b/test/core/bad_ssl/gen_build_yaml.py
index 69f9219..c17b17e 100755
--- a/test/core/bad_ssl/gen_build_yaml.py
+++ b/test/core/bad_ssl/gen_build_yaml.py
@@ -41,7 +41,8 @@
 # maps test names to options
 BAD_CLIENT_TESTS = {
     'cert': default_test_options._replace(cpu_cost=0.1),
-    'alpn': default_test_options._replace(cpu_cost=0.1),
+    # Disabling this test because it does not link correctly as written
+    # 'alpn': default_test_options._replace(cpu_cost=0.1),
 }
 
 def main():
diff --git a/test/core/end2end/end2end_nosec_tests.c b/test/core/end2end/end2end_nosec_tests.c
index 2e8da05..a630262 100644
--- a/test/core/end2end/end2end_nosec_tests.c
+++ b/test/core/end2end/end2end_nosec_tests.c
@@ -117,6 +117,8 @@
 extern void shutdown_finishes_calls_pre_init(void);
 extern void shutdown_finishes_tags(grpc_end2end_test_config config);
 extern void shutdown_finishes_tags_pre_init(void);
+extern void simple_cacheable_request(grpc_end2end_test_config config);
+extern void simple_cacheable_request_pre_init(void);
 extern void simple_delayed_request(grpc_end2end_test_config config);
 extern void simple_delayed_request_pre_init(void);
 extern void simple_metadata(grpc_end2end_test_config config);
@@ -168,6 +170,7 @@
   server_finishes_request_pre_init();
   shutdown_finishes_calls_pre_init();
   shutdown_finishes_tags_pre_init();
+  simple_cacheable_request_pre_init();
   simple_delayed_request_pre_init();
   simple_metadata_pre_init();
   simple_request_pre_init();
@@ -219,6 +222,7 @@
     server_finishes_request(config);
     shutdown_finishes_calls(config);
     shutdown_finishes_tags(config);
+    simple_cacheable_request(config);
     simple_delayed_request(config);
     simple_metadata(config);
     simple_request(config);
@@ -376,6 +380,10 @@
       shutdown_finishes_tags(config);
       continue;
     }
+    if (0 == strcmp("simple_cacheable_request", argv[i])) {
+      simple_cacheable_request(config);
+      continue;
+    }
     if (0 == strcmp("simple_delayed_request", argv[i])) {
       simple_delayed_request(config);
       continue;
diff --git a/test/core/end2end/end2end_tests.c b/test/core/end2end/end2end_tests.c
index 22a914e..925872a 100644
--- a/test/core/end2end/end2end_tests.c
+++ b/test/core/end2end/end2end_tests.c
@@ -119,6 +119,8 @@
 extern void shutdown_finishes_calls_pre_init(void);
 extern void shutdown_finishes_tags(grpc_end2end_test_config config);
 extern void shutdown_finishes_tags_pre_init(void);
+extern void simple_cacheable_request(grpc_end2end_test_config config);
+extern void simple_cacheable_request_pre_init(void);
 extern void simple_delayed_request(grpc_end2end_test_config config);
 extern void simple_delayed_request_pre_init(void);
 extern void simple_metadata(grpc_end2end_test_config config);
@@ -171,6 +173,7 @@
   server_finishes_request_pre_init();
   shutdown_finishes_calls_pre_init();
   shutdown_finishes_tags_pre_init();
+  simple_cacheable_request_pre_init();
   simple_delayed_request_pre_init();
   simple_metadata_pre_init();
   simple_request_pre_init();
@@ -223,6 +226,7 @@
     server_finishes_request(config);
     shutdown_finishes_calls(config);
     shutdown_finishes_tags(config);
+    simple_cacheable_request(config);
     simple_delayed_request(config);
     simple_metadata(config);
     simple_request(config);
@@ -384,6 +388,10 @@
       shutdown_finishes_tags(config);
       continue;
     }
+    if (0 == strcmp("simple_cacheable_request", argv[i])) {
+      simple_cacheable_request(config);
+      continue;
+    }
     if (0 == strcmp("simple_delayed_request", argv[i])) {
       simple_delayed_request(config);
       continue;
diff --git a/test/core/end2end/end2end_tests.h b/test/core/end2end/end2end_tests.h
index dfa041c..34af093 100644
--- a/test/core/end2end/end2end_tests.h
+++ b/test/core/end2end/end2end_tests.h
@@ -42,6 +42,7 @@
 #define FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION 1
 #define FEATURE_MASK_SUPPORTS_HOSTNAME_VERIFICATION 2
 #define FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS 4
+#define FEATURE_MASK_SUPPORTS_REQUEST_PROXYING 8
 
 #define FAIL_AUTH_CHECK_SERVER_ARG_NAME "fail_auth_check"
 
diff --git a/test/core/end2end/fixtures/h2_proxy.c b/test/core/end2end/fixtures/h2_proxy.c
index 8c50eeb..c7b9986 100644
--- a/test/core/end2end/fixtures/h2_proxy.c
+++ b/test/core/end2end/fixtures/h2_proxy.c
@@ -113,7 +113,8 @@
 
 /* All test configurations */
 static grpc_end2end_test_config configs[] = {
-    {"chttp2/fullstack+proxy", FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION,
+    {"chttp2/fullstack+proxy", FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION |
+                                   FEATURE_MASK_SUPPORTS_REQUEST_PROXYING,
      chttp2_create_fixture_fullstack, chttp2_init_client_fullstack,
      chttp2_init_server_fullstack, chttp2_tear_down_fullstack},
 };
diff --git a/test/core/end2end/fixtures/h2_ssl_proxy.c b/test/core/end2end/fixtures/h2_ssl_proxy.c
index 238e6bc..eeb54b8 100644
--- a/test/core/end2end/fixtures/h2_ssl_proxy.c
+++ b/test/core/end2end/fixtures/h2_ssl_proxy.c
@@ -184,6 +184,7 @@
 static grpc_end2end_test_config configs[] = {
     {"chttp2/simple_ssl_fullstack",
      FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION |
+         FEATURE_MASK_SUPPORTS_REQUEST_PROXYING |
          FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS,
      chttp2_create_fixture_secure_fullstack,
      chttp2_init_client_simple_ssl_secure_fullstack,
diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/22967e8ed837f03b76a980cc1d25054fb84b40e9 b/test/core/end2end/fuzzers/api_fuzzer_corpus/22967e8ed837f03b76a980cc1d25054fb84b40e9
new file mode 100644
index 0000000..1aa57b9
--- /dev/null
+++ b/test/core/end2end/fuzzers/api_fuzzer_corpus/22967e8ed837f03b76a980cc1d25054fb84b40e9
Binary files differ
diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/3f464011f8620f227309f6b2c84df6fffb8ed962 b/test/core/end2end/fuzzers/api_fuzzer_corpus/3f464011f8620f227309f6b2c84df6fffb8ed962
new file mode 100644
index 0000000..385a724
--- /dev/null
+++ b/test/core/end2end/fuzzers/api_fuzzer_corpus/3f464011f8620f227309f6b2c84df6fffb8ed962
Binary files differ
diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/crash-15070b2a2719ed8a6cbbaac25da02b7085993648 b/test/core/end2end/fuzzers/api_fuzzer_corpus/crash-15070b2a2719ed8a6cbbaac25da02b7085993648
new file mode 100644
index 0000000..e21c7c6
--- /dev/null
+++ b/test/core/end2end/fuzzers/api_fuzzer_corpus/crash-15070b2a2719ed8a6cbbaac25da02b7085993648
Binary files differ
diff --git a/test/core/end2end/gen_build_yaml.py b/test/core/end2end/gen_build_yaml.py
index b8ff573..fe0f7ba 100755
--- a/test/core/end2end/gen_build_yaml.py
+++ b/test/core/end2end/gen_build_yaml.py
@@ -127,6 +127,7 @@
     'server_finishes_request': default_test_options,
     'shutdown_finishes_calls': default_test_options,
     'shutdown_finishes_tags': default_test_options,
+    'simple_cacheable_request': default_test_options,
     'simple_delayed_request': connectivity_test_options,
     'simple_metadata': default_test_options,
     'simple_request': default_test_options,
@@ -224,7 +225,7 @@
               'name': '%s_nosec_test' % f,
               'build': 'test',
               'language': 'c',
-              'secure': 'no',
+              'secure': False,
               'src': ['test/core/end2end/fixtures/%s.c' % f],
               'run': False,
               'platforms': END2END_FIXTURES[f].platforms,
diff --git a/test/core/end2end/tests/invoke_large_request.c b/test/core/end2end/tests/invoke_large_request.c
index a62fb01..1df237c 100644
--- a/test/core/end2end/tests/invoke_large_request.c
+++ b/test/core/end2end/tests/invoke_large_request.c
@@ -39,6 +39,7 @@
 #include <grpc/byte_buffer.h>
 #include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
+#include <grpc/support/string_util.h>
 #include <grpc/support/time.h>
 #include <grpc/support/useful.h>
 #include "test/core/end2end/cq_verifier.h"
@@ -99,9 +100,25 @@
   return slice;
 }
 
-static void test_invoke_large_request(grpc_end2end_test_config config) {
+static void test_invoke_large_request(grpc_end2end_test_config config,
+                                      int max_frame_size, int lookahead_bytes) {
+  char *name;
+  gpr_asprintf(&name,
+               "test_invoke_large_request:max_frame_size=%d:lookahead_bytes=%d",
+               max_frame_size, lookahead_bytes);
+
+  grpc_arg args[2];
+  args[0].type = GRPC_ARG_INTEGER;
+  args[0].key = GRPC_ARG_HTTP2_MAX_FRAME_SIZE;
+  args[0].value.integer = max_frame_size;
+  args[1].type = GRPC_ARG_INTEGER;
+  args[1].key = GRPC_ARG_HTTP2_STREAM_LOOKAHEAD_BYTES;
+  args[1].value.integer = lookahead_bytes;
+  grpc_channel_args channel_args = {GPR_ARRAY_SIZE(args), args};
+
   grpc_end2end_test_fixture f =
-      begin_test(config, "test_invoke_large_request", NULL, NULL);
+      begin_test(config, name, &channel_args, &channel_args);
+  gpr_free(name);
 
   gpr_slice request_payload_slice = large_slice();
   gpr_slice response_payload_slice = large_slice();
@@ -253,7 +270,26 @@
 }
 
 void invoke_large_request(grpc_end2end_test_config config) {
-  test_invoke_large_request(config);
+  test_invoke_large_request(config, 16384, 65536);
+  test_invoke_large_request(config, 32768, 65536);
+
+  test_invoke_large_request(config, 1000000 - 1, 65536);
+  test_invoke_large_request(config, 1000000, 65536);
+  test_invoke_large_request(config, 1000000 + 1, 65536);
+  test_invoke_large_request(config, 1000000 + 2, 65536);
+  test_invoke_large_request(config, 1000000 + 3, 65536);
+  test_invoke_large_request(config, 1000000 + 4, 65536);
+  test_invoke_large_request(config, 1000000 + 5, 65536);
+  test_invoke_large_request(config, 1000000 + 6, 65536);
+
+  test_invoke_large_request(config, 1000000 - 1, 2000000);
+  test_invoke_large_request(config, 1000000, 2000000);
+  test_invoke_large_request(config, 1000000 + 1, 2000000);
+  test_invoke_large_request(config, 1000000 + 2, 2000000);
+  test_invoke_large_request(config, 1000000 + 3, 2000000);
+  test_invoke_large_request(config, 1000000 + 4, 2000000);
+  test_invoke_large_request(config, 1000000 + 5, 2000000);
+  test_invoke_large_request(config, 1000000 + 6, 2000000);
 }
 
 void invoke_large_request_pre_init(void) {}
diff --git a/test/core/end2end/tests/simple_cacheable_request.c b/test/core/end2end/tests/simple_cacheable_request.c
new file mode 100644
index 0000000..b52eb19
--- /dev/null
+++ b/test/core/end2end/tests/simple_cacheable_request.c
@@ -0,0 +1,276 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "test/core/end2end/end2end_tests.h"
+
+#include <stdio.h>
+#include <string.h>
+
+#include <grpc/byte_buffer.h>
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/time.h>
+#include <grpc/support/useful.h>
+#include "test/core/end2end/cq_verifier.h"
+
+enum { TIMEOUT = 200000 };
+
+static void *tag(intptr_t t) { return (void *)t; }
+
+static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
+                                            const char *test_name,
+                                            grpc_channel_args *client_args,
+                                            grpc_channel_args *server_args) {
+  grpc_end2end_test_fixture f;
+  gpr_log(GPR_INFO, "%s/%s", test_name, config.name);
+  f = config.create_fixture(client_args, server_args);
+  config.init_server(&f, server_args);
+  config.init_client(&f, client_args);
+  return f;
+}
+
+static gpr_timespec n_seconds_time(int n) {
+  return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n);
+}
+
+static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); }
+
+static void drain_cq(grpc_completion_queue *cq) {
+  grpc_event ev;
+  do {
+    ev = grpc_completion_queue_next(cq, five_seconds_time(), NULL);
+  } while (ev.type != GRPC_QUEUE_SHUTDOWN);
+}
+
+static void shutdown_server(grpc_end2end_test_fixture *f) {
+  if (!f->server) return;
+  grpc_server_shutdown_and_notify(f->server, f->cq, tag(1000));
+  GPR_ASSERT(grpc_completion_queue_pluck(
+                 f->cq, tag(1000), GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5), NULL)
+                 .type == GRPC_OP_COMPLETE);
+  grpc_server_destroy(f->server);
+  f->server = NULL;
+}
+
+static void shutdown_client(grpc_end2end_test_fixture *f) {
+  if (!f->client) return;
+  grpc_channel_destroy(f->client);
+  f->client = NULL;
+}
+
+static void end_test(grpc_end2end_test_fixture *f) {
+  shutdown_server(f);
+  shutdown_client(f);
+
+  grpc_completion_queue_shutdown(f->cq);
+  drain_cq(f->cq);
+  grpc_completion_queue_destroy(f->cq);
+}
+
+/* Request/response with metadata and payload.*/
+static void test_cacheable_request_response_with_metadata_and_payload(
+    grpc_end2end_test_config config) {
+  grpc_call *c;
+  grpc_call *s;
+  gpr_slice request_payload_slice = gpr_slice_from_copied_string("hello world");
+  gpr_slice response_payload_slice = gpr_slice_from_copied_string("hello you");
+  grpc_byte_buffer *request_payload =
+      grpc_raw_byte_buffer_create(&request_payload_slice, 1);
+  grpc_byte_buffer *response_payload =
+      grpc_raw_byte_buffer_create(&response_payload_slice, 1);
+  gpr_timespec deadline = five_seconds_time();
+  grpc_metadata meta_c[2] = {
+      {"key1", "val1", 4, 0, {{NULL, NULL, NULL, NULL}}},
+      {"key2", "val2", 4, 0, {{NULL, NULL, NULL, NULL}}}};
+  grpc_metadata meta_s[2] = {
+      {"key3", "val3", 4, 0, {{NULL, NULL, NULL, NULL}}},
+      {"key4", "val4", 4, 0, {{NULL, NULL, NULL, NULL}}}};
+  grpc_end2end_test_fixture f = begin_test(
+      config, "test_cacheable_request_response_with_metadata_and_payload", NULL,
+      NULL);
+  cq_verifier *cqv = cq_verifier_create(f.cq);
+  grpc_op ops[6];
+  grpc_op *op;
+  grpc_metadata_array initial_metadata_recv;
+  grpc_metadata_array trailing_metadata_recv;
+  grpc_metadata_array request_metadata_recv;
+  grpc_byte_buffer *request_payload_recv = NULL;
+  grpc_byte_buffer *response_payload_recv = NULL;
+  grpc_call_details call_details;
+  grpc_status_code status;
+  grpc_call_error error;
+  char *details = NULL;
+  size_t details_capacity = 0;
+  int was_cancelled = 2;
+
+  c = grpc_channel_create_call(f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
+                               "/foo", "foo.test.google.fr", deadline, NULL);
+  GPR_ASSERT(c);
+
+  grpc_metadata_array_init(&initial_metadata_recv);
+  grpc_metadata_array_init(&trailing_metadata_recv);
+  grpc_metadata_array_init(&request_metadata_recv);
+  grpc_call_details_init(&call_details);
+
+  memset(ops, 0, sizeof(ops));
+  op = ops;
+  op->op = GRPC_OP_SEND_INITIAL_METADATA;
+  op->data.send_initial_metadata.count = 2;
+  op->data.send_initial_metadata.metadata = meta_c;
+  op->flags = GRPC_INITIAL_METADATA_CACHEABLE_REQUEST;
+  op->reserved = NULL;
+  op++;
+  op->op = GRPC_OP_SEND_MESSAGE;
+  op->data.send_message = request_payload;
+  op->flags = 0;
+  op->reserved = NULL;
+  op++;
+  op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
+  op->flags = 0;
+  op->reserved = NULL;
+  op++;
+  op->op = GRPC_OP_RECV_INITIAL_METADATA;
+  op->data.recv_initial_metadata = &initial_metadata_recv;
+  op->flags = 0;
+  op->reserved = NULL;
+  op++;
+  op->op = GRPC_OP_RECV_MESSAGE;
+  op->data.recv_message = &response_payload_recv;
+  op->flags = 0;
+  op->reserved = NULL;
+  op++;
+  op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
+  op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
+  op->data.recv_status_on_client.status = &status;
+  op->data.recv_status_on_client.status_details = &details;
+  op->data.recv_status_on_client.status_details_capacity = &details_capacity;
+  op->flags = 0;
+  op->reserved = NULL;
+  op++;
+  error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), NULL);
+  GPR_ASSERT(GRPC_CALL_OK == error);
+
+  error =
+      grpc_server_request_call(f.server, &s, &call_details,
+                               &request_metadata_recv, f.cq, f.cq, tag(101));
+  GPR_ASSERT(GRPC_CALL_OK == error);
+  CQ_EXPECT_COMPLETION(cqv, tag(101), 1);
+  cq_verify(cqv);
+
+  memset(ops, 0, sizeof(ops));
+  op = ops;
+  op->op = GRPC_OP_SEND_INITIAL_METADATA;
+  op->data.send_initial_metadata.count = 2;
+  op->data.send_initial_metadata.metadata = meta_s;
+  op->flags = 0;
+  op->reserved = NULL;
+  op++;
+  op->op = GRPC_OP_RECV_MESSAGE;
+  op->data.recv_message = &request_payload_recv;
+  op->flags = 0;
+  op->reserved = NULL;
+  op++;
+  error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), NULL);
+  GPR_ASSERT(GRPC_CALL_OK == error);
+
+  CQ_EXPECT_COMPLETION(cqv, tag(102), 1);
+  cq_verify(cqv);
+
+  memset(ops, 0, sizeof(ops));
+  op = ops;
+  op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
+  op->data.recv_close_on_server.cancelled = &was_cancelled;
+  op->flags = 0;
+  op->reserved = NULL;
+  op++;
+  op->op = GRPC_OP_SEND_MESSAGE;
+  op->data.send_message = response_payload;
+  op->flags = 0;
+  op->reserved = NULL;
+  op++;
+  op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
+  op->data.send_status_from_server.trailing_metadata_count = 0;
+  op->data.send_status_from_server.status = GRPC_STATUS_OK;
+  op->data.send_status_from_server.status_details = "xyz";
+  op->flags = 0;
+  op->reserved = NULL;
+  op++;
+  error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(103), NULL);
+  GPR_ASSERT(GRPC_CALL_OK == error);
+
+  CQ_EXPECT_COMPLETION(cqv, tag(103), 1);
+  CQ_EXPECT_COMPLETION(cqv, tag(1), 1);
+  cq_verify(cqv);
+
+  GPR_ASSERT(status == GRPC_STATUS_OK);
+  GPR_ASSERT(0 == strcmp(details, "xyz"));
+  GPR_ASSERT(0 == strcmp(call_details.method, "/foo"));
+  GPR_ASSERT(0 == strcmp(call_details.host, "foo.test.google.fr"));
+  if (config.feature_mask & FEATURE_MASK_SUPPORTS_REQUEST_PROXYING) {
+    // Our simple proxy does not support cacheable requests
+  } else {
+    GPR_ASSERT(GRPC_INITIAL_METADATA_CACHEABLE_REQUEST & call_details.flags);
+  }
+  GPR_ASSERT(was_cancelled == 0);
+  GPR_ASSERT(byte_buffer_eq_string(request_payload_recv, "hello world"));
+  GPR_ASSERT(byte_buffer_eq_string(response_payload_recv, "hello you"));
+  GPR_ASSERT(contains_metadata(&request_metadata_recv, "key1", "val1"));
+  GPR_ASSERT(contains_metadata(&request_metadata_recv, "key2", "val2"));
+  GPR_ASSERT(contains_metadata(&initial_metadata_recv, "key3", "val3"));
+  GPR_ASSERT(contains_metadata(&initial_metadata_recv, "key4", "val4"));
+
+  gpr_free(details);
+  grpc_metadata_array_destroy(&initial_metadata_recv);
+  grpc_metadata_array_destroy(&trailing_metadata_recv);
+  grpc_metadata_array_destroy(&request_metadata_recv);
+  grpc_call_details_destroy(&call_details);
+
+  grpc_call_destroy(c);
+  grpc_call_destroy(s);
+
+  cq_verifier_destroy(cqv);
+
+  grpc_byte_buffer_destroy(request_payload);
+  grpc_byte_buffer_destroy(response_payload);
+  grpc_byte_buffer_destroy(request_payload_recv);
+  grpc_byte_buffer_destroy(response_payload_recv);
+
+  end_test(&f);
+  config.tear_down_data(&f);
+}
+
+void simple_cacheable_request(grpc_end2end_test_config config) {
+  test_cacheable_request_response_with_metadata_and_payload(config);
+}
+
+void simple_cacheable_request_pre_init(void) {}
diff --git a/test/core/support/percent_decode_corpus/04cb8ccc553f9b2f5e52c421aff6d1c954d3dae6 b/test/core/support/percent_decode_corpus/04cb8ccc553f9b2f5e52c421aff6d1c954d3dae6
new file mode 100644
index 0000000..a0c7605
--- /dev/null
+++ b/test/core/support/percent_decode_corpus/04cb8ccc553f9b2f5e52c421aff6d1c954d3dae6
@@ -0,0 +1 @@
+:Ê%cE'yzŠ
\ No newline at end of file
diff --git a/test/core/support/percent_decode_corpus/0dd8f3a63745b3a2d39791559b5c1b311447b537 b/test/core/support/percent_decode_corpus/0dd8f3a63745b3a2d39791559b5c1b311447b537
new file mode 100644
index 0000000..8b36124
--- /dev/null
+++ b/test/core/support/percent_decode_corpus/0dd8f3a63745b3a2d39791559b5c1b311447b537
@@ -0,0 +1 @@
+x;x_%C88
\ No newline at end of file
diff --git a/test/core/support/percent_decode_corpus/17eeaca784409adbe43365c32ac87915d736bba3 b/test/core/support/percent_decode_corpus/17eeaca784409adbe43365c32ac87915d736bba3
new file mode 100644
index 0000000..ea02afa
--- /dev/null
+++ b/test/core/support/percent_decode_corpus/17eeaca784409adbe43365c32ac87915d736bba3
@@ -0,0 +1,2 @@
+xxyyz%øyzŠ[zxy'z
+
diff --git a/test/core/support/percent_decode_corpus/2040c1ff65f52a7ae668c2c8f324de5dacc9d695 b/test/core/support/percent_decode_corpus/2040c1ff65f52a7ae668c2c8f324de5dacc9d695
new file mode 100644
index 0000000..9e9b466
--- /dev/null
+++ b/test/core/support/percent_decode_corpus/2040c1ff65f52a7ae668c2c8f324de5dacc9d695
@@ -0,0 +1 @@
+xx;x_%;:Ê%C)x_%C88c8E'yzŠ8
\ No newline at end of file
diff --git a/test/core/support/percent_decode_corpus/26b0d1da23027ae54db96e125e4a9e98842d77fb b/test/core/support/percent_decode_corpus/26b0d1da23027ae54db96e125e4a9e98842d77fb
new file mode 100644
index 0000000..88c739e
--- /dev/null
+++ b/test/core/support/percent_decode_corpus/26b0d1da23027ae54db96e125e4a9e98842d77fb
@@ -0,0 +1 @@
+))'x;x_%C88xy(Pyz)
\ No newline at end of file
diff --git a/test/core/support/percent_decode_corpus/2a089c0db45acdb4c6ed8e7ff81ca7235792c0b9 b/test/core/support/percent_decode_corpus/2a089c0db45acdb4c6ed8e7ff81ca7235792c0b9
new file mode 100644
index 0000000..5e6f546
--- /dev/null
+++ b/test/core/support/percent_decode_corpus/2a089c0db45acdb4c6ed8e7ff81ca7235792c0b9
@@ -0,0 +1 @@
+_x;x)x;x_x;x_%88%8888:
\ No newline at end of file
diff --git a/test/core/support/percent_decode_corpus/35b7b3bc3a740d5c3abca0d75b53f0e1e1ee998a b/test/core/support/percent_decode_corpus/35b7b3bc3a740d5c3abca0d75b53f0e1e1ee998a
new file mode 100644
index 0000000..71d688b
--- /dev/null
+++ b/test/core/support/percent_decode_corpus/35b7b3bc3a740d5c3abca0d75b53f0e1e1ee998a
@@ -0,0 +1 @@
+x8
\ No newline at end of file
diff --git a/test/core/support/percent_decode_corpus/36367ba1adba47a1cbc3a88707fde8cc7abdc248 b/test/core/support/percent_decode_corpus/36367ba1adba47a1cbc3a88707fde8cc7abdc248
new file mode 100644
index 0000000..5a89a07
--- /dev/null
+++ b/test/core/support/percent_decode_corpus/36367ba1adba47a1cbc3a88707fde8cc7abdc248
@@ -0,0 +1 @@
+x);x(_%88x;x_%88
\ No newline at end of file
diff --git a/test/core/support/percent_decode_corpus/39c2ba51548a0beaf0d6d1164531f1447dc311b5 b/test/core/support/percent_decode_corpus/39c2ba51548a0beaf0d6d1164531f1447dc311b5
new file mode 100644
index 0000000..cfa2be9
--- /dev/null
+++ b/test/core/support/percent_decode_corpus/39c2ba51548a0beaf0d6d1164531f1447dc311b5
@@ -0,0 +1 @@
+)x;x_x;x_%88%88:
\ No newline at end of file
diff --git a/test/core/support/percent_decode_corpus/56d08fea787c041395c6697ce26cfbc0decbe688 b/test/core/support/percent_decode_corpus/56d08fea787c041395c6697ce26cfbc0decbe688
new file mode 100644
index 0000000..c1ddf65
--- /dev/null
+++ b/test/core/support/percent_decode_corpus/56d08fea787c041395c6697ce26cfbc0decbe688
@@ -0,0 +1 @@
+%cyzŠ
\ No newline at end of file
diff --git a/test/core/support/percent_decode_corpus/678d981fdabb9f0d6640235cf1719dd1e1e66ae9 b/test/core/support/percent_decode_corpus/678d981fdabb9f0d6640235cf1719dd1e1e66ae9
new file mode 100644
index 0000000..dc427d1
--- /dev/null
+++ b/test/core/support/percent_decode_corpus/678d981fdabb9f0d6640235cf1719dd1e1e66ae9
@@ -0,0 +1 @@
+%øyzŠ
\ No newline at end of file
diff --git a/test/core/support/percent_decode_corpus/68751961609ec010565de0aa87521dcbf0722c5d b/test/core/support/percent_decode_corpus/68751961609ec010565de0aa87521dcbf0722c5d
new file mode 100644
index 0000000..154449d
--- /dev/null
+++ b/test/core/support/percent_decode_corpus/68751961609ec010565de0aa87521dcbf0722c5d
@@ -0,0 +1 @@
+Ê:%Ec
\ No newline at end of file
diff --git a/test/core/support/percent_decode_corpus/7875c06c6f03c9aa2f8e9c59f8d8957c8a32e759 b/test/core/support/percent_decode_corpus/7875c06c6f03c9aa2f8e9c59f8d8957c8a32e759
new file mode 100644
index 0000000..841ced8
--- /dev/null
+++ b/test/core/support/percent_decode_corpus/7875c06c6f03c9aa2f8e9c59f8d8957c8a32e759
@@ -0,0 +1,2 @@
+xxyyz!úyzŠ[zxy'zyz
+Š
diff --git a/test/core/support/percent_decode_corpus/7b302090e090a5829b6d1dd7be30bd4e36a7e60f b/test/core/support/percent_decode_corpus/7b302090e090a5829b6d1dd7be30bd4e36a7e60f
new file mode 100644
index 0000000..6790bc2
--- /dev/null
+++ b/test/core/support/percent_decode_corpus/7b302090e090a5829b6d1dd7be30bd4e36a7e60f
@@ -0,0 +1 @@
+x;:Ê%)x_%C8cE'yzŠ8
\ No newline at end of file
diff --git a/test/core/support/percent_decode_corpus/875e1022169c9e4c541a9ad894e69e989df22ba1 b/test/core/support/percent_decode_corpus/875e1022169c9e4c541a9ad894e69e989df22ba1
new file mode 100644
index 0000000..1625d0a
--- /dev/null
+++ b/test/core/support/percent_decode_corpus/875e1022169c9e4c541a9ad894e69e989df22ba1
@@ -0,0 +1 @@
+x;x_%88
\ No newline at end of file
diff --git a/test/core/support/percent_decode_corpus/8c1051ce066f5a26de9a9d133180621d0da957b4 b/test/core/support/percent_decode_corpus/8c1051ce066f5a26de9a9d133180621d0da957b4
new file mode 100644
index 0000000..125c330
--- /dev/null
+++ b/test/core/support/percent_decode_corpus/8c1051ce066f5a26de9a9d133180621d0da957b4
@@ -0,0 +1 @@
+)))'x;x_%C88)'x;x_%C89xyyzxyyz)
\ No newline at end of file
diff --git a/test/core/support/percent_decode_corpus/8e084e628ab83a18ac7ca7cb3506525263655c63 b/test/core/support/percent_decode_corpus/8e084e628ab83a18ac7ca7cb3506525263655c63
new file mode 100644
index 0000000..6e6f08c
--- /dev/null
+++ b/test/core/support/percent_decode_corpus/8e084e628ab83a18ac7ca7cb3506525263655c63
@@ -0,0 +1 @@
+))'x;x_%C88xyyz)
\ No newline at end of file
diff --git a/test/core/support/percent_decode_corpus/9d316c4675f40ddccaf8f1cc7aea94170b1e4223 b/test/core/support/percent_decode_corpus/9d316c4675f40ddccaf8f1cc7aea94170b1e4223
new file mode 100644
index 0000000..ab4a1c7
--- /dev/null
+++ b/test/core/support/percent_decode_corpus/9d316c4675f40ddccaf8f1cc7aea94170b1e4223
@@ -0,0 +1 @@
+x%8
\ No newline at end of file
diff --git a/test/core/support/percent_decode_corpus/ad1c7c11d18a7d116e2c2ef4d4c5afb1270836ae b/test/core/support/percent_decode_corpus/ad1c7c11d18a7d116e2c2ef4d4c5afb1270836ae
new file mode 100644
index 0000000..4ac1945
--- /dev/null
+++ b/test/core/support/percent_decode_corpus/ad1c7c11d18a7d116e2c2ef4d4c5afb1270836ae
@@ -0,0 +1 @@
+x);x(_%88x;x_xxyyz
\ No newline at end of file
diff --git a/test/core/support/percent_decode_corpus/b471f94aa4facf502e622e4a248f1ba4063ae681 b/test/core/support/percent_decode_corpus/b471f94aa4facf502e622e4a248f1ba4063ae681
new file mode 100644
index 0000000..5c673ae
--- /dev/null
+++ b/test/core/support/percent_decode_corpus/b471f94aa4facf502e622e4a248f1ba4063ae681
@@ -0,0 +1 @@
+Ê%ccyzyzŠ
\ No newline at end of file
diff --git a/test/core/support/percent_decode_corpus/bf52ece030f16136d46e0dc97f58d60a0d8a1f0b b/test/core/support/percent_decode_corpus/bf52ece030f16136d46e0dc97f58d60a0d8a1f0b
new file mode 100644
index 0000000..e478275
--- /dev/null
+++ b/test/core/support/percent_decode_corpus/bf52ece030f16136d46e0dc97f58d60a0d8a1f0b
@@ -0,0 +1,2 @@
+)'xyyz!úyzŠ[zxÊ%ccyzyzy'z*zŠ
+Š
diff --git a/test/core/support/percent_decode_corpus/d5b2a7177339ba2b7ce2f60e5f4459bef1e72758 b/test/core/support/percent_decode_corpus/d5b2a7177339ba2b7ce2f60e5f4459bef1e72758
new file mode 100644
index 0000000..c73cbfe
--- /dev/null
+++ b/test/core/support/percent_decode_corpus/d5b2a7177339ba2b7ce2f60e5f4459bef1e72758
@@ -0,0 +1,2 @@
+)'xyyz)úyzŠ[zxÊ%cCyzyzy'z*zŠ
+Š
diff --git a/test/core/support/percent_decode_corpus/de867b64c54a7ed773dc611fc5cd2f17c5433113 b/test/core/support/percent_decode_corpus/de867b64c54a7ed773dc611fc5cd2f17c5433113
new file mode 100644
index 0000000..f9f7246
--- /dev/null
+++ b/test/core/support/percent_decode_corpus/de867b64c54a7ed773dc611fc5cd2f17c5433113
@@ -0,0 +1,2 @@
+xxyyz%%øyzŠ[zxy'zyz
+Š
diff --git a/test/core/support/percent_decode_corpus/e3948dbe004950591630dd5c52f4e0fcbd5e388a b/test/core/support/percent_decode_corpus/e3948dbe004950591630dd5c52f4e0fcbd5e388a
new file mode 100644
index 0000000..83ac46d
--- /dev/null
+++ b/test/core/support/percent_decode_corpus/e3948dbe004950591630dd5c52f4e0fcbd5e388a
@@ -0,0 +1 @@
+Ê:%Dx;:Ê%)x_%C8cc
\ No newline at end of file
diff --git a/test/core/support/percent_decode_corpus/e7064f0b80f61dbc65915311032d27baa569ae2a b/test/core/support/percent_decode_corpus/e7064f0b80f61dbc65915311032d27baa569ae2a
new file mode 100644
index 0000000..e8a0f87
--- /dev/null
+++ b/test/core/support/percent_decode_corpus/e7064f0b80f61dbc65915311032d27baa569ae2a
@@ -0,0 +1 @@
+)
\ No newline at end of file
diff --git a/test/core/support/percent_decode_corpus/xyz b/test/core/support/percent_decode_corpus/xyz
new file mode 100644
index 0000000..cd470e6
--- /dev/null
+++ b/test/core/support/percent_decode_corpus/xyz
@@ -0,0 +1 @@
+xyz
diff --git a/test/core/support/percent_decode_fuzzer.c b/test/core/support/percent_decode_fuzzer.c
new file mode 100644
index 0000000..3e02980
--- /dev/null
+++ b/test/core/support/percent_decode_fuzzer.c
@@ -0,0 +1,66 @@
+/*
+ *
+ * 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 <stdbool.h>
+#include <stdint.h>
+#include <string.h>
+
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+
+#include "src/core/lib/support/percent_encoding.h"
+#include "test/core/util/memory_counters.h"
+
+bool squelch = true;
+bool leak_check = true;
+
+int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
+  struct grpc_memory_counters counters;
+  grpc_memory_counters_init();
+  gpr_slice input = gpr_slice_from_copied_buffer((const char *)data, size);
+  gpr_slice output;
+  if (gpr_strict_percent_decode_slice(
+          input, gpr_url_percent_encoding_unreserved_bytes, &output)) {
+    gpr_slice_unref(output);
+  }
+  if (gpr_strict_percent_decode_slice(
+          input, gpr_compatible_percent_encoding_unreserved_bytes, &output)) {
+    gpr_slice_unref(output);
+  }
+  gpr_slice_unref(gpr_permissive_percent_decode_slice(input));
+  gpr_slice_unref(input);
+  counters = grpc_memory_counters_snapshot();
+  grpc_memory_counters_destroy();
+  GPR_ASSERT(counters.total_size_relative == 0);
+  return 0;
+}
diff --git a/test/core/support/percent_encode_corpus/0d3ee7fa54e6c66103965fd4409b044ba7db6c3f b/test/core/support/percent_encode_corpus/0d3ee7fa54e6c66103965fd4409b044ba7db6c3f
new file mode 100644
index 0000000..d09c4a0
--- /dev/null
+++ b/test/core/support/percent_encode_corpus/0d3ee7fa54e6c66103965fd4409b044ba7db6c3f
@@ -0,0 +1,3 @@
+_x;7y
+xyz')S)xy-zý
+Æ*
\ No newline at end of file
diff --git a/test/core/support/percent_encode_corpus/2e7ccf75e27b9501e3b28cf1c50ed0c45ab7c226 b/test/core/support/percent_encode_corpus/2e7ccf75e27b9501e3b28cf1c50ed0c45ab7c226
new file mode 100644
index 0000000..4d0c38d
--- /dev/null
+++ b/test/core/support/percent_encode_corpus/2e7ccf75e27b9501e3b28cf1c50ed0c45ab7c226
@@ -0,0 +1 @@
+xyx
\ No newline at end of file
diff --git a/test/core/support/percent_encode_corpus/55bb859f3942c462b03b7cbcf22ab4a0ac9705cf b/test/core/support/percent_encode_corpus/55bb859f3942c462b03b7cbcf22ab4a0ac9705cf
new file mode 100644
index 0000000..fc6e933
--- /dev/null
+++ b/test/core/support/percent_encode_corpus/55bb859f3942c462b03b7cbcf22ab4a0ac9705cf
@@ -0,0 +1 @@
+.yx.yxxxyzxyyzxy
\ No newline at end of file
diff --git a/test/core/support/percent_encode_corpus/56070cecd54c845b6d4334953b17b712eb000d93 b/test/core/support/percent_encode_corpus/56070cecd54c845b6d4334953b17b712eb000d93
new file mode 100644
index 0000000..6823c73
--- /dev/null
+++ b/test/core/support/percent_encode_corpus/56070cecd54c845b6d4334953b17b712eb000d93
@@ -0,0 +1 @@
+xyrxyxyzxxyzxyzxyxyy
\ No newline at end of file
diff --git a/test/core/support/percent_encode_corpus/61f50e891bf7ff5eb7a7af206f1e25d77f8756e7 b/test/core/support/percent_encode_corpus/61f50e891bf7ff5eb7a7af206f1e25d77f8756e7
new file mode 100644
index 0000000..a65cbb4
--- /dev/null
+++ b/test/core/support/percent_encode_corpus/61f50e891bf7ff5eb7a7af206f1e25d77f8756e7
@@ -0,0 +1,3 @@
+xy
+xyz
+)S-Æþ
\ No newline at end of file
diff --git a/test/core/support/percent_encode_corpus/6e0c60cefc704c7940e475a87dd9ae423061cb5a b/test/core/support/percent_encode_corpus/6e0c60cefc704c7940e475a87dd9ae423061cb5a
new file mode 100644
index 0000000..8d031d7
--- /dev/null
+++ b/test/core/support/percent_encode_corpus/6e0c60cefc704c7940e475a87dd9ae423061cb5a
@@ -0,0 +1,3 @@
+xy
+xyz
+)S)Æ*
\ No newline at end of file
diff --git a/test/core/support/percent_encode_corpus/7271ebcc6d22a0f186f7bc3c1973a7ed1bec8d8e b/test/core/support/percent_encode_corpus/7271ebcc6d22a0f186f7bc3c1973a7ed1bec8d8e
new file mode 100644
index 0000000..4d82ca3
--- /dev/null
+++ b/test/core/support/percent_encode_corpus/7271ebcc6d22a0f186f7bc3c1973a7ed1bec8d8e
@@ -0,0 +1,4 @@
+x;7y
+xyz
+)S)xyz
+Æ*
\ No newline at end of file
diff --git a/test/core/support/percent_encode_corpus/74c83ece3e2920a67593a9be9c82468f16cbb969 b/test/core/support/percent_encode_corpus/74c83ece3e2920a67593a9be9c82468f16cbb969
new file mode 100644
index 0000000..bb7f4ae
--- /dev/null
+++ b/test/core/support/percent_encode_corpus/74c83ece3e2920a67593a9be9c82468f16cbb969
@@ -0,0 +1 @@
+xyzxy
\ No newline at end of file
diff --git a/test/core/support/percent_encode_corpus/98e004fd2a9f141a7a019720820080e12d637c06 b/test/core/support/percent_encode_corpus/98e004fd2a9f141a7a019720820080e12d637c06
new file mode 100644
index 0000000..50879d0
--- /dev/null
+++ b/test/core/support/percent_encode_corpus/98e004fd2a9f141a7a019720820080e12d637c06
@@ -0,0 +1,3 @@
+xy
+xz
+)Sxy-Æzx_yþ
\ No newline at end of file
diff --git a/test/core/support/percent_encode_corpus/ba2c1e98227aa21ea3bb2ca4d0e504119717da8b b/test/core/support/percent_encode_corpus/ba2c1e98227aa21ea3bb2ca4d0e504119717da8b
new file mode 100644
index 0000000..dc1ab9b
--- /dev/null
+++ b/test/core/support/percent_encode_corpus/ba2c1e98227aa21ea3bb2ca4d0e504119717da8b
@@ -0,0 +1,3 @@
+_x;7y
+xyz')S)xyz
+Æ*
\ No newline at end of file
diff --git a/test/core/support/percent_encode_corpus/c16b9fd45370d4afb5d3ebd307a6e263c25ffd45 b/test/core/support/percent_encode_corpus/c16b9fd45370d4afb5d3ebd307a6e263c25ffd45
new file mode 100644
index 0000000..3476e0b
--- /dev/null
+++ b/test/core/support/percent_encode_corpus/c16b9fd45370d4afb5d3ebd307a6e263c25ffd45
@@ -0,0 +1,2 @@
+xyz
+)S
\ No newline at end of file
diff --git a/test/core/support/percent_encode_corpus/d58c3cd4eab9b6d2343abfa1c25c90a383fe0ec3 b/test/core/support/percent_encode_corpus/d58c3cd4eab9b6d2343abfa1c25c90a383fe0ec3
new file mode 100644
index 0000000..822d50a
--- /dev/null
+++ b/test/core/support/percent_encode_corpus/d58c3cd4eab9b6d2343abfa1c25c90a383fe0ec3
@@ -0,0 +1 @@
+.yx
\ No newline at end of file
diff --git a/test/core/support/percent_encode_corpus/e2619218ede30d2b7b8ecd601a9f0ae754b728b4 b/test/core/support/percent_encode_corpus/e2619218ede30d2b7b8ecd601a9f0ae754b728b4
new file mode 100644
index 0000000..101639c
--- /dev/null
+++ b/test/core/support/percent_encode_corpus/e2619218ede30d2b7b8ecd601a9f0ae754b728b4
@@ -0,0 +1,4 @@
+x;y
+xyz
+)S)xyz
+Æ*
\ No newline at end of file
diff --git a/test/core/support/percent_encode_corpus/f93b3653e453f0e3eea3198001be6ce46e64bd21 b/test/core/support/percent_encode_corpus/f93b3653e453f0e3eea3198001be6ce46e64bd21
new file mode 100644
index 0000000..6e07ab3
--- /dev/null
+++ b/test/core/support/percent_encode_corpus/f93b3653e453f0e3eea3198001be6ce46e64bd21
@@ -0,0 +1,5 @@
+x;y
+xøyz
+)S)xyz
+Æ.y~
+)S
\ No newline at end of file
diff --git a/test/core/support/percent_encode_corpus/fd41d029c7682ad3d1c40a9fd017a4c85b673a54 b/test/core/support/percent_encode_corpus/fd41d029c7682ad3d1c40a9fd017a4c85b673a54
new file mode 100644
index 0000000..13d7fab
--- /dev/null
+++ b/test/core/support/percent_encode_corpus/fd41d029c7682ad3d1c40a9fd017a4c85b673a54
@@ -0,0 +1,3 @@
+xy
+xyz
+)S)S
\ No newline at end of file
diff --git a/test/core/support/percent_encode_corpus/xyz b/test/core/support/percent_encode_corpus/xyz
new file mode 100644
index 0000000..cd470e6
--- /dev/null
+++ b/test/core/support/percent_encode_corpus/xyz
@@ -0,0 +1 @@
+xyz
diff --git a/test/core/support/percent_encode_fuzzer.c b/test/core/support/percent_encode_fuzzer.c
new file mode 100644
index 0000000..c954823
--- /dev/null
+++ b/test/core/support/percent_encode_fuzzer.c
@@ -0,0 +1,73 @@
+/*
+ *
+ * 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 <stdbool.h>
+#include <stdint.h>
+#include <string.h>
+
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+
+#include "src/core/lib/support/percent_encoding.h"
+#include "test/core/util/memory_counters.h"
+
+bool squelch = true;
+bool leak_check = true;
+
+static void test(const uint8_t *data, size_t size, const uint8_t *dict) {
+  struct grpc_memory_counters counters;
+  grpc_memory_counters_init();
+  gpr_slice input = gpr_slice_from_copied_buffer((const char *)data, size);
+  gpr_slice output = gpr_percent_encode_slice(input, dict);
+  gpr_slice decoded_output;
+  // encoder must always produce decodable output
+  GPR_ASSERT(gpr_strict_percent_decode_slice(output, dict, &decoded_output));
+  gpr_slice permissive_decoded_output =
+      gpr_permissive_percent_decode_slice(output);
+  // and decoded output must always match the input
+  GPR_ASSERT(gpr_slice_cmp(input, decoded_output) == 0);
+  GPR_ASSERT(gpr_slice_cmp(input, permissive_decoded_output) == 0);
+  gpr_slice_unref(input);
+  gpr_slice_unref(output);
+  gpr_slice_unref(decoded_output);
+  gpr_slice_unref(permissive_decoded_output);
+  counters = grpc_memory_counters_snapshot();
+  grpc_memory_counters_destroy();
+  GPR_ASSERT(counters.total_size_relative == 0);
+}
+
+int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
+  test(data, size, gpr_url_percent_encoding_unreserved_bytes);
+  test(data, size, gpr_compatible_percent_encoding_unreserved_bytes);
+  return 0;
+}
diff --git a/test/core/support/percent_encoding_test.c b/test/core/support/percent_encoding_test.c
new file mode 100644
index 0000000..ab5f3f2
--- /dev/null
+++ b/test/core/support/percent_encoding_test.c
@@ -0,0 +1,157 @@
+/*
+ *
+ * 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/lib/support/percent_encoding.h"
+
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+
+#include "src/core/lib/support/string.h"
+#include "test/core/util/test_config.h"
+
+#define TEST_VECTOR(raw, encoded, dict) \
+  test_vector(raw, sizeof(raw) - 1, encoded, sizeof(encoded) - 1, dict)
+
+#define TEST_NONCONFORMANT_VECTOR(encoded, permissive_unencoded, dict) \
+  test_nonconformant_vector(encoded, sizeof(encoded) - 1,              \
+                            permissive_unencoded,                      \
+                            sizeof(permissive_unencoded) - 1, dict)
+
+static void test_vector(const char *raw, size_t raw_length, const char *encoded,
+                        size_t encoded_length, const uint8_t *dict) {
+  char *raw_msg = gpr_dump(raw, raw_length, GPR_DUMP_HEX | GPR_DUMP_ASCII);
+  char *encoded_msg =
+      gpr_dump(encoded, encoded_length, GPR_DUMP_HEX | GPR_DUMP_ASCII);
+  gpr_log(GPR_DEBUG, "Trial:\nraw = %s\nencoded = %s", raw_msg, encoded_msg);
+  gpr_free(raw_msg);
+  gpr_free(encoded_msg);
+
+  gpr_slice raw_slice = gpr_slice_from_copied_buffer(raw, raw_length);
+  gpr_slice encoded_slice =
+      gpr_slice_from_copied_buffer(encoded, encoded_length);
+  gpr_slice raw2encoded_slice = gpr_percent_encode_slice(raw_slice, dict);
+  gpr_slice encoded2raw_slice;
+  GPR_ASSERT(
+      gpr_strict_percent_decode_slice(encoded_slice, dict, &encoded2raw_slice));
+  gpr_slice encoded2raw_permissive_slice =
+      gpr_permissive_percent_decode_slice(encoded_slice);
+
+  char *raw2encoded_msg =
+      gpr_dump_slice(raw2encoded_slice, GPR_DUMP_HEX | GPR_DUMP_ASCII);
+  char *encoded2raw_msg =
+      gpr_dump_slice(encoded2raw_slice, GPR_DUMP_HEX | GPR_DUMP_ASCII);
+  char *encoded2raw_permissive_msg = gpr_dump_slice(
+      encoded2raw_permissive_slice, GPR_DUMP_HEX | GPR_DUMP_ASCII);
+  gpr_log(GPR_DEBUG,
+          "Result:\nraw2encoded = %s\nencoded2raw = %s\nencoded2raw_permissive "
+          "= %s",
+          raw2encoded_msg, encoded2raw_msg, encoded2raw_permissive_msg);
+  gpr_free(raw2encoded_msg);
+  gpr_free(encoded2raw_msg);
+  gpr_free(encoded2raw_permissive_msg);
+
+  GPR_ASSERT(0 == gpr_slice_cmp(raw_slice, encoded2raw_slice));
+  GPR_ASSERT(0 == gpr_slice_cmp(raw_slice, encoded2raw_permissive_slice));
+  GPR_ASSERT(0 == gpr_slice_cmp(encoded_slice, raw2encoded_slice));
+
+  gpr_slice_unref(encoded2raw_slice);
+  gpr_slice_unref(encoded2raw_permissive_slice);
+  gpr_slice_unref(raw2encoded_slice);
+  gpr_slice_unref(raw_slice);
+  gpr_slice_unref(encoded_slice);
+}
+
+static void test_nonconformant_vector(const char *encoded,
+                                      size_t encoded_length,
+                                      const char *permissive_unencoded,
+                                      size_t permissive_unencoded_length,
+                                      const uint8_t *dict) {
+  char *permissive_unencoded_msg =
+      gpr_dump(permissive_unencoded, permissive_unencoded_length,
+               GPR_DUMP_HEX | GPR_DUMP_ASCII);
+  char *encoded_msg =
+      gpr_dump(encoded, encoded_length, GPR_DUMP_HEX | GPR_DUMP_ASCII);
+  gpr_log(GPR_DEBUG, "Trial:\nraw = %s\nencoded = %s", permissive_unencoded_msg,
+          encoded_msg);
+  gpr_free(permissive_unencoded_msg);
+  gpr_free(encoded_msg);
+
+  gpr_slice permissive_unencoded_slice = gpr_slice_from_copied_buffer(
+      permissive_unencoded, permissive_unencoded_length);
+  gpr_slice encoded_slice =
+      gpr_slice_from_copied_buffer(encoded, encoded_length);
+  gpr_slice encoded2raw_slice;
+  GPR_ASSERT(!gpr_strict_percent_decode_slice(encoded_slice, dict,
+                                              &encoded2raw_slice));
+  gpr_slice encoded2raw_permissive_slice =
+      gpr_permissive_percent_decode_slice(encoded_slice);
+
+  char *encoded2raw_permissive_msg = gpr_dump_slice(
+      encoded2raw_permissive_slice, GPR_DUMP_HEX | GPR_DUMP_ASCII);
+  gpr_log(GPR_DEBUG, "Result:\nencoded2raw_permissive = %s",
+          encoded2raw_permissive_msg);
+  gpr_free(encoded2raw_permissive_msg);
+
+  GPR_ASSERT(0 == gpr_slice_cmp(permissive_unencoded_slice,
+                                encoded2raw_permissive_slice));
+
+  gpr_slice_unref(permissive_unencoded_slice);
+  gpr_slice_unref(encoded2raw_permissive_slice);
+  gpr_slice_unref(encoded_slice);
+}
+
+int main(int argc, char **argv) {
+  grpc_test_init(argc, argv);
+  TEST_VECTOR(
+      "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.~",
+      "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.~",
+      gpr_url_percent_encoding_unreserved_bytes);
+  TEST_VECTOR("\x00", "%00", gpr_url_percent_encoding_unreserved_bytes);
+  TEST_VECTOR("\x01", "%01", gpr_url_percent_encoding_unreserved_bytes);
+  TEST_VECTOR("a b", "a%20b", gpr_url_percent_encoding_unreserved_bytes);
+  TEST_VECTOR(" b", "%20b", gpr_url_percent_encoding_unreserved_bytes);
+  TEST_VECTOR("a b", "a b", gpr_compatible_percent_encoding_unreserved_bytes);
+  TEST_VECTOR(" b", " b", gpr_compatible_percent_encoding_unreserved_bytes);
+  TEST_VECTOR("\x0f", "%0F", gpr_url_percent_encoding_unreserved_bytes);
+  TEST_VECTOR("\xff", "%FF", gpr_url_percent_encoding_unreserved_bytes);
+  TEST_VECTOR("\xee", "%EE", gpr_url_percent_encoding_unreserved_bytes);
+  TEST_NONCONFORMANT_VECTOR("%", "%",
+                            gpr_url_percent_encoding_unreserved_bytes);
+  TEST_NONCONFORMANT_VECTOR("%A", "%A",
+                            gpr_url_percent_encoding_unreserved_bytes);
+  TEST_NONCONFORMANT_VECTOR("%AG", "%AG",
+                            gpr_url_percent_encoding_unreserved_bytes);
+  TEST_NONCONFORMANT_VECTOR("\0", "\0",
+                            gpr_url_percent_encoding_unreserved_bytes);
+  return 0;
+}
diff --git a/test/core/surface/public_headers_must_be_c89.c b/test/core/surface/public_headers_must_be_c89.c
index 3eeb55d..53bdf61 100644
--- a/test/core/surface/public_headers_must_be_c89.c
+++ b/test/core/surface/public_headers_must_be_c89.c
@@ -38,22 +38,18 @@
 #include <grpc/grpc.h>
 #include <grpc/grpc_security.h>
 #include <grpc/grpc_security_constants.h>
-#include <grpc/impl/codegen/alloc.h>
 #include <grpc/impl/codegen/atm.h>
-#include <grpc/impl/codegen/byte_buffer.h>
 #include <grpc/impl/codegen/byte_buffer_reader.h>
 #include <grpc/impl/codegen/compression_types.h>
 #include <grpc/impl/codegen/connectivity_state.h>
+#include <grpc/impl/codegen/gpr_types.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/time.h>
 #include <grpc/status.h>
 #include <grpc/support/alloc.h>
 #include <grpc/support/atm.h>
diff --git a/test/core/transport/chttp2/hpack_encoder_test.c b/test/core/transport/chttp2/hpack_encoder_test.c
index 186bb64..1c1c748 100644
--- a/test/core/transport/chttp2/hpack_encoder_test.c
+++ b/test/core/transport/chttp2/hpack_encoder_test.c
@@ -97,7 +97,7 @@
 
   grpc_transport_one_way_stats stats;
   memset(&stats, 0, sizeof(stats));
-  grpc_chttp2_encode_header(&g_compressor, 0xdeadbeef, &b, eof, &stats,
+  grpc_chttp2_encode_header(&g_compressor, 0xdeadbeef, &b, eof, 16384, &stats,
                             &output);
   merged = grpc_slice_merge(output.slices, output.count);
   gpr_slice_buffer_destroy(&output);
@@ -202,7 +202,8 @@
 
   grpc_transport_one_way_stats stats;
   memset(&stats, 0, sizeof(stats));
-  grpc_chttp2_encode_header(&g_compressor, 0xdeadbeef, &b, 0, &stats, &output);
+  grpc_chttp2_encode_header(&g_compressor, 0xdeadbeef, &b, 0, 16384, &stats,
+                            &output);
   gpr_slice_buffer_destroy(&output);
   grpc_metadata_batch_destroy(&b);
 
diff --git a/test/core/util/test_config.c b/test/core/util/test_config.c
index 270d166..479aeda 100644
--- a/test/core/util/test_config.c
+++ b/test/core/util/test_config.c
@@ -34,7 +34,6 @@
 #include "test/core/util/test_config.h"
 
 #include <grpc/support/log.h>
-#include <grpc/support/port_platform.h>
 #include <signal.h>
 #include <stdbool.h>
 #include <stdio.h>
diff --git a/test/cpp/codegen/codegen_test_full.cc b/test/cpp/codegen/codegen_test_full.cc
index 4500540..d6e2416 100644
--- a/test/cpp/codegen/codegen_test_full.cc
+++ b/test/cpp/codegen/codegen_test_full.cc
@@ -32,6 +32,7 @@
  */
 
 #include <grpc++/completion_queue.h>
+#include <grpc/support/time.h>
 #include <gtest/gtest.h>
 
 namespace grpc {
diff --git a/test/cpp/codegen/compiler_test_golden b/test/cpp/codegen/compiler_test_golden
index ef3d1aa..7b0fd6c 100644
--- a/test/cpp/codegen/compiler_test_golden
+++ b/test/cpp/codegen/compiler_test_golden
@@ -43,6 +43,7 @@
 
 #include <grpc++/impl/codegen/async_stream.h>
 #include <grpc++/impl/codegen/async_unary_call.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/service_type.h>
@@ -206,6 +207,27 @@
       return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
     }
   };
+  template <class BaseClass>
+  class WithStreamedUnaryMethod_MethodA1 : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service *service) {}
+   public:
+    WithStreamedUnaryMethod_MethodA1() {
+      ::grpc::Service::MarkMethodStreamedUnary(0,
+        new ::grpc::StreamedUnaryHandler< ::grpc::testing::Request, ::grpc::testing::Response>(std::bind(&WithStreamedUnaryMethod_MethodA1<BaseClass>::StreamedMethodA1, this, std::placeholders::_1, std::placeholders::_2)));
+    }
+    ~WithStreamedUnaryMethod_MethodA1() GRPC_OVERRIDE {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable regular version of this method
+    ::grpc::Status MethodA1(::grpc::ServerContext* context, const ::grpc::testing::Request* request, ::grpc::testing::Response* response) GRPC_FINAL GRPC_OVERRIDE {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    // replace default version of method with streamed unary
+    virtual ::grpc::Status StreamedMethodA1(::grpc::ServerContext* context, ::grpc::ServerUnaryStreamer< ::grpc::testing::Request,::grpc::testing::Response>* server_unary_streamer) = 0;
+  };
+  typedef WithStreamedUnaryMethod_MethodA1<Service > StreamedUnaryService;
 };
 
 // ServiceB leading comment 1
@@ -284,6 +306,27 @@
       return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
     }
   };
+  template <class BaseClass>
+  class WithStreamedUnaryMethod_MethodB1 : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service *service) {}
+   public:
+    WithStreamedUnaryMethod_MethodB1() {
+      ::grpc::Service::MarkMethodStreamedUnary(0,
+        new ::grpc::StreamedUnaryHandler< ::grpc::testing::Request, ::grpc::testing::Response>(std::bind(&WithStreamedUnaryMethod_MethodB1<BaseClass>::StreamedMethodB1, this, std::placeholders::_1, std::placeholders::_2)));
+    }
+    ~WithStreamedUnaryMethod_MethodB1() GRPC_OVERRIDE {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable regular version of this method
+    ::grpc::Status MethodB1(::grpc::ServerContext* context, const ::grpc::testing::Request* request, ::grpc::testing::Response* response) GRPC_FINAL GRPC_OVERRIDE {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    // replace default version of method with streamed unary
+    virtual ::grpc::Status StreamedMethodB1(::grpc::ServerContext* context, ::grpc::ServerUnaryStreamer< ::grpc::testing::Request,::grpc::testing::Response>* server_unary_streamer) = 0;
+  };
+  typedef WithStreamedUnaryMethod_MethodB1<Service > StreamedUnaryService;
 };
 // ServiceB trailing comment 1
 
diff --git a/test/cpp/end2end/async_end2end_test.cc b/test/cpp/end2end/async_end2end_test.cc
index ac79fe8..a9b7c8f 100644
--- a/test/cpp/end2end/async_end2end_test.cc
+++ b/test/cpp/end2end/async_end2end_test.cc
@@ -897,8 +897,8 @@
       GetChannelCredentials(GetParam().credentials_type, &args);
   std::shared_ptr<Channel> channel =
       CreateCustomChannel(server_address_.str(), channel_creds, args);
-  std::unique_ptr<grpc::testing::UnimplementedService::Stub> stub;
-  stub = grpc::testing::UnimplementedService::NewStub(channel);
+  std::unique_ptr<grpc::testing::UnimplementedEchoService::Stub> stub;
+  stub = grpc::testing::UnimplementedEchoService::NewStub(channel);
   EchoRequest send_request;
   EchoResponse recv_response;
   Status recv_status;
diff --git a/test/cpp/end2end/client_crash_test.cc b/test/cpp/end2end/client_crash_test.cc
index 30b04fb..c452ad2 100644
--- a/test/cpp/end2end/client_crash_test.cc
+++ b/test/cpp/end2end/client_crash_test.cc
@@ -38,6 +38,7 @@
 #include <grpc++/server_builder.h>
 #include <grpc++/server_context.h>
 #include <grpc/grpc.h>
+#include <grpc/support/log.h>
 #include <grpc/support/thd.h>
 #include <grpc/support/time.h>
 #include <gtest/gtest.h>
diff --git a/test/cpp/end2end/client_crash_test_server.cc b/test/cpp/end2end/client_crash_test_server.cc
index 9568ca2..6e14574 100644
--- a/test/cpp/end2end/client_crash_test_server.cc
+++ b/test/cpp/end2end/client_crash_test_server.cc
@@ -39,6 +39,8 @@
 #include <grpc++/server.h>
 #include <grpc++/server_builder.h>
 #include <grpc++/server_context.h>
+#include <grpc/support/log.h>
+
 #include "src/proto/grpc/testing/echo.grpc.pb.h"
 
 DEFINE_string(address, "", "Address to bind to");
diff --git a/test/cpp/end2end/end2end_test.cc b/test/cpp/end2end/end2end_test.cc
index 46a58d3..6661492 100644
--- a/test/cpp/end2end/end2end_test.cc
+++ b/test/cpp/end2end/end2end_test.cc
@@ -44,6 +44,7 @@
 #include <grpc++/server_builder.h>
 #include <grpc++/server_context.h>
 #include <grpc/grpc.h>
+#include <grpc/support/log.h>
 #include <grpc/support/thd.h>
 #include <grpc/support/time.h>
 #include <gtest/gtest.h>
@@ -967,8 +968,8 @@
 // Talking to a non-existing service.
 TEST_P(End2endTest, NonExistingService) {
   ResetChannel();
-  std::unique_ptr<grpc::testing::UnimplementedService::Stub> stub;
-  stub = grpc::testing::UnimplementedService::NewStub(channel_);
+  std::unique_ptr<grpc::testing::UnimplementedEchoService::Stub> stub;
+  stub = grpc::testing::UnimplementedEchoService::NewStub(channel_);
 
   EchoRequest request;
   EchoResponse response;
diff --git a/test/cpp/end2end/hybrid_end2end_test.cc b/test/cpp/end2end/hybrid_end2end_test.cc
index 7e0c0e8..82361d0 100644
--- a/test/cpp/end2end/hybrid_end2end_test.cc
+++ b/test/cpp/end2end/hybrid_end2end_test.cc
@@ -199,7 +199,8 @@
   HybridEnd2endTest() {}
 
   void SetUpServer(::grpc::Service* service1, ::grpc::Service* service2,
-                   AsyncGenericService* generic_service) {
+                   AsyncGenericService* generic_service,
+                   int max_message_size = 0) {
     int port = grpc_pick_unused_port_or_die();
     server_address_ << "localhost:" << port;
 
@@ -217,6 +218,11 @@
     if (generic_service) {
       builder.RegisterAsyncGenericService(generic_service);
     }
+
+    if (max_message_size != 0) {
+      builder.SetMaxMessageSize(max_message_size);
+    }
+
     // Create a separate cq for each potential handler.
     for (int i = 0; i < 5; i++) {
       cqs_.push_back(builder.AddCompletionQueue(false));
@@ -346,7 +352,7 @@
     EXPECT_TRUE(s.ok());
   }
 
-  grpc::testing::UnimplementedService::Service unimplemented_service_;
+  grpc::testing::UnimplementedEchoService::Service unimplemented_service_;
   std::vector<std::unique_ptr<ServerCompletionQueue>> cqs_;
   std::unique_ptr<grpc::testing::EchoTestService::Stub> stub_;
   std::unique_ptr<Server> server_;
@@ -415,6 +421,83 @@
   request_stream_handler_thread.join();
 }
 
+// Add a second service with one sync streamed unary method.
+class StreamedUnaryDupPkg
+    : public duplicate::EchoTestService::WithStreamedUnaryMethod_Echo<
+          TestServiceImplDupPkg> {
+ public:
+  Status StreamedEcho(ServerContext* context,
+                      ServerUnaryStreamer<EchoRequest, EchoResponse>* stream)
+      GRPC_OVERRIDE {
+    EchoRequest req;
+    EchoResponse resp;
+    uint32_t next_msg_sz;
+    stream->NextMessageSize(&next_msg_sz);
+    gpr_log(GPR_INFO, "Streamed Unary Next Message Size is %u", next_msg_sz);
+    GPR_ASSERT(stream->Read(&req));
+    resp.set_message(req.message() + "_dup");
+    GPR_ASSERT(stream->Write(resp));
+    return Status::OK;
+  }
+};
+
+TEST_F(HybridEnd2endTest,
+       AsyncRequestStreamResponseStream_SyncStreamedUnaryDupService) {
+  typedef EchoTestService::WithAsyncMethod_RequestStream<
+      EchoTestService::WithAsyncMethod_ResponseStream<TestServiceImpl>>
+      SType;
+  SType service;
+  StreamedUnaryDupPkg dup_service;
+  SetUpServer(&service, &dup_service, nullptr, 8192);
+  ResetStub();
+  std::thread response_stream_handler_thread(HandleServerStreaming<SType>,
+                                             &service, cqs_[0].get());
+  std::thread request_stream_handler_thread(HandleClientStreaming<SType>,
+                                            &service, cqs_[1].get());
+  TestAllMethods();
+  SendEchoToDupService();
+  response_stream_handler_thread.join();
+  request_stream_handler_thread.join();
+}
+
+// Add a second service that is fully Streamed Unary
+class FullyStreamedUnaryDupPkg
+    : public duplicate::EchoTestService::StreamedUnaryService {
+ public:
+  Status StreamedEcho(ServerContext* context,
+                      ServerUnaryStreamer<EchoRequest, EchoResponse>* stream)
+      GRPC_OVERRIDE {
+    EchoRequest req;
+    EchoResponse resp;
+    uint32_t next_msg_sz;
+    stream->NextMessageSize(&next_msg_sz);
+    gpr_log(GPR_INFO, "Streamed Unary Next Message Size is %u", next_msg_sz);
+    GPR_ASSERT(stream->Read(&req));
+    resp.set_message(req.message() + "_dup");
+    GPR_ASSERT(stream->Write(resp));
+    return Status::OK;
+  }
+};
+
+TEST_F(HybridEnd2endTest,
+       AsyncRequestStreamResponseStream_SyncFullyStreamedUnaryDupService) {
+  typedef EchoTestService::WithAsyncMethod_RequestStream<
+      EchoTestService::WithAsyncMethod_ResponseStream<TestServiceImpl>>
+      SType;
+  SType service;
+  FullyStreamedUnaryDupPkg dup_service;
+  SetUpServer(&service, &dup_service, nullptr, 8192);
+  ResetStub();
+  std::thread response_stream_handler_thread(HandleServerStreaming<SType>,
+                                             &service, cqs_[0].get());
+  std::thread request_stream_handler_thread(HandleClientStreaming<SType>,
+                                            &service, cqs_[1].get());
+  TestAllMethods();
+  SendEchoToDupService();
+  response_stream_handler_thread.join();
+  request_stream_handler_thread.join();
+}
+
 // Add a second service with one async method.
 TEST_F(HybridEnd2endTest, AsyncRequestStreamResponseStream_AsyncDupService) {
   typedef EchoTestService::WithAsyncMethod_RequestStream<
diff --git a/test/cpp/end2end/mock_test.cc b/test/cpp/end2end/mock_test.cc
index 0ace5d9..0da5861 100644
--- a/test/cpp/end2end/mock_test.cc
+++ b/test/cpp/end2end/mock_test.cc
@@ -31,6 +31,7 @@
  *
  */
 
+#include <climits>
 #include <thread>
 
 #include <grpc++/channel.h>
@@ -40,6 +41,7 @@
 #include <grpc++/server_builder.h>
 #include <grpc++/server_context.h>
 #include <grpc/grpc.h>
+#include <grpc/support/log.h>
 #include <grpc/support/thd.h>
 #include <grpc/support/time.h>
 #include <gtest/gtest.h>
@@ -63,6 +65,10 @@
     : public ClientReaderWriterInterface<W, R> {
  public:
   void WaitForInitialMetadata() GRPC_OVERRIDE {}
+  bool NextMessageSize(uint32_t* sz) GRPC_OVERRIDE {
+    *sz = UINT_MAX;
+    return true;
+  }
   bool Read(R* msg) GRPC_OVERRIDE { return true; }
   bool Write(const W& msg) GRPC_OVERRIDE { return true; }
   bool WritesDone() GRPC_OVERRIDE { return true; }
@@ -74,6 +80,10 @@
  public:
   MockClientReaderWriter() : writes_done_(false) {}
   void WaitForInitialMetadata() GRPC_OVERRIDE {}
+  bool NextMessageSize(uint32_t* sz) GRPC_OVERRIDE {
+    *sz = UINT_MAX;
+    return true;
+  }
   bool Read(EchoResponse* msg) GRPC_OVERRIDE {
     if (writes_done_) return false;
     msg->set_message(last_message_);
diff --git a/test/cpp/end2end/server_crash_test.cc b/test/cpp/end2end/server_crash_test.cc
index e447360..16a5fa2 100644
--- a/test/cpp/end2end/server_crash_test.cc
+++ b/test/cpp/end2end/server_crash_test.cc
@@ -38,6 +38,7 @@
 #include <grpc++/server_builder.h>
 #include <grpc++/server_context.h>
 #include <grpc/grpc.h>
+#include <grpc/support/log.h>
 #include <grpc/support/thd.h>
 #include <grpc/support/time.h>
 #include <gtest/gtest.h>
diff --git a/test/cpp/end2end/server_crash_test_client.cc b/test/cpp/end2end/server_crash_test_client.cc
index ece948d..10a251c 100644
--- a/test/cpp/end2end/server_crash_test_client.cc
+++ b/test/cpp/end2end/server_crash_test_client.cc
@@ -40,6 +40,8 @@
 #include <grpc++/channel.h>
 #include <grpc++/client_context.h>
 #include <grpc++/create_channel.h>
+#include <grpc/support/log.h>
+
 #include "src/proto/grpc/testing/echo.grpc.pb.h"
 
 DEFINE_string(address, "", "Address to connect to");
diff --git a/test/cpp/end2end/shutdown_test.cc b/test/cpp/end2end/shutdown_test.cc
index 3f98de6..4cba3b1 100644
--- a/test/cpp/end2end/shutdown_test.cc
+++ b/test/cpp/end2end/shutdown_test.cc
@@ -33,6 +33,8 @@
 
 #include <thread>
 
+#include <gtest/gtest.h>
+
 #include <grpc++/channel.h>
 #include <grpc++/client_context.h>
 #include <grpc++/create_channel.h>
@@ -40,8 +42,8 @@
 #include <grpc++/server_builder.h>
 #include <grpc++/server_context.h>
 #include <grpc/grpc.h>
+#include <grpc/support/log.h>
 #include <grpc/support/sync.h>
-#include <gtest/gtest.h>
 
 #include "src/core/lib/support/env.h"
 #include "src/proto/grpc/testing/echo.grpc.pb.h"
diff --git a/test/cpp/end2end/streaming_throughput_test.cc b/test/cpp/end2end/streaming_throughput_test.cc
index 9e82c30..fbef761 100644
--- a/test/cpp/end2end/streaming_throughput_test.cc
+++ b/test/cpp/end2end/streaming_throughput_test.cc
@@ -35,6 +35,8 @@
 #include <mutex>
 #include <thread>
 
+#include <gtest/gtest.h>
+
 #include <grpc++/channel.h>
 #include <grpc++/client_context.h>
 #include <grpc++/create_channel.h>
@@ -45,9 +47,9 @@
 #include <grpc++/server_context.h>
 #include <grpc/grpc.h>
 #include <grpc/support/atm.h>
+#include <grpc/support/log.h>
 #include <grpc/support/thd.h>
 #include <grpc/support/time.h>
-#include <gtest/gtest.h>
 
 #include "src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.h"
 #include "src/proto/grpc/testing/echo.grpc.pb.h"
diff --git a/test/cpp/end2end/test_service_impl.cc b/test/cpp/end2end/test_service_impl.cc
index 52abd80..2de344e 100644
--- a/test/cpp/end2end/test_service_impl.cc
+++ b/test/cpp/end2end/test_service_impl.cc
@@ -38,7 +38,8 @@
 
 #include <grpc++/security/credentials.h>
 #include <grpc++/server_context.h>
-#include <grpc/grpc.h>
+#include <grpc/support/log.h>
+
 #include <gtest/gtest.h>
 
 #include "src/proto/grpc/testing/echo.grpc.pb.h"
diff --git a/test/cpp/grpclb/grpclb_api_test.cc b/test/cpp/grpclb/grpclb_api_test.cc
index 33de1ee..e67189c 100644
--- a/test/cpp/grpclb/grpclb_api_test.cc
+++ b/test/cpp/grpclb/grpclb_api_test.cc
@@ -31,10 +31,12 @@
  *
  */
 
+#include <grpc++/impl/codegen/config.h>
 #include <gtest/gtest.h>
-#include <string>
 
 #include "src/core/ext/lb_policy/grpclb/load_balancer_api.h"
+#include "src/core/lib/iomgr/sockaddr.h"
+#include "src/core/lib/iomgr/sockaddr_utils.h"
 #include "src/proto/grpc/lb/v1/load_balancer.pb.h"  // C++ version
 
 namespace grpc {
@@ -45,8 +47,28 @@
 
 class GrpclbTest : public ::testing::Test {};
 
+grpc::string Ip4ToPackedString(const char* ip_str) {
+  struct in_addr ip4;
+  GPR_ASSERT(inet_pton(AF_INET, ip_str, &ip4) == 1);
+  return grpc::string(reinterpret_cast<const char*>(&ip4), sizeof(ip4));
+}
+
+grpc::string PackedStringToIp(const grpc_grpclb_ip_address& pb_ip) {
+  char ip_str[46] = {0};
+  int af = -1;
+  if (pb_ip.size == 4) {
+    af = AF_INET;
+  } else if (pb_ip.size == 16) {
+    af = AF_INET6;
+  } else {
+    abort();
+  }
+  GPR_ASSERT(inet_ntop(af, pb_ip.bytes, ip_str, 46) != NULL);
+  return ip_str;
+}
+
 TEST_F(GrpclbTest, CreateRequest) {
-  const std::string service_name = "AServiceName";
+  const grpc::string service_name = "AServiceName";
   LoadBalanceRequest request;
   grpc_grpclb_request* c_req = grpc_grpclb_request_create(service_name.c_str());
   gpr_slice slice = grpc_grpclb_request_encode(c_req);
@@ -65,7 +87,7 @@
       initial_response->mutable_client_stats_report_interval();
   client_stats_report_interval->set_seconds(123);
   client_stats_report_interval->set_nanos(456);
-  const std::string encoded_response = response.SerializeAsString();
+  const grpc::string encoded_response = response.SerializeAsString();
   gpr_slice encoded_slice =
       gpr_slice_from_copied_string(encoded_response.c_str());
 
@@ -82,29 +104,31 @@
   LoadBalanceResponse response;
   auto* serverlist = response.mutable_server_list();
   auto* server = serverlist->add_servers();
-  server->set_ip_address("127.0.0.1");
+  server->set_ip_address(Ip4ToPackedString("127.0.0.1"));
   server->set_port(12345);
   server->set_drop_request(true);
   server = response.mutable_server_list()->add_servers();
-  server->set_ip_address("10.0.0.1");
+  server->set_ip_address(Ip4ToPackedString("10.0.0.1"));
   server->set_port(54321);
   server->set_drop_request(false);
   auto* expiration_interval = serverlist->mutable_expiration_interval();
   expiration_interval->set_seconds(888);
   expiration_interval->set_nanos(999);
 
-  const std::string encoded_response = response.SerializeAsString();
-  gpr_slice encoded_slice =
-      gpr_slice_from_copied_string(encoded_response.c_str());
+  const grpc::string encoded_response = response.SerializeAsString();
+  const gpr_slice encoded_slice = gpr_slice_from_copied_buffer(
+      encoded_response.data(), encoded_response.size());
   grpc_grpclb_serverlist* c_serverlist =
       grpc_grpclb_response_parse_serverlist(encoded_slice);
   ASSERT_EQ(c_serverlist->num_servers, 2ul);
   EXPECT_TRUE(c_serverlist->servers[0]->has_ip_address);
-  EXPECT_TRUE(strcmp(c_serverlist->servers[0]->ip_address, "127.0.0.1") == 0);
+  EXPECT_EQ(PackedStringToIp(c_serverlist->servers[0]->ip_address),
+            "127.0.0.1");
   EXPECT_EQ(c_serverlist->servers[0]->port, 12345);
   EXPECT_TRUE(c_serverlist->servers[0]->drop_request);
   EXPECT_TRUE(c_serverlist->servers[1]->has_ip_address);
-  EXPECT_TRUE(strcmp(c_serverlist->servers[1]->ip_address, "10.0.0.1") == 0);
+
+  EXPECT_EQ(PackedStringToIp(c_serverlist->servers[1]->ip_address), "10.0.0.1");
   EXPECT_EQ(c_serverlist->servers[1]->port, 54321);
   EXPECT_FALSE(c_serverlist->servers[1]->drop_request);
 
diff --git a/test/cpp/grpclb/grpclb_test.cc b/test/cpp/grpclb/grpclb_test.cc
index a4aa973..95abe38 100644
--- a/test/cpp/grpclb/grpclb_test.cc
+++ b/test/cpp/grpclb/grpclb_test.cc
@@ -37,8 +37,10 @@
 #include <cstring>
 #include <string>
 
-extern "C" {
+#include <gtest/gtest.h>
+
 #include <grpc/grpc.h>
+#include <grpc/impl/codegen/byte_buffer_reader.h>
 #include <grpc/support/alloc.h>
 #include <grpc/support/host_port.h>
 #include <grpc/support/log.h>
@@ -47,8 +49,11 @@
 #include <grpc/support/thd.h>
 #include <grpc/support/time.h>
 
+#include <grpc++/impl/codegen/config.h>
+extern "C" {
 #include "src/core/ext/client_config/client_channel.h"
 #include "src/core/lib/channel/channel_stack.h"
+#include "src/core/lib/iomgr/sockaddr.h"
 #include "src/core/lib/support/string.h"
 #include "src/core/lib/support/tmpfile.h"
 #include "src/core/lib/surface/channel.h"
@@ -61,16 +66,19 @@
 #include "src/proto/grpc/lb/v1/load_balancer.pb.h"
 
 #define NUM_BACKENDS 4
+#define PAYLOAD "hello you"
 
 // TODO(dgq): Other scenarios in need of testing:
 // - Send an empty serverlist update and verify that the client request blocks
 //   until a new serverlist with actual contents is available.
 // - Send identical serverlist update
+// - Send a serverlist with faulty ip:port addresses (port > 2^16, etc).
 // - Test reception of invalid serverlist
 // - Test pinging
 // - Test against a non-LB server. That server should return UNIMPLEMENTED and
 //   the call should fail.
 // - Random LB server closing the stream unexpectedly.
+// - Test using DNS-resolvable names (localhost?)
 
 namespace grpc {
 namespace {
@@ -105,8 +113,8 @@
     int64_t expiration_interval_secs, int32_t expiration_interval_nanos) {
   // server_list {
   //   servers {
-  //     ip_address: "127.0.0.1"
-  //     port: ...
+  //     ip_address: <in_addr/6 bytes of an IP>
+  //     port: <16 bit uint>
   //     load_balance_token: "token..."
   //   }
   //   ...
@@ -125,21 +133,21 @@
   }
   for (size_t i = 0; i < nports; i++) {
     auto *server = serverlist->add_servers();
-    server->set_ip_address(host);
+    // TODO(dgq): test ipv6
+    struct in_addr ip4;
+    GPR_ASSERT(inet_pton(AF_INET, host, &ip4) == 1);
+    server->set_ip_address(
+        grpc::string(reinterpret_cast<const char *>(&ip4), sizeof(ip4)));
     server->set_port(ports[i]);
     // The following long long int cast is meant to work around the
     // disfunctional implementation of std::to_string in gcc 4.4, which doesn't
     // have a version for int but does have one for long long int.
-    server->set_load_balance_token("token" +
-                                   std::to_string((long long int)ports[i]));
+    string token_data = "token" + std::to_string((long long int)ports[i]);
+    token_data.resize(64, '-');
+    server->set_load_balance_token(token_data);
   }
-
-  gpr_log(GPR_INFO, "generating response: %s",
-          response.ShortDebugString().c_str());
-
-  const gpr_slice response_slice =
-      gpr_slice_from_copied_string(response.SerializeAsString().c_str());
-  return response_slice;
+  const grpc::string &enc_resp = response.SerializeAsString();
+  return gpr_slice_from_copied_buffer(enc_resp.data(), enc_resp.size());
 }
 
 static void drain_cq(grpc_completion_queue *cq) {
@@ -181,6 +189,37 @@
   cq_verify(cqv);
   gpr_log(GPR_INFO, "LB Server[%s] after tag 200", sf->servers_hostport);
 
+  // make sure we've received the initial metadata from the grpclb request.
+  GPR_ASSERT(request_metadata_recv.count > 0);
+  GPR_ASSERT(request_metadata_recv.metadata != NULL);
+
+  // receive request for backends
+  op = ops;
+  op->op = GRPC_OP_RECV_MESSAGE;
+  op->data.recv_message = &request_payload_recv;
+  op->flags = 0;
+  op->reserved = NULL;
+  op++;
+  error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(202), NULL);
+  GPR_ASSERT(GRPC_CALL_OK == error);
+  CQ_EXPECT_COMPLETION(cqv, tag(202), 1);
+  cq_verify(cqv);
+  gpr_log(GPR_INFO, "LB Server[%s] after RECV_MSG", sf->servers_hostport);
+
+  // validate initial request.
+  grpc_byte_buffer_reader bbr;
+  grpc_byte_buffer_reader_init(&bbr, request_payload_recv);
+  gpr_slice request_payload_slice = grpc_byte_buffer_reader_readall(&bbr);
+  grpc::lb::v1::LoadBalanceRequest request;
+  request.ParseFromArray(GPR_SLICE_START_PTR(request_payload_slice),
+                         GPR_SLICE_LENGTH(request_payload_slice));
+  GPR_ASSERT(request.has_initial_request());
+  GPR_ASSERT(request.initial_request().name() == "load.balanced.service.name");
+  gpr_slice_unref(request_payload_slice);
+  grpc_byte_buffer_reader_destroy(&bbr);
+  grpc_byte_buffer_destroy(request_payload_recv);
+
+  gpr_slice response_payload_slice;
   op = ops;
   op->op = GRPC_OP_SEND_INITIAL_METADATA;
   op->data.send_initial_metadata.count = 0;
@@ -196,21 +235,6 @@
   GPR_ASSERT(GRPC_CALL_OK == error);
   gpr_log(GPR_INFO, "LB Server[%s] after tag 201", sf->servers_hostport);
 
-  // receive request for backends
-  op = ops;
-  op->op = GRPC_OP_RECV_MESSAGE;
-  op->data.recv_message = &request_payload_recv;
-  op->flags = 0;
-  op->reserved = NULL;
-  op++;
-  error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(202), NULL);
-  GPR_ASSERT(GRPC_CALL_OK == error);
-  CQ_EXPECT_COMPLETION(cqv, tag(202), 1);
-  cq_verify(cqv);
-  gpr_log(GPR_INFO, "LB Server[%s] after RECV_MSG", sf->servers_hostport);
-  // TODO(dgq): validate request.
-  grpc_byte_buffer_destroy(request_payload_recv);
-  gpr_slice response_payload_slice;
   for (int i = 0; i < 2; i++) {
     if (i == 0) {
       // First half of the ports.
@@ -303,6 +327,16 @@
       return;
     }
     GPR_ASSERT(ev.type == GRPC_OP_COMPLETE);
+
+    // The following long long int cast is meant to work around the
+    // disfunctional implementation of std::to_string in gcc 4.4, which doesn't
+    // have a version for int but does have one for long long int.
+    string expected_token = "token" + std::to_string((long long int)sf->port);
+    expected_token.resize(64, '-');
+    GPR_ASSERT(contains_metadata(&request_metadata_recv,
+                                 "load-reporting-initial",
+                                 expected_token.c_str()));
+
     gpr_log(GPR_INFO, "Server[%s] after tag 100", sf->servers_hostport);
 
     op = ops;
@@ -321,8 +355,7 @@
     gpr_log(GPR_INFO, "Server[%s] after tag 101", sf->servers_hostport);
 
     bool exit = false;
-    gpr_slice response_payload_slice =
-        gpr_slice_from_copied_string("hello you");
+    gpr_slice response_payload_slice = gpr_slice_from_copied_string(PAYLOAD);
     while (!exit) {
       op = ops;
       op->op = GRPC_OP_RECV_MESSAGE;
@@ -474,10 +507,9 @@
     error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(2), NULL);
     GPR_ASSERT(GRPC_CALL_OK == error);
 
-    peer = grpc_call_get_peer(c);
     CQ_EXPECT_COMPLETION(cqv, tag(2), 1);
     cq_verify(cqv);
-    gpr_free(peer);
+    GPR_ASSERT(byte_buffer_eq_string(response_payload_recv, PAYLOAD));
 
     grpc_byte_buffer_destroy(request_payload);
     grpc_byte_buffer_destroy(response_payload_recv);
@@ -583,27 +615,30 @@
                   tf->lb_server_update_delay_ms);
 }
 
-static void setup_test_fixture(test_fixture *tf,
-                               int lb_server_update_delay_ms) {
-  tf->lb_server_update_delay_ms = lb_server_update_delay_ms;
+static test_fixture setup_test_fixture(int lb_server_update_delay_ms) {
+  test_fixture tf;
+  memset(&tf, 0, sizeof(tf));
+  tf.lb_server_update_delay_ms = lb_server_update_delay_ms;
 
   gpr_thd_options options = gpr_thd_options_default();
   gpr_thd_options_set_joinable(&options);
 
   for (int i = 0; i < NUM_BACKENDS; ++i) {
-    setup_server("127.0.0.1", &tf->lb_backends[i]);
-    gpr_thd_new(&tf->lb_backends[i].tid, fork_backend_server,
-                &tf->lb_backends[i], &options);
+    setup_server("127.0.0.1", &tf.lb_backends[i]);
+    gpr_thd_new(&tf.lb_backends[i].tid, fork_backend_server, &tf.lb_backends[i],
+                &options);
   }
 
-  setup_server("127.0.0.1", &tf->lb_server);
-  gpr_thd_new(&tf->lb_server.tid, fork_lb_server, &tf->lb_server, &options);
+  setup_server("127.0.0.1", &tf.lb_server);
+  gpr_thd_new(&tf.lb_server.tid, fork_lb_server, &tf.lb_server, &options);
 
   char *server_uri;
   gpr_asprintf(&server_uri, "ipv4:%s?lb_policy=grpclb&lb_enabled=1",
-               tf->lb_server.servers_hostport);
-  setup_client(server_uri, &tf->client);
+               tf.lb_server.servers_hostport);
+  setup_client(server_uri, &tf.client);
   gpr_free(server_uri);
+
+  return tf;
 }
 
 static void teardown_test_fixture(test_fixture *tf) {
@@ -614,19 +649,13 @@
   teardown_server(&tf->lb_server);
 }
 
-// The LB server will send two updates: batch 1 and batch 2. Each batch
-// contains
-// two addresses, both of a valid and running backend server. Batch 1 is
-// readily
-// available and provided as soon as the client establishes the streaming
-// call.
-// Batch 2 is sent after a delay of \a lb_server_update_delay_ms
-// milliseconds.
+// The LB server will send two updates: batch 1 and batch 2. Each batch contains
+// two addresses, both of a valid and running backend server. Batch 1 is readily
+// available and provided as soon as the client establishes the streaming call.
+// Batch 2 is sent after a delay of \a lb_server_update_delay_ms milliseconds.
 static test_fixture test_update(int lb_server_update_delay_ms) {
   gpr_log(GPR_INFO, "start %s(%d)", __func__, lb_server_update_delay_ms);
-  test_fixture tf;
-  memset(&tf, 0, sizeof(tf));
-  setup_test_fixture(&tf, lb_server_update_delay_ms);
+  test_fixture tf = setup_test_fixture(lb_server_update_delay_ms);
   perform_request(
       &tf.client);  // "consumes" 1st backend server of 1st serverlist
   perform_request(
@@ -642,13 +671,7 @@
   return tf;
 }
 
-}  // namespace
-}  // namespace grpc
-
-int main(int argc, char **argv) {
-  grpc_test_init(argc, argv);
-  grpc_init();
-
+TEST(GrpclbTest, Updates) {
   grpc::test_fixture tf_result;
   // Clients take a bit over one second to complete a call (the last part of the
   // call sleeps for 1 second while verifying the client's completion queue is
@@ -683,7 +706,18 @@
   GPR_ASSERT(tf_result.lb_backends[1].num_calls_serviced > 0);
   GPR_ASSERT(tf_result.lb_backends[2].num_calls_serviced > 0);
   GPR_ASSERT(tf_result.lb_backends[3].num_calls_serviced == 0);
+}
 
+TEST(GrpclbTest, InvalidAddressInServerlist) {}
+
+}  // namespace
+}  // namespace grpc
+
+int main(int argc, char **argv) {
+  ::testing::InitGoogleTest(&argc, argv);
+  grpc_test_init(argc, argv);
+  grpc_init();
+  const auto result = RUN_ALL_TESTS();
   grpc_shutdown();
-  return 0;
+  return result;
 }
diff --git a/test/cpp/interop/client.cc b/test/cpp/interop/client.cc
index e8ae6ee..032b378 100644
--- a/test/cpp/interop/client.cc
+++ b/test/cpp/interop/client.cc
@@ -39,6 +39,7 @@
 #include <grpc++/channel.h>
 #include <grpc++/client_context.h>
 #include <grpc/grpc.h>
+#include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
 #include <grpc/support/useful.h>
 
diff --git a/test/cpp/interop/interop_client.cc b/test/cpp/interop/interop_client.cc
index 8861bc1..6117878 100644
--- a/test/cpp/interop/interop_client.cc
+++ b/test/cpp/interop/interop_client.cc
@@ -40,6 +40,7 @@
 #include <grpc++/client_context.h>
 #include <grpc++/security/credentials.h>
 #include <grpc/grpc.h>
+#include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
 #include <grpc/support/string_util.h>
 #include <grpc/support/useful.h>
diff --git a/test/cpp/interop/metrics_client.cc b/test/cpp/interop/metrics_client.cc
index 179de30..9d5212e 100644
--- a/test/cpp/interop/metrics_client.cc
+++ b/test/cpp/interop/metrics_client.cc
@@ -36,6 +36,7 @@
 
 #include <gflags/gflags.h>
 #include <grpc++/grpc++.h>
+#include <grpc/support/log.h>
 
 #include "src/proto/grpc/testing/metrics.grpc.pb.h"
 #include "src/proto/grpc/testing/metrics.pb.h"
diff --git a/test/cpp/interop/stress_interop_client.cc b/test/cpp/interop/stress_interop_client.cc
index 1d5fc80..0ea71e4 100644
--- a/test/cpp/interop/stress_interop_client.cc
+++ b/test/cpp/interop/stress_interop_client.cc
@@ -38,6 +38,7 @@
 #include <vector>
 
 #include <grpc++/create_channel.h>
+#include <grpc/support/log.h>
 
 #include "test/cpp/interop/interop_client.h"
 #include "test/cpp/util/metrics_server.h"
diff --git a/test/cpp/interop/stress_test.cc b/test/cpp/interop/stress_test.cc
index 7787931..5647cb5 100644
--- a/test/cpp/interop/stress_test.cc
+++ b/test/cpp/interop/stress_test.cc
@@ -41,6 +41,7 @@
 #include <grpc++/create_channel.h>
 #include <grpc++/grpc++.h>
 #include <grpc++/impl/thd.h>
+#include <grpc/support/log.h>
 #include <grpc/support/time.h>
 
 #include "src/proto/grpc/testing/metrics.grpc.pb.h"
diff --git a/test/cpp/qps/driver.cc b/test/cpp/qps/driver.cc
index 93f9271..f67f353 100644
--- a/test/cpp/qps/driver.cc
+++ b/test/cpp/qps/driver.cc
@@ -186,6 +186,9 @@
     const ClientConfig& initial_client_config, size_t num_clients,
     const ServerConfig& initial_server_config, size_t num_servers,
     int warmup_seconds, int benchmark_seconds, int spawn_local_worker_count) {
+  // Log everything from the driver
+  gpr_set_log_verbosity(GPR_LOG_SEVERITY_DEBUG);
+
   // ClientContext allocations (all are destroyed at scope exit)
   list<ClientContext> contexts;
 
diff --git a/test/cpp/util/metrics_server.cc b/test/cpp/util/metrics_server.cc
index 1c7cd63..9296d65 100644
--- a/test/cpp/util/metrics_server.cc
+++ b/test/cpp/util/metrics_server.cc
@@ -35,6 +35,7 @@
 
 #include <grpc++/server.h>
 #include <grpc++/server_builder.h>
+#include <grpc/support/log.h>
 
 #include "src/proto/grpc/testing/metrics.grpc.pb.h"
 #include "src/proto/grpc/testing/metrics.pb.h"
diff --git a/test/cpp/util/test_config.cc b/test/cpp/util/test_config_cc.cc
similarity index 100%
rename from test/cpp/util/test_config.cc
rename to test/cpp/util/test_config_cc.cc
diff --git a/test/cpp/util/test_credentials_provider.cc b/test/cpp/util/test_credentials_provider.cc
index 6e68f59..ca15f29 100644
--- a/test/cpp/util/test_credentials_provider.cc
+++ b/test/cpp/util/test_credentials_provider.cc
@@ -37,6 +37,7 @@
 #include <unordered_map>
 
 #include <grpc++/impl/sync.h>
+#include <grpc/support/log.h>
 #include <grpc/support/sync.h>
 
 #include "test/core/end2end/data/ssl_test_data.h"
diff --git a/test/distrib/csharp/DistribTest/.gitignore b/test/distrib/csharp/DistribTest/.gitignore
index 1746e32..07f3d57 100644
--- a/test/distrib/csharp/DistribTest/.gitignore
+++ b/test/distrib/csharp/DistribTest/.gitignore
@@ -1,2 +1,3 @@
 bin
 obj
+*.lock.json
diff --git a/test/distrib/csharp/DistribTest/DistribTest.csproj b/test/distrib/csharp/DistribTest/DistribTest.csproj
index 6ca03b2..0bff9ff 100644
--- a/test/distrib/csharp/DistribTest/DistribTest.csproj
+++ b/test/distrib/csharp/DistribTest/DistribTest.csproj
@@ -65,7 +65,7 @@
     <Reference Include="System" />
     <Reference Include="System.Core" />
     <Reference Include="System.Interactive.Async">
-      <HintPath>..\packages\Ix-Async.1.2.3\lib\net45\System.Interactive.Async.dll</HintPath>
+      <HintPath>..\packages\System.Interactive.Async.3.0.0\lib\net45\System.Interactive.Async.dll</HintPath>
     </Reference>
     <Reference Include="System.Net" />
     <Reference Include="System.Net.Http" />
diff --git a/test/distrib/csharp/DistribTest/DistribTest.project.json b/test/distrib/csharp/DistribTest/DistribTest.project.json
new file mode 100644
index 0000000..422545e
--- /dev/null
+++ b/test/distrib/csharp/DistribTest/DistribTest.project.json
@@ -0,0 +1,11 @@
+// This file exists only to prevent VS2015 from mistakenly picking up
+// project.json file when building .csproj project.
+// See https://github.com/Microsoft/msbuild/issues/394
+{
+  "frameworks": {
+    "net45": { }
+  },
+  "runtimes": {
+    "win": { }
+  }
+}
diff --git a/test/distrib/csharp/DistribTest/packages.config b/test/distrib/csharp/DistribTest/packages.config
index e5d2d9d..84be8f7 100644
--- a/test/distrib/csharp/DistribTest/packages.config
+++ b/test/distrib/csharp/DistribTest/packages.config
@@ -6,6 +6,6 @@
   <package id="Grpc" version="__GRPC_NUGET_VERSION__" targetFramework="net45" />
   <package id="Grpc.Auth" version="__GRPC_NUGET_VERSION__" targetFramework="net45" />
   <package id="Grpc.Core" version="__GRPC_NUGET_VERSION__" targetFramework="net45" />
-  <package id="Ix-Async" version="1.2.3" targetFramework="net45" />
+  <package id="System.Interactive.Async" version="3.0.0" targetFramework="net45" />
   <package id="Newtonsoft.Json" version="7.0.1" targetFramework="net45" />
-</packages>
+</packages>
\ No newline at end of file
diff --git a/test/distrib/csharp/DistribTest/project.json b/test/distrib/csharp/DistribTest/project.json
new file mode 100644
index 0000000..09266e5
--- /dev/null
+++ b/test/distrib/csharp/DistribTest/project.json
@@ -0,0 +1,22 @@
+{
+  "buildOptions": {
+    "emitEntryPoint": true
+  },
+  "dependencies": {
+    "Grpc.Auth": "__GRPC_NUGET_VERSION__",
+    "Grpc.Core": "__GRPC_NUGET_VERSION__",
+    // Necessary for native deps to get copied correctly.
+    "Microsoft.NETCore.Platforms": "1.0.1"
+  },
+  "frameworks": {
+    "net45": { },
+    "netcoreapp1.0": {
+      "dependencies": {
+        "Microsoft.NETCore.App": {
+          "type": "platform",
+          "version": "1.0.0"
+        }
+      }
+    }
+  }
+}
diff --git a/test/distrib/csharp/run_distrib_test.bat b/test/distrib/csharp/run_distrib_test.bat
index 67bfc58..6cf3811 100644
--- a/test/distrib/csharp/run_distrib_test.bat
+++ b/test/distrib/csharp/run_distrib_test.bat
@@ -31,12 +31,22 @@
 cd /d %~dp0
 
 @rem extract input artifacts
-powershell -Command "Add-Type -Assembly 'System.IO.Compression.FileSystem'; [System.IO.Compression.ZipFile]::ExtractToDirectory('../../../input_artifacts/csharp_nugets.zip', 'TestNugetFeed');"
+powershell -Command "Add-Type -Assembly 'System.IO.Compression.FileSystem'; [System.IO.Compression.ZipFile]::ExtractToDirectory('../../../input_artifacts/csharp_nugets_dotnetcli.zip', 'TestNugetFeed');"
 
 update_version.sh auto
 
 set NUGET=C:\nuget\nuget.exe
-%NUGET% restore || goto :error
+
+@rem TODO(jtattermusch): Get rid of this hack. See #8034
+@rem We can't do just "nuget restore" because restoring a .sln solution doesn't work
+@rem with nuget 3.X. On the other hand, we need nuget 2.12+ to be able to restore
+@rem some of the packages (e.g. System.Interactive.Async), but nuget 2.12
+@rem hasn't been officially released.
+@rem Please note that "Restore nuget packages" in VS2013 and VS2015 GUI works as usual.
+
+cd DistribTest || goto :error
+%NUGET% restore -PackagesDirectory ../packages || goto :error
+cd ..
 
 @call build_vs2015.bat DistribTest.sln %MSBUILD_EXTRA_ARGS% || goto :error
 
diff --git a/test/distrib/csharp/run_distrib_test.sh b/test/distrib/csharp/run_distrib_test.sh
index 64e98d8..0a77c1a 100755
--- a/test/distrib/csharp/run_distrib_test.sh
+++ b/test/distrib/csharp/run_distrib_test.sh
@@ -32,7 +32,7 @@
 
 cd $(dirname $0)
 
-unzip -o "$EXTERNAL_GIT_ROOT/input_artifacts/csharp_nugets.zip" -d TestNugetFeed
+unzip -o "$EXTERNAL_GIT_ROOT/input_artifacts/csharp_nugets_dotnetcli.zip" -d TestNugetFeed
 
 ./update_version.sh auto
 
diff --git a/test/distrib/csharp/run_distrib_test_dotnetcli.sh b/test/distrib/csharp/run_distrib_test_dotnetcli.sh
new file mode 100755
index 0000000..493c504
--- /dev/null
+++ b/test/distrib/csharp/run_distrib_test_dotnetcli.sh
@@ -0,0 +1,58 @@
+#!/bin/bash
+# Copyright 2015, Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+set -ex
+
+cd $(dirname $0)
+
+unzip -o "$EXTERNAL_GIT_ROOT/input_artifacts/csharp_nugets_dotnetcli.zip" -d TestNugetFeed
+
+./update_version.sh auto
+
+cd DistribTest
+
+# TODO(jtattermusch): make sure we don't pollute the global nuget cache with
+# the nugets being tested.
+dotnet restore
+
+dotnet build
+dotnet publish
+
+# .NET 4.5 target after dotnet build
+mono bin/Debug/net45/*-x64/DistribTest.exe
+
+# .NET 4.5 target after dotnet publish
+mono bin/Debug/net45/*-x64/publish/DistribTest.exe
+
+# .NET Core target after dotnet build
+dotnet exec bin/Debug/netcoreapp1.0/DistribTest.dll
+
+# .NET Core target after dotnet publish
+dotnet exec bin/Debug/netcoreapp1.0/publish/DistribTest.dll
diff --git a/test/distrib/csharp/update_version.sh b/test/distrib/csharp/update_version.sh
index 189d0ad..2961d0c 100755
--- a/test/distrib/csharp/update_version.sh
+++ b/test/distrib/csharp/update_version.sh
@@ -35,10 +35,10 @@
 CSHARP_VERSION="$1"
 if [ "$CSHARP_VERSION" == "auto" ]
 then
-  # autodetect C# version
-  CSHARP_VERSION=$(ls TestNugetFeed | grep '^Grpc\.[0-9].*\.nupkg$' | sed s/^Grpc\.// | sed s/\.nupkg$//)
+  # autodetect C# version from the name of Grpc.Core.0.0.0-x.nupkg file
+  CSHARP_VERSION=$(ls TestNugetFeed | grep -m 1 '^Grpc\.Core\.[0-9].*\.nupkg$' | sed s/^Grpc\.Core\.// | sed s/\.nupkg$// | sed s/\.symbols$//)
   echo "Autodetected nuget ${CSHARP_VERSION}"
 fi
 
 # Replaces version placeholder with value provided as first argument.
-sed -ibak "s/__GRPC_NUGET_VERSION__/${CSHARP_VERSION}/g" DistribTest/packages.config DistribTest/DistribTest.csproj
+sed -ibak "s/__GRPC_NUGET_VERSION__/${CSHARP_VERSION}/g" DistribTest/packages.config DistribTest/DistribTest.csproj DistribTest/project.json
diff --git a/third_party/nanopb b/third_party/nanopb
index f8ac463..68a86e9 160000
--- a/third_party/nanopb
+++ b/third_party/nanopb
@@ -1 +1 @@
-Subproject commit f8ac463766281625ad710900479130c7fcb4d63b
+Subproject commit 68a86e96481e6bea987df8de47027847b30c325b
diff --git a/tools/codegen/core/gen_nano_proto.sh b/tools/codegen/core/gen_nano_proto.sh
index c880fc2..df107c2 100755
--- a/tools/codegen/core/gen_nano_proto.sh
+++ b/tools/codegen/core/gen_nano_proto.sh
@@ -123,7 +123,7 @@
 
 # this should be the same version as the submodule we compile against
 # ideally we'd update this as a template to ensure that
-pip install protobuf==3.0.0b2
+pip install protobuf==3.0.0
 
 pushd "$(dirname $INPUT_PROTO)" > /dev/null
 
diff --git a/tools/codegen/core/gen_percent_encoding_tables.c b/tools/codegen/core/gen_percent_encoding_tables.c
new file mode 100644
index 0000000..93f30de
--- /dev/null
+++ b/tools/codegen/core/gen_percent_encoding_tables.c
@@ -0,0 +1,84 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+/* generates constant table for metadata.c */
+
+#include <stdio.h>
+#include <string.h>
+
+static unsigned char legal_bits[256 / 8];
+
+static void legal(int x) {
+  int byte = x / 8;
+  int bit = x % 8;
+  /* NB: the following integer arithmetic operation needs to be in its
+   * expanded form due to the "integral promotion" performed (see section
+   * 3.2.1.1 of the C89 draft standard). A cast to the smaller container type
+   * is then required to avoid the compiler warning */
+  legal_bits[byte] =
+      (unsigned char)((legal_bits[byte] | (unsigned char)(1 << bit)));
+}
+
+static void dump(const char *name) {
+  int i;
+
+  printf("const uint8_t %s[256/8] = ", name);
+  for (i = 0; i < 256 / 8; i++)
+    printf("%c 0x%02x", i ? ',' : '{', legal_bits[i]);
+  printf(" };\n");
+}
+
+static void clear(void) { memset(legal_bits, 0, sizeof(legal_bits)); }
+
+int main(void) {
+  int i;
+
+  clear();
+  for (i = 'a'; i <= 'z'; i++) legal(i);
+  for (i = 'A'; i <= 'Z'; i++) legal(i);
+  for (i = '0'; i <= '9'; i++) legal(i);
+  legal('-');
+  legal('_');
+  legal('.');
+  legal('~');
+  dump("gpr_url_percent_encoding_unreserved_bytes");
+
+  clear();
+  for (i = 32; i <= 126; i++) {
+    if (i == '%') continue;
+    legal(i);
+  }
+  dump("gpr_compatible_percent_encoding_unreserved_bytes");
+
+  return 0;
+}
diff --git a/tools/distrib/c-ish/check_documentation.py b/tools/distrib/c-ish/check_documentation.py
new file mode 100755
index 0000000..0bb3ca6
--- /dev/null
+++ b/tools/distrib/c-ish/check_documentation.py
@@ -0,0 +1,91 @@
+#!/usr/bin/env python2.7
+
+# Copyright 2015, Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# check for directory level 'README.md' files
+# check that all implementation and interface files have a \file doxygen comment
+
+import os
+import sys
+
+# where do we run
+_TARGET_DIRS = [
+  'include/grpc',
+  'include/grpc++',
+  'src/core',
+  'src/cpp',
+  'test/core',
+  'test/cpp'
+]
+
+# which file extensions do we care about
+_INTERESTING_EXTENSIONS = [
+  '.c',
+  '.h',
+  '.cc'
+]
+
+# find our home
+_ROOT = os.path.abspath(
+    os.path.join(os.path.dirname(sys.argv[0]), '../../..'))
+os.chdir(_ROOT)
+
+errors = 0
+
+# walk directories, find things
+printed_banner = False
+for target_dir in _TARGET_DIRS:
+  for root, dirs, filenames in os.walk(target_dir):
+    if 'README.md' not in filenames:
+      if not printed_banner:
+        print 'Missing README.md'
+        print '================='
+        printed_banner = True
+      print root
+      errors += 1
+if printed_banner: print
+printed_banner = False
+for target_dir in _TARGET_DIRS:
+  for root, dirs, filenames in os.walk(target_dir):
+    for filename in filenames:
+      if os.path.splitext(filename)[1] not in _INTERESTING_EXTENSIONS:
+        continue
+      path = os.path.join(root, filename)
+      with open(path) as f:
+        contents = f.read()
+      if '\\file' not in contents:
+        if not printed_banner:
+          print 'Missing \\file comment'
+          print '======================'
+          printed_banner = True
+        print path
+        errors += 1
+
+assert errors == 0, 'error count = %d' % errors
diff --git a/tools/dockerfile/distribtest/csharp_centos7_x64/Dockerfile b/tools/dockerfile/distribtest/csharp_centos7_x64/Dockerfile
index c917b29..6584845 100644
--- a/tools/dockerfile/distribtest/csharp_centos7_x64/Dockerfile
+++ b/tools/dockerfile/distribtest/csharp_centos7_x64/Dockerfile
@@ -34,4 +34,6 @@
 
 RUN yum install -y mono
 RUN yum install -y unzip
-RUN yum install -y nuget
+
+# --nogpgcheck because nuget-2.12 package is not signed.
+RUN yum install -y nuget --nogpgcheck
diff --git a/tools/dockerfile/distribtest/csharp_jessie_x64/Dockerfile b/tools/dockerfile/distribtest/csharp_jessie_x64/Dockerfile
index 249095a..c8cd575 100644
--- a/tools/dockerfile/distribtest/csharp_jessie_x64/Dockerfile
+++ b/tools/dockerfile/distribtest/csharp_jessie_x64/Dockerfile
@@ -40,4 +40,7 @@
     ca-certificates-mono \
     nuget
 
+# make sure we have nuget 2.12+ (in case there's an older cached docker image)
+RUN apt-get update && apt-get install -y nuget
+
 RUN apt-get update && apt-get install -y unzip
diff --git a/tools/dockerfile/distribtest/csharp_jessie_x86/Dockerfile b/tools/dockerfile/distribtest/csharp_jessie_x86/Dockerfile
index 9eda551..28cc654 100644
--- a/tools/dockerfile/distribtest/csharp_jessie_x86/Dockerfile
+++ b/tools/dockerfile/distribtest/csharp_jessie_x86/Dockerfile
@@ -40,4 +40,7 @@
     ca-certificates-mono \
     nuget
 
+# make sure we have nuget 2.12+ (in case there's an older cached docker image)
+RUN apt-get update && apt-get install -y nuget
+
 RUN apt-get update && apt-get install -y unzip
diff --git a/tools/dockerfile/distribtest/csharp_ubuntu1404_x64/Dockerfile b/tools/dockerfile/distribtest/csharp_ubuntu1404_x64/Dockerfile
index 85daea4..1f9a42e 100644
--- a/tools/dockerfile/distribtest/csharp_ubuntu1404_x64/Dockerfile
+++ b/tools/dockerfile/distribtest/csharp_ubuntu1404_x64/Dockerfile
@@ -37,4 +37,24 @@
     ca-certificates-mono \
     nuget
 
+# make sure we have nuget 2.12+ (in case there's an older cached docker image)
+RUN apt-get update && apt-get install -y nuget
+
 RUN apt-get update && apt-get install -y unzip
+
+# Install dotnet CLI
+RUN apt-get install -y apt-transport-https
+RUN sh -c 'echo "deb [arch=amd64] https://apt-mo.trafficmanager.net/repos/dotnet-release/ trusty main" > /etc/apt/sources.list.d/dotnetdev.list'
+RUN apt-key adv --keyserver apt-mo.trafficmanager.net --recv-keys 417A0893
+RUN apt-get update && apt-get install -y dotnet-dev-1.0.0-preview2-003121
+
+# Trigger the population of the local package cache for dotnet CLI
+RUN mkdir warmup \
+    && cd warmup \
+    && dotnet new \
+    && cd .. \
+    && rm -rf warmup
+
+# TODO(jtattermusch): without libc-dev, netcoreapp1.0 targets fail with
+# System.DllNotFoundException: Unable to load DLL 'libdl.so'
+RUN apt-get install -y libc-dev
\ No newline at end of file
diff --git a/tools/dockerfile/distribtest/csharp_ubuntu1504_x64/Dockerfile b/tools/dockerfile/distribtest/csharp_ubuntu1504_x64/Dockerfile
index ec16105..fd39ab2 100644
--- a/tools/dockerfile/distribtest/csharp_ubuntu1504_x64/Dockerfile
+++ b/tools/dockerfile/distribtest/csharp_ubuntu1504_x64/Dockerfile
@@ -37,4 +37,7 @@
     ca-certificates-mono \
     nuget
 
+# make sure we have nuget 2.12+ (in case there's an older cached docker image)
+RUN apt-get update && apt-get install -y nuget
+
 RUN apt-get update && apt-get install -y unzip
diff --git a/tools/dockerfile/distribtest/csharp_ubuntu1510_x64/Dockerfile b/tools/dockerfile/distribtest/csharp_ubuntu1510_x64/Dockerfile
index 110aa2a..1d86dbd 100644
--- a/tools/dockerfile/distribtest/csharp_ubuntu1510_x64/Dockerfile
+++ b/tools/dockerfile/distribtest/csharp_ubuntu1510_x64/Dockerfile
@@ -37,4 +37,7 @@
     ca-certificates-mono \
     nuget
 
+# make sure we have nuget 2.12+ (in case there's an older cached docker image)
+RUN apt-get update && apt-get install -y nuget
+
 RUN apt-get update && apt-get install -y unzip
diff --git a/tools/dockerfile/distribtest/csharp_ubuntu1604_x64/Dockerfile b/tools/dockerfile/distribtest/csharp_ubuntu1604_x64/Dockerfile
index 4ef0766..05fa32b 100644
--- a/tools/dockerfile/distribtest/csharp_ubuntu1604_x64/Dockerfile
+++ b/tools/dockerfile/distribtest/csharp_ubuntu1604_x64/Dockerfile
@@ -34,4 +34,9 @@
     ca-certificates-mono \
     nuget
 
+# make sure we have nuget 2.12+ (in case there's an older cached docker image)
+RUN apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF
+RUN echo "deb http://download.mono-project.com/repo/debian wheezy main" | tee /etc/apt/sources.list.d/mono-xamarin.list
+RUN apt-get update && apt-get install -y nuget
+
 RUN apt-get update && apt-get install -y unzip
diff --git a/tools/dockerfile/distribtest/csharp_wheezy_x64/Dockerfile b/tools/dockerfile/distribtest/csharp_wheezy_x64/Dockerfile
index d9e64fe..0ab2a62 100644
--- a/tools/dockerfile/distribtest/csharp_wheezy_x64/Dockerfile
+++ b/tools/dockerfile/distribtest/csharp_wheezy_x64/Dockerfile
@@ -27,6 +27,9 @@
 # (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 mono:4.2.2.30
+FROM mono:4.4.2.11
+
+# make sure we have nuget 2.12+ (in case there's an older cached docker image)
+RUN apt-get update && apt-get install -y nuget
 
 RUN apt-get update && apt-get install -y unzip
diff --git a/tools/dockerfile/interoptest/grpc_interop_csharpcoreclr/Dockerfile b/tools/dockerfile/interoptest/grpc_interop_csharpcoreclr/Dockerfile
new file mode 100644
index 0000000..efe6e39
--- /dev/null
+++ b/tools/dockerfile/interoptest/grpc_interop_csharpcoreclr/Dockerfile
@@ -0,0 +1,126 @@
+# Copyright 2015, Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+FROM debian:jessie
+
+# Install Git and basic packages.
+RUN apt-get update && apt-get install -y \
+  autoconf \
+  autotools-dev \
+  build-essential \
+  bzip2 \
+  ccache \
+  curl \
+  gcc \
+  gcc-multilib \
+  git \
+  golang \
+  gyp \
+  lcov \
+  libc6 \
+  libc6-dbg \
+  libc6-dev \
+  libgtest-dev \
+  libtool \
+  make \
+  perl \
+  strace \
+  python-dev \
+  python-setuptools \
+  python-yaml \
+  telnet \
+  unzip \
+  wget \
+  zip && apt-get clean
+
+#================
+# Build profiling
+RUN apt-get update && apt-get install -y time && apt-get clean
+
+#====================
+# Python dependencies
+
+# Install dependencies
+
+RUN apt-get update && apt-get install -y \
+    python-all-dev \
+    python3-all-dev \
+    python-pip
+
+# Install Python packages from PyPI
+RUN pip install pip --upgrade
+RUN pip install virtualenv
+RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.0.0a2 six==1.10.0
+
+#================
+# C# dependencies
+
+# Update to a newer version of mono
+RUN apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF
+RUN echo "deb http://download.mono-project.com/repo/debian wheezy main" | tee /etc/apt/sources.list.d/mono-xamarin.list
+RUN echo "deb http://download.mono-project.com/repo/debian wheezy-apache24-compat main" | tee -a /etc/apt/sources.list.d/mono-xamarin.list
+RUN echo "deb http://download.mono-project.com/repo/debian wheezy-libjpeg62-compat main" | tee -a /etc/apt/sources.list.d/mono-xamarin.list
+RUN echo "deb http://download.mono-project.com/repo/debian wheezy-libtiff-compat main" | tee -a /etc/apt/sources.list.d/mono-xamarin.list
+
+# Install dependencies
+RUN apt-get update && apt-get -y dist-upgrade && apt-get install -y \
+    mono-devel \
+    ca-certificates-mono \
+    nuget \
+    && apt-get clean
+
+RUN nuget update -self
+
+# Install dotnet SDK based on https://www.microsoft.com/net/core#debian
+RUN apt-get update && apt-get install -y curl libunwind8 gettext
+RUN curl -sSL -o dotnet.tar.gz https://go.microsoft.com/fwlink/?LinkID=809130
+RUN mkdir -p /opt/dotnet && tar zxf dotnet.tar.gz -C /opt/dotnet
+RUN ln -s /opt/dotnet/dotnet /usr/local/bin
+
+# Trigger the population of the local package cache
+ENV NUGET_XMLDOC_MODE skip
+RUN mkdir warmup \
+    && cd warmup \
+    && dotnet new \
+    && cd .. \
+    && rm -rf warmup
+
+# Prepare ccache
+RUN ln -s /usr/bin/ccache /usr/local/bin/gcc
+RUN ln -s /usr/bin/ccache /usr/local/bin/g++
+RUN ln -s /usr/bin/ccache /usr/local/bin/cc
+RUN ln -s /usr/bin/ccache /usr/local/bin/c++
+RUN ln -s /usr/bin/ccache /usr/local/bin/clang
+RUN ln -s /usr/bin/ccache /usr/local/bin/clang++
+
+
+RUN mkdir /var/local/jenkins
+
+# Define the default command.
+CMD ["bash"]
diff --git a/tools/dockerfile/interoptest/grpc_interop_csharpcoreclr/build_interop.sh b/tools/dockerfile/interoptest/grpc_interop_csharpcoreclr/build_interop.sh
new file mode 100755
index 0000000..77cd65c
--- /dev/null
+++ b/tools/dockerfile/interoptest/grpc_interop_csharpcoreclr/build_interop.sh
@@ -0,0 +1,43 @@
+#!/bin/bash
+# Copyright 2015, Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# Builds C# interop server and client in a base image.
+set -e
+
+mkdir -p /var/local/git
+git clone --recursive /var/local/jenkins/grpc /var/local/git/grpc
+
+# copy service account keys if available
+cp -r /var/local/jenkins/service_account $HOME || true
+
+cd /var/local/git/grpc
+
+# build C# interop client & server
+tools/run_tests/run_tests.py -l csharp -c dbg --compiler coreclr --build_only
diff --git a/tools/dockerfile/test/csharp_coreclr_x64/Dockerfile b/tools/dockerfile/test/csharp_coreclr_x64/Dockerfile
index 4921815..efe6e39 100644
--- a/tools/dockerfile/test/csharp_coreclr_x64/Dockerfile
+++ b/tools/dockerfile/test/csharp_coreclr_x64/Dockerfile
@@ -97,7 +97,6 @@
 
 RUN nuget update -self
 
-
 # Install dotnet SDK based on https://www.microsoft.com/net/core#debian
 RUN apt-get update && apt-get install -y curl libunwind8 gettext
 RUN curl -sSL -o dotnet.tar.gz https://go.microsoft.com/fwlink/?LinkID=809130
diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++
index 314a42d..59a6e1c 100644
--- a/tools/doxygen/Doxyfile.c++
+++ b/tools/doxygen/Doxyfile.c++
@@ -814,27 +814,23 @@
 include/grpc/grpc_posix.h \
 include/grpc/grpc_security_constants.h \
 include/grpc/status.h \
-include/grpc/impl/codegen/byte_buffer.h \
 include/grpc/impl/codegen/byte_buffer_reader.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 \
 include/grpc/impl/codegen/atm_gcc_sync.h \
 include/grpc/impl/codegen/atm_windows.h \
-include/grpc/impl/codegen/log.h \
+include/grpc/impl/codegen/gpr_types.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_windows.h \
-include/grpc/impl/codegen/time.h \
 include/grpc++/impl/codegen/async_stream.h \
 include/grpc++/impl/codegen/async_unary_call.h \
 include/grpc++/impl/codegen/call.h \
diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal
index 12eb651..d94aa42 100644
--- a/tools/doxygen/Doxyfile.c++.internal
+++ b/tools/doxygen/Doxyfile.c++.internal
@@ -814,27 +814,23 @@
 include/grpc/grpc_posix.h \
 include/grpc/grpc_security_constants.h \
 include/grpc/status.h \
-include/grpc/impl/codegen/byte_buffer.h \
 include/grpc/impl/codegen/byte_buffer_reader.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 \
 include/grpc/impl/codegen/atm_gcc_sync.h \
 include/grpc/impl/codegen/atm_windows.h \
-include/grpc/impl/codegen/log.h \
+include/grpc/impl/codegen/gpr_types.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_windows.h \
-include/grpc/impl/codegen/time.h \
 include/grpc++/impl/codegen/async_stream.h \
 include/grpc++/impl/codegen/async_unary_call.h \
 include/grpc++/impl/codegen/call.h \
@@ -953,39 +949,39 @@
 src/core/lib/transport/timeout_encoding.h \
 src/core/lib/transport/transport.h \
 src/core/lib/transport/transport_impl.h \
+src/cpp/client/insecure_credentials.cc \
 src/cpp/client/secure_credentials.cc \
 src/cpp/common/auth_property_iterator.cc \
 src/cpp/common/secure_auth_context.cc \
 src/cpp/common/secure_channel_arguments.cc \
 src/cpp/common/secure_create_auth_context.cc \
+src/cpp/server/insecure_server_credentials.cc \
 src/cpp/server/secure_server_credentials.cc \
-src/cpp/client/channel.cc \
+src/cpp/client/channel_cc.cc \
 src/cpp/client/client_context.cc \
 src/cpp/client/create_channel.cc \
 src/cpp/client/create_channel_internal.cc \
 src/cpp/client/create_channel_posix.cc \
-src/cpp/client/credentials.cc \
+src/cpp/client/credentials_cc.cc \
 src/cpp/client/generic_stub.cc \
-src/cpp/client/insecure_credentials.cc \
 src/cpp/common/channel_arguments.cc \
 src/cpp/common/channel_filter.cc \
-src/cpp/common/completion_queue.cc \
+src/cpp/common/completion_queue_cc.cc \
 src/cpp/common/core_codegen.cc \
 src/cpp/common/rpc_method.cc \
 src/cpp/server/async_generic_service.cc \
 src/cpp/server/create_default_thread_pool.cc \
 src/cpp/server/dynamic_thread_pool.cc \
-src/cpp/server/insecure_server_credentials.cc \
-src/cpp/server/server.cc \
 src/cpp/server/server_builder.cc \
+src/cpp/server/server_cc.cc \
 src/cpp/server/server_context.cc \
 src/cpp/server/server_credentials.cc \
 src/cpp/server/server_posix.cc \
-src/cpp/util/byte_buffer.cc \
-src/cpp/util/slice.cc \
+src/cpp/util/byte_buffer_cc.cc \
+src/cpp/util/slice_cc.cc \
 src/cpp/util/status.cc \
 src/cpp/util/string_ref.cc \
-src/cpp/util/time.cc \
+src/cpp/util/time_cc.cc \
 src/core/lib/channel/channel_args.c \
 src/core/lib/channel/channel_stack.c \
 src/core/lib/channel/channel_stack_builder.c \
diff --git a/tools/doxygen/Doxyfile.core b/tools/doxygen/Doxyfile.core
index 27f878e..003686c 100644
--- a/tools/doxygen/Doxyfile.core
+++ b/tools/doxygen/Doxyfile.core
@@ -767,27 +767,23 @@
 include/grpc/grpc_posix.h \
 include/grpc/grpc_security_constants.h \
 include/grpc/status.h \
-include/grpc/impl/codegen/byte_buffer.h \
 include/grpc/impl/codegen/byte_buffer_reader.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 \
 include/grpc/impl/codegen/atm_gcc_sync.h \
 include/grpc/impl/codegen/atm_windows.h \
-include/grpc/impl/codegen/log.h \
+include/grpc/impl/codegen/gpr_types.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_windows.h \
-include/grpc/impl/codegen/time.h \
 include/grpc/grpc_security.h \
 include/grpc/census.h \
 include/grpc/support/alloc.h \
@@ -818,20 +814,17 @@
 include/grpc/support/tls_msvc.h \
 include/grpc/support/tls_pthread.h \
 include/grpc/support/useful.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_windows.h \
-include/grpc/impl/codegen/log.h \
+include/grpc/impl/codegen/gpr_types.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_windows.h \
-include/grpc/impl/codegen/time.h
+include/grpc/impl/codegen/sync_windows.h
 
 # This tag can be used to specify the character encoding of the source files
 # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal
index 7d279ed..e2d44e8 100644
--- a/tools/doxygen/Doxyfile.core.internal
+++ b/tools/doxygen/Doxyfile.core.internal
@@ -767,27 +767,23 @@
 include/grpc/grpc_posix.h \
 include/grpc/grpc_security_constants.h \
 include/grpc/status.h \
-include/grpc/impl/codegen/byte_buffer.h \
 include/grpc/impl/codegen/byte_buffer_reader.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 \
 include/grpc/impl/codegen/atm_gcc_sync.h \
 include/grpc/impl/codegen/atm_windows.h \
-include/grpc/impl/codegen/log.h \
+include/grpc/impl/codegen/gpr_types.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_windows.h \
-include/grpc/impl/codegen/time.h \
 include/grpc/grpc_security.h \
 include/grpc/census.h \
 src/core/lib/channel/channel_args.h \
@@ -1167,25 +1163,23 @@
 include/grpc/support/tls_msvc.h \
 include/grpc/support/tls_pthread.h \
 include/grpc/support/useful.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_windows.h \
-include/grpc/impl/codegen/log.h \
+include/grpc/impl/codegen/gpr_types.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_windows.h \
-include/grpc/impl/codegen/time.h \
 src/core/lib/profiling/timers.h \
 src/core/lib/support/backoff.h \
 src/core/lib/support/block_annotate.h \
 src/core/lib/support/env.h \
 src/core/lib/support/murmur_hash.h \
+src/core/lib/support/percent_encoding.h \
 src/core/lib/support/stack_lockfree.h \
 src/core/lib/support/string.h \
 src/core/lib/support/string_windows.h \
@@ -1213,6 +1207,7 @@
 src/core/lib/support/log_posix.c \
 src/core/lib/support/log_windows.c \
 src/core/lib/support/murmur_hash.c \
+src/core/lib/support/percent_encoding.c \
 src/core/lib/support/slice.c \
 src/core/lib/support/slice_buffer.c \
 src/core/lib/support/stack_lockfree.c \
diff --git a/tools/fuzzer/runners/percent_decode_fuzzer.sh b/tools/fuzzer/runners/percent_decode_fuzzer.sh
new file mode 100644
index 0000000..5a47fa2
--- /dev/null
+++ b/tools/fuzzer/runners/percent_decode_fuzzer.sh
@@ -0,0 +1,45 @@
+#!/bin/bash
+# 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.
+#
+
+flags="-max_total_time=$runtime -artifact_prefix=fuzzer_output/ -max_len=32 -timeout=120"
+
+
+if [ "$jobs" != "1" ]
+then
+  flags="-jobs=$jobs -workers=$jobs $flags"
+fi
+
+if [ "$config" == "asan-trace-cmp" ]
+then
+  flags="-use_traces=1 $flags"
+fi
+
+bins/$config/percent_decode_fuzzer $flags fuzzer_output test/core/support/percent_decode_corpus
diff --git a/tools/fuzzer/runners/percent_encode_fuzzer.sh b/tools/fuzzer/runners/percent_encode_fuzzer.sh
new file mode 100644
index 0000000..8136ef8
--- /dev/null
+++ b/tools/fuzzer/runners/percent_encode_fuzzer.sh
@@ -0,0 +1,45 @@
+#!/bin/bash
+# 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.
+#
+
+flags="-max_total_time=$runtime -artifact_prefix=fuzzer_output/ -max_len=32 -timeout=120"
+
+
+if [ "$jobs" != "1" ]
+then
+  flags="-jobs=$jobs -workers=$jobs $flags"
+fi
+
+if [ "$config" == "asan-trace-cmp" ]
+then
+  flags="-use_traces=1 $flags"
+fi
+
+bins/$config/percent_encode_fuzzer $flags fuzzer_output test/core/support/percent_encode_corpus
diff --git a/tools/gce/linux_performance_worker_init.sh b/tools/gce/linux_performance_worker_init.sh
index 23a8f08..ea80d74 100755
--- a/tools/gce/linux_performance_worker_init.sh
+++ b/tools/gce/linux_performance_worker_init.sh
@@ -112,6 +112,11 @@
 sudo apt-get update
 sudo apt-get install -y mono-devel nuget
 
+# The version of nuget that is installed using apt-get is too old to download
+# the System.Interactive.Async.3.0.0 C# dependency. Update to the latest version
+# in order to be able download it.
+sudo nuget update -self
+
 # Ruby dependencies
 gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3
 curl -sSL https://get.rvm.io | bash -s stable --ruby
diff --git a/tools/gource/gen-all-logs.sh b/tools/gource/gen-all-logs.sh
index ab60c3c..2512cc2 100755
--- a/tools/gource/gen-all-logs.sh
+++ b/tools/gource/gen-all-logs.sh
@@ -34,7 +34,7 @@
 
 tmpdir=`mktemp -d`
 mkdir -p $tmpdir/logs
-repos="grpc grpc-common grpc-go grpc-java grpc.github.io grpc-tools homebrew-grpc grpc-docker-library"
+repos="grpc grpc-common grpc-go grpc-java grpc.github.io"
 for repo in $repos
 do
   cd $tmpdir
diff --git a/tools/jenkins/run_full_cloud_prod.sh b/tools/jenkins/run_full_cloud_prod.sh
old mode 100644
new mode 100755
diff --git a/tools/jenkins/run_sweep_performance.sh b/tools/jenkins/run_sweep_performance.sh
new file mode 100755
index 0000000..6cd7a91
--- /dev/null
+++ b/tools/jenkins/run_sweep_performance.sh
@@ -0,0 +1,45 @@
+#!/usr/bin/env bash
+# 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 script is invoked by Jenkins and runs full performance test suite.
+set -ex
+
+# Enter the gRPC repo root
+cd $(dirname $0)/../..
+
+# scalability with 32cores (and upload to a different BQ table)
+tools/run_tests/run_performance_tests.py \
+    -l c++ \
+    --category sweep \
+    --bq_result_table performance_test.performance_experiment_32core \
+    --remote_worker_host grpc-performance-server-32core grpc-performance-client-32core grpc-performance-client2-32core \
+    || EXIT_CODE=1
+
+exit $EXIT_CODE
diff --git a/tools/run_tests/build_artifact_protoc.bat b/tools/run_tests/build_artifact_protoc.bat
index e1dc032..3246a90 100644
--- a/tools/run_tests/build_artifact_protoc.bat
+++ b/tools/run_tests/build_artifact_protoc.bat
@@ -32,12 +32,8 @@
 setlocal
 cd third_party/protobuf
 
-powershell -Command "Invoke-WebRequest https://googlemock.googlecode.com/files/gmock-1.7.0.zip -OutFile gmock.zip"
-powershell -Command "Add-Type -Assembly 'System.IO.Compression.FileSystem'; [System.IO.Compression.ZipFile]::ExtractToDirectory('gmock.zip', '.');"
-rename gmock-1.7.0 gmock
-
 cd cmake
-cmake -G "%generator%" || goto :error
+cmake -G "%generator%" -Dprotobuf_BUILD_TESTS=OFF || goto :error
 endlocal
 
 call vsprojects/build_plugins.bat || goto :error
diff --git a/tools/run_tests/build_csharp_coreclr.bat b/tools/run_tests/build_csharp_coreclr.bat
index cead6d0..b6e3ccb 100644
--- a/tools/run_tests/build_csharp_coreclr.bat
+++ b/tools/run_tests/build_csharp_coreclr.bat
@@ -33,7 +33,7 @@
 
 dotnet restore . || goto :error
 
-dotnet build -f netstandard1.5 --configuration %MSBUILD_CONFIG% "**/project.json" || goto :error
+dotnet build --configuration %MSBUILD_CONFIG% "**/project.json" || goto :error
 
 endlocal
 
diff --git a/tools/run_tests/distribtest_targets.py b/tools/run_tests/distribtest_targets.py
index 7930f2a..a16daac 100644
--- a/tools/run_tests/distribtest_targets.py
+++ b/tools/run_tests/distribtest_targets.py
@@ -72,15 +72,22 @@
 class CSharpDistribTest(object):
   """Tests C# NuGet package"""
 
-  def __init__(self, platform, arch, docker_suffix=None):
+  def __init__(self, platform, arch, docker_suffix=None, use_dotnet_cli=False):
     self.name = 'csharp_nuget_%s_%s' % (platform, arch)
     self.platform = platform
     self.arch = arch
     self.docker_suffix = docker_suffix
     self.labels = ['distribtest', 'csharp', platform, arch]
+    self.script_suffix = ''
     if docker_suffix:
       self.name += '_%s' % docker_suffix
       self.labels.append(docker_suffix)
+    if use_dotnet_cli:
+      self.name += '_dotnetcli'
+      self.script_suffix = '_dotnetcli'
+      self.labels.append('dotnetcli')
+    else:
+      self.labels.append('olddotnet')
 
   def pre_build_jobspecs(self):
     return []
@@ -91,10 +98,10 @@
           'tools/dockerfile/distribtest/csharp_%s_%s' % (
               self.docker_suffix,
               self.arch),
-          'test/distrib/csharp/run_distrib_test.sh')
+          'test/distrib/csharp/run_distrib_test%s.sh' % self.script_suffix)
     elif self.platform == 'macos':
       return create_jobspec(self.name,
-          ['test/distrib/csharp/run_distrib_test.sh'],
+          ['test/distrib/csharp/run_distrib_test%s.sh' % self.script_suffix],
           environ={'EXTERNAL_GIT_ROOT': '../../..'})
     elif self.platform == 'windows':
       if self.arch == 'x64':
@@ -103,7 +110,7 @@
       else:
         environ={'DISTRIBTEST_OUTPATH': 'DistribTest\\bin\\\Debug'}
       return create_jobspec(self.name,
-          ['test\\distrib\\csharp\\run_distrib_test.bat'],
+          ['test\\distrib\\csharp\\run_distrib_test%s.bat' % self.script_suffix],
           environ=environ)
     else:
       raise Exception("Not supported yet.")
@@ -276,6 +283,7 @@
           CSharpDistribTest('linux', 'x64', 'ubuntu1504'),
           CSharpDistribTest('linux', 'x64', 'ubuntu1510'),
           CSharpDistribTest('linux', 'x64', 'ubuntu1604'),
+          CSharpDistribTest('linux', 'x64', 'ubuntu1404', use_dotnet_cli=True),
           CSharpDistribTest('macos', 'x86'),
           CSharpDistribTest('windows', 'x86'),
           CSharpDistribTest('windows', 'x64'),
diff --git a/tools/run_tests/package_targets.py b/tools/run_tests/package_targets.py
index 5e6de2e..abbb5fa 100644
--- a/tools/run_tests/package_targets.py
+++ b/tools/run_tests/package_targets.py
@@ -71,11 +71,11 @@
 class CSharpPackage:
   """Builds C# nuget packages."""
 
-  def __init__(self, use_coreclr=False):
-    self.use_coreclr = use_coreclr
-    self.name = 'csharp_package_coreclr' if use_coreclr else 'csharp_package'
+  def __init__(self, use_dotnet_cli=False):
+    self.use_dotnet_cli = use_dotnet_cli
+    self.name = 'csharp_package_dotnetcli' if use_dotnet_cli else 'csharp_package'
     self.labels = ['package', 'csharp']
-    if use_coreclr:
+    if use_dotnet_cli:
       self.labels += ['linux']
     else:
       self.labels += ['windows']
@@ -91,11 +91,11 @@
       return []
 
   def build_jobspec(self):
-    if self.use_coreclr:
+    if self.use_dotnet_cli:
       return create_docker_jobspec(
           self.name,
           'tools/dockerfile/test/csharp_coreclr_x64',
-          'tools/run_tests/build_package_csharp_coreclr.sh')
+          'src/csharp/build_packages_dotnetcli.sh')
     else:
       return create_jobspec(self.name,
                             ['build_packages.bat'],
@@ -177,7 +177,7 @@
 def targets():
   """Gets list of supported targets"""
   return [CSharpPackage(),
-          CSharpPackage(use_coreclr=True),
+          CSharpPackage(use_dotnet_cli=True),
           NodePackage(),
           RubyPackage(),
           PythonPackage(),
diff --git a/tools/run_tests/performance/scenario_config.py b/tools/run_tests/performance/scenario_config.py
index 4dfd01f..99b5596 100644
--- a/tools/run_tests/performance/scenario_config.py
+++ b/tools/run_tests/performance/scenario_config.py
@@ -29,12 +29,15 @@
 
 # performance scenario configuration for various languages
 
+import math
+
 WARMUP_SECONDS=5
 JAVA_WARMUP_SECONDS=15  # Java needs more warmup time for JIT to kick in.
 BENCHMARK_SECONDS=30
 
 SMOKETEST='smoketest'
 SCALABLE='scalable'
+SWEEP='sweep'
 
 SECURE_SECARGS = {'use_test_ca': True,
                   'server_host_override': 'foo.test.google.fr'}
@@ -63,17 +66,17 @@
   }
 }
 
-# deep is the number of RPCs outstanding on a channel in non-ping-pong tests
-# (the value used is 1 otherwise)
-DEEP=100
+# target number of RPCs outstanding on across all client channels in
+# non-ping-pong tests (since we can only specify per-channel numbers, the
+# actual target will be slightly higher)
+OUTSTANDING_REQUESTS={
+    'async': 6400,
+    'sync': 1000
+}
 
 # wide is the number of client channels in multi-channel tests (1 otherwise)
 WIDE=64
 
-# For most synchronous clients, DEEP*WIDE threads will be created.
-SYNC_DEEP=10
-SYNC_WIDE=8
-
 
 def _get_secargs(is_secure):
   if is_secure:
@@ -101,7 +104,8 @@
                         server_core_limit=0,
                         async_server_threads=0,
                         warmup_seconds=WARMUP_SECONDS,
-                        categories=[]):
+                        categories=[],
+                        channels=None):
   """Creates a basic ping pong scenario."""
   scenario = {
     'name': name,
@@ -138,14 +142,8 @@
     scenario['client_config']['payload_config'] = EMPTY_PROTO_PAYLOAD
 
   if unconstrained_client:
-    if unconstrained_client == 'async':
-      deep = DEEP
-      wide = WIDE
-    elif unconstrained_client == 'sync':
-      deep = SYNC_DEEP
-      wide = SYNC_WIDE
-    else:
-      raise Exception('Illegal value of unconstrained_client option.')
+    wide = channels if channels is not None else WIDE
+    deep = int(math.ceil(1.0 * OUTSTANDING_REQUESTS[unconstrained_client] / wide))
 
     scenario['num_clients'] = 0  # use as many client as available.
     scenario['client_config']['outstanding_rpcs_per_channel'] = deep
@@ -185,59 +183,76 @@
       smoketest_categories = [SMOKETEST] if secure else []
 
       yield _ping_pong_scenario(
-          'cpp_generic_async_streaming_ping_pong_%s' % secstr, rpc_type='STREAMING',
-          client_type='ASYNC_CLIENT', server_type='ASYNC_GENERIC_SERVER',
+          'cpp_generic_async_streaming_ping_pong_%s' % secstr,
+          rpc_type='STREAMING',
+          client_type='ASYNC_CLIENT',
+          server_type='ASYNC_GENERIC_SERVER',
           use_generic_payload=True, server_core_limit=1, async_server_threads=1,
           secure=secure,
           categories=smoketest_categories)
 
       yield _ping_pong_scenario(
-          'cpp_protobuf_async_streaming_ping_pong_%s' % secstr, rpc_type='STREAMING',
-          client_type='ASYNC_CLIENT', server_type='ASYNC_SERVER',
-          server_core_limit=1, async_server_threads=1,
-          secure=secure)
-
-      yield _ping_pong_scenario(
-          'cpp_protobuf_async_unary_ping_pong_%s' % secstr, rpc_type='UNARY',
-          client_type='ASYNC_CLIENT', server_type='ASYNC_SERVER',
-          server_core_limit=1, async_server_threads=1,
-          secure=secure,
-          categories=smoketest_categories)
-
-      yield _ping_pong_scenario(
-          'cpp_protobuf_sync_unary_ping_pong_%s' % secstr, rpc_type='UNARY',
-          client_type='SYNC_CLIENT', server_type='SYNC_SERVER',
-          server_core_limit=1, async_server_threads=1,
-          secure=secure)
-
-      yield _ping_pong_scenario(
-          'cpp_protobuf_async_unary_qps_unconstrained_%s' % secstr, rpc_type='UNARY',
-          client_type='ASYNC_CLIENT', server_type='ASYNC_SERVER',
-          unconstrained_client='async',
-          secure=secure,
-          categories=smoketest_categories+[SCALABLE])
-
-      yield _ping_pong_scenario(
-          'cpp_protobuf_async_streaming_qps_unconstrained_%s' % secstr, rpc_type='STREAMING',
-          client_type='ASYNC_CLIENT', server_type='ASYNC_SERVER',
-          unconstrained_client='async',
-          secure=secure,
-          categories=[SCALABLE])
-
-      yield _ping_pong_scenario(
-          'cpp_generic_async_streaming_qps_unconstrained_%s' % secstr, rpc_type='STREAMING',
-          client_type='ASYNC_CLIENT', server_type='ASYNC_GENERIC_SERVER',
+          'cpp_generic_async_streaming_qps_unconstrained_%s' % secstr,
+          rpc_type='STREAMING',
+          client_type='ASYNC_CLIENT',
+          server_type='ASYNC_GENERIC_SERVER',
           unconstrained_client='async', use_generic_payload=True,
           secure=secure,
           categories=smoketest_categories+[SCALABLE])
 
       yield _ping_pong_scenario(
-          'cpp_generic_async_streaming_qps_one_server_core_%s' % secstr, rpc_type='STREAMING',
-          client_type='ASYNC_CLIENT', server_type='ASYNC_GENERIC_SERVER',
+          'cpp_generic_async_streaming_qps_one_server_core_%s' % secstr,
+          rpc_type='STREAMING',
+          client_type='ASYNC_CLIENT',
+          server_type='ASYNC_GENERIC_SERVER',
           unconstrained_client='async', use_generic_payload=True,
           server_core_limit=1, async_server_threads=1,
           secure=secure)
 
+      for synchronicity in ['sync', 'async']:
+        yield _ping_pong_scenario(
+            'cpp_protobuf_%s_streaming_ping_pong_%s' % (synchronicity, secstr),
+            rpc_type='STREAMING',
+            client_type='%s_CLIENT' % synchronicity.upper(),
+            server_type='%s_SERVER' % synchronicity.upper(),
+            server_core_limit=1, async_server_threads=1,
+            secure=secure)
+
+        yield _ping_pong_scenario(
+            'cpp_protobuf_%s_unary_ping_pong_%s' % (synchronicity, secstr),
+            rpc_type='UNARY',
+            client_type='%s_CLIENT' % synchronicity.upper(),
+            server_type='%s_SERVER' % synchronicity.upper(),
+            server_core_limit=1, async_server_threads=1,
+            secure=secure,
+            categories=smoketest_categories)
+
+        yield _ping_pong_scenario(
+            'cpp_protobuf_%s_unary_qps_unconstrained_%s' % (synchronicity, secstr),
+            rpc_type='UNARY',
+            client_type='%s_CLIENT' % synchronicity.upper(),
+            server_type='%s_SERVER' % synchronicity.upper(),
+            unconstrained_client=synchronicity,
+            secure=secure,
+            categories=smoketest_categories+[SCALABLE])
+
+        yield _ping_pong_scenario(
+            'cpp_protobuf_%s_streaming_qps_unconstrained_%s' % (synchronicity, secstr),
+            rpc_type='STREAMING',
+            client_type='%s_CLIENT' % synchronicity.upper(),
+            server_type='%s_SERVER' % synchronicity.upper(),
+            unconstrained_client=synchronicity,
+            secure=secure,
+            categories=[SCALABLE])
+
+        for channels in [1, 3, 10, 31, 100, 316, 1000]:
+          yield _ping_pong_scenario(
+              'cpp_protobuf_%s_unary_qps_unconstrained_%s_%d_channels' % (synchronicity, secstr, channels),
+              rpc_type='UNARY',
+              client_type='ASYNC_CLIENT', server_type='ASYNC_SERVER',
+              unconstrained_client=synchronicity, secure=secure,
+              categories=[SWEEP], channels=channels)
+
   def __str__(self):
     return 'c++'
 
@@ -548,7 +563,7 @@
           async_server_threads=1,
           secure=secure, warmup_seconds=JAVA_WARMUP_SECONDS)
 
-      # TODO(jtattermusch): add scenarios java vs C++ 
+      # TODO(jtattermusch): add scenarios java vs C++
 
   def __str__(self):
     return 'java'
@@ -572,7 +587,7 @@
       smoketest_categories = [SMOKETEST] if secure else []
 
       # ASYNC_GENERIC_SERVER for Go actually uses a sync streaming server,
-      # but that's mostly because of lack of better name of the enum value. 
+      # but that's mostly because of lack of better name of the enum value.
       yield _ping_pong_scenario(
           'go_generic_sync_streaming_ping_pong_%s' % secstr, rpc_type='STREAMING',
           client_type='SYNC_CLIENT', server_type='ASYNC_GENERIC_SERVER',
@@ -619,7 +634,7 @@
           secure=secure,
           categories=[SCALABLE])
 
-      # TODO(jtattermusch): add scenarios go vs C++ 
+      # TODO(jtattermusch): add scenarios go vs C++
 
   def __str__(self):
     return 'go'
diff --git a/tools/run_tests/pre_build_csharp.bat b/tools/run_tests/pre_build_csharp.bat
index 580d563..f15979a 100644
--- a/tools/run_tests/pre_build_csharp.bat
+++ b/tools/run_tests/pre_build_csharp.bat
@@ -38,9 +38,10 @@
 set NUGET=C:\nuget\nuget.exe
 
 if exist %NUGET% (
+  @rem TODO(jtattermusch): Get rid of this hack. See #8034
   @rem Restore Grpc packages by packages since Nuget client 3.4.4 doesnt support restore
   @rem by solution
-  @rem Moving into each directory to let the restores work with both nuget 3.4 and 2.8
+  @rem Moving into each directory to let the restores work based on per-project packages.config files
   %NUGET% restore vsprojects/grpc_csharp_ext.sln || goto :error
 
   cd src/csharp
diff --git a/tools/run_tests/pre_build_csharp.sh b/tools/run_tests/pre_build_csharp.sh
index 0fd3b92..ee678dd 100755
--- a/tools/run_tests/pre_build_csharp.sh
+++ b/tools/run_tests/pre_build_csharp.sh
@@ -37,9 +37,10 @@
 
 if [ -x "$(command -v nuget)" ]
 then
+  # TODO(jtattermusch): Get rid of this hack. See #8034
   # Restoring Nuget packages by packages rather than by solution because of
   # inability to restore by solution with Nuget client 3.4.4
-  # Moving into each directory to let the restores work with nuget 3.4 and 2.8
+  # Moving into each directory to let the restores work based on per-project packages.config files
   cd Grpc.Auth
   nuget restore -PackagesDirectory ../packages
   cd ..
diff --git a/tools/run_tests/run_build_statistics.py b/tools/run_tests/run_build_statistics.py
index 92c5378..df155f8 100755
--- a/tools/run_tests/run_build_statistics.py
+++ b/tools/run_tests/run_build_statistics.py
@@ -56,13 +56,27 @@
            'gRPC_interop_pull_requests': not _HAS_MATRIX,
 }
 _URL_BASE = 'https://grpc-testing.appspot.com/job'
+
+# This is a dynamic list where known and active issues should be added. 
+# Fixed ones should be removed.
+# Also try not to add multiple messages from the same failure.
 _KNOWN_ERRORS = [
     'Failed to build workspace Tests with scheme AllTests',
     'Build timed out',
     'FATAL: Unable to produce a script file',
-    'FAILED: Failed to build interop docker images',
+    'FAILED: build_docker_c++',
+    'cannot find package \"cloud.google.com/go/compute/metadata\"',
     'LLVM ERROR: IO failure on output stream.',
     'MSBUILD : error MSB1009: Project file does not exist.',
+    'fatal: git fetch_pack: expected ACK/NAK',
+    'Failed to fetch from http://github.com/grpc/grpc.git',
+    ('hudson.remoting.RemotingSystemException: java.io.IOException: '
+     'Backing channel is disconnected.'),
+    'FAILED: bins/tsan/qps_openloop_test GRPC_POLL_STRATEGY=epoll',
+    'FAILED: bins/tsan/qps_openloop_test GRPC_POLL_STRATEGY=legacy',
+    'FAILED: bins/tsan/qps_openloop_test GRPC_POLL_STRATEGY=poll',
+    ('tests.bins/asan/h2_proxy_test streaming_error_response '
+     'GRPC_POLL_STRATEGY=legacy'),
 ]
 _UNKNOWN_ERROR = 'Unknown error'
 _DATASET_ID = 'build_statistics'
diff --git a/tools/run_tests/run_interop_tests.py b/tools/run_tests/run_interop_tests.py
index 5feda65..389d070 100755
--- a/tools/run_tests/run_interop_tests.py
+++ b/tools/run_tests/run_interop_tests.py
@@ -127,6 +127,35 @@
     return 'csharp'
 
 
+class CSharpCoreCLRLanguage:
+
+  def __init__(self):
+    self.client_cwd = 'src/csharp/Grpc.IntegrationTesting.Client/bin/Debug/netcoreapp1.0'
+    self.server_cwd = 'src/csharp/Grpc.IntegrationTesting.Server/bin/Debug/netcoreapp1.0'
+    self.safename = str(self)
+
+  def client_cmd(self, args):
+    return ['dotnet', 'exec', 'Grpc.IntegrationTesting.Client.dll'] + args
+
+  def cloud_to_prod_env(self):
+    return {}
+
+  def server_cmd(self, args):
+    return ['dotnet', 'exec', 'Grpc.IntegrationTesting.Server.dll', '--use_tls=true'] + args
+
+  def global_env(self):
+    return {}
+
+  def unimplemented_test_cases(self):
+    return _SKIP_SERVER_COMPRESSION
+
+  def unimplemented_test_cases_server(self):
+    return _SKIP_COMPRESSION
+
+  def __str__(self):
+    return 'csharpcoreclr'
+
+
 class JavaLanguage:
 
   def __init__(self):
@@ -367,6 +396,7 @@
 _LANGUAGES = {
     'c++' : CXXLanguage(),
     'csharp' : CSharpLanguage(),
+    'csharpcoreclr' : CSharpCoreCLRLanguage(),
     'go' : GoLanguage(),
     'java' : JavaLanguage(),
     'node' : NodeLanguage(),
@@ -377,7 +407,7 @@
 }
 
 # languages supported as cloud_to_cloud servers
-_SERVERS = ['c++', 'node', 'csharp', 'java', 'go', 'ruby', 'python']
+_SERVERS = ['c++', 'node', 'csharp', 'csharpcoreclr', 'java', 'go', 'ruby', 'python']
 
 _TEST_CASES = ['large_unary', 'empty_unary', 'ping_pong',
                'empty_stream', 'client_streaming', 'server_streaming',
@@ -435,7 +465,7 @@
   default_account_arg = '--default_service_account=830293263384-compute@developer.gserviceaccount.com'
 
   if test_case in ['jwt_token_creds', 'per_rpc_creds', 'oauth2_auth_token']:
-    if language in ['csharp', 'node', 'php', 'php7', 'python', 'ruby']:
+    if language in ['csharp', 'csharpcoreclr', 'node', 'php', 'php7', 'python', 'ruby']:
       env['GOOGLE_APPLICATION_CREDENTIALS'] = key_filepath
     else:
       cmdargs += [key_file_arg]
diff --git a/tools/run_tests/run_performance_tests.py b/tools/run_tests/run_performance_tests.py
index 5fdf7a4..b8e16af 100755
--- a/tools/run_tests/run_performance_tests.py
+++ b/tools/run_tests/run_performance_tests.py
@@ -33,11 +33,13 @@
 from __future__ import print_function
 
 import argparse
+import collections
 import itertools
 import jobset
 import json
 import multiprocessing
 import os
+import performance.scenario_config as scenario_config
 import pipes
 import re
 import subprocess
@@ -46,7 +48,6 @@
 import time
 import traceback
 import uuid
-import performance.scenario_config as scenario_config
 
 
 _ROOT = os.path.abspath(os.path.join(os.path.dirname(sys.argv[0]), '../..'))
@@ -63,14 +64,19 @@
     self._spec = spec
     self.language = language
     self.host_and_port = host_and_port
-    self._job = jobset.Job(spec, newline_on_success=True, travis=True, add_env={})
+    self._job = None
+
+  def start(self):
+    self._job = jobset.Job(self._spec, newline_on_success=True, travis=True, add_env={})
 
   def is_running(self):
     """Polls a job and returns True if given job is still running."""
-    return self._job.state() == jobset._RUNNING
+    return self._job and self._job.state() == jobset._RUNNING
 
   def kill(self):
-    return self._job.kill()
+    if self._job:
+      self._job.kill()
+      self._job = None
 
 
 def create_qpsworker_job(language, shortname=None,
@@ -119,7 +125,7 @@
 def create_quit_jobspec(workers, remote_host=None):
   """Runs quit using QPS driver."""
   # setting QPS_WORKERS env variable here makes sure it works with SSH too.
-  cmd = 'QPS_WORKERS="%s" bins/opt/qps_json_driver --quit' % ','.join(workers)
+  cmd = 'QPS_WORKERS="%s" bins/opt/qps_json_driver --quit' % ','.join(w.host_and_port for w in workers)
   if remote_host:
     user_at_host = '%s@%s' % (_REMOTE_HOST_USERNAME, remote_host)
     cmd = 'ssh %s "cd ~/performance_workspace/grpc/ && "%s' % (user_at_host, pipes.quote(cmd))
@@ -253,8 +259,8 @@
     sys.exit(1)
 
 
-def start_qpsworkers(languages, worker_hosts):
-  """Starts QPS workers as background jobs."""
+def create_qpsworkers(languages, worker_hosts):
+  """Creates QPS workers (but does not start them)."""
   if not worker_hosts:
     # run two workers locally (for each language)
     workers=[(None, 10000), (None, 10010)]
@@ -274,6 +280,9 @@
           for worker_idx, worker in enumerate(workers)]
 
 
+Scenario = collections.namedtuple('Scenario', 'jobspec workers')
+
+
 def create_scenarios(languages, workers_by_lang, remote_host=None, regex='.*',
                      category='all', bq_result_table=None,
                      netperf=False, netperf_hosts=[]):
@@ -282,6 +291,7 @@
                  for workers in workers_by_lang.values()
                  for worker in workers]
   scenarios = []
+  _NO_WORKERS = []
 
   if netperf:
     if not netperf_hosts:
@@ -293,15 +303,18 @@
     else:
       netperf_server=netperf_hosts[0]
       netperf_client=netperf_hosts[1]
-    scenarios.append(create_netperf_jobspec(server_host=netperf_server,
-                                            client_host=netperf_client,
-                                            bq_result_table=bq_result_table))
+    scenarios.append(Scenario(
+        create_netperf_jobspec(server_host=netperf_server,
+                               client_host=netperf_client,
+                               bq_result_table=bq_result_table),
+        _NO_WORKERS))
 
   for language in languages:
     for scenario_json in language.scenarios():
       if re.search(args.regex, scenario_json['name']):
-        if category in scenario_json.get('CATEGORIES', []) or category == 'all':
-          workers = workers_by_lang[str(language)]
+        categories = scenario_json.get('CATEGORIES', [])
+        if category in categories or (category == 'all' and categories != ['sweep']):
+          workers = workers_by_lang[str(language)][:]
           # 'SERVER_LANGUAGE' is an indicator for this script to pick
           # a server in different language.
           custom_server_lang = scenario_json.get('SERVER_LANGUAGE', None)
@@ -329,14 +342,14 @@
               # replace all client workers by workers of a different language,
               # leave num_server workers as they are server workers.
               workers[idx] = workers_by_lang[custom_client_lang][idx]
-          scenario = create_scenario_jobspec(scenario_json,
-                                             workers,
-                                             remote_host=remote_host,
-                                             bq_result_table=bq_result_table)
+          scenario = Scenario(
+              create_scenario_jobspec(scenario_json,
+                                      [w.host_and_port for w in workers],
+                                      remote_host=remote_host,
+                                      bq_result_table=bq_result_table),
+              workers)
           scenarios.append(scenario)
 
-  # the very last scenario requests shutting down the workers.
-  scenarios.append(create_quit_jobspec(all_workers, remote_host=remote_host))
   return scenarios
 
 
@@ -374,7 +387,7 @@
 argp.add_argument('--bq_result_table', default=None, type=str,
                   help='Bigquery "dataset.table" to upload results to.')
 argp.add_argument('--category',
-                  choices=['smoketest','all','scalable'],
+                  choices=['smoketest','all','scalable','sweep'],
                   default='all',
                   help='Select a category of tests to run.')
 argp.add_argument('--netperf',
@@ -410,42 +423,31 @@
   build_local = True
 build_on_remote_hosts(remote_hosts, languages=[str(l) for l in languages], build_local=build_local)
 
-qpsworker_jobs = start_qpsworkers(languages, args.remote_worker_host)
-
-# TODO(jtattermusch): see https://github.com/grpc/grpc/issues/6174
-time.sleep(5)
+qpsworker_jobs = create_qpsworkers(languages, args.remote_worker_host)
 
 # get list of worker addresses for each language.
-worker_addresses = dict([(str(language), []) for language in languages])
+workers_by_lang = dict([(str(language), []) for language in languages])
 for job in qpsworker_jobs:
-  worker_addresses[str(job.language)].append(job.host_and_port)
+  workers_by_lang[str(job.language)].append(job)
 
-try:
-  scenarios = create_scenarios(languages,
-                               workers_by_lang=worker_addresses,
-                               remote_host=args.remote_driver_host,
-                               regex=args.regex,
-                               category=args.category,
-                               bq_result_table=args.bq_result_table,
-                               netperf=args.netperf,
-                               netperf_hosts=args.remote_worker_host)
+scenarios = create_scenarios(languages,
+                           workers_by_lang=workers_by_lang,
+                           remote_host=args.remote_driver_host,
+                           regex=args.regex,
+                           category=args.category,
+                           bq_result_table=args.bq_result_table,
+                           netperf=args.netperf,
+                           netperf_hosts=args.remote_worker_host)
 
-  if not scenarios:
-    raise Exception('No scenarios to run')
+if not scenarios:
+  raise Exception('No scenarios to run')
 
-  jobset.message('START', 'Running scenarios.', do_newline=True)
-  num_failures, _ = jobset.run(
-      scenarios, newline_on_success=True, maxjobs=1)
-  if num_failures == 0:
-    jobset.message('SUCCESS',
-                   'All scenarios finished successfully.',
-                   do_newline=True)
-  else:
-    jobset.message('FAILED', 'Some of the scenarios failed.',
-                   do_newline=True)
-    sys.exit(1)
-except:
-  traceback.print_exc()
-  raise
-finally:
-  finish_qps_workers(qpsworker_jobs)
+for scenario in scenarios:
+  try:
+    for worker in scenario.workers:
+      worker.start()
+    jobset.run([scenario.jobspec,
+                create_quit_jobspec(scenario.workers, remote_host=args.remote_driver_host)],
+               newline_on_success=True, maxjobs=1)
+  finally:
+    finish_qps_workers(scenario.workers)
diff --git a/tools/run_tests/run_tests.py b/tools/run_tests/run_tests.py
index 78ef05b..c579f14 100755
--- a/tools/run_tests/run_tests.py
+++ b/tools/run_tests/run_tests.py
@@ -346,7 +346,7 @@
     self.config = config
     self.args = args
     _check_compiler(self.args.compiler, ['default', 'node0.12',
-                                         'node4', 'node5'])
+                                         'node4', 'node5', 'node6'])
     if self.args.compiler == 'default':
       self.node_version = '4'
     else:
@@ -654,15 +654,9 @@
     assembly_extension = '.exe'
 
     if self.args.compiler == 'coreclr':
-      if self.platform == 'linux':
-        assembly_subdir += '/netstandard1.5/debian.8-x64'
-        assembly_extension = ''
-      elif self.platform == 'mac':
-        assembly_subdir += '/netstandard1.5/osx.10.11-x64'
-        assembly_extension = ''
-      else:
-        assembly_subdir += '/netstandard1.5/win7-x64'
-      runtime_cmd = []
+      assembly_subdir += '/netcoreapp1.0'
+      runtime_cmd = ['dotnet', 'exec']
+      assembly_extension = '.dll'
     else:
       nunit_args += ['--noresult', '--workers=1']
       if self.platform == 'windows':
diff --git a/tools/run_tests/sanity/check_sources_and_headers.py b/tools/run_tests/sanity/check_sources_and_headers.py
index 28c1dc4..ec0876e 100755
--- a/tools/run_tests/sanity/check_sources_and_headers.py
+++ b/tools/run_tests/sanity/check_sources_and_headers.py
@@ -63,7 +63,8 @@
 def produces_object(name):
   return os.path.splitext(name)[1] in ['.c', '.cc']
 
-obj_producer_to_source = {'c': {}, 'c++': {}, 'csharp': {}}
+c_ish = {}
+obj_producer_to_source = {'c': c_ish, 'c++': c_ish, 'csharp': {}}
 
 errors = 0
 for target in js:
@@ -86,7 +87,7 @@
               'target %s (%s) does not name header %s as a dependency' % (
                 target['name'], fn, m.group(1)))
             errors += 1
-  if target['type'] == 'lib':
+  if target['type'] in ['lib', 'filegroup']:
     for fn in target['src']:
       language = target['language']
       if produces_object(fn):
diff --git a/tools/run_tests/sanity/check_submodules.sh b/tools/run_tests/sanity/check_submodules.sh
index 5562d33..f1d9d5a 100755
--- a/tools/run_tests/sanity/check_submodules.sh
+++ b/tools/run_tests/sanity/check_submodules.sh
@@ -44,7 +44,7 @@
  c880e42ba1c8032d4cdde2aba0541d8a9d9fa2e9 third_party/boringssl (version_for_cocoapods_2.0-100-gc880e42)
  05b155ff59114735ec8cd089f669c4c3d8f59029 third_party/gflags (v2.1.0-45-g05b155f)
  c99458533a9b4c743ed51537e25989ea55944908 third_party/googletest (release-1.7.0)
- f8ac463766281625ad710900479130c7fcb4d63b third_party/nanopb (nanopb-0.3.4-29-gf8ac463)
+ 68a86e96481e6bea987df8de47027847b30c325b third_party/nanopb (nanopb-0.3.6-6-g68a86e9)
  bba446bbf2ac7b0b9923d4eb07d5acd0665a8cf0 third_party/protobuf (v3.0.0-beta-4-160-gbba446b)
  50893291621658f355bc5b4d450a8d06a563053d third_party/zlib (v1.2.8)
  bcad91771b7f0bff28a1cac1981d7ef2b9bcef3c third_party/thrift
diff --git a/tools/run_tests/sources_and_headers.json b/tools/run_tests/sources_and_headers.json
index f0f440d..3df07dc 100644
--- a/tools/run_tests/sources_and_headers.json
+++ b/tools/run_tests/sources_and_headers.json
@@ -486,6 +486,17 @@
     "type": "target"
   }, 
   {
+    "deps": [], 
+    "headers": [], 
+    "language": "c", 
+    "name": "gen_percent_encoding_tables", 
+    "src": [
+      "tools/codegen/core/gen_percent_encoding_tables.c"
+    ], 
+    "third_party": false, 
+    "type": "target"
+  }, 
+  {
     "deps": [
       "gpr", 
       "gpr_test_util", 
@@ -620,6 +631,20 @@
     ], 
     "headers": [], 
     "language": "c", 
+    "name": "gpr_percent_encoding_test", 
+    "src": [
+      "test/core/support/percent_encoding_test.c"
+    ], 
+    "third_party": false, 
+    "type": "target"
+  }, 
+  {
+    "deps": [
+      "gpr", 
+      "gpr_test_util"
+    ], 
+    "headers": [], 
+    "language": "c", 
     "name": "gpr_slice_buffer_test", 
     "src": [
       "test/core/support/slice_buffer_test.c"
@@ -1458,6 +1483,38 @@
     ], 
     "headers": [], 
     "language": "c", 
+    "name": "percent_decode_fuzzer", 
+    "src": [
+      "test/core/support/percent_decode_fuzzer.c"
+    ], 
+    "third_party": false, 
+    "type": "target"
+  }, 
+  {
+    "deps": [
+      "gpr", 
+      "gpr_test_util", 
+      "grpc", 
+      "grpc_test_util"
+    ], 
+    "headers": [], 
+    "language": "c", 
+    "name": "percent_encode_fuzzer", 
+    "src": [
+      "test/core/support/percent_encode_fuzzer.c"
+    ], 
+    "third_party": false, 
+    "type": "target"
+  }, 
+  {
+    "deps": [
+      "gpr", 
+      "gpr_test_util", 
+      "grpc", 
+      "grpc_test_util"
+    ], 
+    "headers": [], 
+    "language": "c", 
     "name": "resolve_address_test", 
     "src": [
       "test/core/iomgr/resolve_address_test.c"
@@ -3507,23 +3564,6 @@
     ], 
     "headers": [], 
     "language": "c", 
-    "name": "bad_ssl_alpn_server", 
-    "src": [
-      "test/core/bad_ssl/servers/alpn.c"
-    ], 
-    "third_party": false, 
-    "type": "target"
-  }, 
-  {
-    "deps": [
-      "bad_ssl_test_server", 
-      "gpr", 
-      "gpr_test_util", 
-      "grpc", 
-      "grpc_test_util"
-    ], 
-    "headers": [], 
-    "language": "c", 
     "name": "bad_ssl_cert_server", 
     "src": [
       "test/core/bad_ssl/servers/cert.c"
@@ -3540,22 +3580,6 @@
     ], 
     "headers": [], 
     "language": "c", 
-    "name": "bad_ssl_alpn_test", 
-    "src": [
-      "test/core/bad_ssl/bad_ssl_test.c"
-    ], 
-    "third_party": false, 
-    "type": "target"
-  }, 
-  {
-    "deps": [
-      "gpr", 
-      "gpr_test_util", 
-      "grpc", 
-      "grpc_test_util"
-    ], 
-    "headers": [], 
-    "language": "c", 
     "name": "bad_ssl_cert_test", 
     "src": [
       "test/core/bad_ssl/bad_ssl_test.c"
@@ -4201,6 +4225,40 @@
     ], 
     "headers": [], 
     "language": "c", 
+    "name": "percent_decode_fuzzer_one_entry", 
+    "src": [
+      "test/core/support/percent_decode_fuzzer.c", 
+      "test/core/util/one_corpus_entry_fuzzer.c"
+    ], 
+    "third_party": false, 
+    "type": "target"
+  }, 
+  {
+    "deps": [
+      "gpr", 
+      "gpr_test_util", 
+      "grpc", 
+      "grpc_test_util"
+    ], 
+    "headers": [], 
+    "language": "c", 
+    "name": "percent_encode_fuzzer_one_entry", 
+    "src": [
+      "test/core/support/percent_encode_fuzzer.c", 
+      "test/core/util/one_corpus_entry_fuzzer.c"
+    ], 
+    "third_party": false, 
+    "type": "target"
+  }, 
+  {
+    "deps": [
+      "gpr", 
+      "gpr_test_util", 
+      "grpc", 
+      "grpc_test_util"
+    ], 
+    "headers": [], 
+    "language": "c", 
     "name": "server_fuzzer_one_entry", 
     "src": [
       "test/core/end2end/fuzzers/server_fuzzer.c", 
@@ -4429,6 +4487,7 @@
     "name": "grpc++", 
     "src": [
       "include/grpc++/impl/codegen/core_codegen.h", 
+      "src/cpp/client/insecure_credentials.cc", 
       "src/cpp/client/secure_credentials.cc", 
       "src/cpp/client/secure_credentials.h", 
       "src/cpp/common/auth_property_iterator.cc", 
@@ -4436,6 +4495,7 @@
       "src/cpp/common/secure_auth_context.h", 
       "src/cpp/common/secure_channel_arguments.cc", 
       "src/cpp/common/secure_create_auth_context.cc", 
+      "src/cpp/server/insecure_server_credentials.cc", 
       "src/cpp/server/secure_server_credentials.cc", 
       "src/cpp/server/secure_server_credentials.h"
     ], 
@@ -4482,8 +4542,8 @@
     "language": "c++", 
     "name": "grpc++_test_config", 
     "src": [
-      "test/cpp/util/test_config.cc", 
-      "test/cpp/util/test_config.h"
+      "test/cpp/util/test_config.h", 
+      "test/cpp/util/test_config_cc.cc"
     ], 
     "third_party": false, 
     "type": "lib"
@@ -4543,7 +4603,9 @@
     "language": "c++", 
     "name": "grpc++_unsecure", 
     "src": [
-      "src/cpp/common/insecure_create_auth_context.cc"
+      "src/cpp/client/insecure_credentials.cc", 
+      "src/cpp/common/insecure_create_auth_context.cc", 
+      "src/cpp/server/insecure_server_credentials.cc"
     ], 
     "third_party": false, 
     "type": "lib"
@@ -5512,6 +5574,7 @@
       "test/core/end2end/tests/server_finishes_request.c", 
       "test/core/end2end/tests/shutdown_finishes_calls.c", 
       "test/core/end2end/tests/shutdown_finishes_tags.c", 
+      "test/core/end2end/tests/simple_cacheable_request.c", 
       "test/core/end2end/tests/simple_delayed_request.c", 
       "test/core/end2end/tests/simple_metadata.c", 
       "test/core/end2end/tests/simple_request.c", 
@@ -5575,6 +5638,7 @@
       "test/core/end2end/tests/server_finishes_request.c", 
       "test/core/end2end/tests/shutdown_finishes_calls.c", 
       "test/core/end2end/tests/shutdown_finishes_tags.c", 
+      "test/core/end2end/tests/simple_cacheable_request.c", 
       "test/core/end2end/tests/simple_delayed_request.c", 
       "test/core/end2end/tests/simple_metadata.c", 
       "test/core/end2end/tests/simple_request.c", 
@@ -5672,6 +5736,7 @@
       "src/core/lib/support/block_annotate.h", 
       "src/core/lib/support/env.h", 
       "src/core/lib/support/murmur_hash.h", 
+      "src/core/lib/support/percent_encoding.h", 
       "src/core/lib/support/stack_lockfree.h", 
       "src/core/lib/support/string.h", 
       "src/core/lib/support/string_windows.h", 
@@ -5736,6 +5801,8 @@
       "src/core/lib/support/log_windows.c", 
       "src/core/lib/support/murmur_hash.c", 
       "src/core/lib/support/murmur_hash.h", 
+      "src/core/lib/support/percent_encoding.c", 
+      "src/core/lib/support/percent_encoding.h", 
       "src/core/lib/support/slice.c", 
       "src/core/lib/support/slice_buffer.c", 
       "src/core/lib/support/stack_lockfree.c", 
@@ -5773,38 +5840,32 @@
   {
     "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_windows.h", 
-      "include/grpc/impl/codegen/log.h", 
+      "include/grpc/impl/codegen/gpr_types.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_windows.h", 
-      "include/grpc/impl/codegen/time.h"
+      "include/grpc/impl/codegen/sync_windows.h"
     ], 
     "language": "c", 
     "name": "gpr_codegen", 
     "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_windows.h", 
-      "include/grpc/impl/codegen/log.h", 
+      "include/grpc/impl/codegen/gpr_types.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_windows.h", 
-      "include/grpc/impl/codegen/time.h"
+      "include/grpc/impl/codegen/sync_windows.h"
     ], 
     "third_party": false, 
     "type": "filegroup"
@@ -6153,7 +6214,6 @@
       "gpr_codegen"
     ], 
     "headers": [
-      "include/grpc/impl/codegen/byte_buffer.h", 
       "include/grpc/impl/codegen/byte_buffer_reader.h", 
       "include/grpc/impl/codegen/compression_types.h", 
       "include/grpc/impl/codegen/connectivity_state.h", 
@@ -6164,7 +6224,6 @@
     "language": "c", 
     "name": "grpc_codegen", 
     "src": [
-      "include/grpc/impl/codegen/byte_buffer.h", 
       "include/grpc/impl/codegen/byte_buffer_reader.h", 
       "include/grpc/impl/codegen/compression_types.h", 
       "include/grpc/impl/codegen/connectivity_state.h", 
@@ -6740,37 +6799,35 @@
       "include/grpc++/support/stub_options.h", 
       "include/grpc++/support/sync_stream.h", 
       "include/grpc++/support/time.h", 
-      "src/cpp/client/channel.cc", 
+      "src/cpp/client/channel_cc.cc", 
       "src/cpp/client/client_context.cc", 
       "src/cpp/client/create_channel.cc", 
       "src/cpp/client/create_channel_internal.cc", 
       "src/cpp/client/create_channel_internal.h", 
       "src/cpp/client/create_channel_posix.cc", 
-      "src/cpp/client/credentials.cc", 
+      "src/cpp/client/credentials_cc.cc", 
       "src/cpp/client/generic_stub.cc", 
-      "src/cpp/client/insecure_credentials.cc", 
       "src/cpp/common/channel_arguments.cc", 
       "src/cpp/common/channel_filter.cc", 
       "src/cpp/common/channel_filter.h", 
-      "src/cpp/common/completion_queue.cc", 
+      "src/cpp/common/completion_queue_cc.cc", 
       "src/cpp/common/core_codegen.cc", 
       "src/cpp/common/rpc_method.cc", 
       "src/cpp/server/async_generic_service.cc", 
       "src/cpp/server/create_default_thread_pool.cc", 
       "src/cpp/server/dynamic_thread_pool.cc", 
       "src/cpp/server/dynamic_thread_pool.h", 
-      "src/cpp/server/insecure_server_credentials.cc", 
-      "src/cpp/server/server.cc", 
       "src/cpp/server/server_builder.cc", 
+      "src/cpp/server/server_cc.cc", 
       "src/cpp/server/server_context.cc", 
       "src/cpp/server/server_credentials.cc", 
       "src/cpp/server/server_posix.cc", 
       "src/cpp/server/thread_pool_interface.h", 
-      "src/cpp/util/byte_buffer.cc", 
-      "src/cpp/util/slice.cc", 
+      "src/cpp/util/byte_buffer_cc.cc", 
+      "src/cpp/util/slice_cc.cc", 
       "src/cpp/util/status.cc", 
       "src/cpp/util/string_ref.cc", 
-      "src/cpp/util/time.cc"
+      "src/cpp/util/time_cc.cc"
     ], 
     "third_party": false, 
     "type": "filegroup"
diff --git a/tools/run_tests/tests.json b/tools/run_tests/tests.json
index a59abba..cbc8f58 100644
--- a/tools/run_tests/tests.json
+++ b/tools/run_tests/tests.json
@@ -710,6 +710,27 @@
     "flaky": false, 
     "gtest": false, 
     "language": "c", 
+    "name": "gpr_percent_encoding_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_slice_buffer_test", 
     "platforms": [
       "linux", 
@@ -2880,25 +2901,6 @@
     "flaky": false, 
     "gtest": false, 
     "language": "c", 
-    "name": "bad_ssl_alpn_test", 
-    "platforms": [
-      "linux", 
-      "mac", 
-      "posix"
-    ]
-  }, 
-  {
-    "args": [], 
-    "ci_platforms": [
-      "linux", 
-      "mac", 
-      "posix"
-    ], 
-    "cpu_cost": 0.1, 
-    "exclude_configs": [], 
-    "flaky": false, 
-    "gtest": false, 
-    "language": "c", 
     "name": "bad_ssl_cert_test", 
     "platforms": [
       "linux", 
@@ -5290,6 +5292,28 @@
   }, 
   {
     "args": [
+      "simple_cacheable_request"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_census_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "simple_delayed_request"
     ], 
     "ci_platforms": [
@@ -6236,6 +6260,28 @@
   }, 
   {
     "args": [
+      "simple_cacheable_request"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_compress_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "simple_delayed_request"
     ], 
     "ci_platforms": [
@@ -7144,6 +7190,27 @@
   }, 
   {
     "args": [
+      "simple_cacheable_request"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_fakesec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "simple_delayed_request"
     ], 
     "ci_platforms": [
@@ -7929,6 +7996,26 @@
   }, 
   {
     "args": [
+      "simple_cacheable_request"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_fd_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "simple_metadata"
     ], 
     "ci_platforms": [
@@ -8845,6 +8932,28 @@
   }, 
   {
     "args": [
+      "simple_cacheable_request"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "simple_delayed_request"
     ], 
     "ci_platforms": [
@@ -9563,6 +9672,22 @@
   }, 
   {
     "args": [
+      "simple_cacheable_request"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+pipe_test", 
+    "platforms": [
+      "linux"
+    ]
+  }, 
+  {
+    "args": [
       "simple_delayed_request"
     ], 
     "ci_platforms": [
@@ -10435,6 +10560,28 @@
   }, 
   {
     "args": [
+      "simple_cacheable_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": [
       "simple_delayed_request"
     ], 
     "ci_platforms": [
@@ -11381,6 +11528,28 @@
   }, 
   {
     "args": [
+      "simple_cacheable_request"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_load_reporting_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "simple_delayed_request"
     ], 
     "ci_platforms": [
@@ -12289,6 +12458,27 @@
   }, 
   {
     "args": [
+      "simple_cacheable_request"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_oauth2_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "simple_delayed_request"
     ], 
     "ci_platforms": [
@@ -13066,6 +13256,27 @@
   }, 
   {
     "args": [
+      "simple_cacheable_request"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_proxy_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "simple_delayed_request"
     ], 
     "ci_platforms": [
@@ -13885,6 +14096,27 @@
   }, 
   {
     "args": [
+      "simple_cacheable_request"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_sockpair_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "simple_metadata"
     ], 
     "ci_platforms": [
@@ -14641,6 +14873,27 @@
   }, 
   {
     "args": [
+      "simple_cacheable_request"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_sockpair+trace_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "simple_metadata"
     ], 
     "ci_platforms": [
@@ -15439,6 +15692,27 @@
   }, 
   {
     "args": [
+      "simple_cacheable_request"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_sockpair_1byte_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "simple_metadata"
     ], 
     "ci_platforms": [
@@ -16359,6 +16633,28 @@
   }, 
   {
     "args": [
+      "simple_cacheable_request"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_ssl_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "simple_delayed_request"
     ], 
     "ci_platforms": [
@@ -17305,6 +17601,28 @@
   }, 
   {
     "args": [
+      "simple_cacheable_request"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_ssl_cert_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "simple_delayed_request"
     ], 
     "ci_platforms": [
@@ -18087,6 +18405,27 @@
   }, 
   {
     "args": [
+      "simple_cacheable_request"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_ssl_proxy_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "simple_delayed_request"
     ], 
     "ci_platforms": [
@@ -18932,6 +19271,26 @@
   }, 
   {
     "args": [
+      "simple_cacheable_request"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_uds_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "simple_delayed_request"
     ], 
     "ci_platforms": [
@@ -19846,6 +20205,28 @@
   }, 
   {
     "args": [
+      "simple_cacheable_request"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_census_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "simple_delayed_request"
     ], 
     "ci_platforms": [
@@ -20770,6 +21151,28 @@
   }, 
   {
     "args": [
+      "simple_cacheable_request"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_compress_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "simple_delayed_request"
     ], 
     "ci_platforms": [
@@ -21540,6 +21943,26 @@
   }, 
   {
     "args": [
+      "simple_cacheable_request"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_fd_nosec_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "simple_metadata"
     ], 
     "ci_platforms": [
@@ -22434,6 +22857,28 @@
   }, 
   {
     "args": [
+      "simple_cacheable_request"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "simple_delayed_request"
     ], 
     "ci_platforms": [
@@ -23136,6 +23581,22 @@
   }, 
   {
     "args": [
+      "simple_cacheable_request"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_full+pipe_nosec_test", 
+    "platforms": [
+      "linux"
+    ]
+  }, 
+  {
+    "args": [
       "simple_delayed_request"
     ], 
     "ci_platforms": [
@@ -23986,6 +24447,28 @@
   }, 
   {
     "args": [
+      "simple_cacheable_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": [
       "simple_delayed_request"
     ], 
     "ci_platforms": [
@@ -24910,6 +25393,28 @@
   }, 
   {
     "args": [
+      "simple_cacheable_request"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_load_reporting_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "simple_delayed_request"
     ], 
     "ci_platforms": [
@@ -25671,6 +26176,27 @@
   }, 
   {
     "args": [
+      "simple_cacheable_request"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_proxy_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "simple_delayed_request"
     ], 
     "ci_platforms": [
@@ -26469,6 +26995,27 @@
   }, 
   {
     "args": [
+      "simple_cacheable_request"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_sockpair_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "simple_metadata"
     ], 
     "ci_platforms": [
@@ -27204,6 +27751,27 @@
   }, 
   {
     "args": [
+      "simple_cacheable_request"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_sockpair+trace_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "simple_metadata"
     ], 
     "ci_platforms": [
@@ -28047,6 +28615,29 @@
   }, 
   {
     "args": [
+      "simple_cacheable_request"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [
+      "msan"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_sockpair_1byte_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "simple_metadata"
     ], 
     "ci_platforms": [
@@ -28859,6 +29450,26 @@
   }, 
   {
     "args": [
+      "simple_cacheable_request"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_uds_nosec_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
       "simple_delayed_request"
     ], 
     "ci_platforms": [
@@ -28987,6 +29598,357 @@
   {
     "args": [
       "--scenarios_json", 
+      "{\"scenarios\": [{\"name\": \"cpp_generic_async_streaming_qps_unconstrained_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"core_limit\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"ASYNC_GENERIC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 0}]}"
+    ], 
+    "boringssl": true, 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "cpu_cost": 8, 
+    "defaults": "boringssl", 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c++", 
+    "name": "json_run_localhost", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "shortname": "json_run_localhost:cpp_generic_async_streaming_qps_unconstrained_secure", 
+    "timeout_seconds": 180
+  }, 
+  {
+    "args": [
+      "--scenarios_json", 
+      "{\"scenarios\": [{\"name\": \"cpp_generic_async_streaming_qps_one_server_core_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"core_limit\": 1, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"ASYNC_GENERIC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 0}]}"
+    ], 
+    "boringssl": true, 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "cpu_cost": 1, 
+    "defaults": "boringssl", 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c++", 
+    "name": "json_run_localhost", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "shortname": "json_run_localhost:cpp_generic_async_streaming_qps_one_server_core_secure", 
+    "timeout_seconds": 180
+  }, 
+  {
+    "args": [
+      "--scenarios_json", 
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_streaming_ping_pong_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"core_limit\": 1, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"SYNC_SERVER\"}, \"client_config\": {\"client_type\": \"SYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 1}]}"
+    ], 
+    "boringssl": true, 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "cpu_cost": 2, 
+    "defaults": "boringssl", 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c++", 
+    "name": "json_run_localhost", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "shortname": "json_run_localhost:cpp_protobuf_sync_streaming_ping_pong_secure", 
+    "timeout_seconds": 180
+  }, 
+  {
+    "args": [
+      "--scenarios_json", 
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_unary_ping_pong_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"core_limit\": 1, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"SYNC_SERVER\"}, \"client_config\": {\"client_type\": \"SYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 1}]}"
+    ], 
+    "boringssl": true, 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "cpu_cost": 2, 
+    "defaults": "boringssl", 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c++", 
+    "name": "json_run_localhost", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "shortname": "json_run_localhost:cpp_protobuf_sync_unary_ping_pong_secure", 
+    "timeout_seconds": 180
+  }, 
+  {
+    "args": [
+      "--scenarios_json", 
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_unary_qps_unconstrained_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"core_limit\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"SYNC_SERVER\"}, \"client_config\": {\"client_type\": \"SYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 16, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 0}]}"
+    ], 
+    "boringssl": true, 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "cpu_cost": 8, 
+    "defaults": "boringssl", 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c++", 
+    "name": "json_run_localhost", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "shortname": "json_run_localhost:cpp_protobuf_sync_unary_qps_unconstrained_secure", 
+    "timeout_seconds": 180
+  }, 
+  {
+    "args": [
+      "--scenarios_json", 
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_streaming_qps_unconstrained_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"core_limit\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"SYNC_SERVER\"}, \"client_config\": {\"client_type\": \"SYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 16, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 0}]}"
+    ], 
+    "boringssl": true, 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "cpu_cost": 8, 
+    "defaults": "boringssl", 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c++", 
+    "name": "json_run_localhost", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "shortname": "json_run_localhost:cpp_protobuf_sync_streaming_qps_unconstrained_secure", 
+    "timeout_seconds": 180
+  }, 
+  {
+    "args": [
+      "--scenarios_json", 
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_unary_qps_unconstrained_secure_1_channels\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"core_limit\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"ASYNC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 1, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 1000, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 0}]}"
+    ], 
+    "boringssl": true, 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "cpu_cost": 8, 
+    "defaults": "boringssl", 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c++", 
+    "name": "json_run_localhost", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "shortname": "json_run_localhost:cpp_protobuf_sync_unary_qps_unconstrained_secure_1_channels", 
+    "timeout_seconds": 180
+  }, 
+  {
+    "args": [
+      "--scenarios_json", 
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_unary_qps_unconstrained_secure_3_channels\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"core_limit\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"ASYNC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 3, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 334, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 0}]}"
+    ], 
+    "boringssl": true, 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "cpu_cost": 8, 
+    "defaults": "boringssl", 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c++", 
+    "name": "json_run_localhost", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "shortname": "json_run_localhost:cpp_protobuf_sync_unary_qps_unconstrained_secure_3_channels", 
+    "timeout_seconds": 180
+  }, 
+  {
+    "args": [
+      "--scenarios_json", 
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_unary_qps_unconstrained_secure_10_channels\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"core_limit\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"ASYNC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 10, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 0}]}"
+    ], 
+    "boringssl": true, 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "cpu_cost": 8, 
+    "defaults": "boringssl", 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c++", 
+    "name": "json_run_localhost", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "shortname": "json_run_localhost:cpp_protobuf_sync_unary_qps_unconstrained_secure_10_channels", 
+    "timeout_seconds": 180
+  }, 
+  {
+    "args": [
+      "--scenarios_json", 
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_unary_qps_unconstrained_secure_31_channels\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"core_limit\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"ASYNC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 31, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 33, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 0}]}"
+    ], 
+    "boringssl": true, 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "cpu_cost": 8, 
+    "defaults": "boringssl", 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c++", 
+    "name": "json_run_localhost", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "shortname": "json_run_localhost:cpp_protobuf_sync_unary_qps_unconstrained_secure_31_channels", 
+    "timeout_seconds": 180
+  }, 
+  {
+    "args": [
+      "--scenarios_json", 
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_unary_qps_unconstrained_secure_100_channels\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"core_limit\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"ASYNC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 100, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 10, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 0}]}"
+    ], 
+    "boringssl": true, 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "cpu_cost": 8, 
+    "defaults": "boringssl", 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c++", 
+    "name": "json_run_localhost", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "shortname": "json_run_localhost:cpp_protobuf_sync_unary_qps_unconstrained_secure_100_channels", 
+    "timeout_seconds": 180
+  }, 
+  {
+    "args": [
+      "--scenarios_json", 
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_unary_qps_unconstrained_secure_316_channels\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"core_limit\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"ASYNC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 316, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 4, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 0}]}"
+    ], 
+    "boringssl": true, 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "cpu_cost": 8, 
+    "defaults": "boringssl", 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c++", 
+    "name": "json_run_localhost", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "shortname": "json_run_localhost:cpp_protobuf_sync_unary_qps_unconstrained_secure_316_channels", 
+    "timeout_seconds": 180
+  }, 
+  {
+    "args": [
+      "--scenarios_json", 
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_unary_qps_unconstrained_secure_1000_channels\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"core_limit\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"ASYNC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 1000, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 0}]}"
+    ], 
+    "boringssl": true, 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "cpu_cost": 8, 
+    "defaults": "boringssl", 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c++", 
+    "name": "json_run_localhost", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "shortname": "json_run_localhost:cpp_protobuf_sync_unary_qps_unconstrained_secure_1000_channels", 
+    "timeout_seconds": 180
+  }, 
+  {
+    "args": [
+      "--scenarios_json", 
       "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_streaming_ping_pong_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"core_limit\": 1, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"ASYNC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 1}]}"
     ], 
     "boringssl": true, 
@@ -29041,33 +30003,6 @@
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_unary_ping_pong_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"core_limit\": 1, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"SYNC_SERVER\"}, \"client_config\": {\"client_type\": \"SYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 1}]}"
-    ], 
-    "boringssl": true, 
-    "ci_platforms": [
-      "linux", 
-      "mac", 
-      "posix", 
-      "windows"
-    ], 
-    "cpu_cost": 2, 
-    "defaults": "boringssl", 
-    "exclude_configs": [], 
-    "flaky": false, 
-    "language": "c++", 
-    "name": "json_run_localhost", 
-    "platforms": [
-      "linux", 
-      "mac", 
-      "posix", 
-      "windows"
-    ], 
-    "shortname": "json_run_localhost:cpp_protobuf_sync_unary_ping_pong_secure", 
-    "timeout_seconds": 180
-  }, 
-  {
-    "args": [
-      "--scenarios_json", 
       "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_unary_qps_unconstrained_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"core_limit\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"ASYNC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 0}]}"
     ], 
     "boringssl": true, 
@@ -29122,7 +30057,7 @@
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_generic_async_streaming_qps_unconstrained_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"core_limit\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"ASYNC_GENERIC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 0}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_unary_qps_unconstrained_secure_1_channels\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"core_limit\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"ASYNC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 1, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 6400, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 0}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
@@ -29143,13 +30078,13 @@
       "posix", 
       "windows"
     ], 
-    "shortname": "json_run_localhost:cpp_generic_async_streaming_qps_unconstrained_secure", 
+    "shortname": "json_run_localhost:cpp_protobuf_async_unary_qps_unconstrained_secure_1_channels", 
     "timeout_seconds": 180
   }, 
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_generic_async_streaming_qps_one_server_core_secure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"core_limit\": 1, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"ASYNC_GENERIC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 0}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_unary_qps_unconstrained_secure_3_channels\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"core_limit\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"ASYNC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 3, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 2134, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 0}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
@@ -29158,7 +30093,7 @@
       "posix", 
       "windows"
     ], 
-    "cpu_cost": 1, 
+    "cpu_cost": 8, 
     "defaults": "boringssl", 
     "exclude_configs": [], 
     "flaky": false, 
@@ -29170,7 +30105,142 @@
       "posix", 
       "windows"
     ], 
-    "shortname": "json_run_localhost:cpp_generic_async_streaming_qps_one_server_core_secure", 
+    "shortname": "json_run_localhost:cpp_protobuf_async_unary_qps_unconstrained_secure_3_channels", 
+    "timeout_seconds": 180
+  }, 
+  {
+    "args": [
+      "--scenarios_json", 
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_unary_qps_unconstrained_secure_10_channels\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"core_limit\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"ASYNC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 10, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 640, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 0}]}"
+    ], 
+    "boringssl": true, 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "cpu_cost": 8, 
+    "defaults": "boringssl", 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c++", 
+    "name": "json_run_localhost", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "shortname": "json_run_localhost:cpp_protobuf_async_unary_qps_unconstrained_secure_10_channels", 
+    "timeout_seconds": 180
+  }, 
+  {
+    "args": [
+      "--scenarios_json", 
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_unary_qps_unconstrained_secure_31_channels\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"core_limit\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"ASYNC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 31, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 207, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 0}]}"
+    ], 
+    "boringssl": true, 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "cpu_cost": 8, 
+    "defaults": "boringssl", 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c++", 
+    "name": "json_run_localhost", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "shortname": "json_run_localhost:cpp_protobuf_async_unary_qps_unconstrained_secure_31_channels", 
+    "timeout_seconds": 180
+  }, 
+  {
+    "args": [
+      "--scenarios_json", 
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_unary_qps_unconstrained_secure_100_channels\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"core_limit\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"ASYNC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 100, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 64, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 0}]}"
+    ], 
+    "boringssl": true, 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "cpu_cost": 8, 
+    "defaults": "boringssl", 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c++", 
+    "name": "json_run_localhost", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "shortname": "json_run_localhost:cpp_protobuf_async_unary_qps_unconstrained_secure_100_channels", 
+    "timeout_seconds": 180
+  }, 
+  {
+    "args": [
+      "--scenarios_json", 
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_unary_qps_unconstrained_secure_316_channels\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"core_limit\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"ASYNC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 316, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 21, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 0}]}"
+    ], 
+    "boringssl": true, 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "cpu_cost": 8, 
+    "defaults": "boringssl", 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c++", 
+    "name": "json_run_localhost", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "shortname": "json_run_localhost:cpp_protobuf_async_unary_qps_unconstrained_secure_316_channels", 
+    "timeout_seconds": 180
+  }, 
+  {
+    "args": [
+      "--scenarios_json", 
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_unary_qps_unconstrained_secure_1000_channels\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"core_limit\": 0, \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"server_type\": \"ASYNC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": {\"use_test_ca\": true, \"server_host_override\": \"foo.test.google.fr\"}, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 1000, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 7, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 0}]}"
+    ], 
+    "boringssl": true, 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "cpu_cost": 8, 
+    "defaults": "boringssl", 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c++", 
+    "name": "json_run_localhost", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "shortname": "json_run_localhost:cpp_protobuf_async_unary_qps_unconstrained_secure_1000_channels", 
     "timeout_seconds": 180
   }, 
   {
@@ -29203,6 +30273,357 @@
   {
     "args": [
       "--scenarios_json", 
+      "{\"scenarios\": [{\"name\": \"cpp_generic_async_streaming_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"core_limit\": 0, \"security_params\": null, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"ASYNC_GENERIC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 0}]}"
+    ], 
+    "boringssl": true, 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "cpu_cost": 8, 
+    "defaults": "boringssl", 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c++", 
+    "name": "json_run_localhost", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "shortname": "json_run_localhost:cpp_generic_async_streaming_qps_unconstrained_insecure", 
+    "timeout_seconds": 180
+  }, 
+  {
+    "args": [
+      "--scenarios_json", 
+      "{\"scenarios\": [{\"name\": \"cpp_generic_async_streaming_qps_one_server_core_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"core_limit\": 1, \"security_params\": null, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"ASYNC_GENERIC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 0}]}"
+    ], 
+    "boringssl": true, 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "cpu_cost": 1, 
+    "defaults": "boringssl", 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c++", 
+    "name": "json_run_localhost", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "shortname": "json_run_localhost:cpp_generic_async_streaming_qps_one_server_core_insecure", 
+    "timeout_seconds": 180
+  }, 
+  {
+    "args": [
+      "--scenarios_json", 
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_streaming_ping_pong_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"core_limit\": 1, \"security_params\": null, \"server_type\": \"SYNC_SERVER\"}, \"client_config\": {\"client_type\": \"SYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 1}]}"
+    ], 
+    "boringssl": true, 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "cpu_cost": 2, 
+    "defaults": "boringssl", 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c++", 
+    "name": "json_run_localhost", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "shortname": "json_run_localhost:cpp_protobuf_sync_streaming_ping_pong_insecure", 
+    "timeout_seconds": 180
+  }, 
+  {
+    "args": [
+      "--scenarios_json", 
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_unary_ping_pong_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"core_limit\": 1, \"security_params\": null, \"server_type\": \"SYNC_SERVER\"}, \"client_config\": {\"client_type\": \"SYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 1}]}"
+    ], 
+    "boringssl": true, 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "cpu_cost": 2, 
+    "defaults": "boringssl", 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c++", 
+    "name": "json_run_localhost", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "shortname": "json_run_localhost:cpp_protobuf_sync_unary_ping_pong_insecure", 
+    "timeout_seconds": 180
+  }, 
+  {
+    "args": [
+      "--scenarios_json", 
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_unary_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"core_limit\": 0, \"security_params\": null, \"server_type\": \"SYNC_SERVER\"}, \"client_config\": {\"client_type\": \"SYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 16, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 0}]}"
+    ], 
+    "boringssl": true, 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "cpu_cost": 8, 
+    "defaults": "boringssl", 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c++", 
+    "name": "json_run_localhost", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "shortname": "json_run_localhost:cpp_protobuf_sync_unary_qps_unconstrained_insecure", 
+    "timeout_seconds": 180
+  }, 
+  {
+    "args": [
+      "--scenarios_json", 
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_streaming_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"core_limit\": 0, \"security_params\": null, \"server_type\": \"SYNC_SERVER\"}, \"client_config\": {\"client_type\": \"SYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 16, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 0}]}"
+    ], 
+    "boringssl": true, 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "cpu_cost": 8, 
+    "defaults": "boringssl", 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c++", 
+    "name": "json_run_localhost", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "shortname": "json_run_localhost:cpp_protobuf_sync_streaming_qps_unconstrained_insecure", 
+    "timeout_seconds": 180
+  }, 
+  {
+    "args": [
+      "--scenarios_json", 
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_unary_qps_unconstrained_insecure_1_channels\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"core_limit\": 0, \"security_params\": null, \"server_type\": \"ASYNC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 1, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 1000, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 0}]}"
+    ], 
+    "boringssl": true, 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "cpu_cost": 8, 
+    "defaults": "boringssl", 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c++", 
+    "name": "json_run_localhost", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "shortname": "json_run_localhost:cpp_protobuf_sync_unary_qps_unconstrained_insecure_1_channels", 
+    "timeout_seconds": 180
+  }, 
+  {
+    "args": [
+      "--scenarios_json", 
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_unary_qps_unconstrained_insecure_3_channels\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"core_limit\": 0, \"security_params\": null, \"server_type\": \"ASYNC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 3, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 334, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 0}]}"
+    ], 
+    "boringssl": true, 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "cpu_cost": 8, 
+    "defaults": "boringssl", 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c++", 
+    "name": "json_run_localhost", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "shortname": "json_run_localhost:cpp_protobuf_sync_unary_qps_unconstrained_insecure_3_channels", 
+    "timeout_seconds": 180
+  }, 
+  {
+    "args": [
+      "--scenarios_json", 
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_unary_qps_unconstrained_insecure_10_channels\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"core_limit\": 0, \"security_params\": null, \"server_type\": \"ASYNC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 10, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 0}]}"
+    ], 
+    "boringssl": true, 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "cpu_cost": 8, 
+    "defaults": "boringssl", 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c++", 
+    "name": "json_run_localhost", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "shortname": "json_run_localhost:cpp_protobuf_sync_unary_qps_unconstrained_insecure_10_channels", 
+    "timeout_seconds": 180
+  }, 
+  {
+    "args": [
+      "--scenarios_json", 
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_unary_qps_unconstrained_insecure_31_channels\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"core_limit\": 0, \"security_params\": null, \"server_type\": \"ASYNC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 31, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 33, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 0}]}"
+    ], 
+    "boringssl": true, 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "cpu_cost": 8, 
+    "defaults": "boringssl", 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c++", 
+    "name": "json_run_localhost", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "shortname": "json_run_localhost:cpp_protobuf_sync_unary_qps_unconstrained_insecure_31_channels", 
+    "timeout_seconds": 180
+  }, 
+  {
+    "args": [
+      "--scenarios_json", 
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_unary_qps_unconstrained_insecure_100_channels\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"core_limit\": 0, \"security_params\": null, \"server_type\": \"ASYNC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 100, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 10, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 0}]}"
+    ], 
+    "boringssl": true, 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "cpu_cost": 8, 
+    "defaults": "boringssl", 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c++", 
+    "name": "json_run_localhost", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "shortname": "json_run_localhost:cpp_protobuf_sync_unary_qps_unconstrained_insecure_100_channels", 
+    "timeout_seconds": 180
+  }, 
+  {
+    "args": [
+      "--scenarios_json", 
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_unary_qps_unconstrained_insecure_316_channels\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"core_limit\": 0, \"security_params\": null, \"server_type\": \"ASYNC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 316, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 4, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 0}]}"
+    ], 
+    "boringssl": true, 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "cpu_cost": 8, 
+    "defaults": "boringssl", 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c++", 
+    "name": "json_run_localhost", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "shortname": "json_run_localhost:cpp_protobuf_sync_unary_qps_unconstrained_insecure_316_channels", 
+    "timeout_seconds": 180
+  }, 
+  {
+    "args": [
+      "--scenarios_json", 
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_unary_qps_unconstrained_insecure_1000_channels\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"core_limit\": 0, \"security_params\": null, \"server_type\": \"ASYNC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 1000, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 0}]}"
+    ], 
+    "boringssl": true, 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "cpu_cost": 8, 
+    "defaults": "boringssl", 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c++", 
+    "name": "json_run_localhost", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "shortname": "json_run_localhost:cpp_protobuf_sync_unary_qps_unconstrained_insecure_1000_channels", 
+    "timeout_seconds": 180
+  }, 
+  {
+    "args": [
+      "--scenarios_json", 
       "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_streaming_ping_pong_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"core_limit\": 1, \"security_params\": null, \"server_type\": \"ASYNC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 1}]}"
     ], 
     "boringssl": true, 
@@ -29257,33 +30678,6 @@
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_protobuf_sync_unary_ping_pong_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"core_limit\": 1, \"security_params\": null, \"server_type\": \"SYNC_SERVER\"}, \"client_config\": {\"client_type\": \"SYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 1, \"async_client_threads\": 1, \"outstanding_rpcs_per_channel\": 1, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 1}]}"
-    ], 
-    "boringssl": true, 
-    "ci_platforms": [
-      "linux", 
-      "mac", 
-      "posix", 
-      "windows"
-    ], 
-    "cpu_cost": 2, 
-    "defaults": "boringssl", 
-    "exclude_configs": [], 
-    "flaky": false, 
-    "language": "c++", 
-    "name": "json_run_localhost", 
-    "platforms": [
-      "linux", 
-      "mac", 
-      "posix", 
-      "windows"
-    ], 
-    "shortname": "json_run_localhost:cpp_protobuf_sync_unary_ping_pong_insecure", 
-    "timeout_seconds": 180
-  }, 
-  {
-    "args": [
-      "--scenarios_json", 
       "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_unary_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"core_limit\": 0, \"security_params\": null, \"server_type\": \"ASYNC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 0}]}"
     ], 
     "boringssl": true, 
@@ -29338,7 +30732,7 @@
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_generic_async_streaming_qps_unconstrained_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"core_limit\": 0, \"security_params\": null, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"ASYNC_GENERIC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 0}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_unary_qps_unconstrained_insecure_1_channels\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"core_limit\": 0, \"security_params\": null, \"server_type\": \"ASYNC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 1, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 6400, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 0}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
@@ -29359,13 +30753,13 @@
       "posix", 
       "windows"
     ], 
-    "shortname": "json_run_localhost:cpp_generic_async_streaming_qps_unconstrained_insecure", 
+    "shortname": "json_run_localhost:cpp_protobuf_async_unary_qps_unconstrained_insecure_1_channels", 
     "timeout_seconds": 180
   }, 
   {
     "args": [
       "--scenarios_json", 
-      "{\"scenarios\": [{\"name\": \"cpp_generic_async_streaming_qps_one_server_core_insecure\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 1, \"core_limit\": 1, \"security_params\": null, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"server_type\": \"ASYNC_GENERIC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"bytebuf_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 64, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 100, \"rpc_type\": \"STREAMING\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 0}]}"
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_unary_qps_unconstrained_insecure_3_channels\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"core_limit\": 0, \"security_params\": null, \"server_type\": \"ASYNC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 3, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 2134, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 0}]}"
     ], 
     "boringssl": true, 
     "ci_platforms": [
@@ -29374,7 +30768,7 @@
       "posix", 
       "windows"
     ], 
-    "cpu_cost": 1, 
+    "cpu_cost": 8, 
     "defaults": "boringssl", 
     "exclude_configs": [], 
     "flaky": false, 
@@ -29386,7 +30780,142 @@
       "posix", 
       "windows"
     ], 
-    "shortname": "json_run_localhost:cpp_generic_async_streaming_qps_one_server_core_insecure", 
+    "shortname": "json_run_localhost:cpp_protobuf_async_unary_qps_unconstrained_insecure_3_channels", 
+    "timeout_seconds": 180
+  }, 
+  {
+    "args": [
+      "--scenarios_json", 
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_unary_qps_unconstrained_insecure_10_channels\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"core_limit\": 0, \"security_params\": null, \"server_type\": \"ASYNC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 10, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 640, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 0}]}"
+    ], 
+    "boringssl": true, 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "cpu_cost": 8, 
+    "defaults": "boringssl", 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c++", 
+    "name": "json_run_localhost", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "shortname": "json_run_localhost:cpp_protobuf_async_unary_qps_unconstrained_insecure_10_channels", 
+    "timeout_seconds": 180
+  }, 
+  {
+    "args": [
+      "--scenarios_json", 
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_unary_qps_unconstrained_insecure_31_channels\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"core_limit\": 0, \"security_params\": null, \"server_type\": \"ASYNC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 31, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 207, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 0}]}"
+    ], 
+    "boringssl": true, 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "cpu_cost": 8, 
+    "defaults": "boringssl", 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c++", 
+    "name": "json_run_localhost", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "shortname": "json_run_localhost:cpp_protobuf_async_unary_qps_unconstrained_insecure_31_channels", 
+    "timeout_seconds": 180
+  }, 
+  {
+    "args": [
+      "--scenarios_json", 
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_unary_qps_unconstrained_insecure_100_channels\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"core_limit\": 0, \"security_params\": null, \"server_type\": \"ASYNC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 100, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 64, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 0}]}"
+    ], 
+    "boringssl": true, 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "cpu_cost": 8, 
+    "defaults": "boringssl", 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c++", 
+    "name": "json_run_localhost", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "shortname": "json_run_localhost:cpp_protobuf_async_unary_qps_unconstrained_insecure_100_channels", 
+    "timeout_seconds": 180
+  }, 
+  {
+    "args": [
+      "--scenarios_json", 
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_unary_qps_unconstrained_insecure_316_channels\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"core_limit\": 0, \"security_params\": null, \"server_type\": \"ASYNC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 316, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 21, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 0}]}"
+    ], 
+    "boringssl": true, 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "cpu_cost": 8, 
+    "defaults": "boringssl", 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c++", 
+    "name": "json_run_localhost", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "shortname": "json_run_localhost:cpp_protobuf_async_unary_qps_unconstrained_insecure_316_channels", 
+    "timeout_seconds": 180
+  }, 
+  {
+    "args": [
+      "--scenarios_json", 
+      "{\"scenarios\": [{\"name\": \"cpp_protobuf_async_unary_qps_unconstrained_insecure_1000_channels\", \"warmup_seconds\": 0, \"benchmark_seconds\": 1, \"num_servers\": 1, \"server_config\": {\"async_server_threads\": 0, \"core_limit\": 0, \"security_params\": null, \"server_type\": \"ASYNC_SERVER\"}, \"client_config\": {\"client_type\": \"ASYNC_CLIENT\", \"security_params\": null, \"payload_config\": {\"simple_params\": {\"resp_size\": 0, \"req_size\": 0}}, \"client_channels\": 1000, \"async_client_threads\": 0, \"outstanding_rpcs_per_channel\": 7, \"rpc_type\": \"UNARY\", \"load_params\": {\"closed_loop\": {}}, \"histogram_params\": {\"max_possible\": 60000000000.0, \"resolution\": 0.01}}, \"num_clients\": 0}]}"
+    ], 
+    "boringssl": true, 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "cpu_cost": 8, 
+    "defaults": "boringssl", 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c++", 
+    "name": "json_run_localhost", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "shortname": "json_run_localhost:cpp_protobuf_async_unary_qps_unconstrained_insecure_1000_channels", 
     "timeout_seconds": 180
   }, 
   {
@@ -33039,6 +34568,25 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/api_fuzzer_corpus/22967e8ed837f03b76a980cc1d25054fb84b40e9"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [
+      "tsan"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "api_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/api_fuzzer_corpus/22c9ed2979d9963bce6500997f1e0433988e7e37"
     ], 
     "ci_platforms": [
@@ -36003,6 +37551,25 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/api_fuzzer_corpus/3f464011f8620f227309f6b2c84df6fffb8ed962"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [
+      "tsan"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "api_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/api_fuzzer_corpus/3f47ad9ab401599f42d3c4f37ab9f702e3ff0fc9"
     ], 
     "ci_platforms": [
@@ -49892,6 +51459,25 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/api_fuzzer_corpus/crash-15070b2a2719ed8a6cbbaac25da02b7085993648"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [
+      "tsan"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "api_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/api_fuzzer_corpus/crash-1b9aeaf762bb1a972dda8f3a455df2628efd693b"
     ], 
     "ci_platforms": [
@@ -83807,6 +85393,804 @@
   }, 
   {
     "args": [
+      "test/core/support/percent_decode_corpus/04cb8ccc553f9b2f5e52c421aff6d1c954d3dae6"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [
+      "tsan"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "percent_decode_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
+      "test/core/support/percent_decode_corpus/0dd8f3a63745b3a2d39791559b5c1b311447b537"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [
+      "tsan"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "percent_decode_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
+      "test/core/support/percent_decode_corpus/17eeaca784409adbe43365c32ac87915d736bba3"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [
+      "tsan"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "percent_decode_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
+      "test/core/support/percent_decode_corpus/2040c1ff65f52a7ae668c2c8f324de5dacc9d695"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [
+      "tsan"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "percent_decode_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
+      "test/core/support/percent_decode_corpus/26b0d1da23027ae54db96e125e4a9e98842d77fb"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [
+      "tsan"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "percent_decode_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
+      "test/core/support/percent_decode_corpus/2a089c0db45acdb4c6ed8e7ff81ca7235792c0b9"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [
+      "tsan"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "percent_decode_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
+      "test/core/support/percent_decode_corpus/35b7b3bc3a740d5c3abca0d75b53f0e1e1ee998a"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [
+      "tsan"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "percent_decode_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
+      "test/core/support/percent_decode_corpus/36367ba1adba47a1cbc3a88707fde8cc7abdc248"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [
+      "tsan"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "percent_decode_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
+      "test/core/support/percent_decode_corpus/39c2ba51548a0beaf0d6d1164531f1447dc311b5"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [
+      "tsan"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "percent_decode_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
+      "test/core/support/percent_decode_corpus/56d08fea787c041395c6697ce26cfbc0decbe688"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [
+      "tsan"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "percent_decode_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
+      "test/core/support/percent_decode_corpus/678d981fdabb9f0d6640235cf1719dd1e1e66ae9"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [
+      "tsan"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "percent_decode_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
+      "test/core/support/percent_decode_corpus/68751961609ec010565de0aa87521dcbf0722c5d"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [
+      "tsan"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "percent_decode_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
+      "test/core/support/percent_decode_corpus/7875c06c6f03c9aa2f8e9c59f8d8957c8a32e759"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [
+      "tsan"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "percent_decode_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
+      "test/core/support/percent_decode_corpus/7b302090e090a5829b6d1dd7be30bd4e36a7e60f"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [
+      "tsan"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "percent_decode_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
+      "test/core/support/percent_decode_corpus/875e1022169c9e4c541a9ad894e69e989df22ba1"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [
+      "tsan"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "percent_decode_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
+      "test/core/support/percent_decode_corpus/8c1051ce066f5a26de9a9d133180621d0da957b4"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [
+      "tsan"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "percent_decode_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
+      "test/core/support/percent_decode_corpus/8e084e628ab83a18ac7ca7cb3506525263655c63"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [
+      "tsan"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "percent_decode_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
+      "test/core/support/percent_decode_corpus/9d316c4675f40ddccaf8f1cc7aea94170b1e4223"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [
+      "tsan"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "percent_decode_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
+      "test/core/support/percent_decode_corpus/ad1c7c11d18a7d116e2c2ef4d4c5afb1270836ae"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [
+      "tsan"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "percent_decode_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
+      "test/core/support/percent_decode_corpus/b471f94aa4facf502e622e4a248f1ba4063ae681"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [
+      "tsan"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "percent_decode_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
+      "test/core/support/percent_decode_corpus/bf52ece030f16136d46e0dc97f58d60a0d8a1f0b"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [
+      "tsan"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "percent_decode_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
+      "test/core/support/percent_decode_corpus/d5b2a7177339ba2b7ce2f60e5f4459bef1e72758"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [
+      "tsan"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "percent_decode_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
+      "test/core/support/percent_decode_corpus/de867b64c54a7ed773dc611fc5cd2f17c5433113"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [
+      "tsan"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "percent_decode_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
+      "test/core/support/percent_decode_corpus/e3948dbe004950591630dd5c52f4e0fcbd5e388a"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [
+      "tsan"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "percent_decode_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
+      "test/core/support/percent_decode_corpus/e7064f0b80f61dbc65915311032d27baa569ae2a"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [
+      "tsan"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "percent_decode_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
+      "test/core/support/percent_decode_corpus/xyz"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [
+      "tsan"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "percent_decode_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
+      "test/core/support/percent_encode_corpus/0d3ee7fa54e6c66103965fd4409b044ba7db6c3f"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [
+      "tsan"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "percent_encode_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
+      "test/core/support/percent_encode_corpus/2e7ccf75e27b9501e3b28cf1c50ed0c45ab7c226"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [
+      "tsan"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "percent_encode_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
+      "test/core/support/percent_encode_corpus/55bb859f3942c462b03b7cbcf22ab4a0ac9705cf"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [
+      "tsan"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "percent_encode_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
+      "test/core/support/percent_encode_corpus/56070cecd54c845b6d4334953b17b712eb000d93"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [
+      "tsan"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "percent_encode_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
+      "test/core/support/percent_encode_corpus/61f50e891bf7ff5eb7a7af206f1e25d77f8756e7"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [
+      "tsan"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "percent_encode_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
+      "test/core/support/percent_encode_corpus/6e0c60cefc704c7940e475a87dd9ae423061cb5a"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [
+      "tsan"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "percent_encode_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
+      "test/core/support/percent_encode_corpus/7271ebcc6d22a0f186f7bc3c1973a7ed1bec8d8e"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [
+      "tsan"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "percent_encode_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
+      "test/core/support/percent_encode_corpus/74c83ece3e2920a67593a9be9c82468f16cbb969"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [
+      "tsan"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "percent_encode_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
+      "test/core/support/percent_encode_corpus/98e004fd2a9f141a7a019720820080e12d637c06"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [
+      "tsan"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "percent_encode_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
+      "test/core/support/percent_encode_corpus/ba2c1e98227aa21ea3bb2ca4d0e504119717da8b"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [
+      "tsan"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "percent_encode_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
+      "test/core/support/percent_encode_corpus/c16b9fd45370d4afb5d3ebd307a6e263c25ffd45"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [
+      "tsan"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "percent_encode_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
+      "test/core/support/percent_encode_corpus/d58c3cd4eab9b6d2343abfa1c25c90a383fe0ec3"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [
+      "tsan"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "percent_encode_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
+      "test/core/support/percent_encode_corpus/e2619218ede30d2b7b8ecd601a9f0ae754b728b4"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [
+      "tsan"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "percent_encode_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
+      "test/core/support/percent_encode_corpus/f93b3653e453f0e3eea3198001be6ce46e64bd21"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [
+      "tsan"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "percent_encode_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
+      "test/core/support/percent_encode_corpus/fd41d029c7682ad3d1c40a9fd017a4c85b673a54"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [
+      "tsan"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "percent_encode_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
+      "test/core/support/percent_encode_corpus/xyz"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [
+      "tsan"
+    ], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "percent_encode_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/server_fuzzer_corpus/01c008fa.bin"
     ], 
     "ci_platforms": [
diff --git a/vsprojects/buildtests_c.sln b/vsprojects/buildtests_c.sln
index c28f3ba..8f3546f 100644
--- a/vsprojects/buildtests_c.sln
+++ b/vsprojects/buildtests_c.sln
@@ -300,6 +300,11 @@
         	lib = "False"
 	EndProjectSection
 EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gen_percent_encoding_tables", "vcxproj\.\gen_percent_encoding_tables\gen_percent_encoding_tables.vcxproj", "{95D6E277-5ED9-EBDB-3DB8-19C610D2C6F5}"
+	ProjectSection(myProperties) = preProject
+        	lib = "False"
+	EndProjectSection
+EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gpr", "vcxproj\.\gpr\gpr.vcxproj", "{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}"
 	ProjectSection(myProperties) = preProject
         	lib = "True"
@@ -377,6 +382,15 @@
 		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
 	EndProjectSection
 EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gpr_percent_encoding_test", "vcxproj\test\gpr_percent_encoding_test\gpr_percent_encoding_test.vcxproj", "{8313AE17-FCFA-8110-95C7-7AF2F814D188}"
+	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_slice_buffer_test", "vcxproj\test\gpr_slice_buffer_test\gpr_slice_buffer_test.vcxproj", "{E679773D-DE89-AEBB-9787-59019989B825}"
 	ProjectSection(myProperties) = preProject
         	lib = "False"
@@ -1898,6 +1912,22 @@
 		{A635DE99-B131-CA00-2D3B-8691D60B76C2}.Release-DLL|Win32.Build.0 = Release|Win32
 		{A635DE99-B131-CA00-2D3B-8691D60B76C2}.Release-DLL|x64.ActiveCfg = Release|x64
 		{A635DE99-B131-CA00-2D3B-8691D60B76C2}.Release-DLL|x64.Build.0 = Release|x64
+		{95D6E277-5ED9-EBDB-3DB8-19C610D2C6F5}.Debug|Win32.ActiveCfg = Debug|Win32
+		{95D6E277-5ED9-EBDB-3DB8-19C610D2C6F5}.Debug|x64.ActiveCfg = Debug|x64
+		{95D6E277-5ED9-EBDB-3DB8-19C610D2C6F5}.Release|Win32.ActiveCfg = Release|Win32
+		{95D6E277-5ED9-EBDB-3DB8-19C610D2C6F5}.Release|x64.ActiveCfg = Release|x64
+		{95D6E277-5ED9-EBDB-3DB8-19C610D2C6F5}.Debug|Win32.Build.0 = Debug|Win32
+		{95D6E277-5ED9-EBDB-3DB8-19C610D2C6F5}.Debug|x64.Build.0 = Debug|x64
+		{95D6E277-5ED9-EBDB-3DB8-19C610D2C6F5}.Release|Win32.Build.0 = Release|Win32
+		{95D6E277-5ED9-EBDB-3DB8-19C610D2C6F5}.Release|x64.Build.0 = Release|x64
+		{95D6E277-5ED9-EBDB-3DB8-19C610D2C6F5}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
+		{95D6E277-5ED9-EBDB-3DB8-19C610D2C6F5}.Debug-DLL|Win32.Build.0 = Debug|Win32
+		{95D6E277-5ED9-EBDB-3DB8-19C610D2C6F5}.Debug-DLL|x64.ActiveCfg = Debug|x64
+		{95D6E277-5ED9-EBDB-3DB8-19C610D2C6F5}.Debug-DLL|x64.Build.0 = Debug|x64
+		{95D6E277-5ED9-EBDB-3DB8-19C610D2C6F5}.Release-DLL|Win32.ActiveCfg = Release|Win32
+		{95D6E277-5ED9-EBDB-3DB8-19C610D2C6F5}.Release-DLL|Win32.Build.0 = Release|Win32
+		{95D6E277-5ED9-EBDB-3DB8-19C610D2C6F5}.Release-DLL|x64.ActiveCfg = Release|x64
+		{95D6E277-5ED9-EBDB-3DB8-19C610D2C6F5}.Release-DLL|x64.Build.0 = Release|x64
 		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}.Debug|Win32.ActiveCfg = Debug|Win32
 		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}.Debug|x64.ActiveCfg = Debug|x64
 		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}.Release|Win32.ActiveCfg = Release|Win32
@@ -2042,6 +2072,22 @@
 		{38797EE3-62CC-3CBF-18D5-009ED6DD0BEC}.Release-DLL|Win32.Build.0 = Release|Win32
 		{38797EE3-62CC-3CBF-18D5-009ED6DD0BEC}.Release-DLL|x64.ActiveCfg = Release|x64
 		{38797EE3-62CC-3CBF-18D5-009ED6DD0BEC}.Release-DLL|x64.Build.0 = Release|x64
+		{8313AE17-FCFA-8110-95C7-7AF2F814D188}.Debug|Win32.ActiveCfg = Debug|Win32
+		{8313AE17-FCFA-8110-95C7-7AF2F814D188}.Debug|x64.ActiveCfg = Debug|x64
+		{8313AE17-FCFA-8110-95C7-7AF2F814D188}.Release|Win32.ActiveCfg = Release|Win32
+		{8313AE17-FCFA-8110-95C7-7AF2F814D188}.Release|x64.ActiveCfg = Release|x64
+		{8313AE17-FCFA-8110-95C7-7AF2F814D188}.Debug|Win32.Build.0 = Debug|Win32
+		{8313AE17-FCFA-8110-95C7-7AF2F814D188}.Debug|x64.Build.0 = Debug|x64
+		{8313AE17-FCFA-8110-95C7-7AF2F814D188}.Release|Win32.Build.0 = Release|Win32
+		{8313AE17-FCFA-8110-95C7-7AF2F814D188}.Release|x64.Build.0 = Release|x64
+		{8313AE17-FCFA-8110-95C7-7AF2F814D188}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
+		{8313AE17-FCFA-8110-95C7-7AF2F814D188}.Debug-DLL|Win32.Build.0 = Debug|Win32
+		{8313AE17-FCFA-8110-95C7-7AF2F814D188}.Debug-DLL|x64.ActiveCfg = Debug|x64
+		{8313AE17-FCFA-8110-95C7-7AF2F814D188}.Debug-DLL|x64.Build.0 = Debug|x64
+		{8313AE17-FCFA-8110-95C7-7AF2F814D188}.Release-DLL|Win32.ActiveCfg = Release|Win32
+		{8313AE17-FCFA-8110-95C7-7AF2F814D188}.Release-DLL|Win32.Build.0 = Release|Win32
+		{8313AE17-FCFA-8110-95C7-7AF2F814D188}.Release-DLL|x64.ActiveCfg = Release|x64
+		{8313AE17-FCFA-8110-95C7-7AF2F814D188}.Release-DLL|x64.Build.0 = Release|x64
 		{E679773D-DE89-AEBB-9787-59019989B825}.Debug|Win32.ActiveCfg = Debug|Win32
 		{E679773D-DE89-AEBB-9787-59019989B825}.Debug|x64.ActiveCfg = Debug|x64
 		{E679773D-DE89-AEBB-9787-59019989B825}.Release|Win32.ActiveCfg = Release|Win32
diff --git a/vsprojects/grpc.sln b/vsprojects/grpc.sln
index 8fccc64..c75c65f 100644
--- a/vsprojects/grpc.sln
+++ b/vsprojects/grpc.sln
@@ -22,6 +22,11 @@
         	lib = "False"
 	EndProjectSection
 EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gen_percent_encoding_tables", "vcxproj\.\gen_percent_encoding_tables\gen_percent_encoding_tables.vcxproj", "{95D6E277-5ED9-EBDB-3DB8-19C610D2C6F5}"
+	ProjectSection(myProperties) = preProject
+        	lib = "False"
+	EndProjectSection
+EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gpr", "vcxproj\.\gpr\gpr.vcxproj", "{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}"
 	ProjectSection(myProperties) = preProject
         	lib = "True"
@@ -222,6 +227,22 @@
 		{A635DE99-B131-CA00-2D3B-8691D60B76C2}.Release-DLL|Win32.Build.0 = Release|Win32
 		{A635DE99-B131-CA00-2D3B-8691D60B76C2}.Release-DLL|x64.ActiveCfg = Release|x64
 		{A635DE99-B131-CA00-2D3B-8691D60B76C2}.Release-DLL|x64.Build.0 = Release|x64
+		{95D6E277-5ED9-EBDB-3DB8-19C610D2C6F5}.Debug|Win32.ActiveCfg = Debug|Win32
+		{95D6E277-5ED9-EBDB-3DB8-19C610D2C6F5}.Debug|x64.ActiveCfg = Debug|x64
+		{95D6E277-5ED9-EBDB-3DB8-19C610D2C6F5}.Release|Win32.ActiveCfg = Release|Win32
+		{95D6E277-5ED9-EBDB-3DB8-19C610D2C6F5}.Release|x64.ActiveCfg = Release|x64
+		{95D6E277-5ED9-EBDB-3DB8-19C610D2C6F5}.Debug|Win32.Build.0 = Debug|Win32
+		{95D6E277-5ED9-EBDB-3DB8-19C610D2C6F5}.Debug|x64.Build.0 = Debug|x64
+		{95D6E277-5ED9-EBDB-3DB8-19C610D2C6F5}.Release|Win32.Build.0 = Release|Win32
+		{95D6E277-5ED9-EBDB-3DB8-19C610D2C6F5}.Release|x64.Build.0 = Release|x64
+		{95D6E277-5ED9-EBDB-3DB8-19C610D2C6F5}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
+		{95D6E277-5ED9-EBDB-3DB8-19C610D2C6F5}.Debug-DLL|Win32.Build.0 = Debug|Win32
+		{95D6E277-5ED9-EBDB-3DB8-19C610D2C6F5}.Debug-DLL|x64.ActiveCfg = Debug|x64
+		{95D6E277-5ED9-EBDB-3DB8-19C610D2C6F5}.Debug-DLL|x64.Build.0 = Debug|x64
+		{95D6E277-5ED9-EBDB-3DB8-19C610D2C6F5}.Release-DLL|Win32.ActiveCfg = Release|Win32
+		{95D6E277-5ED9-EBDB-3DB8-19C610D2C6F5}.Release-DLL|Win32.Build.0 = Release|Win32
+		{95D6E277-5ED9-EBDB-3DB8-19C610D2C6F5}.Release-DLL|x64.ActiveCfg = Release|x64
+		{95D6E277-5ED9-EBDB-3DB8-19C610D2C6F5}.Release-DLL|x64.Build.0 = Release|x64
 		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}.Debug|Win32.ActiveCfg = Debug|Win32
 		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}.Debug|x64.ActiveCfg = Debug|x64
 		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}.Release|Win32.ActiveCfg = Release|Win32
diff --git a/vsprojects/vcxproj/gen_percent_encoding_tables/gen_percent_encoding_tables.vcxproj b/vsprojects/vcxproj/gen_percent_encoding_tables/gen_percent_encoding_tables.vcxproj
new file mode 100644
index 0000000..446b412
--- /dev/null
+++ b/vsprojects/vcxproj/gen_percent_encoding_tables/gen_percent_encoding_tables.vcxproj
@@ -0,0 +1,162 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{95D6E277-5ED9-EBDB-3DB8-19C610D2C6F5}</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>StaticLibrary</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)'=='Release'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="$(SolutionDir)\..\vsprojects\global.props" />
+    <Import Project="$(SolutionDir)\..\vsprojects\winsock.props" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup Condition="'$(Configuration)'=='Debug'">
+    <TargetName>gen_percent_encoding_tables</TargetName>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)'=='Release'">
+    <TargetName>gen_percent_encoding_tables</TargetName>
+  </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)\..\tools\codegen\core\gen_percent_encoding_tables.c">
+    </ClCompile>
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+  <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
+    <PropertyGroup>
+      <ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them.  For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
+    </PropertyGroup>
+  </Target>
+</Project>
+
diff --git a/vsprojects/vcxproj/gen_percent_encoding_tables/gen_percent_encoding_tables.vcxproj.filters b/vsprojects/vcxproj/gen_percent_encoding_tables/gen_percent_encoding_tables.vcxproj.filters
new file mode 100644
index 0000000..a787887
--- /dev/null
+++ b/vsprojects/vcxproj/gen_percent_encoding_tables/gen_percent_encoding_tables.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)\..\tools\codegen\core\gen_percent_encoding_tables.c">
+      <Filter>tools\codegen\core</Filter>
+    </ClCompile>
+  </ItemGroup>
+
+  <ItemGroup>
+    <Filter Include="tools">
+      <UniqueIdentifier>{e587d5b5-125f-1c73-e004-3c5659aa666b}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="tools\codegen">
+      <UniqueIdentifier>{0e90891e-2dd7-433f-2e97-b8495275cc10}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="tools\codegen\core">
+      <UniqueIdentifier>{194d6b8d-bf65-b581-90a4-13447dbfa951}</UniqueIdentifier>
+    </Filter>
+  </ItemGroup>
+</Project>
+
diff --git a/vsprojects/vcxproj/gpr/gpr.vcxproj b/vsprojects/vcxproj/gpr/gpr.vcxproj
index db8594e..a77c16d 100644
--- a/vsprojects/vcxproj/gpr/gpr.vcxproj
+++ b/vsprojects/vcxproj/gpr/gpr.vcxproj
@@ -175,20 +175,17 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\support\tls_msvc.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\support\tls_pthread.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\support\useful.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" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_sync.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_windows.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\log.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_types.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_windows.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\time.h" />
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\profiling\timers.h" />
@@ -196,6 +193,7 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\support\block_annotate.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\support\env.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\support\murmur_hash.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\support\percent_encoding.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\support\stack_lockfree.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\support\string.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\support\string_windows.h" />
@@ -246,6 +244,8 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\support\murmur_hash.c">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\support\percent_encoding.c">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\support\slice.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\support\slice_buffer.c">
diff --git a/vsprojects/vcxproj/gpr/gpr.vcxproj.filters b/vsprojects/vcxproj/gpr/gpr.vcxproj.filters
index 9bab373..f6ba556 100644
--- a/vsprojects/vcxproj/gpr/gpr.vcxproj.filters
+++ b/vsprojects/vcxproj/gpr/gpr.vcxproj.filters
@@ -64,6 +64,9 @@
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\support\murmur_hash.c">
       <Filter>src\core\lib\support</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\support\percent_encoding.c">
+      <Filter>src\core\lib\support</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\support\slice.c">
       <Filter>src\core\lib\support</Filter>
     </ClCompile>
@@ -222,9 +225,6 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\support\useful.h">
       <Filter>include\grpc\support</Filter>
     </ClInclude>
-    <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>
@@ -237,7 +237,7 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_windows.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\log.h">
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_types.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\port_platform.h">
@@ -246,9 +246,6 @@
     <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>
@@ -261,9 +258,6 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_windows.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>
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\profiling\timers.h">
@@ -281,6 +275,9 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\support\murmur_hash.h">
       <Filter>src\core\lib\support</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\support\percent_encoding.h">
+      <Filter>src\core\lib\support</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\support\stack_lockfree.h">
       <Filter>src\core\lib\support</Filter>
     </ClInclude>
diff --git a/vsprojects/vcxproj/grpc++/grpc++.vcxproj b/vsprojects/vcxproj/grpc++/grpc++.vcxproj
index 321a403..cddc904 100644
--- a/vsprojects/vcxproj/grpc++/grpc++.vcxproj
+++ b/vsprojects/vcxproj/grpc++/grpc++.vcxproj
@@ -312,27 +312,23 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\grpc_posix.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\grpc_security_constants.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\byte_buffer_reader.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" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_sync.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_windows.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\log.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_types.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_windows.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\time.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" />
@@ -455,6 +451,8 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\transport_impl.h" />
   </ItemGroup>
   <ItemGroup>
+    <ClCompile Include="$(SolutionDir)\..\src\cpp\client\insecure_credentials.cc">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\client\secure_credentials.cc">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\common\auth_property_iterator.cc">
@@ -465,9 +463,11 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\common\secure_create_auth_context.cc">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\cpp\server\insecure_server_credentials.cc">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\server\secure_server_credentials.cc">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\cpp\client\channel.cc">
+    <ClCompile Include="$(SolutionDir)\..\src\cpp\client\channel_cc.cc">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\client\client_context.cc">
     </ClCompile>
@@ -477,17 +477,15 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\client\create_channel_posix.cc">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\cpp\client\credentials.cc">
+    <ClCompile Include="$(SolutionDir)\..\src\cpp\client\credentials_cc.cc">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\client\generic_stub.cc">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\cpp\client\insecure_credentials.cc">
-    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\common\channel_arguments.cc">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\common\channel_filter.cc">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\cpp\common\completion_queue.cc">
+    <ClCompile Include="$(SolutionDir)\..\src\cpp\common\completion_queue_cc.cc">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\common\core_codegen.cc">
     </ClCompile>
@@ -499,27 +497,25 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\server\dynamic_thread_pool.cc">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\cpp\server\insecure_server_credentials.cc">
-    </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\cpp\server\server.cc">
-    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\server\server_builder.cc">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\cpp\server\server_cc.cc">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\server\server_context.cc">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\server\server_credentials.cc">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\server\server_posix.cc">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\cpp\util\byte_buffer.cc">
+    <ClCompile Include="$(SolutionDir)\..\src\cpp\util\byte_buffer_cc.cc">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\cpp\util\slice.cc">
+    <ClCompile Include="$(SolutionDir)\..\src\cpp\util\slice_cc.cc">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\util\status.cc">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\util\string_ref.cc">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\cpp\util\time.cc">
+    <ClCompile Include="$(SolutionDir)\..\src\cpp\util\time_cc.cc">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\channel_args.c">
     </ClCompile>
diff --git a/vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters b/vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters
index b34ca03..c9a4274 100644
--- a/vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters
@@ -1,6 +1,9 @@
 <?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\client\insecure_credentials.cc">
+      <Filter>src\cpp\client</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\client\secure_credentials.cc">
       <Filter>src\cpp\client</Filter>
     </ClCompile>
@@ -16,10 +19,13 @@
     <ClCompile Include="$(SolutionDir)\..\src\cpp\common\secure_create_auth_context.cc">
       <Filter>src\cpp\common</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\cpp\server\insecure_server_credentials.cc">
+      <Filter>src\cpp\server</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\server\secure_server_credentials.cc">
       <Filter>src\cpp\server</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\cpp\client\channel.cc">
+    <ClCompile Include="$(SolutionDir)\..\src\cpp\client\channel_cc.cc">
       <Filter>src\cpp\client</Filter>
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\client\client_context.cc">
@@ -34,22 +40,19 @@
     <ClCompile Include="$(SolutionDir)\..\src\cpp\client\create_channel_posix.cc">
       <Filter>src\cpp\client</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\cpp\client\credentials.cc">
+    <ClCompile Include="$(SolutionDir)\..\src\cpp\client\credentials_cc.cc">
       <Filter>src\cpp\client</Filter>
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\client\generic_stub.cc">
       <Filter>src\cpp\client</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\cpp\client\insecure_credentials.cc">
-      <Filter>src\cpp\client</Filter>
-    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\common\channel_arguments.cc">
       <Filter>src\cpp\common</Filter>
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\common\channel_filter.cc">
       <Filter>src\cpp\common</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\cpp\common\completion_queue.cc">
+    <ClCompile Include="$(SolutionDir)\..\src\cpp\common\completion_queue_cc.cc">
       <Filter>src\cpp\common</Filter>
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\common\core_codegen.cc">
@@ -67,15 +70,12 @@
     <ClCompile Include="$(SolutionDir)\..\src\cpp\server\dynamic_thread_pool.cc">
       <Filter>src\cpp\server</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\cpp\server\insecure_server_credentials.cc">
-      <Filter>src\cpp\server</Filter>
-    </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\cpp\server\server.cc">
-      <Filter>src\cpp\server</Filter>
-    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\server\server_builder.cc">
       <Filter>src\cpp\server</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\cpp\server\server_cc.cc">
+      <Filter>src\cpp\server</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\server\server_context.cc">
       <Filter>src\cpp\server</Filter>
     </ClCompile>
@@ -85,10 +85,10 @@
     <ClCompile Include="$(SolutionDir)\..\src\cpp\server\server_posix.cc">
       <Filter>src\cpp\server</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\cpp\util\byte_buffer.cc">
+    <ClCompile Include="$(SolutionDir)\..\src\cpp\util\byte_buffer_cc.cc">
       <Filter>src\cpp\util</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\cpp\util\slice.cc">
+    <ClCompile Include="$(SolutionDir)\..\src\cpp\util\slice_cc.cc">
       <Filter>src\cpp\util</Filter>
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\util\status.cc">
@@ -97,7 +97,7 @@
     <ClCompile Include="$(SolutionDir)\..\src\cpp\util\string_ref.cc">
       <Filter>src\cpp\util</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\cpp\util\time.cc">
+    <ClCompile Include="$(SolutionDir)\..\src\cpp\util\time_cc.cc">
       <Filter>src\cpp\util</Filter>
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\channel_args.c">
@@ -534,9 +534,6 @@
     <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>
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\byte_buffer_reader.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
@@ -555,9 +552,6 @@
     <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>
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
@@ -570,7 +564,7 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_windows.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\log.h">
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_types.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\port_platform.h">
@@ -579,9 +573,6 @@
     <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>
@@ -594,9 +585,6 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_windows.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\async_stream.h">
       <Filter>include\grpc++\impl\codegen</Filter>
     </ClInclude>
diff --git a/vsprojects/vcxproj/grpc++_reflection/grpc++_reflection.vcxproj b/vsprojects/vcxproj/grpc++_reflection/grpc++_reflection.vcxproj
index 7c3e63b..c073547 100644
--- a/vsprojects/vcxproj/grpc++_reflection/grpc++_reflection.vcxproj
+++ b/vsprojects/vcxproj/grpc++_reflection/grpc++_reflection.vcxproj
@@ -181,27 +181,23 @@
     <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\byte_buffer_reader.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" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_sync.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_windows.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\log.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_types.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_windows.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\time.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\config_protobuf.h" />
   </ItemGroup>
   <ItemGroup>
diff --git a/vsprojects/vcxproj/grpc++_reflection/grpc++_reflection.vcxproj.filters b/vsprojects/vcxproj/grpc++_reflection/grpc++_reflection.vcxproj.filters
index d9cd49c..a7ae3fc 100644
--- a/vsprojects/vcxproj/grpc++_reflection/grpc++_reflection.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc++_reflection/grpc++_reflection.vcxproj.filters
@@ -117,9 +117,6 @@
     <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\byte_buffer_reader.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
@@ -138,9 +135,6 @@
     <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>
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
@@ -153,7 +147,7 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_windows.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\log.h">
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_types.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\port_platform.h">
@@ -162,9 +156,6 @@
     <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>
@@ -177,9 +168,6 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_windows.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\config_protobuf.h">
       <Filter>include\grpc++\impl\codegen</Filter>
     </ClInclude>
diff --git a/vsprojects/vcxproj/grpc++_test_config/grpc++_test_config.vcxproj b/vsprojects/vcxproj/grpc++_test_config/grpc++_test_config.vcxproj
index 5eab788..cf07e21 100644
--- a/vsprojects/vcxproj/grpc++_test_config/grpc++_test_config.vcxproj
+++ b/vsprojects/vcxproj/grpc++_test_config/grpc++_test_config.vcxproj
@@ -150,7 +150,7 @@
     <ClInclude Include="$(SolutionDir)\..\test\cpp\util\test_config.h" />
   </ItemGroup>
   <ItemGroup>
-    <ClCompile Include="$(SolutionDir)\..\test\cpp\util\test_config.cc">
+    <ClCompile Include="$(SolutionDir)\..\test\cpp\util\test_config_cc.cc">
     </ClCompile>
   </ItemGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
diff --git a/vsprojects/vcxproj/grpc++_test_config/grpc++_test_config.vcxproj.filters b/vsprojects/vcxproj/grpc++_test_config/grpc++_test_config.vcxproj.filters
index b4d4134..73e3614 100644
--- a/vsprojects/vcxproj/grpc++_test_config/grpc++_test_config.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc++_test_config/grpc++_test_config.vcxproj.filters
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <ItemGroup>
-    <ClCompile Include="$(SolutionDir)\..\test\cpp\util\test_config.cc">
+    <ClCompile Include="$(SolutionDir)\..\test\cpp\util\test_config_cc.cc">
       <Filter>test\cpp\util</Filter>
     </ClCompile>
   </ItemGroup>
diff --git a/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj b/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj
index c2c7d00..c04f2f9 100644
--- a/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj
+++ b/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj
@@ -177,27 +177,23 @@
     <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\byte_buffer_reader.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" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_sync.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_windows.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\log.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_types.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_windows.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\time.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\proto_utils.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\config_protobuf.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\thrift_serializer.h" />
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 9b8c8dd..37ba3f0 100644
--- a/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj.filters
@@ -123,9 +123,6 @@
     <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\byte_buffer_reader.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
@@ -144,9 +141,6 @@
     <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>
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
@@ -159,7 +153,7 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_windows.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\log.h">
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_types.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\port_platform.h">
@@ -168,9 +162,6 @@
     <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>
@@ -183,9 +174,6 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_windows.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\proto_utils.h">
       <Filter>include\grpc++\impl\codegen</Filter>
     </ClInclude>
diff --git a/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj b/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj
index a7bb3ef..4146716 100644
--- a/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj
+++ b/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj
@@ -312,27 +312,23 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\grpc_posix.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\grpc_security_constants.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\byte_buffer_reader.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" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_sync.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_windows.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\log.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_types.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_windows.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\time.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" />
@@ -451,9 +447,13 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\transport_impl.h" />
   </ItemGroup>
   <ItemGroup>
+    <ClCompile Include="$(SolutionDir)\..\src\cpp\client\insecure_credentials.cc">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\common\insecure_create_auth_context.cc">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\cpp\client\channel.cc">
+    <ClCompile Include="$(SolutionDir)\..\src\cpp\server\insecure_server_credentials.cc">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\cpp\client\channel_cc.cc">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\client\client_context.cc">
     </ClCompile>
@@ -463,17 +463,15 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\client\create_channel_posix.cc">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\cpp\client\credentials.cc">
+    <ClCompile Include="$(SolutionDir)\..\src\cpp\client\credentials_cc.cc">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\client\generic_stub.cc">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\cpp\client\insecure_credentials.cc">
-    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\common\channel_arguments.cc">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\common\channel_filter.cc">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\cpp\common\completion_queue.cc">
+    <ClCompile Include="$(SolutionDir)\..\src\cpp\common\completion_queue_cc.cc">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\common\core_codegen.cc">
     </ClCompile>
@@ -485,27 +483,25 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\server\dynamic_thread_pool.cc">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\cpp\server\insecure_server_credentials.cc">
-    </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\cpp\server\server.cc">
-    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\server\server_builder.cc">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\cpp\server\server_cc.cc">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\server\server_context.cc">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\server\server_credentials.cc">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\server\server_posix.cc">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\cpp\util\byte_buffer.cc">
+    <ClCompile Include="$(SolutionDir)\..\src\cpp\util\byte_buffer_cc.cc">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\cpp\util\slice.cc">
+    <ClCompile Include="$(SolutionDir)\..\src\cpp\util\slice_cc.cc">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\util\status.cc">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\util\string_ref.cc">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\cpp\util\time.cc">
+    <ClCompile Include="$(SolutionDir)\..\src\cpp\util\time_cc.cc">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\channel_args.c">
     </ClCompile>
diff --git a/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters b/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters
index 4ad0ae3..6746841 100644
--- a/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters
@@ -1,10 +1,16 @@
 <?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\client\insecure_credentials.cc">
+      <Filter>src\cpp\client</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\common\insecure_create_auth_context.cc">
       <Filter>src\cpp\common</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\cpp\client\channel.cc">
+    <ClCompile Include="$(SolutionDir)\..\src\cpp\server\insecure_server_credentials.cc">
+      <Filter>src\cpp\server</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\cpp\client\channel_cc.cc">
       <Filter>src\cpp\client</Filter>
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\client\client_context.cc">
@@ -19,22 +25,19 @@
     <ClCompile Include="$(SolutionDir)\..\src\cpp\client\create_channel_posix.cc">
       <Filter>src\cpp\client</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\cpp\client\credentials.cc">
+    <ClCompile Include="$(SolutionDir)\..\src\cpp\client\credentials_cc.cc">
       <Filter>src\cpp\client</Filter>
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\client\generic_stub.cc">
       <Filter>src\cpp\client</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\cpp\client\insecure_credentials.cc">
-      <Filter>src\cpp\client</Filter>
-    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\common\channel_arguments.cc">
       <Filter>src\cpp\common</Filter>
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\common\channel_filter.cc">
       <Filter>src\cpp\common</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\cpp\common\completion_queue.cc">
+    <ClCompile Include="$(SolutionDir)\..\src\cpp\common\completion_queue_cc.cc">
       <Filter>src\cpp\common</Filter>
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\common\core_codegen.cc">
@@ -52,15 +55,12 @@
     <ClCompile Include="$(SolutionDir)\..\src\cpp\server\dynamic_thread_pool.cc">
       <Filter>src\cpp\server</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\cpp\server\insecure_server_credentials.cc">
-      <Filter>src\cpp\server</Filter>
-    </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\cpp\server\server.cc">
-      <Filter>src\cpp\server</Filter>
-    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\server\server_builder.cc">
       <Filter>src\cpp\server</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\cpp\server\server_cc.cc">
+      <Filter>src\cpp\server</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\server\server_context.cc">
       <Filter>src\cpp\server</Filter>
     </ClCompile>
@@ -70,10 +70,10 @@
     <ClCompile Include="$(SolutionDir)\..\src\cpp\server\server_posix.cc">
       <Filter>src\cpp\server</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\cpp\util\byte_buffer.cc">
+    <ClCompile Include="$(SolutionDir)\..\src\cpp\util\byte_buffer_cc.cc">
       <Filter>src\cpp\util</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\cpp\util\slice.cc">
+    <ClCompile Include="$(SolutionDir)\..\src\cpp\util\slice_cc.cc">
       <Filter>src\cpp\util</Filter>
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\util\status.cc">
@@ -82,7 +82,7 @@
     <ClCompile Include="$(SolutionDir)\..\src\cpp\util\string_ref.cc">
       <Filter>src\cpp\util</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\cpp\util\time.cc">
+    <ClCompile Include="$(SolutionDir)\..\src\cpp\util\time_cc.cc">
       <Filter>src\cpp\util</Filter>
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\channel_args.c">
@@ -519,9 +519,6 @@
     <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>
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\byte_buffer_reader.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
@@ -540,9 +537,6 @@
     <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>
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
@@ -555,7 +549,7 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_windows.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\log.h">
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_types.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\port_platform.h">
@@ -564,9 +558,6 @@
     <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>
@@ -579,9 +570,6 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_windows.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\async_stream.h">
       <Filter>include\grpc++\impl\codegen</Filter>
     </ClInclude>
diff --git a/vsprojects/vcxproj/grpc/grpc.vcxproj b/vsprojects/vcxproj/grpc/grpc.vcxproj
index 7c120bc..badbffd 100644
--- a/vsprojects/vcxproj/grpc/grpc.vcxproj
+++ b/vsprojects/vcxproj/grpc/grpc.vcxproj
@@ -274,27 +274,23 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\grpc_posix.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\grpc_security_constants.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\byte_buffer_reader.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" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_sync.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_windows.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\log.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_types.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_windows.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\time.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\grpc_security.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\census.h" />
   </ItemGroup>
diff --git a/vsprojects/vcxproj/grpc/grpc.vcxproj.filters b/vsprojects/vcxproj/grpc/grpc.vcxproj.filters
index 9cbb2ce..19bdda4 100644
--- a/vsprojects/vcxproj/grpc/grpc.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc/grpc.vcxproj.filters
@@ -594,9 +594,6 @@
     <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>
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\byte_buffer_reader.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
@@ -615,9 +612,6 @@
     <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>
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
@@ -630,7 +624,7 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_windows.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\log.h">
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_types.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\port_platform.h">
@@ -639,9 +633,6 @@
     <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>
@@ -654,9 +645,6 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_windows.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\grpc_security.h">
       <Filter>include\grpc</Filter>
     </ClInclude>
diff --git a/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj b/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj
index 80dd6b2..8eaf7f6 100644
--- a/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj
+++ b/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj
@@ -154,27 +154,23 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\grpc_posix.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\grpc_security_constants.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\byte_buffer_reader.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" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_sync.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_windows.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\log.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_types.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_windows.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\time.h" />
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="$(SolutionDir)\..\test\core\end2end\data\ssl_test_data.h" />
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 8dc28d1..2fc2c6d 100644
--- a/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj.filters
@@ -342,9 +342,6 @@
     <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>
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\byte_buffer_reader.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
@@ -363,9 +360,6 @@
     <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>
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
@@ -378,7 +372,7 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_windows.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\log.h">
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_types.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\port_platform.h">
@@ -387,9 +381,6 @@
     <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>
@@ -402,9 +393,6 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_windows.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>
     <ClInclude Include="$(SolutionDir)\..\test\core\end2end\data\ssl_test_data.h">
diff --git a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj
index d4a8576..9d97645 100644
--- a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj
+++ b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj
@@ -265,27 +265,23 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\grpc_posix.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\grpc_security_constants.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\byte_buffer_reader.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" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_sync.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_windows.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\log.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_types.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_windows.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\time.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\census.h" />
   </ItemGroup>
   <ItemGroup>
diff --git a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters
index fba5a02..251a8fa 100644
--- a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters
@@ -507,9 +507,6 @@
     <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>
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\byte_buffer_reader.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
@@ -528,9 +525,6 @@
     <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>
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
@@ -543,7 +537,7 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_windows.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\log.h">
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_types.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\port_platform.h">
@@ -552,9 +546,6 @@
     <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>
@@ -567,9 +558,6 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_windows.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\census.h">
       <Filter>include\grpc</Filter>
     </ClInclude>
diff --git a/vsprojects/vcxproj/test/codegen_test_full/codegen_test_full.vcxproj b/vsprojects/vcxproj/test/codegen_test_full/codegen_test_full.vcxproj
index e608f7e..273c145 100644
--- a/vsprojects/vcxproj/test/codegen_test_full/codegen_test_full.vcxproj
+++ b/vsprojects/vcxproj/test/codegen_test_full/codegen_test_full.vcxproj
@@ -190,27 +190,23 @@
     <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\byte_buffer_reader.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" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_sync.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_windows.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\log.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_types.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_windows.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\time.h" />
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="$(SolutionDir)\..\src\proto\grpc\testing\control.pb.cc">
diff --git a/vsprojects/vcxproj/test/codegen_test_full/codegen_test_full.vcxproj.filters b/vsprojects/vcxproj/test/codegen_test_full/codegen_test_full.vcxproj.filters
index 8fc8f39..e6d2dc2 100644
--- a/vsprojects/vcxproj/test/codegen_test_full/codegen_test_full.vcxproj.filters
+++ b/vsprojects/vcxproj/test/codegen_test_full/codegen_test_full.vcxproj.filters
@@ -111,9 +111,6 @@
     <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\byte_buffer_reader.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
@@ -132,9 +129,6 @@
     <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>
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
@@ -147,7 +141,7 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_windows.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\log.h">
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_types.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\port_platform.h">
@@ -156,9 +150,6 @@
     <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>
@@ -171,9 +162,6 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_windows.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>
diff --git a/vsprojects/vcxproj/test/codegen_test_minimal/codegen_test_minimal.vcxproj b/vsprojects/vcxproj/test/codegen_test_minimal/codegen_test_minimal.vcxproj
index 3331c61..b40d8c3 100644
--- a/vsprojects/vcxproj/test/codegen_test_minimal/codegen_test_minimal.vcxproj
+++ b/vsprojects/vcxproj/test/codegen_test_minimal/codegen_test_minimal.vcxproj
@@ -190,27 +190,23 @@
     <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\byte_buffer_reader.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" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_sync.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_windows.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\log.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_types.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_windows.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\time.h" />
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="$(SolutionDir)\..\src\proto\grpc\testing\control.pb.cc">
diff --git a/vsprojects/vcxproj/test/codegen_test_minimal/codegen_test_minimal.vcxproj.filters b/vsprojects/vcxproj/test/codegen_test_minimal/codegen_test_minimal.vcxproj.filters
index a8ff115..6db6ab6 100644
--- a/vsprojects/vcxproj/test/codegen_test_minimal/codegen_test_minimal.vcxproj.filters
+++ b/vsprojects/vcxproj/test/codegen_test_minimal/codegen_test_minimal.vcxproj.filters
@@ -114,9 +114,6 @@
     <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\byte_buffer_reader.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
@@ -135,9 +132,6 @@
     <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>
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
@@ -150,7 +144,7 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_windows.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\log.h">
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_types.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\port_platform.h">
@@ -159,9 +153,6 @@
     <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>
@@ -174,9 +165,6 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_windows.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>
diff --git a/vsprojects/vcxproj/test/end2end/fixtures/h2_census_nosec_test/h2_census_nosec_test.vcxproj b/vsprojects/vcxproj/test/end2end/fixtures/h2_census_nosec_test/h2_census_nosec_test.vcxproj
index 3000ec1..b43c39e 100644
--- a/vsprojects/vcxproj/test/end2end/fixtures/h2_census_nosec_test/h2_census_nosec_test.vcxproj
+++ b/vsprojects/vcxproj/test/end2end/fixtures/h2_census_nosec_test/h2_census_nosec_test.vcxproj
@@ -1,6 +1,5 @@
 <?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>
@@ -54,7 +53,6 @@
   <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>
@@ -63,15 +61,11 @@
     <TargetName>h2_census_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_census_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>
@@ -185,8 +179,6 @@
   <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>
@@ -194,9 +186,6 @@
     </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_compress_nosec_test/h2_compress_nosec_test.vcxproj b/vsprojects/vcxproj/test/end2end/fixtures/h2_compress_nosec_test/h2_compress_nosec_test.vcxproj
index 0fddf55..7da53a3 100644
--- a/vsprojects/vcxproj/test/end2end/fixtures/h2_compress_nosec_test/h2_compress_nosec_test.vcxproj
+++ b/vsprojects/vcxproj/test/end2end/fixtures/h2_compress_nosec_test/h2_compress_nosec_test.vcxproj
@@ -1,6 +1,5 @@
 <?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>
@@ -54,7 +53,6 @@
   <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>
@@ -63,15 +61,11 @@
     <TargetName>h2_compress_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_compress_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>
@@ -185,8 +179,6 @@
   <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>
@@ -194,9 +186,6 @@
     </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 b/vsprojects/vcxproj/test/end2end/fixtures/h2_full+trace_nosec_test/h2_full+trace_nosec_test.vcxproj
index a59e082..bbd7d38 100644
--- 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
@@ -1,6 +1,5 @@
 <?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>
@@ -54,7 +53,6 @@
   <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>
@@ -63,15 +61,11 @@
     <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>
@@ -185,8 +179,6 @@
   <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>
@@ -194,9 +186,6 @@
     </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_nosec_test/h2_full_nosec_test.vcxproj b/vsprojects/vcxproj/test/end2end/fixtures/h2_full_nosec_test/h2_full_nosec_test.vcxproj
index b76f51e..c55e07e 100644
--- a/vsprojects/vcxproj/test/end2end/fixtures/h2_full_nosec_test/h2_full_nosec_test.vcxproj
+++ b/vsprojects/vcxproj/test/end2end/fixtures/h2_full_nosec_test/h2_full_nosec_test.vcxproj
@@ -1,6 +1,5 @@
 <?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>
@@ -54,7 +53,6 @@
   <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>
@@ -63,15 +61,11 @@
     <TargetName>h2_full_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_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>
@@ -185,8 +179,6 @@
   <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>
@@ -194,9 +186,6 @@
     </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_load_reporting_nosec_test/h2_load_reporting_nosec_test.vcxproj b/vsprojects/vcxproj/test/end2end/fixtures/h2_load_reporting_nosec_test/h2_load_reporting_nosec_test.vcxproj
index 1ccc6bb..7eacfbd 100644
--- a/vsprojects/vcxproj/test/end2end/fixtures/h2_load_reporting_nosec_test/h2_load_reporting_nosec_test.vcxproj
+++ b/vsprojects/vcxproj/test/end2end/fixtures/h2_load_reporting_nosec_test/h2_load_reporting_nosec_test.vcxproj
@@ -1,6 +1,5 @@
 <?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>
@@ -54,7 +53,6 @@
   <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>
@@ -63,15 +61,11 @@
     <TargetName>h2_load_reporting_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_load_reporting_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>
@@ -185,8 +179,6 @@
   <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>
@@ -194,9 +186,6 @@
     </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_proxy_nosec_test/h2_proxy_nosec_test.vcxproj b/vsprojects/vcxproj/test/end2end/fixtures/h2_proxy_nosec_test/h2_proxy_nosec_test.vcxproj
index 7eb45e4..d4bca1a 100644
--- a/vsprojects/vcxproj/test/end2end/fixtures/h2_proxy_nosec_test/h2_proxy_nosec_test.vcxproj
+++ b/vsprojects/vcxproj/test/end2end/fixtures/h2_proxy_nosec_test/h2_proxy_nosec_test.vcxproj
@@ -1,6 +1,5 @@
 <?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>
@@ -54,7 +53,6 @@
   <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>
@@ -63,15 +61,11 @@
     <TargetName>h2_proxy_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_proxy_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>
@@ -185,8 +179,6 @@
   <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>
@@ -194,9 +186,6 @@
     </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_sockpair+trace_nosec_test/h2_sockpair+trace_nosec_test.vcxproj b/vsprojects/vcxproj/test/end2end/fixtures/h2_sockpair+trace_nosec_test/h2_sockpair+trace_nosec_test.vcxproj
index ebcdb21..7159d07 100644
--- a/vsprojects/vcxproj/test/end2end/fixtures/h2_sockpair+trace_nosec_test/h2_sockpair+trace_nosec_test.vcxproj
+++ b/vsprojects/vcxproj/test/end2end/fixtures/h2_sockpair+trace_nosec_test/h2_sockpair+trace_nosec_test.vcxproj
@@ -1,6 +1,5 @@
 <?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>
@@ -54,7 +53,6 @@
   <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>
@@ -63,15 +61,11 @@
     <TargetName>h2_sockpair+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_sockpair+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>
@@ -185,8 +179,6 @@
   <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>
@@ -194,9 +186,6 @@
     </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_sockpair_1byte_nosec_test/h2_sockpair_1byte_nosec_test.vcxproj b/vsprojects/vcxproj/test/end2end/fixtures/h2_sockpair_1byte_nosec_test/h2_sockpair_1byte_nosec_test.vcxproj
index a3529e5..6d2162e 100644
--- a/vsprojects/vcxproj/test/end2end/fixtures/h2_sockpair_1byte_nosec_test/h2_sockpair_1byte_nosec_test.vcxproj
+++ b/vsprojects/vcxproj/test/end2end/fixtures/h2_sockpair_1byte_nosec_test/h2_sockpair_1byte_nosec_test.vcxproj
@@ -1,6 +1,5 @@
 <?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>
@@ -54,7 +53,6 @@
   <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>
@@ -63,15 +61,11 @@
     <TargetName>h2_sockpair_1byte_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_sockpair_1byte_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>
@@ -185,8 +179,6 @@
   <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>
@@ -194,9 +186,6 @@
     </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_sockpair_nosec_test/h2_sockpair_nosec_test.vcxproj b/vsprojects/vcxproj/test/end2end/fixtures/h2_sockpair_nosec_test/h2_sockpair_nosec_test.vcxproj
index fe01a3d..d33b850 100644
--- a/vsprojects/vcxproj/test/end2end/fixtures/h2_sockpair_nosec_test/h2_sockpair_nosec_test.vcxproj
+++ b/vsprojects/vcxproj/test/end2end/fixtures/h2_sockpair_nosec_test/h2_sockpair_nosec_test.vcxproj
@@ -1,6 +1,5 @@
 <?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>
@@ -54,7 +53,6 @@
   <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>
@@ -63,15 +61,11 @@
     <TargetName>h2_sockpair_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_sockpair_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>
@@ -185,8 +179,6 @@
   <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>
@@ -194,9 +186,6 @@
     </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/tests/end2end_nosec_tests/end2end_nosec_tests.vcxproj b/vsprojects/vcxproj/test/end2end/tests/end2end_nosec_tests/end2end_nosec_tests.vcxproj
index 96c9574..d6ec369 100644
--- a/vsprojects/vcxproj/test/end2end/tests/end2end_nosec_tests/end2end_nosec_tests.vcxproj
+++ b/vsprojects/vcxproj/test/end2end/tests/end2end_nosec_tests/end2end_nosec_tests.vcxproj
@@ -227,6 +227,8 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\shutdown_finishes_tags.c">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\simple_cacheable_request.c">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\simple_delayed_request.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\simple_metadata.c">
diff --git a/vsprojects/vcxproj/test/end2end/tests/end2end_nosec_tests/end2end_nosec_tests.vcxproj.filters b/vsprojects/vcxproj/test/end2end/tests/end2end_nosec_tests/end2end_nosec_tests.vcxproj.filters
index 42f1b8e..a6c24a8 100644
--- a/vsprojects/vcxproj/test/end2end/tests/end2end_nosec_tests/end2end_nosec_tests.vcxproj.filters
+++ b/vsprojects/vcxproj/test/end2end/tests/end2end_nosec_tests/end2end_nosec_tests.vcxproj.filters
@@ -115,6 +115,9 @@
     <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\shutdown_finishes_tags.c">
       <Filter>test\core\end2end\tests</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\simple_cacheable_request.c">
+      <Filter>test\core\end2end\tests</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\simple_delayed_request.c">
       <Filter>test\core\end2end\tests</Filter>
     </ClCompile>
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 4336f36..085b147 100644
--- a/vsprojects/vcxproj/test/end2end/tests/end2end_tests/end2end_tests.vcxproj
+++ b/vsprojects/vcxproj/test/end2end/tests/end2end_tests/end2end_tests.vcxproj
@@ -229,6 +229,8 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\shutdown_finishes_tags.c">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\simple_cacheable_request.c">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\simple_delayed_request.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\simple_metadata.c">
diff --git a/vsprojects/vcxproj/test/end2end/tests/end2end_tests/end2end_tests.vcxproj.filters b/vsprojects/vcxproj/test/end2end/tests/end2end_tests/end2end_tests.vcxproj.filters
index a94dbe8..d224a9c 100644
--- a/vsprojects/vcxproj/test/end2end/tests/end2end_tests/end2end_tests.vcxproj.filters
+++ b/vsprojects/vcxproj/test/end2end/tests/end2end_tests/end2end_tests.vcxproj.filters
@@ -118,6 +118,9 @@
     <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\shutdown_finishes_tags.c">
       <Filter>test\core\end2end\tests</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\simple_cacheable_request.c">
+      <Filter>test\core\end2end\tests</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\core\end2end\tests\simple_delayed_request.c">
       <Filter>test\core\end2end\tests</Filter>
     </ClCompile>
diff --git a/vsprojects/vcxproj/test/gpr_percent_encoding_test/gpr_percent_encoding_test.vcxproj b/vsprojects/vcxproj/test/gpr_percent_encoding_test/gpr_percent_encoding_test.vcxproj
new file mode 100644
index 0000000..1a943e4
--- /dev/null
+++ b/vsprojects/vcxproj/test/gpr_percent_encoding_test/gpr_percent_encoding_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>{8313AE17-FCFA-8110-95C7-7AF2F814D188}</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_percent_encoding_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_percent_encoding_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\percent_encoding_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_percent_encoding_test/gpr_percent_encoding_test.vcxproj.filters b/vsprojects/vcxproj/test/gpr_percent_encoding_test/gpr_percent_encoding_test.vcxproj.filters
new file mode 100644
index 0000000..e25b1ad
--- /dev/null
+++ b/vsprojects/vcxproj/test/gpr_percent_encoding_test/gpr_percent_encoding_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\percent_encoding_test.c">
+      <Filter>test\core\support</Filter>
+    </ClCompile>
+  </ItemGroup>
+
+  <ItemGroup>
+    <Filter Include="test">
+      <UniqueIdentifier>{c2ea1ce7-c916-11e7-6477-92a18d988d54}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="test\core">
+      <UniqueIdentifier>{14fa1f36-5dea-ee3f-d3fa-a137176b235f}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="test\core\support">
+      <UniqueIdentifier>{e245dffe-593f-f63e-8dc8-3c9de4d00697}</UniqueIdentifier>
+    </Filter>
+  </ItemGroup>
+</Project>
+
diff --git a/vsprojects/vcxproj/test/grpc_tool_test/grpc_tool_test.vcxproj b/vsprojects/vcxproj/test/grpc_tool_test/grpc_tool_test.vcxproj
index c6f65aa..76f4415 100644
--- a/vsprojects/vcxproj/test/grpc_tool_test/grpc_tool_test.vcxproj
+++ b/vsprojects/vcxproj/test/grpc_tool_test/grpc_tool_test.vcxproj
@@ -191,27 +191,23 @@
     <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\byte_buffer_reader.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" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_sync.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_windows.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\log.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_types.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_windows.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\time.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\config_protobuf.h" />
   </ItemGroup>
   <ItemGroup>
diff --git a/vsprojects/vcxproj/test/grpc_tool_test/grpc_tool_test.vcxproj.filters b/vsprojects/vcxproj/test/grpc_tool_test/grpc_tool_test.vcxproj.filters
index 731eb2e..7839050 100644
--- a/vsprojects/vcxproj/test/grpc_tool_test/grpc_tool_test.vcxproj.filters
+++ b/vsprojects/vcxproj/test/grpc_tool_test/grpc_tool_test.vcxproj.filters
@@ -108,9 +108,6 @@
     <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\byte_buffer_reader.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
@@ -129,9 +126,6 @@
     <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>
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
@@ -144,7 +138,7 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_windows.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\log.h">
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\gpr_types.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\port_platform.h">
@@ -153,9 +147,6 @@
     <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>
@@ -168,9 +159,6 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_windows.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\config_protobuf.h">
       <Filter>include\grpc++\impl\codegen</Filter>
     </ClInclude>