Merge pull request #6704 from yang-g/distribtest

Add distrib test utilities for c++
diff --git a/BUILD b/BUILD
index fd03d52..5b07e8c 100644
--- a/BUILD
+++ b/BUILD
@@ -53,7 +53,7 @@
     "src/core/lib/support/murmur_hash.h",
     "src/core/lib/support/stack_lockfree.h",
     "src/core/lib/support/string.h",
-    "src/core/lib/support/string_win32.h",
+    "src/core/lib/support/string_windows.h",
     "src/core/lib/support/thd_internal.h",
     "src/core/lib/support/time_precise.h",
     "src/core/lib/support/tmpfile.h",
@@ -69,7 +69,7 @@
     "src/core/lib/support/cpu_windows.c",
     "src/core/lib/support/env_linux.c",
     "src/core/lib/support/env_posix.c",
-    "src/core/lib/support/env_win32.c",
+    "src/core/lib/support/env_windows.c",
     "src/core/lib/support/histogram.c",
     "src/core/lib/support/host_port.c",
     "src/core/lib/support/load_file.c",
@@ -77,31 +77,31 @@
     "src/core/lib/support/log_android.c",
     "src/core/lib/support/log_linux.c",
     "src/core/lib/support/log_posix.c",
-    "src/core/lib/support/log_win32.c",
+    "src/core/lib/support/log_windows.c",
     "src/core/lib/support/murmur_hash.c",
     "src/core/lib/support/slice.c",
     "src/core/lib/support/slice_buffer.c",
     "src/core/lib/support/stack_lockfree.c",
     "src/core/lib/support/string.c",
     "src/core/lib/support/string_posix.c",
-    "src/core/lib/support/string_util_win32.c",
-    "src/core/lib/support/string_win32.c",
+    "src/core/lib/support/string_util_windows.c",
+    "src/core/lib/support/string_windows.c",
     "src/core/lib/support/subprocess_posix.c",
     "src/core/lib/support/subprocess_windows.c",
     "src/core/lib/support/sync.c",
     "src/core/lib/support/sync_posix.c",
-    "src/core/lib/support/sync_win32.c",
+    "src/core/lib/support/sync_windows.c",
     "src/core/lib/support/thd.c",
     "src/core/lib/support/thd_posix.c",
-    "src/core/lib/support/thd_win32.c",
+    "src/core/lib/support/thd_windows.c",
     "src/core/lib/support/time.c",
     "src/core/lib/support/time_posix.c",
     "src/core/lib/support/time_precise.c",
-    "src/core/lib/support/time_win32.c",
+    "src/core/lib/support/time_windows.c",
     "src/core/lib/support/tls_pthread.c",
     "src/core/lib/support/tmpfile_msys.c",
     "src/core/lib/support/tmpfile_posix.c",
-    "src/core/lib/support/tmpfile_win32.c",
+    "src/core/lib/support/tmpfile_windows.c",
     "src/core/lib/support/wrap_memcpy.c",
   ],
   hdrs = [
@@ -109,14 +109,14 @@
     "include/grpc/support/atm.h",
     "include/grpc/support/atm_gcc_atomic.h",
     "include/grpc/support/atm_gcc_sync.h",
-    "include/grpc/support/atm_win32.h",
+    "include/grpc/support/atm_windows.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_win32.h",
+    "include/grpc/support/log_windows.h",
     "include/grpc/support/port_platform.h",
     "include/grpc/support/slice.h",
     "include/grpc/support/slice_buffer.h",
@@ -125,7 +125,7 @@
     "include/grpc/support/sync.h",
     "include/grpc/support/sync_generic.h",
     "include/grpc/support/sync_posix.h",
-    "include/grpc/support/sync_win32.h",
+    "include/grpc/support/sync_windows.h",
     "include/grpc/support/thd.h",
     "include/grpc/support/time.h",
     "include/grpc/support/tls.h",
@@ -137,7 +137,7 @@
     "include/grpc/impl/codegen/atm.h",
     "include/grpc/impl/codegen/atm_gcc_atomic.h",
     "include/grpc/impl/codegen/atm_gcc_sync.h",
-    "include/grpc/impl/codegen/atm_win32.h",
+    "include/grpc/impl/codegen/atm_windows.h",
     "include/grpc/impl/codegen/log.h",
     "include/grpc/impl/codegen/port_platform.h",
     "include/grpc/impl/codegen/slice.h",
@@ -145,7 +145,7 @@
     "include/grpc/impl/codegen/sync.h",
     "include/grpc/impl/codegen/sync_generic.h",
     "include/grpc/impl/codegen/sync_posix.h",
-    "include/grpc/impl/codegen/sync_win32.h",
+    "include/grpc/impl/codegen/sync_windows.h",
     "include/grpc/impl/codegen/time.h",
   ],
   includes = [
@@ -178,6 +178,7 @@
     "src/core/lib/iomgr/closure.h",
     "src/core/lib/iomgr/endpoint.h",
     "src/core/lib/iomgr/endpoint_pair.h",
+    "src/core/lib/iomgr/ev_poll_and_epoll_posix.h",
     "src/core/lib/iomgr/ev_poll_posix.h",
     "src/core/lib/iomgr/ev_posix.h",
     "src/core/lib/iomgr/exec_ctx.h",
@@ -186,6 +187,7 @@
     "src/core/lib/iomgr/iomgr.h",
     "src/core/lib/iomgr/iomgr_internal.h",
     "src/core/lib/iomgr/iomgr_posix.h",
+    "src/core/lib/iomgr/polling_entity.h",
     "src/core/lib/iomgr/pollset.h",
     "src/core/lib/iomgr/pollset_set.h",
     "src/core/lib/iomgr/pollset_set_windows.h",
@@ -194,7 +196,7 @@
     "src/core/lib/iomgr/sockaddr.h",
     "src/core/lib/iomgr/sockaddr_posix.h",
     "src/core/lib/iomgr/sockaddr_utils.h",
-    "src/core/lib/iomgr/sockaddr_win32.h",
+    "src/core/lib/iomgr/sockaddr_windows.h",
     "src/core/lib/iomgr/socket_utils_posix.h",
     "src/core/lib/iomgr/socket_windows.h",
     "src/core/lib/iomgr/tcp_client.h",
@@ -294,12 +296,14 @@
     "src/core/ext/client_config/subchannel_call_holder.h",
     "src/core/ext/client_config/subchannel_index.h",
     "src/core/ext/client_config/uri_parser.h",
-    "third_party/objective_c/Cronet/cronet_c_for_grpc.h",
     "src/core/ext/lb_policy/grpclb/load_balancer_api.h",
     "src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h",
+    "src/core/ext/load_reporting/load_reporting.h",
+    "src/core/ext/load_reporting/load_reporting_filter.h",
     "src/core/ext/census/aggregation.h",
     "src/core/ext/census/census_interface.h",
     "src/core/ext/census/census_rpc_stats.h",
+    "src/core/ext/census/gen/census.pb.h",
     "src/core/ext/census/grpc_filter.h",
     "src/core/ext/census/mlog.h",
     "src/core/ext/census/rpc_metric_id.h",
@@ -311,7 +315,7 @@
     "src/core/lib/channel/connected_channel.c",
     "src/core/lib/channel/http_client_filter.c",
     "src/core/lib/channel/http_server_filter.c",
-    "src/core/lib/compression/compression_algorithm.c",
+    "src/core/lib/compression/compression.c",
     "src/core/lib/compression/message_compress.c",
     "src/core/lib/debug/trace.c",
     "src/core/lib/http/format_request.c",
@@ -321,6 +325,7 @@
     "src/core/lib/iomgr/endpoint.c",
     "src/core/lib/iomgr/endpoint_pair_posix.c",
     "src/core/lib/iomgr/endpoint_pair_windows.c",
+    "src/core/lib/iomgr/ev_poll_and_epoll_posix.c",
     "src/core/lib/iomgr/ev_poll_posix.c",
     "src/core/lib/iomgr/ev_posix.c",
     "src/core/lib/iomgr/exec_ctx.c",
@@ -329,6 +334,7 @@
     "src/core/lib/iomgr/iomgr.c",
     "src/core/lib/iomgr/iomgr_posix.c",
     "src/core/lib/iomgr/iomgr_windows.c",
+    "src/core/lib/iomgr/polling_entity.c",
     "src/core/lib/iomgr/pollset_set_windows.c",
     "src/core/lib/iomgr/pollset_windows.c",
     "src/core/lib/iomgr/resolve_address_posix.c",
@@ -415,7 +421,7 @@
     "src/core/lib/security/credentials/credentials_metadata.c",
     "src/core/lib/security/credentials/fake/fake_credentials.c",
     "src/core/lib/security/credentials/google_default/credentials_posix.c",
-    "src/core/lib/security/credentials/google_default/credentials_win32.c",
+    "src/core/lib/security/credentials/google_default/credentials_windows.c",
     "src/core/lib/security/credentials/google_default/google_default_credentials.c",
     "src/core/lib/security/credentials/iam/iam_credentials.c",
     "src/core/lib/security/credentials/jwt/json_token.c",
@@ -456,17 +462,19 @@
     "src/core/ext/client_config/subchannel_index.c",
     "src/core/ext/client_config/uri_parser.c",
     "src/core/ext/transport/chttp2/server/insecure/server_chttp2.c",
+    "src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.c",
     "src/core/ext/transport/chttp2/client/insecure/channel_create.c",
-    "src/core/ext/transport/cronet/client/secure/cronet_channel_create.c",
-    "src/core/ext/transport/cronet/transport/cronet_api_dummy.c",
-    "src/core/ext/transport/cronet/transport/cronet_transport.c",
+    "src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c",
     "src/core/ext/lb_policy/grpclb/load_balancer_api.c",
     "src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c",
     "src/core/ext/lb_policy/pick_first/pick_first.c",
     "src/core/ext/lb_policy/round_robin/round_robin.c",
     "src/core/ext/resolver/dns/native/dns_resolver.c",
     "src/core/ext/resolver/sockaddr/sockaddr_resolver.c",
+    "src/core/ext/load_reporting/load_reporting.c",
+    "src/core/ext/load_reporting/load_reporting_filter.c",
     "src/core/ext/census/context.c",
+    "src/core/ext/census/gen/census.pb.c",
     "src/core/ext/census/grpc_context.c",
     "src/core/ext/census/grpc_filter.c",
     "src/core/ext/census/grpc_plugin.c",
@@ -482,6 +490,7 @@
     "include/grpc/byte_buffer_reader.h",
     "include/grpc/compression.h",
     "include/grpc/grpc.h",
+    "include/grpc/grpc_posix.h",
     "include/grpc/status.h",
     "include/grpc/impl/codegen/byte_buffer.h",
     "include/grpc/impl/codegen/byte_buffer_reader.h",
@@ -494,7 +503,7 @@
     "include/grpc/impl/codegen/atm.h",
     "include/grpc/impl/codegen/atm_gcc_atomic.h",
     "include/grpc/impl/codegen/atm_gcc_sync.h",
-    "include/grpc/impl/codegen/atm_win32.h",
+    "include/grpc/impl/codegen/atm_windows.h",
     "include/grpc/impl/codegen/log.h",
     "include/grpc/impl/codegen/port_platform.h",
     "include/grpc/impl/codegen/slice.h",
@@ -502,9 +511,8 @@
     "include/grpc/impl/codegen/sync.h",
     "include/grpc/impl/codegen/sync_generic.h",
     "include/grpc/impl/codegen/sync_posix.h",
-    "include/grpc/impl/codegen/sync_win32.h",
+    "include/grpc/impl/codegen/sync_windows.h",
     "include/grpc/impl/codegen/time.h",
-    "include/grpc/grpc_cronet.h",
     "include/grpc/grpc_security.h",
     "include/grpc/grpc_security_constants.h",
     "include/grpc/census.h",
@@ -527,6 +535,347 @@
 
 
 cc_library(
+  name = "grpc_cronet",
+  srcs = [
+    "src/core/lib/channel/channel_args.h",
+    "src/core/lib/channel/channel_stack.h",
+    "src/core/lib/channel/channel_stack_builder.h",
+    "src/core/lib/channel/compress_filter.h",
+    "src/core/lib/channel/connected_channel.h",
+    "src/core/lib/channel/context.h",
+    "src/core/lib/channel/http_client_filter.h",
+    "src/core/lib/channel/http_server_filter.h",
+    "src/core/lib/compression/algorithm_metadata.h",
+    "src/core/lib/compression/message_compress.h",
+    "src/core/lib/debug/trace.h",
+    "src/core/lib/http/format_request.h",
+    "src/core/lib/http/httpcli.h",
+    "src/core/lib/http/parser.h",
+    "src/core/lib/iomgr/closure.h",
+    "src/core/lib/iomgr/endpoint.h",
+    "src/core/lib/iomgr/endpoint_pair.h",
+    "src/core/lib/iomgr/ev_poll_and_epoll_posix.h",
+    "src/core/lib/iomgr/ev_poll_posix.h",
+    "src/core/lib/iomgr/ev_posix.h",
+    "src/core/lib/iomgr/exec_ctx.h",
+    "src/core/lib/iomgr/executor.h",
+    "src/core/lib/iomgr/iocp_windows.h",
+    "src/core/lib/iomgr/iomgr.h",
+    "src/core/lib/iomgr/iomgr_internal.h",
+    "src/core/lib/iomgr/iomgr_posix.h",
+    "src/core/lib/iomgr/polling_entity.h",
+    "src/core/lib/iomgr/pollset.h",
+    "src/core/lib/iomgr/pollset_set.h",
+    "src/core/lib/iomgr/pollset_set_windows.h",
+    "src/core/lib/iomgr/pollset_windows.h",
+    "src/core/lib/iomgr/resolve_address.h",
+    "src/core/lib/iomgr/sockaddr.h",
+    "src/core/lib/iomgr/sockaddr_posix.h",
+    "src/core/lib/iomgr/sockaddr_utils.h",
+    "src/core/lib/iomgr/sockaddr_windows.h",
+    "src/core/lib/iomgr/socket_utils_posix.h",
+    "src/core/lib/iomgr/socket_windows.h",
+    "src/core/lib/iomgr/tcp_client.h",
+    "src/core/lib/iomgr/tcp_posix.h",
+    "src/core/lib/iomgr/tcp_server.h",
+    "src/core/lib/iomgr/tcp_windows.h",
+    "src/core/lib/iomgr/time_averaged_stats.h",
+    "src/core/lib/iomgr/timer.h",
+    "src/core/lib/iomgr/timer_heap.h",
+    "src/core/lib/iomgr/udp_server.h",
+    "src/core/lib/iomgr/unix_sockets_posix.h",
+    "src/core/lib/iomgr/wakeup_fd_pipe.h",
+    "src/core/lib/iomgr/wakeup_fd_posix.h",
+    "src/core/lib/iomgr/workqueue.h",
+    "src/core/lib/iomgr/workqueue_posix.h",
+    "src/core/lib/iomgr/workqueue_windows.h",
+    "src/core/lib/json/json.h",
+    "src/core/lib/json/json_common.h",
+    "src/core/lib/json/json_reader.h",
+    "src/core/lib/json/json_writer.h",
+    "src/core/lib/surface/api_trace.h",
+    "src/core/lib/surface/call.h",
+    "src/core/lib/surface/call_test_only.h",
+    "src/core/lib/surface/channel.h",
+    "src/core/lib/surface/channel_init.h",
+    "src/core/lib/surface/channel_stack_type.h",
+    "src/core/lib/surface/completion_queue.h",
+    "src/core/lib/surface/event_string.h",
+    "src/core/lib/surface/init.h",
+    "src/core/lib/surface/lame_client.h",
+    "src/core/lib/surface/server.h",
+    "src/core/lib/surface/surface_trace.h",
+    "src/core/lib/transport/byte_stream.h",
+    "src/core/lib/transport/connectivity_state.h",
+    "src/core/lib/transport/metadata.h",
+    "src/core/lib/transport/metadata_batch.h",
+    "src/core/lib/transport/static_metadata.h",
+    "src/core/lib/transport/transport.h",
+    "src/core/lib/transport/transport_impl.h",
+    "third_party/objective_c/Cronet/cronet_c_for_grpc.h",
+    "src/core/ext/transport/chttp2/transport/bin_encoder.h",
+    "src/core/ext/transport/chttp2/transport/chttp2_transport.h",
+    "src/core/ext/transport/chttp2/transport/frame.h",
+    "src/core/ext/transport/chttp2/transport/frame_data.h",
+    "src/core/ext/transport/chttp2/transport/frame_goaway.h",
+    "src/core/ext/transport/chttp2/transport/frame_ping.h",
+    "src/core/ext/transport/chttp2/transport/frame_rst_stream.h",
+    "src/core/ext/transport/chttp2/transport/frame_settings.h",
+    "src/core/ext/transport/chttp2/transport/frame_window_update.h",
+    "src/core/ext/transport/chttp2/transport/hpack_encoder.h",
+    "src/core/ext/transport/chttp2/transport/hpack_parser.h",
+    "src/core/ext/transport/chttp2/transport/hpack_table.h",
+    "src/core/ext/transport/chttp2/transport/http2_errors.h",
+    "src/core/ext/transport/chttp2/transport/huffsyms.h",
+    "src/core/ext/transport/chttp2/transport/incoming_metadata.h",
+    "src/core/ext/transport/chttp2/transport/internal.h",
+    "src/core/ext/transport/chttp2/transport/status_conversion.h",
+    "src/core/ext/transport/chttp2/transport/stream_map.h",
+    "src/core/ext/transport/chttp2/transport/timeout_encoding.h",
+    "src/core/ext/transport/chttp2/transport/varint.h",
+    "src/core/ext/transport/chttp2/alpn/alpn.h",
+    "src/core/ext/client_config/client_channel.h",
+    "src/core/ext/client_config/client_channel_factory.h",
+    "src/core/ext/client_config/client_config.h",
+    "src/core/ext/client_config/connector.h",
+    "src/core/ext/client_config/initial_connect_string.h",
+    "src/core/ext/client_config/lb_policy.h",
+    "src/core/ext/client_config/lb_policy_factory.h",
+    "src/core/ext/client_config/lb_policy_registry.h",
+    "src/core/ext/client_config/parse_address.h",
+    "src/core/ext/client_config/resolver.h",
+    "src/core/ext/client_config/resolver_factory.h",
+    "src/core/ext/client_config/resolver_registry.h",
+    "src/core/ext/client_config/subchannel.h",
+    "src/core/ext/client_config/subchannel_call_holder.h",
+    "src/core/ext/client_config/subchannel_index.h",
+    "src/core/ext/client_config/uri_parser.h",
+    "src/core/lib/security/context/security_context.h",
+    "src/core/lib/security/credentials/composite/composite_credentials.h",
+    "src/core/lib/security/credentials/credentials.h",
+    "src/core/lib/security/credentials/fake/fake_credentials.h",
+    "src/core/lib/security/credentials/google_default/google_default_credentials.h",
+    "src/core/lib/security/credentials/iam/iam_credentials.h",
+    "src/core/lib/security/credentials/jwt/json_token.h",
+    "src/core/lib/security/credentials/jwt/jwt_credentials.h",
+    "src/core/lib/security/credentials/jwt/jwt_verifier.h",
+    "src/core/lib/security/credentials/oauth2/oauth2_credentials.h",
+    "src/core/lib/security/credentials/plugin/plugin_credentials.h",
+    "src/core/lib/security/credentials/ssl/ssl_credentials.h",
+    "src/core/lib/security/transport/auth_filters.h",
+    "src/core/lib/security/transport/handshake.h",
+    "src/core/lib/security/transport/secure_endpoint.h",
+    "src/core/lib/security/transport/security_connector.h",
+    "src/core/lib/security/util/b64.h",
+    "src/core/lib/security/util/json_util.h",
+    "src/core/lib/tsi/fake_transport_security.h",
+    "src/core/lib/tsi/ssl_transport_security.h",
+    "src/core/lib/tsi/ssl_types.h",
+    "src/core/lib/tsi/transport_security.h",
+    "src/core/lib/tsi/transport_security_interface.h",
+    "src/core/lib/surface/init.c",
+    "src/core/lib/channel/channel_args.c",
+    "src/core/lib/channel/channel_stack.c",
+    "src/core/lib/channel/channel_stack_builder.c",
+    "src/core/lib/channel/compress_filter.c",
+    "src/core/lib/channel/connected_channel.c",
+    "src/core/lib/channel/http_client_filter.c",
+    "src/core/lib/channel/http_server_filter.c",
+    "src/core/lib/compression/compression.c",
+    "src/core/lib/compression/message_compress.c",
+    "src/core/lib/debug/trace.c",
+    "src/core/lib/http/format_request.c",
+    "src/core/lib/http/httpcli.c",
+    "src/core/lib/http/parser.c",
+    "src/core/lib/iomgr/closure.c",
+    "src/core/lib/iomgr/endpoint.c",
+    "src/core/lib/iomgr/endpoint_pair_posix.c",
+    "src/core/lib/iomgr/endpoint_pair_windows.c",
+    "src/core/lib/iomgr/ev_poll_and_epoll_posix.c",
+    "src/core/lib/iomgr/ev_poll_posix.c",
+    "src/core/lib/iomgr/ev_posix.c",
+    "src/core/lib/iomgr/exec_ctx.c",
+    "src/core/lib/iomgr/executor.c",
+    "src/core/lib/iomgr/iocp_windows.c",
+    "src/core/lib/iomgr/iomgr.c",
+    "src/core/lib/iomgr/iomgr_posix.c",
+    "src/core/lib/iomgr/iomgr_windows.c",
+    "src/core/lib/iomgr/polling_entity.c",
+    "src/core/lib/iomgr/pollset_set_windows.c",
+    "src/core/lib/iomgr/pollset_windows.c",
+    "src/core/lib/iomgr/resolve_address_posix.c",
+    "src/core/lib/iomgr/resolve_address_windows.c",
+    "src/core/lib/iomgr/sockaddr_utils.c",
+    "src/core/lib/iomgr/socket_utils_common_posix.c",
+    "src/core/lib/iomgr/socket_utils_linux.c",
+    "src/core/lib/iomgr/socket_utils_posix.c",
+    "src/core/lib/iomgr/socket_windows.c",
+    "src/core/lib/iomgr/tcp_client_posix.c",
+    "src/core/lib/iomgr/tcp_client_windows.c",
+    "src/core/lib/iomgr/tcp_posix.c",
+    "src/core/lib/iomgr/tcp_server_posix.c",
+    "src/core/lib/iomgr/tcp_server_windows.c",
+    "src/core/lib/iomgr/tcp_windows.c",
+    "src/core/lib/iomgr/time_averaged_stats.c",
+    "src/core/lib/iomgr/timer.c",
+    "src/core/lib/iomgr/timer_heap.c",
+    "src/core/lib/iomgr/udp_server.c",
+    "src/core/lib/iomgr/unix_sockets_posix.c",
+    "src/core/lib/iomgr/unix_sockets_posix_noop.c",
+    "src/core/lib/iomgr/wakeup_fd_eventfd.c",
+    "src/core/lib/iomgr/wakeup_fd_nospecial.c",
+    "src/core/lib/iomgr/wakeup_fd_pipe.c",
+    "src/core/lib/iomgr/wakeup_fd_posix.c",
+    "src/core/lib/iomgr/workqueue_posix.c",
+    "src/core/lib/iomgr/workqueue_windows.c",
+    "src/core/lib/json/json.c",
+    "src/core/lib/json/json_reader.c",
+    "src/core/lib/json/json_string.c",
+    "src/core/lib/json/json_writer.c",
+    "src/core/lib/surface/alarm.c",
+    "src/core/lib/surface/api_trace.c",
+    "src/core/lib/surface/byte_buffer.c",
+    "src/core/lib/surface/byte_buffer_reader.c",
+    "src/core/lib/surface/call.c",
+    "src/core/lib/surface/call_details.c",
+    "src/core/lib/surface/call_log_batch.c",
+    "src/core/lib/surface/channel.c",
+    "src/core/lib/surface/channel_init.c",
+    "src/core/lib/surface/channel_ping.c",
+    "src/core/lib/surface/channel_stack_type.c",
+    "src/core/lib/surface/completion_queue.c",
+    "src/core/lib/surface/event_string.c",
+    "src/core/lib/surface/lame_client.c",
+    "src/core/lib/surface/metadata_array.c",
+    "src/core/lib/surface/server.c",
+    "src/core/lib/surface/validate_metadata.c",
+    "src/core/lib/surface/version.c",
+    "src/core/lib/transport/byte_stream.c",
+    "src/core/lib/transport/connectivity_state.c",
+    "src/core/lib/transport/metadata.c",
+    "src/core/lib/transport/metadata_batch.c",
+    "src/core/lib/transport/static_metadata.c",
+    "src/core/lib/transport/transport.c",
+    "src/core/lib/transport/transport_op_string.c",
+    "src/core/ext/transport/cronet/client/secure/cronet_channel_create.c",
+    "src/core/ext/transport/cronet/transport/cronet_api_dummy.c",
+    "src/core/ext/transport/cronet/transport/cronet_transport.c",
+    "src/core/ext/transport/chttp2/client/secure/secure_channel_create.c",
+    "src/core/ext/transport/chttp2/transport/bin_encoder.c",
+    "src/core/ext/transport/chttp2/transport/chttp2_plugin.c",
+    "src/core/ext/transport/chttp2/transport/chttp2_transport.c",
+    "src/core/ext/transport/chttp2/transport/frame_data.c",
+    "src/core/ext/transport/chttp2/transport/frame_goaway.c",
+    "src/core/ext/transport/chttp2/transport/frame_ping.c",
+    "src/core/ext/transport/chttp2/transport/frame_rst_stream.c",
+    "src/core/ext/transport/chttp2/transport/frame_settings.c",
+    "src/core/ext/transport/chttp2/transport/frame_window_update.c",
+    "src/core/ext/transport/chttp2/transport/hpack_encoder.c",
+    "src/core/ext/transport/chttp2/transport/hpack_parser.c",
+    "src/core/ext/transport/chttp2/transport/hpack_table.c",
+    "src/core/ext/transport/chttp2/transport/huffsyms.c",
+    "src/core/ext/transport/chttp2/transport/incoming_metadata.c",
+    "src/core/ext/transport/chttp2/transport/parsing.c",
+    "src/core/ext/transport/chttp2/transport/status_conversion.c",
+    "src/core/ext/transport/chttp2/transport/stream_lists.c",
+    "src/core/ext/transport/chttp2/transport/stream_map.c",
+    "src/core/ext/transport/chttp2/transport/timeout_encoding.c",
+    "src/core/ext/transport/chttp2/transport/varint.c",
+    "src/core/ext/transport/chttp2/transport/writing.c",
+    "src/core/ext/transport/chttp2/alpn/alpn.c",
+    "src/core/ext/client_config/channel_connectivity.c",
+    "src/core/ext/client_config/client_channel.c",
+    "src/core/ext/client_config/client_channel_factory.c",
+    "src/core/ext/client_config/client_config.c",
+    "src/core/ext/client_config/client_config_plugin.c",
+    "src/core/ext/client_config/connector.c",
+    "src/core/ext/client_config/default_initial_connect_string.c",
+    "src/core/ext/client_config/initial_connect_string.c",
+    "src/core/ext/client_config/lb_policy.c",
+    "src/core/ext/client_config/lb_policy_factory.c",
+    "src/core/ext/client_config/lb_policy_registry.c",
+    "src/core/ext/client_config/parse_address.c",
+    "src/core/ext/client_config/resolver.c",
+    "src/core/ext/client_config/resolver_factory.c",
+    "src/core/ext/client_config/resolver_registry.c",
+    "src/core/ext/client_config/subchannel.c",
+    "src/core/ext/client_config/subchannel_call_holder.c",
+    "src/core/ext/client_config/subchannel_index.c",
+    "src/core/ext/client_config/uri_parser.c",
+    "src/core/lib/http/httpcli_security_connector.c",
+    "src/core/lib/security/context/security_context.c",
+    "src/core/lib/security/credentials/composite/composite_credentials.c",
+    "src/core/lib/security/credentials/credentials.c",
+    "src/core/lib/security/credentials/credentials_metadata.c",
+    "src/core/lib/security/credentials/fake/fake_credentials.c",
+    "src/core/lib/security/credentials/google_default/credentials_posix.c",
+    "src/core/lib/security/credentials/google_default/credentials_windows.c",
+    "src/core/lib/security/credentials/google_default/google_default_credentials.c",
+    "src/core/lib/security/credentials/iam/iam_credentials.c",
+    "src/core/lib/security/credentials/jwt/json_token.c",
+    "src/core/lib/security/credentials/jwt/jwt_credentials.c",
+    "src/core/lib/security/credentials/jwt/jwt_verifier.c",
+    "src/core/lib/security/credentials/oauth2/oauth2_credentials.c",
+    "src/core/lib/security/credentials/plugin/plugin_credentials.c",
+    "src/core/lib/security/credentials/ssl/ssl_credentials.c",
+    "src/core/lib/security/transport/client_auth_filter.c",
+    "src/core/lib/security/transport/handshake.c",
+    "src/core/lib/security/transport/secure_endpoint.c",
+    "src/core/lib/security/transport/security_connector.c",
+    "src/core/lib/security/transport/server_auth_filter.c",
+    "src/core/lib/security/util/b64.c",
+    "src/core/lib/security/util/json_util.c",
+    "src/core/lib/surface/init_secure.c",
+    "src/core/lib/tsi/fake_transport_security.c",
+    "src/core/lib/tsi/ssl_transport_security.c",
+    "src/core/lib/tsi/transport_security.c",
+    "src/core/plugin_registry/grpc_cronet_plugin_registry.c",
+  ],
+  hdrs = [
+    "include/grpc/byte_buffer.h",
+    "include/grpc/byte_buffer_reader.h",
+    "include/grpc/compression.h",
+    "include/grpc/grpc.h",
+    "include/grpc/grpc_posix.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/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",
+    "include/grpc/grpc_security_constants.h",
+  ],
+  includes = [
+    "include",
+    ".",
+  ],
+  deps = [
+    "//external:libssl",
+    ":gpr",
+  ],
+)
+
+
+
+cc_library(
   name = "grpc_unsecure",
   srcs = [
     "src/core/lib/channel/channel_args.h",
@@ -546,6 +895,7 @@
     "src/core/lib/iomgr/closure.h",
     "src/core/lib/iomgr/endpoint.h",
     "src/core/lib/iomgr/endpoint_pair.h",
+    "src/core/lib/iomgr/ev_poll_and_epoll_posix.h",
     "src/core/lib/iomgr/ev_poll_posix.h",
     "src/core/lib/iomgr/ev_posix.h",
     "src/core/lib/iomgr/exec_ctx.h",
@@ -554,6 +904,7 @@
     "src/core/lib/iomgr/iomgr.h",
     "src/core/lib/iomgr/iomgr_internal.h",
     "src/core/lib/iomgr/iomgr_posix.h",
+    "src/core/lib/iomgr/polling_entity.h",
     "src/core/lib/iomgr/pollset.h",
     "src/core/lib/iomgr/pollset_set.h",
     "src/core/lib/iomgr/pollset_set_windows.h",
@@ -562,7 +913,7 @@
     "src/core/lib/iomgr/sockaddr.h",
     "src/core/lib/iomgr/sockaddr_posix.h",
     "src/core/lib/iomgr/sockaddr_utils.h",
-    "src/core/lib/iomgr/sockaddr_win32.h",
+    "src/core/lib/iomgr/sockaddr_windows.h",
     "src/core/lib/iomgr/socket_utils_posix.h",
     "src/core/lib/iomgr/socket_windows.h",
     "src/core/lib/iomgr/tcp_client.h",
@@ -639,11 +990,14 @@
     "src/core/ext/client_config/subchannel_call_holder.h",
     "src/core/ext/client_config/subchannel_index.h",
     "src/core/ext/client_config/uri_parser.h",
+    "src/core/ext/load_reporting/load_reporting.h",
+    "src/core/ext/load_reporting/load_reporting_filter.h",
     "src/core/ext/lb_policy/grpclb/load_balancer_api.h",
     "src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h",
     "src/core/ext/census/aggregation.h",
     "src/core/ext/census/census_interface.h",
     "src/core/ext/census/census_rpc_stats.h",
+    "src/core/ext/census/gen/census.pb.h",
     "src/core/ext/census/grpc_filter.h",
     "src/core/ext/census/mlog.h",
     "src/core/ext/census/rpc_metric_id.h",
@@ -656,7 +1010,7 @@
     "src/core/lib/channel/connected_channel.c",
     "src/core/lib/channel/http_client_filter.c",
     "src/core/lib/channel/http_server_filter.c",
-    "src/core/lib/compression/compression_algorithm.c",
+    "src/core/lib/compression/compression.c",
     "src/core/lib/compression/message_compress.c",
     "src/core/lib/debug/trace.c",
     "src/core/lib/http/format_request.c",
@@ -666,6 +1020,7 @@
     "src/core/lib/iomgr/endpoint.c",
     "src/core/lib/iomgr/endpoint_pair_posix.c",
     "src/core/lib/iomgr/endpoint_pair_windows.c",
+    "src/core/lib/iomgr/ev_poll_and_epoll_posix.c",
     "src/core/lib/iomgr/ev_poll_posix.c",
     "src/core/lib/iomgr/ev_posix.c",
     "src/core/lib/iomgr/exec_ctx.c",
@@ -674,6 +1029,7 @@
     "src/core/lib/iomgr/iomgr.c",
     "src/core/lib/iomgr/iomgr_posix.c",
     "src/core/lib/iomgr/iomgr_windows.c",
+    "src/core/lib/iomgr/polling_entity.c",
     "src/core/lib/iomgr/pollset_set_windows.c",
     "src/core/lib/iomgr/pollset_windows.c",
     "src/core/lib/iomgr/resolve_address_posix.c",
@@ -731,6 +1087,7 @@
     "src/core/lib/transport/transport.c",
     "src/core/lib/transport/transport_op_string.c",
     "src/core/ext/transport/chttp2/server/insecure/server_chttp2.c",
+    "src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.c",
     "src/core/ext/transport/chttp2/transport/bin_encoder.c",
     "src/core/ext/transport/chttp2/transport/chttp2_plugin.c",
     "src/core/ext/transport/chttp2/transport/chttp2_transport.c",
@@ -754,6 +1111,7 @@
     "src/core/ext/transport/chttp2/transport/writing.c",
     "src/core/ext/transport/chttp2/alpn/alpn.c",
     "src/core/ext/transport/chttp2/client/insecure/channel_create.c",
+    "src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c",
     "src/core/ext/client_config/channel_connectivity.c",
     "src/core/ext/client_config/client_channel.c",
     "src/core/ext/client_config/client_channel_factory.c",
@@ -775,11 +1133,14 @@
     "src/core/ext/client_config/uri_parser.c",
     "src/core/ext/resolver/dns/native/dns_resolver.c",
     "src/core/ext/resolver/sockaddr/sockaddr_resolver.c",
+    "src/core/ext/load_reporting/load_reporting.c",
+    "src/core/ext/load_reporting/load_reporting_filter.c",
     "src/core/ext/lb_policy/grpclb/load_balancer_api.c",
     "src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c",
     "src/core/ext/lb_policy/pick_first/pick_first.c",
     "src/core/ext/lb_policy/round_robin/round_robin.c",
     "src/core/ext/census/context.c",
+    "src/core/ext/census/gen/census.pb.c",
     "src/core/ext/census/grpc_context.c",
     "src/core/ext/census/grpc_filter.c",
     "src/core/ext/census/grpc_plugin.c",
@@ -795,6 +1156,7 @@
     "include/grpc/byte_buffer_reader.h",
     "include/grpc/compression.h",
     "include/grpc/grpc.h",
+    "include/grpc/grpc_posix.h",
     "include/grpc/status.h",
     "include/grpc/impl/codegen/byte_buffer.h",
     "include/grpc/impl/codegen/byte_buffer_reader.h",
@@ -807,7 +1169,7 @@
     "include/grpc/impl/codegen/atm.h",
     "include/grpc/impl/codegen/atm_gcc_atomic.h",
     "include/grpc/impl/codegen/atm_gcc_sync.h",
-    "include/grpc/impl/codegen/atm_win32.h",
+    "include/grpc/impl/codegen/atm_windows.h",
     "include/grpc/impl/codegen/log.h",
     "include/grpc/impl/codegen/port_platform.h",
     "include/grpc/impl/codegen/slice.h",
@@ -815,7 +1177,7 @@
     "include/grpc/impl/codegen/sync.h",
     "include/grpc/impl/codegen/sync_generic.h",
     "include/grpc/impl/codegen/sync_posix.h",
-    "include/grpc/impl/codegen/sync_win32.h",
+    "include/grpc/impl/codegen/sync_windows.h",
     "include/grpc/impl/codegen/time.h",
     "include/grpc/census.h",
   ],
@@ -857,8 +1219,8 @@
 cc_library(
   name = "grpc++",
   srcs = [
+    "include/grpc++/impl/codegen/core_codegen.h",
     "src/cpp/client/secure_credentials.h",
-    "src/cpp/common/core_codegen.h",
     "src/cpp/common/secure_auth_context.h",
     "src/cpp/server/secure_server_credentials.h",
     "src/cpp/client/create_channel_internal.h",
@@ -874,6 +1236,7 @@
     "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/generic_stub.cc",
     "src/cpp/client/insecure_credentials.cc",
@@ -889,6 +1252,7 @@
     "src/cpp/server/server_builder.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/status.cc",
@@ -902,14 +1266,15 @@
     "include/grpc++/client_context.h",
     "include/grpc++/completion_queue.h",
     "include/grpc++/create_channel.h",
+    "include/grpc++/create_channel_posix.h",
     "include/grpc++/generic/async_generic_service.h",
     "include/grpc++/generic/generic_stub.h",
     "include/grpc++/grpc++.h",
     "include/grpc++/impl/call.h",
     "include/grpc++/impl/client_unary_call.h",
+    "include/grpc++/impl/codegen/core_codegen.h",
     "include/grpc++/impl/grpc_library.h",
     "include/grpc++/impl/method_handler_impl.h",
-    "include/grpc++/impl/proto_utils.h",
     "include/grpc++/impl/rpc_method.h",
     "include/grpc++/impl/rpc_service_method.h",
     "include/grpc++/impl/serialization_traits.h",
@@ -930,10 +1295,12 @@
     "include/grpc++/server.h",
     "include/grpc++/server_builder.h",
     "include/grpc++/server_context.h",
+    "include/grpc++/server_posix.h",
     "include/grpc++/support/async_stream.h",
     "include/grpc++/support/async_unary_call.h",
     "include/grpc++/support/byte_buffer.h",
     "include/grpc++/support/channel_arguments.h",
+    "include/grpc++/support/config.h",
     "include/grpc++/support/slice.h",
     "include/grpc++/support/status.h",
     "include/grpc++/support/status_code_enum.h",
@@ -950,11 +1317,11 @@
     "include/grpc++/impl/codegen/client_unary_call.h",
     "include/grpc++/impl/codegen/completion_queue.h",
     "include/grpc++/impl/codegen/completion_queue_tag.h",
+    "include/grpc++/impl/codegen/config.h",
     "include/grpc++/impl/codegen/core_codegen_interface.h",
     "include/grpc++/impl/codegen/create_auth_context.h",
     "include/grpc++/impl/codegen/grpc_library.h",
     "include/grpc++/impl/codegen/method_handler_impl.h",
-    "include/grpc++/impl/codegen/proto_utils.h",
     "include/grpc++/impl/codegen/rpc_method.h",
     "include/grpc++/impl/codegen/rpc_service_method.h",
     "include/grpc++/impl/codegen/security/auth_context.h",
@@ -982,7 +1349,7 @@
     "include/grpc/impl/codegen/atm.h",
     "include/grpc/impl/codegen/atm_gcc_atomic.h",
     "include/grpc/impl/codegen/atm_gcc_sync.h",
-    "include/grpc/impl/codegen/atm_win32.h",
+    "include/grpc/impl/codegen/atm_windows.h",
     "include/grpc/impl/codegen/log.h",
     "include/grpc/impl/codegen/port_platform.h",
     "include/grpc/impl/codegen/slice.h",
@@ -990,12 +1357,8 @@
     "include/grpc/impl/codegen/sync.h",
     "include/grpc/impl/codegen/sync_generic.h",
     "include/grpc/impl/codegen/sync_posix.h",
-    "include/grpc/impl/codegen/sync_win32.h",
+    "include/grpc/impl/codegen/sync_windows.h",
     "include/grpc/impl/codegen/time.h",
-    "include/grpc++/impl/codegen/config.h",
-    "include/grpc++/impl/codegen/config_protobuf.h",
-    "include/grpc++/support/config.h",
-    "include/grpc++/support/config_protobuf.h",
   ],
   includes = [
     "include",
@@ -1011,84 +1374,19 @@
 
 
 cc_library(
-  name = "grpc++_unsecure",
+  name = "grpc++_reflection",
   srcs = [
-    "src/cpp/client/create_channel_internal.h",
-    "src/cpp/common/core_codegen.h",
-    "src/cpp/server/dynamic_thread_pool.h",
-    "src/cpp/server/thread_pool_interface.h",
-    "src/cpp/common/insecure_create_auth_context.cc",
-    "src/cpp/client/channel.cc",
-    "src/cpp/client/client_context.cc",
-    "src/cpp/client/create_channel.cc",
-    "src/cpp/client/create_channel_internal.cc",
-    "src/cpp/client/credentials.cc",
-    "src/cpp/client/generic_stub.cc",
-    "src/cpp/client/insecure_credentials.cc",
-    "src/cpp/common/channel_arguments.cc",
-    "src/cpp/common/completion_queue.cc",
-    "src/cpp/common/core_codegen.cc",
-    "src/cpp/common/rpc_method.cc",
-    "src/cpp/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_context.cc",
-    "src/cpp/server/server_credentials.cc",
-    "src/cpp/util/byte_buffer.cc",
-    "src/cpp/util/slice.cc",
-    "src/cpp/util/status.cc",
-    "src/cpp/util/string_ref.cc",
-    "src/cpp/util/time.cc",
-    "src/cpp/codegen/codegen_init.cc",
+    "src/cpp/ext/proto_server_reflection.h",
+    "src/cpp/ext/proto_server_reflection.cc",
+    "src/cpp/ext/proto_server_reflection_plugin.cc",
+    "src/cpp/ext/reflection.grpc.pb.cc",
+    "src/cpp/ext/reflection.pb.cc",
   ],
   hdrs = [
-    "include/grpc++/alarm.h",
-    "include/grpc++/channel.h",
-    "include/grpc++/client_context.h",
-    "include/grpc++/completion_queue.h",
-    "include/grpc++/create_channel.h",
-    "include/grpc++/generic/async_generic_service.h",
-    "include/grpc++/generic/generic_stub.h",
-    "include/grpc++/grpc++.h",
-    "include/grpc++/impl/call.h",
-    "include/grpc++/impl/client_unary_call.h",
-    "include/grpc++/impl/grpc_library.h",
-    "include/grpc++/impl/method_handler_impl.h",
-    "include/grpc++/impl/proto_utils.h",
-    "include/grpc++/impl/rpc_method.h",
-    "include/grpc++/impl/rpc_service_method.h",
-    "include/grpc++/impl/serialization_traits.h",
-    "include/grpc++/impl/server_builder_option.h",
-    "include/grpc++/impl/server_builder_plugin.h",
-    "include/grpc++/impl/server_initializer.h",
-    "include/grpc++/impl/service_type.h",
-    "include/grpc++/impl/sync.h",
-    "include/grpc++/impl/sync_cxx11.h",
-    "include/grpc++/impl/sync_no_cxx11.h",
-    "include/grpc++/impl/thd.h",
-    "include/grpc++/impl/thd_cxx11.h",
-    "include/grpc++/impl/thd_no_cxx11.h",
-    "include/grpc++/security/auth_context.h",
-    "include/grpc++/security/auth_metadata_processor.h",
-    "include/grpc++/security/credentials.h",
-    "include/grpc++/security/server_credentials.h",
-    "include/grpc++/server.h",
-    "include/grpc++/server_builder.h",
-    "include/grpc++/server_context.h",
-    "include/grpc++/support/async_stream.h",
-    "include/grpc++/support/async_unary_call.h",
-    "include/grpc++/support/byte_buffer.h",
-    "include/grpc++/support/channel_arguments.h",
-    "include/grpc++/support/slice.h",
-    "include/grpc++/support/status.h",
-    "include/grpc++/support/status_code_enum.h",
-    "include/grpc++/support/string_ref.h",
-    "include/grpc++/support/stub_options.h",
-    "include/grpc++/support/sync_stream.h",
-    "include/grpc++/support/time.h",
+    "include/grpc++/ext/proto_server_reflection_plugin.h",
+    "include/grpc++/ext/reflection.grpc.pb.h",
+    "include/grpc++/ext/reflection.pb.h",
+    "include/grpc++/impl/codegen/proto_utils.h",
     "include/grpc++/impl/codegen/async_stream.h",
     "include/grpc++/impl/codegen/async_unary_call.h",
     "include/grpc++/impl/codegen/call.h",
@@ -1098,11 +1396,11 @@
     "include/grpc++/impl/codegen/client_unary_call.h",
     "include/grpc++/impl/codegen/completion_queue.h",
     "include/grpc++/impl/codegen/completion_queue_tag.h",
+    "include/grpc++/impl/codegen/config.h",
     "include/grpc++/impl/codegen/core_codegen_interface.h",
     "include/grpc++/impl/codegen/create_auth_context.h",
     "include/grpc++/impl/codegen/grpc_library.h",
     "include/grpc++/impl/codegen/method_handler_impl.h",
-    "include/grpc++/impl/codegen/proto_utils.h",
     "include/grpc++/impl/codegen/rpc_method.h",
     "include/grpc++/impl/codegen/rpc_service_method.h",
     "include/grpc++/impl/codegen/security/auth_context.h",
@@ -1130,7 +1428,7 @@
     "include/grpc/impl/codegen/atm.h",
     "include/grpc/impl/codegen/atm_gcc_atomic.h",
     "include/grpc/impl/codegen/atm_gcc_sync.h",
-    "include/grpc/impl/codegen/atm_win32.h",
+    "include/grpc/impl/codegen/atm_windows.h",
     "include/grpc/impl/codegen/log.h",
     "include/grpc/impl/codegen/port_platform.h",
     "include/grpc/impl/codegen/slice.h",
@@ -1138,12 +1436,155 @@
     "include/grpc/impl/codegen/sync.h",
     "include/grpc/impl/codegen/sync_generic.h",
     "include/grpc/impl/codegen/sync_posix.h",
-    "include/grpc/impl/codegen/sync_win32.h",
+    "include/grpc/impl/codegen/sync_windows.h",
     "include/grpc/impl/codegen/time.h",
-    "include/grpc++/impl/codegen/config.h",
     "include/grpc++/impl/codegen/config_protobuf.h",
+  ],
+  includes = [
+    "include",
+    ".",
+  ],
+  deps = [
+    ":grpc++",
+  ],
+)
+
+
+
+cc_library(
+  name = "grpc++_unsecure",
+  srcs = [
+    "src/cpp/client/create_channel_internal.h",
+    "src/cpp/server/dynamic_thread_pool.h",
+    "src/cpp/server/thread_pool_interface.h",
+    "src/cpp/common/insecure_create_auth_context.cc",
+    "src/cpp/client/channel.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/generic_stub.cc",
+    "src/cpp/client/insecure_credentials.cc",
+    "src/cpp/common/channel_arguments.cc",
+    "src/cpp/common/completion_queue.cc",
+    "src/cpp/common/core_codegen.cc",
+    "src/cpp/common/rpc_method.cc",
+    "src/cpp/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_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/status.cc",
+    "src/cpp/util/string_ref.cc",
+    "src/cpp/util/time.cc",
+    "src/cpp/codegen/codegen_init.cc",
+  ],
+  hdrs = [
+    "include/grpc++/alarm.h",
+    "include/grpc++/channel.h",
+    "include/grpc++/client_context.h",
+    "include/grpc++/completion_queue.h",
+    "include/grpc++/create_channel.h",
+    "include/grpc++/create_channel_posix.h",
+    "include/grpc++/generic/async_generic_service.h",
+    "include/grpc++/generic/generic_stub.h",
+    "include/grpc++/grpc++.h",
+    "include/grpc++/impl/call.h",
+    "include/grpc++/impl/client_unary_call.h",
+    "include/grpc++/impl/codegen/core_codegen.h",
+    "include/grpc++/impl/grpc_library.h",
+    "include/grpc++/impl/method_handler_impl.h",
+    "include/grpc++/impl/rpc_method.h",
+    "include/grpc++/impl/rpc_service_method.h",
+    "include/grpc++/impl/serialization_traits.h",
+    "include/grpc++/impl/server_builder_option.h",
+    "include/grpc++/impl/server_builder_plugin.h",
+    "include/grpc++/impl/server_initializer.h",
+    "include/grpc++/impl/service_type.h",
+    "include/grpc++/impl/sync.h",
+    "include/grpc++/impl/sync_cxx11.h",
+    "include/grpc++/impl/sync_no_cxx11.h",
+    "include/grpc++/impl/thd.h",
+    "include/grpc++/impl/thd_cxx11.h",
+    "include/grpc++/impl/thd_no_cxx11.h",
+    "include/grpc++/security/auth_context.h",
+    "include/grpc++/security/auth_metadata_processor.h",
+    "include/grpc++/security/credentials.h",
+    "include/grpc++/security/server_credentials.h",
+    "include/grpc++/server.h",
+    "include/grpc++/server_builder.h",
+    "include/grpc++/server_context.h",
+    "include/grpc++/server_posix.h",
+    "include/grpc++/support/async_stream.h",
+    "include/grpc++/support/async_unary_call.h",
+    "include/grpc++/support/byte_buffer.h",
+    "include/grpc++/support/channel_arguments.h",
     "include/grpc++/support/config.h",
-    "include/grpc++/support/config_protobuf.h",
+    "include/grpc++/support/slice.h",
+    "include/grpc++/support/status.h",
+    "include/grpc++/support/status_code_enum.h",
+    "include/grpc++/support/string_ref.h",
+    "include/grpc++/support/stub_options.h",
+    "include/grpc++/support/sync_stream.h",
+    "include/grpc++/support/time.h",
+    "include/grpc++/impl/codegen/async_stream.h",
+    "include/grpc++/impl/codegen/async_unary_call.h",
+    "include/grpc++/impl/codegen/call.h",
+    "include/grpc++/impl/codegen/call_hook.h",
+    "include/grpc++/impl/codegen/channel_interface.h",
+    "include/grpc++/impl/codegen/client_context.h",
+    "include/grpc++/impl/codegen/client_unary_call.h",
+    "include/grpc++/impl/codegen/completion_queue.h",
+    "include/grpc++/impl/codegen/completion_queue_tag.h",
+    "include/grpc++/impl/codegen/config.h",
+    "include/grpc++/impl/codegen/core_codegen_interface.h",
+    "include/grpc++/impl/codegen/create_auth_context.h",
+    "include/grpc++/impl/codegen/grpc_library.h",
+    "include/grpc++/impl/codegen/method_handler_impl.h",
+    "include/grpc++/impl/codegen/rpc_method.h",
+    "include/grpc++/impl/codegen/rpc_service_method.h",
+    "include/grpc++/impl/codegen/security/auth_context.h",
+    "include/grpc++/impl/codegen/serialization_traits.h",
+    "include/grpc++/impl/codegen/server_context.h",
+    "include/grpc++/impl/codegen/server_interface.h",
+    "include/grpc++/impl/codegen/service_type.h",
+    "include/grpc++/impl/codegen/status.h",
+    "include/grpc++/impl/codegen/status_code_enum.h",
+    "include/grpc++/impl/codegen/string_ref.h",
+    "include/grpc++/impl/codegen/stub_options.h",
+    "include/grpc++/impl/codegen/sync.h",
+    "include/grpc++/impl/codegen/sync_cxx11.h",
+    "include/grpc++/impl/codegen/sync_no_cxx11.h",
+    "include/grpc++/impl/codegen/sync_stream.h",
+    "include/grpc++/impl/codegen/time.h",
+    "include/grpc/impl/codegen/byte_buffer.h",
+    "include/grpc/impl/codegen/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/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",
@@ -1185,9 +1626,6 @@
     "src/compiler/ruby_generator.cc",
   ],
   hdrs = [
-    "include/grpc++/support/config.h",
-    "include/grpc++/support/config_protobuf.h",
-    "include/grpc++/impl/codegen/config.h",
     "include/grpc++/impl/codegen/config_protobuf.h",
   ],
   includes = [
@@ -1236,7 +1674,7 @@
     "src/core/lib/support/cpu_windows.c",
     "src/core/lib/support/env_linux.c",
     "src/core/lib/support/env_posix.c",
-    "src/core/lib/support/env_win32.c",
+    "src/core/lib/support/env_windows.c",
     "src/core/lib/support/histogram.c",
     "src/core/lib/support/host_port.c",
     "src/core/lib/support/load_file.c",
@@ -1244,31 +1682,31 @@
     "src/core/lib/support/log_android.c",
     "src/core/lib/support/log_linux.c",
     "src/core/lib/support/log_posix.c",
-    "src/core/lib/support/log_win32.c",
+    "src/core/lib/support/log_windows.c",
     "src/core/lib/support/murmur_hash.c",
     "src/core/lib/support/slice.c",
     "src/core/lib/support/slice_buffer.c",
     "src/core/lib/support/stack_lockfree.c",
     "src/core/lib/support/string.c",
     "src/core/lib/support/string_posix.c",
-    "src/core/lib/support/string_util_win32.c",
-    "src/core/lib/support/string_win32.c",
+    "src/core/lib/support/string_util_windows.c",
+    "src/core/lib/support/string_windows.c",
     "src/core/lib/support/subprocess_posix.c",
     "src/core/lib/support/subprocess_windows.c",
     "src/core/lib/support/sync.c",
     "src/core/lib/support/sync_posix.c",
-    "src/core/lib/support/sync_win32.c",
+    "src/core/lib/support/sync_windows.c",
     "src/core/lib/support/thd.c",
     "src/core/lib/support/thd_posix.c",
-    "src/core/lib/support/thd_win32.c",
+    "src/core/lib/support/thd_windows.c",
     "src/core/lib/support/time.c",
     "src/core/lib/support/time_posix.c",
     "src/core/lib/support/time_precise.c",
-    "src/core/lib/support/time_win32.c",
+    "src/core/lib/support/time_windows.c",
     "src/core/lib/support/tls_pthread.c",
     "src/core/lib/support/tmpfile_msys.c",
     "src/core/lib/support/tmpfile_posix.c",
-    "src/core/lib/support/tmpfile_win32.c",
+    "src/core/lib/support/tmpfile_windows.c",
     "src/core/lib/support/wrap_memcpy.c",
   ],
   hdrs = [
@@ -1276,14 +1714,14 @@
     "include/grpc/support/atm.h",
     "include/grpc/support/atm_gcc_atomic.h",
     "include/grpc/support/atm_gcc_sync.h",
-    "include/grpc/support/atm_win32.h",
+    "include/grpc/support/atm_windows.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_win32.h",
+    "include/grpc/support/log_windows.h",
     "include/grpc/support/port_platform.h",
     "include/grpc/support/slice.h",
     "include/grpc/support/slice_buffer.h",
@@ -1292,7 +1730,7 @@
     "include/grpc/support/sync.h",
     "include/grpc/support/sync_generic.h",
     "include/grpc/support/sync_posix.h",
-    "include/grpc/support/sync_win32.h",
+    "include/grpc/support/sync_windows.h",
     "include/grpc/support/thd.h",
     "include/grpc/support/time.h",
     "include/grpc/support/tls.h",
@@ -1304,7 +1742,7 @@
     "include/grpc/impl/codegen/atm.h",
     "include/grpc/impl/codegen/atm_gcc_atomic.h",
     "include/grpc/impl/codegen/atm_gcc_sync.h",
-    "include/grpc/impl/codegen/atm_win32.h",
+    "include/grpc/impl/codegen/atm_windows.h",
     "include/grpc/impl/codegen/log.h",
     "include/grpc/impl/codegen/port_platform.h",
     "include/grpc/impl/codegen/slice.h",
@@ -1312,7 +1750,7 @@
     "include/grpc/impl/codegen/sync.h",
     "include/grpc/impl/codegen/sync_generic.h",
     "include/grpc/impl/codegen/sync_posix.h",
-    "include/grpc/impl/codegen/sync_win32.h",
+    "include/grpc/impl/codegen/sync_windows.h",
     "include/grpc/impl/codegen/time.h",
     "src/core/lib/profiling/timers.h",
     "src/core/lib/support/backoff.h",
@@ -1322,7 +1760,7 @@
     "src/core/lib/support/murmur_hash.h",
     "src/core/lib/support/stack_lockfree.h",
     "src/core/lib/support/string.h",
-    "src/core/lib/support/string_win32.h",
+    "src/core/lib/support/string_windows.h",
     "src/core/lib/support/thd_internal.h",
     "src/core/lib/support/time_precise.h",
     "src/core/lib/support/tmpfile.h",
@@ -1348,7 +1786,7 @@
     "src/core/lib/channel/connected_channel.c",
     "src/core/lib/channel/http_client_filter.c",
     "src/core/lib/channel/http_server_filter.c",
-    "src/core/lib/compression/compression_algorithm.c",
+    "src/core/lib/compression/compression.c",
     "src/core/lib/compression/message_compress.c",
     "src/core/lib/debug/trace.c",
     "src/core/lib/http/format_request.c",
@@ -1358,6 +1796,7 @@
     "src/core/lib/iomgr/endpoint.c",
     "src/core/lib/iomgr/endpoint_pair_posix.c",
     "src/core/lib/iomgr/endpoint_pair_windows.c",
+    "src/core/lib/iomgr/ev_poll_and_epoll_posix.c",
     "src/core/lib/iomgr/ev_poll_posix.c",
     "src/core/lib/iomgr/ev_posix.c",
     "src/core/lib/iomgr/exec_ctx.c",
@@ -1366,6 +1805,7 @@
     "src/core/lib/iomgr/iomgr.c",
     "src/core/lib/iomgr/iomgr_posix.c",
     "src/core/lib/iomgr/iomgr_windows.c",
+    "src/core/lib/iomgr/polling_entity.c",
     "src/core/lib/iomgr/pollset_set_windows.c",
     "src/core/lib/iomgr/pollset_windows.c",
     "src/core/lib/iomgr/resolve_address_posix.c",
@@ -1452,7 +1892,7 @@
     "src/core/lib/security/credentials/credentials_metadata.c",
     "src/core/lib/security/credentials/fake/fake_credentials.c",
     "src/core/lib/security/credentials/google_default/credentials_posix.c",
-    "src/core/lib/security/credentials/google_default/credentials_win32.c",
+    "src/core/lib/security/credentials/google_default/credentials_windows.c",
     "src/core/lib/security/credentials/google_default/google_default_credentials.c",
     "src/core/lib/security/credentials/iam/iam_credentials.c",
     "src/core/lib/security/credentials/jwt/json_token.c",
@@ -1493,17 +1933,19 @@
     "src/core/ext/client_config/subchannel_index.c",
     "src/core/ext/client_config/uri_parser.c",
     "src/core/ext/transport/chttp2/server/insecure/server_chttp2.c",
+    "src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.c",
     "src/core/ext/transport/chttp2/client/insecure/channel_create.c",
-    "src/core/ext/transport/cronet/client/secure/cronet_channel_create.c",
-    "src/core/ext/transport/cronet/transport/cronet_api_dummy.c",
-    "src/core/ext/transport/cronet/transport/cronet_transport.c",
+    "src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c",
     "src/core/ext/lb_policy/grpclb/load_balancer_api.c",
     "src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c",
     "src/core/ext/lb_policy/pick_first/pick_first.c",
     "src/core/ext/lb_policy/round_robin/round_robin.c",
     "src/core/ext/resolver/dns/native/dns_resolver.c",
     "src/core/ext/resolver/sockaddr/sockaddr_resolver.c",
+    "src/core/ext/load_reporting/load_reporting.c",
+    "src/core/ext/load_reporting/load_reporting_filter.c",
     "src/core/ext/census/context.c",
+    "src/core/ext/census/gen/census.pb.c",
     "src/core/ext/census/grpc_context.c",
     "src/core/ext/census/grpc_filter.c",
     "src/core/ext/census/grpc_plugin.c",
@@ -1519,6 +1961,7 @@
     "include/grpc/byte_buffer_reader.h",
     "include/grpc/compression.h",
     "include/grpc/grpc.h",
+    "include/grpc/grpc_posix.h",
     "include/grpc/status.h",
     "include/grpc/impl/codegen/byte_buffer.h",
     "include/grpc/impl/codegen/byte_buffer_reader.h",
@@ -1531,7 +1974,7 @@
     "include/grpc/impl/codegen/atm.h",
     "include/grpc/impl/codegen/atm_gcc_atomic.h",
     "include/grpc/impl/codegen/atm_gcc_sync.h",
-    "include/grpc/impl/codegen/atm_win32.h",
+    "include/grpc/impl/codegen/atm_windows.h",
     "include/grpc/impl/codegen/log.h",
     "include/grpc/impl/codegen/port_platform.h",
     "include/grpc/impl/codegen/slice.h",
@@ -1539,9 +1982,8 @@
     "include/grpc/impl/codegen/sync.h",
     "include/grpc/impl/codegen/sync_generic.h",
     "include/grpc/impl/codegen/sync_posix.h",
-    "include/grpc/impl/codegen/sync_win32.h",
+    "include/grpc/impl/codegen/sync_windows.h",
     "include/grpc/impl/codegen/time.h",
-    "include/grpc/grpc_cronet.h",
     "include/grpc/grpc_security.h",
     "include/grpc/grpc_security_constants.h",
     "include/grpc/census.h",
@@ -1562,6 +2004,7 @@
     "src/core/lib/iomgr/closure.h",
     "src/core/lib/iomgr/endpoint.h",
     "src/core/lib/iomgr/endpoint_pair.h",
+    "src/core/lib/iomgr/ev_poll_and_epoll_posix.h",
     "src/core/lib/iomgr/ev_poll_posix.h",
     "src/core/lib/iomgr/ev_posix.h",
     "src/core/lib/iomgr/exec_ctx.h",
@@ -1570,6 +2013,7 @@
     "src/core/lib/iomgr/iomgr.h",
     "src/core/lib/iomgr/iomgr_internal.h",
     "src/core/lib/iomgr/iomgr_posix.h",
+    "src/core/lib/iomgr/polling_entity.h",
     "src/core/lib/iomgr/pollset.h",
     "src/core/lib/iomgr/pollset_set.h",
     "src/core/lib/iomgr/pollset_set_windows.h",
@@ -1578,7 +2022,7 @@
     "src/core/lib/iomgr/sockaddr.h",
     "src/core/lib/iomgr/sockaddr_posix.h",
     "src/core/lib/iomgr/sockaddr_utils.h",
-    "src/core/lib/iomgr/sockaddr_win32.h",
+    "src/core/lib/iomgr/sockaddr_windows.h",
     "src/core/lib/iomgr/socket_utils_posix.h",
     "src/core/lib/iomgr/socket_windows.h",
     "src/core/lib/iomgr/tcp_client.h",
@@ -1678,12 +2122,14 @@
     "src/core/ext/client_config/subchannel_call_holder.h",
     "src/core/ext/client_config/subchannel_index.h",
     "src/core/ext/client_config/uri_parser.h",
-    "third_party/objective_c/Cronet/cronet_c_for_grpc.h",
     "src/core/ext/lb_policy/grpclb/load_balancer_api.h",
     "src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h",
+    "src/core/ext/load_reporting/load_reporting.h",
+    "src/core/ext/load_reporting/load_reporting_filter.h",
     "src/core/ext/census/aggregation.h",
     "src/core/ext/census/census_interface.h",
     "src/core/ext/census/census_rpc_stats.h",
+    "src/core/ext/census/gen/census.pb.h",
     "src/core/ext/census/grpc_filter.h",
     "src/core/ext/census/mlog.h",
     "src/core/ext/census/rpc_metric_id.h",
diff --git a/Makefile b/Makefile
index b4c6986..da841af 100644
--- a/Makefile
+++ b/Makefile
@@ -1030,6 +1030,7 @@
 json_run_localhost: $(BINDIR)/$(CONFIG)/json_run_localhost
 metrics_client: $(BINDIR)/$(CONFIG)/metrics_client
 mock_test: $(BINDIR)/$(CONFIG)/mock_test
+proto_server_reflection_test: $(BINDIR)/$(CONFIG)/proto_server_reflection_test
 qps_interarrival_test: $(BINDIR)/$(CONFIG)/qps_interarrival_test
 qps_json_driver: $(BINDIR)/$(CONFIG)/qps_json_driver
 qps_openloop_test: $(BINDIR)/$(CONFIG)/qps_openloop_test
@@ -1103,9 +1104,11 @@
 h2_census_test: $(BINDIR)/$(CONFIG)/h2_census_test
 h2_compress_test: $(BINDIR)/$(CONFIG)/h2_compress_test
 h2_fakesec_test: $(BINDIR)/$(CONFIG)/h2_fakesec_test
+h2_fd_test: $(BINDIR)/$(CONFIG)/h2_fd_test
 h2_full_test: $(BINDIR)/$(CONFIG)/h2_full_test
 h2_full+pipe_test: $(BINDIR)/$(CONFIG)/h2_full+pipe_test
 h2_full+trace_test: $(BINDIR)/$(CONFIG)/h2_full+trace_test
+h2_loadreporting_test: $(BINDIR)/$(CONFIG)/h2_loadreporting_test
 h2_oauth2_test: $(BINDIR)/$(CONFIG)/h2_oauth2_test
 h2_proxy_test: $(BINDIR)/$(CONFIG)/h2_proxy_test
 h2_sockpair_test: $(BINDIR)/$(CONFIG)/h2_sockpair_test
@@ -1117,9 +1120,11 @@
 h2_uds_test: $(BINDIR)/$(CONFIG)/h2_uds_test
 h2_census_nosec_test: $(BINDIR)/$(CONFIG)/h2_census_nosec_test
 h2_compress_nosec_test: $(BINDIR)/$(CONFIG)/h2_compress_nosec_test
+h2_fd_nosec_test: $(BINDIR)/$(CONFIG)/h2_fd_nosec_test
 h2_full_nosec_test: $(BINDIR)/$(CONFIG)/h2_full_nosec_test
 h2_full+pipe_nosec_test: $(BINDIR)/$(CONFIG)/h2_full+pipe_nosec_test
 h2_full+trace_nosec_test: $(BINDIR)/$(CONFIG)/h2_full+trace_nosec_test
+h2_loadreporting_nosec_test: $(BINDIR)/$(CONFIG)/h2_loadreporting_nosec_test
 h2_proxy_nosec_test: $(BINDIR)/$(CONFIG)/h2_proxy_nosec_test
 h2_sockpair_nosec_test: $(BINDIR)/$(CONFIG)/h2_sockpair_nosec_test
 h2_sockpair+trace_nosec_test: $(BINDIR)/$(CONFIG)/h2_sockpair+trace_nosec_test
@@ -1161,16 +1166,16 @@
 
 static: static_c static_cxx
 
-static_c: pc_c pc_c_unsecure cache.mk pc_c_zookeeper $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a static_zookeeper_libs
+static_c: pc_c pc_c_unsecure cache.mk pc_c_zookeeper $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgrpc_cronet.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a static_zookeeper_libs
 
 
-static_cxx: pc_cxx pc_cxx_unsecure cache.mk  $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a
+static_cxx: pc_cxx pc_cxx_unsecure cache.mk  $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a
 
 shared: shared_c shared_cxx
 
-shared_c: pc_c pc_c_unsecure cache.mk pc_c_zookeeper $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)gpr$(SHARED_VERSION).$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc$(SHARED_VERSION).$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc_unsecure$(SHARED_VERSION).$(SHARED_EXT) shared_zookeeper_libs
+shared_c: pc_c pc_c_unsecure cache.mk pc_c_zookeeper $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)gpr$(SHARED_VERSION).$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc$(SHARED_VERSION).$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc_cronet$(SHARED_VERSION).$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc_unsecure$(SHARED_VERSION).$(SHARED_EXT) shared_zookeeper_libs
 
-shared_cxx: pc_cxx pc_cxx_unsecure cache.mk $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++$(SHARED_VERSION).$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION).$(SHARED_EXT)
+shared_cxx: pc_cxx pc_cxx_unsecure cache.mk $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++$(SHARED_VERSION).$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION).$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION).$(SHARED_EXT)
 
 shared_csharp: shared_c  $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc_csharp_ext$(SHARED_VERSION).$(SHARED_EXT)
 ifeq ($(HAS_ZOOKEEPER),true)
@@ -1205,7 +1210,7 @@
 
 pc_cxx_unsecure: $(LIBDIR)/$(CONFIG)/pkgconfig/grpc++_unsecure.pc
 
-privatelibs_cxx:  $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libinterop_client_helper.a $(LIBDIR)/$(CONFIG)/libinterop_client_main.a $(LIBDIR)/$(CONFIG)/libinterop_server_helper.a $(LIBDIR)/$(CONFIG)/libinterop_server_main.a $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl_aes_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_asn1_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_base64_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_bio_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_bn_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_bytestring_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_aead_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_cipher_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_cmac_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ed25519_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_x25519_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_dh_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_digest_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ec_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ecdsa_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_err_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_evp_extra_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_evp_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_pbkdf_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_hmac_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_pkcs12_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_pkcs8_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_poly1305_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_rsa_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_x509_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ssl_test_lib.a
+privatelibs_cxx:  $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libinterop_client_helper.a $(LIBDIR)/$(CONFIG)/libinterop_client_main.a $(LIBDIR)/$(CONFIG)/libinterop_server_helper.a $(LIBDIR)/$(CONFIG)/libinterop_server_main.a $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libboringssl_test_util.a $(LIBDIR)/$(CONFIG)/libboringssl_aes_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_asn1_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_base64_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_bio_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_bn_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_bytestring_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_aead_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_cipher_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_cmac_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ed25519_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_x25519_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_dh_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_digest_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ec_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ecdsa_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_err_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_evp_extra_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_evp_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_pbkdf_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_hmac_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_pkcs12_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_pkcs8_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_poly1305_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_rsa_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_x509_test_lib.a $(LIBDIR)/$(CONFIG)/libboringssl_ssl_test_lib.a
 
 ifeq ($(HAS_ZOOKEEPER),true)
 privatelibs_zookeeper: 
@@ -1333,9 +1338,11 @@
   $(BINDIR)/$(CONFIG)/h2_census_test \
   $(BINDIR)/$(CONFIG)/h2_compress_test \
   $(BINDIR)/$(CONFIG)/h2_fakesec_test \
+  $(BINDIR)/$(CONFIG)/h2_fd_test \
   $(BINDIR)/$(CONFIG)/h2_full_test \
   $(BINDIR)/$(CONFIG)/h2_full+pipe_test \
   $(BINDIR)/$(CONFIG)/h2_full+trace_test \
+  $(BINDIR)/$(CONFIG)/h2_loadreporting_test \
   $(BINDIR)/$(CONFIG)/h2_oauth2_test \
   $(BINDIR)/$(CONFIG)/h2_proxy_test \
   $(BINDIR)/$(CONFIG)/h2_sockpair_test \
@@ -1347,9 +1354,11 @@
   $(BINDIR)/$(CONFIG)/h2_uds_test \
   $(BINDIR)/$(CONFIG)/h2_census_nosec_test \
   $(BINDIR)/$(CONFIG)/h2_compress_nosec_test \
+  $(BINDIR)/$(CONFIG)/h2_fd_nosec_test \
   $(BINDIR)/$(CONFIG)/h2_full_nosec_test \
   $(BINDIR)/$(CONFIG)/h2_full+pipe_nosec_test \
   $(BINDIR)/$(CONFIG)/h2_full+trace_nosec_test \
+  $(BINDIR)/$(CONFIG)/h2_loadreporting_nosec_test \
   $(BINDIR)/$(CONFIG)/h2_proxy_nosec_test \
   $(BINDIR)/$(CONFIG)/h2_sockpair_nosec_test \
   $(BINDIR)/$(CONFIG)/h2_sockpair+trace_nosec_test \
@@ -1393,6 +1402,7 @@
   $(BINDIR)/$(CONFIG)/json_run_localhost \
   $(BINDIR)/$(CONFIG)/metrics_client \
   $(BINDIR)/$(CONFIG)/mock_test \
+  $(BINDIR)/$(CONFIG)/proto_server_reflection_test \
   $(BINDIR)/$(CONFIG)/qps_interarrival_test \
   $(BINDIR)/$(CONFIG)/qps_json_driver \
   $(BINDIR)/$(CONFIG)/qps_openloop_test \
@@ -1719,6 +1729,8 @@
 	$(Q) $(BINDIR)/$(CONFIG)/interop_test || ( echo test interop_test failed ; exit 1 )
 	$(E) "[RUN]     Testing mock_test"
 	$(Q) $(BINDIR)/$(CONFIG)/mock_test || ( echo test mock_test failed ; exit 1 )
+	$(E) "[RUN]     Testing proto_server_reflection_test"
+	$(Q) $(BINDIR)/$(CONFIG)/proto_server_reflection_test || ( echo test proto_server_reflection_test failed ; exit 1 )
 	$(E) "[RUN]     Testing qps_openloop_test"
 	$(Q) $(BINDIR)/$(CONFIG)/qps_openloop_test || ( echo test qps_openloop_test failed ; exit 1 )
 	$(E) "[RUN]     Testing secure_auth_context_test"
@@ -1787,6 +1799,8 @@
 	$(Q) $(STRIP) $(LIBDIR)/$(CONFIG)/libgpr.a
 	$(E) "[STRIP]   Stripping libgrpc.a"
 	$(Q) $(STRIP) $(LIBDIR)/$(CONFIG)/libgrpc.a
+	$(E) "[STRIP]   Stripping libgrpc_cronet.a"
+	$(Q) $(STRIP) $(LIBDIR)/$(CONFIG)/libgrpc_cronet.a
 	$(E) "[STRIP]   Stripping libgrpc_unsecure.a"
 	$(Q) $(STRIP) $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a
 ifeq ($(HAS_ZOOKEEPER),true)
@@ -1799,6 +1813,8 @@
 ifeq ($(CONFIG),opt)
 	$(E) "[STRIP]   Stripping libgrpc++.a"
 	$(Q) $(STRIP) $(LIBDIR)/$(CONFIG)/libgrpc++.a
+	$(E) "[STRIP]   Stripping libgrpc++_reflection.a"
+	$(Q) $(STRIP) $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a
 	$(E) "[STRIP]   Stripping libgrpc++_unsecure.a"
 	$(Q) $(STRIP) $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a
 endif
@@ -1809,6 +1825,8 @@
 	$(Q) $(STRIP) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)gpr$(SHARED_VERSION).$(SHARED_EXT)
 	$(E) "[STRIP]   Stripping $(SHARED_PREFIX)grpc$(SHARED_VERSION).$(SHARED_EXT)"
 	$(Q) $(STRIP) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc$(SHARED_VERSION).$(SHARED_EXT)
+	$(E) "[STRIP]   Stripping $(SHARED_PREFIX)grpc_cronet$(SHARED_VERSION).$(SHARED_EXT)"
+	$(Q) $(STRIP) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc_cronet$(SHARED_VERSION).$(SHARED_EXT)
 	$(E) "[STRIP]   Stripping $(SHARED_PREFIX)grpc_unsecure$(SHARED_VERSION).$(SHARED_EXT)"
 	$(Q) $(STRIP) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc_unsecure$(SHARED_VERSION).$(SHARED_EXT)
 ifeq ($(HAS_ZOOKEEPER),true)
@@ -1821,6 +1839,8 @@
 ifeq ($(CONFIG),opt)
 	$(E) "[STRIP]   Stripping $(SHARED_PREFIX)grpc++$(SHARED_VERSION).$(SHARED_EXT)"
 	$(Q) $(STRIP) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++$(SHARED_VERSION).$(SHARED_EXT)
+	$(E) "[STRIP]   Stripping $(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION).$(SHARED_EXT)"
+	$(Q) $(STRIP) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION).$(SHARED_EXT)
 	$(E) "[STRIP]   Stripping $(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION).$(SHARED_EXT)"
 	$(Q) $(STRIP) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION).$(SHARED_EXT)
 endif
@@ -1848,7 +1868,7 @@
 $(LIBDIR)/$(CONFIG)/pkgconfig/grpc_zookeeper.pc:
 	$(E) "[MAKE]    Generating $@"
 	$(Q) mkdir -p $(@D)
-	$(Q) echo -e "$(GRPC_ZOOKEEPER_PC_FILE)" >$@
+	$(Q) echo "$(GRPC_ZOOKEEPER_PC_FILE)" | tr , '\n' >$@
 
 $(LIBDIR)/$(CONFIG)/pkgconfig/grpc++.pc:
 	$(E) "[MAKE]    Generating $@"
@@ -2011,21 +2031,6 @@
 endif
 
 ifeq ($(NO_PROTOC),true)
-$(GENDIR)/src/proto/grpc/testing/perf_db.pb.cc: protoc_dep_error
-$(GENDIR)/src/proto/grpc/testing/perf_db.grpc.pb.cc: protoc_dep_error
-else
-$(GENDIR)/src/proto/grpc/testing/perf_db.pb.cc: src/proto/grpc/testing/perf_db.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/control.pb.cc
-	$(E) "[PROTOC]  Generating protobuf CC file from $<"
-	$(Q) mkdir -p `dirname $@`
-	$(Q) $(PROTOC) --cpp_out=$(GENDIR) $<
-
-$(GENDIR)/src/proto/grpc/testing/perf_db.grpc.pb.cc: src/proto/grpc/testing/perf_db.proto $(PROTOBUF_DEP) $(PROTOC_PLUGINS) $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc
-	$(E) "[GRPC]    Generating gRPC's protobuf service CC file from $<"
-	$(Q) mkdir -p `dirname $@`
-	$(Q) $(PROTOC) --grpc_out=$(GENDIR) --plugin=protoc-gen-grpc=$(BINDIR)/$(CONFIG)/grpc_cpp_plugin $<
-endif
-
-ifeq ($(NO_PROTOC),true)
 $(GENDIR)/src/proto/grpc/testing/services.pb.cc: protoc_dep_error
 $(GENDIR)/src/proto/grpc/testing/services.grpc.pb.cc: protoc_dep_error
 else
@@ -2134,6 +2139,9 @@
 	$(E) "[INSTALL] Installing libgrpc.a"
 	$(Q) $(INSTALL) -d $(prefix)/lib
 	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc.a $(prefix)/lib/libgrpc.a
+	$(E) "[INSTALL] Installing libgrpc_cronet.a"
+	$(Q) $(INSTALL) -d $(prefix)/lib
+	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc_cronet.a $(prefix)/lib/libgrpc_cronet.a
 	$(E) "[INSTALL] Installing libgrpc_unsecure.a"
 	$(Q) $(INSTALL) -d $(prefix)/lib
 	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(prefix)/lib/libgrpc_unsecure.a
@@ -2147,6 +2155,9 @@
 	$(E) "[INSTALL] Installing libgrpc++.a"
 	$(Q) $(INSTALL) -d $(prefix)/lib
 	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc++.a $(prefix)/lib/libgrpc++.a
+	$(E) "[INSTALL] Installing libgrpc++_reflection.a"
+	$(Q) $(INSTALL) -d $(prefix)/lib
+	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(prefix)/lib/libgrpc++_reflection.a
 	$(E) "[INSTALL] Installing libgrpc++_unsecure.a"
 	$(Q) $(INSTALL) -d $(prefix)/lib
 	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(prefix)/lib/libgrpc++_unsecure.a
@@ -2172,6 +2183,15 @@
 	$(Q) ln -sf $(SHARED_PREFIX)grpc$(SHARED_VERSION).$(SHARED_EXT) $(prefix)/lib/libgrpc.so.0
 	$(Q) ln -sf $(SHARED_PREFIX)grpc$(SHARED_VERSION).$(SHARED_EXT) $(prefix)/lib/libgrpc.so
 endif
+	$(E) "[INSTALL] Installing $(SHARED_PREFIX)grpc_cronet$(SHARED_VERSION).$(SHARED_EXT)"
+	$(Q) $(INSTALL) -d $(prefix)/lib
+	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc_cronet$(SHARED_VERSION).$(SHARED_EXT) $(prefix)/lib/$(SHARED_PREFIX)grpc_cronet$(SHARED_VERSION).$(SHARED_EXT)
+ifeq ($(SYSTEM),MINGW32)
+	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc_cronet-imp.a $(prefix)/lib/libgrpc_cronet-imp.a
+else ifneq ($(SYSTEM),Darwin)
+	$(Q) ln -sf $(SHARED_PREFIX)grpc_cronet$(SHARED_VERSION).$(SHARED_EXT) $(prefix)/lib/libgrpc_cronet.so.0
+	$(Q) ln -sf $(SHARED_PREFIX)grpc_cronet$(SHARED_VERSION).$(SHARED_EXT) $(prefix)/lib/libgrpc_cronet.so
+endif
 	$(E) "[INSTALL] Installing $(SHARED_PREFIX)grpc_unsecure$(SHARED_VERSION).$(SHARED_EXT)"
 	$(Q) $(INSTALL) -d $(prefix)/lib
 	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc_unsecure$(SHARED_VERSION).$(SHARED_EXT) $(prefix)/lib/$(SHARED_PREFIX)grpc_unsecure$(SHARED_VERSION).$(SHARED_EXT)
@@ -2209,6 +2229,15 @@
 	$(Q) ln -sf $(SHARED_PREFIX)grpc++$(SHARED_VERSION).$(SHARED_EXT) $(prefix)/lib/libgrpc++.so.0
 	$(Q) ln -sf $(SHARED_PREFIX)grpc++$(SHARED_VERSION).$(SHARED_EXT) $(prefix)/lib/libgrpc++.so
 endif
+	$(E) "[INSTALL] Installing $(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION).$(SHARED_EXT)"
+	$(Q) $(INSTALL) -d $(prefix)/lib
+	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION).$(SHARED_EXT) $(prefix)/lib/$(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION).$(SHARED_EXT)
+ifeq ($(SYSTEM),MINGW32)
+	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc++_reflection-imp.a $(prefix)/lib/libgrpc++_reflection-imp.a
+else ifneq ($(SYSTEM),Darwin)
+	$(Q) ln -sf $(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION).$(SHARED_EXT) $(prefix)/lib/libgrpc++_reflection.so.0
+	$(Q) ln -sf $(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION).$(SHARED_EXT) $(prefix)/lib/libgrpc++_reflection.so
+endif
 	$(E) "[INSTALL] Installing $(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION).$(SHARED_EXT)"
 	$(Q) $(INSTALL) -d $(prefix)/lib
 	$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION).$(SHARED_EXT) $(prefix)/lib/$(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION).$(SHARED_EXT)
@@ -2290,17 +2319,19 @@
 	@echo "Your system looks ready to go."
 	@echo
 else
-	@echo "We couldn't find protoc 3.0.0+ installed on your system. While this"
-	@echo "won't prevent grpc from working, you won't be able to compile"
-	@echo "and run any meaningful code with it."
+	@echo "Warning: it looks like protoc 3.0.0+ isn't installed on your system,"
+	@echo "which means that you won't be able to compile .proto files for use"
+	@echo "with gRPC."
 	@echo
+	@echo "If you are just using pre-compiled protocol buffers, or you otherwise"
+	@echo "have no need to compile .proto files, you can ignore this."
 	@echo
-	@echo "Please download and install protobuf 3.0.0+ from:"
+	@echo "If you do need protobuf for some reason, you can download and install"
+	@echo "it from:"
 	@echo
 	@echo "   https://github.com/google/protobuf/releases"
 	@echo
-	@echo "Once you've done so, or if you think this message is in error,"
-	@echo "you can re-run this check by doing:"
+	@echo "Once you've done so, you can re-run this check by doing:"
 	@echo
 	@echo "   make verify-install"
 endif
@@ -2326,7 +2357,7 @@
     src/core/lib/support/cpu_windows.c \
     src/core/lib/support/env_linux.c \
     src/core/lib/support/env_posix.c \
-    src/core/lib/support/env_win32.c \
+    src/core/lib/support/env_windows.c \
     src/core/lib/support/histogram.c \
     src/core/lib/support/host_port.c \
     src/core/lib/support/load_file.c \
@@ -2334,31 +2365,31 @@
     src/core/lib/support/log_android.c \
     src/core/lib/support/log_linux.c \
     src/core/lib/support/log_posix.c \
-    src/core/lib/support/log_win32.c \
+    src/core/lib/support/log_windows.c \
     src/core/lib/support/murmur_hash.c \
     src/core/lib/support/slice.c \
     src/core/lib/support/slice_buffer.c \
     src/core/lib/support/stack_lockfree.c \
     src/core/lib/support/string.c \
     src/core/lib/support/string_posix.c \
-    src/core/lib/support/string_util_win32.c \
-    src/core/lib/support/string_win32.c \
+    src/core/lib/support/string_util_windows.c \
+    src/core/lib/support/string_windows.c \
     src/core/lib/support/subprocess_posix.c \
     src/core/lib/support/subprocess_windows.c \
     src/core/lib/support/sync.c \
     src/core/lib/support/sync_posix.c \
-    src/core/lib/support/sync_win32.c \
+    src/core/lib/support/sync_windows.c \
     src/core/lib/support/thd.c \
     src/core/lib/support/thd_posix.c \
-    src/core/lib/support/thd_win32.c \
+    src/core/lib/support/thd_windows.c \
     src/core/lib/support/time.c \
     src/core/lib/support/time_posix.c \
     src/core/lib/support/time_precise.c \
-    src/core/lib/support/time_win32.c \
+    src/core/lib/support/time_windows.c \
     src/core/lib/support/tls_pthread.c \
     src/core/lib/support/tmpfile_msys.c \
     src/core/lib/support/tmpfile_posix.c \
-    src/core/lib/support/tmpfile_win32.c \
+    src/core/lib/support/tmpfile_windows.c \
     src/core/lib/support/wrap_memcpy.c \
 
 PUBLIC_HEADERS_C += \
@@ -2366,14 +2397,14 @@
     include/grpc/support/atm.h \
     include/grpc/support/atm_gcc_atomic.h \
     include/grpc/support/atm_gcc_sync.h \
-    include/grpc/support/atm_win32.h \
+    include/grpc/support/atm_windows.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_win32.h \
+    include/grpc/support/log_windows.h \
     include/grpc/support/port_platform.h \
     include/grpc/support/slice.h \
     include/grpc/support/slice_buffer.h \
@@ -2382,7 +2413,7 @@
     include/grpc/support/sync.h \
     include/grpc/support/sync_generic.h \
     include/grpc/support/sync_posix.h \
-    include/grpc/support/sync_win32.h \
+    include/grpc/support/sync_windows.h \
     include/grpc/support/thd.h \
     include/grpc/support/time.h \
     include/grpc/support/tls.h \
@@ -2394,7 +2425,7 @@
     include/grpc/impl/codegen/atm.h \
     include/grpc/impl/codegen/atm_gcc_atomic.h \
     include/grpc/impl/codegen/atm_gcc_sync.h \
-    include/grpc/impl/codegen/atm_win32.h \
+    include/grpc/impl/codegen/atm_windows.h \
     include/grpc/impl/codegen/log.h \
     include/grpc/impl/codegen/port_platform.h \
     include/grpc/impl/codegen/slice.h \
@@ -2402,7 +2433,7 @@
     include/grpc/impl/codegen/sync.h \
     include/grpc/impl/codegen/sync_generic.h \
     include/grpc/impl/codegen/sync_posix.h \
-    include/grpc/impl/codegen/sync_win32.h \
+    include/grpc/impl/codegen/sync_windows.h \
     include/grpc/impl/codegen/time.h \
 
 LIBGPR_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGPR_SRC))))
@@ -2476,7 +2507,7 @@
     src/core/lib/channel/connected_channel.c \
     src/core/lib/channel/http_client_filter.c \
     src/core/lib/channel/http_server_filter.c \
-    src/core/lib/compression/compression_algorithm.c \
+    src/core/lib/compression/compression.c \
     src/core/lib/compression/message_compress.c \
     src/core/lib/debug/trace.c \
     src/core/lib/http/format_request.c \
@@ -2486,6 +2517,7 @@
     src/core/lib/iomgr/endpoint.c \
     src/core/lib/iomgr/endpoint_pair_posix.c \
     src/core/lib/iomgr/endpoint_pair_windows.c \
+    src/core/lib/iomgr/ev_poll_and_epoll_posix.c \
     src/core/lib/iomgr/ev_poll_posix.c \
     src/core/lib/iomgr/ev_posix.c \
     src/core/lib/iomgr/exec_ctx.c \
@@ -2494,6 +2526,7 @@
     src/core/lib/iomgr/iomgr.c \
     src/core/lib/iomgr/iomgr_posix.c \
     src/core/lib/iomgr/iomgr_windows.c \
+    src/core/lib/iomgr/polling_entity.c \
     src/core/lib/iomgr/pollset_set_windows.c \
     src/core/lib/iomgr/pollset_windows.c \
     src/core/lib/iomgr/resolve_address_posix.c \
@@ -2580,7 +2613,7 @@
     src/core/lib/security/credentials/credentials_metadata.c \
     src/core/lib/security/credentials/fake/fake_credentials.c \
     src/core/lib/security/credentials/google_default/credentials_posix.c \
-    src/core/lib/security/credentials/google_default/credentials_win32.c \
+    src/core/lib/security/credentials/google_default/credentials_windows.c \
     src/core/lib/security/credentials/google_default/google_default_credentials.c \
     src/core/lib/security/credentials/iam/iam_credentials.c \
     src/core/lib/security/credentials/jwt/json_token.c \
@@ -2621,10 +2654,9 @@
     src/core/ext/client_config/subchannel_index.c \
     src/core/ext/client_config/uri_parser.c \
     src/core/ext/transport/chttp2/server/insecure/server_chttp2.c \
+    src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.c \
     src/core/ext/transport/chttp2/client/insecure/channel_create.c \
-    src/core/ext/transport/cronet/client/secure/cronet_channel_create.c \
-    src/core/ext/transport/cronet/transport/cronet_api_dummy.c \
-    src/core/ext/transport/cronet/transport/cronet_transport.c \
+    src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c \
     src/core/ext/lb_policy/grpclb/load_balancer_api.c \
     src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c \
     third_party/nanopb/pb_common.c \
@@ -2634,7 +2666,10 @@
     src/core/ext/lb_policy/round_robin/round_robin.c \
     src/core/ext/resolver/dns/native/dns_resolver.c \
     src/core/ext/resolver/sockaddr/sockaddr_resolver.c \
+    src/core/ext/load_reporting/load_reporting.c \
+    src/core/ext/load_reporting/load_reporting_filter.c \
     src/core/ext/census/context.c \
+    src/core/ext/census/gen/census.pb.c \
     src/core/ext/census/grpc_context.c \
     src/core/ext/census/grpc_filter.c \
     src/core/ext/census/grpc_plugin.c \
@@ -2650,6 +2685,7 @@
     include/grpc/byte_buffer_reader.h \
     include/grpc/compression.h \
     include/grpc/grpc.h \
+    include/grpc/grpc_posix.h \
     include/grpc/status.h \
     include/grpc/impl/codegen/byte_buffer.h \
     include/grpc/impl/codegen/byte_buffer_reader.h \
@@ -2662,7 +2698,7 @@
     include/grpc/impl/codegen/atm.h \
     include/grpc/impl/codegen/atm_gcc_atomic.h \
     include/grpc/impl/codegen/atm_gcc_sync.h \
-    include/grpc/impl/codegen/atm_win32.h \
+    include/grpc/impl/codegen/atm_windows.h \
     include/grpc/impl/codegen/log.h \
     include/grpc/impl/codegen/port_platform.h \
     include/grpc/impl/codegen/slice.h \
@@ -2670,9 +2706,8 @@
     include/grpc/impl/codegen/sync.h \
     include/grpc/impl/codegen/sync_generic.h \
     include/grpc/impl/codegen/sync_posix.h \
-    include/grpc/impl/codegen/sync_win32.h \
+    include/grpc/impl/codegen/sync_windows.h \
     include/grpc/impl/codegen/time.h \
-    include/grpc/grpc_cronet.h \
     include/grpc/grpc_security.h \
     include/grpc/grpc_security_constants.h \
     include/grpc/census.h \
@@ -2729,6 +2764,249 @@
 endif
 
 
+LIBGRPC_CRONET_SRC = \
+    src/core/lib/surface/init.c \
+    src/core/lib/channel/channel_args.c \
+    src/core/lib/channel/channel_stack.c \
+    src/core/lib/channel/channel_stack_builder.c \
+    src/core/lib/channel/compress_filter.c \
+    src/core/lib/channel/connected_channel.c \
+    src/core/lib/channel/http_client_filter.c \
+    src/core/lib/channel/http_server_filter.c \
+    src/core/lib/compression/compression.c \
+    src/core/lib/compression/message_compress.c \
+    src/core/lib/debug/trace.c \
+    src/core/lib/http/format_request.c \
+    src/core/lib/http/httpcli.c \
+    src/core/lib/http/parser.c \
+    src/core/lib/iomgr/closure.c \
+    src/core/lib/iomgr/endpoint.c \
+    src/core/lib/iomgr/endpoint_pair_posix.c \
+    src/core/lib/iomgr/endpoint_pair_windows.c \
+    src/core/lib/iomgr/ev_poll_and_epoll_posix.c \
+    src/core/lib/iomgr/ev_poll_posix.c \
+    src/core/lib/iomgr/ev_posix.c \
+    src/core/lib/iomgr/exec_ctx.c \
+    src/core/lib/iomgr/executor.c \
+    src/core/lib/iomgr/iocp_windows.c \
+    src/core/lib/iomgr/iomgr.c \
+    src/core/lib/iomgr/iomgr_posix.c \
+    src/core/lib/iomgr/iomgr_windows.c \
+    src/core/lib/iomgr/polling_entity.c \
+    src/core/lib/iomgr/pollset_set_windows.c \
+    src/core/lib/iomgr/pollset_windows.c \
+    src/core/lib/iomgr/resolve_address_posix.c \
+    src/core/lib/iomgr/resolve_address_windows.c \
+    src/core/lib/iomgr/sockaddr_utils.c \
+    src/core/lib/iomgr/socket_utils_common_posix.c \
+    src/core/lib/iomgr/socket_utils_linux.c \
+    src/core/lib/iomgr/socket_utils_posix.c \
+    src/core/lib/iomgr/socket_windows.c \
+    src/core/lib/iomgr/tcp_client_posix.c \
+    src/core/lib/iomgr/tcp_client_windows.c \
+    src/core/lib/iomgr/tcp_posix.c \
+    src/core/lib/iomgr/tcp_server_posix.c \
+    src/core/lib/iomgr/tcp_server_windows.c \
+    src/core/lib/iomgr/tcp_windows.c \
+    src/core/lib/iomgr/time_averaged_stats.c \
+    src/core/lib/iomgr/timer.c \
+    src/core/lib/iomgr/timer_heap.c \
+    src/core/lib/iomgr/udp_server.c \
+    src/core/lib/iomgr/unix_sockets_posix.c \
+    src/core/lib/iomgr/unix_sockets_posix_noop.c \
+    src/core/lib/iomgr/wakeup_fd_eventfd.c \
+    src/core/lib/iomgr/wakeup_fd_nospecial.c \
+    src/core/lib/iomgr/wakeup_fd_pipe.c \
+    src/core/lib/iomgr/wakeup_fd_posix.c \
+    src/core/lib/iomgr/workqueue_posix.c \
+    src/core/lib/iomgr/workqueue_windows.c \
+    src/core/lib/json/json.c \
+    src/core/lib/json/json_reader.c \
+    src/core/lib/json/json_string.c \
+    src/core/lib/json/json_writer.c \
+    src/core/lib/surface/alarm.c \
+    src/core/lib/surface/api_trace.c \
+    src/core/lib/surface/byte_buffer.c \
+    src/core/lib/surface/byte_buffer_reader.c \
+    src/core/lib/surface/call.c \
+    src/core/lib/surface/call_details.c \
+    src/core/lib/surface/call_log_batch.c \
+    src/core/lib/surface/channel.c \
+    src/core/lib/surface/channel_init.c \
+    src/core/lib/surface/channel_ping.c \
+    src/core/lib/surface/channel_stack_type.c \
+    src/core/lib/surface/completion_queue.c \
+    src/core/lib/surface/event_string.c \
+    src/core/lib/surface/lame_client.c \
+    src/core/lib/surface/metadata_array.c \
+    src/core/lib/surface/server.c \
+    src/core/lib/surface/validate_metadata.c \
+    src/core/lib/surface/version.c \
+    src/core/lib/transport/byte_stream.c \
+    src/core/lib/transport/connectivity_state.c \
+    src/core/lib/transport/metadata.c \
+    src/core/lib/transport/metadata_batch.c \
+    src/core/lib/transport/static_metadata.c \
+    src/core/lib/transport/transport.c \
+    src/core/lib/transport/transport_op_string.c \
+    src/core/ext/transport/cronet/client/secure/cronet_channel_create.c \
+    src/core/ext/transport/cronet/transport/cronet_api_dummy.c \
+    src/core/ext/transport/cronet/transport/cronet_transport.c \
+    src/core/ext/transport/chttp2/client/secure/secure_channel_create.c \
+    src/core/ext/transport/chttp2/transport/bin_encoder.c \
+    src/core/ext/transport/chttp2/transport/chttp2_plugin.c \
+    src/core/ext/transport/chttp2/transport/chttp2_transport.c \
+    src/core/ext/transport/chttp2/transport/frame_data.c \
+    src/core/ext/transport/chttp2/transport/frame_goaway.c \
+    src/core/ext/transport/chttp2/transport/frame_ping.c \
+    src/core/ext/transport/chttp2/transport/frame_rst_stream.c \
+    src/core/ext/transport/chttp2/transport/frame_settings.c \
+    src/core/ext/transport/chttp2/transport/frame_window_update.c \
+    src/core/ext/transport/chttp2/transport/hpack_encoder.c \
+    src/core/ext/transport/chttp2/transport/hpack_parser.c \
+    src/core/ext/transport/chttp2/transport/hpack_table.c \
+    src/core/ext/transport/chttp2/transport/huffsyms.c \
+    src/core/ext/transport/chttp2/transport/incoming_metadata.c \
+    src/core/ext/transport/chttp2/transport/parsing.c \
+    src/core/ext/transport/chttp2/transport/status_conversion.c \
+    src/core/ext/transport/chttp2/transport/stream_lists.c \
+    src/core/ext/transport/chttp2/transport/stream_map.c \
+    src/core/ext/transport/chttp2/transport/timeout_encoding.c \
+    src/core/ext/transport/chttp2/transport/varint.c \
+    src/core/ext/transport/chttp2/transport/writing.c \
+    src/core/ext/transport/chttp2/alpn/alpn.c \
+    src/core/ext/client_config/channel_connectivity.c \
+    src/core/ext/client_config/client_channel.c \
+    src/core/ext/client_config/client_channel_factory.c \
+    src/core/ext/client_config/client_config.c \
+    src/core/ext/client_config/client_config_plugin.c \
+    src/core/ext/client_config/connector.c \
+    src/core/ext/client_config/default_initial_connect_string.c \
+    src/core/ext/client_config/initial_connect_string.c \
+    src/core/ext/client_config/lb_policy.c \
+    src/core/ext/client_config/lb_policy_factory.c \
+    src/core/ext/client_config/lb_policy_registry.c \
+    src/core/ext/client_config/parse_address.c \
+    src/core/ext/client_config/resolver.c \
+    src/core/ext/client_config/resolver_factory.c \
+    src/core/ext/client_config/resolver_registry.c \
+    src/core/ext/client_config/subchannel.c \
+    src/core/ext/client_config/subchannel_call_holder.c \
+    src/core/ext/client_config/subchannel_index.c \
+    src/core/ext/client_config/uri_parser.c \
+    src/core/lib/http/httpcli_security_connector.c \
+    src/core/lib/security/context/security_context.c \
+    src/core/lib/security/credentials/composite/composite_credentials.c \
+    src/core/lib/security/credentials/credentials.c \
+    src/core/lib/security/credentials/credentials_metadata.c \
+    src/core/lib/security/credentials/fake/fake_credentials.c \
+    src/core/lib/security/credentials/google_default/credentials_posix.c \
+    src/core/lib/security/credentials/google_default/credentials_windows.c \
+    src/core/lib/security/credentials/google_default/google_default_credentials.c \
+    src/core/lib/security/credentials/iam/iam_credentials.c \
+    src/core/lib/security/credentials/jwt/json_token.c \
+    src/core/lib/security/credentials/jwt/jwt_credentials.c \
+    src/core/lib/security/credentials/jwt/jwt_verifier.c \
+    src/core/lib/security/credentials/oauth2/oauth2_credentials.c \
+    src/core/lib/security/credentials/plugin/plugin_credentials.c \
+    src/core/lib/security/credentials/ssl/ssl_credentials.c \
+    src/core/lib/security/transport/client_auth_filter.c \
+    src/core/lib/security/transport/handshake.c \
+    src/core/lib/security/transport/secure_endpoint.c \
+    src/core/lib/security/transport/security_connector.c \
+    src/core/lib/security/transport/server_auth_filter.c \
+    src/core/lib/security/util/b64.c \
+    src/core/lib/security/util/json_util.c \
+    src/core/lib/surface/init_secure.c \
+    src/core/lib/tsi/fake_transport_security.c \
+    src/core/lib/tsi/ssl_transport_security.c \
+    src/core/lib/tsi/transport_security.c \
+    src/core/plugin_registry/grpc_cronet_plugin_registry.c \
+
+PUBLIC_HEADERS_C += \
+    include/grpc/byte_buffer.h \
+    include/grpc/byte_buffer_reader.h \
+    include/grpc/compression.h \
+    include/grpc/grpc.h \
+    include/grpc/grpc_posix.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/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 \
+    include/grpc/grpc_security_constants.h \
+
+LIBGRPC_CRONET_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC_CRONET_SRC))))
+
+
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure libraries if you don't have OpenSSL.
+
+$(LIBDIR)/$(CONFIG)/libgrpc_cronet.a: openssl_dep_error
+
+$(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc_cronet$(SHARED_VERSION).$(SHARED_EXT): openssl_dep_error
+
+else
+
+
+$(LIBDIR)/$(CONFIG)/libgrpc_cronet.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(LIBGRPC_CRONET_OBJS)  $(LIBGPR_OBJS)  $(ZLIB_MERGE_OBJS)  $(OPENSSL_MERGE_OBJS) 
+	$(E) "[AR]      Creating $@"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc_cronet.a
+	$(Q) $(AR) $(LIBDIR)/$(CONFIG)/libgrpc_cronet.a $(LIBGRPC_CRONET_OBJS)  $(LIBGPR_OBJS)  $(ZLIB_MERGE_OBJS)  $(OPENSSL_MERGE_OBJS) 
+ifeq ($(SYSTEM),Darwin)
+	$(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libgrpc_cronet.a
+endif
+
+
+
+ifeq ($(SYSTEM),MINGW32)
+$(LIBDIR)/$(CONFIG)/grpc_cronet$(SHARED_VERSION).$(SHARED_EXT): $(LIBGRPC_CRONET_OBJS)  $(ZLIB_DEP) $(LIBDIR)/$(CONFIG)/libgpr.a $(OPENSSL_DEP)
+	$(E) "[LD]      Linking $@"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared grpc_cronet.def -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc_cronet$(SHARED_VERSION).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc_cronet$(SHARED_VERSION)-dll.a -o $(LIBDIR)/$(CONFIG)/grpc_cronet$(SHARED_VERSION).$(SHARED_EXT) $(LIBGRPC_CRONET_OBJS) $(LDLIBS) $(LIBDIR)/$(CONFIG)/libgpr.a $(OPENSSL_MERGE_LIBS) $(LDLIBS_SECURE) $(ZLIB_MERGE_LIBS)
+else
+$(LIBDIR)/$(CONFIG)/libgrpc_cronet$(SHARED_VERSION).$(SHARED_EXT): $(LIBGRPC_CRONET_OBJS)  $(ZLIB_DEP) $(LIBDIR)/$(CONFIG)/libgpr.a $(OPENSSL_DEP)
+	$(E) "[LD]      Linking $@"
+	$(Q) mkdir -p `dirname $@`
+ifeq ($(SYSTEM),Darwin)
+	$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc_cronet$(SHARED_VERSION).$(SHARED_EXT) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc_cronet$(SHARED_VERSION).$(SHARED_EXT) $(LIBGRPC_CRONET_OBJS) $(LDLIBS) $(LIBDIR)/$(CONFIG)/libgpr.a $(OPENSSL_MERGE_LIBS) $(LDLIBS_SECURE) $(ZLIB_MERGE_LIBS)
+else
+	$(Q) $(LD) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc_cronet.so.0 -o $(LIBDIR)/$(CONFIG)/libgrpc_cronet$(SHARED_VERSION).$(SHARED_EXT) $(LIBGRPC_CRONET_OBJS) $(LDLIBS) $(LIBDIR)/$(CONFIG)/libgpr.a $(OPENSSL_MERGE_LIBS) $(LDLIBS_SECURE) $(ZLIB_MERGE_LIBS)
+	$(Q) ln -sf $(SHARED_PREFIX)grpc_cronet$(SHARED_VERSION).$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/libgrpc_cronet$(SHARED_VERSION).so.0
+	$(Q) ln -sf $(SHARED_PREFIX)grpc_cronet$(SHARED_VERSION).$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/libgrpc_cronet$(SHARED_VERSION).so
+endif
+endif
+
+endif
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(LIBGRPC_CRONET_OBJS:.o=.dep)
+endif
+endif
+
+
 LIBGRPC_TEST_UTIL_SRC = \
     test/core/end2end/data/client_certs.c \
     test/core/end2end/data/server1_cert.c \
@@ -2830,7 +3108,7 @@
     src/core/lib/channel/connected_channel.c \
     src/core/lib/channel/http_client_filter.c \
     src/core/lib/channel/http_server_filter.c \
-    src/core/lib/compression/compression_algorithm.c \
+    src/core/lib/compression/compression.c \
     src/core/lib/compression/message_compress.c \
     src/core/lib/debug/trace.c \
     src/core/lib/http/format_request.c \
@@ -2840,6 +3118,7 @@
     src/core/lib/iomgr/endpoint.c \
     src/core/lib/iomgr/endpoint_pair_posix.c \
     src/core/lib/iomgr/endpoint_pair_windows.c \
+    src/core/lib/iomgr/ev_poll_and_epoll_posix.c \
     src/core/lib/iomgr/ev_poll_posix.c \
     src/core/lib/iomgr/ev_posix.c \
     src/core/lib/iomgr/exec_ctx.c \
@@ -2848,6 +3127,7 @@
     src/core/lib/iomgr/iomgr.c \
     src/core/lib/iomgr/iomgr_posix.c \
     src/core/lib/iomgr/iomgr_windows.c \
+    src/core/lib/iomgr/polling_entity.c \
     src/core/lib/iomgr/pollset_set_windows.c \
     src/core/lib/iomgr/pollset_windows.c \
     src/core/lib/iomgr/resolve_address_posix.c \
@@ -2905,6 +3185,7 @@
     src/core/lib/transport/transport.c \
     src/core/lib/transport/transport_op_string.c \
     src/core/ext/transport/chttp2/server/insecure/server_chttp2.c \
+    src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.c \
     src/core/ext/transport/chttp2/transport/bin_encoder.c \
     src/core/ext/transport/chttp2/transport/chttp2_plugin.c \
     src/core/ext/transport/chttp2/transport/chttp2_transport.c \
@@ -2928,6 +3209,7 @@
     src/core/ext/transport/chttp2/transport/writing.c \
     src/core/ext/transport/chttp2/alpn/alpn.c \
     src/core/ext/transport/chttp2/client/insecure/channel_create.c \
+    src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c \
     src/core/ext/client_config/channel_connectivity.c \
     src/core/ext/client_config/client_channel.c \
     src/core/ext/client_config/client_channel_factory.c \
@@ -2949,6 +3231,8 @@
     src/core/ext/client_config/uri_parser.c \
     src/core/ext/resolver/dns/native/dns_resolver.c \
     src/core/ext/resolver/sockaddr/sockaddr_resolver.c \
+    src/core/ext/load_reporting/load_reporting.c \
+    src/core/ext/load_reporting/load_reporting_filter.c \
     src/core/ext/lb_policy/grpclb/load_balancer_api.c \
     src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c \
     third_party/nanopb/pb_common.c \
@@ -2957,6 +3241,7 @@
     src/core/ext/lb_policy/pick_first/pick_first.c \
     src/core/ext/lb_policy/round_robin/round_robin.c \
     src/core/ext/census/context.c \
+    src/core/ext/census/gen/census.pb.c \
     src/core/ext/census/grpc_context.c \
     src/core/ext/census/grpc_filter.c \
     src/core/ext/census/grpc_plugin.c \
@@ -2972,6 +3257,7 @@
     include/grpc/byte_buffer_reader.h \
     include/grpc/compression.h \
     include/grpc/grpc.h \
+    include/grpc/grpc_posix.h \
     include/grpc/status.h \
     include/grpc/impl/codegen/byte_buffer.h \
     include/grpc/impl/codegen/byte_buffer_reader.h \
@@ -2984,7 +3270,7 @@
     include/grpc/impl/codegen/atm.h \
     include/grpc/impl/codegen/atm_gcc_atomic.h \
     include/grpc/impl/codegen/atm_gcc_sync.h \
-    include/grpc/impl/codegen/atm_win32.h \
+    include/grpc/impl/codegen/atm_windows.h \
     include/grpc/impl/codegen/log.h \
     include/grpc/impl/codegen/port_platform.h \
     include/grpc/impl/codegen/slice.h \
@@ -2992,7 +3278,7 @@
     include/grpc/impl/codegen/sync.h \
     include/grpc/impl/codegen/sync_generic.h \
     include/grpc/impl/codegen/sync_posix.h \
-    include/grpc/impl/codegen/sync_win32.h \
+    include/grpc/impl/codegen/sync_windows.h \
     include/grpc/impl/codegen/time.h \
     include/grpc/census.h \
 
@@ -3165,6 +3451,7 @@
     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/generic_stub.cc \
     src/cpp/client/insecure_credentials.cc \
@@ -3180,6 +3467,7 @@
     src/cpp/server/server_builder.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/status.cc \
@@ -3193,14 +3481,15 @@
     include/grpc++/client_context.h \
     include/grpc++/completion_queue.h \
     include/grpc++/create_channel.h \
+    include/grpc++/create_channel_posix.h \
     include/grpc++/generic/async_generic_service.h \
     include/grpc++/generic/generic_stub.h \
     include/grpc++/grpc++.h \
     include/grpc++/impl/call.h \
     include/grpc++/impl/client_unary_call.h \
+    include/grpc++/impl/codegen/core_codegen.h \
     include/grpc++/impl/grpc_library.h \
     include/grpc++/impl/method_handler_impl.h \
-    include/grpc++/impl/proto_utils.h \
     include/grpc++/impl/rpc_method.h \
     include/grpc++/impl/rpc_service_method.h \
     include/grpc++/impl/serialization_traits.h \
@@ -3221,10 +3510,12 @@
     include/grpc++/server.h \
     include/grpc++/server_builder.h \
     include/grpc++/server_context.h \
+    include/grpc++/server_posix.h \
     include/grpc++/support/async_stream.h \
     include/grpc++/support/async_unary_call.h \
     include/grpc++/support/byte_buffer.h \
     include/grpc++/support/channel_arguments.h \
+    include/grpc++/support/config.h \
     include/grpc++/support/slice.h \
     include/grpc++/support/status.h \
     include/grpc++/support/status_code_enum.h \
@@ -3241,11 +3532,11 @@
     include/grpc++/impl/codegen/client_unary_call.h \
     include/grpc++/impl/codegen/completion_queue.h \
     include/grpc++/impl/codegen/completion_queue_tag.h \
+    include/grpc++/impl/codegen/config.h \
     include/grpc++/impl/codegen/core_codegen_interface.h \
     include/grpc++/impl/codegen/create_auth_context.h \
     include/grpc++/impl/codegen/grpc_library.h \
     include/grpc++/impl/codegen/method_handler_impl.h \
-    include/grpc++/impl/codegen/proto_utils.h \
     include/grpc++/impl/codegen/rpc_method.h \
     include/grpc++/impl/codegen/rpc_service_method.h \
     include/grpc++/impl/codegen/security/auth_context.h \
@@ -3273,7 +3564,7 @@
     include/grpc/impl/codegen/atm.h \
     include/grpc/impl/codegen/atm_gcc_atomic.h \
     include/grpc/impl/codegen/atm_gcc_sync.h \
-    include/grpc/impl/codegen/atm_win32.h \
+    include/grpc/impl/codegen/atm_windows.h \
     include/grpc/impl/codegen/log.h \
     include/grpc/impl/codegen/port_platform.h \
     include/grpc/impl/codegen/slice.h \
@@ -3281,12 +3572,8 @@
     include/grpc/impl/codegen/sync.h \
     include/grpc/impl/codegen/sync_generic.h \
     include/grpc/impl/codegen/sync_posix.h \
-    include/grpc/impl/codegen/sync_win32.h \
+    include/grpc/impl/codegen/sync_windows.h \
     include/grpc/impl/codegen/time.h \
-    include/grpc++/impl/codegen/config.h \
-    include/grpc++/impl/codegen/config_protobuf.h \
-    include/grpc++/support/config.h \
-    include/grpc++/support/config_protobuf.h \
 
 LIBGRPC++_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC++_SRC))))
 
@@ -3351,6 +3638,133 @@
 endif
 
 
+LIBGRPC++_REFLECTION_SRC = \
+    src/cpp/ext/proto_server_reflection.cc \
+    src/cpp/ext/proto_server_reflection_plugin.cc \
+    src/cpp/ext/reflection.grpc.pb.cc \
+    src/cpp/ext/reflection.pb.cc \
+
+PUBLIC_HEADERS_CXX += \
+    include/grpc++/ext/proto_server_reflection_plugin.h \
+    include/grpc++/ext/reflection.grpc.pb.h \
+    include/grpc++/ext/reflection.pb.h \
+    include/grpc++/impl/codegen/proto_utils.h \
+    include/grpc++/impl/codegen/async_stream.h \
+    include/grpc++/impl/codegen/async_unary_call.h \
+    include/grpc++/impl/codegen/call.h \
+    include/grpc++/impl/codegen/call_hook.h \
+    include/grpc++/impl/codegen/channel_interface.h \
+    include/grpc++/impl/codegen/client_context.h \
+    include/grpc++/impl/codegen/client_unary_call.h \
+    include/grpc++/impl/codegen/completion_queue.h \
+    include/grpc++/impl/codegen/completion_queue_tag.h \
+    include/grpc++/impl/codegen/config.h \
+    include/grpc++/impl/codegen/core_codegen_interface.h \
+    include/grpc++/impl/codegen/create_auth_context.h \
+    include/grpc++/impl/codegen/grpc_library.h \
+    include/grpc++/impl/codegen/method_handler_impl.h \
+    include/grpc++/impl/codegen/rpc_method.h \
+    include/grpc++/impl/codegen/rpc_service_method.h \
+    include/grpc++/impl/codegen/security/auth_context.h \
+    include/grpc++/impl/codegen/serialization_traits.h \
+    include/grpc++/impl/codegen/server_context.h \
+    include/grpc++/impl/codegen/server_interface.h \
+    include/grpc++/impl/codegen/service_type.h \
+    include/grpc++/impl/codegen/status.h \
+    include/grpc++/impl/codegen/status_code_enum.h \
+    include/grpc++/impl/codegen/string_ref.h \
+    include/grpc++/impl/codegen/stub_options.h \
+    include/grpc++/impl/codegen/sync.h \
+    include/grpc++/impl/codegen/sync_cxx11.h \
+    include/grpc++/impl/codegen/sync_no_cxx11.h \
+    include/grpc++/impl/codegen/sync_stream.h \
+    include/grpc++/impl/codegen/time.h \
+    include/grpc/impl/codegen/byte_buffer.h \
+    include/grpc/impl/codegen/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/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))))
+
+
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure libraries if you don't have OpenSSL.
+
+$(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a: openssl_dep_error
+
+$(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION).$(SHARED_EXT): openssl_dep_error
+
+else
+
+ifeq ($(NO_PROTOBUF),true)
+
+# You can't build a C++ library if you don't have protobuf - a bit overreached, but still okay.
+
+$(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a: protobuf_dep_error
+
+$(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION).$(SHARED_EXT): protobuf_dep_error
+
+else
+
+$(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(PROTOBUF_DEP) $(LIBGRPC++_REFLECTION_OBJS) 
+	$(E) "[AR]      Creating $@"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a
+	$(Q) $(AR) $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(LIBGRPC++_REFLECTION_OBJS) 
+ifeq ($(SYSTEM),Darwin)
+	$(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a
+endif
+
+
+
+ifeq ($(SYSTEM),MINGW32)
+$(LIBDIR)/$(CONFIG)/grpc++_reflection$(SHARED_VERSION).$(SHARED_EXT): $(LIBGRPC++_REFLECTION_OBJS)  $(ZLIB_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/grpc++.$(SHARED_EXT) $(OPENSSL_DEP)
+	$(E) "[LD]      Linking $@"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared grpc++_reflection.def -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc++_reflection$(SHARED_VERSION).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc++_reflection$(SHARED_VERSION)-dll.a -o $(LIBDIR)/$(CONFIG)/grpc++_reflection$(SHARED_VERSION).$(SHARED_EXT) $(LIBGRPC++_REFLECTION_OBJS) $(LDLIBS) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgrpc++-imp
+else
+$(LIBDIR)/$(CONFIG)/libgrpc++_reflection$(SHARED_VERSION).$(SHARED_EXT): $(LIBGRPC++_REFLECTION_OBJS)  $(ZLIB_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/libgrpc++.$(SHARED_EXT) $(OPENSSL_DEP)
+	$(E) "[LD]      Linking $@"
+	$(Q) mkdir -p `dirname $@`
+ifeq ($(SYSTEM),Darwin)
+	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION).$(SHARED_EXT) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc++_reflection$(SHARED_VERSION).$(SHARED_EXT) $(LIBGRPC++_REFLECTION_OBJS) $(LDLIBS) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgrpc++
+else
+	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc++_reflection.so.0 -o $(LIBDIR)/$(CONFIG)/libgrpc++_reflection$(SHARED_VERSION).$(SHARED_EXT) $(LIBGRPC++_REFLECTION_OBJS) $(LDLIBS) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgrpc++
+	$(Q) ln -sf $(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION).$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/libgrpc++_reflection$(SHARED_VERSION).so.0
+	$(Q) ln -sf $(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION).$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/libgrpc++_reflection$(SHARED_VERSION).so
+endif
+endif
+
+endif
+
+endif
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(LIBGRPC++_REFLECTION_OBJS:.o=.dep)
+endif
+endif
+
+
 LIBGRPC++_TEST_CONFIG_SRC = \
     test/cpp/util/test_config.cc \
 
@@ -3406,13 +3820,66 @@
     $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc \
     test/cpp/end2end/test_service_impl.cc \
     test/cpp/util/byte_buffer_proto_helper.cc \
-    test/cpp/util/cli_call.cc \
     test/cpp/util/create_test_channel.cc \
     test/cpp/util/string_ref_helper.cc \
     test/cpp/util/subprocess.cc \
     test/cpp/util/test_credentials_provider.cc \
+    src/cpp/codegen/codegen_init.cc \
 
 PUBLIC_HEADERS_CXX += \
+    include/grpc++/impl/codegen/async_stream.h \
+    include/grpc++/impl/codegen/async_unary_call.h \
+    include/grpc++/impl/codegen/call.h \
+    include/grpc++/impl/codegen/call_hook.h \
+    include/grpc++/impl/codegen/channel_interface.h \
+    include/grpc++/impl/codegen/client_context.h \
+    include/grpc++/impl/codegen/client_unary_call.h \
+    include/grpc++/impl/codegen/completion_queue.h \
+    include/grpc++/impl/codegen/completion_queue_tag.h \
+    include/grpc++/impl/codegen/config.h \
+    include/grpc++/impl/codegen/core_codegen_interface.h \
+    include/grpc++/impl/codegen/create_auth_context.h \
+    include/grpc++/impl/codegen/grpc_library.h \
+    include/grpc++/impl/codegen/method_handler_impl.h \
+    include/grpc++/impl/codegen/rpc_method.h \
+    include/grpc++/impl/codegen/rpc_service_method.h \
+    include/grpc++/impl/codegen/security/auth_context.h \
+    include/grpc++/impl/codegen/serialization_traits.h \
+    include/grpc++/impl/codegen/server_context.h \
+    include/grpc++/impl/codegen/server_interface.h \
+    include/grpc++/impl/codegen/service_type.h \
+    include/grpc++/impl/codegen/status.h \
+    include/grpc++/impl/codegen/status_code_enum.h \
+    include/grpc++/impl/codegen/string_ref.h \
+    include/grpc++/impl/codegen/stub_options.h \
+    include/grpc++/impl/codegen/sync.h \
+    include/grpc++/impl/codegen/sync_cxx11.h \
+    include/grpc++/impl/codegen/sync_no_cxx11.h \
+    include/grpc++/impl/codegen/sync_stream.h \
+    include/grpc++/impl/codegen/time.h \
+    include/grpc/impl/codegen/byte_buffer.h \
+    include/grpc/impl/codegen/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/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 \
 
 LIBGRPC++_TEST_UTIL_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC++_TEST_UTIL_SRC))))
 
@@ -3458,11 +3925,11 @@
 endif
 $(OBJDIR)/$(CONFIG)/test/cpp/end2end/test_service_impl.o: $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc
 $(OBJDIR)/$(CONFIG)/test/cpp/util/byte_buffer_proto_helper.o: $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc
-$(OBJDIR)/$(CONFIG)/test/cpp/util/cli_call.o: $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc
 $(OBJDIR)/$(CONFIG)/test/cpp/util/create_test_channel.o: $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc
 $(OBJDIR)/$(CONFIG)/test/cpp/util/string_ref_helper.o: $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc
 $(OBJDIR)/$(CONFIG)/test/cpp/util/subprocess.o: $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc
 $(OBJDIR)/$(CONFIG)/test/cpp/util/test_credentials_provider.o: $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc
+$(OBJDIR)/$(CONFIG)/src/cpp/codegen/codegen_init.o: $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc
 
 
 LIBGRPC++_UNSECURE_SRC = \
@@ -3471,6 +3938,7 @@
     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/generic_stub.cc \
     src/cpp/client/insecure_credentials.cc \
@@ -3486,6 +3954,7 @@
     src/cpp/server/server_builder.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/status.cc \
@@ -3499,14 +3968,15 @@
     include/grpc++/client_context.h \
     include/grpc++/completion_queue.h \
     include/grpc++/create_channel.h \
+    include/grpc++/create_channel_posix.h \
     include/grpc++/generic/async_generic_service.h \
     include/grpc++/generic/generic_stub.h \
     include/grpc++/grpc++.h \
     include/grpc++/impl/call.h \
     include/grpc++/impl/client_unary_call.h \
+    include/grpc++/impl/codegen/core_codegen.h \
     include/grpc++/impl/grpc_library.h \
     include/grpc++/impl/method_handler_impl.h \
-    include/grpc++/impl/proto_utils.h \
     include/grpc++/impl/rpc_method.h \
     include/grpc++/impl/rpc_service_method.h \
     include/grpc++/impl/serialization_traits.h \
@@ -3527,10 +3997,12 @@
     include/grpc++/server.h \
     include/grpc++/server_builder.h \
     include/grpc++/server_context.h \
+    include/grpc++/server_posix.h \
     include/grpc++/support/async_stream.h \
     include/grpc++/support/async_unary_call.h \
     include/grpc++/support/byte_buffer.h \
     include/grpc++/support/channel_arguments.h \
+    include/grpc++/support/config.h \
     include/grpc++/support/slice.h \
     include/grpc++/support/status.h \
     include/grpc++/support/status_code_enum.h \
@@ -3547,11 +4019,11 @@
     include/grpc++/impl/codegen/client_unary_call.h \
     include/grpc++/impl/codegen/completion_queue.h \
     include/grpc++/impl/codegen/completion_queue_tag.h \
+    include/grpc++/impl/codegen/config.h \
     include/grpc++/impl/codegen/core_codegen_interface.h \
     include/grpc++/impl/codegen/create_auth_context.h \
     include/grpc++/impl/codegen/grpc_library.h \
     include/grpc++/impl/codegen/method_handler_impl.h \
-    include/grpc++/impl/codegen/proto_utils.h \
     include/grpc++/impl/codegen/rpc_method.h \
     include/grpc++/impl/codegen/rpc_service_method.h \
     include/grpc++/impl/codegen/security/auth_context.h \
@@ -3579,7 +4051,7 @@
     include/grpc/impl/codegen/atm.h \
     include/grpc/impl/codegen/atm_gcc_atomic.h \
     include/grpc/impl/codegen/atm_gcc_sync.h \
-    include/grpc/impl/codegen/atm_win32.h \
+    include/grpc/impl/codegen/atm_windows.h \
     include/grpc/impl/codegen/log.h \
     include/grpc/impl/codegen/port_platform.h \
     include/grpc/impl/codegen/slice.h \
@@ -3587,12 +4059,8 @@
     include/grpc/impl/codegen/sync.h \
     include/grpc/impl/codegen/sync_generic.h \
     include/grpc/impl/codegen/sync_posix.h \
-    include/grpc/impl/codegen/sync_win32.h \
+    include/grpc/impl/codegen/sync_windows.h \
     include/grpc/impl/codegen/time.h \
-    include/grpc++/impl/codegen/config.h \
-    include/grpc++/impl/codegen/config_protobuf.h \
-    include/grpc++/support/config.h \
-    include/grpc++/support/config_protobuf.h \
 
 LIBGRPC++_UNSECURE_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC++_UNSECURE_SRC))))
 
@@ -3643,6 +4111,56 @@
 endif
 
 
+LIBGRPC_CLI_LIBS_SRC = \
+    test/cpp/util/cli_call.cc \
+    test/cpp/util/proto_file_parser.cc \
+
+PUBLIC_HEADERS_CXX += \
+
+LIBGRPC_CLI_LIBS_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC_CLI_LIBS_SRC))))
+
+
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure libraries if you don't have OpenSSL.
+
+$(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a: openssl_dep_error
+
+
+else
+
+ifeq ($(NO_PROTOBUF),true)
+
+# You can't build a C++ library if you don't have protobuf - a bit overreached, but still okay.
+
+$(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a: protobuf_dep_error
+
+
+else
+
+$(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(PROTOBUF_DEP) $(LIBGRPC_CLI_LIBS_OBJS) 
+	$(E) "[AR]      Creating $@"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a
+	$(Q) $(AR) $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBGRPC_CLI_LIBS_OBJS) 
+ifeq ($(SYSTEM),Darwin)
+	$(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a
+endif
+
+
+
+
+endif
+
+endif
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(LIBGRPC_CLI_LIBS_OBJS:.o=.dep)
+endif
+endif
+
+
 LIBGRPC_PLUGIN_SUPPORT_SRC = \
     src/compiler/cpp_generator.cc \
     src/compiler/csharp_generator.cc \
@@ -3652,9 +4170,6 @@
     src/compiler/ruby_generator.cc \
 
 PUBLIC_HEADERS_CXX += \
-    include/grpc++/support/config.h \
-    include/grpc++/support/config_protobuf.h \
-    include/grpc++/impl/codegen/config.h \
     include/grpc++/impl/codegen/config_protobuf.h \
 
 LIBGRPC_PLUGIN_SUPPORT_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC_PLUGIN_SUPPORT_SRC))))
@@ -3902,12 +4417,11 @@
     $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc \
     $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc \
     $(GENDIR)/src/proto/grpc/testing/services.pb.cc $(GENDIR)/src/proto/grpc/testing/services.grpc.pb.cc \
-    $(GENDIR)/src/proto/grpc/testing/perf_db.pb.cc $(GENDIR)/src/proto/grpc/testing/perf_db.grpc.pb.cc \
     test/cpp/qps/client_async.cc \
     test/cpp/qps/client_sync.cc \
     test/cpp/qps/driver.cc \
     test/cpp/qps/limit_cores.cc \
-    test/cpp/qps/perf_db_client.cc \
+    test/cpp/qps/parse_json.cc \
     test/cpp/qps/qps_worker.cc \
     test/cpp/qps/report.cc \
     test/cpp/qps/server_async.cc \
@@ -3959,17 +4473,17 @@
 -include $(LIBQPS_OBJS:.o=.dep)
 endif
 endif
-$(OBJDIR)/$(CONFIG)/test/cpp/qps/client_async.o: $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/services.pb.cc $(GENDIR)/src/proto/grpc/testing/services.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/perf_db.pb.cc $(GENDIR)/src/proto/grpc/testing/perf_db.grpc.pb.cc
-$(OBJDIR)/$(CONFIG)/test/cpp/qps/client_sync.o: $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/services.pb.cc $(GENDIR)/src/proto/grpc/testing/services.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/perf_db.pb.cc $(GENDIR)/src/proto/grpc/testing/perf_db.grpc.pb.cc
-$(OBJDIR)/$(CONFIG)/test/cpp/qps/driver.o: $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/services.pb.cc $(GENDIR)/src/proto/grpc/testing/services.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/perf_db.pb.cc $(GENDIR)/src/proto/grpc/testing/perf_db.grpc.pb.cc
-$(OBJDIR)/$(CONFIG)/test/cpp/qps/limit_cores.o: $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/services.pb.cc $(GENDIR)/src/proto/grpc/testing/services.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/perf_db.pb.cc $(GENDIR)/src/proto/grpc/testing/perf_db.grpc.pb.cc
-$(OBJDIR)/$(CONFIG)/test/cpp/qps/perf_db_client.o: $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/services.pb.cc $(GENDIR)/src/proto/grpc/testing/services.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/perf_db.pb.cc $(GENDIR)/src/proto/grpc/testing/perf_db.grpc.pb.cc
-$(OBJDIR)/$(CONFIG)/test/cpp/qps/qps_worker.o: $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/services.pb.cc $(GENDIR)/src/proto/grpc/testing/services.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/perf_db.pb.cc $(GENDIR)/src/proto/grpc/testing/perf_db.grpc.pb.cc
-$(OBJDIR)/$(CONFIG)/test/cpp/qps/report.o: $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/services.pb.cc $(GENDIR)/src/proto/grpc/testing/services.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/perf_db.pb.cc $(GENDIR)/src/proto/grpc/testing/perf_db.grpc.pb.cc
-$(OBJDIR)/$(CONFIG)/test/cpp/qps/server_async.o: $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/services.pb.cc $(GENDIR)/src/proto/grpc/testing/services.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/perf_db.pb.cc $(GENDIR)/src/proto/grpc/testing/perf_db.grpc.pb.cc
-$(OBJDIR)/$(CONFIG)/test/cpp/qps/server_sync.o: $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/services.pb.cc $(GENDIR)/src/proto/grpc/testing/services.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/perf_db.pb.cc $(GENDIR)/src/proto/grpc/testing/perf_db.grpc.pb.cc
-$(OBJDIR)/$(CONFIG)/test/cpp/qps/usage_timer.o: $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/services.pb.cc $(GENDIR)/src/proto/grpc/testing/services.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/perf_db.pb.cc $(GENDIR)/src/proto/grpc/testing/perf_db.grpc.pb.cc
-$(OBJDIR)/$(CONFIG)/test/cpp/util/benchmark_config.o: $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/services.pb.cc $(GENDIR)/src/proto/grpc/testing/services.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/perf_db.pb.cc $(GENDIR)/src/proto/grpc/testing/perf_db.grpc.pb.cc
+$(OBJDIR)/$(CONFIG)/test/cpp/qps/client_async.o: $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/services.pb.cc $(GENDIR)/src/proto/grpc/testing/services.grpc.pb.cc
+$(OBJDIR)/$(CONFIG)/test/cpp/qps/client_sync.o: $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/services.pb.cc $(GENDIR)/src/proto/grpc/testing/services.grpc.pb.cc
+$(OBJDIR)/$(CONFIG)/test/cpp/qps/driver.o: $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/services.pb.cc $(GENDIR)/src/proto/grpc/testing/services.grpc.pb.cc
+$(OBJDIR)/$(CONFIG)/test/cpp/qps/limit_cores.o: $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/services.pb.cc $(GENDIR)/src/proto/grpc/testing/services.grpc.pb.cc
+$(OBJDIR)/$(CONFIG)/test/cpp/qps/parse_json.o: $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/services.pb.cc $(GENDIR)/src/proto/grpc/testing/services.grpc.pb.cc
+$(OBJDIR)/$(CONFIG)/test/cpp/qps/qps_worker.o: $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/services.pb.cc $(GENDIR)/src/proto/grpc/testing/services.grpc.pb.cc
+$(OBJDIR)/$(CONFIG)/test/cpp/qps/report.o: $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/services.pb.cc $(GENDIR)/src/proto/grpc/testing/services.grpc.pb.cc
+$(OBJDIR)/$(CONFIG)/test/cpp/qps/server_async.o: $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/services.pb.cc $(GENDIR)/src/proto/grpc/testing/services.grpc.pb.cc
+$(OBJDIR)/$(CONFIG)/test/cpp/qps/server_sync.o: $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/services.pb.cc $(GENDIR)/src/proto/grpc/testing/services.grpc.pb.cc
+$(OBJDIR)/$(CONFIG)/test/cpp/qps/usage_timer.o: $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/services.pb.cc $(GENDIR)/src/proto/grpc/testing/services.grpc.pb.cc
+$(OBJDIR)/$(CONFIG)/test/cpp/util/benchmark_config.o: $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/services.pb.cc $(GENDIR)/src/proto/grpc/testing/services.grpc.pb.cc
 
 
 LIBGRPC_CSHARP_EXT_SRC = \
@@ -9808,16 +10322,16 @@
 
 else
 
-$(BINDIR)/$(CONFIG)/cli_call_test: $(PROTOBUF_DEP) $(CLI_CALL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(BINDIR)/$(CONFIG)/cli_call_test: $(PROTOBUF_DEP) $(CLI_CALL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(LDXX) $(LDFLAGS) $(CLI_CALL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/cli_call_test
+	$(Q) $(LDXX) $(LDFLAGS) $(CLI_CALL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/cli_call_test
 
 endif
 
 endif
 
-$(OBJDIR)/$(CONFIG)/test/cpp/util/cli_call_test.o:  $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+$(OBJDIR)/$(CONFIG)/test/cpp/util/cli_call_test.o:  $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
 
 deps_cli_call_test: $(CLI_CALL_TEST_OBJS:.o=.dep)
 
@@ -9918,11 +10432,9 @@
     $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc \
     $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc \
     $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc \
-    $(GENDIR)/src/proto/grpc/testing/perf_db.pb.cc $(GENDIR)/src/proto/grpc/testing/perf_db.grpc.pb.cc \
     $(GENDIR)/src/proto/grpc/testing/services.pb.cc $(GENDIR)/src/proto/grpc/testing/services.grpc.pb.cc \
     $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc \
     test/cpp/codegen/codegen_test_full.cc \
-    src/cpp/codegen/codegen_init.cc \
 
 CODEGEN_TEST_FULL_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(CODEGEN_TEST_FULL_SRC))))
 ifeq ($(NO_SECURE),true)
@@ -9959,16 +10471,12 @@
 
 $(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/payloads.o:  $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
 
-$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/perf_db.o:  $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
-
 $(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/services.o:  $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
 
 $(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/stats.o:  $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
 
 $(OBJDIR)/$(CONFIG)/test/cpp/codegen/codegen_test_full.o:  $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
 
-$(OBJDIR)/$(CONFIG)/src/cpp/codegen/codegen_init.o:  $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a
-
 deps_codegen_test_full: $(CODEGEN_TEST_FULL_OBJS:.o=.dep)
 
 ifneq ($(NO_SECURE),true)
@@ -9976,15 +10484,13 @@
 -include $(CODEGEN_TEST_FULL_OBJS:.o=.dep)
 endif
 endif
-$(OBJDIR)/$(CONFIG)/test/cpp/codegen/codegen_test_full.o: $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/perf_db.pb.cc $(GENDIR)/src/proto/grpc/testing/perf_db.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/services.pb.cc $(GENDIR)/src/proto/grpc/testing/services.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc
-$(OBJDIR)/$(CONFIG)/src/cpp/codegen/codegen_init.o: $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/perf_db.pb.cc $(GENDIR)/src/proto/grpc/testing/perf_db.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/services.pb.cc $(GENDIR)/src/proto/grpc/testing/services.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc
+$(OBJDIR)/$(CONFIG)/test/cpp/codegen/codegen_test_full.o: $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/services.pb.cc $(GENDIR)/src/proto/grpc/testing/services.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc
 
 
 CODEGEN_TEST_MINIMAL_SRC = \
     $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc \
     $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc \
     $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc \
-    $(GENDIR)/src/proto/grpc/testing/perf_db.pb.cc $(GENDIR)/src/proto/grpc/testing/perf_db.grpc.pb.cc \
     $(GENDIR)/src/proto/grpc/testing/services.pb.cc $(GENDIR)/src/proto/grpc/testing/services.grpc.pb.cc \
     $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc \
     test/cpp/codegen/codegen_test_minimal.cc \
@@ -10025,8 +10531,6 @@
 
 $(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/payloads.o: 
 
-$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/perf_db.o: 
-
 $(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/services.o: 
 
 $(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/stats.o: 
@@ -10042,8 +10546,8 @@
 -include $(CODEGEN_TEST_MINIMAL_OBJS:.o=.dep)
 endif
 endif
-$(OBJDIR)/$(CONFIG)/test/cpp/codegen/codegen_test_minimal.o: $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/perf_db.pb.cc $(GENDIR)/src/proto/grpc/testing/perf_db.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/services.pb.cc $(GENDIR)/src/proto/grpc/testing/services.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc
-$(OBJDIR)/$(CONFIG)/src/cpp/codegen/codegen_init.o: $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/perf_db.pb.cc $(GENDIR)/src/proto/grpc/testing/perf_db.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/services.pb.cc $(GENDIR)/src/proto/grpc/testing/services.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc
+$(OBJDIR)/$(CONFIG)/test/cpp/codegen/codegen_test_minimal.o: $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/services.pb.cc $(GENDIR)/src/proto/grpc/testing/services.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc
+$(OBJDIR)/$(CONFIG)/src/cpp/codegen/codegen_init.o: $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/services.pb.cc $(GENDIR)/src/proto/grpc/testing/services.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc
 
 
 CREDENTIALS_TEST_SRC = \
@@ -10417,16 +10921,16 @@
 
 else
 
-$(BINDIR)/$(CONFIG)/grpc_cli: $(PROTOBUF_DEP) $(GRPC_CLI_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a
+$(BINDIR)/$(CONFIG)/grpc_cli: $(PROTOBUF_DEP) $(GRPC_CLI_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(LDXX) $(LDFLAGS) $(GRPC_CLI_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/grpc_cli
+	$(Q) $(LDXX) $(LDFLAGS) $(GRPC_CLI_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/grpc_cli
 
 endif
 
 endif
 
-$(OBJDIR)/$(CONFIG)/test/cpp/util/grpc_cli.o:  $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a
+$(OBJDIR)/$(CONFIG)/test/cpp/util/grpc_cli.o:  $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a
 
 deps_grpc_cli: $(GRPC_CLI_OBJS:.o=.dep)
 
@@ -10951,6 +11455,52 @@
 endif
 
 
+PROTO_SERVER_REFLECTION_TEST_SRC = \
+    test/cpp/end2end/proto_server_reflection_test.cc \
+    test/cpp/util/proto_reflection_descriptor_database.cc \
+
+PROTO_SERVER_REFLECTION_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(PROTO_SERVER_REFLECTION_TEST_SRC))))
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure targets if you don't have OpenSSL.
+
+$(BINDIR)/$(CONFIG)/proto_server_reflection_test: openssl_dep_error
+
+else
+
+
+
+
+ifeq ($(NO_PROTOBUF),true)
+
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+.
+
+$(BINDIR)/$(CONFIG)/proto_server_reflection_test: protobuf_dep_error
+
+else
+
+$(BINDIR)/$(CONFIG)/proto_server_reflection_test: $(PROTOBUF_DEP) $(PROTO_SERVER_REFLECTION_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+	$(E) "[LD]      Linking $@"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(LDXX) $(LDFLAGS) $(PROTO_SERVER_REFLECTION_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/proto_server_reflection_test
+
+endif
+
+endif
+
+$(OBJDIR)/$(CONFIG)/test/cpp/end2end/proto_server_reflection_test.o:  $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+$(OBJDIR)/$(CONFIG)/test/cpp/util/proto_reflection_descriptor_database.o:  $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+deps_proto_server_reflection_test: $(PROTO_SERVER_REFLECTION_TEST_OBJS:.o=.dep)
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(PROTO_SERVER_REFLECTION_TEST_OBJS:.o=.dep)
+endif
+endif
+
+
 QPS_INTERARRIVAL_TEST_SRC = \
     test/cpp/qps/qps_interarrival_test.cc \
 
@@ -10995,7 +11545,6 @@
 
 
 QPS_JSON_DRIVER_SRC = \
-    test/cpp/qps/parse_json.cc \
     test/cpp/qps/qps_json_driver.cc \
 
 QPS_JSON_DRIVER_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(QPS_JSON_DRIVER_SRC))))
@@ -11027,8 +11576,6 @@
 
 endif
 
-$(OBJDIR)/$(CONFIG)/test/cpp/qps/parse_json.o:  $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a
-
 $(OBJDIR)/$(CONFIG)/test/cpp/qps/qps_json_driver.o:  $(LIBDIR)/$(CONFIG)/libqps.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a
 
 deps_qps_json_driver: $(QPS_JSON_DRIVER_OBJS:.o=.dep)
@@ -13220,6 +13767,38 @@
 endif
 
 
+H2_FD_TEST_SRC = \
+    test/core/end2end/fixtures/h2_fd.c \
+
+H2_FD_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(H2_FD_TEST_SRC))))
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure targets if you don't have OpenSSL.
+
+$(BINDIR)/$(CONFIG)/h2_fd_test: openssl_dep_error
+
+else
+
+
+
+$(BINDIR)/$(CONFIG)/h2_fd_test: $(H2_FD_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+	$(E) "[LD]      Linking $@"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(LD) $(LDFLAGS) $(H2_FD_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_fd_test
+
+endif
+
+$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_fd.o:  $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+deps_h2_fd_test: $(H2_FD_TEST_OBJS:.o=.dep)
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(H2_FD_TEST_OBJS:.o=.dep)
+endif
+endif
+
+
 H2_FULL_TEST_SRC = \
     test/core/end2end/fixtures/h2_full.c \
 
@@ -13316,6 +13895,38 @@
 endif
 
 
+H2_LOADREPORTING_TEST_SRC = \
+    test/core/end2end/fixtures/h2_loadreporting.c \
+
+H2_LOADREPORTING_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(H2_LOADREPORTING_TEST_SRC))))
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure targets if you don't have OpenSSL.
+
+$(BINDIR)/$(CONFIG)/h2_loadreporting_test: openssl_dep_error
+
+else
+
+
+
+$(BINDIR)/$(CONFIG)/h2_loadreporting_test: $(H2_LOADREPORTING_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+	$(E) "[LD]      Linking $@"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(LD) $(LDFLAGS) $(H2_LOADREPORTING_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/h2_loadreporting_test
+
+endif
+
+$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_loadreporting.o:  $(LIBDIR)/$(CONFIG)/libend2end_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+deps_h2_loadreporting_test: $(H2_LOADREPORTING_TEST_OBJS:.o=.dep)
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(H2_LOADREPORTING_TEST_OBJS:.o=.dep)
+endif
+endif
+
+
 H2_OAUTH2_TEST_SRC = \
     test/core/end2end/fixtures/h2_oauth2.c \
 
@@ -13644,6 +14255,26 @@
 endif
 
 
+H2_FD_NOSEC_TEST_SRC = \
+    test/core/end2end/fixtures/h2_fd.c \
+
+H2_FD_NOSEC_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(H2_FD_NOSEC_TEST_SRC))))
+
+
+$(BINDIR)/$(CONFIG)/h2_fd_nosec_test: $(H2_FD_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+	$(E) "[LD]      Linking $@"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(LD) $(LDFLAGS) $(H2_FD_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/h2_fd_nosec_test
+
+$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_fd.o:  $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+deps_h2_fd_nosec_test: $(H2_FD_NOSEC_TEST_OBJS:.o=.dep)
+
+ifneq ($(NO_DEPS),true)
+-include $(H2_FD_NOSEC_TEST_OBJS:.o=.dep)
+endif
+
+
 H2_FULL_NOSEC_TEST_SRC = \
     test/core/end2end/fixtures/h2_full.c \
 
@@ -13704,6 +14335,26 @@
 endif
 
 
+H2_LOADREPORTING_NOSEC_TEST_SRC = \
+    test/core/end2end/fixtures/h2_loadreporting.c \
+
+H2_LOADREPORTING_NOSEC_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(H2_LOADREPORTING_NOSEC_TEST_SRC))))
+
+
+$(BINDIR)/$(CONFIG)/h2_loadreporting_nosec_test: $(H2_LOADREPORTING_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+	$(E) "[LD]      Linking $@"
+	$(Q) mkdir -p `dirname $@`
+	$(Q) $(LD) $(LDFLAGS) $(H2_LOADREPORTING_NOSEC_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) -o $(BINDIR)/$(CONFIG)/h2_loadreporting_nosec_test
+
+$(OBJDIR)/$(CONFIG)/test/core/end2end/fixtures/h2_loadreporting.o:  $(LIBDIR)/$(CONFIG)/libend2end_nosec_tests.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+deps_h2_loadreporting_nosec_test: $(H2_LOADREPORTING_NOSEC_TEST_OBJS:.o=.dep)
+
+ifneq ($(NO_DEPS),true)
+-include $(H2_LOADREPORTING_NOSEC_TEST_OBJS:.o=.dep)
+endif
+
+
 H2_PROXY_NOSEC_TEST_SRC = \
     test/core/end2end/fixtures/h2_proxy.c \
 
@@ -14139,7 +14790,7 @@
 src/core/lib/security/credentials/credentials_metadata.c: $(OPENSSL_DEP)
 src/core/lib/security/credentials/fake/fake_credentials.c: $(OPENSSL_DEP)
 src/core/lib/security/credentials/google_default/credentials_posix.c: $(OPENSSL_DEP)
-src/core/lib/security/credentials/google_default/credentials_win32.c: $(OPENSSL_DEP)
+src/core/lib/security/credentials/google_default/credentials_windows.c: $(OPENSSL_DEP)
 src/core/lib/security/credentials/google_default/google_default_credentials.c: $(OPENSSL_DEP)
 src/core/lib/security/credentials/iam/iam_credentials.c: $(OPENSSL_DEP)
 src/core/lib/security/credentials/jwt/json_token.c: $(OPENSSL_DEP)
@@ -14159,12 +14810,17 @@
 src/core/lib/tsi/fake_transport_security.c: $(OPENSSL_DEP)
 src/core/lib/tsi/ssl_transport_security.c: $(OPENSSL_DEP)
 src/core/lib/tsi/transport_security.c: $(OPENSSL_DEP)
+src/core/plugin_registry/grpc_cronet_plugin_registry.c: $(OPENSSL_DEP)
 src/core/plugin_registry/grpc_plugin_registry.c: $(OPENSSL_DEP)
 src/cpp/client/secure_credentials.cc: $(OPENSSL_DEP)
 src/cpp/common/auth_property_iterator.cc: $(OPENSSL_DEP)
 src/cpp/common/secure_auth_context.cc: $(OPENSSL_DEP)
 src/cpp/common/secure_channel_arguments.cc: $(OPENSSL_DEP)
 src/cpp/common/secure_create_auth_context.cc: $(OPENSSL_DEP)
+src/cpp/ext/proto_server_reflection.cc: $(OPENSSL_DEP)
+src/cpp/ext/proto_server_reflection_plugin.cc: $(OPENSSL_DEP)
+src/cpp/ext/reflection.grpc.pb.cc: $(OPENSSL_DEP)
+src/cpp/ext/reflection.pb.cc: $(OPENSSL_DEP)
 src/cpp/server/secure_server_credentials.cc: $(OPENSSL_DEP)
 src/csharp/ext/grpc_csharp_ext.c: $(OPENSSL_DEP)
 test/core/bad_client/bad_client.c: $(OPENSSL_DEP)
@@ -14188,7 +14844,7 @@
 test/cpp/qps/client_sync.cc: $(OPENSSL_DEP)
 test/cpp/qps/driver.cc: $(OPENSSL_DEP)
 test/cpp/qps/limit_cores.cc: $(OPENSSL_DEP)
-test/cpp/qps/perf_db_client.cc: $(OPENSSL_DEP)
+test/cpp/qps/parse_json.cc: $(OPENSSL_DEP)
 test/cpp/qps/qps_worker.cc: $(OPENSSL_DEP)
 test/cpp/qps/report.cc: $(OPENSSL_DEP)
 test/cpp/qps/server_async.cc: $(OPENSSL_DEP)
@@ -14198,6 +14854,7 @@
 test/cpp/util/byte_buffer_proto_helper.cc: $(OPENSSL_DEP)
 test/cpp/util/cli_call.cc: $(OPENSSL_DEP)
 test/cpp/util/create_test_channel.cc: $(OPENSSL_DEP)
+test/cpp/util/proto_file_parser.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)
diff --git a/binding.gyp b/binding.gyp
index 7b18707..9b4ae5e 100644
--- a/binding.gyp
+++ b/binding.gyp
@@ -507,7 +507,7 @@
         'src/core/lib/support/cpu_windows.c',
         'src/core/lib/support/env_linux.c',
         'src/core/lib/support/env_posix.c',
-        'src/core/lib/support/env_win32.c',
+        'src/core/lib/support/env_windows.c',
         'src/core/lib/support/histogram.c',
         'src/core/lib/support/host_port.c',
         'src/core/lib/support/load_file.c',
@@ -515,31 +515,31 @@
         'src/core/lib/support/log_android.c',
         'src/core/lib/support/log_linux.c',
         'src/core/lib/support/log_posix.c',
-        'src/core/lib/support/log_win32.c',
+        'src/core/lib/support/log_windows.c',
         'src/core/lib/support/murmur_hash.c',
         'src/core/lib/support/slice.c',
         'src/core/lib/support/slice_buffer.c',
         'src/core/lib/support/stack_lockfree.c',
         'src/core/lib/support/string.c',
         'src/core/lib/support/string_posix.c',
-        'src/core/lib/support/string_util_win32.c',
-        'src/core/lib/support/string_win32.c',
+        'src/core/lib/support/string_util_windows.c',
+        'src/core/lib/support/string_windows.c',
         'src/core/lib/support/subprocess_posix.c',
         'src/core/lib/support/subprocess_windows.c',
         'src/core/lib/support/sync.c',
         'src/core/lib/support/sync_posix.c',
-        'src/core/lib/support/sync_win32.c',
+        'src/core/lib/support/sync_windows.c',
         'src/core/lib/support/thd.c',
         'src/core/lib/support/thd_posix.c',
-        'src/core/lib/support/thd_win32.c',
+        'src/core/lib/support/thd_windows.c',
         'src/core/lib/support/time.c',
         'src/core/lib/support/time_posix.c',
         'src/core/lib/support/time_precise.c',
-        'src/core/lib/support/time_win32.c',
+        'src/core/lib/support/time_windows.c',
         'src/core/lib/support/tls_pthread.c',
         'src/core/lib/support/tmpfile_msys.c',
         'src/core/lib/support/tmpfile_posix.c',
-        'src/core/lib/support/tmpfile_win32.c',
+        'src/core/lib/support/tmpfile_windows.c',
         'src/core/lib/support/wrap_memcpy.c',
       ],
       "conditions": [
@@ -571,7 +571,7 @@
         'src/core/lib/channel/connected_channel.c',
         'src/core/lib/channel/http_client_filter.c',
         'src/core/lib/channel/http_server_filter.c',
-        'src/core/lib/compression/compression_algorithm.c',
+        'src/core/lib/compression/compression.c',
         'src/core/lib/compression/message_compress.c',
         'src/core/lib/debug/trace.c',
         'src/core/lib/http/format_request.c',
@@ -581,6 +581,7 @@
         'src/core/lib/iomgr/endpoint.c',
         'src/core/lib/iomgr/endpoint_pair_posix.c',
         'src/core/lib/iomgr/endpoint_pair_windows.c',
+        'src/core/lib/iomgr/ev_poll_and_epoll_posix.c',
         'src/core/lib/iomgr/ev_poll_posix.c',
         'src/core/lib/iomgr/ev_posix.c',
         'src/core/lib/iomgr/exec_ctx.c',
@@ -589,6 +590,7 @@
         'src/core/lib/iomgr/iomgr.c',
         'src/core/lib/iomgr/iomgr_posix.c',
         'src/core/lib/iomgr/iomgr_windows.c',
+        'src/core/lib/iomgr/polling_entity.c',
         'src/core/lib/iomgr/pollset_set_windows.c',
         'src/core/lib/iomgr/pollset_windows.c',
         'src/core/lib/iomgr/resolve_address_posix.c',
@@ -675,7 +677,7 @@
         'src/core/lib/security/credentials/credentials_metadata.c',
         'src/core/lib/security/credentials/fake/fake_credentials.c',
         'src/core/lib/security/credentials/google_default/credentials_posix.c',
-        'src/core/lib/security/credentials/google_default/credentials_win32.c',
+        'src/core/lib/security/credentials/google_default/credentials_windows.c',
         'src/core/lib/security/credentials/google_default/google_default_credentials.c',
         'src/core/lib/security/credentials/iam/iam_credentials.c',
         'src/core/lib/security/credentials/jwt/json_token.c',
@@ -716,10 +718,9 @@
         'src/core/ext/client_config/subchannel_index.c',
         'src/core/ext/client_config/uri_parser.c',
         'src/core/ext/transport/chttp2/server/insecure/server_chttp2.c',
+        'src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.c',
         'src/core/ext/transport/chttp2/client/insecure/channel_create.c',
-        'src/core/ext/transport/cronet/client/secure/cronet_channel_create.c',
-        'src/core/ext/transport/cronet/transport/cronet_api_dummy.c',
-        'src/core/ext/transport/cronet/transport/cronet_transport.c',
+        'src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c',
         'src/core/ext/lb_policy/grpclb/load_balancer_api.c',
         'src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c',
         'third_party/nanopb/pb_common.c',
@@ -729,7 +730,10 @@
         'src/core/ext/lb_policy/round_robin/round_robin.c',
         'src/core/ext/resolver/dns/native/dns_resolver.c',
         'src/core/ext/resolver/sockaddr/sockaddr_resolver.c',
+        'src/core/ext/load_reporting/load_reporting.c',
+        'src/core/ext/load_reporting/load_reporting_filter.c',
         'src/core/ext/census/context.c',
+        'src/core/ext/census/gen/census.pb.c',
         'src/core/ext/census/grpc_context.c',
         'src/core/ext/census/grpc_filter.c',
         'src/core/ext/census/grpc_plugin.c',
diff --git a/build.yaml b/build.yaml
index 429dbb3..3d1e9b1 100644
--- a/build.yaml
+++ b/build.yaml
@@ -16,11 +16,13 @@
   - src/core/ext/census/aggregation.h
   - src/core/ext/census/census_interface.h
   - src/core/ext/census/census_rpc_stats.h
+  - src/core/ext/census/gen/census.pb.h
   - src/core/ext/census/grpc_filter.h
   - src/core/ext/census/mlog.h
   - src/core/ext/census/rpc_metric_id.h
   src:
   - src/core/ext/census/context.c
+  - src/core/ext/census/gen/census.pb.c
   - src/core/ext/census/grpc_context.c
   - src/core/ext/census/grpc_filter.c
   - src/core/ext/census/grpc_plugin.c
@@ -32,20 +34,21 @@
   plugin: census_grpc_plugin
   uses:
   - grpc_base
+  - nanopb
 - name: gpr_base
   public_headers:
   - include/grpc/support/alloc.h
   - include/grpc/support/atm.h
   - include/grpc/support/atm_gcc_atomic.h
   - include/grpc/support/atm_gcc_sync.h
-  - include/grpc/support/atm_win32.h
+  - include/grpc/support/atm_windows.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_win32.h
+  - include/grpc/support/log_windows.h
   - include/grpc/support/port_platform.h
   - include/grpc/support/slice.h
   - include/grpc/support/slice_buffer.h
@@ -54,7 +57,7 @@
   - include/grpc/support/sync.h
   - include/grpc/support/sync_generic.h
   - include/grpc/support/sync_posix.h
-  - include/grpc/support/sync_win32.h
+  - include/grpc/support/sync_windows.h
   - include/grpc/support/thd.h
   - include/grpc/support/time.h
   - include/grpc/support/tls.h
@@ -71,7 +74,7 @@
   - src/core/lib/support/murmur_hash.h
   - src/core/lib/support/stack_lockfree.h
   - src/core/lib/support/string.h
-  - src/core/lib/support/string_win32.h
+  - src/core/lib/support/string_windows.h
   - src/core/lib/support/thd_internal.h
   - src/core/lib/support/time_precise.h
   - src/core/lib/support/tmpfile.h
@@ -88,7 +91,7 @@
   - src/core/lib/support/cpu_windows.c
   - src/core/lib/support/env_linux.c
   - src/core/lib/support/env_posix.c
-  - src/core/lib/support/env_win32.c
+  - src/core/lib/support/env_windows.c
   - src/core/lib/support/histogram.c
   - src/core/lib/support/host_port.c
   - src/core/lib/support/load_file.c
@@ -96,31 +99,31 @@
   - src/core/lib/support/log_android.c
   - src/core/lib/support/log_linux.c
   - src/core/lib/support/log_posix.c
-  - src/core/lib/support/log_win32.c
+  - src/core/lib/support/log_windows.c
   - src/core/lib/support/murmur_hash.c
   - src/core/lib/support/slice.c
   - src/core/lib/support/slice_buffer.c
   - src/core/lib/support/stack_lockfree.c
   - src/core/lib/support/string.c
   - src/core/lib/support/string_posix.c
-  - src/core/lib/support/string_util_win32.c
-  - src/core/lib/support/string_win32.c
+  - src/core/lib/support/string_util_windows.c
+  - src/core/lib/support/string_windows.c
   - src/core/lib/support/subprocess_posix.c
   - src/core/lib/support/subprocess_windows.c
   - src/core/lib/support/sync.c
   - src/core/lib/support/sync_posix.c
-  - src/core/lib/support/sync_win32.c
+  - src/core/lib/support/sync_windows.c
   - src/core/lib/support/thd.c
   - src/core/lib/support/thd_posix.c
-  - src/core/lib/support/thd_win32.c
+  - src/core/lib/support/thd_windows.c
   - src/core/lib/support/time.c
   - src/core/lib/support/time_posix.c
   - src/core/lib/support/time_precise.c
-  - src/core/lib/support/time_win32.c
+  - src/core/lib/support/time_windows.c
   - src/core/lib/support/tls_pthread.c
   - src/core/lib/support/tmpfile_msys.c
   - src/core/lib/support/tmpfile_posix.c
-  - src/core/lib/support/tmpfile_win32.c
+  - src/core/lib/support/tmpfile_windows.c
   - src/core/lib/support/wrap_memcpy.c
   uses:
   - gpr_codegen
@@ -130,7 +133,7 @@
   - include/grpc/impl/codegen/atm.h
   - include/grpc/impl/codegen/atm_gcc_atomic.h
   - include/grpc/impl/codegen/atm_gcc_sync.h
-  - include/grpc/impl/codegen/atm_win32.h
+  - include/grpc/impl/codegen/atm_windows.h
   - include/grpc/impl/codegen/log.h
   - include/grpc/impl/codegen/port_platform.h
   - include/grpc/impl/codegen/slice.h
@@ -138,14 +141,20 @@
   - include/grpc/impl/codegen/sync.h
   - include/grpc/impl/codegen/sync_generic.h
   - include/grpc/impl/codegen/sync_posix.h
-  - include/grpc/impl/codegen/sync_win32.h
+  - include/grpc/impl/codegen/sync_windows.h
   - include/grpc/impl/codegen/time.h
+- name: grpc++_codegen_base_src
+  src:
+  - src/cpp/codegen/codegen_init.cc
+  uses:
+  - grpc++_codegen_base
 - name: grpc_base
   public_headers:
   - include/grpc/byte_buffer.h
   - include/grpc/byte_buffer_reader.h
   - include/grpc/compression.h
   - include/grpc/grpc.h
+  - include/grpc/grpc_posix.h
   - include/grpc/status.h
   headers:
   - src/core/lib/channel/channel_args.h
@@ -165,6 +174,7 @@
   - src/core/lib/iomgr/closure.h
   - src/core/lib/iomgr/endpoint.h
   - src/core/lib/iomgr/endpoint_pair.h
+  - src/core/lib/iomgr/ev_poll_and_epoll_posix.h
   - src/core/lib/iomgr/ev_poll_posix.h
   - src/core/lib/iomgr/ev_posix.h
   - src/core/lib/iomgr/exec_ctx.h
@@ -173,6 +183,7 @@
   - src/core/lib/iomgr/iomgr.h
   - src/core/lib/iomgr/iomgr_internal.h
   - src/core/lib/iomgr/iomgr_posix.h
+  - src/core/lib/iomgr/polling_entity.h
   - src/core/lib/iomgr/pollset.h
   - src/core/lib/iomgr/pollset_set.h
   - src/core/lib/iomgr/pollset_set_windows.h
@@ -181,7 +192,7 @@
   - src/core/lib/iomgr/sockaddr.h
   - src/core/lib/iomgr/sockaddr_posix.h
   - src/core/lib/iomgr/sockaddr_utils.h
-  - src/core/lib/iomgr/sockaddr_win32.h
+  - src/core/lib/iomgr/sockaddr_windows.h
   - src/core/lib/iomgr/socket_utils_posix.h
   - src/core/lib/iomgr/socket_windows.h
   - src/core/lib/iomgr/tcp_client.h
@@ -229,7 +240,7 @@
   - src/core/lib/channel/connected_channel.c
   - src/core/lib/channel/http_client_filter.c
   - src/core/lib/channel/http_server_filter.c
-  - src/core/lib/compression/compression_algorithm.c
+  - src/core/lib/compression/compression.c
   - src/core/lib/compression/message_compress.c
   - src/core/lib/debug/trace.c
   - src/core/lib/http/format_request.c
@@ -239,6 +250,7 @@
   - src/core/lib/iomgr/endpoint.c
   - src/core/lib/iomgr/endpoint_pair_posix.c
   - src/core/lib/iomgr/endpoint_pair_windows.c
+  - src/core/lib/iomgr/ev_poll_and_epoll_posix.c
   - src/core/lib/iomgr/ev_poll_posix.c
   - src/core/lib/iomgr/ev_posix.c
   - src/core/lib/iomgr/exec_ctx.c
@@ -247,6 +259,7 @@
   - src/core/lib/iomgr/iomgr.c
   - src/core/lib/iomgr/iomgr_posix.c
   - src/core/lib/iomgr/iomgr_windows.c
+  - src/core/lib/iomgr/polling_entity.c
   - src/core/lib/iomgr/pollset_set_windows.c
   - src/core/lib/iomgr/pollset_windows.c
   - src/core/lib/iomgr/resolve_address_posix.c
@@ -384,6 +397,16 @@
   uses:
   - grpc_base
   - grpc_client_config
+- name: grpc_load_reporting
+  headers:
+  - src/core/ext/load_reporting/load_reporting.h
+  - src/core/ext/load_reporting/load_reporting_filter.h
+  src:
+  - src/core/ext/load_reporting/load_reporting.c
+  - src/core/ext/load_reporting/load_reporting_filter.c
+  plugin: grpc_load_reporting_plugin
+  uses:
+  - grpc_base
 - name: grpc_resolver_dns_native
   src:
   - src/core/ext/resolver/dns/native/dns_resolver.c
@@ -400,7 +423,6 @@
   - grpc_client_config
 - name: grpc_secure
   public_headers:
-  - include/grpc/grpc_cronet.h
   - include/grpc/grpc_security.h
   - include/grpc/grpc_security_constants.h
   headers:
@@ -430,7 +452,7 @@
   - src/core/lib/security/credentials/credentials_metadata.c
   - src/core/lib/security/credentials/fake/fake_credentials.c
   - src/core/lib/security/credentials/google_default/credentials_posix.c
-  - src/core/lib/security/credentials/google_default/credentials_win32.c
+  - src/core/lib/security/credentials/google_default/credentials_windows.c
   - src/core/lib/security/credentials/google_default/google_default_credentials.c
   - src/core/lib/security/credentials/iam/iam_credentials.c
   - src/core/lib/security/credentials/jwt/json_token.c
@@ -540,6 +562,7 @@
 - name: grpc_transport_chttp2_client_insecure
   src:
   - src/core/ext/transport/chttp2/client/insecure/channel_create.c
+  - src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c
   uses:
   - grpc_transport_chttp2
   - grpc_base
@@ -555,6 +578,7 @@
 - name: grpc_transport_chttp2_server_insecure
   src:
   - src/core/ext/transport/chttp2/server/insecure/server_chttp2.c
+  - src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.c
   uses:
   - grpc_transport_chttp2
   - grpc_base
@@ -566,6 +590,10 @@
   - grpc_base
   - grpc_secure
 - name: grpc_transport_cronet_client_secure
+  public_headers:
+  - include/grpc/grpc_cronet.h
+  - include/grpc/grpc_security.h
+  - include/grpc/grpc_security_constants.h
   headers:
   - third_party/objective_c/Cronet/cronet_c_for_grpc.h
   src:
@@ -607,14 +635,15 @@
   - include/grpc++/client_context.h
   - include/grpc++/completion_queue.h
   - include/grpc++/create_channel.h
+  - include/grpc++/create_channel_posix.h
   - include/grpc++/generic/async_generic_service.h
   - include/grpc++/generic/generic_stub.h
   - include/grpc++/grpc++.h
   - include/grpc++/impl/call.h
   - include/grpc++/impl/client_unary_call.h
+  - include/grpc++/impl/codegen/core_codegen.h
   - include/grpc++/impl/grpc_library.h
   - include/grpc++/impl/method_handler_impl.h
-  - include/grpc++/impl/proto_utils.h
   - include/grpc++/impl/rpc_method.h
   - include/grpc++/impl/rpc_service_method.h
   - include/grpc++/impl/serialization_traits.h
@@ -635,10 +664,12 @@
   - include/grpc++/server.h
   - include/grpc++/server_builder.h
   - include/grpc++/server_context.h
+  - include/grpc++/server_posix.h
   - include/grpc++/support/async_stream.h
   - include/grpc++/support/async_unary_call.h
   - include/grpc++/support/byte_buffer.h
   - include/grpc++/support/channel_arguments.h
+  - include/grpc++/support/config.h
   - include/grpc++/support/slice.h
   - include/grpc++/support/status.h
   - include/grpc++/support/status_code_enum.h
@@ -648,7 +679,6 @@
   - include/grpc++/support/time.h
   headers:
   - src/cpp/client/create_channel_internal.h
-  - src/cpp/common/core_codegen.h
   - src/cpp/server/dynamic_thread_pool.h
   - src/cpp/server/thread_pool_interface.h
   src:
@@ -656,6 +686,7 @@
   - 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/generic_stub.cc
   - src/cpp/client/insecure_credentials.cc
@@ -671,6 +702,7 @@
   - src/cpp/server/server_builder.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/status.cc
@@ -679,9 +711,8 @@
   deps:
   - grpc
   uses:
-  - grpc++_codegen
-  - grpc++_config
-- name: grpc++_codegen
+  - grpc++_codegen_base
+- name: grpc++_codegen_base
   language: c++
   public_headers:
   - include/grpc++/impl/codegen/async_stream.h
@@ -693,11 +724,11 @@
   - include/grpc++/impl/codegen/client_unary_call.h
   - include/grpc++/impl/codegen/completion_queue.h
   - include/grpc++/impl/codegen/completion_queue_tag.h
+  - include/grpc++/impl/codegen/config.h
   - include/grpc++/impl/codegen/core_codegen_interface.h
   - include/grpc++/impl/codegen/create_auth_context.h
   - include/grpc++/impl/codegen/grpc_library.h
   - include/grpc++/impl/codegen/method_handler_impl.h
-  - include/grpc++/impl/codegen/proto_utils.h
   - include/grpc++/impl/codegen/rpc_method.h
   - include/grpc++/impl/codegen/rpc_service_method.h
   - include/grpc++/impl/codegen/security/auth_context.h
@@ -714,22 +745,18 @@
   - include/grpc++/impl/codegen/sync_no_cxx11.h
   - include/grpc++/impl/codegen/sync_stream.h
   - include/grpc++/impl/codegen/time.h
-  src:
-  - src/cpp/codegen/codegen_init.cc
   uses:
   - grpc_codegen
-  - grpc++_config_codegen
-- name: grpc++_config
+- name: grpc++_codegen_proto
   language: c++
   public_headers:
-  - include/grpc++/support/config.h
-  - include/grpc++/support/config_protobuf.h
+  - include/grpc++/impl/codegen/proto_utils.h
   uses:
-  - grpc++_config_codegen
-- name: grpc++_config_codegen
+  - grpc++_codegen_base
+  - grpc++_config_proto
+- name: grpc++_config_proto
   language: c++
   public_headers:
-  - include/grpc++/impl/codegen/config.h
   - include/grpc++/impl/codegen/config_protobuf.h
 libs:
 - name: gpr
@@ -764,12 +791,12 @@
   - grpc_transport_chttp2_client_secure
   - grpc_transport_chttp2_server_insecure
   - grpc_transport_chttp2_client_insecure
-  - grpc_transport_cronet_client_secure
   - grpc_lb_policy_grpclb
   - grpc_lb_policy_pick_first
   - grpc_lb_policy_round_robin
   - grpc_resolver_dns_native
   - grpc_resolver_sockaddr
+  - grpc_load_reporting
   - grpc_secure
   - census
   generate_plugin_registry: true
@@ -778,6 +805,22 @@
   - grpc.dependencies.openssl
   - grpc.dependencies.zlib
   vs_project_guid: '{29D16885-7228-4C31-81ED-5F9187C7F2A9}'
+- name: grpc_cronet
+  build: all
+  language: c
+  src:
+  - src/core/lib/surface/init.c
+  baselib: true
+  deps_linkage: static
+  dll: true
+  filegroups:
+  - grpc_base
+  - grpc_transport_cronet_client_secure
+  - grpc_transport_chttp2_client_secure
+  generate_plugin_registry: true
+  platforms:
+  - linux
+  secure: true
 - name: grpc_dll
   build: private
   language: c
@@ -844,6 +887,7 @@
   - grpc_transport_chttp2_client_insecure
   - grpc_resolver_dns_native
   - grpc_resolver_sockaddr
+  - grpc_load_reporting
   - grpc_lb_policy_grpclb
   - grpc_lb_policy_pick_first
   - grpc_lb_policy_round_robin
@@ -895,8 +939,8 @@
   build: all
   language: c++
   headers:
+  - include/grpc++/impl/codegen/core_codegen.h
   - src/cpp/client/secure_credentials.h
-  - src/cpp/common/core_codegen.h
   - src/cpp/common/secure_auth_context.h
   - src/cpp/server/secure_server_credentials.h
   src:
@@ -912,9 +956,28 @@
   dll: true
   filegroups:
   - grpc++_base
-  - grpc++_codegen
+  - grpc++_codegen_base
+  - grpc++_codegen_base_src
   secure: check
   vs_project_guid: '{C187A093-A0FE-489D-A40A-6E33DE0F9FEB}'
+- name: grpc++_reflection
+  build: all
+  language: c++
+  public_headers:
+  - include/grpc++/ext/proto_server_reflection_plugin.h
+  - include/grpc++/ext/reflection.grpc.pb.h
+  - include/grpc++/ext/reflection.pb.h
+  headers:
+  - src/cpp/ext/proto_server_reflection.h
+  src:
+  - src/cpp/ext/proto_server_reflection.cc
+  - src/cpp/ext/proto_server_reflection_plugin.cc
+  - src/cpp/ext/reflection.grpc.pb.cc
+  - src/cpp/ext/reflection.pb.cc
+  deps:
+  - grpc++
+  filegroups:
+  - grpc++_codegen_proto
 - name: grpc++_test_config
   build: private
   language: c++
@@ -928,7 +991,6 @@
   headers:
   - test/cpp/end2end/test_service_impl.h
   - test/cpp/util/byte_buffer_proto_helper.h
-  - test/cpp/util/cli_call.h
   - test/cpp/util/create_test_channel.h
   - test/cpp/util/string_ref_helper.h
   - test/cpp/util/subprocess.h
@@ -939,7 +1001,6 @@
   - src/proto/grpc/testing/duplicate/echo_duplicate.proto
   - test/cpp/end2end/test_service_impl.cc
   - test/cpp/util/byte_buffer_proto_helper.cc
-  - test/cpp/util/cli_call.cc
   - test/cpp/util/create_test_channel.cc
   - test/cpp/util/string_ref_helper.cc
   - test/cpp/util/subprocess.cc
@@ -947,6 +1008,11 @@
   deps:
   - grpc++
   - grpc_test_util
+  filegroups:
+  - grpc++_codegen_base
+  - grpc++_codegen_base_src
+  - grpc++_codegen_proto
+  - grpc++_config_proto
 - name: grpc++_unsecure
   build: all
   language: c++
@@ -959,9 +1025,22 @@
   dll: true
   filegroups:
   - grpc++_base
-  - grpc++_codegen
+  - grpc++_codegen_base
+  - grpc++_codegen_base_src
   secure: false
   vs_project_guid: '{6EE56155-DF7C-4F6E-BFC4-F6F776BEB211}'
+- name: grpc_cli_libs
+  build: private
+  language: c++
+  headers:
+  - test/cpp/util/cli_call.h
+  - test/cpp/util/proto_file_parser.h
+  src:
+  - test/cpp/util/cli_call.cc
+  - test/cpp/util/proto_file_parser.cc
+  deps:
+  - grpc++
+  - grpc_plugin_support
 - name: grpc_plugin_support
   build: protoc
   language: c++
@@ -989,7 +1068,7 @@
   - src/compiler/python_generator.cc
   - src/compiler/ruby_generator.cc
   filegroups:
-  - grpc++_config
+  - grpc++_config_proto
   secure: false
   vs_project_guid: '{B6E81D84-2ACB-41B8-8781-493A944C7817}'
   vs_props:
@@ -1066,7 +1145,7 @@
   - test/cpp/qps/histogram.h
   - test/cpp/qps/interarrival.h
   - test/cpp/qps/limit_cores.h
-  - test/cpp/qps/perf_db_client.h
+  - test/cpp/qps/parse_json.h
   - test/cpp/qps/qps_worker.h
   - test/cpp/qps/report.h
   - test/cpp/qps/server.h
@@ -1079,12 +1158,11 @@
   - src/proto/grpc/testing/stats.proto
   - src/proto/grpc/testing/control.proto
   - src/proto/grpc/testing/services.proto
-  - src/proto/grpc/testing/perf_db.proto
   - test/cpp/qps/client_async.cc
   - test/cpp/qps/client_sync.cc
   - test/cpp/qps/driver.cc
   - test/cpp/qps/limit_cores.cc
-  - test/cpp/qps/perf_db_client.cc
+  - test/cpp/qps/parse_json.cc
   - test/cpp/qps/qps_worker.cc
   - test/cpp/qps/report.cc
   - test/cpp/qps/server_async.cc
@@ -2384,6 +2462,7 @@
   src:
   - test/cpp/util/cli_call_test.cc
   deps:
+  - grpc_cli_libs
   - grpc++_test_util
   - grpc_test_util
   - grpc++
@@ -2429,7 +2508,6 @@
   - src/proto/grpc/testing/control.proto
   - src/proto/grpc/testing/messages.proto
   - src/proto/grpc/testing/payloads.proto
-  - src/proto/grpc/testing/perf_db.proto
   - src/proto/grpc/testing/services.proto
   - src/proto/grpc/testing/stats.proto
   - test/cpp/codegen/codegen_test_full.cc
@@ -2438,7 +2516,7 @@
   - grpc
   - gpr
   filegroups:
-  - grpc++_codegen
+  - grpc++_codegen_base
 - name: codegen_test_minimal
   gtest: true
   build: test
@@ -2447,12 +2525,12 @@
   - src/proto/grpc/testing/control.proto
   - src/proto/grpc/testing/messages.proto
   - src/proto/grpc/testing/payloads.proto
-  - src/proto/grpc/testing/perf_db.proto
   - src/proto/grpc/testing/services.proto
   - src/proto/grpc/testing/stats.proto
   - test/cpp/codegen/codegen_test_minimal.cc
   filegroups:
-  - grpc++_codegen
+  - grpc++_codegen_base
+  - grpc++_codegen_base_src
 - name: credentials_test
   gtest: true
   build: test
@@ -2552,6 +2630,7 @@
   src:
   - test/cpp/util/grpc_cli.cc
   deps:
+  - grpc_cli_libs
   - grpc++_test_util
   - grpc_test_util
   - grpc++
@@ -2737,6 +2816,23 @@
   - grpc
   - gpr_test_util
   - gpr
+- name: proto_server_reflection_test
+  gtest: true
+  build: test
+  language: c++
+  headers:
+  - test/cpp/util/proto_reflection_descriptor_database.h
+  src:
+  - test/cpp/end2end/proto_server_reflection_test.cc
+  - test/cpp/util/proto_reflection_descriptor_database.cc
+  deps:
+  - grpc++_reflection
+  - grpc++_test_util
+  - grpc_test_util
+  - grpc++
+  - grpc
+  - gpr_test_util
+  - gpr
 - name: qps_interarrival_test
   build: test
   run: false
@@ -2759,10 +2855,7 @@
   build: test
   run: false
   language: c++
-  headers:
-  - test/cpp/qps/parse_json.h
   src:
-  - test/cpp/qps/parse_json.cc
   - test/cpp/qps/qps_json_driver.cc
   deps:
   - qps
diff --git a/composer.json b/composer.json
index b77a59e..05ac003 100644
--- a/composer.json
+++ b/composer.json
@@ -2,7 +2,6 @@
   "name": "grpc/grpc",
   "type": "library",
   "description": "gRPC library for PHP",
-  "version": "0.15.0",
   "keywords": ["rpc"],
   "homepage": "http://grpc.io",
   "license": "BSD-3-Clause",
diff --git a/config.m4 b/config.m4
index 29df77c..cd653d31 100644
--- a/config.m4
+++ b/config.m4
@@ -48,7 +48,7 @@
     src/core/lib/support/cpu_windows.c \
     src/core/lib/support/env_linux.c \
     src/core/lib/support/env_posix.c \
-    src/core/lib/support/env_win32.c \
+    src/core/lib/support/env_windows.c \
     src/core/lib/support/histogram.c \
     src/core/lib/support/host_port.c \
     src/core/lib/support/load_file.c \
@@ -56,31 +56,31 @@
     src/core/lib/support/log_android.c \
     src/core/lib/support/log_linux.c \
     src/core/lib/support/log_posix.c \
-    src/core/lib/support/log_win32.c \
+    src/core/lib/support/log_windows.c \
     src/core/lib/support/murmur_hash.c \
     src/core/lib/support/slice.c \
     src/core/lib/support/slice_buffer.c \
     src/core/lib/support/stack_lockfree.c \
     src/core/lib/support/string.c \
     src/core/lib/support/string_posix.c \
-    src/core/lib/support/string_util_win32.c \
-    src/core/lib/support/string_win32.c \
+    src/core/lib/support/string_util_windows.c \
+    src/core/lib/support/string_windows.c \
     src/core/lib/support/subprocess_posix.c \
     src/core/lib/support/subprocess_windows.c \
     src/core/lib/support/sync.c \
     src/core/lib/support/sync_posix.c \
-    src/core/lib/support/sync_win32.c \
+    src/core/lib/support/sync_windows.c \
     src/core/lib/support/thd.c \
     src/core/lib/support/thd_posix.c \
-    src/core/lib/support/thd_win32.c \
+    src/core/lib/support/thd_windows.c \
     src/core/lib/support/time.c \
     src/core/lib/support/time_posix.c \
     src/core/lib/support/time_precise.c \
-    src/core/lib/support/time_win32.c \
+    src/core/lib/support/time_windows.c \
     src/core/lib/support/tls_pthread.c \
     src/core/lib/support/tmpfile_msys.c \
     src/core/lib/support/tmpfile_posix.c \
-    src/core/lib/support/tmpfile_win32.c \
+    src/core/lib/support/tmpfile_windows.c \
     src/core/lib/support/wrap_memcpy.c \
     src/core/lib/surface/init.c \
     src/core/lib/channel/channel_args.c \
@@ -90,7 +90,7 @@
     src/core/lib/channel/connected_channel.c \
     src/core/lib/channel/http_client_filter.c \
     src/core/lib/channel/http_server_filter.c \
-    src/core/lib/compression/compression_algorithm.c \
+    src/core/lib/compression/compression.c \
     src/core/lib/compression/message_compress.c \
     src/core/lib/debug/trace.c \
     src/core/lib/http/format_request.c \
@@ -100,6 +100,7 @@
     src/core/lib/iomgr/endpoint.c \
     src/core/lib/iomgr/endpoint_pair_posix.c \
     src/core/lib/iomgr/endpoint_pair_windows.c \
+    src/core/lib/iomgr/ev_poll_and_epoll_posix.c \
     src/core/lib/iomgr/ev_poll_posix.c \
     src/core/lib/iomgr/ev_posix.c \
     src/core/lib/iomgr/exec_ctx.c \
@@ -108,6 +109,7 @@
     src/core/lib/iomgr/iomgr.c \
     src/core/lib/iomgr/iomgr_posix.c \
     src/core/lib/iomgr/iomgr_windows.c \
+    src/core/lib/iomgr/polling_entity.c \
     src/core/lib/iomgr/pollset_set_windows.c \
     src/core/lib/iomgr/pollset_windows.c \
     src/core/lib/iomgr/resolve_address_posix.c \
@@ -194,7 +196,7 @@
     src/core/lib/security/credentials/credentials_metadata.c \
     src/core/lib/security/credentials/fake/fake_credentials.c \
     src/core/lib/security/credentials/google_default/credentials_posix.c \
-    src/core/lib/security/credentials/google_default/credentials_win32.c \
+    src/core/lib/security/credentials/google_default/credentials_windows.c \
     src/core/lib/security/credentials/google_default/google_default_credentials.c \
     src/core/lib/security/credentials/iam/iam_credentials.c \
     src/core/lib/security/credentials/jwt/json_token.c \
@@ -235,10 +237,9 @@
     src/core/ext/client_config/subchannel_index.c \
     src/core/ext/client_config/uri_parser.c \
     src/core/ext/transport/chttp2/server/insecure/server_chttp2.c \
+    src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.c \
     src/core/ext/transport/chttp2/client/insecure/channel_create.c \
-    src/core/ext/transport/cronet/client/secure/cronet_channel_create.c \
-    src/core/ext/transport/cronet/transport/cronet_api_dummy.c \
-    src/core/ext/transport/cronet/transport/cronet_transport.c \
+    src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c \
     src/core/ext/lb_policy/grpclb/load_balancer_api.c \
     src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c \
     third_party/nanopb/pb_common.c \
@@ -248,7 +249,10 @@
     src/core/ext/lb_policy/round_robin/round_robin.c \
     src/core/ext/resolver/dns/native/dns_resolver.c \
     src/core/ext/resolver/sockaddr/sockaddr_resolver.c \
+    src/core/ext/load_reporting/load_reporting.c \
+    src/core/ext/load_reporting/load_reporting_filter.c \
     src/core/ext/census/context.c \
+    src/core/ext/census/gen/census.pb.c \
     src/core/ext/census/grpc_context.c \
     src/core/ext/census/grpc_filter.c \
     src/core/ext/census/grpc_plugin.c \
@@ -564,11 +568,13 @@
 
   PHP_ADD_BUILD_DIR($ext_builddir/src/boringssl)
   PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/census)
+  PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/census/gen)
   PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/client_config)
   PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/lb_policy/grpclb)
   PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1)
   PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/lb_policy/pick_first)
   PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/lb_policy/round_robin)
+  PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/load_reporting)
   PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/resolver/dns/native)
   PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/resolver/sockaddr)
   PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/transport/chttp2/alpn)
@@ -577,8 +583,6 @@
   PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/transport/chttp2/server/insecure)
   PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/transport/chttp2/server/secure)
   PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/transport/chttp2/transport)
-  PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/transport/cronet/client/secure)
-  PHP_ADD_BUILD_DIR($ext_builddir/src/core/ext/transport/cronet/transport)
   PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/channel)
   PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/compression)
   PHP_ADD_BUILD_DIR($ext_builddir/src/core/lib/debug)
diff --git a/doc/c-style-guide.md b/doc/c-style-guide.md
index 87de889..d6f9bbd 100644
--- a/doc/c-style-guide.md
+++ b/doc/c-style-guide.md
@@ -11,7 +11,7 @@
 
 - Layout rules are defined by clang-format, and all code should be passed through
   clang-format. A (docker-based) script to do so is included in 
-  tools/distrib/clang_format_code.sh.
+  [tools/distrib/clang\_format\_code.sh] (../tools/distrib/clang_format_code.sh).
 
 Header Files
 ------------
diff --git a/doc/command_line_tool.md b/doc/command_line_tool.md
new file mode 100644
index 0000000..89a7054
--- /dev/null
+++ b/doc/command_line_tool.md
@@ -0,0 +1,77 @@
+# gRPC command line tool
+
+## Overview
+
+This document describes the command line tool that comes with gRPC repository. It is desireable to have command line
+tools written in other languages to roughly follow the same syntax and flags.
+
+At this point, the tool needs to be built from source, and it should be moved out to grpc-tools repository as a stand
+alone application once it is mature enough.
+
+## Core functionality
+
+The command line tool can do the following things:
+
+- Send unary rpc.
+- Attach metadata and display received metadata.
+- Handle common authentication to server.
+- Find the request/response types from a given proto file.
+- Read proto request in text form.
+- Read request in wire form (for protobuf messages, this means serialized binary form).
+- Display proto response in text form.
+- Write response in wire form to a file.
+
+The command line tool should support the following things:
+
+- List server services and methods through server reflection.
+- Infer request/response types from server reflection result.
+- Fine-grained auth control (such as, use this oauth token to talk to the server).
+- Send streaming rpc.
+
+## Code location
+
+To use the tool, you need to get the grpc repository and in the grpc directory execute
+
+```
+$ make grpc_cli
+```
+
+The main file can be found at
+https://github.com/grpc/grpc/blob/master/test/cpp/util/grpc_cli.cc
+
+## Usage
+
+### Basic usage
+
+Send a rpc to a helloworld server at `localhost:50051`:
+
+```
+$ bins/opt/grpc_cli call localhost:50051 SayHello examples/protos/helloworld.proto \
+    "name: 'world'"  --enable_ssl=false
+```
+
+On success, the tool will print out
+
+```
+Rpc succeeded with OK status
+Response: 
+ message: "Hello world"
+```
+
+The `localhost:50051` part indicates the server you are connecting to. `SayHello` is (part of) the
+gRPC method string. Then there is the path to the proto file containing the service definition,
+if it is not under current directory, you can use `--proto_path` to specify a new search root.
+`"name: 'world'"` is the text format of the request proto message. 
+We are not using ssl here by `--enable_ssl=false`. For information on more
+flags, look at the comments of `grpc_cli.cc`.
+
+### Send non-proto rpc
+
+For using gRPC with protocols other than probobuf, you will need the exact method name string
+and a file containing the raw bytes to be sent on the wire
+
+```
+$ bins/opt/grpc_cli call localhost:50051 /helloworld.Greeter/SayHello --input_binary_file=input.bin \
+    --output_binary_file=output.bin
+```
+On success, you will need to read or decode the response from the `output.bin` file.
diff --git a/doc/connectivity-semantics-and-api.md b/doc/connectivity-semantics-and-api.md
index 5427900..cc007ea 100644
--- a/doc/connectivity-semantics-and-api.md
+++ b/doc/connectivity-semantics-and-api.md
@@ -101,7 +101,7 @@
     <td>Shutdown triggered by application.</td>
   </tr>
   <tr>
-    <th>FATAL_FAILURE</th>
+    <th>SHUTDOWN</th>
     <td></td>
     <td></td>
     <td></td>
diff --git a/doc/cpp-style-guide.md b/doc/cpp-style-guide.md
new file mode 100644
index 0000000..9408c4a
--- /dev/null
+++ b/doc/cpp-style-guide.md
@@ -0,0 +1,85 @@
+GRPC C++ STYLE GUIDE
+=====================
+
+Background
+----------
+
+Here we document style rules for C++ usage in the gRPC C++ bindings
+and tests.
+
+General
+-------
+
+- The majority of gRPC's C++ requirements are drawn from the [Google C++ style
+guide] (https://google.github.io/styleguide/cppguide.html)
+   - However, gRPC has some additional requirements to maintain
+     [portability] (#portability)
+- As in C, layout rules are defined by clang-format, and all code
+should be passed through clang-format. A (docker-based) script to do
+so is included in [tools/distrib/clang\_format\_code.sh]
+(../tools/distrib/clang_format_code.sh).
+
+<a name="portability"></a>
+Portability Restrictions
+-------------------
+
+gRPC supports a large number of compilers, ranging from those that are
+missing many key C++11 features to those that have quite detailed
+analysis. As a result, gRPC compiles with a high level of warnings and
+treat all warnings as errors. gRPC also forbids the use of some common
+C++11 constructs. Here are some guidelines, to be extended as needed:
+- Do not use range-based for. Expressions of the form
+  ```c
+  for (auto& i: vec) {
+    // code
+  }
+  ```
+  
+  are not allowed and should be replaced with code such as
+  ```c
+  for (auto it = vec.begin; it != vec.end(); it++) {
+    auto& i = *it;
+    // code
+  }
+  ```
+  
+- Do not use lambda of any kind (no capture, explicit capture, or
+default capture). Other C++ functional features such as
+`std::function` or `std::bind` are allowed
+- Do not use brace-list initializers.
+- Do not compare a pointer to `nullptr` . This is because gcc 4.4
+  does not support `nullptr` directly and gRPC implements a subset of
+  its features in [include/grpc++/impl/codegen/config.h]
+  (../include/grpc++/impl/codegen/config.h). Instead, pointers should
+  be checked for validity using their implicit conversion to `bool`.
+  In other words, use `if (p)` rather than `if (p != nullptr)`
+- Do not use `final` or `override` as these are not supported by some
+  compilers. Instead use `GRPC_FINAL` and `GRPC_OVERRIDE` . These
+  compile down to the traditional C++ forms for compilers that support
+  them but are just elided if the compiler does not support those features.
+- In the [include] (../../../tree/master/include/grpc++) and [src]
+  (../../../tree/master/src/cpp) directory trees, you should also not
+  use certain STL objects like `std::mutex`, `std::lock_guard`,
+  `std::unique_lock`, `std::nullptr`, `std::thread` . Instead, use
+  `grpc::mutex`, `grpc::lock_guard`, etc., which are gRPC
+  implementations of the prominent features of these objects that are
+  not always available. You can use the `std` versions of those in  [test]
+  (../../../tree/master/test/cpp)
+- Similarly, in the same directories, do not use `std::chrono` unless
+  it is guarded by `#ifndef GRPC_CXX0X_NO_CHRONO` . For platforms that
+  lack`std::chrono,` there is a C-language timer called gpr_timespec that can
+  be used instead.
+- `std::unique_ptr` must be used with extreme care in any kind of
+  collection. For example `vector<std::unique_ptr>` does not work in
+  gcc 4.4 if the vector is constructed to its full size at
+  initialization but does work if elements are added to the vector
+  using functions like `push_back`. `map` and other pair-based
+  collections do not work with `unique_ptr` under gcc 4.4. The issue
+  is that many of these collection implementations assume a copy
+  constructor
+  to be available.
+- Don't use `std::this_thread` . Use `gpr_sleep_until` for sleeping a thread.
+- [Some adjacent character combinations cause problems]
+  (https://en.wikipedia.org/wiki/Digraphs_and_trigraphs#C). If declaring a
+  template against some class relative to the global namespace,
+  `<::name` will be non-portable. Separate the `<` from the `:` and use `< ::name`.
diff --git a/doc/interop-test-descriptions.md b/doc/interop-test-descriptions.md
index 6297b5c..7fd21c7 100644
--- a/doc/interop-test-descriptions.md
+++ b/doc/interop-test-descriptions.md
@@ -93,26 +93,24 @@
 ### large_compressed_unary
 
 This test verifies compressed unary calls succeed in sending messages. It
-sends one unary request for every combination of compression algorithm and
-payload type.
+sends one unary request for every payload type, with and without requesting a
+compressed response from the server.
 
 In all scenarios, whether compression was actually performed is determined by
-the compression bit in the response's message flags. The response's compression
-value indicates which algorithm was used if said compression bit is set.
+the compression bit in the response's message flags.
 
 
 Server features:
 * [UnaryCall][]
 * [Compressable Payload][]
 * [Uncompressable Payload][]
-* [Random Payload][]
 
 Procedure:
  1. Client calls UnaryCall with:
 
     ```
     {
-      response_compression: <one of {NONE, GZIP, DEFLATE}>
+      request_compressed_response: bool
       response_type: COMPRESSABLE
       response_size: 314159
       payload:{
@@ -123,11 +121,10 @@
     Client asserts:
     * call was successful
     * response payload type is COMPRESSABLE
-    * response compression is consistent with the requested one.
-    * if `response_compression == NONE`, the response MUST NOT have the
+    * if `request_compressed_response` is false, the response MUST NOT have the
       compressed message flag set.
-    * if `response_compression != NONE`, the response MUST have the compressed
-      message flag set.
+    * if `request_compressed_response` is true, the response MUST have the
+      compressed message flag set.
     * response payload body is 314159 bytes in size
     * clients are free to assert that the response payload body contents are
       zero and comparing the entire response message against a golden response
@@ -136,7 +133,7 @@
  2. Client calls UnaryCall with:
     ```
     {
-      response_compression: <one of {NONE, GZIP, DEFLATE}>
+      request_compressed_response: bool
       response_type: UNCOMPRESSABLE
       response_size: 314159
       payload:{
@@ -147,30 +144,12 @@
     Client asserts:
     * call was successful
     * response payload type is UNCOMPRESSABLE
-    * response compression is consistent with the requested one.
-    * the response MUST NOT have the compressed message flag set.
+    * the response MAY have the compressed message flag set. Some
+      implementations will choose to compress the payload even when the output
+      size if larger than the input.
     * response payload body is 314159 bytes in size
-    * clients are free to assert that the response payload body contents are
-      identical to the golden uncompressable data at `test/cpp/interop/rnd.dat`.
 
 
- 3. Client calls UnaryCall with:
-    ```
-    {
-      response_compression: <one of {NONE, GZIP, DEFLATE}>
-      response_type: RANDOM
-      response_size: 314159
-      payload:{
-        body: 271828 bytes of zeros
-      }
-    }
-    ```
-    Client asserts:
-    * call was successful
-    * response payload type is either COMPRESSABLE or UNCOMPRESSABLE
-    * the behavior is consistent with the randomly chosen incoming payload type,
-      as described in their respective sections.
-
 ### client_streaming
 
 This test verifies that client-only streaming succeeds.
@@ -245,7 +224,7 @@
         size: 31415
       }
       response_parameters:{
-        size: 9
+        size: 59
       }
       response_parameters:{
         size: 2653
@@ -272,7 +251,6 @@
 * [StreamingOutputCall][]
 * [Compressable Payload][]
 * [Uncompressable Payload][]
-* [Random Payload][]
 
 
 Procedure:
@@ -280,13 +258,13 @@
 
     ```
     {
-      response_compression: <one of {NONE, GZIP, DEFLATE}>
+      request_compressed_response: bool
       response_type:COMPRESSABLE
       response_parameters:{
         size: 31415
       }
       response_parameters:{
-        size: 9
+        size: 59
       }
       response_parameters:{
         size: 2653
@@ -301,12 +279,11 @@
     * call was successful
     * exactly four responses
     * response payloads are COMPRESSABLE
-    * response compression is consistent with the requested one.
-    * if `response_compression == NONE`, the response MUST NOT have the
-      compressed message flag set.
-    * if `response_compression != NONE`, the response MUST have the compressed
-      message flag set.
-    * response payload bodies are sized (in order): 31415, 9, 2653, 58979
+    * if `request_compressed_response` is false, the response's messages MUST
+      NOT have the compressed message flag set.
+    * if `request_compressed_response` is true, the response's messages MUST
+      have the compressed message flag set.
+    * response payload bodies are sized (in order): 31415, 59, 2653, 58979
     * clients are free to assert that the response payload body contents are
       zero and comparing the entire response messages against golden responses
 
@@ -315,13 +292,13 @@
 
     ```
     {
-      response_compression: <one of {NONE, GZIP, DEFLATE}>
+      request_compressed_response: bool
       response_type:UNCOMPRESSABLE
       response_parameters:{
         size: 31415
       }
       response_parameters:{
-        size: 9
+        size: 59
       }
       response_parameters:{
         size: 2653
@@ -336,40 +313,14 @@
     * call was successful
     * exactly four responses
     * response payloads are UNCOMPRESSABLE
-    * response compressions are consistent with the requested one.
-    * the responses MUST NOT have the compressed message flag set.
-    * response payload bodies are sized (in order): 31415, 9, 2653, 58979
+    * the response MAY have the compressed message flag set. Some
+      implementations will choose to compress the payload even when the output
+      size if larger than the input.
+    * response payload bodies are sized (in order): 31415, 59, 2653, 58979
     * clients are free to assert that the body of the responses are identical to
       the golden uncompressable data at `test/cpp/interop/rnd.dat`.
 
 
- 3. Client calls StreamingOutputCall with:
-
-    ```
-    {
-      response_compression: <one of {NONE, GZIP, DEFLATE}>
-      response_type:RANDOM
-      response_parameters:{
-        size: 31415
-      }
-      response_parameters:{
-        size: 9
-      }
-      response_parameters:{
-        size: 2653
-      }
-      response_parameters:{
-        size: 58979
-      }
-    }
-    ```
-
-    Client asserts:
-    * call was successful
-    * response payload type is either COMPRESSABLE or UNCOMPRESSABLE
-    * the behavior is consistent with the randomly chosen incoming payload type,
-      as described in their respective sections.
-
 ### ping_pong
 
 This test verifies that full duplex bidi is supported.
@@ -399,7 +350,7 @@
     {
       response_type: COMPRESSABLE
       response_parameters:{
-        size: 9
+        size: 59
       }
       payload:{
         body: 8 bytes of zeros
@@ -932,9 +883,9 @@
 [UnaryCall]: #unarycall
 
 Server implements UnaryCall which immediately returns a SimpleResponse with a
-payload body of size SimpleRequest.response_size bytes and type as appropriate
-for the SimpleRequest.response_type. If the server does not support the
-response_type, then it should fail the RPC with INVALID_ARGUMENT.
+payload body of size `SimpleRequest.response_size` bytes and type as appropriate
+for the `SimpleRequest.response_type`. If the server does not support the
+`response_type`, then it should fail the RPC with `INVALID_ARGUMENT`.
 
 ### StreamingInputCall
 [StreamingInputCall]: #streaminginputcall
@@ -974,15 +925,7 @@
 
 When the client requests UNCOMPRESSABLE payload, the response includes a payload
 of the size requested containing uncompressable data and the payload type is
-UNCOMPRESSABLE. A 512 kB dump from /dev/urandom is the current golden data,
-stored at `test/cpp/interop/rnd.dat`
-
-### Random Payload
-[Random Payload]: #random-payload
-
-When the client requests RANDOM payload, the response includes either a randomly
-chosen COMPRESSABLE or UNCOMPRESSABLE payload. The data and the payload type
-will be consistent with this choice.
+UNCOMPRESSABLE.
 
 ### Echo Status
 [Echo Status]: #echo-status
@@ -1004,8 +947,8 @@
 [Observe ResponseParameters.interval_us]: #observe-responseparametersinterval_us
 
 In StreamingOutputCall and FullDuplexCall, server delays sending a
-StreamingOutputCallResponse by the ResponseParameters's interval_us for that
-particular response, relative to the last response sent. That is, interval_us
+StreamingOutputCallResponse by the ResponseParameters's `interval_us` for that
+particular response, relative to the last response sent. That is, `interval_us`
 acts like a sleep *before* sending the response and accumulates from one
 response to the next.
 
@@ -1027,13 +970,13 @@
 #### Echo OAuth scope
 [Echo OAuth Scope]: #echo-oauth-scope
 
-If a SimpleRequest has fill_oauth_scope=true and that request was successfully
+If a SimpleRequest has `fill_oauth_scope=true` and that request was successfully
 authenticated via OAuth, then the SimpleResponse should have oauth_scope filled
 with the scope of the method being invoked.
 
 Although a general server-side feature, most test servers won't implement this
-feature. The TLS server grpc-test.sandbox.googleapis.com:443 supports this feature.
-It requires at least the OAuth scope
+feature. The TLS server `grpc-test.sandbox.googleapis.com:443` supports this
+feature. It requires at least the OAuth scope
 `https://www.googleapis.com/auth/xapi.zoo` for authentication to succeed.
 
 Discussion:
diff --git a/doc/statuscodes.md b/doc/statuscodes.md
index 84258c8..c918f9e 100644
--- a/doc/statuscodes.md
+++ b/doc/statuscodes.md
@@ -21,6 +21,8 @@
 | Flow-control protocol violation |	INTERNAL | Both |
 | Error parsing returned status	| UNKNOWN | Client |
 | Incorrect Auth metadata ( Credentials failed to get metadata, Incompatible credentials set on channel and call, Invalid host set in `:authority` metadata, etc.) | UNAUTHENTICATED | Both |
+| Request cardinality violation (method requires exactly one request but client sent some other number of requests) | UNIMPLEMENTED | Server|
+| Response cardinality violation (method requires exactly one response but server sent some other number of responses) | UNIMPLEMENTED | Client|
 | Error parsing response proto	| INTERNAL | Client|
 | Error parsing request proto	| INTERNAL | Server|
 
diff --git a/examples/cpp/helloworld/greeter_async_client.cc b/examples/cpp/helloworld/greeter_async_client.cc
index c1f5eb5..33de59f 100644
--- a/examples/cpp/helloworld/greeter_async_client.cc
+++ b/examples/cpp/helloworld/greeter_async_client.cc
@@ -87,7 +87,9 @@
     void* got_tag;
     bool ok = false;
     // Block until the next result is available in the completion queue "cq".
-    cq.Next(&got_tag, &ok);
+    // The return value of Next should always be checked. This return value
+    // tells us whether there is any kind of event or the cq_ is shutting down.
+    GPR_ASSERT(cq.Next(&got_tag, &ok));
 
     // Verify that the result from "cq" corresponds, by its tag, our previous
     // request.
diff --git a/examples/cpp/helloworld/greeter_async_server.cc b/examples/cpp/helloworld/greeter_async_server.cc
index 64e065b..ead4418 100644
--- a/examples/cpp/helloworld/greeter_async_server.cc
+++ b/examples/cpp/helloworld/greeter_async_server.cc
@@ -160,7 +160,9 @@
       // Block waiting to read the next event from the completion queue. The
       // event is uniquely identified by its tag, which in this case is the
       // memory address of a CallData instance.
-      cq_->Next(&tag, &ok);
+      // The return value of Next should always be checked. This return value
+      // tells us whether there is any kind of event or cq_ is shutting down.
+      GPR_ASSERT(cq_->Next(&tag, &ok));
       GPR_ASSERT(ok);
       static_cast<CallData*>(tag)->Proceed();
     }
diff --git a/examples/node/static_codegen/helloworld_grpc_pb.js b/examples/node/static_codegen/helloworld_grpc_pb.js
index 846f8b6..7a8dce4 100644
--- a/examples/node/static_codegen/helloworld_grpc_pb.js
+++ b/examples/node/static_codegen/helloworld_grpc_pb.js
@@ -1,5 +1,35 @@
 // GENERATED CODE -- DO NOT EDIT!
 
+// Original file comments:
+// 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.
+//
 'use strict';
 var grpc = require('grpc');
 var helloworld_pb = require('./helloworld_pb.js');
@@ -27,7 +57,9 @@
 }
 
 
+// The greeting service definition.
 var GreeterService = exports.GreeterService = {
+  // Sends a greeting
   sayHello: {
     path: '/helloworld.Greeter/SayHello',
     requestStream: false,
diff --git a/examples/node/static_codegen/helloworld_pb.js b/examples/node/static_codegen/helloworld_pb.js
index 6405bd9..d1e50c9 100644
--- a/examples/node/static_codegen/helloworld_pb.js
+++ b/examples/node/static_codegen/helloworld_pb.js
@@ -61,7 +61,7 @@
   };
 
   if (includeInstance) {
-    obj.$jspbMessageInstance = msg
+    obj.$jspbMessageInstance = msg;
   }
   return obj;
 };
@@ -220,7 +220,7 @@
   };
 
   if (includeInstance) {
-    obj.$jspbMessageInstance = msg
+    obj.$jspbMessageInstance = msg;
   }
   return obj;
 };
diff --git a/examples/node/static_codegen/route_guide/route_guide_grpc_pb.js b/examples/node/static_codegen/route_guide/route_guide_grpc_pb.js
index 1dd7133..ce030c8 100644
--- a/examples/node/static_codegen/route_guide/route_guide_grpc_pb.js
+++ b/examples/node/static_codegen/route_guide/route_guide_grpc_pb.js
@@ -1,5 +1,35 @@
 // GENERATED CODE -- DO NOT EDIT!
 
+// Original file comments:
+// 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.
+//
 'use strict';
 var grpc = require('grpc');
 var route_guide_pb = require('./route_guide_pb.js');
@@ -60,7 +90,14 @@
 }
 
 
+// Interface exported by the server.
 var RouteGuideService = exports.RouteGuideService = {
+  // A simple RPC.
+  //
+  // Obtains the feature at a given position.
+  //
+  // A feature with an empty name is returned if there's no feature at the given
+  // position.
   getFeature: {
     path: '/routeguide.RouteGuide/GetFeature',
     requestStream: false,
@@ -72,6 +109,12 @@
     responseSerialize: serialize_Feature,
     responseDeserialize: deserialize_Feature,
   },
+  // A server-to-client streaming RPC.
+  //
+  // Obtains the Features available within the given Rectangle.  Results are
+  // streamed rather than returned at once (e.g. in a response message with a
+  // repeated field), as the rectangle may cover a large area and contain a
+  // huge number of features.
   listFeatures: {
     path: '/routeguide.RouteGuide/ListFeatures',
     requestStream: false,
@@ -83,6 +126,10 @@
     responseSerialize: serialize_Feature,
     responseDeserialize: deserialize_Feature,
   },
+  // A client-to-server streaming RPC.
+  //
+  // Accepts a stream of Points on a route being traversed, returning a
+  // RouteSummary when traversal is completed.
   recordRoute: {
     path: '/routeguide.RouteGuide/RecordRoute',
     requestStream: true,
@@ -94,6 +141,10 @@
     responseSerialize: serialize_RouteSummary,
     responseDeserialize: deserialize_RouteSummary,
   },
+  // A Bidirectional streaming RPC.
+  //
+  // Accepts a stream of RouteNotes sent while a route is being traversed,
+  // while receiving other RouteNotes (e.g. from other users).
   routeChat: {
     path: '/routeguide.RouteGuide/RouteChat',
     requestStream: true,
diff --git a/examples/node/static_codegen/route_guide/route_guide_pb.js b/examples/node/static_codegen/route_guide/route_guide_pb.js
index f604cd6..2e2f9a1 100644
--- a/examples/node/static_codegen/route_guide/route_guide_pb.js
+++ b/examples/node/static_codegen/route_guide/route_guide_pb.js
@@ -65,7 +65,7 @@
   };
 
   if (includeInstance) {
-    obj.$jspbMessageInstance = msg
+    obj.$jspbMessageInstance = msg;
   }
   return obj;
 };
@@ -251,7 +251,7 @@
   };
 
   if (includeInstance) {
-    obj.$jspbMessageInstance = msg
+    obj.$jspbMessageInstance = msg;
   }
   return obj;
 };
@@ -453,7 +453,7 @@
   };
 
   if (includeInstance) {
-    obj.$jspbMessageInstance = msg
+    obj.$jspbMessageInstance = msg;
   }
   return obj;
 };
@@ -647,7 +647,7 @@
   };
 
   if (includeInstance) {
-    obj.$jspbMessageInstance = msg
+    obj.$jspbMessageInstance = msg;
   }
   return obj;
 };
@@ -843,7 +843,7 @@
   };
 
   if (includeInstance) {
-    obj.$jspbMessageInstance = msg
+    obj.$jspbMessageInstance = msg;
   }
   return obj;
 };
diff --git a/examples/php/greeter_client.php b/examples/php/greeter_client.php
index 718ef88..a5c0865 100644
--- a/examples/php/greeter_client.php
+++ b/examples/php/greeter_client.php
@@ -32,19 +32,21 @@
  *
  */
 
-require dirname(__FILE__) . '/vendor/autoload.php';
-require dirname(__FILE__) . '/helloworld.php';
+require dirname(__FILE__).'/vendor/autoload.php';
+require dirname(__FILE__).'/helloworld.php';
 
-function greet($name) {
-  $client = new helloworld\GreeterClient('localhost:50051', [
-    'credentials' => Grpc\ChannelCredentials::createInsecure()
-  ]);
-  $request = new helloworld\HelloRequest();
-  $request->setName($name);
-  list($reply, $status) = $client->SayHello($request)->wait();
-  $message = $reply->getMessage();
-  return $message;
+function greet($name)
+{
+    $client = new helloworld\GreeterClient('localhost:50051', [
+        'credentials' => Grpc\ChannelCredentials::createInsecure(),
+    ]);
+    $request = new helloworld\HelloRequest();
+    $request->setName($name);
+    list($reply, $status) = $client->SayHello($request)->wait();
+    $message = $reply->getMessage();
+
+    return $message;
 }
 
 $name = !empty($argv[1]) ? $argv[1] : 'world';
-print(greet($name)."\n");
+echo greet($name)."\n";
diff --git a/examples/php/helloworld.php b/examples/php/helloworld.php
index 50923e6..697f52a 100644
--- a/examples/php/helloworld.php
+++ b/examples/php/helloworld.php
@@ -5,154 +5,164 @@
 
 namespace helloworld {
 
-  class HelloRequest extends \DrSlump\Protobuf\Message {
-
-    /**  @var string */
+  class HelloRequest extends \DrSlump\Protobuf\Message
+  {
+      /**  @var string */
     public $name = null;
-    
 
     /** @var \Closure[] */
     protected static $__extensions = array();
 
-    public static function descriptor()
-    {
-      $descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'helloworld.HelloRequest');
+      public static function descriptor()
+      {
+          $descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'helloworld.HelloRequest');
 
       // OPTIONAL STRING name = 1
       $f = new \DrSlump\Protobuf\Field();
-      $f->number    = 1;
-      $f->name      = "name";
-      $f->type      = \DrSlump\Protobuf::TYPE_STRING;
-      $f->rule      = \DrSlump\Protobuf::RULE_OPTIONAL;
-      $descriptor->addField($f);
+          $f->number = 1;
+          $f->name = 'name';
+          $f->type = \DrSlump\Protobuf::TYPE_STRING;
+          $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL;
+          $descriptor->addField($f);
 
-      foreach (self::$__extensions as $cb) {
-        $descriptor->addField($cb(), true);
+          foreach (self::$__extensions as $cb) {
+              $descriptor->addField($cb(), true);
+          }
+
+          return $descriptor;
       }
 
-      return $descriptor;
+    /**
+     * Check if <name> has a value.
+     *
+     * @return bool
+     */
+    public function hasName()
+    {
+        return $this->_has(1);
     }
 
     /**
-     * Check if <name> has a value
-     *
-     * @return boolean
-     */
-    public function hasName(){
-      return $this->_has(1);
-    }
-    
-    /**
-     * Clear <name> value
+     * Clear <name> value.
      *
      * @return \helloworld\HelloRequest
      */
-    public function clearName(){
-      return $this->_clear(1);
+    public function clearName()
+    {
+        return $this->_clear(1);
     }
-    
+
     /**
-     * Get <name> value
+     * Get <name> value.
      *
      * @return string
      */
-    public function getName(){
-      return $this->_get(1);
+    public function getName()
+    {
+        return $this->_get(1);
     }
-    
+
     /**
-     * Set <name> value
+     * Set <name> value.
      *
      * @param string $value
+     *
      * @return \helloworld\HelloRequest
      */
-    public function setName( $value){
-      return $this->_set(1, $value);
+    public function setName($value)
+    {
+        return $this->_set(1, $value);
     }
   }
 }
 
 namespace helloworld {
 
-  class HelloReply extends \DrSlump\Protobuf\Message {
-
-    /**  @var string */
+  class HelloReply extends \DrSlump\Protobuf\Message
+  {
+      /**  @var string */
     public $message = null;
-    
 
     /** @var \Closure[] */
     protected static $__extensions = array();
 
-    public static function descriptor()
-    {
-      $descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'helloworld.HelloReply');
+      public static function descriptor()
+      {
+          $descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'helloworld.HelloReply');
 
       // OPTIONAL STRING message = 1
       $f = new \DrSlump\Protobuf\Field();
-      $f->number    = 1;
-      $f->name      = "message";
-      $f->type      = \DrSlump\Protobuf::TYPE_STRING;
-      $f->rule      = \DrSlump\Protobuf::RULE_OPTIONAL;
-      $descriptor->addField($f);
+          $f->number = 1;
+          $f->name = 'message';
+          $f->type = \DrSlump\Protobuf::TYPE_STRING;
+          $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL;
+          $descriptor->addField($f);
 
-      foreach (self::$__extensions as $cb) {
-        $descriptor->addField($cb(), true);
+          foreach (self::$__extensions as $cb) {
+              $descriptor->addField($cb(), true);
+          }
+
+          return $descriptor;
       }
 
-      return $descriptor;
+    /**
+     * Check if <message> has a value.
+     *
+     * @return bool
+     */
+    public function hasMessage()
+    {
+        return $this->_has(1);
     }
 
     /**
-     * Check if <message> has a value
-     *
-     * @return boolean
-     */
-    public function hasMessage(){
-      return $this->_has(1);
-    }
-    
-    /**
-     * Clear <message> value
+     * Clear <message> value.
      *
      * @return \helloworld\HelloReply
      */
-    public function clearMessage(){
-      return $this->_clear(1);
+    public function clearMessage()
+    {
+        return $this->_clear(1);
     }
-    
+
     /**
-     * Get <message> value
+     * Get <message> value.
      *
      * @return string
      */
-    public function getMessage(){
-      return $this->_get(1);
+    public function getMessage()
+    {
+        return $this->_get(1);
     }
-    
+
     /**
-     * Set <message> value
+     * Set <message> value.
      *
      * @param string $value
+     *
      * @return \helloworld\HelloReply
      */
-    public function setMessage( $value){
-      return $this->_set(1, $value);
+    public function setMessage($value)
+    {
+        return $this->_set(1, $value);
     }
   }
 }
 
 namespace helloworld {
 
-  class GreeterClient extends \Grpc\BaseStub {
-
-    public function __construct($hostname, $opts) {
-      parent::__construct($hostname, $opts);
-    }
+  class GreeterClient extends \Grpc\BaseStub
+  {
+      public function __construct($hostname, $opts)
+      {
+          parent::__construct($hostname, $opts);
+      }
     /**
      * @param helloworld\HelloRequest $input
      */
-    public function SayHello(\helloworld\HelloRequest $argument, $metadata = array(), $options = array()) {
-      return $this->_simpleRequest('/helloworld.Greeter/SayHello', $argument, '\helloworld\HelloReply::deserialize', $metadata, $options);
+    public function SayHello(\helloworld\HelloRequest $argument, $metadata = array(), $options = array())
+    {
+        return $this->_simpleRequest('/helloworld.Greeter/SayHello', $argument, '\helloworld\HelloReply::deserialize', $metadata, $options);
     }
   }
 }
diff --git a/examples/php/route_guide/route_guide.php b/examples/php/route_guide/route_guide.php
index 0de3198..65045d0 100644
--- a/examples/php/route_guide/route_guide.php
+++ b/examples/php/route_guide/route_guide.php
@@ -5,725 +5,785 @@
 
 namespace routeguide {
 
-  class Point extends \DrSlump\Protobuf\Message {
+  class Point extends \DrSlump\Protobuf\Message
+  {
+      /**  @var int */
+    public $latitude = 0;
 
     /**  @var int */
-    public $latitude = 0;
-    
-    /**  @var int */
     public $longitude = 0;
-    
 
     /** @var \Closure[] */
     protected static $__extensions = array();
 
-    public static function descriptor()
-    {
-      $descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'routeguide.Point');
+      public static function descriptor()
+      {
+          $descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'routeguide.Point');
 
       // OPTIONAL INT32 latitude = 1
       $f = new \DrSlump\Protobuf\Field();
-      $f->number    = 1;
-      $f->name      = "latitude";
-      $f->type      = \DrSlump\Protobuf::TYPE_INT32;
-      $f->rule      = \DrSlump\Protobuf::RULE_OPTIONAL;
-      $f->default   = 0;
-      $descriptor->addField($f);
+          $f->number = 1;
+          $f->name = 'latitude';
+          $f->type = \DrSlump\Protobuf::TYPE_INT32;
+          $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL;
+          $f->default = 0;
+          $descriptor->addField($f);
 
       // OPTIONAL INT32 longitude = 2
       $f = new \DrSlump\Protobuf\Field();
-      $f->number    = 2;
-      $f->name      = "longitude";
-      $f->type      = \DrSlump\Protobuf::TYPE_INT32;
-      $f->rule      = \DrSlump\Protobuf::RULE_OPTIONAL;
-      $f->default   = 0;
-      $descriptor->addField($f);
+          $f->number = 2;
+          $f->name = 'longitude';
+          $f->type = \DrSlump\Protobuf::TYPE_INT32;
+          $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL;
+          $f->default = 0;
+          $descriptor->addField($f);
 
-      foreach (self::$__extensions as $cb) {
-        $descriptor->addField($cb(), true);
+          foreach (self::$__extensions as $cb) {
+              $descriptor->addField($cb(), true);
+          }
+
+          return $descriptor;
       }
 
-      return $descriptor;
+    /**
+     * Check if <latitude> has a value.
+     *
+     * @return bool
+     */
+    public function hasLatitude()
+    {
+        return $this->_has(1);
     }
 
     /**
-     * Check if <latitude> has a value
-     *
-     * @return boolean
-     */
-    public function hasLatitude(){
-      return $this->_has(1);
-    }
-    
-    /**
-     * Clear <latitude> value
+     * Clear <latitude> value.
      *
      * @return \routeguide\Point
      */
-    public function clearLatitude(){
-      return $this->_clear(1);
+    public function clearLatitude()
+    {
+        return $this->_clear(1);
     }
-    
+
     /**
-     * Get <latitude> value
+     * Get <latitude> value.
      *
      * @return int
      */
-    public function getLatitude(){
-      return $this->_get(1);
+    public function getLatitude()
+    {
+        return $this->_get(1);
     }
-    
+
     /**
-     * Set <latitude> value
+     * Set <latitude> value.
      *
      * @param int $value
-     * @return \routeguide\Point
-     */
-    public function setLatitude( $value){
-      return $this->_set(1, $value);
-    }
-    
-    /**
-     * Check if <longitude> has a value
-     *
-     * @return boolean
-     */
-    public function hasLongitude(){
-      return $this->_has(2);
-    }
-    
-    /**
-     * Clear <longitude> value
      *
      * @return \routeguide\Point
      */
-    public function clearLongitude(){
-      return $this->_clear(2);
+    public function setLatitude($value)
+    {
+        return $this->_set(1, $value);
     }
-    
+
     /**
-     * Get <longitude> value
+     * Check if <longitude> has a value.
+     *
+     * @return bool
+     */
+    public function hasLongitude()
+    {
+        return $this->_has(2);
+    }
+
+    /**
+     * Clear <longitude> value.
+     *
+     * @return \routeguide\Point
+     */
+    public function clearLongitude()
+    {
+        return $this->_clear(2);
+    }
+
+    /**
+     * Get <longitude> value.
      *
      * @return int
      */
-    public function getLongitude(){
-      return $this->_get(2);
+    public function getLongitude()
+    {
+        return $this->_get(2);
     }
-    
+
     /**
-     * Set <longitude> value
+     * Set <longitude> value.
      *
      * @param int $value
+     *
      * @return \routeguide\Point
      */
-    public function setLongitude( $value){
-      return $this->_set(2, $value);
+    public function setLongitude($value)
+    {
+        return $this->_set(2, $value);
     }
   }
 }
 
 namespace routeguide {
 
-  class Rectangle extends \DrSlump\Protobuf\Message {
+  class Rectangle extends \DrSlump\Protobuf\Message
+  {
+      /**  @var \routeguide\Point */
+    public $lo = null;
 
     /**  @var \routeguide\Point */
-    public $lo = null;
-    
-    /**  @var \routeguide\Point */
     public $hi = null;
-    
 
     /** @var \Closure[] */
     protected static $__extensions = array();
 
-    public static function descriptor()
-    {
-      $descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'routeguide.Rectangle');
+      public static function descriptor()
+      {
+          $descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'routeguide.Rectangle');
 
       // OPTIONAL MESSAGE lo = 1
       $f = new \DrSlump\Protobuf\Field();
-      $f->number    = 1;
-      $f->name      = "lo";
-      $f->type      = \DrSlump\Protobuf::TYPE_MESSAGE;
-      $f->rule      = \DrSlump\Protobuf::RULE_OPTIONAL;
-      $f->reference = '\routeguide\Point';
-      $descriptor->addField($f);
+          $f->number = 1;
+          $f->name = 'lo';
+          $f->type = \DrSlump\Protobuf::TYPE_MESSAGE;
+          $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL;
+          $f->reference = '\routeguide\Point';
+          $descriptor->addField($f);
 
       // OPTIONAL MESSAGE hi = 2
       $f = new \DrSlump\Protobuf\Field();
-      $f->number    = 2;
-      $f->name      = "hi";
-      $f->type      = \DrSlump\Protobuf::TYPE_MESSAGE;
-      $f->rule      = \DrSlump\Protobuf::RULE_OPTIONAL;
-      $f->reference = '\routeguide\Point';
-      $descriptor->addField($f);
+          $f->number = 2;
+          $f->name = 'hi';
+          $f->type = \DrSlump\Protobuf::TYPE_MESSAGE;
+          $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL;
+          $f->reference = '\routeguide\Point';
+          $descriptor->addField($f);
 
-      foreach (self::$__extensions as $cb) {
-        $descriptor->addField($cb(), true);
+          foreach (self::$__extensions as $cb) {
+              $descriptor->addField($cb(), true);
+          }
+
+          return $descriptor;
       }
 
-      return $descriptor;
+    /**
+     * Check if <lo> has a value.
+     *
+     * @return bool
+     */
+    public function hasLo()
+    {
+        return $this->_has(1);
     }
 
     /**
-     * Check if <lo> has a value
-     *
-     * @return boolean
-     */
-    public function hasLo(){
-      return $this->_has(1);
-    }
-    
-    /**
-     * Clear <lo> value
+     * Clear <lo> value.
      *
      * @return \routeguide\Rectangle
      */
-    public function clearLo(){
-      return $this->_clear(1);
+    public function clearLo()
+    {
+        return $this->_clear(1);
     }
-    
+
     /**
-     * Get <lo> value
+     * Get <lo> value.
      *
      * @return \routeguide\Point
      */
-    public function getLo(){
-      return $this->_get(1);
+    public function getLo()
+    {
+        return $this->_get(1);
     }
-    
+
     /**
-     * Set <lo> value
+     * Set <lo> value.
      *
      * @param \routeguide\Point $value
-     * @return \routeguide\Rectangle
-     */
-    public function setLo(\routeguide\Point $value){
-      return $this->_set(1, $value);
-    }
-    
-    /**
-     * Check if <hi> has a value
-     *
-     * @return boolean
-     */
-    public function hasHi(){
-      return $this->_has(2);
-    }
-    
-    /**
-     * Clear <hi> value
      *
      * @return \routeguide\Rectangle
      */
-    public function clearHi(){
-      return $this->_clear(2);
+    public function setLo(\routeguide\Point $value)
+    {
+        return $this->_set(1, $value);
     }
-    
+
     /**
-     * Get <hi> value
+     * Check if <hi> has a value.
+     *
+     * @return bool
+     */
+    public function hasHi()
+    {
+        return $this->_has(2);
+    }
+
+    /**
+     * Clear <hi> value.
+     *
+     * @return \routeguide\Rectangle
+     */
+    public function clearHi()
+    {
+        return $this->_clear(2);
+    }
+
+    /**
+     * Get <hi> value.
      *
      * @return \routeguide\Point
      */
-    public function getHi(){
-      return $this->_get(2);
+    public function getHi()
+    {
+        return $this->_get(2);
     }
-    
+
     /**
-     * Set <hi> value
+     * Set <hi> value.
      *
      * @param \routeguide\Point $value
+     *
      * @return \routeguide\Rectangle
      */
-    public function setHi(\routeguide\Point $value){
-      return $this->_set(2, $value);
+    public function setHi(\routeguide\Point $value)
+    {
+        return $this->_set(2, $value);
     }
   }
 }
 
 namespace routeguide {
 
-  class Feature extends \DrSlump\Protobuf\Message {
-
-    /**  @var string */
+  class Feature extends \DrSlump\Protobuf\Message
+  {
+      /**  @var string */
     public $name = null;
-    
+
     /**  @var \routeguide\Point */
     public $location = null;
-    
 
     /** @var \Closure[] */
     protected static $__extensions = array();
 
-    public static function descriptor()
-    {
-      $descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'routeguide.Feature');
+      public static function descriptor()
+      {
+          $descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'routeguide.Feature');
 
       // OPTIONAL STRING name = 1
       $f = new \DrSlump\Protobuf\Field();
-      $f->number    = 1;
-      $f->name      = "name";
-      $f->type      = \DrSlump\Protobuf::TYPE_STRING;
-      $f->rule      = \DrSlump\Protobuf::RULE_OPTIONAL;
-      $descriptor->addField($f);
+          $f->number = 1;
+          $f->name = 'name';
+          $f->type = \DrSlump\Protobuf::TYPE_STRING;
+          $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL;
+          $descriptor->addField($f);
 
       // OPTIONAL MESSAGE location = 2
       $f = new \DrSlump\Protobuf\Field();
-      $f->number    = 2;
-      $f->name      = "location";
-      $f->type      = \DrSlump\Protobuf::TYPE_MESSAGE;
-      $f->rule      = \DrSlump\Protobuf::RULE_OPTIONAL;
-      $f->reference = '\routeguide\Point';
-      $descriptor->addField($f);
+          $f->number = 2;
+          $f->name = 'location';
+          $f->type = \DrSlump\Protobuf::TYPE_MESSAGE;
+          $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL;
+          $f->reference = '\routeguide\Point';
+          $descriptor->addField($f);
 
-      foreach (self::$__extensions as $cb) {
-        $descriptor->addField($cb(), true);
+          foreach (self::$__extensions as $cb) {
+              $descriptor->addField($cb(), true);
+          }
+
+          return $descriptor;
       }
 
-      return $descriptor;
+    /**
+     * Check if <name> has a value.
+     *
+     * @return bool
+     */
+    public function hasName()
+    {
+        return $this->_has(1);
     }
 
     /**
-     * Check if <name> has a value
-     *
-     * @return boolean
-     */
-    public function hasName(){
-      return $this->_has(1);
-    }
-    
-    /**
-     * Clear <name> value
+     * Clear <name> value.
      *
      * @return \routeguide\Feature
      */
-    public function clearName(){
-      return $this->_clear(1);
+    public function clearName()
+    {
+        return $this->_clear(1);
     }
-    
+
     /**
-     * Get <name> value
+     * Get <name> value.
      *
      * @return string
      */
-    public function getName(){
-      return $this->_get(1);
+    public function getName()
+    {
+        return $this->_get(1);
     }
-    
+
     /**
-     * Set <name> value
+     * Set <name> value.
      *
      * @param string $value
-     * @return \routeguide\Feature
-     */
-    public function setName( $value){
-      return $this->_set(1, $value);
-    }
-    
-    /**
-     * Check if <location> has a value
-     *
-     * @return boolean
-     */
-    public function hasLocation(){
-      return $this->_has(2);
-    }
-    
-    /**
-     * Clear <location> value
      *
      * @return \routeguide\Feature
      */
-    public function clearLocation(){
-      return $this->_clear(2);
+    public function setName($value)
+    {
+        return $this->_set(1, $value);
     }
-    
+
     /**
-     * Get <location> value
+     * Check if <location> has a value.
+     *
+     * @return bool
+     */
+    public function hasLocation()
+    {
+        return $this->_has(2);
+    }
+
+    /**
+     * Clear <location> value.
+     *
+     * @return \routeguide\Feature
+     */
+    public function clearLocation()
+    {
+        return $this->_clear(2);
+    }
+
+    /**
+     * Get <location> value.
      *
      * @return \routeguide\Point
      */
-    public function getLocation(){
-      return $this->_get(2);
+    public function getLocation()
+    {
+        return $this->_get(2);
     }
-    
+
     /**
-     * Set <location> value
+     * Set <location> value.
      *
      * @param \routeguide\Point $value
+     *
      * @return \routeguide\Feature
      */
-    public function setLocation(\routeguide\Point $value){
-      return $this->_set(2, $value);
+    public function setLocation(\routeguide\Point $value)
+    {
+        return $this->_set(2, $value);
     }
   }
 }
 
 namespace routeguide {
 
-  class RouteNote extends \DrSlump\Protobuf\Message {
-
-    /**  @var \routeguide\Point */
+  class RouteNote extends \DrSlump\Protobuf\Message
+  {
+      /**  @var \routeguide\Point */
     public $location = null;
-    
+
     /**  @var string */
     public $message = null;
-    
 
     /** @var \Closure[] */
     protected static $__extensions = array();
 
-    public static function descriptor()
-    {
-      $descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'routeguide.RouteNote');
+      public static function descriptor()
+      {
+          $descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'routeguide.RouteNote');
 
       // OPTIONAL MESSAGE location = 1
       $f = new \DrSlump\Protobuf\Field();
-      $f->number    = 1;
-      $f->name      = "location";
-      $f->type      = \DrSlump\Protobuf::TYPE_MESSAGE;
-      $f->rule      = \DrSlump\Protobuf::RULE_OPTIONAL;
-      $f->reference = '\routeguide\Point';
-      $descriptor->addField($f);
+          $f->number = 1;
+          $f->name = 'location';
+          $f->type = \DrSlump\Protobuf::TYPE_MESSAGE;
+          $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL;
+          $f->reference = '\routeguide\Point';
+          $descriptor->addField($f);
 
       // OPTIONAL STRING message = 2
       $f = new \DrSlump\Protobuf\Field();
-      $f->number    = 2;
-      $f->name      = "message";
-      $f->type      = \DrSlump\Protobuf::TYPE_STRING;
-      $f->rule      = \DrSlump\Protobuf::RULE_OPTIONAL;
-      $descriptor->addField($f);
+          $f->number = 2;
+          $f->name = 'message';
+          $f->type = \DrSlump\Protobuf::TYPE_STRING;
+          $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL;
+          $descriptor->addField($f);
 
-      foreach (self::$__extensions as $cb) {
-        $descriptor->addField($cb(), true);
+          foreach (self::$__extensions as $cb) {
+              $descriptor->addField($cb(), true);
+          }
+
+          return $descriptor;
       }
 
-      return $descriptor;
+    /**
+     * Check if <location> has a value.
+     *
+     * @return bool
+     */
+    public function hasLocation()
+    {
+        return $this->_has(1);
     }
 
     /**
-     * Check if <location> has a value
-     *
-     * @return boolean
-     */
-    public function hasLocation(){
-      return $this->_has(1);
-    }
-    
-    /**
-     * Clear <location> value
+     * Clear <location> value.
      *
      * @return \routeguide\RouteNote
      */
-    public function clearLocation(){
-      return $this->_clear(1);
+    public function clearLocation()
+    {
+        return $this->_clear(1);
     }
-    
+
     /**
-     * Get <location> value
+     * Get <location> value.
      *
      * @return \routeguide\Point
      */
-    public function getLocation(){
-      return $this->_get(1);
+    public function getLocation()
+    {
+        return $this->_get(1);
     }
-    
+
     /**
-     * Set <location> value
+     * Set <location> value.
      *
      * @param \routeguide\Point $value
-     * @return \routeguide\RouteNote
-     */
-    public function setLocation(\routeguide\Point $value){
-      return $this->_set(1, $value);
-    }
-    
-    /**
-     * Check if <message> has a value
-     *
-     * @return boolean
-     */
-    public function hasMessage(){
-      return $this->_has(2);
-    }
-    
-    /**
-     * Clear <message> value
      *
      * @return \routeguide\RouteNote
      */
-    public function clearMessage(){
-      return $this->_clear(2);
+    public function setLocation(\routeguide\Point $value)
+    {
+        return $this->_set(1, $value);
     }
-    
+
     /**
-     * Get <message> value
+     * Check if <message> has a value.
+     *
+     * @return bool
+     */
+    public function hasMessage()
+    {
+        return $this->_has(2);
+    }
+
+    /**
+     * Clear <message> value.
+     *
+     * @return \routeguide\RouteNote
+     */
+    public function clearMessage()
+    {
+        return $this->_clear(2);
+    }
+
+    /**
+     * Get <message> value.
      *
      * @return string
      */
-    public function getMessage(){
-      return $this->_get(2);
+    public function getMessage()
+    {
+        return $this->_get(2);
     }
-    
+
     /**
-     * Set <message> value
+     * Set <message> value.
      *
      * @param string $value
+     *
      * @return \routeguide\RouteNote
      */
-    public function setMessage( $value){
-      return $this->_set(2, $value);
+    public function setMessage($value)
+    {
+        return $this->_set(2, $value);
     }
   }
 }
 
 namespace routeguide {
 
-  class RouteSummary extends \DrSlump\Protobuf\Message {
+  class RouteSummary extends \DrSlump\Protobuf\Message
+  {
+      /**  @var int */
+    public $point_count = 0;
 
     /**  @var int */
-    public $point_count = 0;
-    
-    /**  @var int */
     public $feature_count = 0;
-    
+
     /**  @var int */
     public $distance = 0;
-    
+
     /**  @var int */
     public $elapsed_time = 0;
-    
 
     /** @var \Closure[] */
     protected static $__extensions = array();
 
-    public static function descriptor()
-    {
-      $descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'routeguide.RouteSummary');
+      public static function descriptor()
+      {
+          $descriptor = new \DrSlump\Protobuf\Descriptor(__CLASS__, 'routeguide.RouteSummary');
 
       // OPTIONAL INT32 point_count = 1
       $f = new \DrSlump\Protobuf\Field();
-      $f->number    = 1;
-      $f->name      = "point_count";
-      $f->type      = \DrSlump\Protobuf::TYPE_INT32;
-      $f->rule      = \DrSlump\Protobuf::RULE_OPTIONAL;
-      $f->default   = 0;
-      $descriptor->addField($f);
+          $f->number = 1;
+          $f->name = 'point_count';
+          $f->type = \DrSlump\Protobuf::TYPE_INT32;
+          $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL;
+          $f->default = 0;
+          $descriptor->addField($f);
 
       // OPTIONAL INT32 feature_count = 2
       $f = new \DrSlump\Protobuf\Field();
-      $f->number    = 2;
-      $f->name      = "feature_count";
-      $f->type      = \DrSlump\Protobuf::TYPE_INT32;
-      $f->rule      = \DrSlump\Protobuf::RULE_OPTIONAL;
-      $f->default   = 0;
-      $descriptor->addField($f);
+          $f->number = 2;
+          $f->name = 'feature_count';
+          $f->type = \DrSlump\Protobuf::TYPE_INT32;
+          $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL;
+          $f->default = 0;
+          $descriptor->addField($f);
 
       // OPTIONAL INT32 distance = 3
       $f = new \DrSlump\Protobuf\Field();
-      $f->number    = 3;
-      $f->name      = "distance";
-      $f->type      = \DrSlump\Protobuf::TYPE_INT32;
-      $f->rule      = \DrSlump\Protobuf::RULE_OPTIONAL;
-      $f->default   = 0;
-      $descriptor->addField($f);
+          $f->number = 3;
+          $f->name = 'distance';
+          $f->type = \DrSlump\Protobuf::TYPE_INT32;
+          $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL;
+          $f->default = 0;
+          $descriptor->addField($f);
 
       // OPTIONAL INT32 elapsed_time = 4
       $f = new \DrSlump\Protobuf\Field();
-      $f->number    = 4;
-      $f->name      = "elapsed_time";
-      $f->type      = \DrSlump\Protobuf::TYPE_INT32;
-      $f->rule      = \DrSlump\Protobuf::RULE_OPTIONAL;
-      $f->default   = 0;
-      $descriptor->addField($f);
+          $f->number = 4;
+          $f->name = 'elapsed_time';
+          $f->type = \DrSlump\Protobuf::TYPE_INT32;
+          $f->rule = \DrSlump\Protobuf::RULE_OPTIONAL;
+          $f->default = 0;
+          $descriptor->addField($f);
 
-      foreach (self::$__extensions as $cb) {
-        $descriptor->addField($cb(), true);
+          foreach (self::$__extensions as $cb) {
+              $descriptor->addField($cb(), true);
+          }
+
+          return $descriptor;
       }
 
-      return $descriptor;
+    /**
+     * Check if <point_count> has a value.
+     *
+     * @return bool
+     */
+    public function hasPointCount()
+    {
+        return $this->_has(1);
     }
 
     /**
-     * Check if <point_count> has a value
-     *
-     * @return boolean
-     */
-    public function hasPointCount(){
-      return $this->_has(1);
-    }
-    
-    /**
-     * Clear <point_count> value
+     * Clear <point_count> value.
      *
      * @return \routeguide\RouteSummary
      */
-    public function clearPointCount(){
-      return $this->_clear(1);
+    public function clearPointCount()
+    {
+        return $this->_clear(1);
     }
-    
+
     /**
-     * Get <point_count> value
+     * Get <point_count> value.
      *
      * @return int
      */
-    public function getPointCount(){
-      return $this->_get(1);
+    public function getPointCount()
+    {
+        return $this->_get(1);
     }
-    
+
     /**
-     * Set <point_count> value
+     * Set <point_count> value.
      *
      * @param int $value
-     * @return \routeguide\RouteSummary
-     */
-    public function setPointCount( $value){
-      return $this->_set(1, $value);
-    }
-    
-    /**
-     * Check if <feature_count> has a value
-     *
-     * @return boolean
-     */
-    public function hasFeatureCount(){
-      return $this->_has(2);
-    }
-    
-    /**
-     * Clear <feature_count> value
      *
      * @return \routeguide\RouteSummary
      */
-    public function clearFeatureCount(){
-      return $this->_clear(2);
+    public function setPointCount($value)
+    {
+        return $this->_set(1, $value);
     }
-    
+
     /**
-     * Get <feature_count> value
+     * Check if <feature_count> has a value.
+     *
+     * @return bool
+     */
+    public function hasFeatureCount()
+    {
+        return $this->_has(2);
+    }
+
+    /**
+     * Clear <feature_count> value.
+     *
+     * @return \routeguide\RouteSummary
+     */
+    public function clearFeatureCount()
+    {
+        return $this->_clear(2);
+    }
+
+    /**
+     * Get <feature_count> value.
      *
      * @return int
      */
-    public function getFeatureCount(){
-      return $this->_get(2);
+    public function getFeatureCount()
+    {
+        return $this->_get(2);
     }
-    
+
     /**
-     * Set <feature_count> value
+     * Set <feature_count> value.
      *
      * @param int $value
-     * @return \routeguide\RouteSummary
-     */
-    public function setFeatureCount( $value){
-      return $this->_set(2, $value);
-    }
-    
-    /**
-     * Check if <distance> has a value
-     *
-     * @return boolean
-     */
-    public function hasDistance(){
-      return $this->_has(3);
-    }
-    
-    /**
-     * Clear <distance> value
      *
      * @return \routeguide\RouteSummary
      */
-    public function clearDistance(){
-      return $this->_clear(3);
+    public function setFeatureCount($value)
+    {
+        return $this->_set(2, $value);
     }
-    
+
     /**
-     * Get <distance> value
+     * Check if <distance> has a value.
+     *
+     * @return bool
+     */
+    public function hasDistance()
+    {
+        return $this->_has(3);
+    }
+
+    /**
+     * Clear <distance> value.
+     *
+     * @return \routeguide\RouteSummary
+     */
+    public function clearDistance()
+    {
+        return $this->_clear(3);
+    }
+
+    /**
+     * Get <distance> value.
      *
      * @return int
      */
-    public function getDistance(){
-      return $this->_get(3);
+    public function getDistance()
+    {
+        return $this->_get(3);
     }
-    
+
     /**
-     * Set <distance> value
+     * Set <distance> value.
      *
      * @param int $value
-     * @return \routeguide\RouteSummary
-     */
-    public function setDistance( $value){
-      return $this->_set(3, $value);
-    }
-    
-    /**
-     * Check if <elapsed_time> has a value
-     *
-     * @return boolean
-     */
-    public function hasElapsedTime(){
-      return $this->_has(4);
-    }
-    
-    /**
-     * Clear <elapsed_time> value
      *
      * @return \routeguide\RouteSummary
      */
-    public function clearElapsedTime(){
-      return $this->_clear(4);
+    public function setDistance($value)
+    {
+        return $this->_set(3, $value);
     }
-    
+
     /**
-     * Get <elapsed_time> value
+     * Check if <elapsed_time> has a value.
+     *
+     * @return bool
+     */
+    public function hasElapsedTime()
+    {
+        return $this->_has(4);
+    }
+
+    /**
+     * Clear <elapsed_time> value.
+     *
+     * @return \routeguide\RouteSummary
+     */
+    public function clearElapsedTime()
+    {
+        return $this->_clear(4);
+    }
+
+    /**
+     * Get <elapsed_time> value.
      *
      * @return int
      */
-    public function getElapsedTime(){
-      return $this->_get(4);
+    public function getElapsedTime()
+    {
+        return $this->_get(4);
     }
-    
+
     /**
-     * Set <elapsed_time> value
+     * Set <elapsed_time> value.
      *
      * @param int $value
+     *
      * @return \routeguide\RouteSummary
      */
-    public function setElapsedTime( $value){
-      return $this->_set(4, $value);
+    public function setElapsedTime($value)
+    {
+        return $this->_set(4, $value);
     }
   }
 }
 
 namespace routeguide {
 
-  class RouteGuideClient extends \Grpc\BaseStub {
-
-    public function __construct($hostname, $opts) {
-      parent::__construct($hostname, $opts);
-    }
+  class RouteGuideClient extends \Grpc\BaseStub
+  {
+      public function __construct($hostname, $opts)
+      {
+          parent::__construct($hostname, $opts);
+      }
     /**
      * @param routeguide\Point $input
      */
-    public function GetFeature(\routeguide\Point $argument, $metadata = array(), $options = array()) {
-      return $this->_simpleRequest('/routeguide.RouteGuide/GetFeature', $argument, '\routeguide\Feature::deserialize', $metadata, $options);
+    public function GetFeature(\routeguide\Point $argument, $metadata = array(), $options = array())
+    {
+        return $this->_simpleRequest('/routeguide.RouteGuide/GetFeature', $argument, '\routeguide\Feature::deserialize', $metadata, $options);
     }
     /**
      * @param routeguide\Rectangle $input
      */
-    public function ListFeatures($argument, $metadata = array(), $options = array()) {
-      return $this->_serverStreamRequest('/routeguide.RouteGuide/ListFeatures', $argument, '\routeguide\Feature::deserialize', $metadata, $options);
+    public function ListFeatures($argument, $metadata = array(), $options = array())
+    {
+        return $this->_serverStreamRequest('/routeguide.RouteGuide/ListFeatures', $argument, '\routeguide\Feature::deserialize', $metadata, $options);
     }
     /**
      * @param routeguide\Point $input
      */
-    public function RecordRoute($metadata = array()) {
-      return $this->_clientStreamRequest('/routeguide.RouteGuide/RecordRoute', '\routeguide\RouteSummary::deserialize', $metadata);
+    public function RecordRoute($metadata = array())
+    {
+        return $this->_clientStreamRequest('/routeguide.RouteGuide/RecordRoute', '\routeguide\RouteSummary::deserialize', $metadata);
     }
     /**
      * @param routeguide\RouteNote $input
      */
-    public function RouteChat($metadata = array()) {
-      return $this->_bidiRequest('/routeguide.RouteGuide/RouteChat', '\routeguide\RouteNote::deserialize', $metadata);
+    public function RouteChat($metadata = array())
+    {
+        return $this->_bidiRequest('/routeguide.RouteGuide/RouteChat', '\routeguide\RouteNote::deserialize', $metadata);
     }
   }
 }
diff --git a/examples/php/route_guide/route_guide_client.php b/examples/php/route_guide/route_guide_client.php
index 2f9533b..b3cd606 100644
--- a/examples/php/route_guide/route_guide_client.php
+++ b/examples/php/route_guide/route_guide_client.php
@@ -32,48 +32,50 @@
  *
  */
 
-require dirname(__FILE__) . '/../vendor/autoload.php';
-require dirname(__FILE__) . '/route_guide.php';
+require dirname(__FILE__).'/../vendor/autoload.php';
+require dirname(__FILE__).'/route_guide.php';
 
 define('COORD_FACTOR', 1e7);
 
 $client = new routeguide\RouteGuideClient('localhost:50051', [
-  'credentials' => Grpc\ChannelCredentials::createInsecure()
+    'credentials' => Grpc\ChannelCredentials::createInsecure(),
 ]);
 
-function printFeature($feature) {
-  $name = $feature->getName();
-  if (!$name) {
-    $name_str = "no feature";
-  } else {
-    $name_str = "feature called $name";
-  }
-  print sprintf("Found %s \n  at %f, %f\n", $name_str,
-                $feature->getLocation()->getLatitude() / COORD_FACTOR,
-                $feature->getLocation()->getLongitude() / COORD_FACTOR);
+function printFeature($feature)
+{
+    $name = $feature->getName();
+    if (!$name) {
+        $name_str = 'no feature';
+    } else {
+        $name_str = "feature called $name";
+    }
+    echo sprintf("Found %s \n  at %f, %f\n", $name_str,
+                 $feature->getLocation()->getLatitude() / COORD_FACTOR,
+                 $feature->getLocation()->getLongitude() / COORD_FACTOR);
 }
 
 /**
  * Run the getFeature demo. Calls getFeature with a point known to have a
  * feature and a point known not to have a feature.
  */
-function runGetFeature() {
-  print "Running GetFeature...\n";
-  global $client;
+function runGetFeature()
+{
+    echo "Running GetFeature...\n";
+    global $client;
 
-  $point = new routeguide\Point();
-  $points = array(
-    array(409146138, -746188906),
-    array(0, 0),
-  );
+    $point = new routeguide\Point();
+    $points = array(
+        array(409146138, -746188906),
+        array(0, 0),
+    );
 
-  foreach ($points as $p) {
-    $point->setLatitude($p[0]);
-    $point->setLongitude($p[1]);
-    // make a unary grpc call
-    list($feature, $status) = $client->GetFeature($point)->wait();
-    printFeature($feature);
-  }
+    foreach ($points as $p) {
+        $point->setLatitude($p[0]);
+        $point->setLongitude($p[1]);
+        // make a unary grpc call
+        list($feature, $status) = $client->GetFeature($point)->wait();
+        printFeature($feature);
+    }
 }
 
 /**
@@ -81,29 +83,30 @@
  * containing all of the features in the pre-generated
  * database. Prints each response as it comes in.
  */
-function runListFeatures() {
-  print "Running ListFeatures...\n";
-  global $client;
+function runListFeatures()
+{
+    echo "Running ListFeatures...\n";
+    global $client;
 
-  $lo_point = new routeguide\Point();
-  $hi_point = new routeguide\Point();
+    $lo_point = new routeguide\Point();
+    $hi_point = new routeguide\Point();
 
-  $lo_point->setLatitude(400000000);
-  $lo_point->setLongitude(-750000000);
-  $hi_point->setLatitude(420000000);
-  $hi_point->setLongitude(-730000000);
+    $lo_point->setLatitude(400000000);
+    $lo_point->setLongitude(-750000000);
+    $hi_point->setLatitude(420000000);
+    $hi_point->setLongitude(-730000000);
 
-  $rectangle = new routeguide\Rectangle();
-  $rectangle->setLo($lo_point);
-  $rectangle->setHi($hi_point);
+    $rectangle = new routeguide\Rectangle();
+    $rectangle->setLo($lo_point);
+    $rectangle->setHi($hi_point);
 
-  // start the server streaming call
-  $call = $client->ListFeatures($rectangle);
-  // an iterator over the server streaming responses
-  $features = $call->responses();
-  foreach ($features as $feature) {
-    printFeature($feature);
-  }
+    // start the server streaming call
+    $call = $client->ListFeatures($rectangle);
+    // an iterator over the server streaming responses
+    $features = $call->responses();
+    foreach ($features as $feature) {
+        printFeature($feature);
+    }
 }
 
 /**
@@ -111,96 +114,99 @@
  * pre-generated feature database with a variable delay in between. Prints
  * the statistics when they are sent from the server.
  */
-function runRecordRoute() {
-  print "Running RecordRoute...\n";
-  global $client, $argv;
+function runRecordRoute()
+{
+    echo "Running RecordRoute...\n";
+    global $client, $argv;
 
-  // start the client streaming call
-  $call = $client->RecordRoute();
+    // start the client streaming call
+    $call = $client->RecordRoute();
 
-  $db = json_decode(file_get_contents($argv[1]), true);
-  $num_points_in_db = count($db);
-  $num_points = 10;
-  for ($i = 0; $i < $num_points; $i++) {
-    $point = new routeguide\Point();
-    $index = rand(0, $num_points_in_db - 1);
-    $lat = $db[$index]['location']['latitude'];
-    $long = $db[$index]['location']['longitude'];
-    $feature_name = $db[$index]['name'];
-    $point->setLatitude($lat);
-    $point->setLongitude($long);
-    print sprintf("Visiting point %f, %f,\n  with feature name: %s\n",
-                  $lat / COORD_FACTOR, $long / COORD_FACTOR,
-                  $feature_name ? $feature_name : '<empty>');
-    usleep(rand(300000, 800000));
-    $call->write($point);
-  }
-  list($route_summary, $status) = $call->wait();
-  print sprintf("Finished trip with %d points\nPassed %d features\n".
-                "Travelled %d meters\nIt took %d seconds\n",
-                $route_summary->getPointCount(),
-                $route_summary->getFeatureCount(),
-                $route_summary->getDistance(),
-                $route_summary->getElapsedTime());
+    $db = json_decode(file_get_contents($argv[1]), true);
+    $num_points_in_db = count($db);
+    $num_points = 10;
+    for ($i = 0; $i < $num_points; ++$i) {
+        $point = new routeguide\Point();
+        $index = rand(0, $num_points_in_db - 1);
+        $lat = $db[$index]['location']['latitude'];
+        $long = $db[$index]['location']['longitude'];
+        $feature_name = $db[$index]['name'];
+        $point->setLatitude($lat);
+        $point->setLongitude($long);
+        echo sprintf("Visiting point %f, %f,\n  with feature name: %s\n",
+                     $lat / COORD_FACTOR, $long / COORD_FACTOR,
+                     $feature_name ? $feature_name : '<empty>');
+        usleep(rand(300000, 800000));
+        $call->write($point);
+    }
+    list($route_summary, $status) = $call->wait();
+    echo sprintf("Finished trip with %d points\nPassed %d features\n".
+                 "Travelled %d meters\nIt took %d seconds\n",
+                 $route_summary->getPointCount(),
+                 $route_summary->getFeatureCount(),
+                 $route_summary->getDistance(),
+                 $route_summary->getElapsedTime());
 }
 
 /**
  * Run the routeChat demo. Send some chat messages, and print any chat
  * messages that are sent from the server.
  */
-function runRouteChat() {
-  print "Running RouteChat...\n";
-  global $client;
+function runRouteChat()
+{
+    echo "Running RouteChat...\n";
+    global $client;
 
-  // start the bidirectional streaming call
-  $call = $client->RouteChat();
+    // start the bidirectional streaming call
+    $call = $client->RouteChat();
 
-  $notes = array(
-    array(1, 1, 'first message'),
-    array(1, 2, 'second message'),
-    array(2, 1, 'third message'),
-    array(1, 1, 'fourth message'),
-    array(1, 1, 'fifth message'),
-  );
+    $notes = array(
+        array(1, 1, 'first message'),
+        array(1, 2, 'second message'),
+        array(2, 1, 'third message'),
+        array(1, 1, 'fourth message'),
+        array(1, 1, 'fifth message'),
+    );
 
-  foreach ($notes as $n) {
-    $point = new routeguide\Point();
-    $point->setLatitude($lat = $n[0]);
-    $point->setLongitude($long = $n[1]);
+    foreach ($notes as $n) {
+        $point = new routeguide\Point();
+        $point->setLatitude($lat = $n[0]);
+        $point->setLongitude($long = $n[1]);
 
-    $route_note = new routeguide\RouteNote();
-    $route_note->setLocation($point);
-    $route_note->setMessage($message = $n[2]);
+        $route_note = new routeguide\RouteNote();
+        $route_note->setLocation($point);
+        $route_note->setMessage($message = $n[2]);
 
-    print sprintf("Sending message: '%s' at (%d, %d)\n",
-                  $message, $lat, $long);
-    // send a bunch of messages to the server
-    $call->write($route_note);
-  }
-  $call->writesDone();
+        echo sprintf("Sending message: '%s' at (%d, %d)\n",
+                     $message, $lat, $long);
+        // send a bunch of messages to the server
+        $call->write($route_note);
+    }
+    $call->writesDone();
 
-  // read from the server until there's no more
-  while ($route_note_reply = $call->read()) {
-    print sprintf("Previous left message at (%d, %d): '%s'\n",
-                  $route_note_reply->getLocation()->getLatitude(),
-                  $route_note_reply->getLocation()->getLongitude(),
-                  $route_note_reply->getMessage());
-  }
+    // read from the server until there's no more
+    while ($route_note_reply = $call->read()) {
+        echo sprintf("Previous left message at (%d, %d): '%s'\n",
+                     $route_note_reply->getLocation()->getLatitude(),
+                     $route_note_reply->getLocation()->getLongitude(),
+                     $route_note_reply->getMessage());
+    }
 }
 
 /**
- * Run all of the demos in order
+ * Run all of the demos in order.
  */
-function main() {
-  runGetFeature();
-  runListFeatures();
-  runRecordRoute();
-  runRouteChat();
+function main()
+{
+    runGetFeature();
+    runListFeatures();
+    runRecordRoute();
+    runRouteChat();
 }
 
 if (empty($argv[1])) {
-  print "Usage: php -d extension=grpc.so route_guide_client.php " .
+    echo 'Usage: php -d extension=grpc.so route_guide_client.php '.
         "<path to route_guide_db.json>\n";
-  exit(1);
+    exit(1);
 }
 main();
diff --git a/examples/ruby/lib/helloworld_services.rb b/examples/ruby/lib/helloworld_services.rb
index 7da45eb..fbec667 100644
--- a/examples/ruby/lib/helloworld_services.rb
+++ b/examples/ruby/lib/helloworld_services.rb
@@ -1,13 +1,42 @@
 # Generated by the protocol buffer compiler.  DO NOT EDIT!
 # Source: helloworld.proto for package 'helloworld'
+# Original file comments:
+# 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'
 require 'helloworld'
 
 module Helloworld
   module Greeter
-
-    # TODO: add proto service documentation here
+    # The greeting service definition.
     class Service
 
       include GRPC::GenericService
@@ -16,6 +45,7 @@
       self.unmarshal_class_method = :decode
       self.service_name = 'helloworld.Greeter'
 
+      # Sends a greeting
       rpc :SayHello, HelloRequest, HelloReply
     end
 
diff --git a/examples/ruby/lib/route_guide_services.rb b/examples/ruby/lib/route_guide_services.rb
index 082daef..d8f123d 100644
--- a/examples/ruby/lib/route_guide_services.rb
+++ b/examples/ruby/lib/route_guide_services.rb
@@ -1,13 +1,42 @@
 # Generated by the protocol buffer compiler.  DO NOT EDIT!
 # Source: route_guide.proto for package 'routeguide'
+# Original file comments:
+# 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'
 require 'route_guide'
 
 module Routeguide
   module RouteGuide
-
-    # TODO: add proto service documentation here
+    # Interface exported by the server.
     class Service
 
       include GRPC::GenericService
@@ -16,9 +45,29 @@
       self.unmarshal_class_method = :decode
       self.service_name = 'routeguide.RouteGuide'
 
+      # A simple RPC.
+      #
+      # Obtains the feature at a given position.
+      #
+      # A feature with an empty name is returned if there's no feature at the given
+      # position.
       rpc :GetFeature, Point, Feature
+      # A server-to-client streaming RPC.
+      #
+      # Obtains the Features available within the given Rectangle.  Results are
+      # streamed rather than returned at once (e.g. in a response message with a
+      # repeated field), as the rectangle may cover a large area and contain a
+      # huge number of features.
       rpc :ListFeatures, Rectangle, stream(Feature)
+      # A client-to-server streaming RPC.
+      #
+      # Accepts a stream of Points on a route being traversed, returning a
+      # RouteSummary when traversal is completed.
       rpc :RecordRoute, stream(Point), RouteSummary
+      # A Bidirectional streaming RPC.
+      #
+      # Accepts a stream of RouteNotes sent while a route is being traversed,
+      # while receiving other RouteNotes (e.g. from other users).
       rpc :RouteChat, stream(RouteNote), stream(RouteNote)
     end
 
diff --git a/gRPC.podspec b/gRPC.podspec
index cc8ba3d..10a836e 100644
--- a/gRPC.podspec
+++ b/gRPC.podspec
@@ -72,7 +72,7 @@
                       'src/core/lib/support/murmur_hash.h',
                       'src/core/lib/support/stack_lockfree.h',
                       'src/core/lib/support/string.h',
-                      'src/core/lib/support/string_win32.h',
+                      'src/core/lib/support/string_windows.h',
                       'src/core/lib/support/thd_internal.h',
                       'src/core/lib/support/time_precise.h',
                       'src/core/lib/support/tmpfile.h',
@@ -80,14 +80,14 @@
                       'include/grpc/support/atm.h',
                       'include/grpc/support/atm_gcc_atomic.h',
                       'include/grpc/support/atm_gcc_sync.h',
-                      'include/grpc/support/atm_win32.h',
+                      'include/grpc/support/atm_windows.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_win32.h',
+                      'include/grpc/support/log_windows.h',
                       'include/grpc/support/port_platform.h',
                       'include/grpc/support/slice.h',
                       'include/grpc/support/slice_buffer.h',
@@ -96,7 +96,7 @@
                       'include/grpc/support/sync.h',
                       'include/grpc/support/sync_generic.h',
                       'include/grpc/support/sync_posix.h',
-                      'include/grpc/support/sync_win32.h',
+                      'include/grpc/support/sync_windows.h',
                       'include/grpc/support/thd.h',
                       'include/grpc/support/time.h',
                       'include/grpc/support/tls.h',
@@ -108,7 +108,7 @@
                       'include/grpc/impl/codegen/atm.h',
                       'include/grpc/impl/codegen/atm_gcc_atomic.h',
                       'include/grpc/impl/codegen/atm_gcc_sync.h',
-                      'include/grpc/impl/codegen/atm_win32.h',
+                      'include/grpc/impl/codegen/atm_windows.h',
                       'include/grpc/impl/codegen/log.h',
                       'include/grpc/impl/codegen/port_platform.h',
                       'include/grpc/impl/codegen/slice.h',
@@ -116,7 +116,7 @@
                       'include/grpc/impl/codegen/sync.h',
                       'include/grpc/impl/codegen/sync_generic.h',
                       'include/grpc/impl/codegen/sync_posix.h',
-                      'include/grpc/impl/codegen/sync_win32.h',
+                      'include/grpc/impl/codegen/sync_windows.h',
                       'include/grpc/impl/codegen/time.h',
                       'src/core/lib/profiling/basic_timers.c',
                       'src/core/lib/profiling/stap_timers.c',
@@ -130,7 +130,7 @@
                       'src/core/lib/support/cpu_windows.c',
                       'src/core/lib/support/env_linux.c',
                       'src/core/lib/support/env_posix.c',
-                      'src/core/lib/support/env_win32.c',
+                      'src/core/lib/support/env_windows.c',
                       'src/core/lib/support/histogram.c',
                       'src/core/lib/support/host_port.c',
                       'src/core/lib/support/load_file.c',
@@ -138,31 +138,31 @@
                       'src/core/lib/support/log_android.c',
                       'src/core/lib/support/log_linux.c',
                       'src/core/lib/support/log_posix.c',
-                      'src/core/lib/support/log_win32.c',
+                      'src/core/lib/support/log_windows.c',
                       'src/core/lib/support/murmur_hash.c',
                       'src/core/lib/support/slice.c',
                       'src/core/lib/support/slice_buffer.c',
                       'src/core/lib/support/stack_lockfree.c',
                       'src/core/lib/support/string.c',
                       'src/core/lib/support/string_posix.c',
-                      'src/core/lib/support/string_util_win32.c',
-                      'src/core/lib/support/string_win32.c',
+                      'src/core/lib/support/string_util_windows.c',
+                      'src/core/lib/support/string_windows.c',
                       'src/core/lib/support/subprocess_posix.c',
                       'src/core/lib/support/subprocess_windows.c',
                       'src/core/lib/support/sync.c',
                       'src/core/lib/support/sync_posix.c',
-                      'src/core/lib/support/sync_win32.c',
+                      'src/core/lib/support/sync_windows.c',
                       'src/core/lib/support/thd.c',
                       'src/core/lib/support/thd_posix.c',
-                      'src/core/lib/support/thd_win32.c',
+                      'src/core/lib/support/thd_windows.c',
                       'src/core/lib/support/time.c',
                       'src/core/lib/support/time_posix.c',
                       'src/core/lib/support/time_precise.c',
-                      'src/core/lib/support/time_win32.c',
+                      'src/core/lib/support/time_windows.c',
                       'src/core/lib/support/tls_pthread.c',
                       'src/core/lib/support/tmpfile_msys.c',
                       'src/core/lib/support/tmpfile_posix.c',
-                      'src/core/lib/support/tmpfile_win32.c',
+                      'src/core/lib/support/tmpfile_windows.c',
                       'src/core/lib/support/wrap_memcpy.c',
                       'src/core/lib/channel/channel_args.h',
                       'src/core/lib/channel/channel_stack.h',
@@ -181,6 +181,7 @@
                       'src/core/lib/iomgr/closure.h',
                       'src/core/lib/iomgr/endpoint.h',
                       'src/core/lib/iomgr/endpoint_pair.h',
+                      'src/core/lib/iomgr/ev_poll_and_epoll_posix.h',
                       'src/core/lib/iomgr/ev_poll_posix.h',
                       'src/core/lib/iomgr/ev_posix.h',
                       'src/core/lib/iomgr/exec_ctx.h',
@@ -189,6 +190,7 @@
                       'src/core/lib/iomgr/iomgr.h',
                       'src/core/lib/iomgr/iomgr_internal.h',
                       'src/core/lib/iomgr/iomgr_posix.h',
+                      'src/core/lib/iomgr/polling_entity.h',
                       'src/core/lib/iomgr/pollset.h',
                       'src/core/lib/iomgr/pollset_set.h',
                       'src/core/lib/iomgr/pollset_set_windows.h',
@@ -197,7 +199,7 @@
                       'src/core/lib/iomgr/sockaddr.h',
                       'src/core/lib/iomgr/sockaddr_posix.h',
                       'src/core/lib/iomgr/sockaddr_utils.h',
-                      'src/core/lib/iomgr/sockaddr_win32.h',
+                      'src/core/lib/iomgr/sockaddr_windows.h',
                       'src/core/lib/iomgr/socket_utils_posix.h',
                       'src/core/lib/iomgr/socket_windows.h',
                       'src/core/lib/iomgr/tcp_client.h',
@@ -297,16 +299,18 @@
                       'src/core/ext/client_config/subchannel_call_holder.h',
                       'src/core/ext/client_config/subchannel_index.h',
                       'src/core/ext/client_config/uri_parser.h',
-                      'third_party/objective_c/Cronet/cronet_c_for_grpc.h',
                       'src/core/ext/lb_policy/grpclb/load_balancer_api.h',
                       'src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h',
                       'third_party/nanopb/pb.h',
                       'third_party/nanopb/pb_common.h',
                       'third_party/nanopb/pb_decode.h',
                       'third_party/nanopb/pb_encode.h',
+                      'src/core/ext/load_reporting/load_reporting.h',
+                      'src/core/ext/load_reporting/load_reporting_filter.h',
                       'src/core/ext/census/aggregation.h',
                       'src/core/ext/census/census_interface.h',
                       'src/core/ext/census/census_rpc_stats.h',
+                      'src/core/ext/census/gen/census.pb.h',
                       'src/core/ext/census/grpc_filter.h',
                       'src/core/ext/census/mlog.h',
                       'src/core/ext/census/rpc_metric_id.h',
@@ -314,6 +318,7 @@
                       'include/grpc/byte_buffer_reader.h',
                       'include/grpc/compression.h',
                       'include/grpc/grpc.h',
+                      'include/grpc/grpc_posix.h',
                       'include/grpc/status.h',
                       'include/grpc/impl/codegen/byte_buffer.h',
                       'include/grpc/impl/codegen/byte_buffer_reader.h',
@@ -326,7 +331,7 @@
                       'include/grpc/impl/codegen/atm.h',
                       'include/grpc/impl/codegen/atm_gcc_atomic.h',
                       'include/grpc/impl/codegen/atm_gcc_sync.h',
-                      'include/grpc/impl/codegen/atm_win32.h',
+                      'include/grpc/impl/codegen/atm_windows.h',
                       'include/grpc/impl/codegen/log.h',
                       'include/grpc/impl/codegen/port_platform.h',
                       'include/grpc/impl/codegen/slice.h',
@@ -334,9 +339,8 @@
                       'include/grpc/impl/codegen/sync.h',
                       'include/grpc/impl/codegen/sync_generic.h',
                       'include/grpc/impl/codegen/sync_posix.h',
-                      'include/grpc/impl/codegen/sync_win32.h',
+                      'include/grpc/impl/codegen/sync_windows.h',
                       'include/grpc/impl/codegen/time.h',
-                      'include/grpc/grpc_cronet.h',
                       'include/grpc/grpc_security.h',
                       'include/grpc/grpc_security_constants.h',
                       'include/grpc/census.h',
@@ -348,7 +352,7 @@
                       'src/core/lib/channel/connected_channel.c',
                       'src/core/lib/channel/http_client_filter.c',
                       'src/core/lib/channel/http_server_filter.c',
-                      'src/core/lib/compression/compression_algorithm.c',
+                      'src/core/lib/compression/compression.c',
                       'src/core/lib/compression/message_compress.c',
                       'src/core/lib/debug/trace.c',
                       'src/core/lib/http/format_request.c',
@@ -358,6 +362,7 @@
                       'src/core/lib/iomgr/endpoint.c',
                       'src/core/lib/iomgr/endpoint_pair_posix.c',
                       'src/core/lib/iomgr/endpoint_pair_windows.c',
+                      'src/core/lib/iomgr/ev_poll_and_epoll_posix.c',
                       'src/core/lib/iomgr/ev_poll_posix.c',
                       'src/core/lib/iomgr/ev_posix.c',
                       'src/core/lib/iomgr/exec_ctx.c',
@@ -366,6 +371,7 @@
                       'src/core/lib/iomgr/iomgr.c',
                       'src/core/lib/iomgr/iomgr_posix.c',
                       'src/core/lib/iomgr/iomgr_windows.c',
+                      'src/core/lib/iomgr/polling_entity.c',
                       'src/core/lib/iomgr/pollset_set_windows.c',
                       'src/core/lib/iomgr/pollset_windows.c',
                       'src/core/lib/iomgr/resolve_address_posix.c',
@@ -452,7 +458,7 @@
                       'src/core/lib/security/credentials/credentials_metadata.c',
                       'src/core/lib/security/credentials/fake/fake_credentials.c',
                       'src/core/lib/security/credentials/google_default/credentials_posix.c',
-                      'src/core/lib/security/credentials/google_default/credentials_win32.c',
+                      'src/core/lib/security/credentials/google_default/credentials_windows.c',
                       'src/core/lib/security/credentials/google_default/google_default_credentials.c',
                       'src/core/lib/security/credentials/iam/iam_credentials.c',
                       'src/core/lib/security/credentials/jwt/json_token.c',
@@ -493,10 +499,9 @@
                       'src/core/ext/client_config/subchannel_index.c',
                       'src/core/ext/client_config/uri_parser.c',
                       'src/core/ext/transport/chttp2/server/insecure/server_chttp2.c',
+                      'src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.c',
                       'src/core/ext/transport/chttp2/client/insecure/channel_create.c',
-                      'src/core/ext/transport/cronet/client/secure/cronet_channel_create.c',
-                      'src/core/ext/transport/cronet/transport/cronet_api_dummy.c',
-                      'src/core/ext/transport/cronet/transport/cronet_transport.c',
+                      'src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c',
                       'src/core/ext/lb_policy/grpclb/load_balancer_api.c',
                       'src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c',
                       'third_party/nanopb/pb_common.c',
@@ -506,7 +511,10 @@
                       'src/core/ext/lb_policy/round_robin/round_robin.c',
                       'src/core/ext/resolver/dns/native/dns_resolver.c',
                       'src/core/ext/resolver/sockaddr/sockaddr_resolver.c',
+                      'src/core/ext/load_reporting/load_reporting.c',
+                      'src/core/ext/load_reporting/load_reporting_filter.c',
                       'src/core/ext/census/context.c',
+                      'src/core/ext/census/gen/census.pb.c',
                       'src/core/ext/census/grpc_context.c',
                       'src/core/ext/census/grpc_filter.c',
                       'src/core/ext/census/grpc_plugin.c',
@@ -525,7 +533,7 @@
                               'src/core/lib/support/murmur_hash.h',
                               'src/core/lib/support/stack_lockfree.h',
                               'src/core/lib/support/string.h',
-                              'src/core/lib/support/string_win32.h',
+                              'src/core/lib/support/string_windows.h',
                               'src/core/lib/support/thd_internal.h',
                               'src/core/lib/support/time_precise.h',
                               'src/core/lib/support/tmpfile.h',
@@ -546,6 +554,7 @@
                               'src/core/lib/iomgr/closure.h',
                               'src/core/lib/iomgr/endpoint.h',
                               'src/core/lib/iomgr/endpoint_pair.h',
+                              'src/core/lib/iomgr/ev_poll_and_epoll_posix.h',
                               'src/core/lib/iomgr/ev_poll_posix.h',
                               'src/core/lib/iomgr/ev_posix.h',
                               'src/core/lib/iomgr/exec_ctx.h',
@@ -554,6 +563,7 @@
                               'src/core/lib/iomgr/iomgr.h',
                               'src/core/lib/iomgr/iomgr_internal.h',
                               'src/core/lib/iomgr/iomgr_posix.h',
+                              'src/core/lib/iomgr/polling_entity.h',
                               'src/core/lib/iomgr/pollset.h',
                               'src/core/lib/iomgr/pollset_set.h',
                               'src/core/lib/iomgr/pollset_set_windows.h',
@@ -562,7 +572,7 @@
                               'src/core/lib/iomgr/sockaddr.h',
                               'src/core/lib/iomgr/sockaddr_posix.h',
                               'src/core/lib/iomgr/sockaddr_utils.h',
-                              'src/core/lib/iomgr/sockaddr_win32.h',
+                              'src/core/lib/iomgr/sockaddr_windows.h',
                               'src/core/lib/iomgr/socket_utils_posix.h',
                               'src/core/lib/iomgr/socket_windows.h',
                               'src/core/lib/iomgr/tcp_client.h',
@@ -662,16 +672,18 @@
                               'src/core/ext/client_config/subchannel_call_holder.h',
                               'src/core/ext/client_config/subchannel_index.h',
                               'src/core/ext/client_config/uri_parser.h',
-                              'third_party/objective_c/Cronet/cronet_c_for_grpc.h',
                               'src/core/ext/lb_policy/grpclb/load_balancer_api.h',
                               'src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h',
                               'third_party/nanopb/pb.h',
                               'third_party/nanopb/pb_common.h',
                               'third_party/nanopb/pb_decode.h',
                               'third_party/nanopb/pb_encode.h',
+                              'src/core/ext/load_reporting/load_reporting.h',
+                              'src/core/ext/load_reporting/load_reporting_filter.h',
                               'src/core/ext/census/aggregation.h',
                               'src/core/ext/census/census_interface.h',
                               'src/core/ext/census/census_rpc_stats.h',
+                              'src/core/ext/census/gen/census.pb.h',
                               'src/core/ext/census/grpc_filter.h',
                               'src/core/ext/census/mlog.h',
                               'src/core/ext/census/rpc_metric_id.h'
diff --git a/grpc.def b/grpc.def
index b811f0f..0046028 100644
--- a/grpc.def
+++ b/grpc.def
@@ -88,7 +88,8 @@
     grpc_header_nonbin_value_is_legal
     grpc_is_binary_header
     grpc_call_error_to_string
-    grpc_cronet_secure_channel_create
+    grpc_insecure_channel_create_from_fd
+    grpc_server_add_insecure_channel_from_fd
     grpc_auth_property_iterator_next
     grpc_auth_context_property_iterator
     grpc_auth_context_peer_identity
diff --git a/grpc.gemspec b/grpc.gemspec
index ae7f9b7..24d512d 100755
--- a/grpc.gemspec
+++ b/grpc.gemspec
@@ -47,14 +47,14 @@
   s.files += %w( include/grpc/support/atm.h )
   s.files += %w( include/grpc/support/atm_gcc_atomic.h )
   s.files += %w( include/grpc/support/atm_gcc_sync.h )
-  s.files += %w( include/grpc/support/atm_win32.h )
+  s.files += %w( include/grpc/support/atm_windows.h )
   s.files += %w( include/grpc/support/avl.h )
   s.files += %w( include/grpc/support/cmdline.h )
   s.files += %w( include/grpc/support/cpu.h )
   s.files += %w( include/grpc/support/histogram.h )
   s.files += %w( include/grpc/support/host_port.h )
   s.files += %w( include/grpc/support/log.h )
-  s.files += %w( include/grpc/support/log_win32.h )
+  s.files += %w( include/grpc/support/log_windows.h )
   s.files += %w( include/grpc/support/port_platform.h )
   s.files += %w( include/grpc/support/slice.h )
   s.files += %w( include/grpc/support/slice_buffer.h )
@@ -63,7 +63,7 @@
   s.files += %w( include/grpc/support/sync.h )
   s.files += %w( include/grpc/support/sync_generic.h )
   s.files += %w( include/grpc/support/sync_posix.h )
-  s.files += %w( include/grpc/support/sync_win32.h )
+  s.files += %w( include/grpc/support/sync_windows.h )
   s.files += %w( include/grpc/support/thd.h )
   s.files += %w( include/grpc/support/time.h )
   s.files += %w( include/grpc/support/tls.h )
@@ -75,7 +75,7 @@
   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_win32.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/port_platform.h )
   s.files += %w( include/grpc/impl/codegen/slice.h )
@@ -83,7 +83,7 @@
   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_win32.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 )
@@ -93,7 +93,7 @@
   s.files += %w( src/core/lib/support/murmur_hash.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_win32.h )
+  s.files += %w( src/core/lib/support/string_windows.h )
   s.files += %w( src/core/lib/support/thd_internal.h )
   s.files += %w( src/core/lib/support/time_precise.h )
   s.files += %w( src/core/lib/support/tmpfile.h )
@@ -109,7 +109,7 @@
   s.files += %w( src/core/lib/support/cpu_windows.c )
   s.files += %w( src/core/lib/support/env_linux.c )
   s.files += %w( src/core/lib/support/env_posix.c )
-  s.files += %w( src/core/lib/support/env_win32.c )
+  s.files += %w( src/core/lib/support/env_windows.c )
   s.files += %w( src/core/lib/support/histogram.c )
   s.files += %w( src/core/lib/support/host_port.c )
   s.files += %w( src/core/lib/support/load_file.c )
@@ -117,36 +117,37 @@
   s.files += %w( src/core/lib/support/log_android.c )
   s.files += %w( src/core/lib/support/log_linux.c )
   s.files += %w( src/core/lib/support/log_posix.c )
-  s.files += %w( src/core/lib/support/log_win32.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/slice.c )
   s.files += %w( src/core/lib/support/slice_buffer.c )
   s.files += %w( src/core/lib/support/stack_lockfree.c )
   s.files += %w( src/core/lib/support/string.c )
   s.files += %w( src/core/lib/support/string_posix.c )
-  s.files += %w( src/core/lib/support/string_util_win32.c )
-  s.files += %w( src/core/lib/support/string_win32.c )
+  s.files += %w( src/core/lib/support/string_util_windows.c )
+  s.files += %w( src/core/lib/support/string_windows.c )
   s.files += %w( src/core/lib/support/subprocess_posix.c )
   s.files += %w( src/core/lib/support/subprocess_windows.c )
   s.files += %w( src/core/lib/support/sync.c )
   s.files += %w( src/core/lib/support/sync_posix.c )
-  s.files += %w( src/core/lib/support/sync_win32.c )
+  s.files += %w( src/core/lib/support/sync_windows.c )
   s.files += %w( src/core/lib/support/thd.c )
   s.files += %w( src/core/lib/support/thd_posix.c )
-  s.files += %w( src/core/lib/support/thd_win32.c )
+  s.files += %w( src/core/lib/support/thd_windows.c )
   s.files += %w( src/core/lib/support/time.c )
   s.files += %w( src/core/lib/support/time_posix.c )
   s.files += %w( src/core/lib/support/time_precise.c )
-  s.files += %w( src/core/lib/support/time_win32.c )
+  s.files += %w( src/core/lib/support/time_windows.c )
   s.files += %w( src/core/lib/support/tls_pthread.c )
   s.files += %w( src/core/lib/support/tmpfile_msys.c )
   s.files += %w( src/core/lib/support/tmpfile_posix.c )
-  s.files += %w( src/core/lib/support/tmpfile_win32.c )
+  s.files += %w( src/core/lib/support/tmpfile_windows.c )
   s.files += %w( src/core/lib/support/wrap_memcpy.c )
   s.files += %w( include/grpc/byte_buffer.h )
   s.files += %w( include/grpc/byte_buffer_reader.h )
   s.files += %w( include/grpc/compression.h )
   s.files += %w( include/grpc/grpc.h )
+  s.files += %w( include/grpc/grpc_posix.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 )
@@ -159,7 +160,7 @@
   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_win32.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/port_platform.h )
   s.files += %w( include/grpc/impl/codegen/slice.h )
@@ -167,9 +168,8 @@
   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_win32.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_cronet.h )
   s.files += %w( include/grpc/grpc_security.h )
   s.files += %w( include/grpc/grpc_security_constants.h )
   s.files += %w( include/grpc/census.h )
@@ -190,6 +190,7 @@
   s.files += %w( src/core/lib/iomgr/closure.h )
   s.files += %w( src/core/lib/iomgr/endpoint.h )
   s.files += %w( src/core/lib/iomgr/endpoint_pair.h )
+  s.files += %w( src/core/lib/iomgr/ev_poll_and_epoll_posix.h )
   s.files += %w( src/core/lib/iomgr/ev_poll_posix.h )
   s.files += %w( src/core/lib/iomgr/ev_posix.h )
   s.files += %w( src/core/lib/iomgr/exec_ctx.h )
@@ -198,6 +199,7 @@
   s.files += %w( src/core/lib/iomgr/iomgr.h )
   s.files += %w( src/core/lib/iomgr/iomgr_internal.h )
   s.files += %w( src/core/lib/iomgr/iomgr_posix.h )
+  s.files += %w( src/core/lib/iomgr/polling_entity.h )
   s.files += %w( src/core/lib/iomgr/pollset.h )
   s.files += %w( src/core/lib/iomgr/pollset_set.h )
   s.files += %w( src/core/lib/iomgr/pollset_set_windows.h )
@@ -206,7 +208,7 @@
   s.files += %w( src/core/lib/iomgr/sockaddr.h )
   s.files += %w( src/core/lib/iomgr/sockaddr_posix.h )
   s.files += %w( src/core/lib/iomgr/sockaddr_utils.h )
-  s.files += %w( src/core/lib/iomgr/sockaddr_win32.h )
+  s.files += %w( src/core/lib/iomgr/sockaddr_windows.h )
   s.files += %w( src/core/lib/iomgr/socket_utils_posix.h )
   s.files += %w( src/core/lib/iomgr/socket_windows.h )
   s.files += %w( src/core/lib/iomgr/tcp_client.h )
@@ -306,16 +308,18 @@
   s.files += %w( src/core/ext/client_config/subchannel_call_holder.h )
   s.files += %w( src/core/ext/client_config/subchannel_index.h )
   s.files += %w( src/core/ext/client_config/uri_parser.h )
-  s.files += %w( third_party/objective_c/Cronet/cronet_c_for_grpc.h )
   s.files += %w( src/core/ext/lb_policy/grpclb/load_balancer_api.h )
   s.files += %w( src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h )
   s.files += %w( third_party/nanopb/pb.h )
   s.files += %w( third_party/nanopb/pb_common.h )
   s.files += %w( third_party/nanopb/pb_decode.h )
   s.files += %w( third_party/nanopb/pb_encode.h )
+  s.files += %w( src/core/ext/load_reporting/load_reporting.h )
+  s.files += %w( src/core/ext/load_reporting/load_reporting_filter.h )
   s.files += %w( src/core/ext/census/aggregation.h )
   s.files += %w( src/core/ext/census/census_interface.h )
   s.files += %w( src/core/ext/census/census_rpc_stats.h )
+  s.files += %w( src/core/ext/census/gen/census.pb.h )
   s.files += %w( src/core/ext/census/grpc_filter.h )
   s.files += %w( src/core/ext/census/mlog.h )
   s.files += %w( src/core/ext/census/rpc_metric_id.h )
@@ -327,7 +331,7 @@
   s.files += %w( src/core/lib/channel/connected_channel.c )
   s.files += %w( src/core/lib/channel/http_client_filter.c )
   s.files += %w( src/core/lib/channel/http_server_filter.c )
-  s.files += %w( src/core/lib/compression/compression_algorithm.c )
+  s.files += %w( src/core/lib/compression/compression.c )
   s.files += %w( src/core/lib/compression/message_compress.c )
   s.files += %w( src/core/lib/debug/trace.c )
   s.files += %w( src/core/lib/http/format_request.c )
@@ -337,6 +341,7 @@
   s.files += %w( src/core/lib/iomgr/endpoint.c )
   s.files += %w( src/core/lib/iomgr/endpoint_pair_posix.c )
   s.files += %w( src/core/lib/iomgr/endpoint_pair_windows.c )
+  s.files += %w( src/core/lib/iomgr/ev_poll_and_epoll_posix.c )
   s.files += %w( src/core/lib/iomgr/ev_poll_posix.c )
   s.files += %w( src/core/lib/iomgr/ev_posix.c )
   s.files += %w( src/core/lib/iomgr/exec_ctx.c )
@@ -345,6 +350,7 @@
   s.files += %w( src/core/lib/iomgr/iomgr.c )
   s.files += %w( src/core/lib/iomgr/iomgr_posix.c )
   s.files += %w( src/core/lib/iomgr/iomgr_windows.c )
+  s.files += %w( src/core/lib/iomgr/polling_entity.c )
   s.files += %w( src/core/lib/iomgr/pollset_set_windows.c )
   s.files += %w( src/core/lib/iomgr/pollset_windows.c )
   s.files += %w( src/core/lib/iomgr/resolve_address_posix.c )
@@ -431,7 +437,7 @@
   s.files += %w( src/core/lib/security/credentials/credentials_metadata.c )
   s.files += %w( src/core/lib/security/credentials/fake/fake_credentials.c )
   s.files += %w( src/core/lib/security/credentials/google_default/credentials_posix.c )
-  s.files += %w( src/core/lib/security/credentials/google_default/credentials_win32.c )
+  s.files += %w( src/core/lib/security/credentials/google_default/credentials_windows.c )
   s.files += %w( src/core/lib/security/credentials/google_default/google_default_credentials.c )
   s.files += %w( src/core/lib/security/credentials/iam/iam_credentials.c )
   s.files += %w( src/core/lib/security/credentials/jwt/json_token.c )
@@ -472,10 +478,9 @@
   s.files += %w( src/core/ext/client_config/subchannel_index.c )
   s.files += %w( src/core/ext/client_config/uri_parser.c )
   s.files += %w( src/core/ext/transport/chttp2/server/insecure/server_chttp2.c )
+  s.files += %w( src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.c )
   s.files += %w( src/core/ext/transport/chttp2/client/insecure/channel_create.c )
-  s.files += %w( src/core/ext/transport/cronet/client/secure/cronet_channel_create.c )
-  s.files += %w( src/core/ext/transport/cronet/transport/cronet_api_dummy.c )
-  s.files += %w( src/core/ext/transport/cronet/transport/cronet_transport.c )
+  s.files += %w( src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c )
   s.files += %w( src/core/ext/lb_policy/grpclb/load_balancer_api.c )
   s.files += %w( src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c )
   s.files += %w( third_party/nanopb/pb_common.c )
@@ -485,7 +490,10 @@
   s.files += %w( src/core/ext/lb_policy/round_robin/round_robin.c )
   s.files += %w( src/core/ext/resolver/dns/native/dns_resolver.c )
   s.files += %w( src/core/ext/resolver/sockaddr/sockaddr_resolver.c )
+  s.files += %w( src/core/ext/load_reporting/load_reporting.c )
+  s.files += %w( src/core/ext/load_reporting/load_reporting_filter.c )
   s.files += %w( src/core/ext/census/context.c )
+  s.files += %w( src/core/ext/census/gen/census.pb.c )
   s.files += %w( src/core/ext/census/grpc_context.c )
   s.files += %w( src/core/ext/census/grpc_filter.c )
   s.files += %w( src/core/ext/census/grpc_plugin.c )
diff --git a/src/core/lib/support/string_win32.h b/include/grpc++/create_channel_posix.h
similarity index 71%
copy from src/core/lib/support/string_win32.h
copy to include/grpc++/create_channel_posix.h
index ff4a694..0d96159 100644
--- a/src/core/lib/support/string_win32.h
+++ b/include/grpc++/create_channel_posix.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,17 +31,27 @@
  *
  */
 
-#ifndef GRPC_CORE_LIB_SUPPORT_STRING_WIN32_H
-#define GRPC_CORE_LIB_SUPPORT_STRING_WIN32_H
+#ifndef GRPCXX_CREATE_CHANNEL_POSIX_H
+#define GRPCXX_CREATE_CHANNEL_POSIX_H
 
+#include <memory>
+
+#include <grpc++/channel.h>
 #include <grpc/support/port_platform.h>
 
-#ifdef GPR_WIN32
+namespace grpc {
 
-/* These allocate new strings using gpr_malloc to convert from and to utf-8. */
-LPTSTR gpr_char_to_tchar(LPCSTR input);
-LPSTR gpr_tchar_to_char(LPCTSTR input);
+#ifdef GPR_SUPPORT_CHANNELS_FROM_FD
 
-#endif /* GPR_WIN32 */
+/// Create a new \a Channel communicating over given file descriptor
+///
+/// \param target The name of the target.
+/// \param fd The file descriptor representing a socket.
+std::shared_ptr<Channel> CreateInsecureChannelFromFd(const grpc::string& target,
+                                                     int fd);
 
-#endif /* GRPC_CORE_LIB_SUPPORT_STRING_WIN32_H */
+#endif  // GPR_SUPPORT_CHANNELS_FROM_FD
+
+}  // namespace grpc
+
+#endif  // GRPCXX_CREATE_CHANNEL_POSIX_H
diff --git a/include/grpc++/ext/proto_server_reflection_plugin.h b/include/grpc++/ext/proto_server_reflection_plugin.h
new file mode 100644
index 0000000..517c473
--- /dev/null
+++ b/include/grpc++/ext/proto_server_reflection_plugin.h
@@ -0,0 +1,69 @@
+/*
+ *
+ * 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 GRPCXX_EXT_PROTO_SERVER_REFLECTION_PLUGIN_H
+#define GRPCXX_EXT_PROTO_SERVER_REFLECTION_PLUGIN_H
+
+#include <grpc++/impl/server_builder_plugin.h>
+#include <grpc++/support/config.h>
+
+namespace grpc {
+class ServerInitializer;
+class ProtoServerReflection;
+}  // namespace grpc
+
+namespace grpc {
+namespace reflection {
+
+class ProtoServerReflectionPlugin : public ::grpc::ServerBuilderPlugin {
+ public:
+  ProtoServerReflectionPlugin();
+  ::grpc::string name() GRPC_OVERRIDE;
+  void InitServer(::grpc::ServerInitializer* si) GRPC_OVERRIDE;
+  void Finish(::grpc::ServerInitializer* si) GRPC_OVERRIDE;
+  void ChangeArguments(const ::grpc::string& name, void* value) GRPC_OVERRIDE;
+  bool has_async_methods() const GRPC_OVERRIDE;
+  bool has_sync_methods() const GRPC_OVERRIDE;
+
+ private:
+  std::shared_ptr<::grpc::ProtoServerReflection> reflection_service_;
+};
+
+// Add proto reflection plugin to ServerBuilder. This function should be called
+// at the static initialization time.
+void InitProtoReflectionServerBuilderPlugin();
+
+}  // namespace reflection
+}  // namespace grpc
+
+#endif  // GRPCXX_EXT_PROTO_SERVER_REFLECTION_PLUGIN_H
diff --git a/include/grpc++/ext/reflection.grpc.pb.h b/include/grpc++/ext/reflection.grpc.pb.h
new file mode 100644
index 0000000..0b4ef86
--- /dev/null
+++ b/include/grpc++/ext/reflection.grpc.pb.h
@@ -0,0 +1,184 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+
+// Generated by the gRPC protobuf plugin.
+// If you make any local change, they will be lost.
+// source: reflection.proto
+// Original file comments:
+// 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.
+//
+// Service exported by server reflection
+//
+#ifndef GRPC_reflection_2eproto__INCLUDED
+#define GRPC_reflection_2eproto__INCLUDED
+
+#include <grpc++/ext/reflection.pb.h>
+
+#include <grpc++/impl/codegen/async_stream.h>
+#include <grpc++/impl/codegen/async_unary_call.h>
+#include <grpc++/impl/codegen/proto_utils.h>
+#include <grpc++/impl/codegen/rpc_method.h>
+#include <grpc++/impl/codegen/service_type.h>
+#include <grpc++/impl/codegen/status.h>
+#include <grpc++/impl/codegen/stub_options.h>
+#include <grpc++/impl/codegen/sync_stream.h>
+
+namespace grpc {
+class CompletionQueue;
+class Channel;
+class RpcService;
+class ServerCompletionQueue;
+class ServerContext;
+}  // namespace grpc
+
+namespace grpc {
+namespace reflection {
+namespace v1alpha {
+
+class ServerReflection GRPC_FINAL {
+ public:
+  class StubInterface {
+   public:
+    virtual ~StubInterface() {}
+    // The reflection service is structured as a bidirectional stream, ensuring
+    // all related requests go to a single server.
+    std::unique_ptr< ::grpc::ClientReaderWriterInterface< ::grpc::reflection::v1alpha::ServerReflectionRequest, ::grpc::reflection::v1alpha::ServerReflectionResponse>> ServerReflectionInfo(::grpc::ClientContext* context) {
+      return std::unique_ptr< ::grpc::ClientReaderWriterInterface< ::grpc::reflection::v1alpha::ServerReflectionRequest, ::grpc::reflection::v1alpha::ServerReflectionResponse>>(ServerReflectionInfoRaw(context));
+    }
+    std::unique_ptr< ::grpc::ClientAsyncReaderWriterInterface< ::grpc::reflection::v1alpha::ServerReflectionRequest, ::grpc::reflection::v1alpha::ServerReflectionResponse>> AsyncServerReflectionInfo(::grpc::ClientContext* context, ::grpc::CompletionQueue* cq, void* tag) {
+      return std::unique_ptr< ::grpc::ClientAsyncReaderWriterInterface< ::grpc::reflection::v1alpha::ServerReflectionRequest, ::grpc::reflection::v1alpha::ServerReflectionResponse>>(AsyncServerReflectionInfoRaw(context, cq, tag));
+    }
+  private:
+    virtual ::grpc::ClientReaderWriterInterface< ::grpc::reflection::v1alpha::ServerReflectionRequest, ::grpc::reflection::v1alpha::ServerReflectionResponse>* ServerReflectionInfoRaw(::grpc::ClientContext* context) = 0;
+    virtual ::grpc::ClientAsyncReaderWriterInterface< ::grpc::reflection::v1alpha::ServerReflectionRequest, ::grpc::reflection::v1alpha::ServerReflectionResponse>* AsyncServerReflectionInfoRaw(::grpc::ClientContext* context, ::grpc::CompletionQueue* cq, void* tag) = 0;
+  };
+  class Stub GRPC_FINAL : public StubInterface {
+   public:
+    Stub(const std::shared_ptr< ::grpc::ChannelInterface>& channel);
+    std::unique_ptr< ::grpc::ClientReaderWriter< ::grpc::reflection::v1alpha::ServerReflectionRequest, ::grpc::reflection::v1alpha::ServerReflectionResponse>> ServerReflectionInfo(::grpc::ClientContext* context) {
+      return std::unique_ptr< ::grpc::ClientReaderWriter< ::grpc::reflection::v1alpha::ServerReflectionRequest, ::grpc::reflection::v1alpha::ServerReflectionResponse>>(ServerReflectionInfoRaw(context));
+    }
+    std::unique_ptr<  ::grpc::ClientAsyncReaderWriter< ::grpc::reflection::v1alpha::ServerReflectionRequest, ::grpc::reflection::v1alpha::ServerReflectionResponse>> AsyncServerReflectionInfo(::grpc::ClientContext* context, ::grpc::CompletionQueue* cq, void* tag) {
+      return std::unique_ptr< ::grpc::ClientAsyncReaderWriter< ::grpc::reflection::v1alpha::ServerReflectionRequest, ::grpc::reflection::v1alpha::ServerReflectionResponse>>(AsyncServerReflectionInfoRaw(context, cq, tag));
+    }
+
+   private:
+    std::shared_ptr< ::grpc::ChannelInterface> channel_;
+    ::grpc::ClientReaderWriter< ::grpc::reflection::v1alpha::ServerReflectionRequest, ::grpc::reflection::v1alpha::ServerReflectionResponse>* ServerReflectionInfoRaw(::grpc::ClientContext* context) GRPC_OVERRIDE;
+    ::grpc::ClientAsyncReaderWriter< ::grpc::reflection::v1alpha::ServerReflectionRequest, ::grpc::reflection::v1alpha::ServerReflectionResponse>* AsyncServerReflectionInfoRaw(::grpc::ClientContext* context, ::grpc::CompletionQueue* cq, void* tag) GRPC_OVERRIDE;
+    const ::grpc::RpcMethod rpcmethod_ServerReflectionInfo_;
+  };
+  static std::unique_ptr<Stub> NewStub(const std::shared_ptr< ::grpc::ChannelInterface>& channel, const ::grpc::StubOptions& options = ::grpc::StubOptions());
+
+  class Service : public ::grpc::Service {
+   public:
+    Service();
+    virtual ~Service();
+    // The reflection service is structured as a bidirectional stream, ensuring
+    // all related requests go to a single server.
+    virtual ::grpc::Status ServerReflectionInfo(::grpc::ServerContext* context, ::grpc::ServerReaderWriter< ::grpc::reflection::v1alpha::ServerReflectionResponse, ::grpc::reflection::v1alpha::ServerReflectionRequest>* stream);
+  };
+  template <class BaseClass>
+  class WithAsyncMethod_ServerReflectionInfo : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service *service) {}
+   public:
+    WithAsyncMethod_ServerReflectionInfo() {
+      ::grpc::Service::MarkMethodAsync(0);
+    }
+    ~WithAsyncMethod_ServerReflectionInfo() GRPC_OVERRIDE {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status ServerReflectionInfo(::grpc::ServerContext* context, ::grpc::ServerReaderWriter< ::grpc::reflection::v1alpha::ServerReflectionResponse, ::grpc::reflection::v1alpha::ServerReflectionRequest>* stream) GRPC_FINAL GRPC_OVERRIDE {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    void RequestServerReflectionInfo(::grpc::ServerContext* context, ::grpc::ServerAsyncReaderWriter< ::grpc::reflection::v1alpha::ServerReflectionResponse, ::grpc::reflection::v1alpha::ServerReflectionRequest>* stream, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) {
+      ::grpc::Service::RequestAsyncBidiStreaming(0, context, stream, new_call_cq, notification_cq, tag);
+    }
+  };
+  typedef WithAsyncMethod_ServerReflectionInfo<Service > AsyncService;
+  template <class BaseClass>
+  class WithGenericMethod_ServerReflectionInfo : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service *service) {}
+   public:
+    WithGenericMethod_ServerReflectionInfo() {
+      ::grpc::Service::MarkMethodGeneric(0);
+    }
+    ~WithGenericMethod_ServerReflectionInfo() GRPC_OVERRIDE {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status ServerReflectionInfo(::grpc::ServerContext* context, ::grpc::ServerReaderWriter< ::grpc::reflection::v1alpha::ServerReflectionResponse, ::grpc::reflection::v1alpha::ServerReflectionRequest>* stream) GRPC_FINAL GRPC_OVERRIDE {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+  };
+};
+
+}  // namespace v1alpha
+}  // namespace reflection
+}  // namespace grpc
+
+
+#endif  // GRPC_reflection_2eproto__INCLUDED
diff --git a/include/grpc++/ext/reflection.pb.h b/include/grpc++/ext/reflection.pb.h
new file mode 100644
index 0000000..00d0773
--- /dev/null
+++ b/include/grpc++/ext/reflection.pb.h
@@ -0,0 +1,2035 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: reflection.proto
+
+#ifndef PROTOBUF_reflection_2eproto__INCLUDED
+#define PROTOBUF_reflection_2eproto__INCLUDED
+
+#include <string>
+
+#include <google/protobuf/stubs/common.h>
+
+#if GOOGLE_PROTOBUF_VERSION < 3000000
+#error This file was generated by a newer version of protoc which is
+#error incompatible with your Protocol Buffer headers.  Please update
+#error your headers.
+#endif
+#if 3000000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION
+#error This file was generated by an older version of protoc which is
+#error incompatible with your Protocol Buffer headers.  Please
+#error regenerate this file with a newer version of protoc.
+#endif
+
+#include <google/protobuf/arena.h>
+#include <google/protobuf/arenastring.h>
+#include <google/protobuf/generated_message_util.h>
+#include <google/protobuf/metadata.h>
+#include <google/protobuf/message.h>
+#include <google/protobuf/repeated_field.h>
+#include <google/protobuf/extension_set.h>
+#include <google/protobuf/unknown_field_set.h>
+// @@protoc_insertion_point(includes)
+
+namespace grpc {
+namespace reflection {
+namespace v1alpha {
+
+// Internal implementation detail -- do not call these.
+void protobuf_AddDesc_reflection_2eproto();
+void protobuf_AssignDesc_reflection_2eproto();
+void protobuf_ShutdownFile_reflection_2eproto();
+
+class ErrorResponse;
+class ExtensionNumberResponse;
+class ExtensionRequest;
+class FileDescriptorResponse;
+class ListServiceResponse;
+class ServerReflectionRequest;
+class ServerReflectionResponse;
+class ServiceResponse;
+
+// ===================================================================
+
+class ServerReflectionRequest : public ::google::protobuf::Message {
+ public:
+  ServerReflectionRequest();
+  virtual ~ServerReflectionRequest();
+
+  ServerReflectionRequest(const ServerReflectionRequest& from);
+
+  inline ServerReflectionRequest& operator=(const ServerReflectionRequest& from) {
+    CopyFrom(from);
+    return *this;
+  }
+
+  static const ::google::protobuf::Descriptor* descriptor();
+  static const ServerReflectionRequest& default_instance();
+
+  enum MessageRequestCase {
+    kFileByFilename = 3,
+    kFileContainingSymbol = 4,
+    kFileContainingExtension = 5,
+    kAllExtensionNumbersOfType = 6,
+    kListServices = 7,
+    MESSAGE_REQUEST_NOT_SET = 0,
+  };
+
+  void Swap(ServerReflectionRequest* other);
+
+  // implements Message ----------------------------------------------
+
+  inline ServerReflectionRequest* New() const { return New(NULL); }
+
+  ServerReflectionRequest* New(::google::protobuf::Arena* arena) const;
+  void CopyFrom(const ::google::protobuf::Message& from);
+  void MergeFrom(const ::google::protobuf::Message& from);
+  void CopyFrom(const ServerReflectionRequest& from);
+  void MergeFrom(const ServerReflectionRequest& from);
+  void Clear();
+  bool IsInitialized() const;
+
+  int ByteSize() const;
+  bool MergePartialFromCodedStream(
+      ::google::protobuf::io::CodedInputStream* input);
+  void SerializeWithCachedSizes(
+      ::google::protobuf::io::CodedOutputStream* output) const;
+  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+  int GetCachedSize() const { return _cached_size_; }
+  private:
+  void SharedCtor();
+  void SharedDtor();
+  void SetCachedSize(int size) const;
+  void InternalSwap(ServerReflectionRequest* other);
+  private:
+  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
+    return _internal_metadata_.arena();
+  }
+  inline void* MaybeArenaPtr() const {
+    return _internal_metadata_.raw_arena_ptr();
+  }
+  public:
+
+  ::google::protobuf::Metadata GetMetadata() const;
+
+  // nested types ----------------------------------------------------
+
+  // accessors -------------------------------------------------------
+
+  // optional string host = 1;
+  void clear_host();
+  static const int kHostFieldNumber = 1;
+  const ::std::string& host() const;
+  void set_host(const ::std::string& value);
+  void set_host(const char* value);
+  void set_host(const char* value, size_t size);
+  ::std::string* mutable_host();
+  ::std::string* release_host();
+  void set_allocated_host(::std::string* host);
+
+  // optional string file_by_filename = 3;
+  private:
+  bool has_file_by_filename() const;
+  public:
+  void clear_file_by_filename();
+  static const int kFileByFilenameFieldNumber = 3;
+  const ::std::string& file_by_filename() const;
+  void set_file_by_filename(const ::std::string& value);
+  void set_file_by_filename(const char* value);
+  void set_file_by_filename(const char* value, size_t size);
+  ::std::string* mutable_file_by_filename();
+  ::std::string* release_file_by_filename();
+  void set_allocated_file_by_filename(::std::string* file_by_filename);
+
+  // optional string file_containing_symbol = 4;
+  private:
+  bool has_file_containing_symbol() const;
+  public:
+  void clear_file_containing_symbol();
+  static const int kFileContainingSymbolFieldNumber = 4;
+  const ::std::string& file_containing_symbol() const;
+  void set_file_containing_symbol(const ::std::string& value);
+  void set_file_containing_symbol(const char* value);
+  void set_file_containing_symbol(const char* value, size_t size);
+  ::std::string* mutable_file_containing_symbol();
+  ::std::string* release_file_containing_symbol();
+  void set_allocated_file_containing_symbol(::std::string* file_containing_symbol);
+
+  // optional .grpc.reflection.v1alpha.ExtensionRequest file_containing_extension = 5;
+  bool has_file_containing_extension() const;
+  void clear_file_containing_extension();
+  static const int kFileContainingExtensionFieldNumber = 5;
+  const ::grpc::reflection::v1alpha::ExtensionRequest& file_containing_extension() const;
+  ::grpc::reflection::v1alpha::ExtensionRequest* mutable_file_containing_extension();
+  ::grpc::reflection::v1alpha::ExtensionRequest* release_file_containing_extension();
+  void set_allocated_file_containing_extension(::grpc::reflection::v1alpha::ExtensionRequest* file_containing_extension);
+
+  // optional string all_extension_numbers_of_type = 6;
+  private:
+  bool has_all_extension_numbers_of_type() const;
+  public:
+  void clear_all_extension_numbers_of_type();
+  static const int kAllExtensionNumbersOfTypeFieldNumber = 6;
+  const ::std::string& all_extension_numbers_of_type() const;
+  void set_all_extension_numbers_of_type(const ::std::string& value);
+  void set_all_extension_numbers_of_type(const char* value);
+  void set_all_extension_numbers_of_type(const char* value, size_t size);
+  ::std::string* mutable_all_extension_numbers_of_type();
+  ::std::string* release_all_extension_numbers_of_type();
+  void set_allocated_all_extension_numbers_of_type(::std::string* all_extension_numbers_of_type);
+
+  // optional string list_services = 7;
+  private:
+  bool has_list_services() const;
+  public:
+  void clear_list_services();
+  static const int kListServicesFieldNumber = 7;
+  const ::std::string& list_services() const;
+  void set_list_services(const ::std::string& value);
+  void set_list_services(const char* value);
+  void set_list_services(const char* value, size_t size);
+  ::std::string* mutable_list_services();
+  ::std::string* release_list_services();
+  void set_allocated_list_services(::std::string* list_services);
+
+  MessageRequestCase message_request_case() const;
+  // @@protoc_insertion_point(class_scope:grpc.reflection.v1alpha.ServerReflectionRequest)
+ private:
+  inline void set_has_file_by_filename();
+  inline void set_has_file_containing_symbol();
+  inline void set_has_file_containing_extension();
+  inline void set_has_all_extension_numbers_of_type();
+  inline void set_has_list_services();
+
+  inline bool has_message_request() const;
+  void clear_message_request();
+  inline void clear_has_message_request();
+
+  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+  bool _is_default_instance_;
+  ::google::protobuf::internal::ArenaStringPtr host_;
+  union MessageRequestUnion {
+    MessageRequestUnion() {}
+    ::google::protobuf::internal::ArenaStringPtr file_by_filename_;
+    ::google::protobuf::internal::ArenaStringPtr file_containing_symbol_;
+    ::grpc::reflection::v1alpha::ExtensionRequest* file_containing_extension_;
+    ::google::protobuf::internal::ArenaStringPtr all_extension_numbers_of_type_;
+    ::google::protobuf::internal::ArenaStringPtr list_services_;
+  } message_request_;
+  mutable int _cached_size_;
+  ::google::protobuf::uint32 _oneof_case_[1];
+
+  friend void  protobuf_AddDesc_reflection_2eproto();
+  friend void protobuf_AssignDesc_reflection_2eproto();
+  friend void protobuf_ShutdownFile_reflection_2eproto();
+
+  void InitAsDefaultInstance();
+  static ServerReflectionRequest* default_instance_;
+};
+// -------------------------------------------------------------------
+
+class ExtensionRequest : public ::google::protobuf::Message {
+ public:
+  ExtensionRequest();
+  virtual ~ExtensionRequest();
+
+  ExtensionRequest(const ExtensionRequest& from);
+
+  inline ExtensionRequest& operator=(const ExtensionRequest& from) {
+    CopyFrom(from);
+    return *this;
+  }
+
+  static const ::google::protobuf::Descriptor* descriptor();
+  static const ExtensionRequest& default_instance();
+
+  void Swap(ExtensionRequest* other);
+
+  // implements Message ----------------------------------------------
+
+  inline ExtensionRequest* New() const { return New(NULL); }
+
+  ExtensionRequest* New(::google::protobuf::Arena* arena) const;
+  void CopyFrom(const ::google::protobuf::Message& from);
+  void MergeFrom(const ::google::protobuf::Message& from);
+  void CopyFrom(const ExtensionRequest& from);
+  void MergeFrom(const ExtensionRequest& from);
+  void Clear();
+  bool IsInitialized() const;
+
+  int ByteSize() const;
+  bool MergePartialFromCodedStream(
+      ::google::protobuf::io::CodedInputStream* input);
+  void SerializeWithCachedSizes(
+      ::google::protobuf::io::CodedOutputStream* output) const;
+  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+  int GetCachedSize() const { return _cached_size_; }
+  private:
+  void SharedCtor();
+  void SharedDtor();
+  void SetCachedSize(int size) const;
+  void InternalSwap(ExtensionRequest* other);
+  private:
+  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
+    return _internal_metadata_.arena();
+  }
+  inline void* MaybeArenaPtr() const {
+    return _internal_metadata_.raw_arena_ptr();
+  }
+  public:
+
+  ::google::protobuf::Metadata GetMetadata() const;
+
+  // nested types ----------------------------------------------------
+
+  // accessors -------------------------------------------------------
+
+  // optional string containing_type = 1;
+  void clear_containing_type();
+  static const int kContainingTypeFieldNumber = 1;
+  const ::std::string& containing_type() const;
+  void set_containing_type(const ::std::string& value);
+  void set_containing_type(const char* value);
+  void set_containing_type(const char* value, size_t size);
+  ::std::string* mutable_containing_type();
+  ::std::string* release_containing_type();
+  void set_allocated_containing_type(::std::string* containing_type);
+
+  // optional int32 extension_number = 2;
+  void clear_extension_number();
+  static const int kExtensionNumberFieldNumber = 2;
+  ::google::protobuf::int32 extension_number() const;
+  void set_extension_number(::google::protobuf::int32 value);
+
+  // @@protoc_insertion_point(class_scope:grpc.reflection.v1alpha.ExtensionRequest)
+ private:
+
+  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+  bool _is_default_instance_;
+  ::google::protobuf::internal::ArenaStringPtr containing_type_;
+  ::google::protobuf::int32 extension_number_;
+  mutable int _cached_size_;
+  friend void  protobuf_AddDesc_reflection_2eproto();
+  friend void protobuf_AssignDesc_reflection_2eproto();
+  friend void protobuf_ShutdownFile_reflection_2eproto();
+
+  void InitAsDefaultInstance();
+  static ExtensionRequest* default_instance_;
+};
+// -------------------------------------------------------------------
+
+class ServerReflectionResponse : public ::google::protobuf::Message {
+ public:
+  ServerReflectionResponse();
+  virtual ~ServerReflectionResponse();
+
+  ServerReflectionResponse(const ServerReflectionResponse& from);
+
+  inline ServerReflectionResponse& operator=(const ServerReflectionResponse& from) {
+    CopyFrom(from);
+    return *this;
+  }
+
+  static const ::google::protobuf::Descriptor* descriptor();
+  static const ServerReflectionResponse& default_instance();
+
+  enum MessageResponseCase {
+    kFileDescriptorResponse = 4,
+    kAllExtensionNumbersResponse = 5,
+    kListServicesResponse = 6,
+    kErrorResponse = 7,
+    MESSAGE_RESPONSE_NOT_SET = 0,
+  };
+
+  void Swap(ServerReflectionResponse* other);
+
+  // implements Message ----------------------------------------------
+
+  inline ServerReflectionResponse* New() const { return New(NULL); }
+
+  ServerReflectionResponse* New(::google::protobuf::Arena* arena) const;
+  void CopyFrom(const ::google::protobuf::Message& from);
+  void MergeFrom(const ::google::protobuf::Message& from);
+  void CopyFrom(const ServerReflectionResponse& from);
+  void MergeFrom(const ServerReflectionResponse& from);
+  void Clear();
+  bool IsInitialized() const;
+
+  int ByteSize() const;
+  bool MergePartialFromCodedStream(
+      ::google::protobuf::io::CodedInputStream* input);
+  void SerializeWithCachedSizes(
+      ::google::protobuf::io::CodedOutputStream* output) const;
+  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+  int GetCachedSize() const { return _cached_size_; }
+  private:
+  void SharedCtor();
+  void SharedDtor();
+  void SetCachedSize(int size) const;
+  void InternalSwap(ServerReflectionResponse* other);
+  private:
+  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
+    return _internal_metadata_.arena();
+  }
+  inline void* MaybeArenaPtr() const {
+    return _internal_metadata_.raw_arena_ptr();
+  }
+  public:
+
+  ::google::protobuf::Metadata GetMetadata() const;
+
+  // nested types ----------------------------------------------------
+
+  // accessors -------------------------------------------------------
+
+  // optional string valid_host = 1;
+  void clear_valid_host();
+  static const int kValidHostFieldNumber = 1;
+  const ::std::string& valid_host() const;
+  void set_valid_host(const ::std::string& value);
+  void set_valid_host(const char* value);
+  void set_valid_host(const char* value, size_t size);
+  ::std::string* mutable_valid_host();
+  ::std::string* release_valid_host();
+  void set_allocated_valid_host(::std::string* valid_host);
+
+  // optional .grpc.reflection.v1alpha.ServerReflectionRequest original_request = 2;
+  bool has_original_request() const;
+  void clear_original_request();
+  static const int kOriginalRequestFieldNumber = 2;
+  const ::grpc::reflection::v1alpha::ServerReflectionRequest& original_request() const;
+  ::grpc::reflection::v1alpha::ServerReflectionRequest* mutable_original_request();
+  ::grpc::reflection::v1alpha::ServerReflectionRequest* release_original_request();
+  void set_allocated_original_request(::grpc::reflection::v1alpha::ServerReflectionRequest* original_request);
+
+  // optional .grpc.reflection.v1alpha.FileDescriptorResponse file_descriptor_response = 4;
+  bool has_file_descriptor_response() const;
+  void clear_file_descriptor_response();
+  static const int kFileDescriptorResponseFieldNumber = 4;
+  const ::grpc::reflection::v1alpha::FileDescriptorResponse& file_descriptor_response() const;
+  ::grpc::reflection::v1alpha::FileDescriptorResponse* mutable_file_descriptor_response();
+  ::grpc::reflection::v1alpha::FileDescriptorResponse* release_file_descriptor_response();
+  void set_allocated_file_descriptor_response(::grpc::reflection::v1alpha::FileDescriptorResponse* file_descriptor_response);
+
+  // optional .grpc.reflection.v1alpha.ExtensionNumberResponse all_extension_numbers_response = 5;
+  bool has_all_extension_numbers_response() const;
+  void clear_all_extension_numbers_response();
+  static const int kAllExtensionNumbersResponseFieldNumber = 5;
+  const ::grpc::reflection::v1alpha::ExtensionNumberResponse& all_extension_numbers_response() const;
+  ::grpc::reflection::v1alpha::ExtensionNumberResponse* mutable_all_extension_numbers_response();
+  ::grpc::reflection::v1alpha::ExtensionNumberResponse* release_all_extension_numbers_response();
+  void set_allocated_all_extension_numbers_response(::grpc::reflection::v1alpha::ExtensionNumberResponse* all_extension_numbers_response);
+
+  // optional .grpc.reflection.v1alpha.ListServiceResponse list_services_response = 6;
+  bool has_list_services_response() const;
+  void clear_list_services_response();
+  static const int kListServicesResponseFieldNumber = 6;
+  const ::grpc::reflection::v1alpha::ListServiceResponse& list_services_response() const;
+  ::grpc::reflection::v1alpha::ListServiceResponse* mutable_list_services_response();
+  ::grpc::reflection::v1alpha::ListServiceResponse* release_list_services_response();
+  void set_allocated_list_services_response(::grpc::reflection::v1alpha::ListServiceResponse* list_services_response);
+
+  // optional .grpc.reflection.v1alpha.ErrorResponse error_response = 7;
+  bool has_error_response() const;
+  void clear_error_response();
+  static const int kErrorResponseFieldNumber = 7;
+  const ::grpc::reflection::v1alpha::ErrorResponse& error_response() const;
+  ::grpc::reflection::v1alpha::ErrorResponse* mutable_error_response();
+  ::grpc::reflection::v1alpha::ErrorResponse* release_error_response();
+  void set_allocated_error_response(::grpc::reflection::v1alpha::ErrorResponse* error_response);
+
+  MessageResponseCase message_response_case() const;
+  // @@protoc_insertion_point(class_scope:grpc.reflection.v1alpha.ServerReflectionResponse)
+ private:
+  inline void set_has_file_descriptor_response();
+  inline void set_has_all_extension_numbers_response();
+  inline void set_has_list_services_response();
+  inline void set_has_error_response();
+
+  inline bool has_message_response() const;
+  void clear_message_response();
+  inline void clear_has_message_response();
+
+  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+  bool _is_default_instance_;
+  ::google::protobuf::internal::ArenaStringPtr valid_host_;
+  ::grpc::reflection::v1alpha::ServerReflectionRequest* original_request_;
+  union MessageResponseUnion {
+    MessageResponseUnion() {}
+    ::grpc::reflection::v1alpha::FileDescriptorResponse* file_descriptor_response_;
+    ::grpc::reflection::v1alpha::ExtensionNumberResponse* all_extension_numbers_response_;
+    ::grpc::reflection::v1alpha::ListServiceResponse* list_services_response_;
+    ::grpc::reflection::v1alpha::ErrorResponse* error_response_;
+  } message_response_;
+  mutable int _cached_size_;
+  ::google::protobuf::uint32 _oneof_case_[1];
+
+  friend void  protobuf_AddDesc_reflection_2eproto();
+  friend void protobuf_AssignDesc_reflection_2eproto();
+  friend void protobuf_ShutdownFile_reflection_2eproto();
+
+  void InitAsDefaultInstance();
+  static ServerReflectionResponse* default_instance_;
+};
+// -------------------------------------------------------------------
+
+class FileDescriptorResponse : public ::google::protobuf::Message {
+ public:
+  FileDescriptorResponse();
+  virtual ~FileDescriptorResponse();
+
+  FileDescriptorResponse(const FileDescriptorResponse& from);
+
+  inline FileDescriptorResponse& operator=(const FileDescriptorResponse& from) {
+    CopyFrom(from);
+    return *this;
+  }
+
+  static const ::google::protobuf::Descriptor* descriptor();
+  static const FileDescriptorResponse& default_instance();
+
+  void Swap(FileDescriptorResponse* other);
+
+  // implements Message ----------------------------------------------
+
+  inline FileDescriptorResponse* New() const { return New(NULL); }
+
+  FileDescriptorResponse* New(::google::protobuf::Arena* arena) const;
+  void CopyFrom(const ::google::protobuf::Message& from);
+  void MergeFrom(const ::google::protobuf::Message& from);
+  void CopyFrom(const FileDescriptorResponse& from);
+  void MergeFrom(const FileDescriptorResponse& from);
+  void Clear();
+  bool IsInitialized() const;
+
+  int ByteSize() const;
+  bool MergePartialFromCodedStream(
+      ::google::protobuf::io::CodedInputStream* input);
+  void SerializeWithCachedSizes(
+      ::google::protobuf::io::CodedOutputStream* output) const;
+  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+  int GetCachedSize() const { return _cached_size_; }
+  private:
+  void SharedCtor();
+  void SharedDtor();
+  void SetCachedSize(int size) const;
+  void InternalSwap(FileDescriptorResponse* other);
+  private:
+  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
+    return _internal_metadata_.arena();
+  }
+  inline void* MaybeArenaPtr() const {
+    return _internal_metadata_.raw_arena_ptr();
+  }
+  public:
+
+  ::google::protobuf::Metadata GetMetadata() const;
+
+  // nested types ----------------------------------------------------
+
+  // accessors -------------------------------------------------------
+
+  // repeated bytes file_descriptor_proto = 1;
+  int file_descriptor_proto_size() const;
+  void clear_file_descriptor_proto();
+  static const int kFileDescriptorProtoFieldNumber = 1;
+  const ::std::string& file_descriptor_proto(int index) const;
+  ::std::string* mutable_file_descriptor_proto(int index);
+  void set_file_descriptor_proto(int index, const ::std::string& value);
+  void set_file_descriptor_proto(int index, const char* value);
+  void set_file_descriptor_proto(int index, const void* value, size_t size);
+  ::std::string* add_file_descriptor_proto();
+  void add_file_descriptor_proto(const ::std::string& value);
+  void add_file_descriptor_proto(const char* value);
+  void add_file_descriptor_proto(const void* value, size_t size);
+  const ::google::protobuf::RepeatedPtrField< ::std::string>& file_descriptor_proto() const;
+  ::google::protobuf::RepeatedPtrField< ::std::string>* mutable_file_descriptor_proto();
+
+  // @@protoc_insertion_point(class_scope:grpc.reflection.v1alpha.FileDescriptorResponse)
+ private:
+
+  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+  bool _is_default_instance_;
+  ::google::protobuf::RepeatedPtrField< ::std::string> file_descriptor_proto_;
+  mutable int _cached_size_;
+  friend void  protobuf_AddDesc_reflection_2eproto();
+  friend void protobuf_AssignDesc_reflection_2eproto();
+  friend void protobuf_ShutdownFile_reflection_2eproto();
+
+  void InitAsDefaultInstance();
+  static FileDescriptorResponse* default_instance_;
+};
+// -------------------------------------------------------------------
+
+class ExtensionNumberResponse : public ::google::protobuf::Message {
+ public:
+  ExtensionNumberResponse();
+  virtual ~ExtensionNumberResponse();
+
+  ExtensionNumberResponse(const ExtensionNumberResponse& from);
+
+  inline ExtensionNumberResponse& operator=(const ExtensionNumberResponse& from) {
+    CopyFrom(from);
+    return *this;
+  }
+
+  static const ::google::protobuf::Descriptor* descriptor();
+  static const ExtensionNumberResponse& default_instance();
+
+  void Swap(ExtensionNumberResponse* other);
+
+  // implements Message ----------------------------------------------
+
+  inline ExtensionNumberResponse* New() const { return New(NULL); }
+
+  ExtensionNumberResponse* New(::google::protobuf::Arena* arena) const;
+  void CopyFrom(const ::google::protobuf::Message& from);
+  void MergeFrom(const ::google::protobuf::Message& from);
+  void CopyFrom(const ExtensionNumberResponse& from);
+  void MergeFrom(const ExtensionNumberResponse& from);
+  void Clear();
+  bool IsInitialized() const;
+
+  int ByteSize() const;
+  bool MergePartialFromCodedStream(
+      ::google::protobuf::io::CodedInputStream* input);
+  void SerializeWithCachedSizes(
+      ::google::protobuf::io::CodedOutputStream* output) const;
+  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+  int GetCachedSize() const { return _cached_size_; }
+  private:
+  void SharedCtor();
+  void SharedDtor();
+  void SetCachedSize(int size) const;
+  void InternalSwap(ExtensionNumberResponse* other);
+  private:
+  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
+    return _internal_metadata_.arena();
+  }
+  inline void* MaybeArenaPtr() const {
+    return _internal_metadata_.raw_arena_ptr();
+  }
+  public:
+
+  ::google::protobuf::Metadata GetMetadata() const;
+
+  // nested types ----------------------------------------------------
+
+  // accessors -------------------------------------------------------
+
+  // optional string base_type_name = 1;
+  void clear_base_type_name();
+  static const int kBaseTypeNameFieldNumber = 1;
+  const ::std::string& base_type_name() const;
+  void set_base_type_name(const ::std::string& value);
+  void set_base_type_name(const char* value);
+  void set_base_type_name(const char* value, size_t size);
+  ::std::string* mutable_base_type_name();
+  ::std::string* release_base_type_name();
+  void set_allocated_base_type_name(::std::string* base_type_name);
+
+  // repeated int32 extension_number = 2;
+  int extension_number_size() const;
+  void clear_extension_number();
+  static const int kExtensionNumberFieldNumber = 2;
+  ::google::protobuf::int32 extension_number(int index) const;
+  void set_extension_number(int index, ::google::protobuf::int32 value);
+  void add_extension_number(::google::protobuf::int32 value);
+  const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >&
+      extension_number() const;
+  ::google::protobuf::RepeatedField< ::google::protobuf::int32 >*
+      mutable_extension_number();
+
+  // @@protoc_insertion_point(class_scope:grpc.reflection.v1alpha.ExtensionNumberResponse)
+ private:
+
+  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+  bool _is_default_instance_;
+  ::google::protobuf::internal::ArenaStringPtr base_type_name_;
+  ::google::protobuf::RepeatedField< ::google::protobuf::int32 > extension_number_;
+  mutable int _extension_number_cached_byte_size_;
+  mutable int _cached_size_;
+  friend void  protobuf_AddDesc_reflection_2eproto();
+  friend void protobuf_AssignDesc_reflection_2eproto();
+  friend void protobuf_ShutdownFile_reflection_2eproto();
+
+  void InitAsDefaultInstance();
+  static ExtensionNumberResponse* default_instance_;
+};
+// -------------------------------------------------------------------
+
+class ListServiceResponse : public ::google::protobuf::Message {
+ public:
+  ListServiceResponse();
+  virtual ~ListServiceResponse();
+
+  ListServiceResponse(const ListServiceResponse& from);
+
+  inline ListServiceResponse& operator=(const ListServiceResponse& from) {
+    CopyFrom(from);
+    return *this;
+  }
+
+  static const ::google::protobuf::Descriptor* descriptor();
+  static const ListServiceResponse& default_instance();
+
+  void Swap(ListServiceResponse* other);
+
+  // implements Message ----------------------------------------------
+
+  inline ListServiceResponse* New() const { return New(NULL); }
+
+  ListServiceResponse* New(::google::protobuf::Arena* arena) const;
+  void CopyFrom(const ::google::protobuf::Message& from);
+  void MergeFrom(const ::google::protobuf::Message& from);
+  void CopyFrom(const ListServiceResponse& from);
+  void MergeFrom(const ListServiceResponse& from);
+  void Clear();
+  bool IsInitialized() const;
+
+  int ByteSize() const;
+  bool MergePartialFromCodedStream(
+      ::google::protobuf::io::CodedInputStream* input);
+  void SerializeWithCachedSizes(
+      ::google::protobuf::io::CodedOutputStream* output) const;
+  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+  int GetCachedSize() const { return _cached_size_; }
+  private:
+  void SharedCtor();
+  void SharedDtor();
+  void SetCachedSize(int size) const;
+  void InternalSwap(ListServiceResponse* other);
+  private:
+  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
+    return _internal_metadata_.arena();
+  }
+  inline void* MaybeArenaPtr() const {
+    return _internal_metadata_.raw_arena_ptr();
+  }
+  public:
+
+  ::google::protobuf::Metadata GetMetadata() const;
+
+  // nested types ----------------------------------------------------
+
+  // accessors -------------------------------------------------------
+
+  // repeated .grpc.reflection.v1alpha.ServiceResponse service = 1;
+  int service_size() const;
+  void clear_service();
+  static const int kServiceFieldNumber = 1;
+  const ::grpc::reflection::v1alpha::ServiceResponse& service(int index) const;
+  ::grpc::reflection::v1alpha::ServiceResponse* mutable_service(int index);
+  ::grpc::reflection::v1alpha::ServiceResponse* add_service();
+  ::google::protobuf::RepeatedPtrField< ::grpc::reflection::v1alpha::ServiceResponse >*
+      mutable_service();
+  const ::google::protobuf::RepeatedPtrField< ::grpc::reflection::v1alpha::ServiceResponse >&
+      service() const;
+
+  // @@protoc_insertion_point(class_scope:grpc.reflection.v1alpha.ListServiceResponse)
+ private:
+
+  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+  bool _is_default_instance_;
+  ::google::protobuf::RepeatedPtrField< ::grpc::reflection::v1alpha::ServiceResponse > service_;
+  mutable int _cached_size_;
+  friend void  protobuf_AddDesc_reflection_2eproto();
+  friend void protobuf_AssignDesc_reflection_2eproto();
+  friend void protobuf_ShutdownFile_reflection_2eproto();
+
+  void InitAsDefaultInstance();
+  static ListServiceResponse* default_instance_;
+};
+// -------------------------------------------------------------------
+
+class ServiceResponse : public ::google::protobuf::Message {
+ public:
+  ServiceResponse();
+  virtual ~ServiceResponse();
+
+  ServiceResponse(const ServiceResponse& from);
+
+  inline ServiceResponse& operator=(const ServiceResponse& from) {
+    CopyFrom(from);
+    return *this;
+  }
+
+  static const ::google::protobuf::Descriptor* descriptor();
+  static const ServiceResponse& default_instance();
+
+  void Swap(ServiceResponse* other);
+
+  // implements Message ----------------------------------------------
+
+  inline ServiceResponse* New() const { return New(NULL); }
+
+  ServiceResponse* New(::google::protobuf::Arena* arena) const;
+  void CopyFrom(const ::google::protobuf::Message& from);
+  void MergeFrom(const ::google::protobuf::Message& from);
+  void CopyFrom(const ServiceResponse& from);
+  void MergeFrom(const ServiceResponse& from);
+  void Clear();
+  bool IsInitialized() const;
+
+  int ByteSize() const;
+  bool MergePartialFromCodedStream(
+      ::google::protobuf::io::CodedInputStream* input);
+  void SerializeWithCachedSizes(
+      ::google::protobuf::io::CodedOutputStream* output) const;
+  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+  int GetCachedSize() const { return _cached_size_; }
+  private:
+  void SharedCtor();
+  void SharedDtor();
+  void SetCachedSize(int size) const;
+  void InternalSwap(ServiceResponse* other);
+  private:
+  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
+    return _internal_metadata_.arena();
+  }
+  inline void* MaybeArenaPtr() const {
+    return _internal_metadata_.raw_arena_ptr();
+  }
+  public:
+
+  ::google::protobuf::Metadata GetMetadata() const;
+
+  // nested types ----------------------------------------------------
+
+  // accessors -------------------------------------------------------
+
+  // optional string name = 1;
+  void clear_name();
+  static const int kNameFieldNumber = 1;
+  const ::std::string& name() const;
+  void set_name(const ::std::string& value);
+  void set_name(const char* value);
+  void set_name(const char* value, size_t size);
+  ::std::string* mutable_name();
+  ::std::string* release_name();
+  void set_allocated_name(::std::string* name);
+
+  // @@protoc_insertion_point(class_scope:grpc.reflection.v1alpha.ServiceResponse)
+ private:
+
+  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+  bool _is_default_instance_;
+  ::google::protobuf::internal::ArenaStringPtr name_;
+  mutable int _cached_size_;
+  friend void  protobuf_AddDesc_reflection_2eproto();
+  friend void protobuf_AssignDesc_reflection_2eproto();
+  friend void protobuf_ShutdownFile_reflection_2eproto();
+
+  void InitAsDefaultInstance();
+  static ServiceResponse* default_instance_;
+};
+// -------------------------------------------------------------------
+
+class ErrorResponse : public ::google::protobuf::Message {
+ public:
+  ErrorResponse();
+  virtual ~ErrorResponse();
+
+  ErrorResponse(const ErrorResponse& from);
+
+  inline ErrorResponse& operator=(const ErrorResponse& from) {
+    CopyFrom(from);
+    return *this;
+  }
+
+  static const ::google::protobuf::Descriptor* descriptor();
+  static const ErrorResponse& default_instance();
+
+  void Swap(ErrorResponse* other);
+
+  // implements Message ----------------------------------------------
+
+  inline ErrorResponse* New() const { return New(NULL); }
+
+  ErrorResponse* New(::google::protobuf::Arena* arena) const;
+  void CopyFrom(const ::google::protobuf::Message& from);
+  void MergeFrom(const ::google::protobuf::Message& from);
+  void CopyFrom(const ErrorResponse& from);
+  void MergeFrom(const ErrorResponse& from);
+  void Clear();
+  bool IsInitialized() const;
+
+  int ByteSize() const;
+  bool MergePartialFromCodedStream(
+      ::google::protobuf::io::CodedInputStream* input);
+  void SerializeWithCachedSizes(
+      ::google::protobuf::io::CodedOutputStream* output) const;
+  ::google::protobuf::uint8* SerializeWithCachedSizesToArray(::google::protobuf::uint8* output) const;
+  int GetCachedSize() const { return _cached_size_; }
+  private:
+  void SharedCtor();
+  void SharedDtor();
+  void SetCachedSize(int size) const;
+  void InternalSwap(ErrorResponse* other);
+  private:
+  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
+    return _internal_metadata_.arena();
+  }
+  inline void* MaybeArenaPtr() const {
+    return _internal_metadata_.raw_arena_ptr();
+  }
+  public:
+
+  ::google::protobuf::Metadata GetMetadata() const;
+
+  // nested types ----------------------------------------------------
+
+  // accessors -------------------------------------------------------
+
+  // optional int32 error_code = 1;
+  void clear_error_code();
+  static const int kErrorCodeFieldNumber = 1;
+  ::google::protobuf::int32 error_code() const;
+  void set_error_code(::google::protobuf::int32 value);
+
+  // optional string error_message = 2;
+  void clear_error_message();
+  static const int kErrorMessageFieldNumber = 2;
+  const ::std::string& error_message() const;
+  void set_error_message(const ::std::string& value);
+  void set_error_message(const char* value);
+  void set_error_message(const char* value, size_t size);
+  ::std::string* mutable_error_message();
+  ::std::string* release_error_message();
+  void set_allocated_error_message(::std::string* error_message);
+
+  // @@protoc_insertion_point(class_scope:grpc.reflection.v1alpha.ErrorResponse)
+ private:
+
+  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+  bool _is_default_instance_;
+  ::google::protobuf::internal::ArenaStringPtr error_message_;
+  ::google::protobuf::int32 error_code_;
+  mutable int _cached_size_;
+  friend void  protobuf_AddDesc_reflection_2eproto();
+  friend void protobuf_AssignDesc_reflection_2eproto();
+  friend void protobuf_ShutdownFile_reflection_2eproto();
+
+  void InitAsDefaultInstance();
+  static ErrorResponse* default_instance_;
+};
+// ===================================================================
+
+
+// ===================================================================
+
+#if !PROTOBUF_INLINE_NOT_IN_HEADERS
+// ServerReflectionRequest
+
+// optional string host = 1;
+inline void ServerReflectionRequest::clear_host() {
+  host_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline const ::std::string& ServerReflectionRequest::host() const {
+  // @@protoc_insertion_point(field_get:grpc.reflection.v1alpha.ServerReflectionRequest.host)
+  return host_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void ServerReflectionRequest::set_host(const ::std::string& value) {
+  
+  host_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:grpc.reflection.v1alpha.ServerReflectionRequest.host)
+}
+inline void ServerReflectionRequest::set_host(const char* value) {
+  
+  host_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:grpc.reflection.v1alpha.ServerReflectionRequest.host)
+}
+inline void ServerReflectionRequest::set_host(const char* value, size_t size) {
+  
+  host_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:grpc.reflection.v1alpha.ServerReflectionRequest.host)
+}
+inline ::std::string* ServerReflectionRequest::mutable_host() {
+  
+  // @@protoc_insertion_point(field_mutable:grpc.reflection.v1alpha.ServerReflectionRequest.host)
+  return host_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline ::std::string* ServerReflectionRequest::release_host() {
+  // @@protoc_insertion_point(field_release:grpc.reflection.v1alpha.ServerReflectionRequest.host)
+  
+  return host_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void ServerReflectionRequest::set_allocated_host(::std::string* host) {
+  if (host != NULL) {
+    
+  } else {
+    
+  }
+  host_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), host);
+  // @@protoc_insertion_point(field_set_allocated:grpc.reflection.v1alpha.ServerReflectionRequest.host)
+}
+
+// optional string file_by_filename = 3;
+inline bool ServerReflectionRequest::has_file_by_filename() const {
+  return message_request_case() == kFileByFilename;
+}
+inline void ServerReflectionRequest::set_has_file_by_filename() {
+  _oneof_case_[0] = kFileByFilename;
+}
+inline void ServerReflectionRequest::clear_file_by_filename() {
+  if (has_file_by_filename()) {
+    message_request_.file_by_filename_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+    clear_has_message_request();
+  }
+}
+inline const ::std::string& ServerReflectionRequest::file_by_filename() const {
+  // @@protoc_insertion_point(field_get:grpc.reflection.v1alpha.ServerReflectionRequest.file_by_filename)
+  if (has_file_by_filename()) {
+    return message_request_.file_by_filename_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  }
+  return *&::google::protobuf::internal::GetEmptyStringAlreadyInited();
+}
+inline void ServerReflectionRequest::set_file_by_filename(const ::std::string& value) {
+  // @@protoc_insertion_point(field_set:grpc.reflection.v1alpha.ServerReflectionRequest.file_by_filename)
+  if (!has_file_by_filename()) {
+    clear_message_request();
+    set_has_file_by_filename();
+    message_request_.file_by_filename_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  }
+  message_request_.file_by_filename_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:grpc.reflection.v1alpha.ServerReflectionRequest.file_by_filename)
+}
+inline void ServerReflectionRequest::set_file_by_filename(const char* value) {
+  if (!has_file_by_filename()) {
+    clear_message_request();
+    set_has_file_by_filename();
+    message_request_.file_by_filename_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  }
+  message_request_.file_by_filename_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:grpc.reflection.v1alpha.ServerReflectionRequest.file_by_filename)
+}
+inline void ServerReflectionRequest::set_file_by_filename(const char* value, size_t size) {
+  if (!has_file_by_filename()) {
+    clear_message_request();
+    set_has_file_by_filename();
+    message_request_.file_by_filename_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  }
+  message_request_.file_by_filename_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(
+      reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:grpc.reflection.v1alpha.ServerReflectionRequest.file_by_filename)
+}
+inline ::std::string* ServerReflectionRequest::mutable_file_by_filename() {
+  if (!has_file_by_filename()) {
+    clear_message_request();
+    set_has_file_by_filename();
+    message_request_.file_by_filename_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  }
+  // @@protoc_insertion_point(field_mutable:grpc.reflection.v1alpha.ServerReflectionRequest.file_by_filename)
+  return message_request_.file_by_filename_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline ::std::string* ServerReflectionRequest::release_file_by_filename() {
+  // @@protoc_insertion_point(field_release:grpc.reflection.v1alpha.ServerReflectionRequest.file_by_filename)
+  if (has_file_by_filename()) {
+    clear_has_message_request();
+    return message_request_.file_by_filename_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  } else {
+    return NULL;
+  }
+}
+inline void ServerReflectionRequest::set_allocated_file_by_filename(::std::string* file_by_filename) {
+  if (!has_file_by_filename()) {
+    message_request_.file_by_filename_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  }
+  clear_message_request();
+  if (file_by_filename != NULL) {
+    set_has_file_by_filename();
+    message_request_.file_by_filename_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+        file_by_filename);
+  }
+  // @@protoc_insertion_point(field_set_allocated:grpc.reflection.v1alpha.ServerReflectionRequest.file_by_filename)
+}
+
+// optional string file_containing_symbol = 4;
+inline bool ServerReflectionRequest::has_file_containing_symbol() const {
+  return message_request_case() == kFileContainingSymbol;
+}
+inline void ServerReflectionRequest::set_has_file_containing_symbol() {
+  _oneof_case_[0] = kFileContainingSymbol;
+}
+inline void ServerReflectionRequest::clear_file_containing_symbol() {
+  if (has_file_containing_symbol()) {
+    message_request_.file_containing_symbol_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+    clear_has_message_request();
+  }
+}
+inline const ::std::string& ServerReflectionRequest::file_containing_symbol() const {
+  // @@protoc_insertion_point(field_get:grpc.reflection.v1alpha.ServerReflectionRequest.file_containing_symbol)
+  if (has_file_containing_symbol()) {
+    return message_request_.file_containing_symbol_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  }
+  return *&::google::protobuf::internal::GetEmptyStringAlreadyInited();
+}
+inline void ServerReflectionRequest::set_file_containing_symbol(const ::std::string& value) {
+  // @@protoc_insertion_point(field_set:grpc.reflection.v1alpha.ServerReflectionRequest.file_containing_symbol)
+  if (!has_file_containing_symbol()) {
+    clear_message_request();
+    set_has_file_containing_symbol();
+    message_request_.file_containing_symbol_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  }
+  message_request_.file_containing_symbol_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:grpc.reflection.v1alpha.ServerReflectionRequest.file_containing_symbol)
+}
+inline void ServerReflectionRequest::set_file_containing_symbol(const char* value) {
+  if (!has_file_containing_symbol()) {
+    clear_message_request();
+    set_has_file_containing_symbol();
+    message_request_.file_containing_symbol_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  }
+  message_request_.file_containing_symbol_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:grpc.reflection.v1alpha.ServerReflectionRequest.file_containing_symbol)
+}
+inline void ServerReflectionRequest::set_file_containing_symbol(const char* value, size_t size) {
+  if (!has_file_containing_symbol()) {
+    clear_message_request();
+    set_has_file_containing_symbol();
+    message_request_.file_containing_symbol_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  }
+  message_request_.file_containing_symbol_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(
+      reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:grpc.reflection.v1alpha.ServerReflectionRequest.file_containing_symbol)
+}
+inline ::std::string* ServerReflectionRequest::mutable_file_containing_symbol() {
+  if (!has_file_containing_symbol()) {
+    clear_message_request();
+    set_has_file_containing_symbol();
+    message_request_.file_containing_symbol_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  }
+  // @@protoc_insertion_point(field_mutable:grpc.reflection.v1alpha.ServerReflectionRequest.file_containing_symbol)
+  return message_request_.file_containing_symbol_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline ::std::string* ServerReflectionRequest::release_file_containing_symbol() {
+  // @@protoc_insertion_point(field_release:grpc.reflection.v1alpha.ServerReflectionRequest.file_containing_symbol)
+  if (has_file_containing_symbol()) {
+    clear_has_message_request();
+    return message_request_.file_containing_symbol_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  } else {
+    return NULL;
+  }
+}
+inline void ServerReflectionRequest::set_allocated_file_containing_symbol(::std::string* file_containing_symbol) {
+  if (!has_file_containing_symbol()) {
+    message_request_.file_containing_symbol_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  }
+  clear_message_request();
+  if (file_containing_symbol != NULL) {
+    set_has_file_containing_symbol();
+    message_request_.file_containing_symbol_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+        file_containing_symbol);
+  }
+  // @@protoc_insertion_point(field_set_allocated:grpc.reflection.v1alpha.ServerReflectionRequest.file_containing_symbol)
+}
+
+// optional .grpc.reflection.v1alpha.ExtensionRequest file_containing_extension = 5;
+inline bool ServerReflectionRequest::has_file_containing_extension() const {
+  return message_request_case() == kFileContainingExtension;
+}
+inline void ServerReflectionRequest::set_has_file_containing_extension() {
+  _oneof_case_[0] = kFileContainingExtension;
+}
+inline void ServerReflectionRequest::clear_file_containing_extension() {
+  if (has_file_containing_extension()) {
+    delete message_request_.file_containing_extension_;
+    clear_has_message_request();
+  }
+}
+inline  const ::grpc::reflection::v1alpha::ExtensionRequest& ServerReflectionRequest::file_containing_extension() const {
+  // @@protoc_insertion_point(field_get:grpc.reflection.v1alpha.ServerReflectionRequest.file_containing_extension)
+  return has_file_containing_extension()
+      ? *message_request_.file_containing_extension_
+      : ::grpc::reflection::v1alpha::ExtensionRequest::default_instance();
+}
+inline ::grpc::reflection::v1alpha::ExtensionRequest* ServerReflectionRequest::mutable_file_containing_extension() {
+  if (!has_file_containing_extension()) {
+    clear_message_request();
+    set_has_file_containing_extension();
+    message_request_.file_containing_extension_ = new ::grpc::reflection::v1alpha::ExtensionRequest;
+  }
+  // @@protoc_insertion_point(field_mutable:grpc.reflection.v1alpha.ServerReflectionRequest.file_containing_extension)
+  return message_request_.file_containing_extension_;
+}
+inline ::grpc::reflection::v1alpha::ExtensionRequest* ServerReflectionRequest::release_file_containing_extension() {
+  // @@protoc_insertion_point(field_release:grpc.reflection.v1alpha.ServerReflectionRequest.file_containing_extension)
+  if (has_file_containing_extension()) {
+    clear_has_message_request();
+    ::grpc::reflection::v1alpha::ExtensionRequest* temp = message_request_.file_containing_extension_;
+    message_request_.file_containing_extension_ = NULL;
+    return temp;
+  } else {
+    return NULL;
+  }
+}
+inline void ServerReflectionRequest::set_allocated_file_containing_extension(::grpc::reflection::v1alpha::ExtensionRequest* file_containing_extension) {
+  clear_message_request();
+  if (file_containing_extension) {
+    set_has_file_containing_extension();
+    message_request_.file_containing_extension_ = file_containing_extension;
+  }
+  // @@protoc_insertion_point(field_set_allocated:grpc.reflection.v1alpha.ServerReflectionRequest.file_containing_extension)
+}
+
+// optional string all_extension_numbers_of_type = 6;
+inline bool ServerReflectionRequest::has_all_extension_numbers_of_type() const {
+  return message_request_case() == kAllExtensionNumbersOfType;
+}
+inline void ServerReflectionRequest::set_has_all_extension_numbers_of_type() {
+  _oneof_case_[0] = kAllExtensionNumbersOfType;
+}
+inline void ServerReflectionRequest::clear_all_extension_numbers_of_type() {
+  if (has_all_extension_numbers_of_type()) {
+    message_request_.all_extension_numbers_of_type_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+    clear_has_message_request();
+  }
+}
+inline const ::std::string& ServerReflectionRequest::all_extension_numbers_of_type() const {
+  // @@protoc_insertion_point(field_get:grpc.reflection.v1alpha.ServerReflectionRequest.all_extension_numbers_of_type)
+  if (has_all_extension_numbers_of_type()) {
+    return message_request_.all_extension_numbers_of_type_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  }
+  return *&::google::protobuf::internal::GetEmptyStringAlreadyInited();
+}
+inline void ServerReflectionRequest::set_all_extension_numbers_of_type(const ::std::string& value) {
+  // @@protoc_insertion_point(field_set:grpc.reflection.v1alpha.ServerReflectionRequest.all_extension_numbers_of_type)
+  if (!has_all_extension_numbers_of_type()) {
+    clear_message_request();
+    set_has_all_extension_numbers_of_type();
+    message_request_.all_extension_numbers_of_type_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  }
+  message_request_.all_extension_numbers_of_type_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:grpc.reflection.v1alpha.ServerReflectionRequest.all_extension_numbers_of_type)
+}
+inline void ServerReflectionRequest::set_all_extension_numbers_of_type(const char* value) {
+  if (!has_all_extension_numbers_of_type()) {
+    clear_message_request();
+    set_has_all_extension_numbers_of_type();
+    message_request_.all_extension_numbers_of_type_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  }
+  message_request_.all_extension_numbers_of_type_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:grpc.reflection.v1alpha.ServerReflectionRequest.all_extension_numbers_of_type)
+}
+inline void ServerReflectionRequest::set_all_extension_numbers_of_type(const char* value, size_t size) {
+  if (!has_all_extension_numbers_of_type()) {
+    clear_message_request();
+    set_has_all_extension_numbers_of_type();
+    message_request_.all_extension_numbers_of_type_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  }
+  message_request_.all_extension_numbers_of_type_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(
+      reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:grpc.reflection.v1alpha.ServerReflectionRequest.all_extension_numbers_of_type)
+}
+inline ::std::string* ServerReflectionRequest::mutable_all_extension_numbers_of_type() {
+  if (!has_all_extension_numbers_of_type()) {
+    clear_message_request();
+    set_has_all_extension_numbers_of_type();
+    message_request_.all_extension_numbers_of_type_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  }
+  // @@protoc_insertion_point(field_mutable:grpc.reflection.v1alpha.ServerReflectionRequest.all_extension_numbers_of_type)
+  return message_request_.all_extension_numbers_of_type_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline ::std::string* ServerReflectionRequest::release_all_extension_numbers_of_type() {
+  // @@protoc_insertion_point(field_release:grpc.reflection.v1alpha.ServerReflectionRequest.all_extension_numbers_of_type)
+  if (has_all_extension_numbers_of_type()) {
+    clear_has_message_request();
+    return message_request_.all_extension_numbers_of_type_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  } else {
+    return NULL;
+  }
+}
+inline void ServerReflectionRequest::set_allocated_all_extension_numbers_of_type(::std::string* all_extension_numbers_of_type) {
+  if (!has_all_extension_numbers_of_type()) {
+    message_request_.all_extension_numbers_of_type_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  }
+  clear_message_request();
+  if (all_extension_numbers_of_type != NULL) {
+    set_has_all_extension_numbers_of_type();
+    message_request_.all_extension_numbers_of_type_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+        all_extension_numbers_of_type);
+  }
+  // @@protoc_insertion_point(field_set_allocated:grpc.reflection.v1alpha.ServerReflectionRequest.all_extension_numbers_of_type)
+}
+
+// optional string list_services = 7;
+inline bool ServerReflectionRequest::has_list_services() const {
+  return message_request_case() == kListServices;
+}
+inline void ServerReflectionRequest::set_has_list_services() {
+  _oneof_case_[0] = kListServices;
+}
+inline void ServerReflectionRequest::clear_list_services() {
+  if (has_list_services()) {
+    message_request_.list_services_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+    clear_has_message_request();
+  }
+}
+inline const ::std::string& ServerReflectionRequest::list_services() const {
+  // @@protoc_insertion_point(field_get:grpc.reflection.v1alpha.ServerReflectionRequest.list_services)
+  if (has_list_services()) {
+    return message_request_.list_services_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  }
+  return *&::google::protobuf::internal::GetEmptyStringAlreadyInited();
+}
+inline void ServerReflectionRequest::set_list_services(const ::std::string& value) {
+  // @@protoc_insertion_point(field_set:grpc.reflection.v1alpha.ServerReflectionRequest.list_services)
+  if (!has_list_services()) {
+    clear_message_request();
+    set_has_list_services();
+    message_request_.list_services_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  }
+  message_request_.list_services_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:grpc.reflection.v1alpha.ServerReflectionRequest.list_services)
+}
+inline void ServerReflectionRequest::set_list_services(const char* value) {
+  if (!has_list_services()) {
+    clear_message_request();
+    set_has_list_services();
+    message_request_.list_services_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  }
+  message_request_.list_services_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:grpc.reflection.v1alpha.ServerReflectionRequest.list_services)
+}
+inline void ServerReflectionRequest::set_list_services(const char* value, size_t size) {
+  if (!has_list_services()) {
+    clear_message_request();
+    set_has_list_services();
+    message_request_.list_services_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  }
+  message_request_.list_services_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(
+      reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:grpc.reflection.v1alpha.ServerReflectionRequest.list_services)
+}
+inline ::std::string* ServerReflectionRequest::mutable_list_services() {
+  if (!has_list_services()) {
+    clear_message_request();
+    set_has_list_services();
+    message_request_.list_services_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  }
+  // @@protoc_insertion_point(field_mutable:grpc.reflection.v1alpha.ServerReflectionRequest.list_services)
+  return message_request_.list_services_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline ::std::string* ServerReflectionRequest::release_list_services() {
+  // @@protoc_insertion_point(field_release:grpc.reflection.v1alpha.ServerReflectionRequest.list_services)
+  if (has_list_services()) {
+    clear_has_message_request();
+    return message_request_.list_services_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  } else {
+    return NULL;
+  }
+}
+inline void ServerReflectionRequest::set_allocated_list_services(::std::string* list_services) {
+  if (!has_list_services()) {
+    message_request_.list_services_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  }
+  clear_message_request();
+  if (list_services != NULL) {
+    set_has_list_services();
+    message_request_.list_services_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+        list_services);
+  }
+  // @@protoc_insertion_point(field_set_allocated:grpc.reflection.v1alpha.ServerReflectionRequest.list_services)
+}
+
+inline bool ServerReflectionRequest::has_message_request() const {
+  return message_request_case() != MESSAGE_REQUEST_NOT_SET;
+}
+inline void ServerReflectionRequest::clear_has_message_request() {
+  _oneof_case_[0] = MESSAGE_REQUEST_NOT_SET;
+}
+inline ServerReflectionRequest::MessageRequestCase ServerReflectionRequest::message_request_case() const {
+  return ServerReflectionRequest::MessageRequestCase(_oneof_case_[0]);
+}
+// -------------------------------------------------------------------
+
+// ExtensionRequest
+
+// optional string containing_type = 1;
+inline void ExtensionRequest::clear_containing_type() {
+  containing_type_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline const ::std::string& ExtensionRequest::containing_type() const {
+  // @@protoc_insertion_point(field_get:grpc.reflection.v1alpha.ExtensionRequest.containing_type)
+  return containing_type_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void ExtensionRequest::set_containing_type(const ::std::string& value) {
+  
+  containing_type_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:grpc.reflection.v1alpha.ExtensionRequest.containing_type)
+}
+inline void ExtensionRequest::set_containing_type(const char* value) {
+  
+  containing_type_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:grpc.reflection.v1alpha.ExtensionRequest.containing_type)
+}
+inline void ExtensionRequest::set_containing_type(const char* value, size_t size) {
+  
+  containing_type_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:grpc.reflection.v1alpha.ExtensionRequest.containing_type)
+}
+inline ::std::string* ExtensionRequest::mutable_containing_type() {
+  
+  // @@protoc_insertion_point(field_mutable:grpc.reflection.v1alpha.ExtensionRequest.containing_type)
+  return containing_type_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline ::std::string* ExtensionRequest::release_containing_type() {
+  // @@protoc_insertion_point(field_release:grpc.reflection.v1alpha.ExtensionRequest.containing_type)
+  
+  return containing_type_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void ExtensionRequest::set_allocated_containing_type(::std::string* containing_type) {
+  if (containing_type != NULL) {
+    
+  } else {
+    
+  }
+  containing_type_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), containing_type);
+  // @@protoc_insertion_point(field_set_allocated:grpc.reflection.v1alpha.ExtensionRequest.containing_type)
+}
+
+// optional int32 extension_number = 2;
+inline void ExtensionRequest::clear_extension_number() {
+  extension_number_ = 0;
+}
+inline ::google::protobuf::int32 ExtensionRequest::extension_number() const {
+  // @@protoc_insertion_point(field_get:grpc.reflection.v1alpha.ExtensionRequest.extension_number)
+  return extension_number_;
+}
+inline void ExtensionRequest::set_extension_number(::google::protobuf::int32 value) {
+  
+  extension_number_ = value;
+  // @@protoc_insertion_point(field_set:grpc.reflection.v1alpha.ExtensionRequest.extension_number)
+}
+
+// -------------------------------------------------------------------
+
+// ServerReflectionResponse
+
+// optional string valid_host = 1;
+inline void ServerReflectionResponse::clear_valid_host() {
+  valid_host_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline const ::std::string& ServerReflectionResponse::valid_host() const {
+  // @@protoc_insertion_point(field_get:grpc.reflection.v1alpha.ServerReflectionResponse.valid_host)
+  return valid_host_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void ServerReflectionResponse::set_valid_host(const ::std::string& value) {
+  
+  valid_host_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:grpc.reflection.v1alpha.ServerReflectionResponse.valid_host)
+}
+inline void ServerReflectionResponse::set_valid_host(const char* value) {
+  
+  valid_host_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:grpc.reflection.v1alpha.ServerReflectionResponse.valid_host)
+}
+inline void ServerReflectionResponse::set_valid_host(const char* value, size_t size) {
+  
+  valid_host_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:grpc.reflection.v1alpha.ServerReflectionResponse.valid_host)
+}
+inline ::std::string* ServerReflectionResponse::mutable_valid_host() {
+  
+  // @@protoc_insertion_point(field_mutable:grpc.reflection.v1alpha.ServerReflectionResponse.valid_host)
+  return valid_host_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline ::std::string* ServerReflectionResponse::release_valid_host() {
+  // @@protoc_insertion_point(field_release:grpc.reflection.v1alpha.ServerReflectionResponse.valid_host)
+  
+  return valid_host_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void ServerReflectionResponse::set_allocated_valid_host(::std::string* valid_host) {
+  if (valid_host != NULL) {
+    
+  } else {
+    
+  }
+  valid_host_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), valid_host);
+  // @@protoc_insertion_point(field_set_allocated:grpc.reflection.v1alpha.ServerReflectionResponse.valid_host)
+}
+
+// optional .grpc.reflection.v1alpha.ServerReflectionRequest original_request = 2;
+inline bool ServerReflectionResponse::has_original_request() const {
+  return !_is_default_instance_ && original_request_ != NULL;
+}
+inline void ServerReflectionResponse::clear_original_request() {
+  if (GetArenaNoVirtual() == NULL && original_request_ != NULL) delete original_request_;
+  original_request_ = NULL;
+}
+inline const ::grpc::reflection::v1alpha::ServerReflectionRequest& ServerReflectionResponse::original_request() const {
+  // @@protoc_insertion_point(field_get:grpc.reflection.v1alpha.ServerReflectionResponse.original_request)
+  return original_request_ != NULL ? *original_request_ : *default_instance_->original_request_;
+}
+inline ::grpc::reflection::v1alpha::ServerReflectionRequest* ServerReflectionResponse::mutable_original_request() {
+  
+  if (original_request_ == NULL) {
+    original_request_ = new ::grpc::reflection::v1alpha::ServerReflectionRequest;
+  }
+  // @@protoc_insertion_point(field_mutable:grpc.reflection.v1alpha.ServerReflectionResponse.original_request)
+  return original_request_;
+}
+inline ::grpc::reflection::v1alpha::ServerReflectionRequest* ServerReflectionResponse::release_original_request() {
+  // @@protoc_insertion_point(field_release:grpc.reflection.v1alpha.ServerReflectionResponse.original_request)
+  
+  ::grpc::reflection::v1alpha::ServerReflectionRequest* temp = original_request_;
+  original_request_ = NULL;
+  return temp;
+}
+inline void ServerReflectionResponse::set_allocated_original_request(::grpc::reflection::v1alpha::ServerReflectionRequest* original_request) {
+  delete original_request_;
+  original_request_ = original_request;
+  if (original_request) {
+    
+  } else {
+    
+  }
+  // @@protoc_insertion_point(field_set_allocated:grpc.reflection.v1alpha.ServerReflectionResponse.original_request)
+}
+
+// optional .grpc.reflection.v1alpha.FileDescriptorResponse file_descriptor_response = 4;
+inline bool ServerReflectionResponse::has_file_descriptor_response() const {
+  return message_response_case() == kFileDescriptorResponse;
+}
+inline void ServerReflectionResponse::set_has_file_descriptor_response() {
+  _oneof_case_[0] = kFileDescriptorResponse;
+}
+inline void ServerReflectionResponse::clear_file_descriptor_response() {
+  if (has_file_descriptor_response()) {
+    delete message_response_.file_descriptor_response_;
+    clear_has_message_response();
+  }
+}
+inline  const ::grpc::reflection::v1alpha::FileDescriptorResponse& ServerReflectionResponse::file_descriptor_response() const {
+  // @@protoc_insertion_point(field_get:grpc.reflection.v1alpha.ServerReflectionResponse.file_descriptor_response)
+  return has_file_descriptor_response()
+      ? *message_response_.file_descriptor_response_
+      : ::grpc::reflection::v1alpha::FileDescriptorResponse::default_instance();
+}
+inline ::grpc::reflection::v1alpha::FileDescriptorResponse* ServerReflectionResponse::mutable_file_descriptor_response() {
+  if (!has_file_descriptor_response()) {
+    clear_message_response();
+    set_has_file_descriptor_response();
+    message_response_.file_descriptor_response_ = new ::grpc::reflection::v1alpha::FileDescriptorResponse;
+  }
+  // @@protoc_insertion_point(field_mutable:grpc.reflection.v1alpha.ServerReflectionResponse.file_descriptor_response)
+  return message_response_.file_descriptor_response_;
+}
+inline ::grpc::reflection::v1alpha::FileDescriptorResponse* ServerReflectionResponse::release_file_descriptor_response() {
+  // @@protoc_insertion_point(field_release:grpc.reflection.v1alpha.ServerReflectionResponse.file_descriptor_response)
+  if (has_file_descriptor_response()) {
+    clear_has_message_response();
+    ::grpc::reflection::v1alpha::FileDescriptorResponse* temp = message_response_.file_descriptor_response_;
+    message_response_.file_descriptor_response_ = NULL;
+    return temp;
+  } else {
+    return NULL;
+  }
+}
+inline void ServerReflectionResponse::set_allocated_file_descriptor_response(::grpc::reflection::v1alpha::FileDescriptorResponse* file_descriptor_response) {
+  clear_message_response();
+  if (file_descriptor_response) {
+    set_has_file_descriptor_response();
+    message_response_.file_descriptor_response_ = file_descriptor_response;
+  }
+  // @@protoc_insertion_point(field_set_allocated:grpc.reflection.v1alpha.ServerReflectionResponse.file_descriptor_response)
+}
+
+// optional .grpc.reflection.v1alpha.ExtensionNumberResponse all_extension_numbers_response = 5;
+inline bool ServerReflectionResponse::has_all_extension_numbers_response() const {
+  return message_response_case() == kAllExtensionNumbersResponse;
+}
+inline void ServerReflectionResponse::set_has_all_extension_numbers_response() {
+  _oneof_case_[0] = kAllExtensionNumbersResponse;
+}
+inline void ServerReflectionResponse::clear_all_extension_numbers_response() {
+  if (has_all_extension_numbers_response()) {
+    delete message_response_.all_extension_numbers_response_;
+    clear_has_message_response();
+  }
+}
+inline  const ::grpc::reflection::v1alpha::ExtensionNumberResponse& ServerReflectionResponse::all_extension_numbers_response() const {
+  // @@protoc_insertion_point(field_get:grpc.reflection.v1alpha.ServerReflectionResponse.all_extension_numbers_response)
+  return has_all_extension_numbers_response()
+      ? *message_response_.all_extension_numbers_response_
+      : ::grpc::reflection::v1alpha::ExtensionNumberResponse::default_instance();
+}
+inline ::grpc::reflection::v1alpha::ExtensionNumberResponse* ServerReflectionResponse::mutable_all_extension_numbers_response() {
+  if (!has_all_extension_numbers_response()) {
+    clear_message_response();
+    set_has_all_extension_numbers_response();
+    message_response_.all_extension_numbers_response_ = new ::grpc::reflection::v1alpha::ExtensionNumberResponse;
+  }
+  // @@protoc_insertion_point(field_mutable:grpc.reflection.v1alpha.ServerReflectionResponse.all_extension_numbers_response)
+  return message_response_.all_extension_numbers_response_;
+}
+inline ::grpc::reflection::v1alpha::ExtensionNumberResponse* ServerReflectionResponse::release_all_extension_numbers_response() {
+  // @@protoc_insertion_point(field_release:grpc.reflection.v1alpha.ServerReflectionResponse.all_extension_numbers_response)
+  if (has_all_extension_numbers_response()) {
+    clear_has_message_response();
+    ::grpc::reflection::v1alpha::ExtensionNumberResponse* temp = message_response_.all_extension_numbers_response_;
+    message_response_.all_extension_numbers_response_ = NULL;
+    return temp;
+  } else {
+    return NULL;
+  }
+}
+inline void ServerReflectionResponse::set_allocated_all_extension_numbers_response(::grpc::reflection::v1alpha::ExtensionNumberResponse* all_extension_numbers_response) {
+  clear_message_response();
+  if (all_extension_numbers_response) {
+    set_has_all_extension_numbers_response();
+    message_response_.all_extension_numbers_response_ = all_extension_numbers_response;
+  }
+  // @@protoc_insertion_point(field_set_allocated:grpc.reflection.v1alpha.ServerReflectionResponse.all_extension_numbers_response)
+}
+
+// optional .grpc.reflection.v1alpha.ListServiceResponse list_services_response = 6;
+inline bool ServerReflectionResponse::has_list_services_response() const {
+  return message_response_case() == kListServicesResponse;
+}
+inline void ServerReflectionResponse::set_has_list_services_response() {
+  _oneof_case_[0] = kListServicesResponse;
+}
+inline void ServerReflectionResponse::clear_list_services_response() {
+  if (has_list_services_response()) {
+    delete message_response_.list_services_response_;
+    clear_has_message_response();
+  }
+}
+inline  const ::grpc::reflection::v1alpha::ListServiceResponse& ServerReflectionResponse::list_services_response() const {
+  // @@protoc_insertion_point(field_get:grpc.reflection.v1alpha.ServerReflectionResponse.list_services_response)
+  return has_list_services_response()
+      ? *message_response_.list_services_response_
+      : ::grpc::reflection::v1alpha::ListServiceResponse::default_instance();
+}
+inline ::grpc::reflection::v1alpha::ListServiceResponse* ServerReflectionResponse::mutable_list_services_response() {
+  if (!has_list_services_response()) {
+    clear_message_response();
+    set_has_list_services_response();
+    message_response_.list_services_response_ = new ::grpc::reflection::v1alpha::ListServiceResponse;
+  }
+  // @@protoc_insertion_point(field_mutable:grpc.reflection.v1alpha.ServerReflectionResponse.list_services_response)
+  return message_response_.list_services_response_;
+}
+inline ::grpc::reflection::v1alpha::ListServiceResponse* ServerReflectionResponse::release_list_services_response() {
+  // @@protoc_insertion_point(field_release:grpc.reflection.v1alpha.ServerReflectionResponse.list_services_response)
+  if (has_list_services_response()) {
+    clear_has_message_response();
+    ::grpc::reflection::v1alpha::ListServiceResponse* temp = message_response_.list_services_response_;
+    message_response_.list_services_response_ = NULL;
+    return temp;
+  } else {
+    return NULL;
+  }
+}
+inline void ServerReflectionResponse::set_allocated_list_services_response(::grpc::reflection::v1alpha::ListServiceResponse* list_services_response) {
+  clear_message_response();
+  if (list_services_response) {
+    set_has_list_services_response();
+    message_response_.list_services_response_ = list_services_response;
+  }
+  // @@protoc_insertion_point(field_set_allocated:grpc.reflection.v1alpha.ServerReflectionResponse.list_services_response)
+}
+
+// optional .grpc.reflection.v1alpha.ErrorResponse error_response = 7;
+inline bool ServerReflectionResponse::has_error_response() const {
+  return message_response_case() == kErrorResponse;
+}
+inline void ServerReflectionResponse::set_has_error_response() {
+  _oneof_case_[0] = kErrorResponse;
+}
+inline void ServerReflectionResponse::clear_error_response() {
+  if (has_error_response()) {
+    delete message_response_.error_response_;
+    clear_has_message_response();
+  }
+}
+inline  const ::grpc::reflection::v1alpha::ErrorResponse& ServerReflectionResponse::error_response() const {
+  // @@protoc_insertion_point(field_get:grpc.reflection.v1alpha.ServerReflectionResponse.error_response)
+  return has_error_response()
+      ? *message_response_.error_response_
+      : ::grpc::reflection::v1alpha::ErrorResponse::default_instance();
+}
+inline ::grpc::reflection::v1alpha::ErrorResponse* ServerReflectionResponse::mutable_error_response() {
+  if (!has_error_response()) {
+    clear_message_response();
+    set_has_error_response();
+    message_response_.error_response_ = new ::grpc::reflection::v1alpha::ErrorResponse;
+  }
+  // @@protoc_insertion_point(field_mutable:grpc.reflection.v1alpha.ServerReflectionResponse.error_response)
+  return message_response_.error_response_;
+}
+inline ::grpc::reflection::v1alpha::ErrorResponse* ServerReflectionResponse::release_error_response() {
+  // @@protoc_insertion_point(field_release:grpc.reflection.v1alpha.ServerReflectionResponse.error_response)
+  if (has_error_response()) {
+    clear_has_message_response();
+    ::grpc::reflection::v1alpha::ErrorResponse* temp = message_response_.error_response_;
+    message_response_.error_response_ = NULL;
+    return temp;
+  } else {
+    return NULL;
+  }
+}
+inline void ServerReflectionResponse::set_allocated_error_response(::grpc::reflection::v1alpha::ErrorResponse* error_response) {
+  clear_message_response();
+  if (error_response) {
+    set_has_error_response();
+    message_response_.error_response_ = error_response;
+  }
+  // @@protoc_insertion_point(field_set_allocated:grpc.reflection.v1alpha.ServerReflectionResponse.error_response)
+}
+
+inline bool ServerReflectionResponse::has_message_response() const {
+  return message_response_case() != MESSAGE_RESPONSE_NOT_SET;
+}
+inline void ServerReflectionResponse::clear_has_message_response() {
+  _oneof_case_[0] = MESSAGE_RESPONSE_NOT_SET;
+}
+inline ServerReflectionResponse::MessageResponseCase ServerReflectionResponse::message_response_case() const {
+  return ServerReflectionResponse::MessageResponseCase(_oneof_case_[0]);
+}
+// -------------------------------------------------------------------
+
+// FileDescriptorResponse
+
+// repeated bytes file_descriptor_proto = 1;
+inline int FileDescriptorResponse::file_descriptor_proto_size() const {
+  return file_descriptor_proto_.size();
+}
+inline void FileDescriptorResponse::clear_file_descriptor_proto() {
+  file_descriptor_proto_.Clear();
+}
+inline const ::std::string& FileDescriptorResponse::file_descriptor_proto(int index) const {
+  // @@protoc_insertion_point(field_get:grpc.reflection.v1alpha.FileDescriptorResponse.file_descriptor_proto)
+  return file_descriptor_proto_.Get(index);
+}
+inline ::std::string* FileDescriptorResponse::mutable_file_descriptor_proto(int index) {
+  // @@protoc_insertion_point(field_mutable:grpc.reflection.v1alpha.FileDescriptorResponse.file_descriptor_proto)
+  return file_descriptor_proto_.Mutable(index);
+}
+inline void FileDescriptorResponse::set_file_descriptor_proto(int index, const ::std::string& value) {
+  // @@protoc_insertion_point(field_set:grpc.reflection.v1alpha.FileDescriptorResponse.file_descriptor_proto)
+  file_descriptor_proto_.Mutable(index)->assign(value);
+}
+inline void FileDescriptorResponse::set_file_descriptor_proto(int index, const char* value) {
+  file_descriptor_proto_.Mutable(index)->assign(value);
+  // @@protoc_insertion_point(field_set_char:grpc.reflection.v1alpha.FileDescriptorResponse.file_descriptor_proto)
+}
+inline void FileDescriptorResponse::set_file_descriptor_proto(int index, const void* value, size_t size) {
+  file_descriptor_proto_.Mutable(index)->assign(
+    reinterpret_cast<const char*>(value), size);
+  // @@protoc_insertion_point(field_set_pointer:grpc.reflection.v1alpha.FileDescriptorResponse.file_descriptor_proto)
+}
+inline ::std::string* FileDescriptorResponse::add_file_descriptor_proto() {
+  // @@protoc_insertion_point(field_add_mutable:grpc.reflection.v1alpha.FileDescriptorResponse.file_descriptor_proto)
+  return file_descriptor_proto_.Add();
+}
+inline void FileDescriptorResponse::add_file_descriptor_proto(const ::std::string& value) {
+  file_descriptor_proto_.Add()->assign(value);
+  // @@protoc_insertion_point(field_add:grpc.reflection.v1alpha.FileDescriptorResponse.file_descriptor_proto)
+}
+inline void FileDescriptorResponse::add_file_descriptor_proto(const char* value) {
+  file_descriptor_proto_.Add()->assign(value);
+  // @@protoc_insertion_point(field_add_char:grpc.reflection.v1alpha.FileDescriptorResponse.file_descriptor_proto)
+}
+inline void FileDescriptorResponse::add_file_descriptor_proto(const void* value, size_t size) {
+  file_descriptor_proto_.Add()->assign(reinterpret_cast<const char*>(value), size);
+  // @@protoc_insertion_point(field_add_pointer:grpc.reflection.v1alpha.FileDescriptorResponse.file_descriptor_proto)
+}
+inline const ::google::protobuf::RepeatedPtrField< ::std::string>&
+FileDescriptorResponse::file_descriptor_proto() const {
+  // @@protoc_insertion_point(field_list:grpc.reflection.v1alpha.FileDescriptorResponse.file_descriptor_proto)
+  return file_descriptor_proto_;
+}
+inline ::google::protobuf::RepeatedPtrField< ::std::string>*
+FileDescriptorResponse::mutable_file_descriptor_proto() {
+  // @@protoc_insertion_point(field_mutable_list:grpc.reflection.v1alpha.FileDescriptorResponse.file_descriptor_proto)
+  return &file_descriptor_proto_;
+}
+
+// -------------------------------------------------------------------
+
+// ExtensionNumberResponse
+
+// optional string base_type_name = 1;
+inline void ExtensionNumberResponse::clear_base_type_name() {
+  base_type_name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline const ::std::string& ExtensionNumberResponse::base_type_name() const {
+  // @@protoc_insertion_point(field_get:grpc.reflection.v1alpha.ExtensionNumberResponse.base_type_name)
+  return base_type_name_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void ExtensionNumberResponse::set_base_type_name(const ::std::string& value) {
+  
+  base_type_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:grpc.reflection.v1alpha.ExtensionNumberResponse.base_type_name)
+}
+inline void ExtensionNumberResponse::set_base_type_name(const char* value) {
+  
+  base_type_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:grpc.reflection.v1alpha.ExtensionNumberResponse.base_type_name)
+}
+inline void ExtensionNumberResponse::set_base_type_name(const char* value, size_t size) {
+  
+  base_type_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:grpc.reflection.v1alpha.ExtensionNumberResponse.base_type_name)
+}
+inline ::std::string* ExtensionNumberResponse::mutable_base_type_name() {
+  
+  // @@protoc_insertion_point(field_mutable:grpc.reflection.v1alpha.ExtensionNumberResponse.base_type_name)
+  return base_type_name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline ::std::string* ExtensionNumberResponse::release_base_type_name() {
+  // @@protoc_insertion_point(field_release:grpc.reflection.v1alpha.ExtensionNumberResponse.base_type_name)
+  
+  return base_type_name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void ExtensionNumberResponse::set_allocated_base_type_name(::std::string* base_type_name) {
+  if (base_type_name != NULL) {
+    
+  } else {
+    
+  }
+  base_type_name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), base_type_name);
+  // @@protoc_insertion_point(field_set_allocated:grpc.reflection.v1alpha.ExtensionNumberResponse.base_type_name)
+}
+
+// repeated int32 extension_number = 2;
+inline int ExtensionNumberResponse::extension_number_size() const {
+  return extension_number_.size();
+}
+inline void ExtensionNumberResponse::clear_extension_number() {
+  extension_number_.Clear();
+}
+inline ::google::protobuf::int32 ExtensionNumberResponse::extension_number(int index) const {
+  // @@protoc_insertion_point(field_get:grpc.reflection.v1alpha.ExtensionNumberResponse.extension_number)
+  return extension_number_.Get(index);
+}
+inline void ExtensionNumberResponse::set_extension_number(int index, ::google::protobuf::int32 value) {
+  extension_number_.Set(index, value);
+  // @@protoc_insertion_point(field_set:grpc.reflection.v1alpha.ExtensionNumberResponse.extension_number)
+}
+inline void ExtensionNumberResponse::add_extension_number(::google::protobuf::int32 value) {
+  extension_number_.Add(value);
+  // @@protoc_insertion_point(field_add:grpc.reflection.v1alpha.ExtensionNumberResponse.extension_number)
+}
+inline const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >&
+ExtensionNumberResponse::extension_number() const {
+  // @@protoc_insertion_point(field_list:grpc.reflection.v1alpha.ExtensionNumberResponse.extension_number)
+  return extension_number_;
+}
+inline ::google::protobuf::RepeatedField< ::google::protobuf::int32 >*
+ExtensionNumberResponse::mutable_extension_number() {
+  // @@protoc_insertion_point(field_mutable_list:grpc.reflection.v1alpha.ExtensionNumberResponse.extension_number)
+  return &extension_number_;
+}
+
+// -------------------------------------------------------------------
+
+// ListServiceResponse
+
+// repeated .grpc.reflection.v1alpha.ServiceResponse service = 1;
+inline int ListServiceResponse::service_size() const {
+  return service_.size();
+}
+inline void ListServiceResponse::clear_service() {
+  service_.Clear();
+}
+inline const ::grpc::reflection::v1alpha::ServiceResponse& ListServiceResponse::service(int index) const {
+  // @@protoc_insertion_point(field_get:grpc.reflection.v1alpha.ListServiceResponse.service)
+  return service_.Get(index);
+}
+inline ::grpc::reflection::v1alpha::ServiceResponse* ListServiceResponse::mutable_service(int index) {
+  // @@protoc_insertion_point(field_mutable:grpc.reflection.v1alpha.ListServiceResponse.service)
+  return service_.Mutable(index);
+}
+inline ::grpc::reflection::v1alpha::ServiceResponse* ListServiceResponse::add_service() {
+  // @@protoc_insertion_point(field_add:grpc.reflection.v1alpha.ListServiceResponse.service)
+  return service_.Add();
+}
+inline ::google::protobuf::RepeatedPtrField< ::grpc::reflection::v1alpha::ServiceResponse >*
+ListServiceResponse::mutable_service() {
+  // @@protoc_insertion_point(field_mutable_list:grpc.reflection.v1alpha.ListServiceResponse.service)
+  return &service_;
+}
+inline const ::google::protobuf::RepeatedPtrField< ::grpc::reflection::v1alpha::ServiceResponse >&
+ListServiceResponse::service() const {
+  // @@protoc_insertion_point(field_list:grpc.reflection.v1alpha.ListServiceResponse.service)
+  return service_;
+}
+
+// -------------------------------------------------------------------
+
+// ServiceResponse
+
+// optional string name = 1;
+inline void ServiceResponse::clear_name() {
+  name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline const ::std::string& ServiceResponse::name() const {
+  // @@protoc_insertion_point(field_get:grpc.reflection.v1alpha.ServiceResponse.name)
+  return name_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void ServiceResponse::set_name(const ::std::string& value) {
+  
+  name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:grpc.reflection.v1alpha.ServiceResponse.name)
+}
+inline void ServiceResponse::set_name(const char* value) {
+  
+  name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:grpc.reflection.v1alpha.ServiceResponse.name)
+}
+inline void ServiceResponse::set_name(const char* value, size_t size) {
+  
+  name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:grpc.reflection.v1alpha.ServiceResponse.name)
+}
+inline ::std::string* ServiceResponse::mutable_name() {
+  
+  // @@protoc_insertion_point(field_mutable:grpc.reflection.v1alpha.ServiceResponse.name)
+  return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline ::std::string* ServiceResponse::release_name() {
+  // @@protoc_insertion_point(field_release:grpc.reflection.v1alpha.ServiceResponse.name)
+  
+  return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void ServiceResponse::set_allocated_name(::std::string* name) {
+  if (name != NULL) {
+    
+  } else {
+    
+  }
+  name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name);
+  // @@protoc_insertion_point(field_set_allocated:grpc.reflection.v1alpha.ServiceResponse.name)
+}
+
+// -------------------------------------------------------------------
+
+// ErrorResponse
+
+// optional int32 error_code = 1;
+inline void ErrorResponse::clear_error_code() {
+  error_code_ = 0;
+}
+inline ::google::protobuf::int32 ErrorResponse::error_code() const {
+  // @@protoc_insertion_point(field_get:grpc.reflection.v1alpha.ErrorResponse.error_code)
+  return error_code_;
+}
+inline void ErrorResponse::set_error_code(::google::protobuf::int32 value) {
+  
+  error_code_ = value;
+  // @@protoc_insertion_point(field_set:grpc.reflection.v1alpha.ErrorResponse.error_code)
+}
+
+// optional string error_message = 2;
+inline void ErrorResponse::clear_error_message() {
+  error_message_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline const ::std::string& ErrorResponse::error_message() const {
+  // @@protoc_insertion_point(field_get:grpc.reflection.v1alpha.ErrorResponse.error_message)
+  return error_message_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void ErrorResponse::set_error_message(const ::std::string& value) {
+  
+  error_message_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:grpc.reflection.v1alpha.ErrorResponse.error_message)
+}
+inline void ErrorResponse::set_error_message(const char* value) {
+  
+  error_message_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:grpc.reflection.v1alpha.ErrorResponse.error_message)
+}
+inline void ErrorResponse::set_error_message(const char* value, size_t size) {
+  
+  error_message_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:grpc.reflection.v1alpha.ErrorResponse.error_message)
+}
+inline ::std::string* ErrorResponse::mutable_error_message() {
+  
+  // @@protoc_insertion_point(field_mutable:grpc.reflection.v1alpha.ErrorResponse.error_message)
+  return error_message_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline ::std::string* ErrorResponse::release_error_message() {
+  // @@protoc_insertion_point(field_release:grpc.reflection.v1alpha.ErrorResponse.error_message)
+  
+  return error_message_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void ErrorResponse::set_allocated_error_message(::std::string* error_message) {
+  if (error_message != NULL) {
+    
+  } else {
+    
+  }
+  error_message_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), error_message);
+  // @@protoc_insertion_point(field_set_allocated:grpc.reflection.v1alpha.ErrorResponse.error_message)
+}
+
+#endif  // !PROTOBUF_INLINE_NOT_IN_HEADERS
+// -------------------------------------------------------------------
+
+// -------------------------------------------------------------------
+
+// -------------------------------------------------------------------
+
+// -------------------------------------------------------------------
+
+// -------------------------------------------------------------------
+
+// -------------------------------------------------------------------
+
+// -------------------------------------------------------------------
+
+
+// @@protoc_insertion_point(namespace_scope)
+
+}  // namespace v1alpha
+}  // namespace reflection
+}  // namespace grpc
+
+// @@protoc_insertion_point(global_scope)
+
+#endif  // PROTOBUF_reflection_2eproto__INCLUDED
diff --git a/include/grpc++/grpc++.h b/include/grpc++/grpc++.h
index b7d5fb0..ef07e19 100644
--- a/include/grpc++/grpc++.h
+++ b/include/grpc++/grpc++.h
@@ -57,8 +57,10 @@
 #include <grpc++/client_context.h>
 #include <grpc++/completion_queue.h>
 #include <grpc++/create_channel.h>
+#include <grpc++/create_channel_posix.h>
 #include <grpc++/server.h>
 #include <grpc++/server_builder.h>
 #include <grpc++/server_context.h>
+#include <grpc++/server_posix.h>
 
 #endif  // GRPCXX_GRPCXX_H
diff --git a/include/grpc++/impl/codegen/async_stream.h b/include/grpc++/impl/codegen/async_stream.h
index a607a47..0606441 100644
--- a/include/grpc++/impl/codegen/async_stream.h
+++ b/include/grpc++/impl/codegen/async_stream.h
@@ -172,6 +172,7 @@
                     R* response, void* tag)
       : context_(context), call_(channel->CreateCall(method, context, cq)) {
     finish_ops_.RecvMessage(response);
+    finish_ops_.AllowNoMessage();
 
     init_ops_.set_output_tag(tag);
     init_ops_.SendInitialMetadata(context->send_initial_metadata_,
@@ -298,8 +299,16 @@
 };
 
 template <class W, class R>
-class ServerAsyncReader GRPC_FINAL : public ServerAsyncStreamingInterface,
-                                     public AsyncReaderInterface<R> {
+class ServerAsyncReaderInterface : public ServerAsyncStreamingInterface,
+                                   public AsyncReaderInterface<R> {
+ public:
+  virtual void Finish(const W& msg, const Status& status, void* tag) = 0;
+
+  virtual void FinishWithError(const Status& status, void* tag) = 0;
+};
+
+template <class W, class R>
+class ServerAsyncReader GRPC_FINAL : public ServerAsyncReaderInterface<W, R> {
  public:
   explicit ServerAsyncReader(ServerContext* ctx)
       : call_(nullptr, nullptr, nullptr), ctx_(ctx) {}
@@ -320,7 +329,7 @@
     call_.PerformOps(&read_ops_);
   }
 
-  void Finish(const W& msg, const Status& status, void* tag) {
+  void Finish(const W& msg, const Status& status, void* tag) GRPC_OVERRIDE {
     finish_ops_.set_output_tag(tag);
     if (!ctx_->sent_initial_metadata_) {
       finish_ops_.SendInitialMetadata(ctx_->initial_metadata_,
@@ -337,7 +346,7 @@
     call_.PerformOps(&finish_ops_);
   }
 
-  void FinishWithError(const Status& status, void* tag) {
+  void FinishWithError(const Status& status, void* tag) GRPC_OVERRIDE {
     GPR_CODEGEN_ASSERT(!status.ok());
     finish_ops_.set_output_tag(tag);
     if (!ctx_->sent_initial_metadata_) {
@@ -362,8 +371,14 @@
 };
 
 template <class W>
-class ServerAsyncWriter GRPC_FINAL : public ServerAsyncStreamingInterface,
-                                     public AsyncWriterInterface<W> {
+class ServerAsyncWriterInterface : public ServerAsyncStreamingInterface,
+                                   public AsyncWriterInterface<W> {
+ public:
+  virtual void Finish(const Status& status, void* tag) = 0;
+};
+
+template <class W>
+class ServerAsyncWriter GRPC_FINAL : public ServerAsyncWriterInterface<W> {
  public:
   explicit ServerAsyncWriter(ServerContext* ctx)
       : call_(nullptr, nullptr, nullptr), ctx_(ctx) {}
@@ -390,7 +405,7 @@
     call_.PerformOps(&write_ops_);
   }
 
-  void Finish(const Status& status, void* tag) {
+  void Finish(const Status& status, void* tag) GRPC_OVERRIDE {
     finish_ops_.set_output_tag(tag);
     if (!ctx_->sent_initial_metadata_) {
       finish_ops_.SendInitialMetadata(ctx_->initial_metadata_,
@@ -413,9 +428,16 @@
 
 /// Server-side interface for asynchronous bi-directional streaming.
 template <class W, class R>
-class ServerAsyncReaderWriter GRPC_FINAL : public ServerAsyncStreamingInterface,
-                                           public AsyncWriterInterface<W>,
-                                           public AsyncReaderInterface<R> {
+class ServerAsyncReaderWriterInterface : public ServerAsyncStreamingInterface,
+                                         public AsyncWriterInterface<W>,
+                                         public AsyncReaderInterface<R> {
+ public:
+  virtual void Finish(const Status& status, void* tag) = 0;
+};
+
+template <class W, class R>
+class ServerAsyncReaderWriter GRPC_FINAL
+    : public ServerAsyncReaderWriterInterface<W, R> {
  public:
   explicit ServerAsyncReaderWriter(ServerContext* ctx)
       : call_(nullptr, nullptr, nullptr), ctx_(ctx) {}
@@ -448,7 +470,7 @@
     call_.PerformOps(&write_ops_);
   }
 
-  void Finish(const Status& status, void* tag) {
+  void Finish(const Status& status, void* tag) GRPC_OVERRIDE {
     finish_ops_.set_output_tag(tag);
     if (!ctx_->sent_initial_metadata_) {
       finish_ops_.SendInitialMetadata(ctx_->initial_metadata_,
diff --git a/include/grpc++/impl/codegen/async_unary_call.h b/include/grpc++/impl/codegen/async_unary_call.h
index 55c9788..47ac5be 100644
--- a/include/grpc++/impl/codegen/async_unary_call.h
+++ b/include/grpc++/impl/codegen/async_unary_call.h
@@ -91,6 +91,7 @@
       collection_->finish_buf_.RecvInitialMetadata(context_);
     }
     collection_->finish_buf_.RecvMessage(msg);
+    collection_->finish_buf_.AllowNoMessage();
     collection_->finish_buf_.ClientRecvStatus(context_, status);
     call_.PerformOps(&collection_->finish_buf_);
   }
diff --git a/include/grpc++/impl/codegen/call.h b/include/grpc++/impl/codegen/call.h
index d457f03..d720f27 100644
--- a/include/grpc++/impl/codegen/call.h
+++ b/include/grpc++/impl/codegen/call.h
@@ -47,7 +47,9 @@
 #include <grpc++/impl/codegen/serialization_traits.h>
 #include <grpc++/impl/codegen/status.h>
 #include <grpc++/impl/codegen/string_ref.h>
+
 #include <grpc/impl/codegen/alloc.h>
+#include <grpc/impl/codegen/compression_types.h>
 #include <grpc/impl/codegen/grpc_types.h>
 
 struct grpc_byte_buffer;
@@ -187,6 +189,8 @@
     flags_ = flags;
     initial_metadata_count_ = metadata.size();
     initial_metadata_ = FillMetadataArray(metadata);
+    // TODO(dgq): expose compression level in API so it can be properly set.
+    maybe_compression_level_.is_set = false;
   }
 
  protected:
@@ -198,6 +202,10 @@
     op->reserved = NULL;
     op->data.send_initial_metadata.count = initial_metadata_count_;
     op->data.send_initial_metadata.metadata = initial_metadata_;
+    op->data.send_initial_metadata.maybe_compression_level.is_set =
+        maybe_compression_level_.is_set;
+    op->data.send_initial_metadata.maybe_compression_level.level =
+        maybe_compression_level_.level;
   }
   void FinishOp(bool* status, int max_message_size) {
     if (!send_) return;
@@ -209,6 +217,10 @@
   uint32_t flags_;
   size_t initial_metadata_count_;
   grpc_metadata* initial_metadata_;
+  struct {
+    bool is_set;
+    grpc_compression_level level;
+  } maybe_compression_level_;
 };
 
 class CallOpSendMessage {
@@ -261,10 +273,16 @@
 template <class R>
 class CallOpRecvMessage {
  public:
-  CallOpRecvMessage() : got_message(false), message_(nullptr) {}
+  CallOpRecvMessage()
+      : got_message(false),
+        message_(nullptr),
+        allow_not_getting_message_(false) {}
 
   void RecvMessage(R* message) { message_ = message; }
 
+  // Do not change status if no message is received.
+  void AllowNoMessage() { allow_not_getting_message_ = true; }
+
   bool got_message;
 
  protected:
@@ -290,7 +308,9 @@
       }
     } else {
       got_message = false;
-      *status = false;
+      if (!allow_not_getting_message_) {
+        *status = false;
+      }
     }
     message_ = nullptr;
   }
@@ -298,6 +318,7 @@
  private:
   R* message_;
   grpc_byte_buffer* recv_buf_;
+  bool allow_not_getting_message_;
 };
 
 namespace CallOpGenericRecvMessageHelper {
@@ -325,7 +346,8 @@
 
 class CallOpGenericRecvMessage {
  public:
-  CallOpGenericRecvMessage() : got_message(false) {}
+  CallOpGenericRecvMessage()
+      : got_message(false), allow_not_getting_message_(false) {}
 
   template <class R>
   void RecvMessage(R* message) {
@@ -336,6 +358,9 @@
     deserialize_.reset(func);
   }
 
+  // Do not change status if no message is received.
+  void AllowNoMessage() { allow_not_getting_message_ = true; }
+
   bool got_message;
 
  protected:
@@ -360,7 +385,9 @@
       }
     } else {
       got_message = false;
-      *status = false;
+      if (!allow_not_getting_message_) {
+        *status = false;
+      }
     }
     deserialize_.reset();
   }
@@ -368,6 +395,7 @@
  private:
   std::unique_ptr<CallOpGenericRecvMessageHelper::DeserializeFunc> deserialize_;
   grpc_byte_buffer* recv_buf_;
+  bool allow_not_getting_message_;
 };
 
 class CallOpClientSendClose {
diff --git a/include/grpc++/impl/codegen/config_protobuf.h b/include/grpc++/impl/codegen/config_protobuf.h
index f1b6bea..4bee1bc 100644
--- a/include/grpc++/impl/codegen/config_protobuf.h
+++ b/include/grpc++/impl/codegen/config_protobuf.h
@@ -44,6 +44,19 @@
 #define GRPC_CUSTOM_MESSAGE ::google::protobuf::Message
 #endif
 
+#ifndef GRPC_CUSTOM_DESCRIPTOR
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/descriptor.pb.h>
+#define GRPC_CUSTOM_DESCRIPTOR ::google::protobuf::Descriptor
+#define GRPC_CUSTOM_DESCRIPTORPOOL ::google::protobuf::DescriptorPool
+#define GPRC_CUSTOM_FIELDDESCRIPTOR ::google::protobuf::FieldDescriptor
+#define GRPC_CUSTOM_FILEDESCRIPTOR ::google::protobuf::FileDescriptor
+#define GRPC_CUSTOM_FILEDESCRIPTORPROTO ::google::protobuf::FileDescriptorProto
+#define GRPC_CUSTOM_METHODDESCRIPTOR ::google::protobuf::MethodDescriptor
+#define GRPC_CUSTOM_SERVICEDESCRIPTOR ::google::protobuf::ServiceDescriptor
+#define GRPC_CUSTOM_SOURCELOCATION ::google::protobuf::SourceLocation
+#endif
+
 #ifndef GRPC_CUSTOM_ZEROCOPYOUTPUTSTREAM
 #include <google/protobuf/io/coded_stream.h>
 #include <google/protobuf/io/zero_copy_stream.h>
@@ -60,6 +73,15 @@
 typedef GRPC_CUSTOM_MESSAGE Message;
 typedef GRPC_CUSTOM_PROTOBUF_INT64 int64;
 
+typedef GRPC_CUSTOM_DESCRIPTOR Descriptor;
+typedef GRPC_CUSTOM_DESCRIPTORPOOL DescriptorPool;
+typedef GPRC_CUSTOM_FIELDDESCRIPTOR FieldDescriptor;
+typedef GRPC_CUSTOM_FILEDESCRIPTOR FileDescriptor;
+typedef GRPC_CUSTOM_FILEDESCRIPTORPROTO FileDescriptorProto;
+typedef GRPC_CUSTOM_METHODDESCRIPTOR MethodDescriptor;
+typedef GRPC_CUSTOM_SERVICEDESCRIPTOR ServiceDescriptor;
+typedef GRPC_CUSTOM_SOURCELOCATION SourceLocation;
+
 namespace io {
 typedef GRPC_CUSTOM_ZEROCOPYOUTPUTSTREAM ZeroCopyOutputStream;
 typedef GRPC_CUSTOM_ZEROCOPYINPUTSTREAM ZeroCopyInputStream;
diff --git a/src/cpp/common/core_codegen.h b/include/grpc++/impl/codegen/core_codegen.h
similarity index 100%
rename from src/cpp/common/core_codegen.h
rename to include/grpc++/impl/codegen/core_codegen.h
diff --git a/include/grpc++/impl/codegen/core_codegen_interface.h b/include/grpc++/impl/codegen/core_codegen_interface.h
index aa9013c..64d882e 100644
--- a/include/grpc++/impl/codegen/core_codegen_interface.h
+++ b/include/grpc++/impl/codegen/core_codegen_interface.h
@@ -34,7 +34,7 @@
 #ifndef GRPCXX_IMPL_CODEGEN_CORE_CODEGEN_INTERFACE_H
 #define GRPCXX_IMPL_CODEGEN_CORE_CODEGEN_INTERFACE_H
 
-#include <grpc++/impl/codegen/config_protobuf.h>
+#include <grpc++/impl/codegen/config.h>
 #include <grpc++/impl/codegen/status.h>
 #include <grpc/impl/codegen/grpc_types.h>
 
diff --git a/include/grpc++/impl/codegen/impl/async_stream.h b/include/grpc++/impl/codegen/impl/async_stream.h
index 8f99e7e..7d7a956 100644
--- a/include/grpc++/impl/codegen/impl/async_stream.h
+++ b/include/grpc++/impl/codegen/impl/async_stream.h
@@ -295,8 +295,16 @@
 };
 
 template <class W, class R>
-class ServerAsyncReader GRPC_FINAL : public ServerAsyncStreamingInterface,
-                                     public AsyncReaderInterface<R> {
+class ServerAsyncReaderInterface : public ServerAsyncStreamingInterface,
+                                   public AsyncReaderInterface<R> {
+ public:
+  virtual void Finish(const W& msg, const Status& status, void* tag) = 0;
+
+  virtual void FinishWithError(const Status& status, void* tag) = 0;
+};
+
+template <class W, class R>
+class ServerAsyncReader GRPC_FINAL : public ServerAsyncReaderInterface<W, R> {
  public:
   explicit ServerAsyncReader(ServerContext* ctx)
       : call_(nullptr, nullptr, nullptr), ctx_(ctx) {}
@@ -316,7 +324,7 @@
     call_.PerformOps(&read_ops_);
   }
 
-  void Finish(const W& msg, const Status& status, void* tag) {
+  void Finish(const W& msg, const Status& status, void* tag) GRPC_OVERRIDE {
     finish_ops_.set_output_tag(tag);
     if (!ctx_->sent_initial_metadata_) {
       finish_ops_.SendInitialMetadata(ctx_->initial_metadata_);
@@ -332,7 +340,7 @@
     call_.PerformOps(&finish_ops_);
   }
 
-  void FinishWithError(const Status& status, void* tag) {
+  void FinishWithError(const Status& status, void* tag) GRPC_OVERRIDE {
     GPR_CODEGEN_ASSERT(!status.ok());
     finish_ops_.set_output_tag(tag);
     if (!ctx_->sent_initial_metadata_) {
@@ -356,8 +364,14 @@
 };
 
 template <class W>
-class ServerAsyncWriter GRPC_FINAL : public ServerAsyncStreamingInterface,
-                                     public AsyncWriterInterface<W> {
+class ServerAsyncWriterInterface : public ServerAsyncStreamingInterface,
+                                   public AsyncWriterInterface<W> {
+ public:
+  virtual void Finish(const Status& status, void* tag) = 0;
+};
+
+template <class W>
+class ServerAsyncWriter GRPC_FINAL : public ServerAsyncWriterInterface<W> {
  public:
   explicit ServerAsyncWriter(ServerContext* ctx)
       : call_(nullptr, nullptr, nullptr), ctx_(ctx) {}
@@ -382,7 +396,7 @@
     call_.PerformOps(&write_ops_);
   }
 
-  void Finish(const Status& status, void* tag) {
+  void Finish(const Status& status, void* tag) GRPC_OVERRIDE {
     finish_ops_.set_output_tag(tag);
     if (!ctx_->sent_initial_metadata_) {
       finish_ops_.SendInitialMetadata(ctx_->initial_metadata_);
@@ -404,9 +418,16 @@
 
 /// Server-side interface for asynchronous bi-directional streaming.
 template <class W, class R>
-class ServerAsyncReaderWriter GRPC_FINAL : public ServerAsyncStreamingInterface,
-                                           public AsyncWriterInterface<W>,
-                                           public AsyncReaderInterface<R> {
+class ServerAsyncReaderWriterInterface : public ServerAsyncStreamingInterface,
+                                         public AsyncWriterInterface<W>,
+                                         public AsyncReaderInterface<R> {
+ public:
+  virtual void Finish(const Status& status, void* tag) = 0;
+};
+
+template <class W, class R>
+class ServerAsyncReaderWriter GRPC_FINAL
+    : public ServerAsyncReaderWriterInterface<W, R> {
  public:
   explicit ServerAsyncReaderWriter(ServerContext* ctx)
       : call_(nullptr, nullptr, nullptr), ctx_(ctx) {}
@@ -437,7 +458,7 @@
     call_.PerformOps(&write_ops_);
   }
 
-  void Finish(const Status& status, void* tag) {
+  void Finish(const Status& status, void* tag) GRPC_OVERRIDE {
     finish_ops_.set_output_tag(tag);
     if (!ctx_->sent_initial_metadata_) {
       finish_ops_.SendInitialMetadata(ctx_->initial_metadata_);
diff --git a/include/grpc++/impl/codegen/sync_stream.h b/include/grpc++/impl/codegen/sync_stream.h
index 9100ce0..e94ffe5 100644
--- a/include/grpc++/impl/codegen/sync_stream.h
+++ b/include/grpc++/impl/codegen/sync_stream.h
@@ -189,6 +189,7 @@
                ClientContext* context, R* response)
       : context_(context), call_(channel->CreateCall(method, context, &cq_)) {
     finish_ops_.RecvMessage(response);
+    finish_ops_.AllowNoMessage();
 
     CallOpSet<CallOpSendInitialMetadata> ops;
     ops.SendInitialMetadata(context->send_initial_metadata_,
diff --git a/include/grpc++/impl/grpc_library.h b/include/grpc++/impl/grpc_library.h
index 175cf99..1184d1b 100644
--- a/include/grpc++/impl/grpc_library.h
+++ b/include/grpc++/impl/grpc_library.h
@@ -37,11 +37,10 @@
 #include <iostream>
 
 #include <grpc++/impl/codegen/config.h>
+#include <grpc++/impl/codegen/core_codegen.h>
 #include <grpc++/impl/codegen/grpc_library.h>
 #include <grpc/grpc.h>
 
-#include "src/cpp/common/core_codegen.h"
-
 namespace grpc {
 
 namespace internal {
diff --git a/include/grpc++/impl/proto_utils.h b/include/grpc++/impl/proto_utils.h
deleted file mode 100644
index a34cf9b..0000000
--- a/include/grpc++/impl/proto_utils.h
+++ /dev/null
@@ -1,39 +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 GRPCXX_IMPL_PROTO_UTILS_H
-#define GRPCXX_IMPL_PROTO_UTILS_H
-
-#include <grpc++/impl/codegen/proto_utils.h>
-
-#endif  // GRPCXX_IMPL_PROTO_UTILS_H
diff --git a/include/grpc++/server.h b/include/grpc++/server.h
index a0ee0e9..7a8858e 100644
--- a/include/grpc++/server.h
+++ b/include/grpc++/server.h
@@ -93,6 +93,12 @@
   /// until all server objects in the process have been destroyed.
   static void SetGlobalCallbacks(GlobalCallbacks* callbacks);
 
+  // Returns a \em raw pointer to the underlying grpc_server instance.
+  grpc_server* c_server();
+
+  // Returns a \em raw pointer to the underlying CompletionQueue.
+  CompletionQueue* completion_queue();
+
  private:
   friend class AsyncGenericService;
   friend class ServerBuilder;
diff --git a/include/grpc++/server_builder.h b/include/grpc++/server_builder.h
index 8525cb7..54f01d1 100644
--- a/include/grpc++/server_builder.h
+++ b/include/grpc++/server_builder.h
@@ -66,29 +66,43 @@
   /// The service must exist for the lifetime of the \a Server instance returned
   /// by \a BuildAndStart().
   /// Matches requests with any :authority
-  void RegisterService(Service* service);
+  ServerBuilder& RegisterService(Service* service);
 
   /// Register a generic service.
   /// Matches requests with any :authority
-  void RegisterAsyncGenericService(AsyncGenericService* service);
+  ServerBuilder& RegisterAsyncGenericService(AsyncGenericService* service);
 
   /// Register a service. This call does not take ownership of the service.
   /// The service must exist for the lifetime of the \a Server instance returned
   /// by BuildAndStart().
   /// Only matches requests with :authority \a host
-  void RegisterService(const grpc::string& host, Service* service);
+  ServerBuilder& RegisterService(const grpc::string& host, Service* service);
 
   /// Set max message size in bytes.
-  void SetMaxMessageSize(int max_message_size) {
+  ServerBuilder& SetMaxMessageSize(int max_message_size) {
     max_message_size_ = max_message_size;
+    return *this;
   }
 
-  /// Set the compression options to be used by the server.
-  void SetCompressionOptions(const grpc_compression_options& options) {
-    compression_options_ = options;
-  }
+  /// Set the support status for compression algorithms. All algorithms are
+  /// enabled by default.
+  ///
+  /// Incoming calls compressed with an unsupported algorithm will fail with
+  /// GRPC_STATUS_UNIMPLEMENTED.
+  ServerBuilder& SetCompressionAlgorithmSupportStatus(
+      grpc_compression_algorithm algorithm, bool enabled);
 
-  void SetOption(std::unique_ptr<ServerBuilderOption> option);
+  /// The default compression level to use for all channel calls in the
+  /// absence of a call-specific level.
+  ServerBuilder& SetDefaultCompressionLevel(grpc_compression_level level);
+
+  /// The default compression algorithm to use for all channel calls in the
+  /// absence of a call-specific level. Note that it overrides any compression
+  /// level set by \a SetDefaultCompressionLevel.
+  ServerBuilder& SetDefaultCompressionAlgorithm(
+      grpc_compression_algorithm algorithm);
+
+  ServerBuilder& SetOption(std::unique_ptr<ServerBuilderOption> option);
 
   /// Tries to bind \a server to the given \a addr.
   ///
@@ -101,9 +115,9 @@
   /// number. \a nullptr otherwise.
   ///
   // TODO(dgq): the "port" part seems to be a misnomer.
-  void AddListeningPort(const grpc::string& addr,
-                        std::shared_ptr<ServerCredentials> creds,
-                        int* selected_port = nullptr);
+  ServerBuilder& AddListeningPort(const grpc::string& addr,
+                                  std::shared_ptr<ServerCredentials> creds,
+                                  int* selected_port = nullptr);
 
   /// Add a completion queue for handling asynchronous services
   /// Caller is required to keep this completion queue live until
@@ -144,7 +158,6 @@
   };
 
   int max_message_size_;
-  grpc_compression_options compression_options_;
   std::vector<std::unique_ptr<ServerBuilderOption>> options_;
   std::vector<std::unique_ptr<NamedService>> services_;
   std::vector<Port> ports_;
@@ -152,6 +165,15 @@
   std::shared_ptr<ServerCredentials> creds_;
   std::map<grpc::string, std::unique_ptr<ServerBuilderPlugin>> plugins_;
   AsyncGenericService* generic_service_;
+  struct {
+    bool is_set;
+    grpc_compression_level level;
+  } maybe_default_compression_level_;
+  struct {
+    bool is_set;
+    grpc_compression_algorithm algorithm;
+  } maybe_default_compression_algorithm_;
+  uint32_t enabled_compression_algorithms_bitset_;
 };
 
 }  // namespace grpc
diff --git a/src/core/lib/support/string_win32.h b/include/grpc++/server_posix.h
similarity index 74%
copy from src/core/lib/support/string_win32.h
copy to include/grpc++/server_posix.h
index ff4a694..e6066d4 100644
--- a/src/core/lib/support/string_win32.h
+++ b/include/grpc++/server_posix.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,17 +31,26 @@
  *
  */
 
-#ifndef GRPC_CORE_LIB_SUPPORT_STRING_WIN32_H
-#define GRPC_CORE_LIB_SUPPORT_STRING_WIN32_H
+#ifndef GRPCXX_SERVER_POSIX_H
+#define GRPCXX_SERVER_POSIX_H
 
+#include <memory>
+
+#include <grpc++/server.h>
 #include <grpc/support/port_platform.h>
 
-#ifdef GPR_WIN32
+namespace grpc {
 
-/* These allocate new strings using gpr_malloc to convert from and to utf-8. */
-LPTSTR gpr_char_to_tchar(LPCSTR input);
-LPSTR gpr_tchar_to_char(LPCTSTR input);
+#ifdef GPR_SUPPORT_CHANNELS_FROM_FD
 
-#endif /* GPR_WIN32 */
+/// Adds new client to a \a Server communicating over given file descriptor
+///
+/// \param server The server to add a client to.
+/// \param fd The file descriptor representing a socket.
+void AddInsecureChannelFromFd(Server* server, int fd);
 
-#endif /* GRPC_CORE_LIB_SUPPORT_STRING_WIN32_H */
+#endif  // GPR_SUPPORT_CHANNELS_FROM_FD
+
+}  // namespace grpc
+
+#endif  // GRPCXX_SERVER_POSIX_H
diff --git a/include/grpc++/support/config_protobuf.h b/include/grpc++/support/config_protobuf.h
deleted file mode 100644
index 3e7f169..0000000
--- a/include/grpc++/support/config_protobuf.h
+++ /dev/null
@@ -1,39 +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 GRPCXX_SUPPORT_CONFIG_PROTOBUF_H
-#define GRPCXX_SUPPORT_CONFIG_PROTOBUF_H
-
-#include <grpc++/impl/codegen/config_protobuf.h>
-
-#endif  // GRPCXX_SUPPORT_CONFIG_PROTOBUF_H
diff --git a/include/grpc/compression.h b/include/grpc/compression.h
index 8de4b13..22bcf0e 100644
--- a/include/grpc/compression.h
+++ b/include/grpc/compression.h
@@ -51,7 +51,8 @@
     grpc_compression_algorithm *algorithm);
 
 /** Updates \a name with the encoding name corresponding to a valid \a
- * algorithm.  Returns 1 upon success, 0 otherwise. */
+ * algorithm. Note that \a name is statically allocated and must *not* be freed.
+ * Returns 1 upon success, 0 otherwise. */
 GRPCAPI int grpc_compression_algorithm_name(
     grpc_compression_algorithm algorithm, char **name);
 
diff --git a/include/grpc/grpc_posix.h b/include/grpc/grpc_posix.h
new file mode 100644
index 0000000..9742b83
--- /dev/null
+++ b/include/grpc/grpc_posix.h
@@ -0,0 +1,70 @@
+/*
+ *
+ * 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_GRPC_POSIX_H
+#define GRPC_GRPC_POSIX_H
+
+#include <grpc/impl/codegen/grpc_types.h>
+#include <grpc/support/port_platform.h>
+
+#include <stddef.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*! \mainpage GRPC Core POSIX
+ *
+ * The GRPC Core POSIX library provides some POSIX-specific low-level
+ * functionality on top of GRPC Core.
+ */
+
+/** Create a client channel to 'target' using file descriptor 'fd'. The 'target'
+    argument will be used to indicate the name for this channel. See the comment
+    for grpc_insecure_channel_create for description of 'args' argument. */
+GRPCAPI grpc_channel *grpc_insecure_channel_create_from_fd(
+    const char *target, int fd, const grpc_channel_args *args);
+
+/** Add the connected communication channel based on file descriptor 'fd' to the
+    'server'. The 'fd' must be an open file descriptor corresponding to a
+    connected socket. The 'cq' is a completion queue that will be getting events
+    from that descriptor. */
+GRPCAPI void grpc_server_add_insecure_channel_from_fd(grpc_server *server,
+                                                      grpc_completion_queue *cq,
+                                                      int fd);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GRPC_GRPC_POSIX_H */
diff --git a/include/grpc/impl/codegen/atm.h b/include/grpc/impl/codegen/atm.h
index 5376026..5589d5d 100644
--- a/include/grpc/impl/codegen/atm.h
+++ b/include/grpc/impl/codegen/atm.h
@@ -83,8 +83,8 @@
 #include <grpc/impl/codegen/atm_gcc_atomic.h>
 #elif defined(GPR_GCC_SYNC)
 #include <grpc/impl/codegen/atm_gcc_sync.h>
-#elif defined(GPR_WIN32_ATOMIC)
-#include <grpc/impl/codegen/atm_win32.h>
+#elif defined(GPR_WINDOWS_ATOMIC)
+#include <grpc/impl/codegen/atm_windows.h>
 #else
 #error could not determine platform for atm
 #endif
diff --git a/include/grpc/impl/codegen/atm_win32.h b/include/grpc/impl/codegen/atm_windows.h
similarity index 96%
rename from include/grpc/impl/codegen/atm_win32.h
rename to include/grpc/impl/codegen/atm_windows.h
index 7c1ccaf..d5fa8c0 100644
--- a/include/grpc/impl/codegen/atm_win32.h
+++ b/include/grpc/impl/codegen/atm_windows.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_IMPL_CODEGEN_ATM_WIN32_H
-#define GRPC_IMPL_CODEGEN_ATM_WIN32_H
+#ifndef GRPC_IMPL_CODEGEN_ATM_WINDOWS_H
+#define GRPC_IMPL_CODEGEN_ATM_WINDOWS_H
 
 /* Win32 variant of atm_platform.h */
 #include <grpc/impl/codegen/port_platform.h>
@@ -122,4 +122,4 @@
   return old;
 }
 
-#endif /* GRPC_IMPL_CODEGEN_ATM_WIN32_H */
+#endif /* GRPC_IMPL_CODEGEN_ATM_WINDOWS_H */
diff --git a/include/grpc/impl/codegen/compression_types.h b/include/grpc/impl/codegen/compression_types.h
index 8d2ec3b..9065d1e 100644
--- a/include/grpc/impl/codegen/compression_types.h
+++ b/include/grpc/impl/codegen/compression_types.h
@@ -35,11 +35,17 @@
 #define GRPC_IMPL_CODEGEN_COMPRESSION_TYPES_H
 
 #include <grpc/impl/codegen/port_platform.h>
+#include <stdbool.h>
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+/** To be used as initial metadata key for the request of a concrete compression
+ * algorithm */
+#define GRPC_COMPRESSION_REQUEST_ALGORITHM_MD_KEY \
+  "grpc-internal-encoding-request"
+
 /** To be used in channel arguments */
 #define GRPC_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM \
   "grpc.default_compression_algorithm"
@@ -74,15 +80,24 @@
    */
   uint32_t enabled_algorithms_bitset;
 
-  /** The default channel compression algorithm. It'll be used in the absence of
-   * call specific settings. This option corresponds to the channel argument key
-   * behind \a GRPC_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM */
-  grpc_compression_algorithm default_compression_algorithm;
-
   /** The default channel compression level. It'll be used in the absence of
    * call specific settings. This option corresponds to the channel argument key
-   * behind \a GRPC_COMPRESSION_CHANNEL_DEFAULT_LEVEL */
-  grpc_compression_algorithm default_compression_level;
+   * behind \a GRPC_COMPRESSION_CHANNEL_DEFAULT_LEVEL. If present, takes
+   * precedence over \a default_algorithm.
+   * TODO(dgq): currently only available for server channels. */
+  struct {
+    bool is_set;
+    grpc_compression_level level;
+  } default_level;
+
+  /** The default channel compression algorithm. It'll be used in the absence of
+   * call specific settings. This option corresponds to the channel argument key
+   * behind \a GRPC_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM. */
+  struct {
+    bool is_set;
+    grpc_compression_algorithm algorithm;
+  } default_algorithm;
+
 } grpc_compression_options;
 
 #ifdef __cplusplus
diff --git a/include/grpc/impl/codegen/connectivity_state.h b/include/grpc/impl/codegen/connectivity_state.h
index 5bb9eb8..71865d8 100644
--- a/include/grpc/impl/codegen/connectivity_state.h
+++ b/include/grpc/impl/codegen/connectivity_state.h
@@ -49,7 +49,7 @@
   /** channel has seen a failure but expects to recover */
   GRPC_CHANNEL_TRANSIENT_FAILURE,
   /** channel has seen a failure that it cannot recover from */
-  GRPC_CHANNEL_FATAL_FAILURE
+  GRPC_CHANNEL_SHUTDOWN
 } grpc_connectivity_state;
 
 #ifdef __cplusplus
diff --git a/include/grpc/impl/codegen/grpc_types.h b/include/grpc/impl/codegen/grpc_types.h
index af3d0c2..c51ffa4 100644
--- a/include/grpc/impl/codegen/grpc_types.h
+++ b/include/grpc/impl/codegen/grpc_types.h
@@ -115,6 +115,8 @@
 /* Channel argument keys: */
 /** Enable census for tracing and stats collection */
 #define GRPC_ARG_ENABLE_CENSUS "grpc.census"
+/** Enable load reporting */
+#define GRPC_ARG_ENABLE_LOAD_REPORTING "grpc.loadreporting"
 /** Maximum number of concurrent incoming streams to allow on a http2
     connection */
 #define GRPC_ARG_MAX_CONCURRENT_STREAMS "grpc.max_concurrent_streams"
@@ -332,6 +334,12 @@
     struct {
       size_t count;
       grpc_metadata *metadata;
+      /** If \a is_set, \a compression_level will be used for the call.
+       * Otherwise, \a compression_level won't be considered */
+      struct {
+        uint8_t is_set;
+        grpc_compression_level level;
+      } maybe_compression_level;
     } send_initial_metadata;
     grpc_byte_buffer *send_message;
     struct {
diff --git a/include/grpc/impl/codegen/port_platform.h b/include/grpc/impl/codegen/port_platform.h
index d2d9ac7..7fff36c 100644
--- a/include/grpc/impl/codegen/port_platform.h
+++ b/include/grpc/impl/codegen/port_platform.h
@@ -89,10 +89,10 @@
 #define GPR_ARCH_32 1
 #endif
 #define GPR_PLATFORM_STRING "windows"
-#define GPR_WIN32 1
+#define GPR_WINDOWS 1
 #define GPR_WINSOCK_SOCKET 1
 #define GPR_WINDOWS_SUBPROCESS 1
-#define GPR_WIN32_ENV
+#define GPR_WINDOWS_ENV
 #ifdef __MSYS__
 #define GPR_GETPID_IN_UNISTD_H 1
 #define GPR_MSYS_TMPFILE
@@ -101,17 +101,17 @@
 #define GPR_POSIX_TIME
 #else
 #define GPR_GETPID_IN_PROCESS_H 1
-#define GPR_WIN32_TMPFILE
-#define GPR_WIN32_LOG
+#define GPR_WINDOWS_TMPFILE
+#define GPR_WINDOWS_LOG
 #define GPR_WINDOWS_CRASH_HANDLER 1
-#define GPR_WIN32_STRING
-#define GPR_WIN32_TIME
+#define GPR_WINDOWS_STRING
+#define GPR_WINDOWS_TIME
 #endif
 #ifdef __GNUC__
 #define GPR_GCC_ATOMIC 1
 #define GPR_GCC_TLS 1
 #else
-#define GPR_WIN32_ATOMIC 1
+#define GPR_WINDOWS_ATOMIC 1
 #define GPR_MSVC_TLS 1
 #endif
 #elif defined(GPR_MANYLINUX1)
@@ -129,6 +129,7 @@
 #define GPR_POSIX_SOCKETADDR 1
 #define GPR_POSIX_NO_SPECIAL_WAKEUP_FD 1
 #define GPR_POSIX_SOCKETUTILS 1
+#define GPR_SUPPORT_CHANNELS_FROM_FD 1
 #define GPR_HAVE_UNIX_SOCKET 1
 #define GPR_HAVE_IP_PKTINFO 1
 #define GPR_HAVE_IPV6_RECVPKTINFO 1
@@ -168,6 +169,7 @@
 #define GPR_POSIX_SYNC 1
 #define GPR_POSIX_TIME 1
 #define GPR_GETPID_IN_UNISTD_H 1
+#define GPR_SUPPORT_CHANNELS_FROM_FD 1
 #define GPR_HAVE_MSG_NOSIGNAL 1
 #define GPR_HAVE_UNIX_SOCKET 1
 #define GPR_HAVE_IP_PKTINFO 1
@@ -194,6 +196,7 @@
 #define GPR_POSIX_WAKEUP_FD 1
 #define GPR_POSIX_SOCKET 1
 #define GPR_POSIX_SOCKETADDR 1
+#define GPR_SUPPORT_CHANNELS_FROM_FD 1
 #define GPR_HAVE_UNIX_SOCKET 1
 #define GPR_HAVE_IP_PKTINFO 1
 #define GPR_HAVE_IPV6_RECVPKTINFO 1
@@ -258,6 +261,7 @@
 #define GPR_POSIX_SYNC 1
 #define GPR_POSIX_TIME 1
 #define GPR_GETPID_IN_UNISTD_H 1
+#define GPR_SUPPORT_CHANNELS_FROM_FD 1
 #define GPR_HAVE_SO_NOSIGPIPE 1
 #define GPR_HAVE_UNIX_SOCKET 1
 #define GPR_HAVE_IP_PKTINFO 1
@@ -289,6 +293,7 @@
 #define GPR_POSIX_SYNC 1
 #define GPR_POSIX_TIME 1
 #define GPR_GETPID_IN_UNISTD_H 1
+#define GPR_SUPPORT_CHANNELS_FROM_FD 1
 #define GPR_HAVE_SO_NOSIGPIPE 1
 #define GPR_HAVE_UNIX_SOCKET 1
 #define GPR_HAVE_IP_PKTINFO 1
@@ -386,19 +391,19 @@
 
 /* Validate platform combinations */
 #if defined(GPR_GCC_ATOMIC) + defined(GPR_GCC_SYNC) + \
-        defined(GPR_WIN32_ATOMIC) !=                  \
+        defined(GPR_WINDOWS_ATOMIC) !=                \
     1
-#error Must define exactly one of GPR_GCC_ATOMIC, GPR_GCC_SYNC, GPR_WIN32_ATOMIC
+#error Must define exactly one of GPR_GCC_ATOMIC, GPR_GCC_SYNC, GPR_WINDOWS_ATOMIC
 #endif
 
 #if defined(GPR_ARCH_32) + defined(GPR_ARCH_64) != 1
 #error Must define exactly one of GPR_ARCH_32, GPR_ARCH_64
 #endif
 
-#if defined(GPR_CPU_LINUX) + defined(GPR_CPU_POSIX) + defined(GPR_WIN32) + \
-        defined(GPR_CPU_IPHONE) + defined(GPR_CPU_CUSTOM) !=               \
+#if defined(GPR_CPU_LINUX) + defined(GPR_CPU_POSIX) + defined(GPR_WINDOWS) + \
+        defined(GPR_CPU_IPHONE) + defined(GPR_CPU_CUSTOM) !=                 \
     1
-#error Must define exactly one of GPR_CPU_LINUX, GPR_CPU_POSIX, GPR_WIN32, GPR_CPU_IPHONE, GPR_CPU_CUSTOM
+#error Must define exactly one of GPR_CPU_LINUX, GPR_CPU_POSIX, GPR_WINDOWS, GPR_CPU_IPHONE, GPR_CPU_CUSTOM
 #endif
 
 #if defined(GPR_POSIX_MULTIPOLL_WITH_POLL) && !defined(GPR_POSIX_SOCKET)
diff --git a/include/grpc/impl/codegen/sync.h b/include/grpc/impl/codegen/sync.h
index 6fd7d64..5542482 100644
--- a/include/grpc/impl/codegen/sync.h
+++ b/include/grpc/impl/codegen/sync.h
@@ -58,8 +58,8 @@
 
 #if defined(GPR_POSIX_SYNC)
 #include <grpc/impl/codegen/sync_posix.h>
-#elif defined(GPR_WIN32)
-#include <grpc/impl/codegen/sync_win32.h>
+#elif defined(GPR_WINDOWS)
+#include <grpc/impl/codegen/sync_windows.h>
 #elif !defined(GPR_CUSTOM_SYNC)
 #error Unable to determine platform for sync
 #endif
diff --git a/include/grpc/impl/codegen/sync_win32.h b/include/grpc/impl/codegen/sync_windows.h
similarity index 93%
rename from include/grpc/impl/codegen/sync_win32.h
rename to include/grpc/impl/codegen/sync_windows.h
index bdc43dd..aa4e515 100644
--- a/include/grpc/impl/codegen/sync_win32.h
+++ b/include/grpc/impl/codegen/sync_windows.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_IMPL_CODEGEN_SYNC_WIN32_H
-#define GRPC_IMPL_CODEGEN_SYNC_WIN32_H
+#ifndef GRPC_IMPL_CODEGEN_SYNC_WINDOWS_H
+#define GRPC_IMPL_CODEGEN_SYNC_WINDOWS_H
 
 #include <grpc/impl/codegen/sync_generic.h>
 
@@ -46,4 +46,4 @@
 typedef INIT_ONCE gpr_once;
 #define GPR_ONCE_INIT INIT_ONCE_STATIC_INIT
 
-#endif /* GRPC_IMPL_CODEGEN_SYNC_WIN32_H */
+#endif /* GRPC_IMPL_CODEGEN_SYNC_WINDOWS_H */
diff --git a/include/grpc/support/atm_win32.h b/include/grpc/support/atm_windows.h
similarity index 90%
rename from include/grpc/support/atm_win32.h
rename to include/grpc/support/atm_windows.h
index 13526d9..6aec5b7 100644
--- a/include/grpc/support/atm_win32.h
+++ b/include/grpc/support/atm_windows.h
@@ -31,9 +31,9 @@
  *
  */
 
-#ifndef GRPC_SUPPORT_ATM_WIN32_H
-#define GRPC_SUPPORT_ATM_WIN32_H
+#ifndef GRPC_SUPPORT_ATM_WINDOWS_H
+#define GRPC_SUPPORT_ATM_WINDOWS_H
 
-#include <grpc/impl/codegen/atm_win32.h>
+#include <grpc/impl/codegen/atm_windows.h>
 
-#endif /* GRPC_SUPPORT_ATM_WIN32_H */
+#endif /* GRPC_SUPPORT_ATM_WINDOWS_H */
diff --git a/include/grpc/support/log_win32.h b/include/grpc/support/log_windows.h
similarity index 94%
rename from include/grpc/support/log_win32.h
rename to include/grpc/support/log_windows.h
index e5c25e0..12bf8cc 100644
--- a/include/grpc/support/log_win32.h
+++ b/include/grpc/support/log_windows.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_SUPPORT_LOG_WIN32_H
-#define GRPC_SUPPORT_LOG_WIN32_H
+#ifndef GRPC_SUPPORT_LOG_WINDOWS_H
+#define GRPC_SUPPORT_LOG_WINDOWS_H
 
 #ifdef __cplusplus
 extern "C" {
@@ -48,4 +48,4 @@
 }
 #endif
 
-#endif /* GRPC_SUPPORT_LOG_WIN32_H */
+#endif /* GRPC_SUPPORT_LOG_WINDOWS_H */
diff --git a/include/grpc/support/sync_win32.h b/include/grpc/support/sync_win32.h
deleted file mode 100644
index 5631c52..0000000
--- a/include/grpc/support/sync_win32.h
+++ /dev/null
@@ -1,39 +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_SUPPORT_SYNC_WIN32_H
-#define GRPC_SUPPORT_SYNC_WIN32_H
-
-#include <grpc/impl/codegen/sync_win32.h>
-
-#endif /* GRPC_SUPPORT_SYNC_WIN32_H */
diff --git a/include/grpc/support/atm_win32.h b/include/grpc/support/sync_windows.h
similarity index 90%
copy from include/grpc/support/atm_win32.h
copy to include/grpc/support/sync_windows.h
index 13526d9..0624e0c 100644
--- a/include/grpc/support/atm_win32.h
+++ b/include/grpc/support/sync_windows.h
@@ -31,9 +31,9 @@
  *
  */
 
-#ifndef GRPC_SUPPORT_ATM_WIN32_H
-#define GRPC_SUPPORT_ATM_WIN32_H
+#ifndef GRPC_SUPPORT_SYNC_WINDOWS_H
+#define GRPC_SUPPORT_SYNC_WINDOWS_H
 
-#include <grpc/impl/codegen/atm_win32.h>
+#include <grpc/impl/codegen/sync_windows.h>
 
-#endif /* GRPC_SUPPORT_ATM_WIN32_H */
+#endif /* GRPC_SUPPORT_SYNC_WINDOWS_H */
diff --git a/package.xml b/package.xml
index 507a2a7..9fa63e3 100644
--- a/package.xml
+++ b/package.xml
@@ -54,14 +54,14 @@
     <file baseinstalldir="/" name="include/grpc/support/atm.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/support/atm_gcc_atomic.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/support/atm_gcc_sync.h" role="src" />
-    <file baseinstalldir="/" name="include/grpc/support/atm_win32.h" role="src" />
+    <file baseinstalldir="/" name="include/grpc/support/atm_windows.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/support/avl.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/support/cmdline.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/support/cpu.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/support/histogram.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/support/host_port.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/support/log.h" role="src" />
-    <file baseinstalldir="/" name="include/grpc/support/log_win32.h" role="src" />
+    <file baseinstalldir="/" name="include/grpc/support/log_windows.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/support/port_platform.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/support/slice.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/support/slice_buffer.h" role="src" />
@@ -70,7 +70,7 @@
     <file baseinstalldir="/" name="include/grpc/support/sync.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/support/sync_generic.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/support/sync_posix.h" role="src" />
-    <file baseinstalldir="/" name="include/grpc/support/sync_win32.h" role="src" />
+    <file baseinstalldir="/" name="include/grpc/support/sync_windows.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/support/thd.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/support/time.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/support/tls.h" role="src" />
@@ -82,7 +82,7 @@
     <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_win32.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/port_platform.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/impl/codegen/slice.h" role="src" />
@@ -90,7 +90,7 @@
     <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_win32.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" />
@@ -100,7 +100,7 @@
     <file baseinstalldir="/" name="src/core/lib/support/murmur_hash.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_win32.h" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/support/string_windows.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/support/thd_internal.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/support/time_precise.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/support/tmpfile.h" role="src" />
@@ -116,7 +116,7 @@
     <file baseinstalldir="/" name="src/core/lib/support/cpu_windows.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/support/env_linux.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/support/env_posix.c" role="src" />
-    <file baseinstalldir="/" name="src/core/lib/support/env_win32.c" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/support/env_windows.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/support/histogram.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/support/host_port.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/support/load_file.c" role="src" />
@@ -124,36 +124,37 @@
     <file baseinstalldir="/" name="src/core/lib/support/log_android.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/support/log_linux.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/support/log_posix.c" role="src" />
-    <file baseinstalldir="/" name="src/core/lib/support/log_win32.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/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" />
     <file baseinstalldir="/" name="src/core/lib/support/string.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/support/string_posix.c" role="src" />
-    <file baseinstalldir="/" name="src/core/lib/support/string_util_win32.c" role="src" />
-    <file baseinstalldir="/" name="src/core/lib/support/string_win32.c" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/support/string_util_windows.c" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/support/string_windows.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/support/subprocess_posix.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/support/subprocess_windows.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/support/sync.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/support/sync_posix.c" role="src" />
-    <file baseinstalldir="/" name="src/core/lib/support/sync_win32.c" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/support/sync_windows.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/support/thd.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/support/thd_posix.c" role="src" />
-    <file baseinstalldir="/" name="src/core/lib/support/thd_win32.c" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/support/thd_windows.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/support/time.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/support/time_posix.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/support/time_precise.c" role="src" />
-    <file baseinstalldir="/" name="src/core/lib/support/time_win32.c" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/support/time_windows.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/support/tls_pthread.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/support/tmpfile_msys.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/support/tmpfile_posix.c" role="src" />
-    <file baseinstalldir="/" name="src/core/lib/support/tmpfile_win32.c" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/support/tmpfile_windows.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/support/wrap_memcpy.c" role="src" />
     <file baseinstalldir="/" name="include/grpc/byte_buffer.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/byte_buffer_reader.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/compression.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/grpc.h" role="src" />
+    <file baseinstalldir="/" name="include/grpc/grpc_posix.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" />
@@ -166,7 +167,7 @@
     <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_win32.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/port_platform.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/impl/codegen/slice.h" role="src" />
@@ -174,9 +175,8 @@
     <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_win32.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_cronet.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/grpc_security.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/grpc_security_constants.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/census.h" role="src" />
@@ -197,6 +197,7 @@
     <file baseinstalldir="/" name="src/core/lib/iomgr/closure.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/endpoint.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/endpoint_pair.h" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/iomgr/ev_poll_and_epoll_posix.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/ev_poll_posix.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/ev_posix.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/exec_ctx.h" role="src" />
@@ -205,6 +206,7 @@
     <file baseinstalldir="/" name="src/core/lib/iomgr/iomgr.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/iomgr_internal.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/iomgr_posix.h" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/iomgr/polling_entity.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/pollset.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/pollset_set.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/pollset_set_windows.h" role="src" />
@@ -213,7 +215,7 @@
     <file baseinstalldir="/" name="src/core/lib/iomgr/sockaddr.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/sockaddr_posix.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/sockaddr_utils.h" role="src" />
-    <file baseinstalldir="/" name="src/core/lib/iomgr/sockaddr_win32.h" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/iomgr/sockaddr_windows.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/socket_utils_posix.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/socket_windows.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/tcp_client.h" role="src" />
@@ -313,16 +315,18 @@
     <file baseinstalldir="/" name="src/core/ext/client_config/subchannel_call_holder.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/client_config/subchannel_index.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/client_config/uri_parser.h" role="src" />
-    <file baseinstalldir="/" name="third_party/objective_c/Cronet/cronet_c_for_grpc.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/lb_policy/grpclb/load_balancer_api.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h" role="src" />
     <file baseinstalldir="/" name="third_party/nanopb/pb.h" role="src" />
     <file baseinstalldir="/" name="third_party/nanopb/pb_common.h" role="src" />
     <file baseinstalldir="/" name="third_party/nanopb/pb_decode.h" role="src" />
     <file baseinstalldir="/" name="third_party/nanopb/pb_encode.h" role="src" />
+    <file baseinstalldir="/" name="src/core/ext/load_reporting/load_reporting.h" role="src" />
+    <file baseinstalldir="/" name="src/core/ext/load_reporting/load_reporting_filter.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/census/aggregation.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/census/census_interface.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/census/census_rpc_stats.h" role="src" />
+    <file baseinstalldir="/" name="src/core/ext/census/gen/census.pb.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/census/grpc_filter.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/census/mlog.h" role="src" />
     <file baseinstalldir="/" name="src/core/ext/census/rpc_metric_id.h" role="src" />
@@ -334,7 +338,7 @@
     <file baseinstalldir="/" name="src/core/lib/channel/connected_channel.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/channel/http_client_filter.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/channel/http_server_filter.c" role="src" />
-    <file baseinstalldir="/" name="src/core/lib/compression/compression_algorithm.c" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/compression/compression.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/compression/message_compress.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/debug/trace.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/http/format_request.c" role="src" />
@@ -344,6 +348,7 @@
     <file baseinstalldir="/" name="src/core/lib/iomgr/endpoint.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/endpoint_pair_posix.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/endpoint_pair_windows.c" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/iomgr/ev_poll_and_epoll_posix.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/ev_poll_posix.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/ev_posix.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/exec_ctx.c" role="src" />
@@ -352,6 +357,7 @@
     <file baseinstalldir="/" name="src/core/lib/iomgr/iomgr.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/iomgr_posix.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/iomgr_windows.c" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/iomgr/polling_entity.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/pollset_set_windows.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/pollset_windows.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/iomgr/resolve_address_posix.c" role="src" />
@@ -438,7 +444,7 @@
     <file baseinstalldir="/" name="src/core/lib/security/credentials/credentials_metadata.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/security/credentials/fake/fake_credentials.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/security/credentials/google_default/credentials_posix.c" role="src" />
-    <file baseinstalldir="/" name="src/core/lib/security/credentials/google_default/credentials_win32.c" role="src" />
+    <file baseinstalldir="/" name="src/core/lib/security/credentials/google_default/credentials_windows.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/security/credentials/google_default/google_default_credentials.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/security/credentials/iam/iam_credentials.c" role="src" />
     <file baseinstalldir="/" name="src/core/lib/security/credentials/jwt/json_token.c" role="src" />
@@ -479,10 +485,9 @@
     <file baseinstalldir="/" name="src/core/ext/client_config/subchannel_index.c" role="src" />
     <file baseinstalldir="/" name="src/core/ext/client_config/uri_parser.c" role="src" />
     <file baseinstalldir="/" name="src/core/ext/transport/chttp2/server/insecure/server_chttp2.c" role="src" />
+    <file baseinstalldir="/" name="src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.c" role="src" />
     <file baseinstalldir="/" name="src/core/ext/transport/chttp2/client/insecure/channel_create.c" role="src" />
-    <file baseinstalldir="/" name="src/core/ext/transport/cronet/client/secure/cronet_channel_create.c" role="src" />
-    <file baseinstalldir="/" name="src/core/ext/transport/cronet/transport/cronet_api_dummy.c" role="src" />
-    <file baseinstalldir="/" name="src/core/ext/transport/cronet/transport/cronet_transport.c" role="src" />
+    <file baseinstalldir="/" name="src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c" role="src" />
     <file baseinstalldir="/" name="src/core/ext/lb_policy/grpclb/load_balancer_api.c" role="src" />
     <file baseinstalldir="/" name="src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c" role="src" />
     <file baseinstalldir="/" name="third_party/nanopb/pb_common.c" role="src" />
@@ -492,7 +497,10 @@
     <file baseinstalldir="/" name="src/core/ext/lb_policy/round_robin/round_robin.c" role="src" />
     <file baseinstalldir="/" name="src/core/ext/resolver/dns/native/dns_resolver.c" role="src" />
     <file baseinstalldir="/" name="src/core/ext/resolver/sockaddr/sockaddr_resolver.c" role="src" />
+    <file baseinstalldir="/" name="src/core/ext/load_reporting/load_reporting.c" role="src" />
+    <file baseinstalldir="/" name="src/core/ext/load_reporting/load_reporting_filter.c" role="src" />
     <file baseinstalldir="/" name="src/core/ext/census/context.c" role="src" />
+    <file baseinstalldir="/" name="src/core/ext/census/gen/census.pb.c" role="src" />
     <file baseinstalldir="/" name="src/core/ext/census/grpc_context.c" role="src" />
     <file baseinstalldir="/" name="src/core/ext/census/grpc_filter.c" role="src" />
     <file baseinstalldir="/" name="src/core/ext/census/grpc_plugin.c" role="src" />
diff --git a/setup.py b/setup.py
index f96824f..e2de96d 100644
--- a/setup.py
+++ b/setup.py
@@ -33,9 +33,11 @@
 import os.path
 import shutil
 import sys
+import sysconfig
 
 from distutils import core as _core
 from distutils import extension as _extension
+import pkg_resources
 import setuptools
 from setuptools.command import egg_info
 
@@ -110,6 +112,16 @@
   DEFINE_MACROS += (('PyMODINIT_FUNC', pymodinit),)
 
 
+# By default, Python3 distutils enforces compatibility of
+# c plugins (.so files) with the OSX version Python3 was built with.
+# For Python3.4, this is OSX 10.6, but we need Thread Local Support (__thread)
+if 'darwin' in sys.platform and PY3:
+  mac_target = sysconfig.get_config_var('MACOSX_DEPLOYMENT_TARGET')
+  if mac_target and (pkg_resources.parse_version(mac_target) <
+                     pkg_resources.parse_version('10.7.0')):
+    os.environ['MACOSX_DEPLOYMENT_TARGET'] = '10.7'
+
+
 def cython_extensions(module_names, extra_sources, include_dirs,
                       libraries, define_macros, build_with_cython=False):
   # Set compiler directives linetrace argument only if we care about tracing;
@@ -202,7 +214,7 @@
 }
 
 TESTS_REQUIRE = (
-    'oauth2client>=1.4.7',
+    'oauth2client>=2.1.0',
     'protobuf>=3.0.0a3',
     'coverage>=4.0',
 ) + INSTALL_REQUIRES
@@ -234,8 +246,7 @@
   ext_modules=CYTHON_EXTENSION_MODULES,
   packages=list(PACKAGES),
   package_dir=PACKAGE_DIRECTORIES,
-  # TODO(atash): Figure out why auditwheel doesn't like namespace packages.
-  #namespace_packages=['grpc'],
+  namespace_packages=['grpc'],
   package_data=PACKAGE_DATA,
   install_requires=INSTALL_REQUIRES,
   setup_requires=SETUP_REQUIRES,
diff --git a/src/compiler/config.h b/src/compiler/config.h
index d8b9581..1cbd842 100644
--- a/src/compiler/config.h
+++ b/src/compiler/config.h
@@ -34,19 +34,7 @@
 #ifndef SRC_COMPILER_CONFIG_H
 #define SRC_COMPILER_CONFIG_H
 
-#include <grpc++/support/config.h>
-#include <grpc++/support/config_protobuf.h>
-
-#ifndef GRPC_CUSTOM_DESCRIPTOR
-#include <google/protobuf/descriptor.h>
-#include <google/protobuf/descriptor.pb.h>
-#define GRPC_CUSTOM_DESCRIPTOR ::google::protobuf::Descriptor
-#define GRPC_CUSTOM_FILEDESCRIPTOR ::google::protobuf::FileDescriptor
-#define GRPC_CUSTOM_FILEDESCRIPTORPROTO ::google::protobuf::FileDescriptorProto
-#define GRPC_CUSTOM_METHODDESCRIPTOR ::google::protobuf::MethodDescriptor
-#define GRPC_CUSTOM_SERVICEDESCRIPTOR ::google::protobuf::ServiceDescriptor
-#define GRPC_CUSTOM_SOURCELOCATION ::google::protobuf::SourceLocation
-#endif
+#include <grpc++/impl/codegen/config_protobuf.h>
 
 #ifndef GRPC_CUSTOM_CODEGENERATOR
 #include <google/protobuf/compiler/code_generator.h>
@@ -75,14 +63,17 @@
 #define GRPC_CUSTOM_PARSEGENERATORPARAMETER ::google::protobuf::compiler::ParseGeneratorParameter
 #endif
 
+#ifndef GRPC_CUSTOM_STRING
+#include <string>
+#define GRPC_CUSTOM_STRING std::string
+#endif
+
 namespace grpc {
+
+typedef GRPC_CUSTOM_STRING string;
+
 namespace protobuf {
-typedef GRPC_CUSTOM_DESCRIPTOR Descriptor;
-typedef GRPC_CUSTOM_FILEDESCRIPTOR FileDescriptor;
-typedef GRPC_CUSTOM_FILEDESCRIPTORPROTO FileDescriptorProto;
-typedef GRPC_CUSTOM_METHODDESCRIPTOR MethodDescriptor;
-typedef GRPC_CUSTOM_SERVICEDESCRIPTOR ServiceDescriptor;
-typedef GRPC_CUSTOM_SOURCELOCATION SourceLocation;
+
 namespace compiler {
 typedef GRPC_CUSTOM_CODEGENERATOR CodeGenerator;
 typedef GRPC_CUSTOM_GENERATORCONTEXT GeneratorContext;
diff --git a/src/compiler/cpp_generator_helpers.h b/src/compiler/cpp_generator_helpers.h
index be68cbe..87e278f 100644
--- a/src/compiler/cpp_generator_helpers.h
+++ b/src/compiler/cpp_generator_helpers.h
@@ -65,6 +65,13 @@
   }
 }
 
+// Get leading or trailing comments in a string. Comment lines start with "// ".
+// Leading detached comments are put in in front of leading comments.
+template <typename DescriptorType>
+inline grpc::string GetCppComments(const DescriptorType *desc, bool leading) {
+  return grpc_generator::GetPrefixedComments(desc, leading, "//");
+}
+
 }  // namespace grpc_cpp_generator
 
 #endif  // GRPC_INTERNAL_COMPILER_CPP_GENERATOR_HELPERS_H
diff --git a/src/compiler/cpp_plugin.cc b/src/compiler/cpp_plugin.cc
index 0ec183e..fc0296c 100644
--- a/src/compiler/cpp_plugin.cc
+++ b/src/compiler/cpp_plugin.cc
@@ -43,7 +43,7 @@
 #include "src/compiler/cpp_generator_helpers.h"
 #include "src/compiler/generator_helpers.h"
 
-using grpc_generator::GetCppComments;
+using grpc_cpp_generator::GetCppComments;
 
 class ProtoBufMethod : public grpc_cpp_generator::Method {
  public:
diff --git a/src/compiler/csharp_generator.cc b/src/compiler/csharp_generator.cc
index 29c359c..fc8feaf 100644
--- a/src/compiler/csharp_generator.cc
+++ b/src/compiler/csharp_generator.cc
@@ -52,7 +52,6 @@
 using grpc::protobuf::io::Printer;
 using grpc::protobuf::io::StringOutputStream;
 using grpc_generator::MethodType;
-using grpc_generator::GetCppComments;
 using grpc_generator::GetMethodType;
 using grpc_generator::METHODTYPE_NO_STREAMING;
 using grpc_generator::METHODTYPE_CLIENT_STREAMING;
@@ -120,18 +119,10 @@
   return service->name();
 }
 
-std::string GetClientInterfaceName(const ServiceDescriptor* service) {
-  return "I" + service->name() + "Client";
-}
-
 std::string GetClientClassName(const ServiceDescriptor* service) {
   return service->name() + "Client";
 }
 
-std::string GetServerInterfaceName(const ServiceDescriptor* service) {
-  return "I" + service->name();
-}
-
 std::string GetServerClassName(const ServiceDescriptor* service) {
   return service->name() + "Base";
 }
@@ -303,86 +294,6 @@
   out->Print("\n");
 }
 
-void GenerateClientInterface(Printer* out, const ServiceDescriptor *service) {
-  out->Print("/// <summary>Client for $servicename$</summary>\n",
-             "servicename", GetServiceClassName(service));
-  out->Print("[System.Obsolete(\"Client side interfaced will be removed "
-             "in the next release. Use client class directly.\")]\n");
-  out->Print("public interface $name$\n", "name",
-             GetClientInterfaceName(service));
-  out->Print("{\n");
-  out->Indent();
-  for (int i = 0; i < service->method_count(); i++) {
-    const MethodDescriptor *method = service->method(i);
-    MethodType method_type = GetMethodType(method);
-
-    if (method_type == METHODTYPE_NO_STREAMING) {
-      // unary calls have an extra synchronous stub method
-      GenerateDocCommentBody(out, method);
-      out->Print(
-          "$response$ $methodname$($request$ request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));\n",
-          "methodname", method->name(), "request",
-          GetClassName(method->input_type()), "response",
-          GetClassName(method->output_type()));
-
-      // overload taking CallOptions as a param
-      GenerateDocCommentBody(out, method);
-      out->Print(
-          "$response$ $methodname$($request$ request, CallOptions options);\n",
-          "methodname", method->name(), "request",
-          GetClassName(method->input_type()), "response",
-          GetClassName(method->output_type()));
-    }
-
-    std::string method_name = method->name();
-    if (method_type == METHODTYPE_NO_STREAMING) {
-      method_name += "Async";  // prevent name clash with synchronous method.
-    }
-    GenerateDocCommentBody(out, method);
-    out->Print(
-        "$returntype$ $methodname$($request_maybe$Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));\n",
-        "methodname", method_name, "request_maybe",
-        GetMethodRequestParamMaybe(method), "returntype",
-        GetMethodReturnTypeClient(method));
-
-    // overload taking CallOptions as a param
-    GenerateDocCommentBody(out, method);
-    out->Print(
-        "$returntype$ $methodname$($request_maybe$CallOptions options);\n",
-        "methodname", method_name, "request_maybe",
-        GetMethodRequestParamMaybe(method), "returntype",
-        GetMethodReturnTypeClient(method));
-  }
-  out->Outdent();
-  out->Print("}\n");
-  out->Print("\n");
-}
-
-void GenerateServerInterface(Printer* out, const ServiceDescriptor *service) {
-  out->Print("/// <summary>Interface of server-side implementations of $servicename$</summary>\n",
-             "servicename", GetServiceClassName(service));
-  out->Print("[System.Obsolete(\"Service implementations should inherit"
-      " from the generated abstract base class instead.\")]\n");
-  out->Print("public interface $name$\n", "name",
-             GetServerInterfaceName(service));
-  out->Print("{\n");
-  out->Indent();
-  for (int i = 0; i < service->method_count(); i++) {
-    const MethodDescriptor *method = service->method(i);
-    GenerateDocCommentBody(out, method);
-    out->Print(
-        "$returntype$ $methodname$($request$$response_stream_maybe$, "
-        "ServerCallContext context);\n",
-        "methodname", method->name(), "returntype",
-        GetMethodReturnTypeServer(method), "request",
-        GetMethodRequestParamServer(method), "response_stream_maybe",
-        GetMethodResponseStreamMaybe(method));
-  }
-  out->Outdent();
-  out->Print("}\n");
-  out->Print("\n");
-}
-
 void GenerateServerClass(Printer* out, const ServiceDescriptor *service) {
   out->Print("/// <summary>Base class for server-side implementations of $servicename$</summary>\n",
              "servicename", GetServiceClassName(service));
@@ -415,12 +326,9 @@
 void GenerateClientStub(Printer* out, const ServiceDescriptor *service) {
   out->Print("/// <summary>Client for $servicename$</summary>\n",
              "servicename", GetServiceClassName(service));
-  out->Print("#pragma warning disable 0618\n");
   out->Print(
-      "public class $name$ : ClientBase<$name$>, $interface$\n",
-      "name", GetClientClassName(service),
-      "interface", GetClientInterfaceName(service));
-  out->Print("#pragma warning restore 0618\n");
+      "public class $name$ : ClientBase<$name$>\n",
+      "name", GetClientClassName(service));
   out->Print("{\n");
   out->Indent();
 
@@ -547,22 +455,16 @@
   out->Print("\n");
 }
 
-void GenerateBindServiceMethod(Printer* out, const ServiceDescriptor *service,
-                               bool use_server_class) {
+void GenerateBindServiceMethod(Printer* out, const ServiceDescriptor *service) {
   out->Print(
       "/// <summary>Creates service definition that can be registered with a server</summary>\n");
-  out->Print("#pragma warning disable 0618\n");
   out->Print(
-      "public static ServerServiceDefinition BindService($interface$ serviceImpl)\n",
-      "interface", use_server_class ? GetServerClassName(service) :
-          GetServerInterfaceName(service));
-  out->Print("#pragma warning restore 0618\n");
+      "public static ServerServiceDefinition BindService($implclass$ serviceImpl)\n",
+      "implclass", GetServerClassName(service));
   out->Print("{\n");
   out->Indent();
 
-  out->Print(
-      "return ServerServiceDefinition.CreateBuilder($servicenamefield$)\n",
-      "servicenamefield", GetServiceNameFieldName());
+  out->Print("return ServerServiceDefinition.CreateBuilder()\n");
   out->Indent();
   out->Indent();
   for (int i = 0; i < service->method_count(); i++) {
@@ -617,11 +519,7 @@
   }
   GenerateServiceDescriptorProperty(out, service);
 
-  if (generate_client) {
-    GenerateClientInterface(out, service);
-  }
   if (generate_server) {
-    GenerateServerInterface(out, service);
     GenerateServerClass(out, service);
   }
   if (generate_client) {
@@ -629,8 +527,7 @@
     GenerateNewStubMethods(out, service);
   }
   if (generate_server) {
-    GenerateBindServiceMethod(out, service, false);
-    GenerateBindServiceMethod(out, service, true);
+    GenerateBindServiceMethod(out, service);
   }
 
   out->Outdent();
@@ -659,7 +556,7 @@
     out.Print("// source: $filename$\n", "filename", file->name());
 
     // use C++ style as there are no file-level XML comments in .NET
-    grpc::string leading_comments = GetCppComments(file, true);
+    grpc::string leading_comments = GetCsharpComments(file, true);
     if (!leading_comments.empty()) {
       out.Print("// Original file comments:\n");
       out.Print(leading_comments.c_str());
diff --git a/src/compiler/csharp_generator_helpers.h b/src/compiler/csharp_generator_helpers.h
index 5639ea0..9bdf6fb 100644
--- a/src/compiler/csharp_generator_helpers.h
+++ b/src/compiler/csharp_generator_helpers.h
@@ -45,6 +45,13 @@
   return true;
 }
 
+// Get leading or trailing comments in a string. Comment lines start with "// ".
+// Leading detached comments are put in in front of leading comments.
+template <typename DescriptorType>
+inline grpc::string GetCsharpComments(const DescriptorType *desc, bool leading) {
+  return grpc_generator::GetPrefixedComments(desc, leading, "//");
+}
+
 }  // namespace grpc_csharp_generator
 
 #endif  // GRPC_INTERNAL_COMPILER_CSHARP_GENERATOR_HELPERS_H
diff --git a/src/compiler/generator_helpers.h b/src/compiler/generator_helpers.h
index bd077cf..53391bc 100644
--- a/src/compiler/generator_helpers.h
+++ b/src/compiler/generator_helpers.h
@@ -265,10 +265,10 @@
   return oss.str();
 }
 
-// Get leading or trailing comments in a string. Comment lines start with "// ".
-// Leading detached comments are put in in front of leading comments.
 template <typename DescriptorType>
-inline grpc::string GetCppComments(const DescriptorType *desc, bool leading) {
+inline grpc::string GetPrefixedComments(const DescriptorType *desc,
+                                        bool leading,
+                                        const grpc::string &prefix) {
   std::vector<grpc::string> out;
   if (leading) {
     grpc_generator::GetComment(
@@ -281,7 +281,7 @@
     grpc_generator::GetComment(desc, grpc_generator::COMMENTTYPE_TRAILING,
                                &out);
   }
-  return GenerateCommentsWithPrefix(out, "//");
+  return GenerateCommentsWithPrefix(out, prefix);
 }
 
 }  // namespace grpc_generator
diff --git a/src/compiler/node_generator.cc b/src/compiler/node_generator.cc
index 822622c..986b97c 100644
--- a/src/compiler/node_generator.cc
+++ b/src/compiler/node_generator.cc
@@ -181,26 +181,67 @@
 // Prints out the service descriptor object
 void PrintService(const ServiceDescriptor *service, Printer *out) {
   map<grpc::string, grpc::string> template_vars;
+  out->Print(GetNodeComments(service, true).c_str());
   template_vars["name"] = service->name();
   out->Print(template_vars, "var $name$Service = exports.$name$Service = {\n");
   out->Indent();
   for (int i = 0; i < service->method_count(); i++) {
     grpc::string method_name = grpc_generator::LowercaseFirstLetter(
         service->method(i)->name());
+    out->Print(GetNodeComments(service->method(i), true).c_str());
     out->Print("$method_name$: ",
                "method_name", method_name);
     PrintMethod(service->method(i), out);
     out->Print(",\n");
+    out->Print(GetNodeComments(service->method(i), false).c_str());
   }
   out->Outdent();
   out->Print("};\n\n");
   out->Print(template_vars, "exports.$name$Client = "
              "grpc.makeGenericClientConstructor($name$Service);\n");
+  out->Print(GetNodeComments(service, false).c_str());
+}
+
+void PrintImports(const FileDescriptor *file, Printer *out) {
+  out->Print("var grpc = require('grpc');\n");
+  if (file->message_type_count() > 0) {
+    grpc::string file_path = GetRelativePath(file->name(),
+                                             GetJSMessageFilename(
+                                                 file->name()));
+    out->Print("var $module_alias$ = require('$file_path$');\n",
+               "module_alias", ModuleAlias(file->name()),
+               "file_path", file_path);
+  }
+
+  for (int i = 0; i < file->dependency_count(); i++) {
+    grpc::string file_path = GetRelativePath(
+        file->name(), GetJSMessageFilename(file->dependency(i)->name()));
+    out->Print("var $module_alias$ = require('$file_path$');\n",
+               "module_alias", ModuleAlias(file->dependency(i)->name()),
+               "file_path", file_path);
+  }
+  out->Print("\n");
+}
+
+void PrintTransformers(const FileDescriptor *file, Printer *out) {
+  map<grpc::string, const Descriptor*> messages = GetAllMessages(file);
+  for (std::map<grpc::string, const Descriptor*>::iterator it =
+           messages.begin();
+       it != messages.end(); it++) {
+    PrintMessageTransformer(it->second, out);
+  }
+  out->Print("\n");
+}
+
+void PrintServices(const FileDescriptor *file, Printer *out) {
+  for (int i = 0; i < file->service_count(); i++) {
+    PrintService(file->service(i), out);
+  }
 }
 
 }
 
-grpc::string GetImports(const FileDescriptor *file) {
+grpc::string GenerateFile(const FileDescriptor *file) {
   grpc::string output;
   {
     StringOutputStream output_stream(&output);
@@ -209,67 +250,23 @@
     if (file->service_count() == 0) {
       return output;
     }
-
     out.Print("// GENERATED CODE -- DO NOT EDIT!\n\n");
 
+    grpc::string leading_comments = GetNodeComments(file, true);
+    if (!leading_comments.empty()) {
+      out.Print("// Original file comments:\n");
+      out.Print(leading_comments.c_str());
+    }
+
     out.Print("'use strict';\n");
 
-    out.Print("var grpc = require('grpc');\n");
-    if (file->message_type_count() > 0) {
-      grpc::string file_path = GetRelativePath(file->name(),
-                                               GetJSMessageFilename(
-                                                   file->name()));
-      out.Print("var $module_alias$ = require('$file_path$');\n",
-                "module_alias", ModuleAlias(file->name()),
-                "file_path", file_path);
-    }
+    PrintImports(file, &out);
 
-    for (int i = 0; i < file->dependency_count(); i++) {
-      grpc::string file_path = GetRelativePath(
-          file->name(), GetJSMessageFilename(file->dependency(i)->name()));
-      out.Print("var $module_alias$ = require('$file_path$');\n",
-                "module_alias", ModuleAlias(file->dependency(i)->name()),
-                "file_path", file_path);
-    }
-    out.Print("\n");
-  }
-  return output;
-}
+    PrintTransformers(file, &out);
 
-grpc::string GetTransformers(const FileDescriptor *file) {
-  grpc::string output;
-  {
-    StringOutputStream output_stream(&output);
-    Printer out(&output_stream, '$');
+    PrintServices(file, &out);
 
-    if (file->service_count() == 0) {
-      return output;
-    }
-
-    map<grpc::string, const Descriptor*> messages = GetAllMessages(file);
-    for (std::map<grpc::string, const Descriptor*>::iterator it =
-             messages.begin();
-         it != messages.end(); it++) {
-      PrintMessageTransformer(it->second, &out);
-    }
-    out.Print("\n");
-  }
-  return output;
-}
-
-grpc::string GetServices(const FileDescriptor *file) {
-  grpc::string output;
-  {
-    StringOutputStream output_stream(&output);
-    Printer out(&output_stream, '$');
-
-    if (file->service_count() == 0) {
-      return output;
-    }
-
-    for (int i = 0; i < file->service_count(); i++) {
-      PrintService(file->service(i), &out);
-    }
+    out.Print(GetNodeComments(file, false).c_str());
   }
   return output;
 }
diff --git a/src/compiler/node_generator.h b/src/compiler/node_generator.h
index 249a0d0..d7765e2 100644
--- a/src/compiler/node_generator.h
+++ b/src/compiler/node_generator.h
@@ -38,11 +38,7 @@
 
 namespace grpc_node_generator {
 
-grpc::string GetImports(const grpc::protobuf::FileDescriptor *file);
-
-grpc::string GetTransformers(const grpc::protobuf::FileDescriptor *file);
-
-grpc::string GetServices(const grpc::protobuf::FileDescriptor *file);
+grpc::string GenerateFile(const grpc::protobuf::FileDescriptor *file);
 
 }  // namespace grpc_node_generator
 
diff --git a/src/compiler/node_generator_helpers.h b/src/compiler/node_generator_helpers.h
index f41a2bc..5862772 100644
--- a/src/compiler/node_generator_helpers.h
+++ b/src/compiler/node_generator_helpers.h
@@ -45,6 +45,13 @@
   return grpc_generator::StripProto(filename) + "_grpc_pb.js";
 }
 
+// Get leading or trailing comments in a string. Comment lines start with "// ".
+// Leading detached comments are put in in front of leading comments.
+template <typename DescriptorType>
+inline grpc::string GetNodeComments(const DescriptorType *desc, bool leading) {
+  return grpc_generator::GetPrefixedComments(desc, leading, "//");
+}
+
 }  // namespace grpc_node_generator
 
 #endif  // GRPC_INTERNAL_COMPILER_NODE_GENERATOR_HELPERS_H
diff --git a/src/compiler/node_plugin.cc b/src/compiler/node_plugin.cc
index ac5ced3..39dfa77 100644
--- a/src/compiler/node_plugin.cc
+++ b/src/compiler/node_plugin.cc
@@ -39,10 +39,8 @@
 #include "src/compiler/node_generator.h"
 #include "src/compiler/node_generator_helpers.h"
 
-using grpc_node_generator::GetImports;
+using grpc_node_generator::GenerateFile;
 using grpc_node_generator::GetJSServiceFilename;
-using grpc_node_generator::GetServices;
-using grpc_node_generator::GetTransformers;
 
 class NodeGrpcGenerator : public grpc::protobuf::compiler::CodeGenerator {
  public:
@@ -53,9 +51,7 @@
                 const grpc::string &parameter,
                 grpc::protobuf::compiler::GeneratorContext *context,
                 grpc::string *error) const {
-    grpc::string code = GetImports(file) +
-        GetTransformers(file) +
-        GetServices(file);
+    grpc::string code = GenerateFile(file);
     if (code.size() == 0) {
       return true;
     }
diff --git a/src/compiler/objective_c_generator.cc b/src/compiler/objective_c_generator.cc
index 465491e..4be8cb4 100644
--- a/src/compiler/objective_c_generator.cc
+++ b/src/compiler/objective_c_generator.cc
@@ -60,9 +60,34 @@
                  " returns ($server_stream$$response_type$)\n\n");
 }
 
+template <typename DescriptorType>
+static void PrintAllComments(const DescriptorType* desc, Printer* printer) {
+  std::vector<grpc::string> comments;
+  grpc_generator::GetComment(desc, grpc_generator::COMMENTTYPE_LEADING_DETACHED,
+                             &comments);
+  grpc_generator::GetComment(desc, grpc_generator::COMMENTTYPE_LEADING,
+                             &comments);
+  grpc_generator::GetComment(desc, grpc_generator::COMMENTTYPE_TRAILING,
+                             &comments);
+  if (comments.empty()) {
+    return;
+  }
+  printer->Print("/**\n");
+  for (auto it = comments.begin(); it != comments.end(); ++it) {
+    printer->Print(" * ");
+    size_t start_pos = it->find_first_not_of(' ');
+    if (start_pos != grpc::string::npos) {
+      printer->Print(it->c_str() + start_pos);
+    }
+    printer->Print("\n");
+  }
+  printer->Print(" */\n");
+}
+
 void PrintMethodSignature(Printer *printer, const MethodDescriptor *method,
                           const map< ::grpc::string, ::grpc::string> &vars) {
-  // TODO(jcanizales): Print method comments.
+  // Print comment
+  PrintAllComments(method, printer);
 
   printer->Print(vars, "- ($return_type$)$method_name$With");
   if (method->client_streaming()) {
@@ -94,7 +119,7 @@
 void PrintAdvancedSignature(Printer *printer, const MethodDescriptor *method,
                             map< ::grpc::string, ::grpc::string> vars) {
   vars["method_name"] = "RPCTo" + vars["method_name"];
-  vars["return_type"] = "ProtoRPC *";
+  vars["return_type"] = "GRPCProtoCall *";
   PrintMethodSignature(printer, method, vars);
 }
 
@@ -195,11 +220,13 @@
     printer.Print("@end\n\n");
 
     printer.Print(
-        "// Basic service implementation, over gRPC, that only does"
-        " marshalling and parsing.\n");
+        "/**\n"
+        " * Basic service implementation, over gRPC, that only does\n"
+        " * marshalling and parsing.\n"
+        " */\n");
     printer.Print(vars,
                   "@interface $service_class$ :"
-                  " ProtoService<$service_class$>\n");
+                  " GRPCProtoService<$service_class$>\n");
     printer.Print(
         "- (instancetype)initWithHost:(NSString *)host"
         " NS_DESIGNATED_INITIALIZER;\n");
@@ -220,18 +247,13 @@
                                 {"service_class", ServiceClassName(service)},
                                 {"package", service->file()->package()}};
 
-    printer.Print(vars,
-                  "static NSString *const kPackageName = @\"$package$\";\n");
-    printer.Print(
-        vars, "static NSString *const kServiceName = @\"$service_name$\";\n\n");
-
     printer.Print(vars, "@implementation $service_class$\n\n");
 
     printer.Print("// Designated initializer\n");
     printer.Print("- (instancetype)initWithHost:(NSString *)host {\n");
-    printer.Print(
+    printer.Print(vars,
         "  return (self = [super initWithHost:host"
-        " packageName:kPackageName serviceName:kServiceName]);\n");
+        " packageName:@\"$package$\" serviceName:@\"$service_name$\"]);\n");
     printer.Print("}\n\n");
     printer.Print(
         "// Override superclass initializer to disallow different"
diff --git a/src/compiler/ruby_generator.cc b/src/compiler/ruby_generator.cc
index 936a186..1501c3f 100644
--- a/src/compiler/ruby_generator.cc
+++ b/src/compiler/ruby_generator.cc
@@ -66,7 +66,9 @@
   std::map<grpc::string, grpc::string> method_vars =
       ListToDict({"mth.name", method->name(), "input.type", input_type,
                   "output.type", output_type, });
+  out->Print(GetRubyComments(method, true).c_str());
   out->Print(method_vars, "rpc :$mth.name$, $input.type$, $output.type$\n");
+  out->Print(GetRubyComments(method, false).c_str());
 }
 
 // Prints out the service using the ruby gRPC DSL.
@@ -82,12 +84,7 @@
   out->Print(module_vars, "module $module.name$\n");
   out->Indent();
 
-  // TODO(temiola): add documentation
-  grpc::string doc = "TODO: add proto service documentation here";
-  std::map<grpc::string, grpc::string> template_vars =
-      ListToDict({"Documentation", doc, });
-  out->Print("\n");
-  out->Print(template_vars, "# $Documentation$\n");
+  out->Print(GetRubyComments(service, true).c_str());
   out->Print("class Service\n");
 
   // Write the indented class body.
@@ -113,6 +110,7 @@
   // End the service module
   out->Outdent();
   out->Print("end\n");
+  out->Print(GetRubyComments(service, false).c_str());
 }
 
 }  // namespace
@@ -138,6 +136,12 @@
     out.Print(header_comment_vars,
               "# Source: $file.name$ for package '$file.package$'\n");
 
+    grpc::string leading_comments = GetRubyComments(file, true);
+    if (!leading_comments.empty()) {
+      out.Print("# Original file comments:\n");
+      out.Print(leading_comments.c_str());
+    }
+
     out.Print("\n");
     out.Print("require 'grpc'\n");
     // Write out require statemment to import the separately generated file
@@ -164,6 +168,8 @@
       out.Outdent();
       out.Print("end\n");
     }
+
+    out.Print(GetRubyComments(file, false).c_str());
   }
   return output;
 }
diff --git a/src/compiler/ruby_generator_helpers-inl.h b/src/compiler/ruby_generator_helpers-inl.h
index 9da7cab..ff6939e 100644
--- a/src/compiler/ruby_generator_helpers-inl.h
+++ b/src/compiler/ruby_generator_helpers-inl.h
@@ -35,6 +35,7 @@
 #define GRPC_INTERNAL_COMPILER_RUBY_GENERATOR_HELPERS_INL_H
 
 #include "src/compiler/config.h"
+#include "src/compiler/generator_helpers.h"
 #include "src/compiler/ruby_generator_string-inl.h"
 
 namespace grpc_ruby_generator {
@@ -60,6 +61,13 @@
   return Replace(file->name(), ".proto", "");
 }
 
+// Get leading or trailing comments in a string. Comment lines start with "# ".
+// Leading detached comments are put in in front of leading comments.
+template <typename DescriptorType>
+inline grpc::string GetRubyComments(const DescriptorType *desc, bool leading) {
+  return grpc_generator::GetPrefixedComments(desc, leading, "#");
+}
+
 }  // namespace grpc_ruby_generator
 
 #endif  // GRPC_INTERNAL_COMPILER_RUBY_GENERATOR_HELPERS_INL_H
diff --git a/src/core/ext/census/gen/README.md b/src/core/ext/census/gen/README.md
new file mode 100644
index 0000000..72bef65
--- /dev/null
+++ b/src/core/ext/census/gen/README.md
@@ -0,0 +1,6 @@
+Files generated for use by Census stats and trace recording subsystem.
+
+#Files
+* census.pb.{h,c} - Generated from src/core/ext/census/census.proto, using the
+  script `tools/codegen/core/gen_nano_proto.sh src/proto/census/census.proto
+  $PWD/src/core/ext/census/gen src/core/ext/census/gen`
diff --git a/src/core/ext/census/gen/census.pb.c b/src/core/ext/census/gen/census.pb.c
new file mode 100644
index 0000000..d614636
--- /dev/null
+++ b/src/core/ext/census/gen/census.pb.c
@@ -0,0 +1,179 @@
+/*
+ *
+ * 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.
+ *
+ */
+/* Automatically generated nanopb constant definitions */
+/* Generated by nanopb-0.3.5-dev */
+
+#include "src/core/ext/census/gen/census.pb.h"
+
+#if PB_PROTO_HEADER_VERSION != 30
+#error Regenerate this file with the current version of nanopb generator.
+#endif
+
+
+
+const pb_field_t google_census_Duration_fields[3] = {
+    PB_FIELD(  1, INT64   , OPTIONAL, STATIC  , FIRST, google_census_Duration, seconds, seconds, 0),
+    PB_FIELD(  2, INT32   , OPTIONAL, STATIC  , OTHER, google_census_Duration, nanos, seconds, 0),
+    PB_LAST_FIELD
+};
+
+const pb_field_t google_census_Timestamp_fields[3] = {
+    PB_FIELD(  1, INT64   , OPTIONAL, STATIC  , FIRST, google_census_Timestamp, seconds, seconds, 0),
+    PB_FIELD(  2, INT32   , OPTIONAL, STATIC  , OTHER, google_census_Timestamp, nanos, seconds, 0),
+    PB_LAST_FIELD
+};
+
+const pb_field_t google_census_Metric_fields[5] = {
+    PB_FIELD(  1, STRING  , OPTIONAL, CALLBACK, FIRST, google_census_Metric, name, name, 0),
+    PB_FIELD(  2, STRING  , OPTIONAL, CALLBACK, OTHER, google_census_Metric, description, name, 0),
+    PB_FIELD(  3, MESSAGE , OPTIONAL, STATIC  , OTHER, google_census_Metric, unit, description, &google_census_Metric_MeasurementUnit_fields),
+    PB_FIELD(  4, INT32   , OPTIONAL, STATIC  , OTHER, google_census_Metric, id, unit, 0),
+    PB_LAST_FIELD
+};
+
+const pb_field_t google_census_Metric_BasicUnit_fields[2] = {
+    PB_FIELD(  1, UENUM   , OPTIONAL, STATIC  , FIRST, google_census_Metric_BasicUnit, type, type, 0),
+    PB_LAST_FIELD
+};
+
+const pb_field_t google_census_Metric_MeasurementUnit_fields[4] = {
+    PB_FIELD(  1, INT32   , OPTIONAL, STATIC  , FIRST, google_census_Metric_MeasurementUnit, prefix, prefix, 0),
+    PB_FIELD(  2, MESSAGE , REPEATED, CALLBACK, OTHER, google_census_Metric_MeasurementUnit, numerator, prefix, &google_census_Metric_BasicUnit_fields),
+    PB_FIELD(  3, MESSAGE , REPEATED, CALLBACK, OTHER, google_census_Metric_MeasurementUnit, denominator, numerator, &google_census_Metric_BasicUnit_fields),
+    PB_LAST_FIELD
+};
+
+const pb_field_t google_census_AggregationDescriptor_fields[3] = {
+    PB_ONEOF_FIELD(options,   1, MESSAGE , ONEOF, STATIC  , FIRST, google_census_AggregationDescriptor, bucket_boundaries, bucket_boundaries, &google_census_AggregationDescriptor_BucketBoundaries_fields),
+    PB_ONEOF_FIELD(options,   2, MESSAGE , ONEOF, STATIC  , FIRST, google_census_AggregationDescriptor, interval_boundaries, interval_boundaries, &google_census_AggregationDescriptor_IntervalBoundaries_fields),
+    PB_LAST_FIELD
+};
+
+const pb_field_t google_census_AggregationDescriptor_BucketBoundaries_fields[2] = {
+    PB_FIELD(  1, DOUBLE  , REPEATED, CALLBACK, FIRST, google_census_AggregationDescriptor_BucketBoundaries, bounds, bounds, 0),
+    PB_LAST_FIELD
+};
+
+const pb_field_t google_census_AggregationDescriptor_IntervalBoundaries_fields[2] = {
+    PB_FIELD(  1, DOUBLE  , REPEATED, CALLBACK, FIRST, google_census_AggregationDescriptor_IntervalBoundaries, window_size, window_size, 0),
+    PB_LAST_FIELD
+};
+
+const pb_field_t google_census_Distribution_fields[5] = {
+    PB_FIELD(  1, INT64   , OPTIONAL, STATIC  , FIRST, google_census_Distribution, count, count, 0),
+    PB_FIELD(  2, DOUBLE  , OPTIONAL, STATIC  , OTHER, google_census_Distribution, mean, count, 0),
+    PB_FIELD(  3, MESSAGE , OPTIONAL, STATIC  , OTHER, google_census_Distribution, range, mean, &google_census_Distribution_Range_fields),
+    PB_FIELD(  4, INT64   , REPEATED, CALLBACK, OTHER, google_census_Distribution, bucket_count, range, 0),
+    PB_LAST_FIELD
+};
+
+const pb_field_t google_census_Distribution_Range_fields[3] = {
+    PB_FIELD(  1, DOUBLE  , OPTIONAL, STATIC  , FIRST, google_census_Distribution_Range, min, min, 0),
+    PB_FIELD(  2, DOUBLE  , OPTIONAL, STATIC  , OTHER, google_census_Distribution_Range, max, min, 0),
+    PB_LAST_FIELD
+};
+
+const pb_field_t google_census_IntervalStats_fields[2] = {
+    PB_FIELD(  1, MESSAGE , REPEATED, CALLBACK, FIRST, google_census_IntervalStats, window, window, &google_census_IntervalStats_Window_fields),
+    PB_LAST_FIELD
+};
+
+const pb_field_t google_census_IntervalStats_Window_fields[4] = {
+    PB_FIELD(  1, MESSAGE , OPTIONAL, STATIC  , FIRST, google_census_IntervalStats_Window, window_size, window_size, &google_census_Duration_fields),
+    PB_FIELD(  2, INT64   , OPTIONAL, STATIC  , OTHER, google_census_IntervalStats_Window, count, window_size, 0),
+    PB_FIELD(  3, DOUBLE  , OPTIONAL, STATIC  , OTHER, google_census_IntervalStats_Window, mean, count, 0),
+    PB_LAST_FIELD
+};
+
+const pb_field_t google_census_Tag_fields[3] = {
+    PB_FIELD(  1, STRING  , OPTIONAL, STATIC  , FIRST, google_census_Tag, key, key, 0),
+    PB_FIELD(  2, STRING  , OPTIONAL, STATIC  , OTHER, google_census_Tag, value, key, 0),
+    PB_LAST_FIELD
+};
+
+const pb_field_t google_census_View_fields[6] = {
+    PB_FIELD(  1, STRING  , OPTIONAL, CALLBACK, FIRST, google_census_View, name, name, 0),
+    PB_FIELD(  2, STRING  , OPTIONAL, CALLBACK, OTHER, google_census_View, description, name, 0),
+    PB_FIELD(  3, INT32   , OPTIONAL, STATIC  , OTHER, google_census_View, metric_id, description, 0),
+    PB_FIELD(  4, MESSAGE , OPTIONAL, STATIC  , OTHER, google_census_View, aggregation, metric_id, &google_census_AggregationDescriptor_fields),
+    PB_FIELD(  5, STRING  , REPEATED, CALLBACK, OTHER, google_census_View, tag_key, aggregation, 0),
+    PB_LAST_FIELD
+};
+
+const pb_field_t google_census_Aggregation_fields[6] = {
+    PB_FIELD(  1, STRING  , OPTIONAL, CALLBACK, FIRST, google_census_Aggregation, name, name, 0),
+    PB_FIELD(  2, STRING  , OPTIONAL, CALLBACK, OTHER, google_census_Aggregation, description, name, 0),
+    PB_ONEOF_FIELD(data,   3, MESSAGE , ONEOF, STATIC  , OTHER, google_census_Aggregation, distribution, description, &google_census_Distribution_fields),
+    PB_ONEOF_FIELD(data,   4, MESSAGE , ONEOF, STATIC  , OTHER, google_census_Aggregation, interval_stats, description, &google_census_IntervalStats_fields),
+    PB_FIELD(  5, MESSAGE , REPEATED, CALLBACK, OTHER, google_census_Aggregation, tag, data.interval_stats, &google_census_Tag_fields),
+    PB_LAST_FIELD
+};
+
+const pb_field_t google_census_ViewAggregations_fields[4] = {
+    PB_FIELD(  1, MESSAGE , REPEATED, CALLBACK, FIRST, google_census_ViewAggregations, aggregation, aggregation, &google_census_Aggregation_fields),
+    PB_FIELD(  2, MESSAGE , OPTIONAL, STATIC  , OTHER, google_census_ViewAggregations, start, aggregation, &google_census_Timestamp_fields),
+    PB_FIELD(  3, MESSAGE , OPTIONAL, STATIC  , OTHER, google_census_ViewAggregations, end, start, &google_census_Timestamp_fields),
+    PB_LAST_FIELD
+};
+
+
+/* Check that field information fits in pb_field_t */
+#if !defined(PB_FIELD_32BIT)
+/* If you get an error here, it means that you need to define PB_FIELD_32BIT
+ * compile-time option. You can do that in pb.h or on compiler command line.
+ * 
+ * The reason you need to do this is that some of your messages contain tag
+ * numbers or field sizes that are larger than what can fit in 8 or 16 bit
+ * field descriptors.
+ */
+PB_STATIC_ASSERT((pb_membersize(google_census_Metric, unit) < 65536 && pb_membersize(google_census_Metric_MeasurementUnit, numerator) < 65536 && pb_membersize(google_census_Metric_MeasurementUnit, denominator) < 65536 && pb_membersize(google_census_AggregationDescriptor, options.bucket_boundaries) < 65536 && pb_membersize(google_census_AggregationDescriptor, options.interval_boundaries) < 65536 && pb_membersize(google_census_Metric, unit) < 65536 && pb_membersize(google_census_Metric_MeasurementUnit, numerator) < 65536 && pb_membersize(google_census_Metric_MeasurementUnit, denominator) < 65536 && pb_membersize(google_census_AggregationDescriptor, options.bucket_boundaries) < 65536 && pb_membersize(google_census_AggregationDescriptor, options.interval_boundaries) < 65536 && pb_membersize(google_census_Distribution, range) < 65536 && pb_membersize(google_census_IntervalStats, window) < 65536 && pb_membersize(google_census_IntervalStats_Window, window_size) < 65536 && pb_membersize(google_census_View, aggregation) < 65536 && pb_membersize(google_census_Aggregation, data.distribution) < 65536 && pb_membersize(google_census_Aggregation, data.interval_stats) < 65536 && pb_membersize(google_census_Metric, unit) < 65536 && pb_membersize(google_census_Metric_MeasurementUnit, numerator) < 65536 && pb_membersize(google_census_Metric_MeasurementUnit, denominator) < 65536 && pb_membersize(google_census_AggregationDescriptor, options.bucket_boundaries) < 65536 && pb_membersize(google_census_AggregationDescriptor, options.interval_boundaries) < 65536 && pb_membersize(google_census_Metric, unit) < 65536 && pb_membersize(google_census_Metric_MeasurementUnit, numerator) < 65536 && pb_membersize(google_census_Metric_MeasurementUnit, denominator) < 65536 && pb_membersize(google_census_AggregationDescriptor, options.bucket_boundaries) < 65536 && pb_membersize(google_census_AggregationDescriptor, options.interval_boundaries) < 65536 && pb_membersize(google_census_Distribution, range) < 65536 && pb_membersize(google_census_IntervalStats, window) < 65536 && pb_membersize(google_census_IntervalStats_Window, window_size) < 65536 && pb_membersize(google_census_View, aggregation) < 65536 && pb_membersize(google_census_Aggregation, data.distribution) < 65536 && pb_membersize(google_census_Aggregation, data.interval_stats) < 65536 && pb_membersize(google_census_Aggregation, tag) < 65536 && pb_membersize(google_census_ViewAggregations, aggregation) < 65536 && pb_membersize(google_census_ViewAggregations, start) < 65536 && pb_membersize(google_census_ViewAggregations, end) < 65536), YOU_MUST_DEFINE_PB_FIELD_32BIT_FOR_MESSAGES_google_census_Duration_google_census_Timestamp_google_census_Metric_google_census_Metric_BasicUnit_google_census_Metric_MeasurementUnit_google_census_AggregationDescriptor_google_census_AggregationDescriptor_BucketBoundaries_google_census_AggregationDescriptor_IntervalBoundaries_google_census_Distribution_google_census_Distribution_Range_google_census_IntervalStats_google_census_IntervalStats_Window_google_census_Tag_google_census_View_google_census_Aggregation_google_census_ViewAggregations)
+#endif
+
+#if !defined(PB_FIELD_16BIT) && !defined(PB_FIELD_32BIT)
+/* If you get an error here, it means that you need to define PB_FIELD_16BIT
+ * compile-time option. You can do that in pb.h or on compiler command line.
+ * 
+ * The reason you need to do this is that some of your messages contain tag
+ * numbers or field sizes that are larger than what can fit in the default
+ * 8 bit descriptors.
+ */
+PB_STATIC_ASSERT((pb_membersize(google_census_Metric, unit) < 256 && pb_membersize(google_census_Metric_MeasurementUnit, numerator) < 256 && pb_membersize(google_census_Metric_MeasurementUnit, denominator) < 256 && pb_membersize(google_census_AggregationDescriptor, options.bucket_boundaries) < 256 && pb_membersize(google_census_AggregationDescriptor, options.interval_boundaries) < 256 && pb_membersize(google_census_Metric, unit) < 256 && pb_membersize(google_census_Metric_MeasurementUnit, numerator) < 256 && pb_membersize(google_census_Metric_MeasurementUnit, denominator) < 256 && pb_membersize(google_census_AggregationDescriptor, options.bucket_boundaries) < 256 && pb_membersize(google_census_AggregationDescriptor, options.interval_boundaries) < 256 && pb_membersize(google_census_Distribution, range) < 256 && pb_membersize(google_census_IntervalStats, window) < 256 && pb_membersize(google_census_IntervalStats_Window, window_size) < 256 && pb_membersize(google_census_View, aggregation) < 256 && pb_membersize(google_census_Aggregation, data.distribution) < 256 && pb_membersize(google_census_Aggregation, data.interval_stats) < 256 && pb_membersize(google_census_Metric, unit) < 256 && pb_membersize(google_census_Metric_MeasurementUnit, numerator) < 256 && pb_membersize(google_census_Metric_MeasurementUnit, denominator) < 256 && pb_membersize(google_census_AggregationDescriptor, options.bucket_boundaries) < 256 && pb_membersize(google_census_AggregationDescriptor, options.interval_boundaries) < 256 && pb_membersize(google_census_Metric, unit) < 256 && pb_membersize(google_census_Metric_MeasurementUnit, numerator) < 256 && pb_membersize(google_census_Metric_MeasurementUnit, denominator) < 256 && pb_membersize(google_census_AggregationDescriptor, options.bucket_boundaries) < 256 && pb_membersize(google_census_AggregationDescriptor, options.interval_boundaries) < 256 && pb_membersize(google_census_Distribution, range) < 256 && pb_membersize(google_census_IntervalStats, window) < 256 && pb_membersize(google_census_IntervalStats_Window, window_size) < 256 && pb_membersize(google_census_View, aggregation) < 256 && pb_membersize(google_census_Aggregation, data.distribution) < 256 && pb_membersize(google_census_Aggregation, data.interval_stats) < 256 && pb_membersize(google_census_Aggregation, tag) < 256 && pb_membersize(google_census_ViewAggregations, aggregation) < 256 && pb_membersize(google_census_ViewAggregations, start) < 256 && pb_membersize(google_census_ViewAggregations, end) < 256), YOU_MUST_DEFINE_PB_FIELD_16BIT_FOR_MESSAGES_google_census_Duration_google_census_Timestamp_google_census_Metric_google_census_Metric_BasicUnit_google_census_Metric_MeasurementUnit_google_census_AggregationDescriptor_google_census_AggregationDescriptor_BucketBoundaries_google_census_AggregationDescriptor_IntervalBoundaries_google_census_Distribution_google_census_Distribution_Range_google_census_IntervalStats_google_census_IntervalStats_Window_google_census_Tag_google_census_View_google_census_Aggregation_google_census_ViewAggregations)
+#endif
+
+
+/* On some platforms (such as AVR), double is really float.
+ * These are not directly supported by nanopb, but see example_avr_double.
+ * To get rid of this error, remove any double fields from your .proto.
+ */
+PB_STATIC_ASSERT(sizeof(double) == 8, DOUBLE_MUST_BE_8_BYTES)
+
diff --git a/src/core/ext/census/gen/census.pb.h b/src/core/ext/census/gen/census.pb.h
new file mode 100644
index 0000000..d040fe2
--- /dev/null
+++ b/src/core/ext/census/gen/census.pb.h
@@ -0,0 +1,294 @@
+/*
+ *
+ * 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.
+ *
+ */
+/* Automatically generated nanopb header */
+/* Generated by nanopb-0.3.5-dev */
+
+#ifndef GRPC_CORE_EXT_CENSUS_GEN_CENSUS_PB_H
+#define GRPC_CORE_EXT_CENSUS_GEN_CENSUS_PB_H
+#include "third_party/nanopb/pb.h"
+#if PB_PROTO_HEADER_VERSION != 30
+#error Regenerate this file with the current version of nanopb generator.
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Enum definitions */
+typedef enum _google_census_Metric_BasicUnit_Measure {
+    google_census_Metric_BasicUnit_Measure_UNKNOWN = 0,
+    google_census_Metric_BasicUnit_Measure_BITS = 1,
+    google_census_Metric_BasicUnit_Measure_BYTES = 2,
+    google_census_Metric_BasicUnit_Measure_SECS = 3,
+    google_census_Metric_BasicUnit_Measure_CORES = 4,
+    google_census_Metric_BasicUnit_Measure_MAX_UNITS = 5
+} google_census_Metric_BasicUnit_Measure;
+
+/* Struct definitions */
+typedef struct _google_census_AggregationDescriptor_BucketBoundaries {
+    pb_callback_t bounds;
+} google_census_AggregationDescriptor_BucketBoundaries;
+
+typedef struct _google_census_AggregationDescriptor_IntervalBoundaries {
+    pb_callback_t window_size;
+} google_census_AggregationDescriptor_IntervalBoundaries;
+
+typedef struct _google_census_IntervalStats {
+    pb_callback_t window;
+} google_census_IntervalStats;
+
+typedef struct _google_census_AggregationDescriptor {
+    pb_size_t which_options;
+    union {
+        google_census_AggregationDescriptor_BucketBoundaries bucket_boundaries;
+        google_census_AggregationDescriptor_IntervalBoundaries interval_boundaries;
+    } options;
+} google_census_AggregationDescriptor;
+
+typedef struct _google_census_Distribution_Range {
+    bool has_min;
+    double min;
+    bool has_max;
+    double max;
+} google_census_Distribution_Range;
+
+typedef struct _google_census_Duration {
+    bool has_seconds;
+    int64_t seconds;
+    bool has_nanos;
+    int32_t nanos;
+} google_census_Duration;
+
+typedef struct _google_census_Metric_BasicUnit {
+    bool has_type;
+    google_census_Metric_BasicUnit_Measure type;
+} google_census_Metric_BasicUnit;
+
+typedef struct _google_census_Metric_MeasurementUnit {
+    bool has_prefix;
+    int32_t prefix;
+    pb_callback_t numerator;
+    pb_callback_t denominator;
+} google_census_Metric_MeasurementUnit;
+
+typedef struct _google_census_Tag {
+    bool has_key;
+    char key[255];
+    bool has_value;
+    char value[255];
+} google_census_Tag;
+
+typedef struct _google_census_Timestamp {
+    bool has_seconds;
+    int64_t seconds;
+    bool has_nanos;
+    int32_t nanos;
+} google_census_Timestamp;
+
+typedef struct _google_census_Distribution {
+    bool has_count;
+    int64_t count;
+    bool has_mean;
+    double mean;
+    bool has_range;
+    google_census_Distribution_Range range;
+    pb_callback_t bucket_count;
+} google_census_Distribution;
+
+typedef struct _google_census_IntervalStats_Window {
+    bool has_window_size;
+    google_census_Duration window_size;
+    bool has_count;
+    int64_t count;
+    bool has_mean;
+    double mean;
+} google_census_IntervalStats_Window;
+
+typedef struct _google_census_Metric {
+    pb_callback_t name;
+    pb_callback_t description;
+    bool has_unit;
+    google_census_Metric_MeasurementUnit unit;
+    bool has_id;
+    int32_t id;
+} google_census_Metric;
+
+typedef struct _google_census_View {
+    pb_callback_t name;
+    pb_callback_t description;
+    bool has_metric_id;
+    int32_t metric_id;
+    bool has_aggregation;
+    google_census_AggregationDescriptor aggregation;
+    pb_callback_t tag_key;
+} google_census_View;
+
+typedef struct _google_census_ViewAggregations {
+    pb_callback_t aggregation;
+    bool has_start;
+    google_census_Timestamp start;
+    bool has_end;
+    google_census_Timestamp end;
+} google_census_ViewAggregations;
+
+typedef struct _google_census_Aggregation {
+    pb_callback_t name;
+    pb_callback_t description;
+    pb_size_t which_data;
+    union {
+        google_census_Distribution distribution;
+        google_census_IntervalStats interval_stats;
+    } data;
+    pb_callback_t tag;
+} google_census_Aggregation;
+
+/* Default values for struct fields */
+
+/* Initializer values for message structs */
+#define google_census_Duration_init_default      {false, 0, false, 0}
+#define google_census_Timestamp_init_default     {false, 0, false, 0}
+#define google_census_Metric_init_default        {{{NULL}, NULL}, {{NULL}, NULL}, false, google_census_Metric_MeasurementUnit_init_default, false, 0}
+#define google_census_Metric_BasicUnit_init_default {false, (google_census_Metric_BasicUnit_Measure)0}
+#define google_census_Metric_MeasurementUnit_init_default {false, 0, {{NULL}, NULL}, {{NULL}, NULL}}
+#define google_census_AggregationDescriptor_init_default {0, {google_census_AggregationDescriptor_BucketBoundaries_init_default}}
+#define google_census_AggregationDescriptor_BucketBoundaries_init_default {{{NULL}, NULL}}
+#define google_census_AggregationDescriptor_IntervalBoundaries_init_default {{{NULL}, NULL}}
+#define google_census_Distribution_init_default  {false, 0, false, 0, false, google_census_Distribution_Range_init_default, {{NULL}, NULL}}
+#define google_census_Distribution_Range_init_default {false, 0, false, 0}
+#define google_census_IntervalStats_init_default {{{NULL}, NULL}}
+#define google_census_IntervalStats_Window_init_default {false, google_census_Duration_init_default, false, 0, false, 0}
+#define google_census_Tag_init_default           {false, "", false, ""}
+#define google_census_View_init_default          {{{NULL}, NULL}, {{NULL}, NULL}, false, 0, false, google_census_AggregationDescriptor_init_default, {{NULL}, NULL}}
+#define google_census_Aggregation_init_default   {{{NULL}, NULL}, {{NULL}, NULL}, 0, {google_census_Distribution_init_default}, {{NULL}, NULL}}
+#define google_census_ViewAggregations_init_default {{{NULL}, NULL}, false, google_census_Timestamp_init_default, false, google_census_Timestamp_init_default}
+#define google_census_Duration_init_zero         {false, 0, false, 0}
+#define google_census_Timestamp_init_zero        {false, 0, false, 0}
+#define google_census_Metric_init_zero           {{{NULL}, NULL}, {{NULL}, NULL}, false, google_census_Metric_MeasurementUnit_init_zero, false, 0}
+#define google_census_Metric_BasicUnit_init_zero {false, (google_census_Metric_BasicUnit_Measure)0}
+#define google_census_Metric_MeasurementUnit_init_zero {false, 0, {{NULL}, NULL}, {{NULL}, NULL}}
+#define google_census_AggregationDescriptor_init_zero {0, {google_census_AggregationDescriptor_BucketBoundaries_init_zero}}
+#define google_census_AggregationDescriptor_BucketBoundaries_init_zero {{{NULL}, NULL}}
+#define google_census_AggregationDescriptor_IntervalBoundaries_init_zero {{{NULL}, NULL}}
+#define google_census_Distribution_init_zero     {false, 0, false, 0, false, google_census_Distribution_Range_init_zero, {{NULL}, NULL}}
+#define google_census_Distribution_Range_init_zero {false, 0, false, 0}
+#define google_census_IntervalStats_init_zero    {{{NULL}, NULL}}
+#define google_census_IntervalStats_Window_init_zero {false, google_census_Duration_init_zero, false, 0, false, 0}
+#define google_census_Tag_init_zero              {false, "", false, ""}
+#define google_census_View_init_zero             {{{NULL}, NULL}, {{NULL}, NULL}, false, 0, false, google_census_AggregationDescriptor_init_zero, {{NULL}, NULL}}
+#define google_census_Aggregation_init_zero      {{{NULL}, NULL}, {{NULL}, NULL}, 0, {google_census_Distribution_init_zero}, {{NULL}, NULL}}
+#define google_census_ViewAggregations_init_zero {{{NULL}, NULL}, false, google_census_Timestamp_init_zero, false, google_census_Timestamp_init_zero}
+
+/* Field tags (for use in manual encoding/decoding) */
+#define google_census_AggregationDescriptor_BucketBoundaries_bounds_tag 1
+#define google_census_AggregationDescriptor_IntervalBoundaries_window_size_tag 1
+#define google_census_IntervalStats_window_tag   1
+#define google_census_AggregationDescriptor_bucket_boundaries_tag 1
+
+#define google_census_AggregationDescriptor_interval_boundaries_tag 2
+#define google_census_Distribution_Range_min_tag 1
+#define google_census_Distribution_Range_max_tag 2
+#define google_census_Duration_seconds_tag       1
+#define google_census_Duration_nanos_tag         2
+#define google_census_Metric_BasicUnit_type_tag  1
+#define google_census_Metric_MeasurementUnit_prefix_tag 1
+#define google_census_Metric_MeasurementUnit_numerator_tag 2
+#define google_census_Metric_MeasurementUnit_denominator_tag 3
+#define google_census_Tag_key_tag                1
+#define google_census_Tag_value_tag              2
+#define google_census_Timestamp_seconds_tag      1
+#define google_census_Timestamp_nanos_tag        2
+#define google_census_Distribution_count_tag     1
+#define google_census_Distribution_mean_tag      2
+#define google_census_Distribution_range_tag     3
+#define google_census_Distribution_bucket_count_tag 4
+#define google_census_IntervalStats_Window_window_size_tag 1
+#define google_census_IntervalStats_Window_count_tag 2
+#define google_census_IntervalStats_Window_mean_tag 3
+#define google_census_Metric_name_tag            1
+#define google_census_Metric_description_tag     2
+#define google_census_Metric_unit_tag            3
+#define google_census_Metric_id_tag              4
+#define google_census_View_name_tag              1
+#define google_census_View_description_tag       2
+#define google_census_View_metric_id_tag         3
+#define google_census_View_aggregation_tag       4
+#define google_census_View_tag_key_tag           5
+#define google_census_ViewAggregations_aggregation_tag 1
+#define google_census_ViewAggregations_start_tag 2
+#define google_census_ViewAggregations_end_tag   3
+#define google_census_Aggregation_distribution_tag 3
+
+#define google_census_Aggregation_interval_stats_tag 4
+#define google_census_Aggregation_name_tag       1
+#define google_census_Aggregation_description_tag 2
+#define google_census_Aggregation_tag_tag        5
+
+/* Struct field encoding specification for nanopb */
+extern const pb_field_t google_census_Duration_fields[3];
+extern const pb_field_t google_census_Timestamp_fields[3];
+extern const pb_field_t google_census_Metric_fields[5];
+extern const pb_field_t google_census_Metric_BasicUnit_fields[2];
+extern const pb_field_t google_census_Metric_MeasurementUnit_fields[4];
+extern const pb_field_t google_census_AggregationDescriptor_fields[3];
+extern const pb_field_t google_census_AggregationDescriptor_BucketBoundaries_fields[2];
+extern const pb_field_t google_census_AggregationDescriptor_IntervalBoundaries_fields[2];
+extern const pb_field_t google_census_Distribution_fields[5];
+extern const pb_field_t google_census_Distribution_Range_fields[3];
+extern const pb_field_t google_census_IntervalStats_fields[2];
+extern const pb_field_t google_census_IntervalStats_Window_fields[4];
+extern const pb_field_t google_census_Tag_fields[3];
+extern const pb_field_t google_census_View_fields[6];
+extern const pb_field_t google_census_Aggregation_fields[6];
+extern const pb_field_t google_census_ViewAggregations_fields[4];
+
+/* Maximum encoded size of messages (where known) */
+#define google_census_Duration_size              22
+#define google_census_Timestamp_size             22
+#define google_census_Metric_BasicUnit_size      2
+#define google_census_Distribution_Range_size    18
+#define google_census_IntervalStats_Window_size  44
+#define google_census_Tag_size                   516
+
+/* Message IDs (where set with "msgid" option) */
+#ifdef PB_MSGID
+
+#define CENSUS_MESSAGES \
+
+
+#endif
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif
diff --git a/src/core/ext/census/grpc_filter.c b/src/core/ext/census/grpc_filter.c
index 5e278ef..86ec2ae 100644
--- a/src/core/ext/census/grpc_filter.c
+++ b/src/core/ext/census/grpc_filter.c
@@ -134,7 +134,9 @@
 }
 
 static void client_destroy_call_elem(grpc_exec_ctx *exec_ctx,
-                                     grpc_call_element *elem, void *ignored) {
+                                     grpc_call_element *elem,
+                                     const grpc_call_stats *stats,
+                                     void *ignored) {
   call_data *d = elem->call_data;
   GPR_ASSERT(d != NULL);
   /* TODO(hongyu): record rpc client stats and census_rpc_end_op here */
@@ -152,7 +154,9 @@
 }
 
 static void server_destroy_call_elem(grpc_exec_ctx *exec_ctx,
-                                     grpc_call_element *elem, void *ignored) {
+                                     grpc_call_element *elem,
+                                     const grpc_call_stats *stats,
+                                     void *ignored) {
   call_data *d = elem->call_data;
   GPR_ASSERT(d != NULL);
   /* TODO(hongyu): record rpc server stats and census_tracing_end_op here */
@@ -176,7 +180,7 @@
     grpc_channel_next_op,
     sizeof(call_data),
     client_init_call_elem,
-    grpc_call_stack_ignore_set_pollset,
+    grpc_call_stack_ignore_set_pollset_or_pollset_set,
     client_destroy_call_elem,
     sizeof(channel_data),
     init_channel_elem,
@@ -189,7 +193,7 @@
     grpc_channel_next_op,
     sizeof(call_data),
     server_init_call_elem,
-    grpc_call_stack_ignore_set_pollset,
+    grpc_call_stack_ignore_set_pollset_or_pollset_set,
     server_destroy_call_elem,
     sizeof(channel_data),
     init_channel_elem,
diff --git a/src/core/ext/client_config/channel_connectivity.c b/src/core/ext/client_config/channel_connectivity.c
index 3ebc333..cc60f24 100644
--- a/src/core/ext/client_config/channel_connectivity.c
+++ b/src/core/ext/client_config/channel_connectivity.c
@@ -62,7 +62,7 @@
           "not a (u)client channel, but '%s'",
           client_channel_elem->filter->name);
   grpc_exec_ctx_finish(&exec_ctx);
-  return GRPC_CHANNEL_FATAL_FAILURE;
+  return GRPC_CHANNEL_SHUTDOWN;
 }
 
 typedef enum {
diff --git a/src/core/ext/client_config/client_channel.c b/src/core/ext/client_config/client_channel.c
index 9b5a078..e297dfa 100644
--- a/src/core/ext/client_config/client_channel.c
+++ b/src/core/ext/client_config/client_channel.c
@@ -119,7 +119,7 @@
                                                   grpc_connectivity_state state,
                                                   const char *reason) {
   if ((state == GRPC_CHANNEL_TRANSIENT_FAILURE ||
-       state == GRPC_CHANNEL_FATAL_FAILURE) &&
+       state == GRPC_CHANNEL_SHUTDOWN) &&
       chand->lb_policy != NULL) {
     /* cancel fail-fast picks */
     grpc_lb_policy_cancel_picks(
@@ -136,8 +136,7 @@
   /* check if the notification is for a stale policy */
   if (w->lb_policy != w->chand->lb_policy) return;
 
-  if (publish_state == GRPC_CHANNEL_FATAL_FAILURE &&
-      w->chand->resolver != NULL) {
+  if (publish_state == GRPC_CHANNEL_SHUTDOWN && w->chand->resolver != NULL) {
     publish_state = GRPC_CHANNEL_TRANSIENT_FAILURE;
     grpc_resolver_channel_saw_error(exec_ctx, w->chand->resolver);
     GRPC_LB_POLICY_UNREF(exec_ctx, w->chand->lb_policy, "channel");
@@ -145,7 +144,7 @@
   }
   set_channel_connectivity_state_locked(exec_ctx, w->chand, publish_state,
                                         "lb_changed");
-  if (w->state != GRPC_CHANNEL_FATAL_FAILURE) {
+  if (w->state != GRPC_CHANNEL_SHUTDOWN) {
     watch_lb_policy(exec_ctx, w->chand, w->lb_policy, w->state);
   }
 }
@@ -237,7 +236,7 @@
       chand->resolver = NULL;
     }
     set_channel_connectivity_state_locked(
-        exec_ctx, chand, GRPC_CHANNEL_FATAL_FAILURE, "resolver_gone");
+        exec_ctx, chand, GRPC_CHANNEL_SHUTDOWN, "resolver_gone");
     gpr_mu_unlock(&chand->mu_config);
   }
 
@@ -292,8 +291,8 @@
   }
 
   if (op->disconnect && chand->resolver != NULL) {
-    set_channel_connectivity_state_locked(
-        exec_ctx, chand, GRPC_CHANNEL_FATAL_FAILURE, "disconnect");
+    set_channel_connectivity_state_locked(exec_ctx, chand,
+                                          GRPC_CHANNEL_SHUTDOWN, "disconnect");
     grpc_resolver_shutdown(exec_ctx, chand->resolver);
     GRPC_RESOLVER_UNREF(exec_ctx, chand->resolver, "channel");
     chand->resolver = NULL;
@@ -377,7 +376,7 @@
     int r;
     GRPC_LB_POLICY_REF(lb_policy, "cc_pick_subchannel");
     gpr_mu_unlock(&chand->mu_config);
-    r = grpc_lb_policy_pick(exec_ctx, lb_policy, calld->pollset,
+    r = grpc_lb_policy_pick(exec_ctx, lb_policy, calld->pollent,
                             initial_metadata, initial_metadata_flags,
                             connected_subchannel, on_ready);
     GRPC_LB_POLICY_UNREF(exec_ctx, lb_policy, "cc_pick_subchannel");
@@ -416,6 +415,7 @@
 
 /* Destructor for call_data */
 static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
+                              const grpc_call_stats *stats,
                               void *and_free_memory) {
   grpc_subchannel_call_holder_destroy(exec_ctx, elem->call_data);
   gpr_free(and_free_memory);
@@ -461,10 +461,11 @@
   gpr_mu_destroy(&chand->mu_config);
 }
 
-static void cc_set_pollset(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
-                           grpc_pollset *pollset) {
+static void cc_set_pollset_or_pollset_set(grpc_exec_ctx *exec_ctx,
+                                          grpc_call_element *elem,
+                                          grpc_polling_entity *pollent) {
   call_data *calld = elem->call_data;
-  calld->pollset = pollset;
+  calld->pollent = pollent;
 }
 
 const grpc_channel_filter grpc_client_channel_filter = {
@@ -472,7 +473,7 @@
     cc_start_transport_op,
     sizeof(call_data),
     init_call_elem,
-    cc_set_pollset,
+    cc_set_pollset_or_pollset_set,
     destroy_call_elem,
     sizeof(channel_data),
     init_channel_elem,
diff --git a/src/core/ext/client_config/lb_policy.c b/src/core/ext/client_config/lb_policy.c
index a7ad984..2053539 100644
--- a/src/core/ext/client_config/lb_policy.c
+++ b/src/core/ext/client_config/lb_policy.c
@@ -99,12 +99,12 @@
 }
 
 int grpc_lb_policy_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy,
-                        grpc_pollset *pollset,
+                        grpc_polling_entity *pollent,
                         grpc_metadata_batch *initial_metadata,
                         uint32_t initial_metadata_flags,
                         grpc_connected_subchannel **target,
                         grpc_closure *on_complete) {
-  return policy->vtable->pick(exec_ctx, policy, pollset, initial_metadata,
+  return policy->vtable->pick(exec_ctx, policy, pollent, initial_metadata,
                               initial_metadata_flags, target, on_complete);
 }
 
diff --git a/src/core/ext/client_config/lb_policy.h b/src/core/ext/client_config/lb_policy.h
index 0384e0b..56fa111 100644
--- a/src/core/ext/client_config/lb_policy.h
+++ b/src/core/ext/client_config/lb_policy.h
@@ -35,6 +35,7 @@
 #define GRPC_CORE_EXT_CLIENT_CONFIG_LB_POLICY_H
 
 #include "src/core/ext/client_config/subchannel.h"
+#include "src/core/lib/iomgr/polling_entity.h"
 #include "src/core/lib/transport/connectivity_state.h"
 
 /** A load balancing policy: specified by a vtable and a struct (which
@@ -59,7 +60,8 @@
 
   /** implement grpc_lb_policy_pick */
   int (*pick)(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy,
-              grpc_pollset *pollset, grpc_metadata_batch *initial_metadata,
+              grpc_polling_entity *pollent,
+              grpc_metadata_batch *initial_metadata,
               uint32_t initial_metadata_flags,
               grpc_connected_subchannel **target, grpc_closure *on_complete);
   void (*cancel_pick)(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy,
@@ -124,7 +126,7 @@
     \a target.
     Picking can be asynchronous. Any IO should be done under \a pollset. */
 int grpc_lb_policy_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *policy,
-                        grpc_pollset *pollset,
+                        grpc_polling_entity *pollent,
                         grpc_metadata_batch *initial_metadata,
                         uint32_t initial_metadata_flags,
                         grpc_connected_subchannel **target,
diff --git a/src/core/ext/client_config/subchannel.c b/src/core/ext/client_config/subchannel.c
index cfd39e7..85183b0 100644
--- a/src/core/ext/client_config/subchannel.c
+++ b/src/core/ext/client_config/subchannel.c
@@ -480,11 +480,11 @@
   if (iomgr_success) {
     if (sw->connectivity_state == GRPC_CHANNEL_TRANSIENT_FAILURE) {
       /* any errors on a subchannel ==> we're done, create a new one */
-      sw->connectivity_state = GRPC_CHANNEL_FATAL_FAILURE;
+      sw->connectivity_state = GRPC_CHANNEL_SHUTDOWN;
     }
     grpc_connectivity_state_set(exec_ctx, &c->state_tracker,
                                 sw->connectivity_state, "reflect_child");
-    if (sw->connectivity_state != GRPC_CHANNEL_FATAL_FAILURE) {
+    if (sw->connectivity_state != GRPC_CHANNEL_SHUTDOWN) {
       grpc_connected_subchannel_notify_on_state_change(
           exec_ctx, GET_CONNECTED_SUBCHANNEL(c, no_barrier), NULL,
           &sw->connectivity_state, &sw->closure);
@@ -645,7 +645,7 @@
   grpc_subchannel_call *c = call;
   GPR_TIMER_BEGIN("grpc_subchannel_call_unref.destroy", 0);
   grpc_connected_subchannel *connection = c->connection;
-  grpc_call_stack_destroy(exec_ctx, SUBCHANNEL_CALL_TO_CALL_STACK(c), c);
+  grpc_call_stack_destroy(exec_ctx, SUBCHANNEL_CALL_TO_CALL_STACK(c), NULL, c);
   GRPC_CONNECTED_SUBCHANNEL_UNREF(exec_ctx, connection, "subchannel_call");
   GPR_TIMER_END("grpc_subchannel_call_unref.destroy", 0);
 }
@@ -683,7 +683,7 @@
 
 grpc_subchannel_call *grpc_connected_subchannel_create_call(
     grpc_exec_ctx *exec_ctx, grpc_connected_subchannel *con,
-    grpc_pollset *pollset) {
+    grpc_polling_entity *pollent) {
   grpc_channel_stack *chanstk = CHANNEL_STACK_FROM_CONNECTION(con);
   grpc_subchannel_call *call =
       gpr_malloc(sizeof(grpc_subchannel_call) + chanstk->call_stack_size);
@@ -692,7 +692,7 @@
   GRPC_CONNECTED_SUBCHANNEL_REF(con, "subchannel_call");
   grpc_call_stack_init(exec_ctx, chanstk, 1, subchannel_call_destroy, call,
                        NULL, NULL, callstk);
-  grpc_call_stack_set_pollset(exec_ctx, callstk, pollset);
+  grpc_call_stack_set_pollset_or_pollset_set(exec_ctx, callstk, pollent);
   return call;
 }
 
diff --git a/src/core/ext/client_config/subchannel.h b/src/core/ext/client_config/subchannel.h
index 0765a54..525f854 100644
--- a/src/core/ext/client_config/subchannel.h
+++ b/src/core/ext/client_config/subchannel.h
@@ -36,6 +36,7 @@
 
 #include "src/core/ext/client_config/connector.h"
 #include "src/core/lib/channel/channel_stack.h"
+#include "src/core/lib/iomgr/polling_entity.h"
 #include "src/core/lib/transport/connectivity_state.h"
 
 /** A (sub-)channel that knows how to connect to exactly one target
@@ -109,7 +110,7 @@
 /** construct a subchannel call */
 grpc_subchannel_call *grpc_connected_subchannel_create_call(
     grpc_exec_ctx *exec_ctx, grpc_connected_subchannel *connected_subchannel,
-    grpc_pollset *pollset);
+    grpc_polling_entity *pollent);
 
 /** process a transport level op */
 void grpc_connected_subchannel_process_transport_op(
diff --git a/src/core/ext/client_config/subchannel_call_holder.c b/src/core/ext/client_config/subchannel_call_holder.c
index 91fa917..3df1f25 100644
--- a/src/core/ext/client_config/subchannel_call_holder.c
+++ b/src/core/ext/client_config/subchannel_call_holder.c
@@ -68,6 +68,7 @@
   holder->waiting_ops_capacity = 0;
   holder->creation_phase = GRPC_SUBCHANNEL_CALL_HOLDER_NOT_CREATING;
   holder->owning_call = owning_call;
+  holder->pollent = NULL;
 }
 
 void grpc_subchannel_call_holder_destroy(grpc_exec_ctx *exec_ctx,
@@ -157,7 +158,7 @@
     gpr_atm_rel_store(
         &holder->subchannel_call,
         (gpr_atm)(uintptr_t)grpc_connected_subchannel_create_call(
-            exec_ctx, holder->connected_subchannel, holder->pollset));
+            exec_ctx, holder->connected_subchannel, holder->pollent));
     retry_waiting_locked(exec_ctx, holder);
     goto retry;
   }
@@ -183,7 +184,7 @@
     gpr_atm_rel_store(
         &holder->subchannel_call,
         (gpr_atm)(uintptr_t)grpc_connected_subchannel_create_call(
-            exec_ctx, holder->connected_subchannel, holder->pollset));
+            exec_ctx, holder->connected_subchannel, holder->pollent));
     retry_waiting_locked(exec_ctx, holder);
   }
   gpr_mu_unlock(&holder->mu);
diff --git a/src/core/ext/client_config/subchannel_call_holder.h b/src/core/ext/client_config/subchannel_call_holder.h
index 9299908..8d2deb0 100644
--- a/src/core/ext/client_config/subchannel_call_holder.h
+++ b/src/core/ext/client_config/subchannel_call_holder.h
@@ -35,6 +35,7 @@
 #define GRPC_CORE_EXT_CLIENT_CONFIG_SUBCHANNEL_CALL_HOLDER_H
 
 #include "src/core/ext/client_config/subchannel.h"
+#include "src/core/lib/iomgr/polling_entity.h"
 
 /** Pick a subchannel for grpc_subchannel_call_holder;
     Return 1 if subchannel is available immediately (in which case on_ready
@@ -71,7 +72,7 @@
 
   grpc_subchannel_call_holder_creation_phase creation_phase;
   grpc_connected_subchannel *connected_subchannel;
-  grpc_pollset *pollset;
+  grpc_polling_entity *pollent;
 
   grpc_transport_stream_op *waiting_ops;
   size_t waiting_ops_count;
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 d5dc39a..46fe588 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
@@ -33,8 +33,8 @@
 /* Automatically generated nanopb header */
 /* Generated by nanopb-0.3.5-dev */
 
-#ifndef PB_LOAD_BALANCER_PB_H_INCLUDED
-#define PB_LOAD_BALANCER_PB_H_INCLUDED
+#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
 #include "third_party/nanopb/pb.h"
 #if PB_PROTO_HEADER_VERSION != 30
 #error Regenerate this file with the current version of nanopb generator.
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 0d215cd..cc559eb 100644
--- a/src/core/ext/lb_policy/pick_first/pick_first.c
+++ b/src/core/ext/lb_policy/pick_first/pick_first.c
@@ -39,7 +39,7 @@
 
 typedef struct pending_pick {
   struct pending_pick *next;
-  grpc_pollset *pollset;
+  grpc_polling_entity *pollent;
   uint32_t initial_metadata_flags;
   grpc_connected_subchannel **target;
   grpc_closure *on_complete;
@@ -104,7 +104,7 @@
   pp = p->pending_picks;
   p->pending_picks = NULL;
   grpc_connectivity_state_set(exec_ctx, &p->state_tracker,
-                              GRPC_CHANNEL_FATAL_FAILURE, "shutdown");
+                              GRPC_CHANNEL_SHUTDOWN, "shutdown");
   /* cancel subscription */
   if (selected != NULL) {
     grpc_connected_subchannel_notify_on_state_change(
@@ -118,8 +118,8 @@
   while (pp != NULL) {
     pending_pick *next = pp->next;
     *pp->target = NULL;
-    grpc_pollset_set_del_pollset(exec_ctx, p->base.interested_parties,
-                                 pp->pollset);
+    grpc_polling_entity_del_from_pollset_set(exec_ctx, pp->pollent,
+                                             p->base.interested_parties);
     grpc_exec_ctx_enqueue(exec_ctx, pp->on_complete, true, NULL);
     gpr_free(pp);
     pp = next;
@@ -136,8 +136,8 @@
   while (pp != NULL) {
     pending_pick *next = pp->next;
     if (pp->target == target) {
-      grpc_pollset_set_del_pollset(exec_ctx, p->base.interested_parties,
-                                   pp->pollset);
+      grpc_polling_entity_del_from_pollset_set(exec_ctx, pp->pollent,
+                                               p->base.interested_parties);
       *target = NULL;
       grpc_exec_ctx_enqueue(exec_ctx, pp->on_complete, false, NULL);
       gpr_free(pp);
@@ -162,8 +162,8 @@
     pending_pick *next = pp->next;
     if ((pp->initial_metadata_flags & initial_metadata_flags_mask) ==
         initial_metadata_flags_eq) {
-      grpc_pollset_set_del_pollset(exec_ctx, p->base.interested_parties,
-                                   pp->pollset);
+      grpc_polling_entity_del_from_pollset_set(exec_ctx, pp->pollent,
+                                               p->base.interested_parties);
       grpc_exec_ctx_enqueue(exec_ctx, pp->on_complete, false, NULL);
       gpr_free(pp);
     } else {
@@ -196,7 +196,8 @@
 }
 
 static int pf_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol,
-                   grpc_pollset *pollset, grpc_metadata_batch *initial_metadata,
+                   grpc_polling_entity *pollent,
+                   grpc_metadata_batch *initial_metadata,
                    uint32_t initial_metadata_flags,
                    grpc_connected_subchannel **target,
                    grpc_closure *on_complete) {
@@ -221,10 +222,11 @@
     if (!p->started_picking) {
       start_picking(exec_ctx, p);
     }
-    grpc_pollset_set_add_pollset(exec_ctx, p->base.interested_parties, pollset);
+    grpc_polling_entity_add_to_pollset_set(exec_ctx, pollent,
+                                           p->base.interested_parties);
     pp = gpr_malloc(sizeof(*pp));
     pp->next = p->pending_picks;
-    pp->pollset = pollset;
+    pp->pollent = pollent;
     pp->target = target;
     pp->initial_metadata_flags = initial_metadata_flags;
     pp->on_complete = on_complete;
@@ -273,11 +275,11 @@
   } else if (selected != NULL) {
     if (p->checking_connectivity == GRPC_CHANNEL_TRANSIENT_FAILURE) {
       /* if the selected channel goes bad, we're done */
-      p->checking_connectivity = GRPC_CHANNEL_FATAL_FAILURE;
+      p->checking_connectivity = GRPC_CHANNEL_SHUTDOWN;
     }
     grpc_connectivity_state_set(exec_ctx, &p->state_tracker,
                                 p->checking_connectivity, "selected_changed");
-    if (p->checking_connectivity != GRPC_CHANNEL_FATAL_FAILURE) {
+    if (p->checking_connectivity != GRPC_CHANNEL_SHUTDOWN) {
       grpc_connected_subchannel_notify_on_state_change(
           exec_ctx, selected, p->base.interested_parties,
           &p->checking_connectivity, &p->connectivity_changed);
@@ -304,8 +306,8 @@
         while ((pp = p->pending_picks)) {
           p->pending_picks = pp->next;
           *pp->target = selected;
-          grpc_pollset_set_del_pollset(exec_ctx, p->base.interested_parties,
-                                       pp->pollset);
+          grpc_polling_entity_del_from_pollset_set(exec_ctx, pp->pollent,
+                                                   p->base.interested_parties);
           grpc_exec_ctx_enqueue(exec_ctx, pp->on_complete, true, NULL);
           gpr_free(pp);
         }
@@ -343,7 +345,7 @@
             p->base.interested_parties, &p->checking_connectivity,
             &p->connectivity_changed);
         break;
-      case GRPC_CHANNEL_FATAL_FAILURE:
+      case GRPC_CHANNEL_SHUTDOWN:
         p->num_subchannels--;
         GPR_SWAP(grpc_subchannel *, p->subchannels[p->checking_subchannel],
                  p->subchannels[p->num_subchannels]);
@@ -351,7 +353,7 @@
                               "pick_first");
         if (p->num_subchannels == 0) {
           grpc_connectivity_state_set(exec_ctx, &p->state_tracker,
-                                      GRPC_CHANNEL_FATAL_FAILURE,
+                                      GRPC_CHANNEL_SHUTDOWN,
                                       "no_more_channels");
           while ((pp = p->pending_picks)) {
             p->pending_picks = pp->next;
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 dcdc0c6..da2cdfe 100644
--- a/src/core/ext/lb_policy/round_robin/round_robin.c
+++ b/src/core/ext/lb_policy/round_robin/round_robin.c
@@ -31,6 +31,34 @@
  *
  */
 
+/** Round Robin Policy.
+ *
+ * This policy keeps:
+ * - A circular list of ready (connected) subchannels, the *readylist*. An empty
+ *   readylist consists solely of its root (dummy) node.
+ * - A pointer to the last element picked from the readylist, the *lastpick*.
+ *   Initially set to point to the readylist's root.
+ *
+ * Behavior:
+ * - When a subchannel connects, it's *prepended* to the readylist's root node.
+ *   Ie, if readylist = A <-> B <-> ROOT <-> C
+ *                      ^                    ^
+ *                      |____________________|
+ *   and subchannel D becomes connected, the addition of D to the readylist
+ *   results in  readylist = A <-> B <-> D <-> ROOT <-> C
+ *                           ^                          ^
+ *                           |__________________________|
+ * - When a subchannel disconnects, it's removed from the readylist. If the
+ *   subchannel being removed was the most recently picked, the *lastpick*
+ *   pointer moves to the removed node's previous element. Note that if the
+ *   readylist only had one element, this is still legal, as the lastpick would
+ *   point to the dummy root node, for an empty readylist.
+ * - Upon picking, *lastpick* is updated to point to the returned (connected)
+ *   subchannel. Note that it's possible that the selected subchannel becomes
+ *   disconnected in the interim between the selection and the actual usage of
+ *   the subchannel by the caller.
+ */
+
 #include <string.h>
 
 #include <grpc/support/alloc.h>
@@ -48,7 +76,7 @@
  * Once a pick is available, \a target is updated and \a on_complete called. */
 typedef struct pending_pick {
   struct pending_pick *next;
-  grpc_pollset *pollset;
+  grpc_polling_entity *pollent;
   uint32_t initial_metadata_flags;
   grpc_connected_subchannel **target;
   grpc_closure *on_complete;
@@ -173,9 +201,7 @@
     return;
   }
   if (node == p->ready_list_last_pick) {
-    /* If removing the lastly picked node, reset the last pick pointer to the
-     * dummy root of the list */
-    p->ready_list_last_pick = &p->ready_list;
+    p->ready_list_last_pick = p->ready_list_last_pick->prev;
   }
 
   /* removing last item */
@@ -243,7 +269,7 @@
     gpr_free(pp);
   }
   grpc_connectivity_state_set(exec_ctx, &p->state_tracker,
-                              GRPC_CHANNEL_FATAL_FAILURE, "shutdown");
+                              GRPC_CHANNEL_SHUTDOWN, "shutdown");
   for (i = 0; i < p->num_subchannels; i++) {
     subchannel_data *sd = p->subchannels[i];
     grpc_subchannel_notify_on_state_change(exec_ctx, sd->subchannel, NULL, NULL,
@@ -262,8 +288,8 @@
   while (pp != NULL) {
     pending_pick *next = pp->next;
     if (pp->target == target) {
-      grpc_pollset_set_del_pollset(exec_ctx, p->base.interested_parties,
-                                   pp->pollset);
+      grpc_polling_entity_del_from_pollset_set(exec_ctx, pp->pollent,
+                                               p->base.interested_parties);
       *target = NULL;
       grpc_exec_ctx_enqueue(exec_ctx, pp->on_complete, false, NULL);
       gpr_free(pp);
@@ -288,8 +314,8 @@
     pending_pick *next = pp->next;
     if ((pp->initial_metadata_flags & initial_metadata_flags_mask) ==
         initial_metadata_flags_eq) {
-      grpc_pollset_set_del_pollset(exec_ctx, p->base.interested_parties,
-                                   pp->pollset);
+      grpc_polling_entity_del_from_pollset_set(exec_ctx, pp->pollent,
+                                               p->base.interested_parties);
       *pp->target = NULL;
       grpc_exec_ctx_enqueue(exec_ctx, pp->on_complete, false, NULL);
       gpr_free(pp);
@@ -331,7 +357,8 @@
 }
 
 static int rr_pick(grpc_exec_ctx *exec_ctx, grpc_lb_policy *pol,
-                   grpc_pollset *pollset, grpc_metadata_batch *initial_metadata,
+                   grpc_polling_entity *pollent,
+                   grpc_metadata_batch *initial_metadata,
                    uint32_t initial_metadata_flags,
                    grpc_connected_subchannel **target,
                    grpc_closure *on_complete) {
@@ -344,8 +371,8 @@
     *target = grpc_subchannel_get_connected_subchannel(selected->subchannel);
     if (grpc_lb_round_robin_trace) {
       gpr_log(GPR_DEBUG,
-              "[RR PICK] TARGET <-- CONNECTED SUBCHANNEL %p (NODE %p)",
-              selected->subchannel, selected);
+              "[RR PICK] TARGET <-- CONNECTED SUBCHANNEL %p (NODE %p)", *target,
+              selected);
     }
     /* only advance the last picked pointer if the selection was used */
     advance_last_picked_locked(p);
@@ -354,10 +381,11 @@
     if (!p->started_picking) {
       start_picking(exec_ctx, p);
     }
-    grpc_pollset_set_add_pollset(exec_ctx, p->base.interested_parties, pollset);
+    grpc_polling_entity_add_to_pollset_set(exec_ctx, pollent,
+                                           p->base.interested_parties);
     pp = gpr_malloc(sizeof(*pp));
     pp->next = p->pending_picks;
-    pp->pollset = pollset;
+    pp->pollent = pollent;
     pp->target = target;
     pp->on_complete = on_complete;
     pp->initial_metadata_flags = initial_metadata_flags;
@@ -406,8 +434,8 @@
                     "[RR CONN CHANGED] TARGET <-- SUBCHANNEL %p (NODE %p)",
                     selected->subchannel, selected);
           }
-          grpc_pollset_set_del_pollset(exec_ctx, p->base.interested_parties,
-                                       pp->pollset);
+          grpc_polling_entity_del_from_pollset_set(exec_ctx, pp->pollent,
+                                                   p->base.interested_parties);
           grpc_exec_ctx_enqueue(exec_ctx, pp->on_complete, true, NULL);
           gpr_free(pp);
         }
@@ -439,7 +467,7 @@
                                     GRPC_CHANNEL_TRANSIENT_FAILURE,
                                     "connecting_transient_failure");
         break;
-      case GRPC_CHANNEL_FATAL_FAILURE:
+      case GRPC_CHANNEL_SHUTDOWN:
         if (sd->ready_list_node != NULL) {
           remove_disconnected_sc_locked(p, sd->ready_list_node);
           sd->ready_list_node = NULL;
@@ -455,7 +483,7 @@
         unref = 1;
         if (p->num_subchannels == 0) {
           grpc_connectivity_state_set(exec_ctx, &p->state_tracker,
-                                      GRPC_CHANNEL_FATAL_FAILURE,
+                                      GRPC_CHANNEL_SHUTDOWN,
                                       "no_more_channels");
           while ((pp = p->pending_picks)) {
             p->pending_picks = pp->next;
@@ -524,7 +552,7 @@
 
 static void round_robin_factory_unref(grpc_lb_policy_factory *factory) {}
 
-static grpc_lb_policy *create_round_robin(grpc_exec_ctx *exec_ctx,
+static grpc_lb_policy *round_robin_create(grpc_exec_ctx *exec_ctx,
                                           grpc_lb_policy_factory *factory,
                                           grpc_lb_policy_args *args) {
   GPR_ASSERT(args->addresses != NULL);
@@ -580,7 +608,7 @@
 }
 
 static const grpc_lb_policy_factory_vtable round_robin_factory_vtable = {
-    round_robin_factory_ref, round_robin_factory_unref, create_round_robin,
+    round_robin_factory_ref, round_robin_factory_unref, round_robin_create,
     "round_robin"};
 
 static grpc_lb_policy_factory round_robin_lb_policy_factory = {
diff --git a/src/core/ext/load_reporting/load_reporting.c b/src/core/ext/load_reporting/load_reporting.c
new file mode 100644
index 0000000..9e4d326
--- /dev/null
+++ b/src/core/ext/load_reporting/load_reporting.c
@@ -0,0 +1,133 @@
+/*
+ *
+ * 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 <limits.h>
+#include <string.h>
+
+#include <grpc/support/alloc.h>
+#include <grpc/support/sync.h>
+
+#include "src/core/ext/load_reporting/load_reporting.h"
+#include "src/core/ext/load_reporting/load_reporting_filter.h"
+#include "src/core/lib/channel/channel_stack_builder.h"
+#include "src/core/lib/surface/channel_init.h"
+
+struct grpc_load_reporting_config {
+  grpc_load_reporting_fn fn;
+  void *user_data;
+};
+
+grpc_load_reporting_config *grpc_load_reporting_config_create(
+    grpc_load_reporting_fn fn, void *user_data) {
+  GPR_ASSERT(fn != NULL);
+  grpc_load_reporting_config *lrc =
+      gpr_malloc(sizeof(grpc_load_reporting_config));
+  lrc->fn = fn;
+  lrc->user_data = user_data;
+  return lrc;
+}
+
+grpc_load_reporting_config *grpc_load_reporting_config_copy(
+    grpc_load_reporting_config *src) {
+  return grpc_load_reporting_config_create(src->fn, src->user_data);
+}
+
+void grpc_load_reporting_config_destroy(grpc_load_reporting_config *lrc) {
+  gpr_free(lrc);
+}
+
+void grpc_load_reporting_config_call(
+    grpc_load_reporting_config *lrc,
+    const grpc_load_reporting_call_data *call_data) {
+  lrc->fn(call_data, lrc->user_data);
+}
+
+static bool is_load_reporting_enabled(const grpc_channel_args *a) {
+  if (a == NULL) return false;
+  for (size_t i = 0; i < a->num_args; i++) {
+    if (0 == strcmp(a->args[i].key, GRPC_ARG_ENABLE_LOAD_REPORTING)) {
+      return a->args[i].type == GRPC_ARG_POINTER &&
+             a->args[i].value.pointer.p != NULL;
+    }
+  }
+  return false;
+}
+
+static bool maybe_add_load_reporting_filter(grpc_channel_stack_builder *builder,
+                                            void *arg) {
+  const grpc_channel_args *args =
+      grpc_channel_stack_builder_get_channel_arguments(builder);
+  if (is_load_reporting_enabled(args)) {
+    return grpc_channel_stack_builder_prepend_filter(
+        builder, (const grpc_channel_filter *)arg, NULL, NULL);
+  }
+  return true;
+}
+
+static void lrd_arg_destroy(void *p) { grpc_load_reporting_config_destroy(p); }
+
+static void *lrd_arg_copy(void *p) {
+  return grpc_load_reporting_config_copy(p);
+}
+
+static int lrd_arg_cmp(void *a, void *b) {
+  grpc_load_reporting_config *lhs = a;
+  grpc_load_reporting_config *rhs = b;
+  return !(lhs->fn == rhs->fn && lhs->user_data == rhs->user_data);
+}
+
+static const grpc_arg_pointer_vtable lrd_ptr_vtable = {
+    lrd_arg_copy, lrd_arg_destroy, lrd_arg_cmp};
+
+grpc_arg grpc_load_reporting_config_create_arg(
+    grpc_load_reporting_config *lrc) {
+  grpc_arg arg;
+  arg.type = GRPC_ARG_POINTER;
+  arg.key = GRPC_ARG_ENABLE_LOAD_REPORTING;
+  arg.value.pointer.p = lrc;
+  arg.value.pointer.vtable = &lrd_ptr_vtable;
+  return arg;
+}
+
+/* Plugin registration */
+
+void grpc_load_reporting_plugin_init(void) {
+  grpc_channel_init_register_stage(GRPC_CLIENT_CHANNEL, INT_MAX,
+                                   maybe_add_load_reporting_filter,
+                                   (void *)&grpc_load_reporting_filter);
+  grpc_channel_init_register_stage(GRPC_SERVER_CHANNEL, INT_MAX,
+                                   maybe_add_load_reporting_filter,
+                                   (void *)&grpc_load_reporting_filter);
+}
+
+void grpc_load_reporting_plugin_shutdown() {}
diff --git a/src/core/ext/load_reporting/load_reporting.h b/src/core/ext/load_reporting/load_reporting.h
new file mode 100644
index 0000000..316cd89
--- /dev/null
+++ b/src/core/ext/load_reporting/load_reporting.h
@@ -0,0 +1,75 @@
+/*
+ *
+ * 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_EXT_LOAD_REPORTING_LOAD_REPORTING_H
+#define GRPC_CORE_EXT_LOAD_REPORTING_LOAD_REPORTING_H
+
+#include "src/core/lib/iomgr/closure.h"
+#include "src/core/lib/surface/call.h"
+
+typedef struct grpc_load_reporting_config grpc_load_reporting_config;
+
+/** Call information to be passed to the provided load reporting function upon
+ * completion of the call */
+typedef struct grpc_load_reporting_call_data {
+  const grpc_call_stats *stats;   /**< Stats for the call */
+  const char *trailing_md_string; /**< LR trailing metadata info */
+} grpc_load_reporting_call_data;
+
+/** Custom function to be called by the load reporting filter. */
+typedef void (*grpc_load_reporting_fn)(
+    const grpc_load_reporting_call_data *call_data, void *user_data);
+
+/** Register \a fn as the function to be invoked by the load reporting filter.
+ * \a fn will be invoked at the beginning and at the end of the call.
+ *
+ * For the first invocation, \a fn's first argument
+ * (grpc_load_reporting_call_data*) will be NULL. \a user_data is always passed
+ * as-is. */
+grpc_load_reporting_config *grpc_load_reporting_config_create(
+    grpc_load_reporting_fn fn, void *user_data);
+
+grpc_load_reporting_config *grpc_load_reporting_config_copy(
+    grpc_load_reporting_config *src);
+
+void grpc_load_reporting_config_destroy(grpc_load_reporting_config *lrc);
+
+/** Invoke the function registered by \a grpc_load_reporting_init. */
+void grpc_load_reporting_config_call(
+    grpc_load_reporting_config *lrc,
+    const grpc_load_reporting_call_data *call_data);
+
+/** Return a \a grpc_arg enabling load reporting */
+grpc_arg grpc_load_reporting_config_create_arg(grpc_load_reporting_config *lrc);
+
+#endif /* GRPC_CORE_EXT_LOAD_REPORTING_LOAD_REPORTING_H */
diff --git a/src/core/ext/load_reporting/load_reporting_filter.c b/src/core/ext/load_reporting/load_reporting_filter.c
new file mode 100644
index 0000000..f372f88
--- /dev/null
+++ b/src/core/ext/load_reporting/load_reporting_filter.c
@@ -0,0 +1,151 @@
+/*
+ *
+ * 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 <grpc/support/log.h>
+#include <grpc/support/string_util.h>
+#include <grpc/support/sync.h>
+#include <string.h>
+
+#include "src/core/ext/load_reporting/load_reporting.h"
+#include "src/core/ext/load_reporting/load_reporting_filter.h"
+#include "src/core/lib/channel/channel_args.h"
+#include "src/core/lib/profiling/timers.h"
+#include "src/core/lib/transport/static_metadata.h"
+
+typedef struct call_data { const char *trailing_md_string; } call_data;
+typedef struct channel_data {
+  gpr_mu mu;
+  grpc_load_reporting_config *lrc;
+} channel_data;
+
+static void invoke_lr_fn_locked(grpc_load_reporting_config *lrc,
+                                grpc_load_reporting_call_data *lr_call_data) {
+  GPR_TIMER_BEGIN("load_reporting_config_fn", 0);
+  grpc_load_reporting_config_call(lrc, lr_call_data);
+  GPR_TIMER_END("load_reporting_config_fn", 0);
+}
+
+/* Constructor for call_data */
+static void init_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
+                           grpc_call_element_args *args) {
+  call_data *calld = elem->call_data;
+  memset(calld, 0, sizeof(call_data));
+}
+
+/* Destructor for call_data */
+static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
+                              const grpc_call_stats *stats, void *ignored) {
+  channel_data *chand = elem->channel_data;
+  call_data *calld = elem->call_data;
+
+  grpc_load_reporting_call_data lr_call_data = {stats,
+                                                calld->trailing_md_string};
+
+  gpr_mu_lock(&chand->mu);
+  invoke_lr_fn_locked(chand->lrc, &lr_call_data);
+  gpr_mu_unlock(&chand->mu);
+}
+
+/* Constructor for channel_data */
+static void init_channel_elem(grpc_exec_ctx *exec_ctx,
+                              grpc_channel_element *elem,
+                              grpc_channel_element_args *args) {
+  GPR_ASSERT(!args->is_last);
+
+  channel_data *chand = elem->channel_data;
+  memset(chand, 0, sizeof(channel_data));
+
+  gpr_mu_init(&chand->mu);
+  for (size_t i = 0; i < args->channel_args->num_args; i++) {
+    if (0 == strcmp(args->channel_args->args[i].key,
+                    GRPC_ARG_ENABLE_LOAD_REPORTING)) {
+      grpc_load_reporting_config *arg_lrc =
+          args->channel_args->args[i].value.pointer.p;
+      chand->lrc = grpc_load_reporting_config_copy(arg_lrc);
+      GPR_ASSERT(chand->lrc != NULL);
+      break;
+    }
+  }
+  GPR_ASSERT(chand->lrc != NULL); /* arg actually found */
+
+  gpr_mu_lock(&chand->mu);
+  invoke_lr_fn_locked(chand->lrc, NULL);
+  gpr_mu_unlock(&chand->mu);
+}
+
+/* Destructor for channel data */
+static void destroy_channel_elem(grpc_exec_ctx *exec_ctx,
+                                 grpc_channel_element *elem) {
+  channel_data *chand = elem->channel_data;
+  gpr_mu_destroy(&chand->mu);
+  grpc_load_reporting_config_destroy(chand->lrc);
+}
+
+static grpc_mdelem *lr_trailing_md_filter(void *user_data, grpc_mdelem *md) {
+  grpc_call_element *elem = user_data;
+  call_data *calld = elem->call_data;
+
+  if (md->key == GRPC_MDSTR_LOAD_REPORTING) {
+    calld->trailing_md_string = gpr_strdup(grpc_mdstr_as_c_string(md->value));
+    return NULL;
+  }
+
+  return md;
+}
+
+static void lr_start_transport_stream_op(grpc_exec_ctx *exec_ctx,
+                                         grpc_call_element *elem,
+                                         grpc_transport_stream_op *op) {
+  GPR_TIMER_BEGIN("lr_start_transport_stream_op", 0);
+
+  if (op->send_trailing_metadata) {
+    grpc_metadata_batch_filter(op->send_trailing_metadata,
+                               lr_trailing_md_filter, elem);
+  }
+  grpc_call_next_op(exec_ctx, elem, op);
+
+  GPR_TIMER_END("lr_start_transport_stream_op", 0);
+}
+
+const grpc_channel_filter grpc_load_reporting_filter = {
+    lr_start_transport_stream_op,
+    grpc_channel_next_op,
+    sizeof(call_data),
+    init_call_elem,
+    grpc_call_stack_ignore_set_pollset_or_pollset_set,
+    destroy_call_elem,
+    sizeof(channel_data),
+    init_channel_elem,
+    destroy_channel_elem,
+    grpc_call_next_get_peer,
+    "load_reporting"};
diff --git a/include/grpc/support/atm_win32.h b/src/core/ext/load_reporting/load_reporting_filter.h
similarity index 81%
copy from include/grpc/support/atm_win32.h
copy to src/core/ext/load_reporting/load_reporting_filter.h
index 13526d9..f69cd6f 100644
--- a/include/grpc/support/atm_win32.h
+++ b/src/core/ext/load_reporting/load_reporting_filter.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,9 +31,11 @@
  *
  */
 
-#ifndef GRPC_SUPPORT_ATM_WIN32_H
-#define GRPC_SUPPORT_ATM_WIN32_H
+#ifndef GRPC_CORE_EXT_LOAD_REPORTING_LOAD_REPORTING_FILTER_H
+#define GRPC_CORE_EXT_LOAD_REPORTING_LOAD_REPORTING_FILTER_H
 
-#include <grpc/impl/codegen/atm_win32.h>
+#include "src/core/lib/channel/channel_stack.h"
 
-#endif /* GRPC_SUPPORT_ATM_WIN32_H */
+extern const grpc_channel_filter grpc_load_reporting_filter;
+
+#endif /* GRPC_CORE_EXT_LOAD_REPORTING_LOAD_REPORTING_FILTER_H */
diff --git a/src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c b/src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c
new file mode 100644
index 0000000..ca435c2
--- /dev/null
+++ b/src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c
@@ -0,0 +1,95 @@
+/*
+ *
+ * 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 <grpc/grpc.h>
+#include <grpc/grpc_posix.h>
+#include <grpc/support/log.h>
+#include <grpc/support/port_platform.h>
+
+#ifdef GPR_SUPPORT_CHANNELS_FROM_FD
+
+#include <fcntl.h>
+
+#include "src/core/ext/transport/chttp2/transport/chttp2_transport.h"
+#include "src/core/lib/channel/channel_args.h"
+#include "src/core/lib/iomgr/endpoint.h"
+#include "src/core/lib/iomgr/exec_ctx.h"
+#include "src/core/lib/iomgr/tcp_posix.h"
+#include "src/core/lib/surface/api_trace.h"
+#include "src/core/lib/surface/channel.h"
+#include "src/core/lib/transport/transport.h"
+
+grpc_channel *grpc_insecure_channel_create_from_fd(
+    const char *target, int fd, const grpc_channel_args *args) {
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+  GRPC_API_TRACE("grpc_insecure_channel_create(target=%p, fd=%d, args=%p)", 3,
+                 (target, fd, args));
+
+  grpc_arg default_authority_arg;
+  default_authority_arg.type = GRPC_ARG_STRING;
+  default_authority_arg.key = GRPC_ARG_DEFAULT_AUTHORITY;
+  default_authority_arg.value.string = "test.authority";
+  grpc_channel_args *final_args =
+      grpc_channel_args_copy_and_add(args, &default_authority_arg, 1);
+
+  int flags = fcntl(fd, F_GETFL, 0);
+  GPR_ASSERT(fcntl(fd, F_SETFL, flags | O_NONBLOCK) == 0);
+
+  grpc_endpoint *client =
+      grpc_tcp_create(grpc_fd_create(fd, "client"),
+                      GRPC_TCP_DEFAULT_READ_SLICE_SIZE, "fd-client");
+
+  grpc_transport *transport =
+      grpc_create_chttp2_transport(&exec_ctx, final_args, client, 1);
+  GPR_ASSERT(transport);
+  grpc_channel *channel = grpc_channel_create(
+      &exec_ctx, target, final_args, GRPC_CLIENT_DIRECT_CHANNEL, transport);
+  grpc_channel_args_destroy(final_args);
+  grpc_chttp2_transport_start_reading(&exec_ctx, transport, NULL, 0);
+
+  grpc_exec_ctx_finish(&exec_ctx);
+
+  return channel != NULL ? channel : grpc_lame_client_channel_create(
+                                         target, GRPC_STATUS_INTERNAL,
+                                         "Failed to create client channel");
+}
+
+#else  // !GPR_SUPPORT_CHANNELS_FROM_FD
+
+grpc_channel *grpc_insecure_channel_create_from_fd(
+    const char *target, int fd, const grpc_channel_args *args) {
+  GPR_ASSERT(0);
+  return NULL;
+}
+
+#endif  // GPR_SUPPORT_CHANNELS_FROM_FD
diff --git a/src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.c b/src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.c
new file mode 100644
index 0000000..96bf4d6
--- /dev/null
+++ b/src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.c
@@ -0,0 +1,82 @@
+/*
+ *
+ * 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 <grpc/grpc.h>
+#include <grpc/grpc_posix.h>
+#include <grpc/support/log.h>
+#include <grpc/support/port_platform.h>
+
+#ifdef GPR_SUPPORT_CHANNELS_FROM_FD
+
+#include <grpc/support/alloc.h>
+#include <grpc/support/string_util.h>
+
+#include "src/core/ext/transport/chttp2/transport/chttp2_transport.h"
+#include "src/core/lib/channel/channel_args.h"
+#include "src/core/lib/iomgr/endpoint.h"
+#include "src/core/lib/iomgr/exec_ctx.h"
+#include "src/core/lib/iomgr/tcp_posix.h"
+#include "src/core/lib/surface/completion_queue.h"
+#include "src/core/lib/surface/server.h"
+
+void grpc_server_add_insecure_channel_from_fd(grpc_server *server,
+                                              grpc_completion_queue *cq,
+                                              int fd) {
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+
+  char *name;
+  gpr_asprintf(&name, "fd:%d", fd);
+
+  grpc_endpoint *server_endpoint = grpc_tcp_create(
+      grpc_fd_create(fd, name), GRPC_TCP_DEFAULT_READ_SLICE_SIZE, name);
+
+  gpr_free(name);
+
+  const grpc_channel_args *server_args = grpc_server_get_channel_args(server);
+  grpc_transport *transport = grpc_create_chttp2_transport(
+      &exec_ctx, server_args, server_endpoint, 0 /* is_client */);
+  grpc_endpoint_add_to_pollset(&exec_ctx, server_endpoint, grpc_cq_pollset(cq));
+  grpc_server_setup_transport(&exec_ctx, server, transport, NULL, server_args);
+  grpc_chttp2_transport_start_reading(&exec_ctx, transport, NULL, 0);
+  grpc_exec_ctx_finish(&exec_ctx);
+}
+
+#else  // !GPR_SUPPORT_CHANNELS_FROM_FD
+
+void grpc_server_add_insecure_channel_from_fd(grpc_server *server,
+                                              grpc_completion_queue *cq,
+                                              int fd) {
+  GPR_ASSERT(0);
+}
+
+#endif  // GPR_SUPPORT_CHANNELS_FROM_FD
diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.c b/src/core/ext/transport/chttp2/transport/chttp2_transport.c
index b6886a2..2375a45 100644
--- a/src/core/ext/transport/chttp2/transport/chttp2_transport.c
+++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.c
@@ -47,6 +47,7 @@
 #include "src/core/ext/transport/chttp2/transport/internal.h"
 #include "src/core/ext/transport/chttp2/transport/status_conversion.h"
 #include "src/core/ext/transport/chttp2/transport/timeout_encoding.h"
+#include "src/core/lib/http/parser.h"
 #include "src/core/lib/profiling/timers.h"
 #include "src/core/lib/support/string.h"
 #include "src/core/lib/transport/static_metadata.h"
@@ -107,7 +108,8 @@
 static void cancel_from_api(grpc_exec_ctx *exec_ctx,
                             grpc_chttp2_transport_global *transport_global,
                             grpc_chttp2_stream_global *stream_global,
-                            grpc_status_code status);
+                            grpc_status_code status,
+                            gpr_slice *optional_message);
 
 static void close_from_api(grpc_exec_ctx *exec_ctx,
                            grpc_chttp2_transport_global *transport_global,
@@ -161,6 +163,8 @@
 
   GPR_ASSERT(t->ep == NULL);
 
+  gpr_slice_unref(t->optional_drop_message);
+
   gpr_slice_buffer_destroy(&t->global.qbuf);
 
   gpr_slice_buffer_destroy(&t->writing.outbuf);
@@ -260,6 +264,7 @@
   t->parsing.deframe_state =
       is_client ? GRPC_DTS_FH_0 : GRPC_DTS_CLIENT_PREFIX_0;
   t->writing.is_client = is_client;
+  t->optional_drop_message = gpr_empty_slice();
   grpc_connectivity_state_init(
       &t->channel_callback.state_tracker, GRPC_CHANNEL_READY,
       is_client ? "client_transport" : "server_transport");
@@ -444,7 +449,7 @@
                                    void *arg_ignored) {
   if (!t->closed) {
     t->closed = 1;
-    connectivity_state_set(exec_ctx, &t->global, GRPC_CHANNEL_FATAL_FAILURE,
+    connectivity_state_set(exec_ctx, &t->global, GRPC_CHANNEL_SHUTDOWN,
                            "close_transport");
     if (t->ep) {
       allow_endpoint_shutdown_locked(exec_ctx, t);
@@ -804,8 +809,10 @@
   gpr_free(msg);
   gpr_slice_unref(goaway_text);
   transport_global->seen_goaway = 1;
-  connectivity_state_set(exec_ctx, transport_global, GRPC_CHANNEL_FATAL_FAILURE,
-                         "got_goaway");
+  /* lie: use transient failure from the transport to indicate goaway has been
+   * received */
+  connectivity_state_set(exec_ctx, transport_global,
+                         GRPC_CHANNEL_TRANSIENT_FAILURE, "got_goaway");
 }
 
 static void maybe_start_some_streams(
@@ -859,7 +866,7 @@
          grpc_chttp2_list_pop_waiting_for_concurrency(transport_global,
                                                       &stream_global)) {
     cancel_from_api(exec_ctx, transport_global, stream_global,
-                    GRPC_STATUS_UNAVAILABLE);
+                    GRPC_STATUS_UNAVAILABLE, NULL);
   }
 }
 
@@ -936,7 +943,7 @@
 
   if (op->cancel_with_status != GRPC_STATUS_OK) {
     cancel_from_api(exec_ctx, transport_global, stream_global,
-                    op->cancel_with_status);
+                    op->cancel_with_status, op->optional_close_message);
   }
 
   if (op->close_with_status != GRPC_STATUS_OK) {
@@ -960,7 +967,7 @@
               "(%lu vs. %lu)",
               metadata_size, metadata_peer_limit);
       cancel_from_api(exec_ctx, transport_global, stream_global,
-                      GRPC_STATUS_RESOURCE_EXHAUSTED);
+                      GRPC_STATUS_RESOURCE_EXHAUSTED, NULL);
     } else {
       if (contains_non_ok_status(transport_global, op->send_initial_metadata)) {
         stream_global->seen_error = true;
@@ -1015,7 +1022,7 @@
               "(%lu vs. %lu)",
               metadata_size, metadata_peer_limit);
       cancel_from_api(exec_ctx, transport_global, stream_global,
-                      GRPC_STATUS_RESOURCE_EXHAUSTED);
+                      GRPC_STATUS_RESOURCE_EXHAUSTED, NULL);
     } else {
       if (contains_non_ok_status(transport_global,
                                  op->send_trailing_metadata)) {
@@ -1201,7 +1208,7 @@
         }
         if (stream_global->exceeded_metadata_size) {
           cancel_from_api(exec_ctx, transport_global, stream_global,
-                          GRPC_STATUS_RESOURCE_EXHAUSTED);
+                          GRPC_STATUS_RESOURCE_EXHAUSTED, NULL);
         }
       }
       grpc_chttp2_incoming_metadata_buffer_publish(
@@ -1240,7 +1247,7 @@
         }
         if (stream_global->exceeded_metadata_size) {
           cancel_from_api(exec_ctx, transport_global, stream_global,
-                          GRPC_STATUS_RESOURCE_EXHAUSTED);
+                          GRPC_STATUS_RESOURCE_EXHAUSTED, NULL);
         }
       }
       if (stream_global->all_incoming_byte_streams_finished) {
@@ -1303,7 +1310,8 @@
 static void cancel_from_api(grpc_exec_ctx *exec_ctx,
                             grpc_chttp2_transport_global *transport_global,
                             grpc_chttp2_stream_global *stream_global,
-                            grpc_status_code status) {
+                            grpc_status_code status,
+                            gpr_slice *optional_message) {
   if (!stream_global->read_closed || !stream_global->write_closed) {
     if (stream_global->id != 0) {
       gpr_slice_buffer_add(
@@ -1313,8 +1321,12 @@
               (uint32_t)grpc_chttp2_grpc_status_to_http2_error(status),
               &stream_global->stats.outgoing));
     }
+
+    if (optional_message) {
+      gpr_slice_ref(*optional_message);
+    }
     grpc_chttp2_fake_status(exec_ctx, transport_global, stream_global, status,
-                            NULL);
+                            optional_message);
   }
   if (status != GRPC_STATUS_OK && !stream_global->seen_error) {
     stream_global->seen_error = true;
@@ -1426,93 +1438,95 @@
 
   GPR_ASSERT(status >= 0 && (int)status < 100);
 
-  GPR_ASSERT(stream_global->id != 0);
-
-  /* Hand roll a header block.
-     This is unnecessarily ugly - at some point we should find a more elegant
-     solution.
-     It's complicated by the fact that our send machinery would be dead by the
-     time we got around to sending this, so instead we ignore HPACK compression
-     and just write the uncompressed bytes onto the wire. */
-  status_hdr = gpr_slice_malloc(15 + (status >= 10));
-  p = GPR_SLICE_START_PTR(status_hdr);
-  *p++ = 0x40; /* literal header */
-  *p++ = 11;   /* len(grpc-status) */
-  *p++ = 'g';
-  *p++ = 'r';
-  *p++ = 'p';
-  *p++ = 'c';
-  *p++ = '-';
-  *p++ = 's';
-  *p++ = 't';
-  *p++ = 'a';
-  *p++ = 't';
-  *p++ = 'u';
-  *p++ = 's';
-  if (status < 10) {
-    *p++ = 1;
-    *p++ = (uint8_t)('0' + status);
-  } else {
-    *p++ = 2;
-    *p++ = (uint8_t)('0' + (status / 10));
-    *p++ = (uint8_t)('0' + (status % 10));
-  }
-  GPR_ASSERT(p == GPR_SLICE_END_PTR(status_hdr));
-  len += (uint32_t)GPR_SLICE_LENGTH(status_hdr);
-
-  if (optional_message) {
-    GPR_ASSERT(GPR_SLICE_LENGTH(*optional_message) < 127);
-    message_pfx = gpr_slice_malloc(15);
-    p = GPR_SLICE_START_PTR(message_pfx);
-    *p++ = 0x40;
-    *p++ = 12; /* len(grpc-message) */
+  if (stream_global->id != 0 && !transport_global->is_client) {
+    /* Hand roll a header block.
+       This is unnecessarily ugly - at some point we should find a more elegant
+       solution.
+       It's complicated by the fact that our send machinery would be dead by the
+       time we got around to sending this, so instead we ignore HPACK
+       compression
+       and just write the uncompressed bytes onto the wire. */
+    status_hdr = gpr_slice_malloc(15 + (status >= 10));
+    p = GPR_SLICE_START_PTR(status_hdr);
+    *p++ = 0x40; /* literal header */
+    *p++ = 11;   /* len(grpc-status) */
     *p++ = 'g';
     *p++ = 'r';
     *p++ = 'p';
     *p++ = 'c';
     *p++ = '-';
-    *p++ = 'm';
-    *p++ = 'e';
     *p++ = 's';
-    *p++ = 's';
+    *p++ = 't';
     *p++ = 'a';
-    *p++ = 'g';
-    *p++ = 'e';
-    *p++ = (uint8_t)GPR_SLICE_LENGTH(*optional_message);
-    GPR_ASSERT(p == GPR_SLICE_END_PTR(message_pfx));
-    len += (uint32_t)GPR_SLICE_LENGTH(message_pfx);
-    len += (uint32_t)GPR_SLICE_LENGTH(*optional_message);
+    *p++ = 't';
+    *p++ = 'u';
+    *p++ = 's';
+    if (status < 10) {
+      *p++ = 1;
+      *p++ = (uint8_t)('0' + status);
+    } else {
+      *p++ = 2;
+      *p++ = (uint8_t)('0' + (status / 10));
+      *p++ = (uint8_t)('0' + (status % 10));
+    }
+    GPR_ASSERT(p == GPR_SLICE_END_PTR(status_hdr));
+    len += (uint32_t)GPR_SLICE_LENGTH(status_hdr);
+
+    if (optional_message) {
+      GPR_ASSERT(GPR_SLICE_LENGTH(*optional_message) < 127);
+      message_pfx = gpr_slice_malloc(15);
+      p = GPR_SLICE_START_PTR(message_pfx);
+      *p++ = 0x40;
+      *p++ = 12; /* len(grpc-message) */
+      *p++ = 'g';
+      *p++ = 'r';
+      *p++ = 'p';
+      *p++ = 'c';
+      *p++ = '-';
+      *p++ = 'm';
+      *p++ = 'e';
+      *p++ = 's';
+      *p++ = 's';
+      *p++ = 'a';
+      *p++ = 'g';
+      *p++ = 'e';
+      *p++ = (uint8_t)GPR_SLICE_LENGTH(*optional_message);
+      GPR_ASSERT(p == GPR_SLICE_END_PTR(message_pfx));
+      len += (uint32_t)GPR_SLICE_LENGTH(message_pfx);
+      len += (uint32_t)GPR_SLICE_LENGTH(*optional_message);
+    }
+
+    hdr = gpr_slice_malloc(9);
+    p = GPR_SLICE_START_PTR(hdr);
+    *p++ = (uint8_t)(len >> 16);
+    *p++ = (uint8_t)(len >> 8);
+    *p++ = (uint8_t)(len);
+    *p++ = GRPC_CHTTP2_FRAME_HEADER;
+    *p++ = GRPC_CHTTP2_DATA_FLAG_END_STREAM | GRPC_CHTTP2_DATA_FLAG_END_HEADERS;
+    *p++ = (uint8_t)(stream_global->id >> 24);
+    *p++ = (uint8_t)(stream_global->id >> 16);
+    *p++ = (uint8_t)(stream_global->id >> 8);
+    *p++ = (uint8_t)(stream_global->id);
+    GPR_ASSERT(p == GPR_SLICE_END_PTR(hdr));
+
+    gpr_slice_buffer_add(&transport_global->qbuf, hdr);
+    gpr_slice_buffer_add(&transport_global->qbuf, status_hdr);
+    if (optional_message) {
+      gpr_slice_buffer_add(&transport_global->qbuf, message_pfx);
+      gpr_slice_buffer_add(&transport_global->qbuf,
+                           gpr_slice_ref(*optional_message));
+    }
+
+    gpr_slice_buffer_add(
+        &transport_global->qbuf,
+        grpc_chttp2_rst_stream_create(stream_global->id, GRPC_CHTTP2_NO_ERROR,
+                                      &stream_global->stats.outgoing));
+
+    if (optional_message) {
+      gpr_slice_ref(*optional_message);
+    }
   }
 
-  hdr = gpr_slice_malloc(9);
-  p = GPR_SLICE_START_PTR(hdr);
-  *p++ = (uint8_t)(len >> 16);
-  *p++ = (uint8_t)(len >> 8);
-  *p++ = (uint8_t)(len);
-  *p++ = GRPC_CHTTP2_FRAME_HEADER;
-  *p++ = GRPC_CHTTP2_DATA_FLAG_END_STREAM | GRPC_CHTTP2_DATA_FLAG_END_HEADERS;
-  *p++ = (uint8_t)(stream_global->id >> 24);
-  *p++ = (uint8_t)(stream_global->id >> 16);
-  *p++ = (uint8_t)(stream_global->id >> 8);
-  *p++ = (uint8_t)(stream_global->id);
-  GPR_ASSERT(p == GPR_SLICE_END_PTR(hdr));
-
-  gpr_slice_buffer_add(&transport_global->qbuf, hdr);
-  gpr_slice_buffer_add(&transport_global->qbuf, status_hdr);
-  if (optional_message) {
-    gpr_slice_buffer_add(&transport_global->qbuf, message_pfx);
-    gpr_slice_buffer_add(&transport_global->qbuf,
-                         gpr_slice_ref(*optional_message));
-  }
-
-  gpr_slice_buffer_add(
-      &transport_global->qbuf,
-      grpc_chttp2_rst_stream_create(stream_global->id, GRPC_CHTTP2_NO_ERROR,
-                                    &stream_global->stats.outgoing));
-
-  if (optional_message) {
-    gpr_slice_ref(*optional_message);
-  }
   grpc_chttp2_fake_status(exec_ctx, transport_global, stream_global, status,
                           optional_message);
   grpc_chttp2_mark_stream_closed(exec_ctx, transport_global, stream_global, 1,
@@ -1522,8 +1536,12 @@
 static void cancel_stream_cb(grpc_chttp2_transport_global *transport_global,
                              void *user_data,
                              grpc_chttp2_stream_global *stream_global) {
+  grpc_chttp2_transport *transport = TRANSPORT_FROM_GLOBAL(transport_global);
   cancel_from_api(user_data, transport_global, stream_global,
-                  GRPC_STATUS_UNAVAILABLE);
+                  GRPC_STATUS_UNAVAILABLE,
+                  GPR_SLICE_IS_EMPTY(transport->optional_drop_message)
+                      ? NULL
+                      : &transport->optional_drop_message);
 }
 
 static void end_all_the_calls(grpc_exec_ctx *exec_ctx,
@@ -1599,6 +1617,29 @@
   }
 }
 
+static bool try_http_parsing(grpc_exec_ctx *exec_ctx,
+                             grpc_chttp2_transport *t) {
+  grpc_http_parser parser;
+  size_t i = 0;
+  bool success = false;
+
+  grpc_http_parser_init(&parser);
+
+  for (; i < t->read_buffer.count &&
+         grpc_http_parser_parse(&parser, t->read_buffer.slices[i]);
+       i++)
+    ;
+  if (grpc_http_parser_eof(&parser) && parser.type == GRPC_HTTP_RESPONSE) {
+    success = true;
+    GRPC_CHTTP2_IF_TRACING(gpr_log(
+        GPR_DEBUG, "Trying to connect an http1.x server, received status:%d",
+        parser.http.response.status));
+  }
+
+  grpc_http_parser_destroy(&parser);
+  return success;
+}
+
 static void parsing_action(grpc_exec_ctx *exec_ctx, void *arg, bool success) {
   grpc_chttp2_transport *t = arg;
   GPR_TIMER_BEGIN("reading_action.parse", 0);
@@ -1610,6 +1651,14 @@
     ;
   if (i != t->read_buffer.count) {
     success = false;
+    gpr_slice_unref(t->optional_drop_message);
+    if (try_http_parsing(exec_ctx, t)) {
+      t->optional_drop_message = gpr_slice_from_copied_string(
+          "Connection dropped: received http1.x response");
+    } else {
+      t->optional_drop_message = gpr_slice_from_copied_string(
+          "Connection dropped: received unparseable response");
+    }
   }
   GPR_TIMER_END("reading_action.parse", 0);
   grpc_chttp2_run_with_global_lock(exec_ctx, t, NULL, post_parse_locked,
@@ -1732,6 +1781,13 @@
                                    add_to_pollset_locked, pollset, 0);
 }
 
+static void set_pollset_set(grpc_exec_ctx *exec_ctx, grpc_transport *gt,
+                            grpc_stream *gs, grpc_pollset_set *pollset_set) {
+  grpc_chttp2_run_with_global_lock(exec_ctx, (grpc_chttp2_transport *)gt,
+                                   (grpc_chttp2_stream *)gs,
+                                   add_to_pollset_set_locked, pollset_set, 0);
+}
+
 /*******************************************************************************
  * BYTE STREAM
  */
@@ -2053,6 +2109,7 @@
                                              "chttp2",
                                              init_stream,
                                              set_pollset,
+                                             set_pollset_set,
                                              perform_stream_op,
                                              perform_transport_op,
                                              destroy_stream,
diff --git a/src/core/ext/transport/chttp2/transport/internal.h b/src/core/ext/transport/chttp2/transport/internal.h
index 5872fd8..7f3339a 100644
--- a/src/core/ext/transport/chttp2/transport/internal.h
+++ b/src/core/ext/transport/chttp2/transport/internal.h
@@ -383,6 +383,9 @@
 
   /** Transport op to be applied post-parsing */
   grpc_transport_op *post_parsing_op;
+
+  /** Message explaining the reason of dropping connection */
+  gpr_slice optional_drop_message;
 };
 
 typedef struct {
diff --git a/src/core/ext/transport/cronet/transport/cronet_transport.c b/src/core/ext/transport/cronet/transport/cronet_transport.c
index 5bb0851..1bb53b7 100644
--- a/src/core/ext/transport/cronet/transport/cronet_transport.c
+++ b/src/core/ext/transport/cronet/transport/cronet_transport.c
@@ -152,6 +152,10 @@
 static void set_pollset_do_nothing(grpc_exec_ctx *exec_ctx, grpc_transport *gt,
                                    grpc_stream *gs, grpc_pollset *pollset) {}
 
+static void set_pollset_set_do_nothing(grpc_exec_ctx *exec_ctx,
+                                       grpc_transport *gt, grpc_stream *gs,
+                                       grpc_pollset_set *pollset_set) {}
+
 static void enqueue_callbacks(grpc_closure *callback_list[]) {
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   if (callback_list[0]) {
@@ -218,8 +222,11 @@
 static void process_recv_message(stream_obj *s, const uint8_t *recv_data) {
   gpr_slice read_data_slice = gpr_slice_malloc((uint32_t)s->total_read_bytes);
   uint8_t *dst_p = GPR_SLICE_START_PTR(read_data_slice);
-  memcpy(dst_p, recv_data, (size_t)s->total_read_bytes);
-  gpr_slice_buffer_add(&s->read_slice_buffer, read_data_slice);
+  if (s->total_read_bytes > 0) {
+    // Only copy if there is non-zero number of bytes
+    memcpy(dst_p, recv_data, (size_t)s->total_read_bytes);
+    gpr_slice_buffer_add(&s->read_slice_buffer, read_data_slice);
+  }
   grpc_slice_buffer_stream_init(&s->sbs, &s->read_slice_buffer, 0);
   *s->recv_message = (grpc_byte_buffer *)&s->sbs;
 }
@@ -347,8 +354,17 @@
           if (grpc_cronet_trace) {
             gpr_log(GPR_DEBUG, "R: cronet_bidirectional_stream_read()");
           }
-          cronet_bidirectional_stream_read(s->cbs, (char *)s->read_buffer,
-                                           s->remaining_read_bytes);
+          if (s->remaining_read_bytes > 0) {
+            cronet_bidirectional_stream_read(s->cbs, (char *)s->read_buffer,
+                                             s->remaining_read_bytes);
+          } else {
+            // Calling the closing callback directly since this is a 0 byte read
+            // for an empty message.
+            process_recv_message(s, NULL);
+            enqueue_callbacks(s->callback_list[CB_RECV_MESSAGE]);
+            invoke_closing_callback(s);
+            set_recv_state(s, CRONET_RECV_CLOSED);
+          }
         }
       }
       break;
@@ -634,7 +650,13 @@
   }
 }
 
-const grpc_transport_vtable grpc_cronet_vtable = {
-    sizeof(stream_obj),     "cronet_http",     init_stream,
-    set_pollset_do_nothing, perform_stream_op, NULL,
-    destroy_stream,         destroy_transport, NULL};
+const grpc_transport_vtable grpc_cronet_vtable = {sizeof(stream_obj),
+                                                  "cronet_http",
+                                                  init_stream,
+                                                  set_pollset_do_nothing,
+                                                  set_pollset_set_do_nothing,
+                                                  perform_stream_op,
+                                                  NULL,
+                                                  destroy_stream,
+                                                  destroy_transport,
+                                                  NULL};
diff --git a/src/core/lib/channel/channel_args.c b/src/core/lib/channel/channel_args.c
index 569be4d..d53ce90 100644
--- a/src/core/lib/channel/channel_args.c
+++ b/src/core/lib/channel/channel_args.c
@@ -35,6 +35,7 @@
 #include <grpc/grpc.h>
 #include "src/core/lib/support/string.h"
 
+#include <grpc/compression.h>
 #include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
 #include <grpc/support/string_util.h>
@@ -181,6 +182,7 @@
 
 grpc_channel_args *grpc_channel_args_set_compression_algorithm(
     grpc_channel_args *a, grpc_compression_algorithm algorithm) {
+  GPR_ASSERT(algorithm < GRPC_COMPRESS_ALGORITHMS_COUNT);
   grpc_arg tmp;
   tmp.type = GRPC_ARG_INTEGER;
   tmp.key = GRPC_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM;
@@ -200,7 +202,8 @@
           !strcmp(GRPC_COMPRESSION_CHANNEL_ENABLED_ALGORITHMS_BITSET,
                   a->args[i].key)) {
         *states_arg = &a->args[i].value.integer;
-        return 1; /* GPR_TRUE */
+        **states_arg |= 0x1; /* forcefully enable support for no compression */
+        return 1;
       }
     }
   }
@@ -214,10 +217,18 @@
   const int states_arg_found =
       find_compression_algorithm_states_bitset(*a, &states_arg);
 
-  if (states_arg_found) {
+  if (grpc_channel_args_get_compression_algorithm(*a) == algorithm &&
+      state == 0) {
+    char *algo_name = NULL;
+    GPR_ASSERT(grpc_compression_algorithm_name(algorithm, &algo_name) != 0);
+    gpr_log(GPR_ERROR,
+            "Tried to disable default compression algorithm '%s'. The "
+            "operation has been ignored.",
+            algo_name);
+  } else if (states_arg_found) {
     if (state != 0) {
       GPR_BITSET((unsigned *)states_arg, algorithm);
-    } else {
+    } else if (algorithm != GRPC_COMPRESS_NONE) {
       GPR_BITCLEAR((unsigned *)states_arg, algorithm);
     }
   } else {
@@ -229,7 +240,7 @@
     tmp.value.integer = (1u << GRPC_COMPRESS_ALGORITHMS_COUNT) - 1;
     if (state != 0) {
       GPR_BITSET((unsigned *)&tmp.value.integer, algorithm);
-    } else {
+    } else if (algorithm != GRPC_COMPRESS_NONE) {
       GPR_BITCLEAR((unsigned *)&tmp.value.integer, algorithm);
     }
     result = grpc_channel_args_copy_and_add(*a, &tmp, 1);
@@ -239,11 +250,11 @@
   return result;
 }
 
-int grpc_channel_args_compression_algorithm_get_states(
+uint32_t grpc_channel_args_compression_algorithm_get_states(
     const grpc_channel_args *a) {
   int *states_arg;
   if (find_compression_algorithm_states_bitset(a, &states_arg)) {
-    return *states_arg;
+    return (uint32_t)*states_arg;
   } else {
     return (1u << GRPC_COMPRESS_ALGORITHMS_COUNT) - 1; /* All algs. enabled */
   }
diff --git a/src/core/lib/channel/channel_args.h b/src/core/lib/channel/channel_args.h
index 23c7b7b..653d04f 100644
--- a/src/core/lib/channel/channel_args.h
+++ b/src/core/lib/channel/channel_args.h
@@ -81,7 +81,7 @@
  *
  * The i-th bit of the returned bitset corresponds to the i-th entry in the
  * grpc_compression_algorithm enum. */
-int grpc_channel_args_compression_algorithm_get_states(
+uint32_t grpc_channel_args_compression_algorithm_get_states(
     const grpc_channel_args *a);
 
 int grpc_channel_args_compare(const grpc_channel_args *a,
diff --git a/src/core/lib/channel/channel_stack.c b/src/core/lib/channel/channel_stack.c
index ad182d1..bbba85d 100644
--- a/src/core/lib/channel/channel_stack.c
+++ b/src/core/lib/channel/channel_stack.c
@@ -106,6 +106,7 @@
                              const grpc_channel_filter **filters,
                              size_t filter_count,
                              const grpc_channel_args *channel_args,
+                             grpc_transport *optional_transport,
                              const char *name, grpc_channel_stack *stack) {
   size_t call_size =
       ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(grpc_call_stack)) +
@@ -127,6 +128,7 @@
   for (i = 0; i < filter_count; i++) {
     args.channel_stack = stack;
     args.channel_args = channel_args;
+    args.optional_transport = optional_transport;
     args.is_first = i == 0;
     args.is_last = i == (filter_count - 1);
     elems[i].filter = filters[i];
@@ -189,9 +191,9 @@
   }
 }
 
-void grpc_call_stack_set_pollset(grpc_exec_ctx *exec_ctx,
-                                 grpc_call_stack *call_stack,
-                                 grpc_pollset *pollset) {
+void grpc_call_stack_set_pollset_or_pollset_set(grpc_exec_ctx *exec_ctx,
+                                                grpc_call_stack *call_stack,
+                                                grpc_polling_entity *pollent) {
   size_t count = call_stack->count;
   grpc_call_element *call_elems;
   char *user_data;
@@ -203,17 +205,19 @@
 
   /* init per-filter data */
   for (i = 0; i < count; i++) {
-    call_elems[i].filter->set_pollset(exec_ctx, &call_elems[i], pollset);
+    call_elems[i].filter->set_pollset_or_pollset_set(exec_ctx, &call_elems[i],
+                                                     pollent);
     user_data +=
         ROUND_UP_TO_ALIGNMENT_SIZE(call_elems[i].filter->sizeof_call_data);
   }
 }
 
-void grpc_call_stack_ignore_set_pollset(grpc_exec_ctx *exec_ctx,
-                                        grpc_call_element *elem,
-                                        grpc_pollset *pollset) {}
+void grpc_call_stack_ignore_set_pollset_or_pollset_set(
+    grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
+    grpc_polling_entity *pollent) {}
 
 void grpc_call_stack_destroy(grpc_exec_ctx *exec_ctx, grpc_call_stack *stack,
+                             const grpc_call_stats *call_stats,
                              void *and_free_memory) {
   grpc_call_element *elems = CALL_ELEMS_FROM_STACK(stack);
   size_t count = stack->count;
@@ -221,7 +225,7 @@
 
   /* destroy per-filter data */
   for (i = 0; i < count; i++) {
-    elems[i].filter->destroy_call_elem(exec_ctx, &elems[i],
+    elems[i].filter->destroy_call_elem(exec_ctx, &elems[i], call_stats,
                                        i == count - 1 ? and_free_memory : NULL);
   }
 }
diff --git a/src/core/lib/channel/channel_stack.h b/src/core/lib/channel/channel_stack.h
index 36c17cb..41dd4a0 100644
--- a/src/core/lib/channel/channel_stack.h
+++ b/src/core/lib/channel/channel_stack.h
@@ -45,7 +45,10 @@
 
 #include <grpc/grpc.h>
 #include <grpc/support/log.h>
+#include <grpc/support/time.h>
+
 #include "src/core/lib/debug/trace.h"
+#include "src/core/lib/iomgr/polling_entity.h"
 #include "src/core/lib/transport/transport.h"
 
 typedef struct grpc_channel_element grpc_channel_element;
@@ -57,6 +60,8 @@
 typedef struct {
   grpc_channel_stack *channel_stack;
   const grpc_channel_args *channel_args;
+  /** Transport, iff it is known */
+  grpc_transport *optional_transport;
   int is_first;
   int is_last;
 } grpc_channel_element_args;
@@ -67,6 +72,12 @@
   grpc_call_context_element *context;
 } grpc_call_element_args;
 
+typedef struct {
+  grpc_transport_stream_stats transport_stream_stats;
+  gpr_timespec latency; /* From call creating to enqueing of received status */
+  grpc_status_code final_status;
+} grpc_call_stats;
+
 /* Channel filters specify:
    1. the amount of memory needed in the channel & call (via the sizeof_XXX
       members)
@@ -101,14 +112,16 @@
      argument. */
   void (*init_call_elem)(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
                          grpc_call_element_args *args);
-  void (*set_pollset)(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
-                      grpc_pollset *pollset);
+  void (*set_pollset_or_pollset_set)(grpc_exec_ctx *exec_ctx,
+                                     grpc_call_element *elem,
+                                     grpc_polling_entity *pollent);
   /* Destroy per call data.
      The filter does not need to do any chaining.
      The bottom filter of a stack will be passed a non-NULL pointer to
      \a and_free_memory that should be passed to gpr_free when destruction
      is complete. */
   void (*destroy_call_elem)(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
+                            const grpc_call_stats *stats,
                             void *and_free_memory);
 
   /* sizeof(per channel data) */
@@ -187,6 +200,7 @@
                              grpc_iomgr_cb_func destroy, void *destroy_arg,
                              const grpc_channel_filter **filters,
                              size_t filter_count, const grpc_channel_args *args,
+                             grpc_transport *optional_transport,
                              const char *name, grpc_channel_stack *stack);
 /* Destroy a channel stack */
 void grpc_channel_stack_destroy(grpc_exec_ctx *exec_ctx,
@@ -201,10 +215,11 @@
                           grpc_call_context_element *context,
                           const void *transport_server_data,
                           grpc_call_stack *call_stack);
-/* Set a pollset for a call stack: must occur before the first op is started */
-void grpc_call_stack_set_pollset(grpc_exec_ctx *exec_ctx,
-                                 grpc_call_stack *call_stack,
-                                 grpc_pollset *pollset);
+/* Set a pollset or a pollset_set for a call stack: must occur before the first
+ * op is started */
+void grpc_call_stack_set_pollset_or_pollset_set(grpc_exec_ctx *exec_ctx,
+                                                grpc_call_stack *call_stack,
+                                                grpc_polling_entity *pollent);
 
 #ifdef GRPC_STREAM_REFCOUNT_DEBUG
 #define GRPC_CALL_STACK_REF(call_stack, reason) \
@@ -228,13 +243,14 @@
 
 /* Destroy a call stack */
 void grpc_call_stack_destroy(grpc_exec_ctx *exec_ctx, grpc_call_stack *stack,
+                             const grpc_call_stats *call_stats,
                              void *and_free_memory);
 
-/* Ignore set pollset - used by filters to implement the set_pollset method
-   if they don't care about pollsets at all. Does nothing. */
-void grpc_call_stack_ignore_set_pollset(grpc_exec_ctx *exec_ctx,
-                                        grpc_call_element *elem,
-                                        grpc_pollset *pollset);
+/* Ignore set pollset{_set} - used by filters if they don't care about pollsets
+ * at all. Does nothing. */
+void grpc_call_stack_ignore_set_pollset_or_pollset_set(
+    grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
+    grpc_polling_entity *pollent);
 /* Call the next operation in a call stack */
 void grpc_call_next_op(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
                        grpc_transport_stream_op *op);
diff --git a/src/core/lib/channel/channel_stack_builder.c b/src/core/lib/channel/channel_stack_builder.c
index a8646c9..eda4968 100644
--- a/src/core/lib/channel/channel_stack_builder.c
+++ b/src/core/lib/channel/channel_stack_builder.c
@@ -257,8 +257,8 @@
   // and initialize it
   grpc_channel_stack_init(exec_ctx, initial_refs, destroy,
                           destroy_arg == NULL ? result : destroy_arg, filters,
-                          num_filters, builder->args, builder->name,
-                          channel_stack);
+                          num_filters, builder->args, builder->transport,
+                          builder->name, channel_stack);
 
   // run post-initialization functions
   i = 0;
diff --git a/src/core/lib/channel/compress_filter.c b/src/core/lib/channel/compress_filter.c
index 0e548c6..4fe9a7f 100644
--- a/src/core/lib/channel/compress_filter.c
+++ b/src/core/lib/channel/compress_filter.c
@@ -73,8 +73,8 @@
 typedef struct channel_data {
   /** The default, channel-level, compression algorithm */
   grpc_compression_algorithm default_compression_algorithm;
-  /** Compression options for the channel */
-  grpc_compression_options compression_options;
+  /** Bitset of enabled algorithms */
+  uint32_t enabled_algorithms_bitset;
   /** Supported compression algorithms */
   uint32_t supported_compression_algorithms;
 } channel_data;
@@ -96,9 +96,8 @@
               md_c_str);
       calld->compression_algorithm = GRPC_COMPRESS_NONE;
     }
-    if (grpc_compression_options_is_algorithm_enabled(
-            &channeld->compression_options, calld->compression_algorithm) ==
-        0) {
+    if (!GPR_BITGET(channeld->enabled_algorithms_bitset,
+                    calld->compression_algorithm)) {
       gpr_log(GPR_ERROR,
               "Invalid compression algorithm: '%s' (previously disabled). "
               "Ignoring.",
@@ -271,7 +270,7 @@
 
 /* Destructor for call_data */
 static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
-                              void *ignored) {
+                              const grpc_call_stats *stats, void *ignored) {
   /* grab pointers to our data from the call element */
   call_data *calld = elem->call_data;
   gpr_slice_buffer_destroy(&calld->slices);
@@ -282,32 +281,26 @@
                               grpc_channel_element *elem,
                               grpc_channel_element_args *args) {
   channel_data *channeld = elem->channel_data;
-  grpc_compression_algorithm algo_idx;
 
-  grpc_compression_options_init(&channeld->compression_options);
-  channeld->compression_options.enabled_algorithms_bitset =
-      (uint32_t)grpc_channel_args_compression_algorithm_get_states(
-          args->channel_args);
+  channeld->enabled_algorithms_bitset =
+      grpc_channel_args_compression_algorithm_get_states(args->channel_args);
 
   channeld->default_compression_algorithm =
       grpc_channel_args_get_compression_algorithm(args->channel_args);
   /* Make sure the default isn't disabled. */
-  if (!grpc_compression_options_is_algorithm_enabled(
-          &channeld->compression_options,
-          channeld->default_compression_algorithm)) {
+  if (!GPR_BITGET(channeld->enabled_algorithms_bitset,
+                  channeld->default_compression_algorithm)) {
     gpr_log(GPR_DEBUG,
             "compression algorithm %d not enabled: switching to none",
             channeld->default_compression_algorithm);
     channeld->default_compression_algorithm = GRPC_COMPRESS_NONE;
   }
-  channeld->compression_options.default_compression_algorithm =
-      channeld->default_compression_algorithm;
 
-  channeld->supported_compression_algorithms = 0;
-  for (algo_idx = 0; algo_idx < GRPC_COMPRESS_ALGORITHMS_COUNT; ++algo_idx) {
+  channeld->supported_compression_algorithms = 1; /* always support identity */
+  for (grpc_compression_algorithm algo_idx = 1;
+       algo_idx < GRPC_COMPRESS_ALGORITHMS_COUNT; ++algo_idx) {
     /* skip disabled algorithms */
-    if (grpc_compression_options_is_algorithm_enabled(
-            &channeld->compression_options, algo_idx) == 0) {
+    if (!GPR_BITGET(channeld->enabled_algorithms_bitset, algo_idx)) {
       continue;
     }
     channeld->supported_compression_algorithms |= 1u << algo_idx;
@@ -325,7 +318,7 @@
     grpc_channel_next_op,
     sizeof(call_data),
     init_call_elem,
-    grpc_call_stack_ignore_set_pollset,
+    grpc_call_stack_ignore_set_pollset_or_pollset_set,
     destroy_call_elem,
     sizeof(channel_data),
     init_channel_elem,
diff --git a/src/core/lib/channel/compress_filter.h b/src/core/lib/channel/compress_filter.h
index 0ce5d08..e4a2a82 100644
--- a/src/core/lib/channel/compress_filter.h
+++ b/src/core/lib/channel/compress_filter.h
@@ -34,9 +34,9 @@
 #ifndef GRPC_CORE_LIB_CHANNEL_COMPRESS_FILTER_H
 #define GRPC_CORE_LIB_CHANNEL_COMPRESS_FILTER_H
 
-#include "src/core/lib/channel/channel_stack.h"
+#include <grpc/impl/codegen/compression_types.h>
 
-#define GRPC_COMPRESS_REQUEST_ALGORITHM_KEY "grpc-internal-encoding-request"
+#include "src/core/lib/channel/channel_stack.h"
 
 extern int grpc_compression_trace;
 
@@ -48,7 +48,7 @@
  *  - Channel configuration, as established at channel creation time.
  *  - The metadata accompanying the outgoing data to be compressed. This is
  *    taken as a request only. We may choose not to honor it. The metadata key
- *    is given by \a GRPC_COMPRESS_REQUEST_ALGORITHM_KEY.
+ *    is given by \a GRPC_COMPRESSION_REQUEST_ALGORITHM_MD_KEY.
  *
  * Compression can be disabled for concrete messages (for instance in order to
  * prevent CRIME/BEAST type attacks) by having the GRPC_WRITE_NO_COMPRESS set in
diff --git a/src/core/lib/channel/connected_channel.c b/src/core/lib/channel/connected_channel.c
index 68a3a7d..0a7d27a 100644
--- a/src/core/lib/channel/connected_channel.c
+++ b/src/core/lib/channel/connected_channel.c
@@ -93,16 +93,18 @@
   GPR_ASSERT(r == 0);
 }
 
-static void set_pollset(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
-                        grpc_pollset *pollset) {
+static void set_pollset_or_pollset_set(grpc_exec_ctx *exec_ctx,
+                                       grpc_call_element *elem,
+                                       grpc_polling_entity *pollent) {
   call_data *calld = elem->call_data;
   channel_data *chand = elem->channel_data;
-  grpc_transport_set_pollset(exec_ctx, chand->transport,
-                             TRANSPORT_STREAM_FROM_CALL_DATA(calld), pollset);
+  grpc_transport_set_pops(exec_ctx, chand->transport,
+                          TRANSPORT_STREAM_FROM_CALL_DATA(calld), pollent);
 }
 
 /* Destructor for call_data */
 static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
+                              const grpc_call_stats *stats,
                               void *and_free_memory) {
   call_data *calld = elem->call_data;
   channel_data *chand = elem->channel_data;
@@ -137,7 +139,7 @@
     con_start_transport_op,
     sizeof(call_data),
     init_call_elem,
-    set_pollset,
+    set_pollset_or_pollset_set,
     destroy_call_elem,
     sizeof(channel_data),
     init_channel_elem,
diff --git a/src/core/lib/channel/http_client_filter.c b/src/core/lib/channel/http_client_filter.c
index 516e708..792f0d8 100644
--- a/src/core/lib/channel/http_client_filter.c
+++ b/src/core/lib/channel/http_client_filter.c
@@ -38,6 +38,10 @@
 #include "src/core/lib/profiling/timers.h"
 #include "src/core/lib/support/string.h"
 #include "src/core/lib/transport/static_metadata.h"
+#include "src/core/lib/transport/transport_impl.h"
+
+#define EXPECTED_CONTENT_TYPE "application/grpc"
+#define EXPECTED_CONTENT_TYPE_LENGTH sizeof(EXPECTED_CONTENT_TYPE) - 1
 
 typedef struct call_data {
   grpc_linked_mdelem method;
@@ -74,7 +78,24 @@
   } else if (md->key == GRPC_MDSTR_STATUS) {
     grpc_call_element_send_cancel(a->exec_ctx, a->elem);
     return NULL;
+  } else if (md == GRPC_MDELEM_CONTENT_TYPE_APPLICATION_SLASH_GRPC) {
+    return NULL;
   } else if (md->key == GRPC_MDSTR_CONTENT_TYPE) {
+    const char *value_str = grpc_mdstr_as_c_string(md->value);
+    if (strncmp(value_str, EXPECTED_CONTENT_TYPE,
+                EXPECTED_CONTENT_TYPE_LENGTH) == 0 &&
+        (value_str[EXPECTED_CONTENT_TYPE_LENGTH] == '+' ||
+         value_str[EXPECTED_CONTENT_TYPE_LENGTH] == ';')) {
+      /* Although the C implementation doesn't (currently) generate them,
+         any custom +-suffix is explicitly valid. */
+      /* TODO(klempner): We should consider preallocating common values such
+         as +proto or +json, or at least stashing them if we see them. */
+      /* TODO(klempner): Should we be surfacing this to application code? */
+    } else {
+      /* TODO(klempner): We're currently allowing this, but we shouldn't
+         see it without a proxy so log for now. */
+      gpr_log(GPR_INFO, "Unexpected content-type '%s'", value_str);
+    }
     return NULL;
   }
   return md;
@@ -156,7 +177,7 @@
 
 /* Destructor for call_data */
 static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
-                              void *ignored) {}
+                              const grpc_call_stats *stats, void *ignored) {}
 
 static grpc_mdelem *scheme_from_args(const grpc_channel_args *args) {
   unsigned i;
@@ -179,7 +200,8 @@
   return GRPC_MDELEM_SCHEME_HTTP;
 }
 
-static grpc_mdstr *user_agent_from_args(const grpc_channel_args *args) {
+static grpc_mdstr *user_agent_from_args(const grpc_channel_args *args,
+                                        const char *transport_name) {
   gpr_strvec v;
   size_t i;
   int is_first = 1;
@@ -201,8 +223,8 @@
     }
   }
 
-  gpr_asprintf(&tmp, "%sgrpc-c/%s (%s)", is_first ? "" : " ",
-               grpc_version_string(), GPR_PLATFORM_STRING);
+  gpr_asprintf(&tmp, "%sgrpc-c/%s (%s; %s)", is_first ? "" : " ",
+               grpc_version_string(), GPR_PLATFORM_STRING, transport_name);
   is_first = 0;
   gpr_strvec_add(&v, tmp);
 
@@ -233,9 +255,12 @@
                               grpc_channel_element_args *args) {
   channel_data *chand = elem->channel_data;
   GPR_ASSERT(!args->is_last);
+  GPR_ASSERT(args->optional_transport != NULL);
   chand->static_scheme = scheme_from_args(args->channel_args);
   chand->user_agent = grpc_mdelem_from_metadata_strings(
-      GRPC_MDSTR_USER_AGENT, user_agent_from_args(args->channel_args));
+      GRPC_MDSTR_USER_AGENT,
+      user_agent_from_args(args->channel_args,
+                           args->optional_transport->vtable->name));
 }
 
 /* Destructor for channel data */
@@ -250,7 +275,7 @@
     grpc_channel_next_op,
     sizeof(call_data),
     init_call_elem,
-    grpc_call_stack_ignore_set_pollset,
+    grpc_call_stack_ignore_set_pollset_or_pollset_set,
     destroy_call_elem,
     sizeof(channel_data),
     init_channel_elem,
diff --git a/src/core/lib/channel/http_client_filter.h b/src/core/lib/channel/http_client_filter.h
index a884b36..4708117 100644
--- a/src/core/lib/channel/http_client_filter.h
+++ b/src/core/lib/channel/http_client_filter.h
@@ -1,5 +1,4 @@
 /*
- *
  * Copyright 2015, Google Inc.
  * All rights reserved.
  *
@@ -39,6 +38,7 @@
 /* Processes metadata on the client side for HTTP2 transports */
 extern const grpc_channel_filter grpc_http_client_filter;
 
+/* Channel arg to override the http2 :scheme header */
 #define GRPC_ARG_HTTP2_SCHEME "grpc.http2_scheme"
 
 #endif /* GRPC_CORE_LIB_CHANNEL_HTTP_CLIENT_FILTER_H */
diff --git a/src/core/lib/channel/http_server_filter.c b/src/core/lib/channel/http_server_filter.c
index ba86541..922f771 100644
--- a/src/core/lib/channel/http_server_filter.c
+++ b/src/core/lib/channel/http_server_filter.c
@@ -108,7 +108,7 @@
     } else {
       /* TODO(klempner): We're currently allowing this, but we shouldn't
          see it without a proxy so log for now. */
-      gpr_log(GPR_INFO, "Unexpected content-type %s", value_str);
+      gpr_log(GPR_INFO, "Unexpected content-type '%s'", value_str);
     }
     return NULL;
   } else if (md->key == GRPC_MDSTR_TE || md->key == GRPC_MDSTR_METHOD ||
@@ -226,7 +226,7 @@
 
 /* Destructor for call_data */
 static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
-                              void *ignored) {}
+                              const grpc_call_stats *stats, void *ignored) {}
 
 /* Constructor for channel_data */
 static void init_channel_elem(grpc_exec_ctx *exec_ctx,
@@ -244,7 +244,7 @@
     grpc_channel_next_op,
     sizeof(call_data),
     init_call_elem,
-    grpc_call_stack_ignore_set_pollset,
+    grpc_call_stack_ignore_set_pollset_or_pollset_set,
     destroy_call_elem,
     sizeof(channel_data),
     init_channel_elem,
diff --git a/src/core/lib/compression/compression_algorithm.c b/src/core/lib/compression/compression.c
similarity index 97%
rename from src/core/lib/compression/compression_algorithm.c
rename to src/core/lib/compression/compression.c
index 820871d..54efb5e 100644
--- a/src/core/lib/compression/compression_algorithm.c
+++ b/src/core/lib/compression/compression.c
@@ -125,6 +125,28 @@
   return NULL;
 }
 
+void grpc_compression_options_init(grpc_compression_options *opts) {
+  memset(opts, 0, sizeof(*opts));
+  /* all enabled by default */
+  opts->enabled_algorithms_bitset = (1u << GRPC_COMPRESS_ALGORITHMS_COUNT) - 1;
+}
+
+void grpc_compression_options_enable_algorithm(
+    grpc_compression_options *opts, grpc_compression_algorithm algorithm) {
+  GPR_BITSET(&opts->enabled_algorithms_bitset, algorithm);
+}
+
+void grpc_compression_options_disable_algorithm(
+    grpc_compression_options *opts, grpc_compression_algorithm algorithm) {
+  GPR_BITCLEAR(&opts->enabled_algorithms_bitset, algorithm);
+}
+
+int grpc_compression_options_is_algorithm_enabled(
+    const grpc_compression_options *opts,
+    grpc_compression_algorithm algorithm) {
+  return GPR_BITGET(opts->enabled_algorithms_bitset, algorithm);
+}
+
 /* TODO(dgq): Add the ability to specify parameters to the individual
  * compression algorithms */
 grpc_compression_algorithm grpc_compression_algorithm_for_level(
@@ -180,25 +202,3 @@
       abort();
   };
 }
-
-void grpc_compression_options_init(grpc_compression_options *opts) {
-  opts->enabled_algorithms_bitset = (1u << GRPC_COMPRESS_ALGORITHMS_COUNT) - 1;
-  opts->default_compression_algorithm = GRPC_COMPRESS_NONE;
-}
-
-void grpc_compression_options_enable_algorithm(
-    grpc_compression_options *opts, grpc_compression_algorithm algorithm) {
-  GPR_BITSET(&opts->enabled_algorithms_bitset, algorithm);
-}
-
-void grpc_compression_options_disable_algorithm(
-    grpc_compression_options *opts, grpc_compression_algorithm algorithm) {
-  GPR_BITCLEAR(&opts->enabled_algorithms_bitset, algorithm);
-}
-
-int grpc_compression_options_is_algorithm_enabled(
-    const grpc_compression_options *opts,
-    grpc_compression_algorithm algorithm) {
-  if (algorithm >= GRPC_COMPRESS_ALGORITHMS_COUNT) return 0;
-  return GPR_BITGET(opts->enabled_algorithms_bitset, algorithm);
-}
diff --git a/src/core/lib/http/httpcli.c b/src/core/lib/http/httpcli.c
index f22721a..e8957bf 100644
--- a/src/core/lib/http/httpcli.c
+++ b/src/core/lib/http/httpcli.c
@@ -62,7 +62,7 @@
   grpc_httpcli_response_cb on_response;
   void *user_data;
   grpc_httpcli_context *context;
-  grpc_pollset *pollset;
+  grpc_polling_entity *pollent;
   grpc_iomgr_object iomgr_obj;
   gpr_slice_buffer incoming;
   gpr_slice_buffer outgoing;
@@ -97,8 +97,8 @@
 
 static void finish(grpc_exec_ctx *exec_ctx, internal_request *req,
                    int success) {
-  grpc_pollset_set_del_pollset(exec_ctx, req->context->pollset_set,
-                               req->pollset);
+  grpc_polling_entity_del_from_pollset_set(exec_ctx, req->pollent,
+                                           req->context->pollset_set);
   req->on_response(exec_ctx, req->user_data,
                    success ? &req->parser.http.response : NULL);
   grpc_http_parser_destroy(&req->parser);
@@ -222,7 +222,7 @@
 
 static void internal_request_begin(
     grpc_exec_ctx *exec_ctx, grpc_httpcli_context *context,
-    grpc_pollset *pollset, const grpc_httpcli_request *request,
+    grpc_polling_entity *pollent, const grpc_httpcli_request *request,
     gpr_timespec deadline, grpc_httpcli_response_cb on_response,
     void *user_data, const char *name, gpr_slice request_text) {
   internal_request *req = gpr_malloc(sizeof(internal_request));
@@ -235,7 +235,7 @@
   req->handshaker =
       request->handshaker ? request->handshaker : &grpc_httpcli_plaintext;
   req->context = context;
-  req->pollset = pollset;
+  req->pollent = pollent;
   grpc_closure_init(&req->on_read, on_read, req);
   grpc_closure_init(&req->done_write, done_write, req);
   gpr_slice_buffer_init(&req->incoming);
@@ -244,14 +244,15 @@
   req->host = gpr_strdup(request->host);
   req->ssl_host_override = gpr_strdup(request->ssl_host_override);
 
-  grpc_pollset_set_add_pollset(exec_ctx, req->context->pollset_set,
-                               req->pollset);
+  GPR_ASSERT(pollent);
+  grpc_polling_entity_add_to_pollset_set(exec_ctx, req->pollent,
+                                         req->context->pollset_set);
   grpc_resolve_address(exec_ctx, request->host, req->handshaker->default_port,
                        on_resolved, req);
 }
 
 void grpc_httpcli_get(grpc_exec_ctx *exec_ctx, grpc_httpcli_context *context,
-                      grpc_pollset *pollset,
+                      grpc_polling_entity *pollent,
                       const grpc_httpcli_request *request,
                       gpr_timespec deadline,
                       grpc_httpcli_response_cb on_response, void *user_data) {
@@ -261,14 +262,14 @@
     return;
   }
   gpr_asprintf(&name, "HTTP:GET:%s:%s", request->host, request->http.path);
-  internal_request_begin(exec_ctx, context, pollset, request, deadline,
+  internal_request_begin(exec_ctx, context, pollent, request, deadline,
                          on_response, user_data, name,
                          grpc_httpcli_format_get_request(request));
   gpr_free(name);
 }
 
 void grpc_httpcli_post(grpc_exec_ctx *exec_ctx, grpc_httpcli_context *context,
-                       grpc_pollset *pollset,
+                       grpc_polling_entity *pollent,
                        const grpc_httpcli_request *request,
                        const char *body_bytes, size_t body_size,
                        gpr_timespec deadline,
@@ -281,7 +282,7 @@
   }
   gpr_asprintf(&name, "HTTP:POST:%s:%s", request->host, request->http.path);
   internal_request_begin(
-      exec_ctx, context, pollset, request, deadline, on_response, user_data,
+      exec_ctx, context, pollent, request, deadline, on_response, user_data,
       name, grpc_httpcli_format_post_request(request, body_bytes, body_size));
   gpr_free(name);
 }
diff --git a/src/core/lib/http/httpcli.h b/src/core/lib/http/httpcli.h
index 11a32a1..7e7784f 100644
--- a/src/core/lib/http/httpcli.h
+++ b/src/core/lib/http/httpcli.h
@@ -41,6 +41,7 @@
 #include "src/core/lib/http/parser.h"
 #include "src/core/lib/iomgr/endpoint.h"
 #include "src/core/lib/iomgr/iomgr_internal.h"
+#include "src/core/lib/iomgr/polling_entity.h"
 #include "src/core/lib/iomgr/pollset_set.h"
 
 /* User agent this library reports */
@@ -100,7 +101,7 @@
    'on_response' is a callback to report results to (and 'user_data' is a user
      supplied pointer to pass to said call) */
 void grpc_httpcli_get(grpc_exec_ctx *exec_ctx, grpc_httpcli_context *context,
-                      grpc_pollset *pollset,
+                      grpc_polling_entity *pollent,
                       const grpc_httpcli_request *request,
                       gpr_timespec deadline,
                       grpc_httpcli_response_cb on_response, void *user_data);
@@ -121,7 +122,7 @@
      supplied pointer to pass to said call)
    Does not support ?var1=val1&var2=val2 in the path. */
 void grpc_httpcli_post(grpc_exec_ctx *exec_ctx, grpc_httpcli_context *context,
-                       grpc_pollset *pollset,
+                       grpc_polling_entity *pollent,
                        const grpc_httpcli_request *request,
                        const char *body_bytes, size_t body_size,
                        gpr_timespec deadline,
diff --git a/src/core/lib/iomgr/ev_poll_and_epoll_posix.c b/src/core/lib/iomgr/ev_poll_and_epoll_posix.c
new file mode 100644
index 0000000..943c404
--- /dev/null
+++ b/src/core/lib/iomgr/ev_poll_and_epoll_posix.c
@@ -0,0 +1,1978 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/* This file will be removed shortly: it's here to keep refactoring
+ * steps simple and auditable.
+ * It's the combination of the old files:
+ *  - fd_posix.{h,c}
+ *  - pollset_posix.{h,c}
+ *  - pullset_multipoller_with_{poll,epoll}.{h,c}
+ * The new version will be split into:
+ *  - ev_poll_posix.{h,c}
+ *  - ev_epoll_posix.{h,c}
+ */
+
+#include <grpc/support/port_platform.h>
+
+#ifdef GPR_POSIX_SOCKET
+
+#include "src/core/lib/iomgr/ev_poll_and_epoll_posix.h"
+
+#include <assert.h>
+#include <errno.h>
+#include <poll.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <unistd.h>
+
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/string_util.h>
+#include <grpc/support/tls.h>
+#include <grpc/support/useful.h>
+
+#include "src/core/lib/iomgr/iomgr_internal.h"
+#include "src/core/lib/iomgr/wakeup_fd_posix.h"
+#include "src/core/lib/profiling/timers.h"
+#include "src/core/lib/support/block_annotate.h"
+
+/*******************************************************************************
+ * FD declarations
+ */
+
+typedef struct grpc_fd_watcher {
+  struct grpc_fd_watcher *next;
+  struct grpc_fd_watcher *prev;
+  grpc_pollset *pollset;
+  grpc_pollset_worker *worker;
+  grpc_fd *fd;
+} grpc_fd_watcher;
+
+struct grpc_fd {
+  int fd;
+  /* refst format:
+     bit0:   1=active/0=orphaned
+     bit1-n: refcount
+     meaning that mostly we ref by two to avoid altering the orphaned bit,
+     and just unref by 1 when we're ready to flag the object as orphaned */
+  gpr_atm refst;
+
+  gpr_mu mu;
+  int shutdown;
+  int closed;
+  int released;
+
+  /* The watcher list.
+
+     The following watcher related fields are protected by watcher_mu.
+
+     An fd_watcher is an ephemeral object created when an fd wants to
+     begin polling, and destroyed after the poll.
+
+     It denotes the fd's interest in whether to read poll or write poll
+     or both or neither on this fd.
+
+     If a watcher is asked to poll for reads or writes, the read_watcher
+     or write_watcher fields are set respectively. A watcher may be asked
+     to poll for both, in which case both fields will be set.
+
+     read_watcher and write_watcher may be NULL if no watcher has been
+     asked to poll for reads or writes.
+
+     If an fd_watcher is not asked to poll for reads or writes, it's added
+     to a linked list of inactive watchers, rooted at inactive_watcher_root.
+     If at a later time there becomes need of a poller to poll, one of
+     the inactive pollers may be kicked out of their poll loops to take
+     that responsibility. */
+  grpc_fd_watcher inactive_watcher_root;
+  grpc_fd_watcher *read_watcher;
+  grpc_fd_watcher *write_watcher;
+
+  grpc_closure *read_closure;
+  grpc_closure *write_closure;
+
+  struct grpc_fd *freelist_next;
+
+  grpc_closure *on_done_closure;
+
+  grpc_iomgr_object iomgr_object;
+
+  /* The pollset that last noticed and notified that the fd is readable */
+  grpc_pollset *read_notifier_pollset;
+};
+
+/* Begin polling on an fd.
+   Registers that the given pollset is interested in this fd - so that if read
+   or writability interest changes, the pollset can be kicked to pick up that
+   new interest.
+   Return value is:
+     (fd_needs_read? read_mask : 0) | (fd_needs_write? write_mask : 0)
+   i.e. a combination of read_mask and write_mask determined by the fd's current
+   interest in said events.
+   Polling strategies that do not need to alter their behavior depending on the
+   fd's current interest (such as epoll) do not need to call this function.
+   MUST NOT be called with a pollset lock taken */
+static uint32_t fd_begin_poll(grpc_fd *fd, grpc_pollset *pollset,
+                              grpc_pollset_worker *worker, uint32_t read_mask,
+                              uint32_t write_mask, grpc_fd_watcher *rec);
+/* Complete polling previously started with fd_begin_poll
+   MUST NOT be called with a pollset lock taken
+   if got_read or got_write are 1, also does the become_{readable,writable} as
+   appropriate. */
+static void fd_end_poll(grpc_exec_ctx *exec_ctx, grpc_fd_watcher *rec,
+                        int got_read, int got_write,
+                        grpc_pollset *read_notifier_pollset);
+
+/* Return 1 if this fd is orphaned, 0 otherwise */
+static bool fd_is_orphaned(grpc_fd *fd);
+
+/* Reference counting for fds */
+/*#define GRPC_FD_REF_COUNT_DEBUG*/
+#ifdef GRPC_FD_REF_COUNT_DEBUG
+static void fd_ref(grpc_fd *fd, const char *reason, const char *file, int line);
+static void fd_unref(grpc_fd *fd, const char *reason, const char *file,
+                     int line);
+#define GRPC_FD_REF(fd, reason) fd_ref(fd, reason, __FILE__, __LINE__)
+#define GRPC_FD_UNREF(fd, reason) fd_unref(fd, reason, __FILE__, __LINE__)
+#else
+static void fd_ref(grpc_fd *fd);
+static void fd_unref(grpc_fd *fd);
+#define GRPC_FD_REF(fd, reason) fd_ref(fd)
+#define GRPC_FD_UNREF(fd, reason) fd_unref(fd)
+#endif
+
+static void fd_global_init(void);
+static void fd_global_shutdown(void);
+
+#define CLOSURE_NOT_READY ((grpc_closure *)0)
+#define CLOSURE_READY ((grpc_closure *)1)
+
+/*******************************************************************************
+ * pollset declarations
+ */
+
+typedef struct grpc_pollset_vtable grpc_pollset_vtable;
+
+typedef struct grpc_cached_wakeup_fd {
+  grpc_wakeup_fd fd;
+  struct grpc_cached_wakeup_fd *next;
+} grpc_cached_wakeup_fd;
+
+struct grpc_pollset_worker {
+  grpc_cached_wakeup_fd *wakeup_fd;
+  int reevaluate_polling_on_wakeup;
+  int kicked_specifically;
+  struct grpc_pollset_worker *next;
+  struct grpc_pollset_worker *prev;
+};
+
+struct grpc_pollset {
+  /* pollsets under posix can mutate representation as fds are added and
+     removed.
+     For example, we may choose a poll() based implementation on linux for
+     few fds, and an epoll() based implementation for many fds */
+  const grpc_pollset_vtable *vtable;
+  gpr_mu mu;
+  grpc_pollset_worker root_worker;
+  int in_flight_cbs;
+  int shutting_down;
+  int called_shutdown;
+  int kicked_without_pollers;
+  grpc_closure *shutdown_done;
+  grpc_closure_list idle_jobs;
+  union {
+    int fd;
+    void *ptr;
+  } data;
+  /* Local cache of eventfds for workers */
+  grpc_cached_wakeup_fd *local_wakeup_cache;
+};
+
+struct grpc_pollset_vtable {
+  void (*add_fd)(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
+                 struct grpc_fd *fd, int and_unlock_pollset);
+  void (*maybe_work_and_unlock)(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
+                                grpc_pollset_worker *worker,
+                                gpr_timespec deadline, gpr_timespec now);
+  void (*finish_shutdown)(grpc_pollset *pollset);
+  void (*destroy)(grpc_pollset *pollset);
+};
+
+/* Add an fd to a pollset */
+static void pollset_add_fd(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
+                           struct grpc_fd *fd);
+
+static void pollset_set_add_fd(grpc_exec_ctx *exec_ctx,
+                               grpc_pollset_set *pollset_set, grpc_fd *fd);
+
+/* Convert a timespec to milliseconds:
+   - very small or negative poll times are clamped to zero to do a
+     non-blocking poll (which becomes spin polling)
+   - other small values are rounded up to one millisecond
+   - longer than a millisecond polls are rounded up to the next nearest
+     millisecond to avoid spinning
+   - infinite timeouts are converted to -1 */
+static int poll_deadline_to_millis_timeout(gpr_timespec deadline,
+                                           gpr_timespec now);
+
+/* Allow kick to wakeup the currently polling worker */
+#define GRPC_POLLSET_CAN_KICK_SELF 1
+/* Force the wakee to repoll when awoken */
+#define GRPC_POLLSET_REEVALUATE_POLLING_ON_WAKEUP 2
+/* As per pollset_kick, with an extended set of flags (defined above)
+   -- mostly for fd_posix's use. */
+static void pollset_kick_ext(grpc_pollset *p,
+                             grpc_pollset_worker *specific_worker,
+                             uint32_t flags);
+
+/* turn a pollset into a multipoller: platform specific */
+typedef void (*platform_become_multipoller_type)(grpc_exec_ctx *exec_ctx,
+                                                 grpc_pollset *pollset,
+                                                 struct grpc_fd **fds,
+                                                 size_t fd_count);
+static platform_become_multipoller_type platform_become_multipoller;
+
+/* Return 1 if the pollset has active threads in pollset_work (pollset must
+ * be locked) */
+static int pollset_has_workers(grpc_pollset *pollset);
+
+static void remove_fd_from_all_epoll_sets(int fd);
+
+/*******************************************************************************
+ * pollset_set definitions
+ */
+
+struct grpc_pollset_set {
+  gpr_mu mu;
+
+  size_t pollset_count;
+  size_t pollset_capacity;
+  grpc_pollset **pollsets;
+
+  size_t pollset_set_count;
+  size_t pollset_set_capacity;
+  struct grpc_pollset_set **pollset_sets;
+
+  size_t fd_count;
+  size_t fd_capacity;
+  grpc_fd **fds;
+};
+
+/*******************************************************************************
+ * fd_posix.c
+ */
+
+/* We need to keep a freelist not because of any concerns of malloc performance
+ * but instead so that implementations with multiple threads in (for example)
+ * epoll_wait deal with the race between pollset removal and incoming poll
+ * notifications.
+ *
+ * The problem is that the poller ultimately holds a reference to this
+ * object, so it is very difficult to know when is safe to free it, at least
+ * without some expensive synchronization.
+ *
+ * If we keep the object freelisted, in the worst case losing this race just
+ * becomes a spurious read notification on a reused fd.
+ */
+/* TODO(klempner): We could use some form of polling generation count to know
+ * when these are safe to free. */
+/* TODO(klempner): Consider disabling freelisting if we don't have multiple
+ * threads in poll on the same fd */
+/* TODO(klempner): Batch these allocations to reduce fragmentation */
+static grpc_fd *fd_freelist = NULL;
+static gpr_mu fd_freelist_mu;
+
+static void freelist_fd(grpc_fd *fd) {
+  gpr_mu_lock(&fd_freelist_mu);
+  fd->freelist_next = fd_freelist;
+  fd_freelist = fd;
+  grpc_iomgr_unregister_object(&fd->iomgr_object);
+  gpr_mu_unlock(&fd_freelist_mu);
+}
+
+static grpc_fd *alloc_fd(int fd) {
+  grpc_fd *r = NULL;
+  gpr_mu_lock(&fd_freelist_mu);
+  if (fd_freelist != NULL) {
+    r = fd_freelist;
+    fd_freelist = fd_freelist->freelist_next;
+  }
+  gpr_mu_unlock(&fd_freelist_mu);
+  if (r == NULL) {
+    r = gpr_malloc(sizeof(grpc_fd));
+    gpr_mu_init(&r->mu);
+  }
+
+  gpr_mu_lock(&r->mu);
+  gpr_atm_rel_store(&r->refst, 1);
+  r->shutdown = 0;
+  r->read_closure = CLOSURE_NOT_READY;
+  r->write_closure = CLOSURE_NOT_READY;
+  r->fd = fd;
+  r->inactive_watcher_root.next = r->inactive_watcher_root.prev =
+      &r->inactive_watcher_root;
+  r->freelist_next = NULL;
+  r->read_watcher = r->write_watcher = NULL;
+  r->on_done_closure = NULL;
+  r->closed = 0;
+  r->released = 0;
+  r->read_notifier_pollset = NULL;
+  gpr_mu_unlock(&r->mu);
+  return r;
+}
+
+static void destroy(grpc_fd *fd) {
+  gpr_mu_destroy(&fd->mu);
+  gpr_free(fd);
+}
+
+#ifdef GRPC_FD_REF_COUNT_DEBUG
+#define REF_BY(fd, n, reason) ref_by(fd, n, reason, __FILE__, __LINE__)
+#define UNREF_BY(fd, n, reason) unref_by(fd, n, reason, __FILE__, __LINE__)
+static void ref_by(grpc_fd *fd, int n, const char *reason, const char *file,
+                   int line) {
+  gpr_log(GPR_DEBUG, "FD %d %p   ref %d %d -> %d [%s; %s:%d]", fd->fd, fd, n,
+          gpr_atm_no_barrier_load(&fd->refst),
+          gpr_atm_no_barrier_load(&fd->refst) + n, reason, file, line);
+#else
+#define REF_BY(fd, n, reason) ref_by(fd, n)
+#define UNREF_BY(fd, n, reason) unref_by(fd, n)
+static void ref_by(grpc_fd *fd, int n) {
+#endif
+  GPR_ASSERT(gpr_atm_no_barrier_fetch_add(&fd->refst, n) > 0);
+}
+
+#ifdef GRPC_FD_REF_COUNT_DEBUG
+static void unref_by(grpc_fd *fd, int n, const char *reason, const char *file,
+                     int line) {
+  gpr_atm old;
+  gpr_log(GPR_DEBUG, "FD %d %p unref %d %d -> %d [%s; %s:%d]", fd->fd, fd, n,
+          gpr_atm_no_barrier_load(&fd->refst),
+          gpr_atm_no_barrier_load(&fd->refst) - n, reason, file, line);
+#else
+static void unref_by(grpc_fd *fd, int n) {
+  gpr_atm old;
+#endif
+  old = gpr_atm_full_fetch_add(&fd->refst, -n);
+  if (old == n) {
+    freelist_fd(fd);
+  } else {
+    GPR_ASSERT(old > n);
+  }
+}
+
+static void fd_global_init(void) { gpr_mu_init(&fd_freelist_mu); }
+
+static void fd_global_shutdown(void) {
+  gpr_mu_lock(&fd_freelist_mu);
+  gpr_mu_unlock(&fd_freelist_mu);
+  while (fd_freelist != NULL) {
+    grpc_fd *fd = fd_freelist;
+    fd_freelist = fd_freelist->freelist_next;
+    destroy(fd);
+  }
+  gpr_mu_destroy(&fd_freelist_mu);
+}
+
+static grpc_fd *fd_create(int fd, const char *name) {
+  grpc_fd *r = alloc_fd(fd);
+  char *name2;
+  gpr_asprintf(&name2, "%s fd=%d", name, fd);
+  grpc_iomgr_register_object(&r->iomgr_object, name2);
+  gpr_free(name2);
+#ifdef GRPC_FD_REF_COUNT_DEBUG
+  gpr_log(GPR_DEBUG, "FD %d %p create %s", fd, r, name);
+#endif
+  return r;
+}
+
+static bool fd_is_orphaned(grpc_fd *fd) {
+  return (gpr_atm_acq_load(&fd->refst) & 1) == 0;
+}
+
+static void pollset_kick_locked(grpc_fd_watcher *watcher) {
+  gpr_mu_lock(&watcher->pollset->mu);
+  GPR_ASSERT(watcher->worker);
+  pollset_kick_ext(watcher->pollset, watcher->worker,
+                   GRPC_POLLSET_REEVALUATE_POLLING_ON_WAKEUP);
+  gpr_mu_unlock(&watcher->pollset->mu);
+}
+
+static void maybe_wake_one_watcher_locked(grpc_fd *fd) {
+  if (fd->inactive_watcher_root.next != &fd->inactive_watcher_root) {
+    pollset_kick_locked(fd->inactive_watcher_root.next);
+  } else if (fd->read_watcher) {
+    pollset_kick_locked(fd->read_watcher);
+  } else if (fd->write_watcher) {
+    pollset_kick_locked(fd->write_watcher);
+  }
+}
+
+static void wake_all_watchers_locked(grpc_fd *fd) {
+  grpc_fd_watcher *watcher;
+  for (watcher = fd->inactive_watcher_root.next;
+       watcher != &fd->inactive_watcher_root; watcher = watcher->next) {
+    pollset_kick_locked(watcher);
+  }
+  if (fd->read_watcher) {
+    pollset_kick_locked(fd->read_watcher);
+  }
+  if (fd->write_watcher && fd->write_watcher != fd->read_watcher) {
+    pollset_kick_locked(fd->write_watcher);
+  }
+}
+
+static int has_watchers(grpc_fd *fd) {
+  return fd->read_watcher != NULL || fd->write_watcher != NULL ||
+         fd->inactive_watcher_root.next != &fd->inactive_watcher_root;
+}
+
+static void close_fd_locked(grpc_exec_ctx *exec_ctx, grpc_fd *fd) {
+  fd->closed = 1;
+  if (!fd->released) {
+    close(fd->fd);
+  } else {
+    remove_fd_from_all_epoll_sets(fd->fd);
+  }
+  grpc_exec_ctx_enqueue(exec_ctx, fd->on_done_closure, true, NULL);
+}
+
+static int fd_wrapped_fd(grpc_fd *fd) {
+  if (fd->released || fd->closed) {
+    return -1;
+  } else {
+    return fd->fd;
+  }
+}
+
+static void fd_orphan(grpc_exec_ctx *exec_ctx, grpc_fd *fd,
+                      grpc_closure *on_done, int *release_fd,
+                      const char *reason) {
+  fd->on_done_closure = on_done;
+  fd->released = release_fd != NULL;
+  if (!fd->released) {
+    shutdown(fd->fd, SHUT_RDWR);
+  } else {
+    *release_fd = fd->fd;
+  }
+  gpr_mu_lock(&fd->mu);
+  REF_BY(fd, 1, reason); /* remove active status, but keep referenced */
+  if (!has_watchers(fd)) {
+    close_fd_locked(exec_ctx, fd);
+  } else {
+    wake_all_watchers_locked(fd);
+  }
+  gpr_mu_unlock(&fd->mu);
+  UNREF_BY(fd, 2, reason); /* drop the reference */
+}
+
+/* increment refcount by two to avoid changing the orphan bit */
+#ifdef GRPC_FD_REF_COUNT_DEBUG
+static void fd_ref(grpc_fd *fd, const char *reason, const char *file,
+                   int line) {
+  ref_by(fd, 2, reason, file, line);
+}
+
+static void fd_unref(grpc_fd *fd, const char *reason, const char *file,
+                     int line) {
+  unref_by(fd, 2, reason, file, line);
+}
+#else
+static void fd_ref(grpc_fd *fd) { ref_by(fd, 2); }
+
+static void fd_unref(grpc_fd *fd) { unref_by(fd, 2); }
+#endif
+
+static void notify_on_locked(grpc_exec_ctx *exec_ctx, grpc_fd *fd,
+                             grpc_closure **st, grpc_closure *closure) {
+  if (*st == CLOSURE_NOT_READY) {
+    /* not ready ==> switch to a waiting state by setting the closure */
+    *st = closure;
+  } else if (*st == CLOSURE_READY) {
+    /* already ready ==> queue the closure to run immediately */
+    *st = CLOSURE_NOT_READY;
+    grpc_exec_ctx_enqueue(exec_ctx, closure, !fd->shutdown, NULL);
+    maybe_wake_one_watcher_locked(fd);
+  } else {
+    /* upcallptr was set to a different closure.  This is an error! */
+    gpr_log(GPR_ERROR,
+            "User called a notify_on function with a previous callback still "
+            "pending");
+    abort();
+  }
+}
+
+/* returns 1 if state becomes not ready */
+static int set_ready_locked(grpc_exec_ctx *exec_ctx, grpc_fd *fd,
+                            grpc_closure **st) {
+  if (*st == CLOSURE_READY) {
+    /* duplicate ready ==> ignore */
+    return 0;
+  } else if (*st == CLOSURE_NOT_READY) {
+    /* not ready, and not waiting ==> flag ready */
+    *st = CLOSURE_READY;
+    return 0;
+  } else {
+    /* waiting ==> queue closure */
+    grpc_exec_ctx_enqueue(exec_ctx, *st, !fd->shutdown, NULL);
+    *st = CLOSURE_NOT_READY;
+    return 1;
+  }
+}
+
+static void set_read_notifier_pollset_locked(
+    grpc_exec_ctx *exec_ctx, grpc_fd *fd, grpc_pollset *read_notifier_pollset) {
+  fd->read_notifier_pollset = read_notifier_pollset;
+}
+
+static void fd_shutdown(grpc_exec_ctx *exec_ctx, grpc_fd *fd) {
+  gpr_mu_lock(&fd->mu);
+  GPR_ASSERT(!fd->shutdown);
+  fd->shutdown = 1;
+  set_ready_locked(exec_ctx, fd, &fd->read_closure);
+  set_ready_locked(exec_ctx, fd, &fd->write_closure);
+  gpr_mu_unlock(&fd->mu);
+}
+
+static void fd_notify_on_read(grpc_exec_ctx *exec_ctx, grpc_fd *fd,
+                              grpc_closure *closure) {
+  gpr_mu_lock(&fd->mu);
+  notify_on_locked(exec_ctx, fd, &fd->read_closure, closure);
+  gpr_mu_unlock(&fd->mu);
+}
+
+static void fd_notify_on_write(grpc_exec_ctx *exec_ctx, grpc_fd *fd,
+                               grpc_closure *closure) {
+  gpr_mu_lock(&fd->mu);
+  notify_on_locked(exec_ctx, fd, &fd->write_closure, closure);
+  gpr_mu_unlock(&fd->mu);
+}
+
+/* Return the read-notifier pollset */
+static grpc_pollset *fd_get_read_notifier_pollset(grpc_exec_ctx *exec_ctx,
+                                                  grpc_fd *fd) {
+  grpc_pollset *notifier = NULL;
+
+  gpr_mu_lock(&fd->mu);
+  notifier = fd->read_notifier_pollset;
+  gpr_mu_unlock(&fd->mu);
+
+  return notifier;
+}
+
+static uint32_t fd_begin_poll(grpc_fd *fd, grpc_pollset *pollset,
+                              grpc_pollset_worker *worker, uint32_t read_mask,
+                              uint32_t write_mask, grpc_fd_watcher *watcher) {
+  uint32_t mask = 0;
+  grpc_closure *cur;
+  int requested;
+  /* keep track of pollers that have requested our events, in case they change
+   */
+  GRPC_FD_REF(fd, "poll");
+
+  gpr_mu_lock(&fd->mu);
+
+  /* if we are shutdown, then don't add to the watcher set */
+  if (fd->shutdown) {
+    watcher->fd = NULL;
+    watcher->pollset = NULL;
+    watcher->worker = NULL;
+    gpr_mu_unlock(&fd->mu);
+    GRPC_FD_UNREF(fd, "poll");
+    return 0;
+  }
+
+  /* if there is nobody polling for read, but we need to, then start doing so */
+  cur = fd->read_closure;
+  requested = cur != CLOSURE_READY;
+  if (read_mask && fd->read_watcher == NULL && requested) {
+    fd->read_watcher = watcher;
+    mask |= read_mask;
+  }
+  /* if there is nobody polling for write, but we need to, then start doing so
+   */
+  cur = fd->write_closure;
+  requested = cur != CLOSURE_READY;
+  if (write_mask && fd->write_watcher == NULL && requested) {
+    fd->write_watcher = watcher;
+    mask |= write_mask;
+  }
+  /* if not polling, remember this watcher in case we need someone to later */
+  if (mask == 0 && worker != NULL) {
+    watcher->next = &fd->inactive_watcher_root;
+    watcher->prev = watcher->next->prev;
+    watcher->next->prev = watcher->prev->next = watcher;
+  }
+  watcher->pollset = pollset;
+  watcher->worker = worker;
+  watcher->fd = fd;
+  gpr_mu_unlock(&fd->mu);
+
+  return mask;
+}
+
+static void fd_end_poll(grpc_exec_ctx *exec_ctx, grpc_fd_watcher *watcher,
+                        int got_read, int got_write,
+                        grpc_pollset *read_notifier_pollset) {
+  int was_polling = 0;
+  int kick = 0;
+  grpc_fd *fd = watcher->fd;
+
+  if (fd == NULL) {
+    return;
+  }
+
+  gpr_mu_lock(&fd->mu);
+
+  if (watcher == fd->read_watcher) {
+    /* remove read watcher, kick if we still need a read */
+    was_polling = 1;
+    if (!got_read) {
+      kick = 1;
+    }
+    fd->read_watcher = NULL;
+  }
+  if (watcher == fd->write_watcher) {
+    /* remove write watcher, kick if we still need a write */
+    was_polling = 1;
+    if (!got_write) {
+      kick = 1;
+    }
+    fd->write_watcher = NULL;
+  }
+  if (!was_polling && watcher->worker != NULL) {
+    /* remove from inactive list */
+    watcher->next->prev = watcher->prev;
+    watcher->prev->next = watcher->next;
+  }
+  if (got_read) {
+    if (set_ready_locked(exec_ctx, fd, &fd->read_closure)) {
+      kick = 1;
+    }
+
+    if (read_notifier_pollset != NULL) {
+      set_read_notifier_pollset_locked(exec_ctx, fd, read_notifier_pollset);
+    }
+  }
+  if (got_write) {
+    if (set_ready_locked(exec_ctx, fd, &fd->write_closure)) {
+      kick = 1;
+    }
+  }
+  if (kick) {
+    maybe_wake_one_watcher_locked(fd);
+  }
+  if (fd_is_orphaned(fd) && !has_watchers(fd) && !fd->closed) {
+    close_fd_locked(exec_ctx, fd);
+  }
+  gpr_mu_unlock(&fd->mu);
+
+  GRPC_FD_UNREF(fd, "poll");
+}
+
+/*******************************************************************************
+ * pollset_posix.c
+ */
+
+GPR_TLS_DECL(g_current_thread_poller);
+GPR_TLS_DECL(g_current_thread_worker);
+
+/** The alarm system needs to be able to wakeup 'some poller' sometimes
+ *  (specifically when a new alarm needs to be triggered earlier than the next
+ *  alarm 'epoch').
+ *  This wakeup_fd gives us something to alert on when such a case occurs. */
+grpc_wakeup_fd grpc_global_wakeup_fd;
+
+static void remove_worker(grpc_pollset *p, grpc_pollset_worker *worker) {
+  worker->prev->next = worker->next;
+  worker->next->prev = worker->prev;
+}
+
+static int pollset_has_workers(grpc_pollset *p) {
+  return p->root_worker.next != &p->root_worker;
+}
+
+static grpc_pollset_worker *pop_front_worker(grpc_pollset *p) {
+  if (pollset_has_workers(p)) {
+    grpc_pollset_worker *w = p->root_worker.next;
+    remove_worker(p, w);
+    return w;
+  } else {
+    return NULL;
+  }
+}
+
+static void push_back_worker(grpc_pollset *p, grpc_pollset_worker *worker) {
+  worker->next = &p->root_worker;
+  worker->prev = worker->next->prev;
+  worker->prev->next = worker->next->prev = worker;
+}
+
+static void push_front_worker(grpc_pollset *p, grpc_pollset_worker *worker) {
+  worker->prev = &p->root_worker;
+  worker->next = worker->prev->next;
+  worker->prev->next = worker->next->prev = worker;
+}
+
+static void pollset_kick_ext(grpc_pollset *p,
+                             grpc_pollset_worker *specific_worker,
+                             uint32_t flags) {
+  GPR_TIMER_BEGIN("pollset_kick_ext", 0);
+
+  /* pollset->mu already held */
+  if (specific_worker != NULL) {
+    if (specific_worker == GRPC_POLLSET_KICK_BROADCAST) {
+      GPR_TIMER_BEGIN("pollset_kick_ext.broadcast", 0);
+      GPR_ASSERT((flags & GRPC_POLLSET_REEVALUATE_POLLING_ON_WAKEUP) == 0);
+      for (specific_worker = p->root_worker.next;
+           specific_worker != &p->root_worker;
+           specific_worker = specific_worker->next) {
+        grpc_wakeup_fd_wakeup(&specific_worker->wakeup_fd->fd);
+      }
+      p->kicked_without_pollers = 1;
+      GPR_TIMER_END("pollset_kick_ext.broadcast", 0);
+    } else if (gpr_tls_get(&g_current_thread_worker) !=
+               (intptr_t)specific_worker) {
+      GPR_TIMER_MARK("different_thread_worker", 0);
+      if ((flags & GRPC_POLLSET_REEVALUATE_POLLING_ON_WAKEUP) != 0) {
+        specific_worker->reevaluate_polling_on_wakeup = 1;
+      }
+      specific_worker->kicked_specifically = 1;
+      grpc_wakeup_fd_wakeup(&specific_worker->wakeup_fd->fd);
+    } else if ((flags & GRPC_POLLSET_CAN_KICK_SELF) != 0) {
+      GPR_TIMER_MARK("kick_yoself", 0);
+      if ((flags & GRPC_POLLSET_REEVALUATE_POLLING_ON_WAKEUP) != 0) {
+        specific_worker->reevaluate_polling_on_wakeup = 1;
+      }
+      specific_worker->kicked_specifically = 1;
+      grpc_wakeup_fd_wakeup(&specific_worker->wakeup_fd->fd);
+    }
+  } else if (gpr_tls_get(&g_current_thread_poller) != (intptr_t)p) {
+    GPR_ASSERT((flags & GRPC_POLLSET_REEVALUATE_POLLING_ON_WAKEUP) == 0);
+    GPR_TIMER_MARK("kick_anonymous", 0);
+    specific_worker = pop_front_worker(p);
+    if (specific_worker != NULL) {
+      if (gpr_tls_get(&g_current_thread_worker) == (intptr_t)specific_worker) {
+        /* Prefer not to kick self. Push the worker to the end of the list and
+         * pop the one from front */
+        GPR_TIMER_MARK("kick_anonymous_not_self", 0);
+        push_back_worker(p, specific_worker);
+        specific_worker = pop_front_worker(p);
+        /* If there was only one worker on the pollset, we would get the same
+         * worker we pushed (the one set on current thread local) back. If so,
+         * kick it only if GRPC_POLLSET_CAN_KICK_SELF flag is set */
+        if ((flags & GRPC_POLLSET_CAN_KICK_SELF) == 0 &&
+            gpr_tls_get(&g_current_thread_worker) ==
+                (intptr_t)specific_worker) {
+          push_back_worker(p, specific_worker);
+          specific_worker = NULL;
+        }
+      }
+      if (specific_worker != NULL) {
+        GPR_TIMER_MARK("finally_kick", 0);
+        push_back_worker(p, specific_worker);
+        grpc_wakeup_fd_wakeup(&specific_worker->wakeup_fd->fd);
+      }
+    } else {
+      GPR_TIMER_MARK("kicked_no_pollers", 0);
+      p->kicked_without_pollers = 1;
+    }
+  }
+
+  GPR_TIMER_END("pollset_kick_ext", 0);
+}
+
+static void pollset_kick(grpc_pollset *p,
+                         grpc_pollset_worker *specific_worker) {
+  pollset_kick_ext(p, specific_worker, 0);
+}
+
+/* global state management */
+
+static void pollset_global_init(void) {
+  gpr_tls_init(&g_current_thread_poller);
+  gpr_tls_init(&g_current_thread_worker);
+  grpc_wakeup_fd_init(&grpc_global_wakeup_fd);
+}
+
+static void pollset_global_shutdown(void) {
+  grpc_wakeup_fd_destroy(&grpc_global_wakeup_fd);
+  gpr_tls_destroy(&g_current_thread_poller);
+  gpr_tls_destroy(&g_current_thread_worker);
+}
+
+static void kick_poller(void) { grpc_wakeup_fd_wakeup(&grpc_global_wakeup_fd); }
+
+/* main interface */
+
+static void become_basic_pollset(grpc_pollset *pollset, grpc_fd *fd_or_null);
+
+static void pollset_init(grpc_pollset *pollset, gpr_mu **mu) {
+  gpr_mu_init(&pollset->mu);
+  *mu = &pollset->mu;
+  pollset->root_worker.next = pollset->root_worker.prev = &pollset->root_worker;
+  pollset->in_flight_cbs = 0;
+  pollset->shutting_down = 0;
+  pollset->called_shutdown = 0;
+  pollset->kicked_without_pollers = 0;
+  pollset->idle_jobs.head = pollset->idle_jobs.tail = NULL;
+  pollset->local_wakeup_cache = NULL;
+  pollset->kicked_without_pollers = 0;
+  become_basic_pollset(pollset, NULL);
+}
+
+static void pollset_destroy(grpc_pollset *pollset) {
+  GPR_ASSERT(pollset->in_flight_cbs == 0);
+  GPR_ASSERT(!pollset_has_workers(pollset));
+  GPR_ASSERT(pollset->idle_jobs.head == pollset->idle_jobs.tail);
+  pollset->vtable->destroy(pollset);
+  while (pollset->local_wakeup_cache) {
+    grpc_cached_wakeup_fd *next = pollset->local_wakeup_cache->next;
+    grpc_wakeup_fd_destroy(&pollset->local_wakeup_cache->fd);
+    gpr_free(pollset->local_wakeup_cache);
+    pollset->local_wakeup_cache = next;
+  }
+  gpr_mu_destroy(&pollset->mu);
+}
+
+static void pollset_reset(grpc_pollset *pollset) {
+  GPR_ASSERT(pollset->shutting_down);
+  GPR_ASSERT(pollset->in_flight_cbs == 0);
+  GPR_ASSERT(!pollset_has_workers(pollset));
+  GPR_ASSERT(pollset->idle_jobs.head == pollset->idle_jobs.tail);
+  pollset->vtable->destroy(pollset);
+  pollset->shutting_down = 0;
+  pollset->called_shutdown = 0;
+  pollset->kicked_without_pollers = 0;
+  become_basic_pollset(pollset, NULL);
+}
+
+static void pollset_add_fd(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
+                           grpc_fd *fd) {
+  gpr_mu_lock(&pollset->mu);
+  pollset->vtable->add_fd(exec_ctx, pollset, fd, 1);
+/* the following (enabled only in debug) will reacquire and then release
+   our lock - meaning that if the unlocking flag passed to add_fd above is
+   not respected, the code will deadlock (in a way that we have a chance of
+   debugging) */
+#ifndef NDEBUG
+  gpr_mu_lock(&pollset->mu);
+  gpr_mu_unlock(&pollset->mu);
+#endif
+}
+
+static void finish_shutdown(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset) {
+  GPR_ASSERT(grpc_closure_list_empty(pollset->idle_jobs));
+  pollset->vtable->finish_shutdown(pollset);
+  grpc_exec_ctx_enqueue(exec_ctx, pollset->shutdown_done, true, NULL);
+}
+
+static void pollset_work(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
+                         grpc_pollset_worker **worker_hdl, gpr_timespec now,
+                         gpr_timespec deadline) {
+  grpc_pollset_worker worker;
+  *worker_hdl = &worker;
+
+  /* pollset->mu already held */
+  int added_worker = 0;
+  int locked = 1;
+  int queued_work = 0;
+  int keep_polling = 0;
+  GPR_TIMER_BEGIN("pollset_work", 0);
+  /* this must happen before we (potentially) drop pollset->mu */
+  worker.next = worker.prev = NULL;
+  worker.reevaluate_polling_on_wakeup = 0;
+  if (pollset->local_wakeup_cache != NULL) {
+    worker.wakeup_fd = pollset->local_wakeup_cache;
+    pollset->local_wakeup_cache = worker.wakeup_fd->next;
+  } else {
+    worker.wakeup_fd = gpr_malloc(sizeof(*worker.wakeup_fd));
+    grpc_wakeup_fd_init(&worker.wakeup_fd->fd);
+  }
+  worker.kicked_specifically = 0;
+  /* If there's work waiting for the pollset to be idle, and the
+     pollset is idle, then do that work */
+  if (!pollset_has_workers(pollset) &&
+      !grpc_closure_list_empty(pollset->idle_jobs)) {
+    GPR_TIMER_MARK("pollset_work.idle_jobs", 0);
+    grpc_exec_ctx_enqueue_list(exec_ctx, &pollset->idle_jobs, NULL);
+    goto done;
+  }
+  /* If we're shutting down then we don't execute any extended work */
+  if (pollset->shutting_down) {
+    GPR_TIMER_MARK("pollset_work.shutting_down", 0);
+    goto done;
+  }
+  /* Give do_promote priority so we don't starve it out */
+  if (pollset->in_flight_cbs) {
+    GPR_TIMER_MARK("pollset_work.in_flight_cbs", 0);
+    gpr_mu_unlock(&pollset->mu);
+    locked = 0;
+    goto done;
+  }
+  /* Start polling, and keep doing so while we're being asked to
+     re-evaluate our pollers (this allows poll() based pollers to
+     ensure they don't miss wakeups) */
+  keep_polling = 1;
+  while (keep_polling) {
+    keep_polling = 0;
+    if (!pollset->kicked_without_pollers) {
+      if (!added_worker) {
+        push_front_worker(pollset, &worker);
+        added_worker = 1;
+        gpr_tls_set(&g_current_thread_worker, (intptr_t)&worker);
+      }
+      gpr_tls_set(&g_current_thread_poller, (intptr_t)pollset);
+      GPR_TIMER_BEGIN("maybe_work_and_unlock", 0);
+      pollset->vtable->maybe_work_and_unlock(exec_ctx, pollset, &worker,
+                                             deadline, now);
+      GPR_TIMER_END("maybe_work_and_unlock", 0);
+      locked = 0;
+      gpr_tls_set(&g_current_thread_poller, 0);
+    } else {
+      GPR_TIMER_MARK("pollset_work.kicked_without_pollers", 0);
+      pollset->kicked_without_pollers = 0;
+    }
+  /* Finished execution - start cleaning up.
+     Note that we may arrive here from outside the enclosing while() loop.
+     In that case we won't loop though as we haven't added worker to the
+     worker list, which means nobody could ask us to re-evaluate polling). */
+  done:
+    if (!locked) {
+      queued_work |= grpc_exec_ctx_flush(exec_ctx);
+      gpr_mu_lock(&pollset->mu);
+      locked = 1;
+    }
+    /* If we're forced to re-evaluate polling (via pollset_kick with
+       GRPC_POLLSET_REEVALUATE_POLLING_ON_WAKEUP) then we land here and force
+       a loop */
+    if (worker.reevaluate_polling_on_wakeup) {
+      worker.reevaluate_polling_on_wakeup = 0;
+      pollset->kicked_without_pollers = 0;
+      if (queued_work || worker.kicked_specifically) {
+        /* If there's queued work on the list, then set the deadline to be
+           immediate so we get back out of the polling loop quickly */
+        deadline = gpr_inf_past(GPR_CLOCK_MONOTONIC);
+      }
+      keep_polling = 1;
+    }
+  }
+  if (added_worker) {
+    remove_worker(pollset, &worker);
+    gpr_tls_set(&g_current_thread_worker, 0);
+  }
+  /* release wakeup fd to the local pool */
+  worker.wakeup_fd->next = pollset->local_wakeup_cache;
+  pollset->local_wakeup_cache = worker.wakeup_fd;
+  /* check shutdown conditions */
+  if (pollset->shutting_down) {
+    if (pollset_has_workers(pollset)) {
+      pollset_kick(pollset, NULL);
+    } else if (!pollset->called_shutdown && pollset->in_flight_cbs == 0) {
+      pollset->called_shutdown = 1;
+      gpr_mu_unlock(&pollset->mu);
+      finish_shutdown(exec_ctx, pollset);
+      grpc_exec_ctx_flush(exec_ctx);
+      /* Continuing to access pollset here is safe -- it is the caller's
+       * responsibility to not destroy when it has outstanding calls to
+       * pollset_work.
+       * TODO(dklempner): Can we refactor the shutdown logic to avoid this? */
+      gpr_mu_lock(&pollset->mu);
+    } else if (!grpc_closure_list_empty(pollset->idle_jobs)) {
+      grpc_exec_ctx_enqueue_list(exec_ctx, &pollset->idle_jobs, NULL);
+      gpr_mu_unlock(&pollset->mu);
+      grpc_exec_ctx_flush(exec_ctx);
+      gpr_mu_lock(&pollset->mu);
+    }
+  }
+  *worker_hdl = NULL;
+  GPR_TIMER_END("pollset_work", 0);
+}
+
+static void pollset_shutdown(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
+                             grpc_closure *closure) {
+  GPR_ASSERT(!pollset->shutting_down);
+  pollset->shutting_down = 1;
+  pollset->shutdown_done = closure;
+  pollset_kick(pollset, GRPC_POLLSET_KICK_BROADCAST);
+  if (!pollset_has_workers(pollset)) {
+    grpc_exec_ctx_enqueue_list(exec_ctx, &pollset->idle_jobs, NULL);
+  }
+  if (!pollset->called_shutdown && pollset->in_flight_cbs == 0 &&
+      !pollset_has_workers(pollset)) {
+    pollset->called_shutdown = 1;
+    finish_shutdown(exec_ctx, pollset);
+  }
+}
+
+static int poll_deadline_to_millis_timeout(gpr_timespec deadline,
+                                           gpr_timespec now) {
+  gpr_timespec timeout;
+  static const int64_t max_spin_polling_us = 10;
+  if (gpr_time_cmp(deadline, gpr_inf_future(deadline.clock_type)) == 0) {
+    return -1;
+  }
+  if (gpr_time_cmp(deadline, gpr_time_add(now, gpr_time_from_micros(
+                                                   max_spin_polling_us,
+                                                   GPR_TIMESPAN))) <= 0) {
+    return 0;
+  }
+  timeout = gpr_time_sub(deadline, now);
+  return gpr_time_to_millis(gpr_time_add(
+      timeout, gpr_time_from_nanos(GPR_NS_PER_MS - 1, GPR_TIMESPAN)));
+}
+
+/*
+ * basic_pollset - a vtable that provides polling for zero or one file
+ *                 descriptor via poll()
+ */
+
+typedef struct grpc_unary_promote_args {
+  const grpc_pollset_vtable *original_vtable;
+  grpc_pollset *pollset;
+  grpc_fd *fd;
+  grpc_closure promotion_closure;
+} grpc_unary_promote_args;
+
+static void basic_do_promote(grpc_exec_ctx *exec_ctx, void *args,
+                             bool success) {
+  grpc_unary_promote_args *up_args = args;
+  const grpc_pollset_vtable *original_vtable = up_args->original_vtable;
+  grpc_pollset *pollset = up_args->pollset;
+  grpc_fd *fd = up_args->fd;
+
+  /*
+   * This is quite tricky. There are a number of cases to keep in mind here:
+   * 1. fd may have been orphaned
+   * 2. The pollset may no longer be a unary poller (and we can't let case #1
+   * leak to other pollset types!)
+   * 3. pollset's fd (which may have changed) may have been orphaned
+   * 4. The pollset may be shutting down.
+   */
+
+  gpr_mu_lock(&pollset->mu);
+  /* First we need to ensure that nobody is polling concurrently */
+  GPR_ASSERT(!pollset_has_workers(pollset));
+
+  gpr_free(up_args);
+  /* At this point the pollset may no longer be a unary poller. In that case
+   * we should just call the right add function and be done. */
+  /* TODO(klempner): If we're not careful this could cause infinite recursion.
+   * That's not a problem for now because empty_pollset has a trivial poller
+   * and we don't have any mechanism to unbecome multipoller. */
+  pollset->in_flight_cbs--;
+  if (pollset->shutting_down) {
+    /* We don't care about this pollset anymore. */
+    if (pollset->in_flight_cbs == 0 && !pollset->called_shutdown) {
+      pollset->called_shutdown = 1;
+      finish_shutdown(exec_ctx, pollset);
+    }
+  } else if (fd_is_orphaned(fd)) {
+    /* Don't try to add it to anything, we'll drop our ref on it below */
+  } else if (pollset->vtable != original_vtable) {
+    pollset->vtable->add_fd(exec_ctx, pollset, fd, 0);
+  } else if (fd != pollset->data.ptr) {
+    grpc_fd *fds[2];
+    fds[0] = pollset->data.ptr;
+    fds[1] = fd;
+
+    if (fds[0] && !fd_is_orphaned(fds[0])) {
+      platform_become_multipoller(exec_ctx, pollset, fds, GPR_ARRAY_SIZE(fds));
+      GRPC_FD_UNREF(fds[0], "basicpoll");
+    } else {
+      /* old fd is orphaned and we haven't cleaned it up until now, so remain a
+       * unary poller */
+      /* Note that it is possible that fds[1] is also orphaned at this point.
+       * That's okay, we'll correct it at the next add or poll. */
+      if (fds[0]) GRPC_FD_UNREF(fds[0], "basicpoll");
+      pollset->data.ptr = fd;
+      GRPC_FD_REF(fd, "basicpoll");
+    }
+  }
+
+  gpr_mu_unlock(&pollset->mu);
+
+  /* Matching ref in basic_pollset_add_fd */
+  GRPC_FD_UNREF(fd, "basicpoll_add");
+}
+
+static void basic_pollset_add_fd(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
+                                 grpc_fd *fd, int and_unlock_pollset) {
+  grpc_unary_promote_args *up_args;
+  GPR_ASSERT(fd);
+  if (fd == pollset->data.ptr) goto exit;
+
+  if (!pollset_has_workers(pollset)) {
+    /* Fast path -- no in flight cbs */
+    /* TODO(klempner): Comment this out and fix any test failures or establish
+     * they are due to timing issues */
+    grpc_fd *fds[2];
+    fds[0] = pollset->data.ptr;
+    fds[1] = fd;
+
+    if (fds[0] == NULL) {
+      pollset->data.ptr = fd;
+      GRPC_FD_REF(fd, "basicpoll");
+    } else if (!fd_is_orphaned(fds[0])) {
+      platform_become_multipoller(exec_ctx, pollset, fds, GPR_ARRAY_SIZE(fds));
+      GRPC_FD_UNREF(fds[0], "basicpoll");
+    } else {
+      /* old fd is orphaned and we haven't cleaned it up until now, so remain a
+       * unary poller */
+      GRPC_FD_UNREF(fds[0], "basicpoll");
+      pollset->data.ptr = fd;
+      GRPC_FD_REF(fd, "basicpoll");
+    }
+    goto exit;
+  }
+
+  /* Now we need to promote. This needs to happen when we're not polling. Since
+   * this may be called from poll, the wait needs to happen asynchronously. */
+  GRPC_FD_REF(fd, "basicpoll_add");
+  pollset->in_flight_cbs++;
+  up_args = gpr_malloc(sizeof(*up_args));
+  up_args->fd = fd;
+  up_args->original_vtable = pollset->vtable;
+  up_args->pollset = pollset;
+  up_args->promotion_closure.cb = basic_do_promote;
+  up_args->promotion_closure.cb_arg = up_args;
+
+  grpc_closure_list_add(&pollset->idle_jobs, &up_args->promotion_closure, 1);
+  pollset_kick(pollset, GRPC_POLLSET_KICK_BROADCAST);
+
+exit:
+  if (and_unlock_pollset) {
+    gpr_mu_unlock(&pollset->mu);
+  }
+}
+
+static void basic_pollset_maybe_work_and_unlock(grpc_exec_ctx *exec_ctx,
+                                                grpc_pollset *pollset,
+                                                grpc_pollset_worker *worker,
+                                                gpr_timespec deadline,
+                                                gpr_timespec now) {
+#define POLLOUT_CHECK (POLLOUT | POLLHUP | POLLERR)
+#define POLLIN_CHECK (POLLIN | POLLHUP | POLLERR)
+
+  struct pollfd pfd[3];
+  grpc_fd *fd;
+  grpc_fd_watcher fd_watcher;
+  int timeout;
+  int r;
+  nfds_t nfds;
+
+  fd = pollset->data.ptr;
+  if (fd && fd_is_orphaned(fd)) {
+    GRPC_FD_UNREF(fd, "basicpoll");
+    fd = pollset->data.ptr = NULL;
+  }
+  timeout = poll_deadline_to_millis_timeout(deadline, now);
+  pfd[0].fd = GRPC_WAKEUP_FD_GET_READ_FD(&grpc_global_wakeup_fd);
+  pfd[0].events = POLLIN;
+  pfd[0].revents = 0;
+  pfd[1].fd = GRPC_WAKEUP_FD_GET_READ_FD(&worker->wakeup_fd->fd);
+  pfd[1].events = POLLIN;
+  pfd[1].revents = 0;
+  nfds = 2;
+  if (fd) {
+    pfd[2].fd = fd->fd;
+    pfd[2].revents = 0;
+    GRPC_FD_REF(fd, "basicpoll_begin");
+    gpr_mu_unlock(&pollset->mu);
+    pfd[2].events =
+        (short)fd_begin_poll(fd, pollset, worker, POLLIN, POLLOUT, &fd_watcher);
+    if (pfd[2].events != 0) {
+      nfds++;
+    }
+  } else {
+    gpr_mu_unlock(&pollset->mu);
+  }
+
+  /* TODO(vpai): Consider first doing a 0 timeout poll here to avoid
+     even going into the blocking annotation if possible */
+  /* poll fd count (argument 2) is shortened by one if we have no events
+     to poll on - such that it only includes the kicker */
+  GPR_TIMER_BEGIN("poll", 0);
+  GRPC_SCHEDULING_START_BLOCKING_REGION;
+  r = grpc_poll_function(pfd, nfds, timeout);
+  GRPC_SCHEDULING_END_BLOCKING_REGION;
+  GPR_TIMER_END("poll", 0);
+
+  if (r < 0) {
+    if (errno != EINTR) {
+      gpr_log(GPR_ERROR, "poll() failed: %s", strerror(errno));
+    }
+    if (fd) {
+      fd_end_poll(exec_ctx, &fd_watcher, 0, 0, NULL);
+    }
+  } else if (r == 0) {
+    if (fd) {
+      fd_end_poll(exec_ctx, &fd_watcher, 0, 0, NULL);
+    }
+  } else {
+    if (pfd[0].revents & POLLIN_CHECK) {
+      grpc_wakeup_fd_consume_wakeup(&grpc_global_wakeup_fd);
+    }
+    if (pfd[1].revents & POLLIN_CHECK) {
+      grpc_wakeup_fd_consume_wakeup(&worker->wakeup_fd->fd);
+    }
+    if (nfds > 2) {
+      fd_end_poll(exec_ctx, &fd_watcher, pfd[2].revents & POLLIN_CHECK,
+                  pfd[2].revents & POLLOUT_CHECK, pollset);
+    } else if (fd) {
+      fd_end_poll(exec_ctx, &fd_watcher, 0, 0, NULL);
+    }
+  }
+
+  if (fd) {
+    GRPC_FD_UNREF(fd, "basicpoll_begin");
+  }
+}
+
+static void basic_pollset_destroy(grpc_pollset *pollset) {
+  if (pollset->data.ptr != NULL) {
+    GRPC_FD_UNREF(pollset->data.ptr, "basicpoll");
+    pollset->data.ptr = NULL;
+  }
+}
+
+static const grpc_pollset_vtable basic_pollset = {
+    basic_pollset_add_fd, basic_pollset_maybe_work_and_unlock,
+    basic_pollset_destroy, basic_pollset_destroy};
+
+static void become_basic_pollset(grpc_pollset *pollset, grpc_fd *fd_or_null) {
+  pollset->vtable = &basic_pollset;
+  pollset->data.ptr = fd_or_null;
+  if (fd_or_null != NULL) {
+    GRPC_FD_REF(fd_or_null, "basicpoll");
+  }
+}
+
+/*******************************************************************************
+ * pollset_multipoller_with_poll_posix.c
+ */
+
+#ifndef GPR_LINUX_MULTIPOLL_WITH_EPOLL
+
+typedef struct {
+  /* all polled fds */
+  size_t fd_count;
+  size_t fd_capacity;
+  grpc_fd **fds;
+  /* fds that have been removed from the pollset explicitly */
+  size_t del_count;
+  size_t del_capacity;
+  grpc_fd **dels;
+} poll_hdr;
+
+static void multipoll_with_poll_pollset_add_fd(grpc_exec_ctx *exec_ctx,
+                                               grpc_pollset *pollset,
+                                               grpc_fd *fd,
+                                               int and_unlock_pollset) {
+  size_t i;
+  poll_hdr *h = pollset->data.ptr;
+  /* TODO(ctiller): this is O(num_fds^2); maybe switch to a hash set here */
+  for (i = 0; i < h->fd_count; i++) {
+    if (h->fds[i] == fd) goto exit;
+  }
+  if (h->fd_count == h->fd_capacity) {
+    h->fd_capacity = GPR_MAX(h->fd_capacity + 8, h->fd_count * 3 / 2);
+    h->fds = gpr_realloc(h->fds, sizeof(grpc_fd *) * h->fd_capacity);
+  }
+  h->fds[h->fd_count++] = fd;
+  GRPC_FD_REF(fd, "multipoller");
+exit:
+  if (and_unlock_pollset) {
+    gpr_mu_unlock(&pollset->mu);
+  }
+}
+
+static void multipoll_with_poll_pollset_maybe_work_and_unlock(
+    grpc_exec_ctx *exec_ctx, grpc_pollset *pollset, grpc_pollset_worker *worker,
+    gpr_timespec deadline, gpr_timespec now) {
+#define POLLOUT_CHECK (POLLOUT | POLLHUP | POLLERR)
+#define POLLIN_CHECK (POLLIN | POLLHUP | POLLERR)
+
+  int timeout;
+  int r;
+  size_t i, j, fd_count;
+  nfds_t pfd_count;
+  poll_hdr *h;
+  /* TODO(ctiller): inline some elements to avoid an allocation */
+  grpc_fd_watcher *watchers;
+  struct pollfd *pfds;
+
+  h = pollset->data.ptr;
+  timeout = poll_deadline_to_millis_timeout(deadline, now);
+  /* TODO(ctiller): perform just one malloc here if we exceed the inline case */
+  pfds = gpr_malloc(sizeof(*pfds) * (h->fd_count + 2));
+  watchers = gpr_malloc(sizeof(*watchers) * (h->fd_count + 2));
+  fd_count = 0;
+  pfd_count = 2;
+  pfds[0].fd = GRPC_WAKEUP_FD_GET_READ_FD(&grpc_global_wakeup_fd);
+  pfds[0].events = POLLIN;
+  pfds[0].revents = 0;
+  pfds[1].fd = GRPC_WAKEUP_FD_GET_READ_FD(&worker->wakeup_fd->fd);
+  pfds[1].events = POLLIN;
+  pfds[1].revents = 0;
+  for (i = 0; i < h->fd_count; i++) {
+    int remove = fd_is_orphaned(h->fds[i]);
+    for (j = 0; !remove && j < h->del_count; j++) {
+      if (h->fds[i] == h->dels[j]) remove = 1;
+    }
+    if (remove) {
+      GRPC_FD_UNREF(h->fds[i], "multipoller");
+    } else {
+      h->fds[fd_count++] = h->fds[i];
+      watchers[pfd_count].fd = h->fds[i];
+      GRPC_FD_REF(watchers[pfd_count].fd, "multipoller_start");
+      pfds[pfd_count].fd = h->fds[i]->fd;
+      pfds[pfd_count].revents = 0;
+      pfd_count++;
+    }
+  }
+  for (j = 0; j < h->del_count; j++) {
+    GRPC_FD_UNREF(h->dels[j], "multipoller_del");
+  }
+  h->del_count = 0;
+  h->fd_count = fd_count;
+  gpr_mu_unlock(&pollset->mu);
+
+  for (i = 2; i < pfd_count; i++) {
+    grpc_fd *fd = watchers[i].fd;
+    pfds[i].events = (short)fd_begin_poll(fd, pollset, worker, POLLIN, POLLOUT,
+                                          &watchers[i]);
+    GRPC_FD_UNREF(fd, "multipoller_start");
+  }
+
+  /* TODO(vpai): Consider first doing a 0 timeout poll here to avoid
+     even going into the blocking annotation if possible */
+  GRPC_SCHEDULING_START_BLOCKING_REGION;
+  r = grpc_poll_function(pfds, pfd_count, timeout);
+  GRPC_SCHEDULING_END_BLOCKING_REGION;
+
+  if (r < 0) {
+    if (errno != EINTR) {
+      gpr_log(GPR_ERROR, "poll() failed: %s", strerror(errno));
+    }
+    for (i = 2; i < pfd_count; i++) {
+      fd_end_poll(exec_ctx, &watchers[i], 0, 0, NULL);
+    }
+  } else if (r == 0) {
+    for (i = 2; i < pfd_count; i++) {
+      fd_end_poll(exec_ctx, &watchers[i], 0, 0, NULL);
+    }
+  } else {
+    if (pfds[0].revents & POLLIN_CHECK) {
+      grpc_wakeup_fd_consume_wakeup(&grpc_global_wakeup_fd);
+    }
+    if (pfds[1].revents & POLLIN_CHECK) {
+      grpc_wakeup_fd_consume_wakeup(&worker->wakeup_fd->fd);
+    }
+    for (i = 2; i < pfd_count; i++) {
+      if (watchers[i].fd == NULL) {
+        fd_end_poll(exec_ctx, &watchers[i], 0, 0, NULL);
+        continue;
+      }
+      fd_end_poll(exec_ctx, &watchers[i], pfds[i].revents & POLLIN_CHECK,
+                  pfds[i].revents & POLLOUT_CHECK, pollset);
+    }
+  }
+
+  gpr_free(pfds);
+  gpr_free(watchers);
+}
+
+static void multipoll_with_poll_pollset_finish_shutdown(grpc_pollset *pollset) {
+  size_t i;
+  poll_hdr *h = pollset->data.ptr;
+  for (i = 0; i < h->fd_count; i++) {
+    GRPC_FD_UNREF(h->fds[i], "multipoller");
+  }
+  for (i = 0; i < h->del_count; i++) {
+    GRPC_FD_UNREF(h->dels[i], "multipoller_del");
+  }
+  h->fd_count = 0;
+  h->del_count = 0;
+}
+
+static void multipoll_with_poll_pollset_destroy(grpc_pollset *pollset) {
+  poll_hdr *h = pollset->data.ptr;
+  multipoll_with_poll_pollset_finish_shutdown(pollset);
+  gpr_free(h->fds);
+  gpr_free(h->dels);
+  gpr_free(h);
+}
+
+static const grpc_pollset_vtable multipoll_with_poll_pollset = {
+    multipoll_with_poll_pollset_add_fd,
+    multipoll_with_poll_pollset_maybe_work_and_unlock,
+    multipoll_with_poll_pollset_finish_shutdown,
+    multipoll_with_poll_pollset_destroy};
+
+static void poll_become_multipoller(grpc_exec_ctx *exec_ctx,
+                                    grpc_pollset *pollset, grpc_fd **fds,
+                                    size_t nfds) {
+  size_t i;
+  poll_hdr *h = gpr_malloc(sizeof(poll_hdr));
+  pollset->vtable = &multipoll_with_poll_pollset;
+  pollset->data.ptr = h;
+  h->fd_count = nfds;
+  h->fd_capacity = nfds;
+  h->fds = gpr_malloc(nfds * sizeof(grpc_fd *));
+  h->del_count = 0;
+  h->del_capacity = 0;
+  h->dels = NULL;
+  for (i = 0; i < nfds; i++) {
+    h->fds[i] = fds[i];
+    GRPC_FD_REF(fds[i], "multipoller");
+  }
+}
+
+#endif /* !GPR_LINUX_MULTIPOLL_WITH_EPOLL */
+
+/*******************************************************************************
+ * pollset_multipoller_with_epoll_posix.c
+ */
+
+#ifdef GPR_LINUX_MULTIPOLL_WITH_EPOLL
+
+#include <errno.h>
+#include <poll.h>
+#include <string.h>
+#include <sys/epoll.h>
+#include <unistd.h>
+
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/useful.h>
+
+#include "src/core/lib/iomgr/ev_posix.h"
+#include "src/core/lib/profiling/timers.h"
+#include "src/core/lib/support/block_annotate.h"
+
+static void set_ready(grpc_exec_ctx *exec_ctx, grpc_fd *fd, grpc_closure **st,
+                      grpc_pollset *read_notifier_pollset) {
+  /* only one set_ready can be active at once (but there may be a racing
+     notify_on) */
+  gpr_mu_lock(&fd->mu);
+  set_ready_locked(exec_ctx, fd, st);
+
+  /* A non-NULL read_notifier_pollset means that the fd is readable. */
+  if (read_notifier_pollset != NULL) {
+    /* Note: Since the fd might be a part of multiple pollsets, this might be
+     * called multiple times (for each time the fd becomes readable) and it is
+     * okay to set the fd's read-notifier pollset to anyone of these pollsets */
+    set_read_notifier_pollset_locked(exec_ctx, fd, read_notifier_pollset);
+  }
+
+  gpr_mu_unlock(&fd->mu);
+}
+
+static void fd_become_readable(grpc_exec_ctx *exec_ctx, grpc_fd *fd,
+                               grpc_pollset *notifier_pollset) {
+  set_ready(exec_ctx, fd, &fd->read_closure, notifier_pollset);
+}
+
+static void fd_become_writable(grpc_exec_ctx *exec_ctx, grpc_fd *fd) {
+  set_ready(exec_ctx, fd, &fd->write_closure, NULL);
+}
+
+struct epoll_fd_list {
+  int *epoll_fds;
+  size_t count;
+  size_t capacity;
+};
+
+static struct epoll_fd_list epoll_fd_global_list;
+static gpr_once init_epoll_fd_list_mu = GPR_ONCE_INIT;
+static gpr_mu epoll_fd_list_mu;
+
+static void init_mu(void) { gpr_mu_init(&epoll_fd_list_mu); }
+
+static void add_epoll_fd_to_global_list(int epoll_fd) {
+  gpr_once_init(&init_epoll_fd_list_mu, init_mu);
+
+  gpr_mu_lock(&epoll_fd_list_mu);
+  if (epoll_fd_global_list.count == epoll_fd_global_list.capacity) {
+    epoll_fd_global_list.capacity =
+        GPR_MAX((size_t)8, epoll_fd_global_list.capacity * 2);
+    epoll_fd_global_list.epoll_fds =
+        gpr_realloc(epoll_fd_global_list.epoll_fds,
+                    epoll_fd_global_list.capacity * sizeof(int));
+  }
+  epoll_fd_global_list.epoll_fds[epoll_fd_global_list.count++] = epoll_fd;
+  gpr_mu_unlock(&epoll_fd_list_mu);
+}
+
+static void remove_epoll_fd_from_global_list(int epoll_fd) {
+  gpr_mu_lock(&epoll_fd_list_mu);
+  GPR_ASSERT(epoll_fd_global_list.count > 0);
+  for (size_t i = 0; i < epoll_fd_global_list.count; i++) {
+    if (epoll_fd == epoll_fd_global_list.epoll_fds[i]) {
+      epoll_fd_global_list.epoll_fds[i] =
+          epoll_fd_global_list.epoll_fds[--(epoll_fd_global_list.count)];
+      break;
+    }
+  }
+  gpr_mu_unlock(&epoll_fd_list_mu);
+}
+
+static void remove_fd_from_all_epoll_sets(int fd) {
+  int err;
+  gpr_once_init(&init_epoll_fd_list_mu, init_mu);
+  gpr_mu_lock(&epoll_fd_list_mu);
+  if (epoll_fd_global_list.count == 0) {
+    gpr_mu_unlock(&epoll_fd_list_mu);
+    return;
+  }
+  for (size_t i = 0; i < epoll_fd_global_list.count; i++) {
+    err = epoll_ctl(epoll_fd_global_list.epoll_fds[i], EPOLL_CTL_DEL, fd, NULL);
+    if (err < 0 && errno != ENOENT) {
+      gpr_log(GPR_ERROR, "epoll_ctl del for %d failed: %s", fd,
+              strerror(errno));
+    }
+  }
+  gpr_mu_unlock(&epoll_fd_list_mu);
+}
+
+typedef struct {
+  grpc_pollset *pollset;
+  grpc_fd *fd;
+  grpc_closure closure;
+} delayed_add;
+
+typedef struct { int epoll_fd; } epoll_hdr;
+
+static void finally_add_fd(grpc_exec_ctx *exec_ctx, grpc_pollset *pollset,
+                           grpc_fd *fd) {
+  epoll_hdr *h = pollset->data.ptr;
+  struct epoll_event ev;
+  int err;
+  grpc_fd_watcher watcher;
+
+  /* We pretend to be polling whilst adding an fd to keep the fd from being
+     closed during the add. This may result in a spurious wakeup being assigned
+     to this pollset whilst adding, but that should be benign. */
+  GPR_ASSERT(fd_begin_poll(fd, pollset, NULL, 0, 0, &watcher) == 0);
+  if (watcher.fd != NULL) {
+    ev.events = (uint32_t)(EPOLLIN | EPOLLOUT | EPOLLET);
+    ev.data.ptr = fd;
+    err = epoll_ctl(h->epoll_fd, EPOLL_CTL_ADD, fd->fd, &ev);
+    if (err < 0) {
+      /* FDs may be added to a pollset multiple times, so EEXIST is normal. */
+      if (errno != EEXIST) {
+        gpr_log(GPR_ERROR, "epoll_ctl add for %d failed: %s", fd->fd,
+                strerror(errno));
+      }
+    }
+  }
+  fd_end_poll(exec_ctx, &watcher, 0, 0, NULL);
+}
+
+static void perform_delayed_add(grpc_exec_ctx *exec_ctx, void *arg,
+                                bool iomgr_status) {
+  delayed_add *da = arg;
+
+  if (!fd_is_orphaned(da->fd)) {
+    finally_add_fd(exec_ctx, da->pollset, da->fd);
+  }
+
+  gpr_mu_lock(&da->pollset->mu);
+  da->pollset->in_flight_cbs--;
+  if (da->pollset->shutting_down) {
+    /* We don't care about this pollset anymore. */
+    if (da->pollset->in_flight_cbs == 0 && !da->pollset->called_shutdown) {
+      da->pollset->called_shutdown = 1;
+      grpc_exec_ctx_enqueue(exec_ctx, da->pollset->shutdown_done, true, NULL);
+    }
+  }
+  gpr_mu_unlock(&da->pollset->mu);
+
+  GRPC_FD_UNREF(da->fd, "delayed_add");
+
+  gpr_free(da);
+}
+
+static void multipoll_with_epoll_pollset_add_fd(grpc_exec_ctx *exec_ctx,
+                                                grpc_pollset *pollset,
+                                                grpc_fd *fd,
+                                                int and_unlock_pollset) {
+  if (and_unlock_pollset) {
+    gpr_mu_unlock(&pollset->mu);
+    finally_add_fd(exec_ctx, pollset, fd);
+  } else {
+    delayed_add *da = gpr_malloc(sizeof(*da));
+    da->pollset = pollset;
+    da->fd = fd;
+    GRPC_FD_REF(fd, "delayed_add");
+    grpc_closure_init(&da->closure, perform_delayed_add, da);
+    pollset->in_flight_cbs++;
+    grpc_exec_ctx_enqueue(exec_ctx, &da->closure, true, NULL);
+  }
+}
+
+/* TODO(klempner): We probably want to turn this down a bit */
+#define GRPC_EPOLL_MAX_EVENTS 1000
+
+static void multipoll_with_epoll_pollset_maybe_work_and_unlock(
+    grpc_exec_ctx *exec_ctx, grpc_pollset *pollset, grpc_pollset_worker *worker,
+    gpr_timespec deadline, gpr_timespec now) {
+  struct epoll_event ep_ev[GRPC_EPOLL_MAX_EVENTS];
+  int ep_rv;
+  int poll_rv;
+  epoll_hdr *h = pollset->data.ptr;
+  int timeout_ms;
+  struct pollfd pfds[2];
+
+  /* If you want to ignore epoll's ability to sanely handle parallel pollers,
+   * for a more apples-to-apples performance comparison with poll, add a
+   * if (pollset->counter != 0) { return 0; }
+   * here.
+   */
+
+  gpr_mu_unlock(&pollset->mu);
+
+  timeout_ms = poll_deadline_to_millis_timeout(deadline, now);
+
+  pfds[0].fd = GRPC_WAKEUP_FD_GET_READ_FD(&worker->wakeup_fd->fd);
+  pfds[0].events = POLLIN;
+  pfds[0].revents = 0;
+  pfds[1].fd = h->epoll_fd;
+  pfds[1].events = POLLIN;
+  pfds[1].revents = 0;
+
+  /* TODO(vpai): Consider first doing a 0 timeout poll here to avoid
+     even going into the blocking annotation if possible */
+  GPR_TIMER_BEGIN("poll", 0);
+  GRPC_SCHEDULING_START_BLOCKING_REGION;
+  poll_rv = grpc_poll_function(pfds, 2, timeout_ms);
+  GRPC_SCHEDULING_END_BLOCKING_REGION;
+  GPR_TIMER_END("poll", 0);
+
+  if (poll_rv < 0) {
+    if (errno != EINTR) {
+      gpr_log(GPR_ERROR, "poll() failed: %s", strerror(errno));
+    }
+  } else if (poll_rv == 0) {
+    /* do nothing */
+  } else {
+    if (pfds[0].revents) {
+      grpc_wakeup_fd_consume_wakeup(&worker->wakeup_fd->fd);
+    }
+    if (pfds[1].revents) {
+      do {
+        /* The following epoll_wait never blocks; it has a timeout of 0 */
+        ep_rv = epoll_wait(h->epoll_fd, ep_ev, GRPC_EPOLL_MAX_EVENTS, 0);
+        if (ep_rv < 0) {
+          if (errno != EINTR) {
+            gpr_log(GPR_ERROR, "epoll_wait() failed: %s", strerror(errno));
+          }
+        } else {
+          int i;
+          for (i = 0; i < ep_rv; ++i) {
+            grpc_fd *fd = ep_ev[i].data.ptr;
+            /* TODO(klempner): We might want to consider making err and pri
+             * separate events */
+            int cancel = ep_ev[i].events & (EPOLLERR | EPOLLHUP);
+            int read_ev = ep_ev[i].events & (EPOLLIN | EPOLLPRI);
+            int write_ev = ep_ev[i].events & EPOLLOUT;
+            if (fd == NULL) {
+              grpc_wakeup_fd_consume_wakeup(&grpc_global_wakeup_fd);
+            } else {
+              if (read_ev || cancel) {
+                fd_become_readable(exec_ctx, fd, pollset);
+              }
+              if (write_ev || cancel) {
+                fd_become_writable(exec_ctx, fd);
+              }
+            }
+          }
+        }
+      } while (ep_rv == GRPC_EPOLL_MAX_EVENTS);
+    }
+  }
+}
+
+static void multipoll_with_epoll_pollset_finish_shutdown(
+    grpc_pollset *pollset) {}
+
+static void multipoll_with_epoll_pollset_destroy(grpc_pollset *pollset) {
+  epoll_hdr *h = pollset->data.ptr;
+  close(h->epoll_fd);
+  remove_epoll_fd_from_global_list(h->epoll_fd);
+  gpr_free(h);
+}
+
+static const grpc_pollset_vtable multipoll_with_epoll_pollset = {
+    multipoll_with_epoll_pollset_add_fd,
+    multipoll_with_epoll_pollset_maybe_work_and_unlock,
+    multipoll_with_epoll_pollset_finish_shutdown,
+    multipoll_with_epoll_pollset_destroy};
+
+static void epoll_become_multipoller(grpc_exec_ctx *exec_ctx,
+                                     grpc_pollset *pollset, grpc_fd **fds,
+                                     size_t nfds) {
+  size_t i;
+  epoll_hdr *h = gpr_malloc(sizeof(epoll_hdr));
+  struct epoll_event ev;
+  int err;
+
+  pollset->vtable = &multipoll_with_epoll_pollset;
+  pollset->data.ptr = h;
+  h->epoll_fd = epoll_create1(EPOLL_CLOEXEC);
+  if (h->epoll_fd < 0) {
+    /* TODO(klempner): Fall back to poll here, especially on ENOSYS */
+    gpr_log(GPR_ERROR, "epoll_create1 failed: %s", strerror(errno));
+    abort();
+  }
+  add_epoll_fd_to_global_list(h->epoll_fd);
+
+  ev.events = (uint32_t)(EPOLLIN | EPOLLET);
+  ev.data.ptr = NULL;
+  err = epoll_ctl(h->epoll_fd, EPOLL_CTL_ADD,
+                  GRPC_WAKEUP_FD_GET_READ_FD(&grpc_global_wakeup_fd), &ev);
+  if (err < 0) {
+    gpr_log(GPR_ERROR, "epoll_ctl add for %d failed: %s",
+            GRPC_WAKEUP_FD_GET_READ_FD(&grpc_global_wakeup_fd),
+            strerror(errno));
+  }
+
+  for (i = 0; i < nfds; i++) {
+    multipoll_with_epoll_pollset_add_fd(exec_ctx, pollset, fds[i], 0);
+  }
+}
+
+#else /* GPR_LINUX_MULTIPOLL_WITH_EPOLL */
+
+static void remove_fd_from_all_epoll_sets(int fd) {}
+
+#endif /* GPR_LINUX_MULTIPOLL_WITH_EPOLL */
+
+/*******************************************************************************
+ * pollset_set_posix.c
+ */
+
+static grpc_pollset_set *pollset_set_create(void) {
+  grpc_pollset_set *pollset_set = gpr_malloc(sizeof(*pollset_set));
+  memset(pollset_set, 0, sizeof(*pollset_set));
+  gpr_mu_init(&pollset_set->mu);
+  return pollset_set;
+}
+
+static void pollset_set_destroy(grpc_pollset_set *pollset_set) {
+  size_t i;
+  gpr_mu_destroy(&pollset_set->mu);
+  for (i = 0; i < pollset_set->fd_count; i++) {
+    GRPC_FD_UNREF(pollset_set->fds[i], "pollset_set");
+  }
+  gpr_free(pollset_set->pollsets);
+  gpr_free(pollset_set->pollset_sets);
+  gpr_free(pollset_set->fds);
+  gpr_free(pollset_set);
+}
+
+static void pollset_set_add_pollset(grpc_exec_ctx *exec_ctx,
+                                    grpc_pollset_set *pollset_set,
+                                    grpc_pollset *pollset) {
+  size_t i, j;
+  gpr_mu_lock(&pollset_set->mu);
+  if (pollset_set->pollset_count == pollset_set->pollset_capacity) {
+    pollset_set->pollset_capacity =
+        GPR_MAX(8, 2 * pollset_set->pollset_capacity);
+    pollset_set->pollsets =
+        gpr_realloc(pollset_set->pollsets, pollset_set->pollset_capacity *
+                                               sizeof(*pollset_set->pollsets));
+  }
+  pollset_set->pollsets[pollset_set->pollset_count++] = pollset;
+  for (i = 0, j = 0; i < pollset_set->fd_count; i++) {
+    if (fd_is_orphaned(pollset_set->fds[i])) {
+      GRPC_FD_UNREF(pollset_set->fds[i], "pollset_set");
+    } else {
+      pollset_add_fd(exec_ctx, pollset, pollset_set->fds[i]);
+      pollset_set->fds[j++] = pollset_set->fds[i];
+    }
+  }
+  pollset_set->fd_count = j;
+  gpr_mu_unlock(&pollset_set->mu);
+}
+
+static void pollset_set_del_pollset(grpc_exec_ctx *exec_ctx,
+                                    grpc_pollset_set *pollset_set,
+                                    grpc_pollset *pollset) {
+  size_t i;
+  gpr_mu_lock(&pollset_set->mu);
+  for (i = 0; i < pollset_set->pollset_count; i++) {
+    if (pollset_set->pollsets[i] == pollset) {
+      pollset_set->pollset_count--;
+      GPR_SWAP(grpc_pollset *, pollset_set->pollsets[i],
+               pollset_set->pollsets[pollset_set->pollset_count]);
+      break;
+    }
+  }
+  gpr_mu_unlock(&pollset_set->mu);
+}
+
+static void pollset_set_add_pollset_set(grpc_exec_ctx *exec_ctx,
+                                        grpc_pollset_set *bag,
+                                        grpc_pollset_set *item) {
+  size_t i, j;
+  gpr_mu_lock(&bag->mu);
+  if (bag->pollset_set_count == bag->pollset_set_capacity) {
+    bag->pollset_set_capacity = GPR_MAX(8, 2 * bag->pollset_set_capacity);
+    bag->pollset_sets =
+        gpr_realloc(bag->pollset_sets,
+                    bag->pollset_set_capacity * sizeof(*bag->pollset_sets));
+  }
+  bag->pollset_sets[bag->pollset_set_count++] = item;
+  for (i = 0, j = 0; i < bag->fd_count; i++) {
+    if (fd_is_orphaned(bag->fds[i])) {
+      GRPC_FD_UNREF(bag->fds[i], "pollset_set");
+    } else {
+      pollset_set_add_fd(exec_ctx, item, bag->fds[i]);
+      bag->fds[j++] = bag->fds[i];
+    }
+  }
+  bag->fd_count = j;
+  gpr_mu_unlock(&bag->mu);
+}
+
+static void pollset_set_del_pollset_set(grpc_exec_ctx *exec_ctx,
+                                        grpc_pollset_set *bag,
+                                        grpc_pollset_set *item) {
+  size_t i;
+  gpr_mu_lock(&bag->mu);
+  for (i = 0; i < bag->pollset_set_count; i++) {
+    if (bag->pollset_sets[i] == item) {
+      bag->pollset_set_count--;
+      GPR_SWAP(grpc_pollset_set *, bag->pollset_sets[i],
+               bag->pollset_sets[bag->pollset_set_count]);
+      break;
+    }
+  }
+  gpr_mu_unlock(&bag->mu);
+}
+
+static void pollset_set_add_fd(grpc_exec_ctx *exec_ctx,
+                               grpc_pollset_set *pollset_set, grpc_fd *fd) {
+  size_t i;
+  gpr_mu_lock(&pollset_set->mu);
+  if (pollset_set->fd_count == pollset_set->fd_capacity) {
+    pollset_set->fd_capacity = GPR_MAX(8, 2 * pollset_set->fd_capacity);
+    pollset_set->fds = gpr_realloc(
+        pollset_set->fds, pollset_set->fd_capacity * sizeof(*pollset_set->fds));
+  }
+  GRPC_FD_REF(fd, "pollset_set");
+  pollset_set->fds[pollset_set->fd_count++] = fd;
+  for (i = 0; i < pollset_set->pollset_count; i++) {
+    pollset_add_fd(exec_ctx, pollset_set->pollsets[i], fd);
+  }
+  for (i = 0; i < pollset_set->pollset_set_count; i++) {
+    pollset_set_add_fd(exec_ctx, pollset_set->pollset_sets[i], fd);
+  }
+  gpr_mu_unlock(&pollset_set->mu);
+}
+
+static void pollset_set_del_fd(grpc_exec_ctx *exec_ctx,
+                               grpc_pollset_set *pollset_set, grpc_fd *fd) {
+  size_t i;
+  gpr_mu_lock(&pollset_set->mu);
+  for (i = 0; i < pollset_set->fd_count; i++) {
+    if (pollset_set->fds[i] == fd) {
+      pollset_set->fd_count--;
+      GPR_SWAP(grpc_fd *, pollset_set->fds[i],
+               pollset_set->fds[pollset_set->fd_count]);
+      GRPC_FD_UNREF(fd, "pollset_set");
+      break;
+    }
+  }
+  for (i = 0; i < pollset_set->pollset_set_count; i++) {
+    pollset_set_del_fd(exec_ctx, pollset_set->pollset_sets[i], fd);
+  }
+  gpr_mu_unlock(&pollset_set->mu);
+}
+
+/*******************************************************************************
+ * event engine binding
+ */
+
+static void shutdown_engine(void) {
+  fd_global_shutdown();
+  pollset_global_shutdown();
+}
+
+static const grpc_event_engine_vtable vtable = {
+    .pollset_size = sizeof(grpc_pollset),
+
+    .fd_create = fd_create,
+    .fd_wrapped_fd = fd_wrapped_fd,
+    .fd_orphan = fd_orphan,
+    .fd_shutdown = fd_shutdown,
+    .fd_notify_on_read = fd_notify_on_read,
+    .fd_notify_on_write = fd_notify_on_write,
+    .fd_get_read_notifier_pollset = fd_get_read_notifier_pollset,
+
+    .pollset_init = pollset_init,
+    .pollset_shutdown = pollset_shutdown,
+    .pollset_reset = pollset_reset,
+    .pollset_destroy = pollset_destroy,
+    .pollset_work = pollset_work,
+    .pollset_kick = pollset_kick,
+    .pollset_add_fd = pollset_add_fd,
+
+    .pollset_set_create = pollset_set_create,
+    .pollset_set_destroy = pollset_set_destroy,
+    .pollset_set_add_pollset = pollset_set_add_pollset,
+    .pollset_set_del_pollset = pollset_set_del_pollset,
+    .pollset_set_add_pollset_set = pollset_set_add_pollset_set,
+    .pollset_set_del_pollset_set = pollset_set_del_pollset_set,
+    .pollset_set_add_fd = pollset_set_add_fd,
+    .pollset_set_del_fd = pollset_set_del_fd,
+
+    .kick_poller = kick_poller,
+
+    .shutdown_engine = shutdown_engine,
+};
+
+const grpc_event_engine_vtable *grpc_init_poll_and_epoll_posix(void) {
+#ifdef GPR_LINUX_MULTIPOLL_WITH_EPOLL
+  platform_become_multipoller = epoll_become_multipoller;
+#else
+  platform_become_multipoller = poll_become_multipoller;
+#endif
+  fd_global_init();
+  pollset_global_init();
+  return &vtable;
+}
+
+#endif
diff --git a/include/grpc/support/atm_win32.h b/src/core/lib/iomgr/ev_poll_and_epoll_posix.h
similarity index 84%
copy from include/grpc/support/atm_win32.h
copy to src/core/lib/iomgr/ev_poll_and_epoll_posix.h
index 13526d9..06d6dbf 100644
--- a/include/grpc/support/atm_win32.h
+++ b/src/core/lib/iomgr/ev_poll_and_epoll_posix.h
@@ -31,9 +31,11 @@
  *
  */
 
-#ifndef GRPC_SUPPORT_ATM_WIN32_H
-#define GRPC_SUPPORT_ATM_WIN32_H
+#ifndef GRPC_CORE_LIB_IOMGR_EV_POLL_AND_EPOLL_POSIX_H
+#define GRPC_CORE_LIB_IOMGR_EV_POLL_AND_EPOLL_POSIX_H
 
-#include <grpc/impl/codegen/atm_win32.h>
+#include "src/core/lib/iomgr/ev_posix.h"
 
-#endif /* GRPC_SUPPORT_ATM_WIN32_H */
+const grpc_event_engine_vtable *grpc_init_poll_and_epoll_posix(void);
+
+#endif /* GRPC_CORE_LIB_IOMGR_EV_POLL_AND_EPOLL_POSIX_H */
diff --git a/src/core/lib/iomgr/ev_poll_posix.c b/src/core/lib/iomgr/ev_poll_posix.c
index e2a2123..0167999 100644
--- a/src/core/lib/iomgr/ev_poll_posix.c
+++ b/src/core/lib/iomgr/ev_poll_posix.c
@@ -59,8 +59,6 @@
  * FD declarations
  */
 
-grpc_wakeup_fd grpc_global_wakeup_fd;
-
 typedef struct grpc_fd_watcher {
   struct grpc_fd_watcher *next;
   struct grpc_fd_watcher *prev;
diff --git a/src/core/lib/iomgr/ev_posix.c b/src/core/lib/iomgr/ev_posix.c
index 95520b0..6477b05 100644
--- a/src/core/lib/iomgr/ev_posix.c
+++ b/src/core/lib/iomgr/ev_posix.c
@@ -44,6 +44,7 @@
 #include <grpc/support/string_util.h>
 #include <grpc/support/useful.h>
 
+#include "src/core/lib/iomgr/ev_poll_and_epoll_posix.h"
 #include "src/core/lib/iomgr/ev_poll_posix.h"
 #include "src/core/lib/support/env.h"
 
@@ -61,7 +62,7 @@
 } event_engine_factory;
 
 static const event_engine_factory g_factories[] = {
-    {"poll", grpc_init_poll_posix},
+    {"poll", grpc_init_poll_posix}, {"legacy", grpc_init_poll_and_epoll_posix},
 };
 
 static void add(const char *beg, const char *end, char ***ss, size_t *ns) {
diff --git a/src/core/lib/iomgr/iocp_windows.c b/src/core/lib/iomgr/iocp_windows.c
index d46558a..7082322 100644
--- a/src/core/lib/iomgr/iocp_windows.c
+++ b/src/core/lib/iomgr/iocp_windows.c
@@ -39,7 +39,7 @@
 
 #include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
-#include <grpc/support/log_win32.h>
+#include <grpc/support/log_windows.h>
 #include <grpc/support/thd.h>
 
 #include "src/core/lib/iomgr/iocp_windows.h"
diff --git a/src/core/lib/iomgr/iomgr_windows.c b/src/core/lib/iomgr/iomgr_windows.c
index 398517f..7653f6e 100644
--- a/src/core/lib/iomgr/iomgr_windows.c
+++ b/src/core/lib/iomgr/iomgr_windows.c
@@ -35,7 +35,7 @@
 
 #ifdef GPR_WINSOCK_SOCKET
 
-#include "src/core/lib/iomgr/sockaddr_win32.h"
+#include "src/core/lib/iomgr/sockaddr_windows.h"
 
 #include <grpc/support/log.h>
 
diff --git a/src/core/lib/iomgr/polling_entity.c b/src/core/lib/iomgr/polling_entity.c
new file mode 100644
index 0000000..d1686aa
--- /dev/null
+++ b/src/core/lib/iomgr/polling_entity.c
@@ -0,0 +1,104 @@
+/*
+ *
+ * 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 <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+
+#include "src/core/lib/iomgr/polling_entity.h"
+
+grpc_polling_entity grpc_polling_entity_create_from_pollset_set(
+    grpc_pollset_set *pollset_set) {
+  grpc_polling_entity pollent;
+  pollent.pollent.pollset_set = pollset_set;
+  pollent.tag = POPS_POLLSET_SET;
+  return pollent;
+}
+
+grpc_polling_entity grpc_polling_entity_create_from_pollset(
+    grpc_pollset *pollset) {
+  grpc_polling_entity pollent;
+  pollent.pollent.pollset = pollset;
+  pollent.tag = POPS_POLLSET;
+  return pollent;
+}
+
+grpc_pollset *grpc_polling_entity_pollset(grpc_polling_entity *pollent) {
+  if (pollent->tag == POPS_POLLSET) {
+    return pollent->pollent.pollset;
+  }
+  return NULL;
+}
+
+grpc_pollset_set *grpc_polling_entity_pollset_set(
+    grpc_polling_entity *pollent) {
+  if (pollent->tag == POPS_POLLSET_SET) {
+    return pollent->pollent.pollset_set;
+  }
+  return NULL;
+}
+
+bool grpc_polling_entity_is_empty(const grpc_polling_entity *pollent) {
+  return pollent->tag == POPS_NONE;
+}
+
+void grpc_polling_entity_add_to_pollset_set(grpc_exec_ctx *exec_ctx,
+                                            grpc_polling_entity *pollent,
+                                            grpc_pollset_set *pss_dst) {
+  if (pollent->tag == POPS_POLLSET) {
+    GPR_ASSERT(pollent->pollent.pollset != NULL);
+    grpc_pollset_set_add_pollset(exec_ctx, pss_dst, pollent->pollent.pollset);
+  } else if (pollent->tag == POPS_POLLSET_SET) {
+    GPR_ASSERT(pollent->pollent.pollset_set != NULL);
+    grpc_pollset_set_add_pollset_set(exec_ctx, pss_dst,
+                                     pollent->pollent.pollset_set);
+  } else {
+    gpr_log(GPR_ERROR, "Invalid grpc_polling_entity tag '%d'", pollent->tag);
+    abort();
+  }
+}
+
+void grpc_polling_entity_del_from_pollset_set(grpc_exec_ctx *exec_ctx,
+                                              grpc_polling_entity *pollent,
+                                              grpc_pollset_set *pss_dst) {
+  if (pollent->tag == POPS_POLLSET) {
+    GPR_ASSERT(pollent->pollent.pollset != NULL);
+    grpc_pollset_set_del_pollset(exec_ctx, pss_dst, pollent->pollent.pollset);
+  } else if (pollent->tag == POPS_POLLSET_SET) {
+    GPR_ASSERT(pollent->pollent.pollset_set != NULL);
+    grpc_pollset_set_del_pollset_set(exec_ctx, pss_dst,
+                                     pollent->pollent.pollset_set);
+  } else {
+    gpr_log(GPR_ERROR, "Invalid grpc_polling_entity tag '%d'", pollent->tag);
+    abort();
+  }
+}
diff --git a/src/core/lib/iomgr/polling_entity.h b/src/core/lib/iomgr/polling_entity.h
new file mode 100644
index 0000000..e815310
--- /dev/null
+++ b/src/core/lib/iomgr/polling_entity.h
@@ -0,0 +1,81 @@
+/*
+ *
+ * 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_CORE_LIB_IOMGR_POLLING_ENTITY_H
+#define GRPC_CORE_LIB_IOMGR_POLLING_ENTITY_H
+
+#include "src/core/lib/iomgr/pollset.h"
+#include "src/core/lib/iomgr/pollset_set.h"
+
+/* A grpc_polling_entity is a pollset-or-pollset_set container. It allows
+ * functions that
+ * accept a pollset XOR a pollset_set to do so through an abstract interface.
+ * No ownership is taken. */
+
+typedef struct grpc_polling_entity {
+  union {
+    grpc_pollset *pollset;
+    grpc_pollset_set *pollset_set;
+  } pollent;
+  enum pops_tag { POPS_NONE, POPS_POLLSET, POPS_POLLSET_SET } tag;
+} grpc_polling_entity;
+
+grpc_polling_entity grpc_polling_entity_create_from_pollset_set(
+    grpc_pollset_set *pollset_set);
+grpc_polling_entity grpc_polling_entity_create_from_pollset(
+    grpc_pollset *pollset);
+
+/** If \a pollent contains a pollset, return it. Otherwise, return NULL */
+grpc_pollset *grpc_polling_entity_pollset(grpc_polling_entity *pollent);
+
+/** If \a pollent contains a pollset_set, return it. Otherwise, return NULL */
+grpc_pollset_set *grpc_polling_entity_pollset_set(grpc_polling_entity *pollent);
+
+bool grpc_polling_entity_is_empty(const grpc_polling_entity *pollent);
+
+/** Add the pollset or pollset_set in \a pollent to the destination pollset_set
+ * \a
+ * pss_dst */
+void grpc_polling_entity_add_to_pollset_set(grpc_exec_ctx *exec_ctx,
+                                            grpc_polling_entity *pollent,
+                                            grpc_pollset_set *pss_dst);
+
+/** Delete the pollset or pollset_set in \a pollent from the destination
+ * pollset_set \a
+ * pss_dst */
+void grpc_polling_entity_del_from_pollset_set(grpc_exec_ctx *exec_ctx,
+                                              grpc_polling_entity *pollent,
+                                              grpc_pollset_set *pss_dst);
+/* pollset_set specific */
+
+#endif /* GRPC_CORE_LIB_IOMGR_POLLING_ENTITY_H */
diff --git a/src/core/lib/iomgr/pollset_set_windows.c b/src/core/lib/iomgr/pollset_set_windows.c
index 89f60b9..a35a976 100644
--- a/src/core/lib/iomgr/pollset_set_windows.c
+++ b/src/core/lib/iomgr/pollset_set_windows.c
@@ -32,12 +32,15 @@
  */
 
 #include <grpc/support/port_platform.h>
+#include <stdint.h>
 
 #ifdef GPR_WINSOCK_SOCKET
 
 #include "src/core/lib/iomgr/pollset_set_windows.h"
 
-grpc_pollset_set* grpc_pollset_set_create(void) { return NULL; }
+grpc_pollset_set* grpc_pollset_set_create(void) {
+  return (grpc_pollset_set*)((intptr_t)0xdeafbeef);
+}
 
 void grpc_pollset_set_destroy(grpc_pollset_set* pollset_set) {}
 
diff --git a/src/core/lib/iomgr/resolve_address_windows.c b/src/core/lib/iomgr/resolve_address_windows.c
index 9147362..c1bbb3d 100644
--- a/src/core/lib/iomgr/resolve_address_windows.c
+++ b/src/core/lib/iomgr/resolve_address_windows.c
@@ -43,7 +43,7 @@
 #include <grpc/support/alloc.h>
 #include <grpc/support/host_port.h>
 #include <grpc/support/log.h>
-#include <grpc/support/log_win32.h>
+#include <grpc/support/log_windows.h>
 #include <grpc/support/string_util.h>
 #include <grpc/support/thd.h>
 #include <grpc/support/time.h>
diff --git a/src/core/lib/iomgr/sockaddr.h b/src/core/lib/iomgr/sockaddr.h
index 891a2f0..5563d0b 100644
--- a/src/core/lib/iomgr/sockaddr.h
+++ b/src/core/lib/iomgr/sockaddr.h
@@ -36,8 +36,8 @@
 
 #include <grpc/support/port_platform.h>
 
-#ifdef GPR_WIN32
-#include "src/core/lib/iomgr/sockaddr_win32.h"
+#ifdef GPR_WINDOWS
+#include "src/core/lib/iomgr/sockaddr_windows.h"
 #endif
 
 #ifdef GPR_POSIX_SOCKETADDR
diff --git a/src/core/lib/iomgr/sockaddr_win32.h b/src/core/lib/iomgr/sockaddr_windows.h
similarity index 91%
rename from src/core/lib/iomgr/sockaddr_win32.h
rename to src/core/lib/iomgr/sockaddr_windows.h
index 02aeae7..971db5b 100644
--- a/src/core/lib/iomgr/sockaddr_win32.h
+++ b/src/core/lib/iomgr/sockaddr_windows.h
@@ -31,8 +31,8 @@
  *
  */
 
-#ifndef GRPC_CORE_LIB_IOMGR_SOCKADDR_WIN32_H
-#define GRPC_CORE_LIB_IOMGR_SOCKADDR_WIN32_H
+#ifndef GRPC_CORE_LIB_IOMGR_SOCKADDR_WINDOWS_H
+#define GRPC_CORE_LIB_IOMGR_SOCKADDR_WINDOWS_H
 
 #include <winsock2.h>
 #include <ws2tcpip.h>
@@ -40,4 +40,4 @@
 // must be included after the above
 #include <mswsock.h>
 
-#endif /* GRPC_CORE_LIB_IOMGR_SOCKADDR_WIN32_H */
+#endif /* GRPC_CORE_LIB_IOMGR_SOCKADDR_WINDOWS_H */
diff --git a/src/core/lib/iomgr/socket_utils_common_posix.c b/src/core/lib/iomgr/socket_utils_common_posix.c
index fa83cee..2147c86 100644
--- a/src/core/lib/iomgr/socket_utils_common_posix.c
+++ b/src/core/lib/iomgr/socket_utils_common_posix.c
@@ -111,6 +111,16 @@
 #endif
 }
 
+int grpc_set_socket_sndbuf(int fd, int buffer_size_bytes) {
+  return 0 == setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &buffer_size_bytes,
+                         sizeof(buffer_size_bytes));
+}
+
+int grpc_set_socket_rcvbuf(int fd, int buffer_size_bytes) {
+  return 0 == setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &buffer_size_bytes,
+                         sizeof(buffer_size_bytes));
+}
+
 /* set a socket to close on exec */
 int grpc_set_socket_cloexec(int fd, int close_on_exec) {
   int oldflags = fcntl(fd, F_GETFD, 0);
diff --git a/src/core/lib/iomgr/socket_utils_posix.h b/src/core/lib/iomgr/socket_utils_posix.h
index a8f6e5e..7e41d1c 100644
--- a/src/core/lib/iomgr/socket_utils_posix.h
+++ b/src/core/lib/iomgr/socket_utils_posix.h
@@ -78,6 +78,14 @@
    If IPV6_RECVPKTINFO is not available, returns 1. */
 int grpc_set_socket_ipv6_recvpktinfo_if_possible(int fd);
 
+/* Tries to set the socket's send buffer to given size.
+   Returns 1 on success, 0 on failure. */
+int grpc_set_socket_sndbuf(int fd, int buffer_size_bytes);
+
+/* Tries to set the socket's receive buffer to given size.
+   Returns 1 on success, 0 on failure. */
+int grpc_set_socket_rcvbuf(int fd, int buffer_size_bytes);
+
 /* An enum to keep track of IPv4/IPv6 socket modes.
 
    Currently, this information is only used when a socket is first created, but
diff --git a/src/core/lib/iomgr/socket_windows.c b/src/core/lib/iomgr/socket_windows.c
index ebd77e0..7d8f9f7 100644
--- a/src/core/lib/iomgr/socket_windows.c
+++ b/src/core/lib/iomgr/socket_windows.c
@@ -42,7 +42,7 @@
 
 #include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
-#include <grpc/support/log_win32.h>
+#include <grpc/support/log_windows.h>
 #include <grpc/support/string_util.h>
 
 #include "src/core/lib/iomgr/iocp_windows.h"
diff --git a/src/core/lib/iomgr/tcp_client_windows.c b/src/core/lib/iomgr/tcp_client_windows.c
index 66f9ff7..efa0140 100644
--- a/src/core/lib/iomgr/tcp_client_windows.c
+++ b/src/core/lib/iomgr/tcp_client_windows.c
@@ -35,11 +35,11 @@
 
 #ifdef GPR_WINSOCK_SOCKET
 
-#include "src/core/lib/iomgr/sockaddr_win32.h"
+#include "src/core/lib/iomgr/sockaddr_windows.h"
 
 #include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
-#include <grpc/support/log_win32.h>
+#include <grpc/support/log_windows.h>
 #include <grpc/support/slice_buffer.h>
 #include <grpc/support/useful.h>
 
diff --git a/src/core/lib/iomgr/tcp_server_posix.c b/src/core/lib/iomgr/tcp_server_posix.c
index c695621..909e34a 100644
--- a/src/core/lib/iomgr/tcp_server_posix.c
+++ b/src/core/lib/iomgr/tcp_server_posix.c
@@ -128,6 +128,9 @@
   grpc_pollset **pollsets;
   /* number of pollsets in the pollsets array */
   size_t pollset_count;
+
+  /* next pollset to assign a channel to */
+  size_t next_pollset_to_assign;
 };
 
 grpc_tcp_server *grpc_tcp_server_create(grpc_closure *shutdown_complete) {
@@ -145,6 +148,7 @@
   s->head = NULL;
   s->tail = NULL;
   s->nports = 0;
+  s->next_pollset_to_assign = 0;
   return s;
 }
 
@@ -317,7 +321,9 @@
     goto error;
   }
 
-  read_notifier_pollset = grpc_fd_get_read_notifier_pollset(exec_ctx, sp->emfd);
+  read_notifier_pollset =
+      sp->server->pollsets[(sp->server->next_pollset_to_assign++) %
+                           sp->server->pollset_count];
 
   /* loop until accept4 returns EAGAIN, and then re-arm notification */
   for (;;) {
diff --git a/src/core/lib/iomgr/tcp_server_windows.c b/src/core/lib/iomgr/tcp_server_windows.c
index e15f8b0..8a21d93 100644
--- a/src/core/lib/iomgr/tcp_server_windows.c
+++ b/src/core/lib/iomgr/tcp_server_windows.c
@@ -41,7 +41,7 @@
 
 #include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
-#include <grpc/support/log_win32.h>
+#include <grpc/support/log_windows.h>
 #include <grpc/support/string_util.h>
 #include <grpc/support/sync.h>
 #include <grpc/support/time.h>
diff --git a/src/core/lib/iomgr/tcp_windows.c b/src/core/lib/iomgr/tcp_windows.c
index 551149e..f44bf5f 100644
--- a/src/core/lib/iomgr/tcp_windows.c
+++ b/src/core/lib/iomgr/tcp_windows.c
@@ -37,11 +37,11 @@
 
 #include <limits.h>
 
-#include "src/core/lib/iomgr/sockaddr_win32.h"
+#include "src/core/lib/iomgr/sockaddr_windows.h"
 
 #include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
-#include <grpc/support/log_win32.h>
+#include <grpc/support/log_windows.h>
 #include <grpc/support/slice_buffer.h>
 #include <grpc/support/string_util.h>
 #include <grpc/support/useful.h>
diff --git a/src/core/lib/iomgr/timer.c b/src/core/lib/iomgr/timer.c
index acb5b26..69d3bab 100644
--- a/src/core/lib/iomgr/timer.c
+++ b/src/core/lib/iomgr/timer.c
@@ -278,8 +278,8 @@
   return !grpc_timer_heap_is_empty(&shard->heap);
 }
 
-/* This pops the next non-cancelled timer with deadline <= now from the queue,
-   or returns NULL if there isn't one.
+/* This pops the next non-cancelled timer with deadline <= now from the
+   queue, or returns NULL if there isn't one.
    REQUIRES: shard->mu locked */
 static grpc_timer *pop_one(shard_type *shard, gpr_timespec now) {
   grpc_timer *timer;
diff --git a/src/core/lib/iomgr/udp_server.c b/src/core/lib/iomgr/udp_server.c
index 98ffccd..1615068 100644
--- a/src/core/lib/iomgr/udp_server.c
+++ b/src/core/lib/iomgr/udp_server.c
@@ -210,6 +210,8 @@
                           size_t addr_len) {
   struct sockaddr_storage sockname_temp;
   socklen_t sockname_len;
+  /* Set send/receive socket buffers to 1 MB */
+  int buffer_size_bytes = 1024 * 1024;
 
   if (fd < 0) {
     goto error;
@@ -239,6 +241,18 @@
     goto error;
   }
 
+  if (!grpc_set_socket_sndbuf(fd, buffer_size_bytes)) {
+    gpr_log(GPR_ERROR, "Failed to set send buffer size to %d bytes",
+            buf_size_bytes);
+    goto error;
+  }
+
+  if (!grpc_set_socket_rcvbuf(fd, buffer_size_bytes)) {
+    gpr_log(GPR_ERROR, "Failed to set receive buffer size to %d bytes",
+            buf_size_bytes);
+    goto error;
+  }
+
   return grpc_sockaddr_get_port((struct sockaddr *)&sockname_temp);
 
 error:
diff --git a/src/core/lib/iomgr/workqueue.h b/src/core/lib/iomgr/workqueue.h
index 3e2b223..eeca8c0 100644
--- a/src/core/lib/iomgr/workqueue.h
+++ b/src/core/lib/iomgr/workqueue.h
@@ -43,7 +43,7 @@
 #include "src/core/lib/iomgr/workqueue_posix.h"
 #endif
 
-#ifdef GPR_WIN32
+#ifdef GPR_WINDOWS
 #include "src/core/lib/iomgr/workqueue_windows.h"
 #endif
 
diff --git a/src/core/lib/iomgr/workqueue_windows.c b/src/core/lib/iomgr/workqueue_windows.c
index c3c0446..275f040 100644
--- a/src/core/lib/iomgr/workqueue_windows.c
+++ b/src/core/lib/iomgr/workqueue_windows.c
@@ -33,8 +33,8 @@
 
 #include <grpc/support/port_platform.h>
 
-#ifdef GPR_WIN32
+#ifdef GPR_WINDOWS
 
 #include "src/core/lib/iomgr/workqueue.h"
 
-#endif /* GPR_WIN32 */
+#endif /* GPR_WINDOWS */
diff --git a/src/core/lib/security/credentials/composite/composite_credentials.c b/src/core/lib/security/credentials/composite/composite_credentials.c
index 18189a8..07db8bf 100644
--- a/src/core/lib/security/credentials/composite/composite_credentials.c
+++ b/src/core/lib/security/credentials/composite/composite_credentials.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -35,6 +35,7 @@
 
 #include <string.h>
 
+#include "src/core/lib/iomgr/polling_entity.h"
 #include "src/core/lib/surface/api_trace.h"
 
 #include <grpc/support/alloc.h>
@@ -49,7 +50,7 @@
   grpc_credentials_md_store *md_elems;
   grpc_auth_metadata_context auth_md_context;
   void *user_data;
-  grpc_pollset *pollset;
+  grpc_polling_entity *pollent;
   grpc_credentials_metadata_cb cb;
 } grpc_composite_call_credentials_metadata_context;
 
@@ -93,7 +94,7 @@
     grpc_call_credentials *inner_creds =
         ctx->composite_creds->inner.creds_array[ctx->creds_index++];
     grpc_call_credentials_get_request_metadata(
-        exec_ctx, inner_creds, ctx->pollset, ctx->auth_md_context,
+        exec_ctx, inner_creds, ctx->pollent, ctx->auth_md_context,
         composite_call_metadata_cb, ctx);
     return;
   }
@@ -106,7 +107,7 @@
 
 static void composite_call_get_request_metadata(
     grpc_exec_ctx *exec_ctx, grpc_call_credentials *creds,
-    grpc_pollset *pollset, grpc_auth_metadata_context auth_md_context,
+    grpc_polling_entity *pollent, grpc_auth_metadata_context auth_md_context,
     grpc_credentials_metadata_cb cb, void *user_data) {
   grpc_composite_call_credentials *c = (grpc_composite_call_credentials *)creds;
   grpc_composite_call_credentials_metadata_context *ctx;
@@ -117,10 +118,10 @@
   ctx->user_data = user_data;
   ctx->cb = cb;
   ctx->composite_creds = c;
-  ctx->pollset = pollset;
+  ctx->pollent = pollent;
   ctx->md_elems = grpc_credentials_md_store_create(c->inner.num_creds);
   grpc_call_credentials_get_request_metadata(
-      exec_ctx, c->inner.creds_array[ctx->creds_index++], pollset,
+      exec_ctx, c->inner.creds_array[ctx->creds_index++], ctx->pollent,
       auth_md_context, composite_call_metadata_cb, ctx);
 }
 
diff --git a/src/core/lib/security/credentials/credentials.c b/src/core/lib/security/credentials/credentials.c
index 3dde6e5..f45a8d8 100644
--- a/src/core/lib/security/credentials/credentials.c
+++ b/src/core/lib/security/credentials/credentials.c
@@ -111,7 +111,7 @@
 
 void grpc_call_credentials_get_request_metadata(
     grpc_exec_ctx *exec_ctx, grpc_call_credentials *creds,
-    grpc_pollset *pollset, grpc_auth_metadata_context context,
+    grpc_polling_entity *pollent, grpc_auth_metadata_context context,
     grpc_credentials_metadata_cb cb, void *user_data) {
   if (creds == NULL || creds->vtable->get_request_metadata == NULL) {
     if (cb != NULL) {
@@ -119,7 +119,7 @@
     }
     return;
   }
-  creds->vtable->get_request_metadata(exec_ctx, creds, pollset, context, cb,
+  creds->vtable->get_request_metadata(exec_ctx, creds, pollent, context, cb,
                                       user_data);
 }
 
diff --git a/src/core/lib/security/credentials/credentials.h b/src/core/lib/security/credentials/credentials.h
index 5f44c7c..15dcfe4 100644
--- a/src/core/lib/security/credentials/credentials.h
+++ b/src/core/lib/security/credentials/credentials.h
@@ -41,6 +41,7 @@
 
 #include "src/core/lib/http/httpcli.h"
 #include "src/core/lib/http/parser.h"
+#include "src/core/lib/iomgr/polling_entity.h"
 #include "src/core/lib/security/transport/security_connector.h"
 
 struct grpc_http_response;
@@ -164,7 +165,8 @@
 typedef struct {
   void (*destruct)(grpc_call_credentials *c);
   void (*get_request_metadata)(grpc_exec_ctx *exec_ctx,
-                               grpc_call_credentials *c, grpc_pollset *pollset,
+                               grpc_call_credentials *c,
+                               grpc_polling_entity *pollent,
                                grpc_auth_metadata_context context,
                                grpc_credentials_metadata_cb cb,
                                void *user_data);
@@ -180,7 +182,7 @@
 void grpc_call_credentials_unref(grpc_call_credentials *creds);
 void grpc_call_credentials_get_request_metadata(
     grpc_exec_ctx *exec_ctx, grpc_call_credentials *creds,
-    grpc_pollset *pollset, grpc_auth_metadata_context context,
+    grpc_polling_entity *pollent, grpc_auth_metadata_context context,
     grpc_credentials_metadata_cb cb, void *user_data);
 
 /* Metadata-only credentials with the specified key and value where
diff --git a/src/core/lib/security/credentials/fake/fake_credentials.c b/src/core/lib/security/credentials/fake/fake_credentials.c
index 54d7cf2..005777d 100644
--- a/src/core/lib/security/credentials/fake/fake_credentials.c
+++ b/src/core/lib/security/credentials/fake/fake_credentials.c
@@ -106,7 +106,7 @@
 
 static void md_only_test_get_request_metadata(
     grpc_exec_ctx *exec_ctx, grpc_call_credentials *creds,
-    grpc_pollset *pollset, grpc_auth_metadata_context context,
+    grpc_polling_entity *pollent, grpc_auth_metadata_context context,
     grpc_credentials_metadata_cb cb, void *user_data) {
   grpc_md_only_test_credentials *c = (grpc_md_only_test_credentials *)creds;
 
diff --git a/src/core/lib/security/credentials/google_default/credentials_win32.c b/src/core/lib/security/credentials/google_default/credentials_windows.c
similarity index 97%
rename from src/core/lib/security/credentials/google_default/credentials_win32.c
rename to src/core/lib/security/credentials/google_default/credentials_windows.c
index cd8b480..208b8fd 100644
--- a/src/core/lib/security/credentials/google_default/credentials_win32.c
+++ b/src/core/lib/security/credentials/google_default/credentials_windows.c
@@ -33,7 +33,7 @@
 
 #include <grpc/support/port_platform.h>
 
-#ifdef GPR_WIN32
+#ifdef GPR_WINDOWS
 
 #include "src/core/lib/security/credentials/google_default/google_default_credentials.h"
 
@@ -58,4 +58,4 @@
   return result;
 }
 
-#endif /* GPR_WIN32 */
+#endif /* GPR_WINDOWS */
diff --git a/src/core/lib/security/credentials/google_default/google_default_credentials.c b/src/core/lib/security/credentials/google_default/google_default_credentials.c
index a521d95..98df68e 100644
--- a/src/core/lib/security/credentials/google_default/google_default_credentials.c
+++ b/src/core/lib/security/credentials/google_default/google_default_credentials.c
@@ -41,6 +41,7 @@
 
 #include "src/core/lib/http/httpcli.h"
 #include "src/core/lib/http/parser.h"
+#include "src/core/lib/iomgr/polling_entity.h"
 #include "src/core/lib/security/credentials/jwt/jwt_credentials.h"
 #include "src/core/lib/security/credentials/oauth2/oauth2_credentials.h"
 #include "src/core/lib/support/env.h"
@@ -62,7 +63,7 @@
 static void init_default_credentials(void) { gpr_mu_init(&g_state_mu); }
 
 typedef struct {
-  grpc_pollset *pollset;
+  grpc_polling_entity pollent;
   int is_done;
   int success;
 } compute_engine_detector;
@@ -86,7 +87,7 @@
   }
   gpr_mu_lock(g_polling_mu);
   detector->is_done = 1;
-  grpc_pollset_kick(detector->pollset, NULL);
+  grpc_pollset_kick(grpc_polling_entity_pollset(&detector->pollent), NULL);
   gpr_mu_unlock(g_polling_mu);
 }
 
@@ -105,8 +106,9 @@
      on compute engine. */
   gpr_timespec max_detection_delay = gpr_time_from_seconds(1, GPR_TIMESPAN);
 
-  detector.pollset = gpr_malloc(grpc_pollset_size());
-  grpc_pollset_init(detector.pollset, &g_polling_mu);
+  grpc_pollset *pollset = gpr_malloc(grpc_pollset_size());
+  grpc_pollset_init(pollset, &g_polling_mu);
+  detector.pollent = grpc_polling_entity_create_from_pollset(pollset);
   detector.is_done = 0;
   detector.success = 0;
 
@@ -117,7 +119,7 @@
   grpc_httpcli_context_init(&context);
 
   grpc_httpcli_get(
-      &exec_ctx, &context, detector.pollset, &request,
+      &exec_ctx, &context, &detector.pollent, &request,
       gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), max_detection_delay),
       on_compute_engine_detection_http_response, &detector);
 
@@ -128,19 +130,22 @@
   gpr_mu_lock(g_polling_mu);
   while (!detector.is_done) {
     grpc_pollset_worker *worker = NULL;
-    grpc_pollset_work(&exec_ctx, detector.pollset, &worker,
-                      gpr_now(GPR_CLOCK_MONOTONIC),
+    grpc_pollset_work(&exec_ctx, grpc_polling_entity_pollset(&detector.pollent),
+                      &worker, gpr_now(GPR_CLOCK_MONOTONIC),
                       gpr_inf_future(GPR_CLOCK_MONOTONIC));
   }
   gpr_mu_unlock(g_polling_mu);
 
   grpc_httpcli_context_destroy(&context);
-  grpc_closure_init(&destroy_closure, destroy_pollset, detector.pollset);
-  grpc_pollset_shutdown(&exec_ctx, detector.pollset, &destroy_closure);
+  grpc_closure_init(&destroy_closure, destroy_pollset,
+                    grpc_polling_entity_pollset(&detector.pollent));
+  grpc_pollset_shutdown(&exec_ctx,
+                        grpc_polling_entity_pollset(&detector.pollent),
+                        &destroy_closure);
   grpc_exec_ctx_finish(&exec_ctx);
   g_polling_mu = NULL;
 
-  gpr_free(detector.pollset);
+  gpr_free(grpc_polling_entity_pollset(&detector.pollent));
 
   return detector.success;
 }
diff --git a/src/core/lib/security/credentials/iam/iam_credentials.c b/src/core/lib/security/credentials/iam/iam_credentials.c
index 89defa7..64d5871 100644
--- a/src/core/lib/security/credentials/iam/iam_credentials.c
+++ b/src/core/lib/security/credentials/iam/iam_credentials.c
@@ -49,7 +49,7 @@
 
 static void iam_get_request_metadata(grpc_exec_ctx *exec_ctx,
                                      grpc_call_credentials *creds,
-                                     grpc_pollset *pollset,
+                                     grpc_polling_entity *pollent,
                                      grpc_auth_metadata_context context,
                                      grpc_credentials_metadata_cb cb,
                                      void *user_data) {
diff --git a/src/core/lib/security/credentials/jwt/jwt_credentials.c b/src/core/lib/security/credentials/jwt/jwt_credentials.c
index 8755a96..973fb75 100644
--- a/src/core/lib/security/credentials/jwt/jwt_credentials.c
+++ b/src/core/lib/security/credentials/jwt/jwt_credentials.c
@@ -64,7 +64,7 @@
 
 static void jwt_get_request_metadata(grpc_exec_ctx *exec_ctx,
                                      grpc_call_credentials *creds,
-                                     grpc_pollset *pollset,
+                                     grpc_polling_entity *pollent,
                                      grpc_auth_metadata_context context,
                                      grpc_credentials_metadata_cb cb,
                                      void *user_data) {
diff --git a/src/core/lib/security/credentials/jwt/jwt_verifier.c b/src/core/lib/security/credentials/jwt/jwt_verifier.c
index cd6c7ce..1f67db1 100644
--- a/src/core/lib/security/credentials/jwt/jwt_verifier.c
+++ b/src/core/lib/security/credentials/jwt/jwt_verifier.c
@@ -37,6 +37,7 @@
 #include <string.h>
 
 #include "src/core/lib/http/httpcli.h"
+#include "src/core/lib/iomgr/polling_entity.h"
 #include "src/core/lib/security/util/b64.h"
 #include "src/core/lib/tsi/ssl_types.h"
 
@@ -321,7 +322,7 @@
 
 typedef struct {
   grpc_jwt_verifier *verifier;
-  grpc_pollset *pollset;
+  grpc_polling_entity pollent;
   jose_header *header;
   grpc_jwt_claims *claims;
   char *audience;
@@ -337,10 +338,11 @@
     grpc_jwt_claims *claims, const char *audience, gpr_slice signature,
     const char *signed_jwt, size_t signed_jwt_len, void *user_data,
     grpc_jwt_verification_done_cb cb) {
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   verifier_cb_ctx *ctx = gpr_malloc(sizeof(verifier_cb_ctx));
   memset(ctx, 0, sizeof(verifier_cb_ctx));
   ctx->verifier = verifier;
-  ctx->pollset = pollset;
+  ctx->pollent = grpc_polling_entity_create_from_pollset(pollset);
   ctx->header = header;
   ctx->audience = gpr_strdup(audience);
   ctx->claims = claims;
@@ -348,6 +350,7 @@
   ctx->signed_data = gpr_slice_from_copied_buffer(signed_jwt, signed_jwt_len);
   ctx->user_data = user_data;
   ctx->user_cb = cb;
+  grpc_exec_ctx_finish(&exec_ctx);
   return ctx;
 }
 
@@ -642,7 +645,7 @@
     *(req.host + (req.http.path - jwks_uri)) = '\0';
   }
   grpc_httpcli_get(
-      exec_ctx, &ctx->verifier->http_ctx, ctx->pollset, &req,
+      exec_ctx, &ctx->verifier->http_ctx, &ctx->pollent, &req,
       gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), grpc_jwt_verifier_max_delay),
       on_keys_retrieved, ctx);
   grpc_json_destroy(json);
@@ -745,7 +748,7 @@
   }
 
   grpc_httpcli_get(
-      exec_ctx, &ctx->verifier->http_ctx, ctx->pollset, &req,
+      exec_ctx, &ctx->verifier->http_ctx, &ctx->pollent, &req,
       gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), grpc_jwt_verifier_max_delay),
       http_cb, ctx);
   gpr_free(req.host);
diff --git a/src/core/lib/security/credentials/oauth2/oauth2_credentials.c b/src/core/lib/security/credentials/oauth2/oauth2_credentials.c
index 973c6e1..268026b 100644
--- a/src/core/lib/security/credentials/oauth2/oauth2_credentials.c
+++ b/src/core/lib/security/credentials/oauth2/oauth2_credentials.c
@@ -244,7 +244,7 @@
 
 static void oauth2_token_fetcher_get_request_metadata(
     grpc_exec_ctx *exec_ctx, grpc_call_credentials *creds,
-    grpc_pollset *pollset, grpc_auth_metadata_context context,
+    grpc_polling_entity *pollent, grpc_auth_metadata_context context,
     grpc_credentials_metadata_cb cb, void *user_data) {
   grpc_oauth2_token_fetcher_credentials *c =
       (grpc_oauth2_token_fetcher_credentials *)creds;
@@ -270,7 +270,7 @@
     c->fetch_func(
         exec_ctx,
         grpc_credentials_metadata_request_create(creds, cb, user_data),
-        &c->httpcli_context, pollset, on_oauth2_token_fetcher_http_response,
+        &c->httpcli_context, pollent, on_oauth2_token_fetcher_http_response,
         gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), refresh_threshold));
   }
 }
@@ -295,7 +295,7 @@
 
 static void compute_engine_fetch_oauth2(
     grpc_exec_ctx *exec_ctx, grpc_credentials_metadata_request *metadata_req,
-    grpc_httpcli_context *httpcli_context, grpc_pollset *pollset,
+    grpc_httpcli_context *httpcli_context, grpc_polling_entity *pollent,
     grpc_httpcli_response_cb response_cb, gpr_timespec deadline) {
   grpc_http_header header = {"Metadata-Flavor", "Google"};
   grpc_httpcli_request request;
@@ -304,7 +304,7 @@
   request.http.path = GRPC_COMPUTE_ENGINE_METADATA_TOKEN_PATH;
   request.http.hdr_count = 1;
   request.http.hdrs = &header;
-  grpc_httpcli_get(exec_ctx, httpcli_context, pollset, &request, deadline,
+  grpc_httpcli_get(exec_ctx, httpcli_context, pollent, &request, deadline,
                    response_cb, metadata_req);
 }
 
@@ -336,7 +336,7 @@
 
 static void refresh_token_fetch_oauth2(
     grpc_exec_ctx *exec_ctx, grpc_credentials_metadata_request *metadata_req,
-    grpc_httpcli_context *httpcli_context, grpc_pollset *pollset,
+    grpc_httpcli_context *httpcli_context, grpc_polling_entity *pollent,
     grpc_httpcli_response_cb response_cb, gpr_timespec deadline) {
   grpc_google_refresh_token_credentials *c =
       (grpc_google_refresh_token_credentials *)metadata_req->creds;
@@ -353,7 +353,7 @@
   request.http.hdr_count = 1;
   request.http.hdrs = &header;
   request.handshaker = &grpc_httpcli_ssl;
-  grpc_httpcli_post(exec_ctx, httpcli_context, pollset, &request, body,
+  grpc_httpcli_post(exec_ctx, httpcli_context, pollent, &request, body,
                     strlen(body), deadline, response_cb, metadata_req);
   gpr_free(body);
 }
@@ -396,7 +396,7 @@
 
 static void access_token_get_request_metadata(
     grpc_exec_ctx *exec_ctx, grpc_call_credentials *creds,
-    grpc_pollset *pollset, grpc_auth_metadata_context context,
+    grpc_polling_entity *pollent, grpc_auth_metadata_context context,
     grpc_credentials_metadata_cb cb, void *user_data) {
   grpc_access_token_credentials *c = (grpc_access_token_credentials *)creds;
   cb(exec_ctx, user_data, c->access_token_md->entries, 1, GRPC_CREDENTIALS_OK);
diff --git a/src/core/lib/security/credentials/oauth2/oauth2_credentials.h b/src/core/lib/security/credentials/oauth2/oauth2_credentials.h
index 04915b3..3bc8360 100644
--- a/src/core/lib/security/credentials/oauth2/oauth2_credentials.h
+++ b/src/core/lib/security/credentials/oauth2/oauth2_credentials.h
@@ -70,7 +70,7 @@
 typedef void (*grpc_fetch_oauth2_func)(grpc_exec_ctx *exec_ctx,
                                        grpc_credentials_metadata_request *req,
                                        grpc_httpcli_context *http_context,
-                                       grpc_pollset *pollset,
+                                       grpc_polling_entity *pollent,
                                        grpc_httpcli_response_cb response_cb,
                                        gpr_timespec deadline);
 typedef struct {
diff --git a/src/core/lib/security/credentials/plugin/plugin_credentials.c b/src/core/lib/security/credentials/plugin/plugin_credentials.c
index bae3573..9fb55e8 100644
--- a/src/core/lib/security/credentials/plugin/plugin_credentials.c
+++ b/src/core/lib/security/credentials/plugin/plugin_credentials.c
@@ -94,7 +94,7 @@
 
 static void plugin_get_request_metadata(grpc_exec_ctx *exec_ctx,
                                         grpc_call_credentials *creds,
-                                        grpc_pollset *pollset,
+                                        grpc_polling_entity *pollent,
                                         grpc_auth_metadata_context context,
                                         grpc_credentials_metadata_cb cb,
                                         void *user_data) {
diff --git a/src/core/lib/security/transport/client_auth_filter.c b/src/core/lib/security/transport/client_auth_filter.c
index e3cbcb4..76be2ac 100644
--- a/src/core/lib/security/transport/client_auth_filter.c
+++ b/src/core/lib/security/transport/client_auth_filter.c
@@ -54,11 +54,11 @@
   grpc_call_credentials *creds;
   grpc_mdstr *host;
   grpc_mdstr *method;
-  /* pollset bound to this call; if we need to make external
-     network requests, they should be done under this pollset
-     so that work can progress when this call wants work to
-     progress */
-  grpc_pollset *pollset;
+  /* pollset{_set} bound to this call; if we need to make external
+     network requests, they should be done under a pollset added to this
+     pollset_set so that work can progress when this call wants work to progress
+  */
+  grpc_polling_entity *pollent;
   grpc_transport_stream_op op;
   uint8_t security_context_set;
   grpc_linked_mdelem md_links[MAX_CREDENTIALS_METADATA_COUNT];
@@ -184,9 +184,9 @@
   build_auth_metadata_context(&chand->security_connector->base,
                               chand->auth_context, calld);
   calld->op = *op; /* Copy op (originates from the caller's stack). */
-  GPR_ASSERT(calld->pollset);
+  GPR_ASSERT(calld->pollent != NULL);
   grpc_call_credentials_get_request_metadata(
-      exec_ctx, calld->creds, calld->pollset, calld->auth_md_context,
+      exec_ctx, calld->creds, calld->pollent, calld->auth_md_context,
       on_credentials_metadata, elem);
 }
 
@@ -270,15 +270,16 @@
   memset(calld, 0, sizeof(*calld));
 }
 
-static void set_pollset(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
-                        grpc_pollset *pollset) {
+static void set_pollset_or_pollset_set(grpc_exec_ctx *exec_ctx,
+                                       grpc_call_element *elem,
+                                       grpc_polling_entity *pollent) {
   call_data *calld = elem->call_data;
-  calld->pollset = pollset;
+  calld->pollent = pollent;
 }
 
 /* Destructor for call_data */
 static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
-                              void *ignored) {
+                              const grpc_call_stats *stats, void *ignored) {
   call_data *calld = elem->call_data;
   grpc_call_credentials_unref(calld->creds);
   if (calld->host != NULL) {
@@ -329,8 +330,14 @@
   GRPC_AUTH_CONTEXT_UNREF(chand->auth_context, "client_auth_filter");
 }
 
-const grpc_channel_filter grpc_client_auth_filter = {
-    auth_start_transport_op, grpc_channel_next_op, sizeof(call_data),
-    init_call_elem,          set_pollset,          destroy_call_elem,
-    sizeof(channel_data),    init_channel_elem,    destroy_channel_elem,
-    grpc_call_next_get_peer, "client-auth"};
+const grpc_channel_filter grpc_client_auth_filter = {auth_start_transport_op,
+                                                     grpc_channel_next_op,
+                                                     sizeof(call_data),
+                                                     init_call_elem,
+                                                     set_pollset_or_pollset_set,
+                                                     destroy_call_elem,
+                                                     sizeof(channel_data),
+                                                     init_channel_elem,
+                                                     destroy_channel_elem,
+                                                     grpc_call_next_get_peer,
+                                                     "client-auth"};
diff --git a/src/core/lib/security/transport/server_auth_filter.c b/src/core/lib/security/transport/server_auth_filter.c
index 006a30f..b36be12 100644
--- a/src/core/lib/security/transport/server_auth_filter.c
+++ b/src/core/lib/security/transport/server_auth_filter.c
@@ -220,12 +220,9 @@
       grpc_server_security_context_destroy;
 }
 
-static void set_pollset(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
-                        grpc_pollset *pollset) {}
-
 /* Destructor for call_data */
 static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
-                              void *ignored) {}
+                              const grpc_call_stats *stats, void *ignored) {}
 
 /* Constructor for channel_data */
 static void init_channel_elem(grpc_exec_ctx *exec_ctx,
@@ -258,7 +255,14 @@
 }
 
 const grpc_channel_filter grpc_server_auth_filter = {
-    auth_start_transport_op, grpc_channel_next_op, sizeof(call_data),
-    init_call_elem,          set_pollset,          destroy_call_elem,
-    sizeof(channel_data),    init_channel_elem,    destroy_channel_elem,
-    grpc_call_next_get_peer, "server-auth"};
+    auth_start_transport_op,
+    grpc_channel_next_op,
+    sizeof(call_data),
+    init_call_elem,
+    grpc_call_stack_ignore_set_pollset_or_pollset_set,
+    destroy_call_elem,
+    sizeof(channel_data),
+    init_channel_elem,
+    destroy_channel_elem,
+    grpc_call_next_get_peer,
+    "server-auth"};
diff --git a/src/core/lib/support/cpu_windows.c b/src/core/lib/support/cpu_windows.c
index ce32eb0..34d006b 100644
--- a/src/core/lib/support/cpu_windows.c
+++ b/src/core/lib/support/cpu_windows.c
@@ -33,7 +33,7 @@
 
 #include <grpc/support/port_platform.h>
 
-#ifdef GPR_WIN32
+#ifdef GPR_WINDOWS
 #include <grpc/support/log.h>
 
 unsigned gpr_cpu_num_cores(void) {
@@ -44,4 +44,4 @@
 
 unsigned gpr_cpu_current_cpu(void) { return GetCurrentProcessorNumber(); }
 
-#endif /* GPR_WIN32 */
+#endif /* GPR_WINDOWS */
diff --git a/src/core/lib/support/env_win32.c b/src/core/lib/support/env_windows.c
similarity index 95%
rename from src/core/lib/support/env_win32.c
rename to src/core/lib/support/env_windows.c
index e670e1e..9116959 100644
--- a/src/core/lib/support/env_win32.c
+++ b/src/core/lib/support/env_windows.c
@@ -33,13 +33,13 @@
 
 #include <grpc/support/port_platform.h>
 
-#ifdef GPR_WIN32_ENV
+#ifdef GPR_WINDOWS_ENV
 
 #include <windows.h>
 
 #include "src/core/lib/support/env.h"
 #include "src/core/lib/support/string.h"
-#include "src/core/lib/support/string_win32.h"
+#include "src/core/lib/support/string_windows.h"
 
 #include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
@@ -76,4 +76,4 @@
   GPR_ASSERT(res);
 }
 
-#endif /* GPR_WIN32_ENV */
+#endif /* GPR_WINDOWS_ENV */
diff --git a/src/core/lib/support/log_win32.c b/src/core/lib/support/log_windows.c
similarity index 95%
rename from src/core/lib/support/log_win32.c
rename to src/core/lib/support/log_windows.c
index 29735bd..ea898c3 100644
--- a/src/core/lib/support/log_win32.c
+++ b/src/core/lib/support/log_windows.c
@@ -33,19 +33,19 @@
 
 #include <grpc/support/port_platform.h>
 
-#ifdef GPR_WIN32_LOG
+#ifdef GPR_WINDOWS_LOG
 
 #include <stdarg.h>
 #include <stdio.h>
 
 #include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
-#include <grpc/support/log_win32.h>
+#include <grpc/support/log_windows.h>
 #include <grpc/support/string_util.h>
 #include <grpc/support/time.h>
 
 #include "src/core/lib/support/string.h"
-#include "src/core/lib/support/string_win32.h"
+#include "src/core/lib/support/string_windows.h"
 
 void gpr_log(const char *file, int line, gpr_log_severity severity,
              const char *format, ...) {
@@ -109,4 +109,4 @@
   fflush(stderr);
 }
 
-#endif /* GPR_WIN32_LOG */
+#endif /* GPR_WINDOWS_LOG */
diff --git a/src/core/lib/support/string_util_win32.c b/src/core/lib/support/string_util_windows.c
similarity index 98%
rename from src/core/lib/support/string_util_win32.c
rename to src/core/lib/support/string_util_windows.c
index 0d7bcdb..049c9a8 100644
--- a/src/core/lib/support/string_util_win32.c
+++ b/src/core/lib/support/string_util_windows.c
@@ -35,7 +35,7 @@
 
 #include <grpc/support/port_platform.h>
 
-#ifdef GPR_WIN32
+#ifdef GPR_WINDOWS
 
 /* Some platforms (namely msys) need wchar to be included BEFORE
    anything else, especially strsafe.h. */
@@ -91,4 +91,4 @@
   return message;
 }
 
-#endif /* GPR_WIN32 */
+#endif /* GPR_WINDOWS */
diff --git a/src/core/lib/support/string_win32.c b/src/core/lib/support/string_windows.c
similarity index 97%
rename from src/core/lib/support/string_win32.c
rename to src/core/lib/support/string_windows.c
index 6b92f79..ecc2a3a 100644
--- a/src/core/lib/support/string_win32.c
+++ b/src/core/lib/support/string_windows.c
@@ -35,7 +35,7 @@
 
 #include <grpc/support/port_platform.h>
 
-#ifdef GPR_WIN32_STRING
+#ifdef GPR_WINDOWS_STRING
 
 #include <stdarg.h>
 #include <stdio.h>
@@ -80,4 +80,4 @@
   return -1;
 }
 
-#endif /* GPR_WIN32_STRING */
+#endif /* GPR_WINDOWS_STRING */
diff --git a/src/core/lib/support/string_win32.h b/src/core/lib/support/string_windows.h
similarity index 89%
rename from src/core/lib/support/string_win32.h
rename to src/core/lib/support/string_windows.h
index ff4a694..899563b 100644
--- a/src/core/lib/support/string_win32.h
+++ b/src/core/lib/support/string_windows.h
@@ -31,17 +31,17 @@
  *
  */
 
-#ifndef GRPC_CORE_LIB_SUPPORT_STRING_WIN32_H
-#define GRPC_CORE_LIB_SUPPORT_STRING_WIN32_H
+#ifndef GRPC_CORE_LIB_SUPPORT_STRING_WINDOWS_H
+#define GRPC_CORE_LIB_SUPPORT_STRING_WINDOWS_H
 
 #include <grpc/support/port_platform.h>
 
-#ifdef GPR_WIN32
+#ifdef GPR_WINDOWS
 
 /* These allocate new strings using gpr_malloc to convert from and to utf-8. */
 LPTSTR gpr_char_to_tchar(LPCSTR input);
 LPSTR gpr_tchar_to_char(LPCTSTR input);
 
-#endif /* GPR_WIN32 */
+#endif /* GPR_WINDOWS */
 
-#endif /* GRPC_CORE_LIB_SUPPORT_STRING_WIN32_H */
+#endif /* GRPC_CORE_LIB_SUPPORT_STRING_WINDOWS_H */
diff --git a/src/core/lib/support/subprocess_windows.c b/src/core/lib/support/subprocess_windows.c
index 264306f..dee8c44 100644
--- a/src/core/lib/support/subprocess_windows.c
+++ b/src/core/lib/support/subprocess_windows.c
@@ -43,7 +43,7 @@
 #include <grpc/support/log.h>
 #include <grpc/support/subprocess.h>
 #include "src/core/lib/support/string.h"
-#include "src/core/lib/support/string_win32.h"
+#include "src/core/lib/support/string_windows.h"
 
 struct gpr_subprocess {
   PROCESS_INFORMATION pi;
diff --git a/src/core/lib/support/sync_win32.c b/src/core/lib/support/sync_windows.c
similarity index 98%
rename from src/core/lib/support/sync_win32.c
rename to src/core/lib/support/sync_windows.c
index 470a9f9..8f0e8ff 100644
--- a/src/core/lib/support/sync_win32.c
+++ b/src/core/lib/support/sync_windows.c
@@ -35,7 +35,7 @@
 
 #include <grpc/support/port_platform.h>
 
-#ifdef GPR_WIN32
+#ifdef GPR_WINDOWS
 
 #include <grpc/support/log.h>
 #include <grpc/support/sync.h>
@@ -130,4 +130,4 @@
   InitOnceExecuteOnce(once, run_once_func, &arg, &dummy);
 }
 
-#endif /* GPR_WIN32 */
+#endif /* GPR_WINDOWS */
diff --git a/src/core/lib/support/thd_win32.c b/src/core/lib/support/thd_windows.c
similarity index 98%
rename from src/core/lib/support/thd_win32.c
rename to src/core/lib/support/thd_windows.c
index 6deb314..74d2250 100644
--- a/src/core/lib/support/thd_win32.c
+++ b/src/core/lib/support/thd_windows.c
@@ -35,7 +35,7 @@
 
 #include <grpc/support/port_platform.h>
 
-#ifdef GPR_WIN32
+#ifdef GPR_WINDOWS
 
 #include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
@@ -114,4 +114,4 @@
   destroy_thread(info);
 }
 
-#endif /* GPR_WIN32 */
+#endif /* GPR_WINDOWS */
diff --git a/src/core/lib/support/time_win32.c b/src/core/lib/support/time_windows.c
similarity index 98%
rename from src/core/lib/support/time_win32.c
rename to src/core/lib/support/time_windows.c
index 9e924ab..6459732 100644
--- a/src/core/lib/support/time_win32.c
+++ b/src/core/lib/support/time_windows.c
@@ -35,7 +35,7 @@
 
 #include <grpc/support/port_platform.h>
 
-#ifdef GPR_WIN32_TIME
+#ifdef GPR_WINDOWS_TIME
 
 #include <grpc/support/log.h>
 #include <grpc/support/time.h>
@@ -107,4 +107,4 @@
   }
 }
 
-#endif /* GPR_WIN32_TIME */
+#endif /* GPR_WINDOWS_TIME */
diff --git a/src/core/lib/support/tmpfile_msys.c b/src/core/lib/support/tmpfile_msys.c
index 2fdc89a..4f566c4 100644
--- a/src/core/lib/support/tmpfile_msys.c
+++ b/src/core/lib/support/tmpfile_msys.c
@@ -44,7 +44,7 @@
 #include <grpc/support/log.h>
 #include <grpc/support/string_util.h>
 
-#include "src/core/lib/support/string_win32.h"
+#include "src/core/lib/support/string_windows.h"
 #include "src/core/lib/support/tmpfile.h"
 
 FILE *gpr_tmpfile(const char *prefix, char **tmp_filename_out) {
diff --git a/src/core/lib/support/tmpfile_win32.c b/src/core/lib/support/tmpfile_windows.c
similarity index 95%
rename from src/core/lib/support/tmpfile_win32.c
rename to src/core/lib/support/tmpfile_windows.c
index 9ac7312..542f53e 100644
--- a/src/core/lib/support/tmpfile_win32.c
+++ b/src/core/lib/support/tmpfile_windows.c
@@ -33,7 +33,7 @@
 
 #include <grpc/support/port_platform.h>
 
-#ifdef GPR_WIN32_TMPFILE
+#ifdef GPR_WINDOWS_TMPFILE
 
 #include <io.h>
 #include <stdio.h>
@@ -44,7 +44,7 @@
 #include <grpc/support/log.h>
 #include <grpc/support/string_util.h>
 
-#include "src/core/lib/support/string_win32.h"
+#include "src/core/lib/support/string_windows.h"
 #include "src/core/lib/support/tmpfile.h"
 
 FILE *gpr_tmpfile(const char *prefix, char **tmp_filename_out) {
@@ -81,4 +81,4 @@
   return result;
 }
 
-#endif /* GPR_WIN32_TMPFILE */
+#endif /* GPR_WINDOWS_TMPFILE */
diff --git a/src/core/lib/surface/call.c b/src/core/lib/surface/call.c
index c8728fa..a9b1e25 100644
--- a/src/core/lib/surface/call.c
+++ b/src/core/lib/surface/call.c
@@ -40,6 +40,7 @@
 #include <grpc/grpc.h>
 #include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
+#include <grpc/support/slice.h>
 #include <grpc/support/string_util.h>
 #include <grpc/support/useful.h>
 
@@ -52,7 +53,9 @@
 #include "src/core/lib/surface/call.h"
 #include "src/core/lib/surface/channel.h"
 #include "src/core/lib/surface/completion_queue.h"
+#include "src/core/lib/transport/metadata.h"
 #include "src/core/lib/transport/static_metadata.h"
+#include "src/core/lib/transport/transport.h"
 
 /** The maximum number of concurrent batches possible.
     Based upon the maximum number of individually queueable ops in the batch
@@ -65,12 +68,6 @@
       - status/close recv (depending on client/server) */
 #define MAX_CONCURRENT_BATCHES 6
 
-typedef struct {
-  grpc_ioreq_completion_func on_complete;
-  void *user_data;
-  int success;
-} completed_request;
-
 #define MAX_SEND_EXTRA_METADATA_COUNT 3
 
 /* Status data for a request can come from several sources; this
@@ -97,25 +94,6 @@
   grpc_mdstr *details;
 } received_status;
 
-/* How far through the GRPC stream have we read? */
-typedef enum {
-  /* We are still waiting for initial metadata to complete */
-  READ_STATE_INITIAL = 0,
-  /* We have gotten initial metadata, and are reading either
-     messages or trailing metadata */
-  READ_STATE_GOT_INITIAL_METADATA,
-  /* The stream is closed for reading */
-  READ_STATE_READ_CLOSED,
-  /* The stream is closed for reading & writing */
-  READ_STATE_STREAM_CLOSED
-} read_state;
-
-typedef enum {
-  WRITE_STATE_INITIAL = 0,
-  WRITE_STATE_STARTED,
-  WRITE_STATE_WRITE_CLOSED
-} write_state;
-
 typedef struct batch_control {
   grpc_call *call;
   grpc_cq_completion cq_completion;
@@ -135,6 +113,7 @@
 
 struct grpc_call {
   grpc_completion_queue *cq;
+  grpc_polling_entity pollent;
   grpc_channel *channel;
   grpc_call *parent;
   grpc_call *first_child;
@@ -176,10 +155,10 @@
   received_status status[STATUS_SOURCE_COUNT];
 
   /* Call stats: only valid after trailing metadata received */
-  grpc_transport_stream_stats stats;
+  grpc_call_stats stats;
 
-  /* Compression algorithm for the call */
-  grpc_compression_algorithm compression_algorithm;
+  /* Compression algorithm for *incoming* data */
+  grpc_compression_algorithm incoming_compression_algorithm;
   /* Supported encodings (compression algorithms), a bitset */
   uint32_t encodings_accepted_by_peer;
 
@@ -238,18 +217,19 @@
 static grpc_call_error cancel_with_status(grpc_exec_ctx *exec_ctx, grpc_call *c,
                                           grpc_status_code status,
                                           const char *description);
+static grpc_call_error close_with_status(grpc_exec_ctx *exec_ctx, grpc_call *c,
+                                         grpc_status_code status,
+                                         const char *description);
 static void destroy_call(grpc_exec_ctx *exec_ctx, void *call_stack,
                          bool success);
 static void receiving_slice_ready(grpc_exec_ctx *exec_ctx, void *bctlp,
                                   bool success);
 
-grpc_call *grpc_call_create(grpc_channel *channel, grpc_call *parent_call,
-                            uint32_t propagation_mask,
-                            grpc_completion_queue *cq,
-                            const void *server_transport_data,
-                            grpc_mdelem **add_initial_metadata,
-                            size_t add_initial_metadata_count,
-                            gpr_timespec send_deadline) {
+grpc_call *grpc_call_create(
+    grpc_channel *channel, grpc_call *parent_call, uint32_t propagation_mask,
+    grpc_completion_queue *cq, grpc_pollset_set *pollset_set_alternative,
+    const void *server_transport_data, grpc_mdelem **add_initial_metadata,
+    size_t add_initial_metadata_count, gpr_timespec send_deadline) {
   size_t i, j;
   grpc_channel_stack *channel_stack = grpc_channel_get_channel_stack(channel);
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
@@ -286,9 +266,20 @@
                        call->context, server_transport_data,
                        CALL_STACK_FROM_CALL(call));
   if (cq != NULL) {
+    GPR_ASSERT(
+        pollset_set_alternative == NULL &&
+        "Only one of 'cq' and 'pollset_set_alternative' should be non-NULL.");
     GRPC_CQ_INTERNAL_REF(cq, "bind");
-    grpc_call_stack_set_pollset(&exec_ctx, CALL_STACK_FROM_CALL(call),
-                                grpc_cq_pollset(cq));
+    call->pollent =
+        grpc_polling_entity_create_from_pollset(grpc_cq_pollset(cq));
+  }
+  if (pollset_set_alternative != NULL) {
+    call->pollent =
+        grpc_polling_entity_create_from_pollset_set(pollset_set_alternative);
+  }
+  if (!grpc_polling_entity_is_empty(&call->pollent)) {
+    grpc_call_stack_set_pollset_or_pollset_set(
+        &exec_ctx, CALL_STACK_FROM_CALL(call), &call->pollent);
   }
   if (parent_call != NULL) {
     GRPC_CALL_INTERNAL_REF(parent_call, "child");
@@ -343,10 +334,16 @@
 void grpc_call_set_completion_queue(grpc_exec_ctx *exec_ctx, grpc_call *call,
                                     grpc_completion_queue *cq) {
   GPR_ASSERT(cq);
+
+  if (grpc_polling_entity_pollset_set(&call->pollent) != NULL) {
+    gpr_log(GPR_ERROR, "A pollset_set is already registered for this call.");
+    abort();
+  }
   call->cq = cq;
   GRPC_CQ_INTERNAL_REF(cq, "bind");
-  grpc_call_stack_set_pollset(exec_ctx, CALL_STACK_FROM_CALL(call),
-                              grpc_cq_pollset(cq));
+  call->pollent = grpc_polling_entity_create_from_pollset(grpc_cq_pollset(cq));
+  grpc_call_stack_set_pollset_or_pollset_set(
+      exec_ctx, CALL_STACK_FROM_CALL(call), &call->pollent);
 }
 
 #ifdef GRPC_STREAM_REFCOUNT_DEBUG
@@ -393,7 +390,7 @@
     GRPC_CQ_INTERNAL_UNREF(c->cq, "bind");
   }
   grpc_channel *channel = c->channel;
-  grpc_call_stack_destroy(exec_ctx, CALL_STACK_FROM_CALL(c), c);
+  grpc_call_stack_destroy(exec_ctx, CALL_STACK_FROM_CALL(c), &c->stats, c);
   GRPC_CHANNEL_INTERNAL_UNREF(exec_ctx, channel, "call");
   GPR_TIMER_END("destroy_call", 0);
 }
@@ -408,21 +405,27 @@
   /* TODO(ctiller): what to do about the flush that was previously here */
 }
 
-static void set_compression_algorithm(grpc_call *call,
-                                      grpc_compression_algorithm algo) {
+static void set_incoming_compression_algorithm(
+    grpc_call *call, grpc_compression_algorithm algo) {
   GPR_ASSERT(algo < GRPC_COMPRESS_ALGORITHMS_COUNT);
-  call->compression_algorithm = algo;
+  call->incoming_compression_algorithm = algo;
 }
 
 grpc_compression_algorithm grpc_call_test_only_get_compression_algorithm(
     grpc_call *call) {
   grpc_compression_algorithm algorithm;
   gpr_mu_lock(&call->mu);
-  algorithm = call->compression_algorithm;
+  algorithm = call->incoming_compression_algorithm;
   gpr_mu_unlock(&call->mu);
   return algorithm;
 }
 
+static grpc_compression_algorithm compression_algorithm_for_level_locked(
+    grpc_call *call, grpc_compression_level level) {
+  return grpc_compression_algorithm_for_level(level,
+                                              call->encodings_accepted_by_peer);
+}
+
 uint32_t grpc_call_test_only_get_message_flags(grpc_call *call) {
   uint32_t flags;
   gpr_mu_lock(&call->mu);
@@ -548,15 +551,28 @@
   return (grpc_linked_mdelem *)&md->internal_data;
 }
 
+static grpc_metadata *get_md_elem(grpc_metadata *metadata,
+                                  grpc_metadata *additional_metadata, int i,
+                                  int count) {
+  grpc_metadata *res =
+      i < count ? &metadata[i] : &additional_metadata[i - count];
+  GPR_ASSERT(res);
+  return res;
+}
+
 static int prepare_application_metadata(grpc_call *call, int count,
                                         grpc_metadata *metadata,
                                         int is_trailing,
-                                        int prepend_extra_metadata) {
+                                        int prepend_extra_metadata,
+                                        grpc_metadata *additional_metadata,
+                                        int additional_metadata_count) {
+  int total_count = count + additional_metadata_count;
   int i;
   grpc_metadata_batch *batch =
       &call->metadata_batch[0 /* is_receiving */][is_trailing];
-  for (i = 0; i < count; i++) {
-    grpc_metadata *md = &metadata[i];
+  for (i = 0; i < total_count; i++) {
+    const grpc_metadata *md =
+        get_md_elem(metadata, additional_metadata, i, count);
     grpc_linked_mdelem *l = (grpc_linked_mdelem *)&md->internal_data;
     GPR_ASSERT(sizeof(grpc_linked_mdelem) == sizeof(md->internal_data));
     l->md = grpc_mdelem_from_string_and_buffer(
@@ -575,9 +591,10 @@
       break;
     }
   }
-  if (i != count) {
+  if (i != total_count) {
     for (int j = 0; j <= i; j++) {
-      grpc_metadata *md = &metadata[j];
+      const grpc_metadata *md =
+          get_md_elem(metadata, additional_metadata, j, count);
       grpc_linked_mdelem *l = (grpc_linked_mdelem *)&md->internal_data;
       GRPC_MDELEM_UNREF(l->md);
     }
@@ -598,24 +615,36 @@
       }
     }
   }
-  for (i = 1; i < count; i++) {
-    linked_from_md(&metadata[i])->prev = linked_from_md(&metadata[i - 1]);
+  for (i = 1; i < total_count; i++) {
+    grpc_metadata *md = get_md_elem(metadata, additional_metadata, i, count);
+    grpc_metadata *prev_md =
+        get_md_elem(metadata, additional_metadata, i - 1, count);
+    linked_from_md(md)->prev = linked_from_md(prev_md);
   }
-  for (i = 0; i < count - 1; i++) {
-    linked_from_md(&metadata[i])->next = linked_from_md(&metadata[i + 1]);
+  for (i = 0; i < total_count - 1; i++) {
+    grpc_metadata *md = get_md_elem(metadata, additional_metadata, i, count);
+    grpc_metadata *next_md =
+        get_md_elem(metadata, additional_metadata, i + 1, count);
+    linked_from_md(md)->next = linked_from_md(next_md);
   }
-  switch (prepend_extra_metadata * 2 + (count != 0)) {
+
+  switch (prepend_extra_metadata * 2 + (total_count != 0)) {
     case 0:
       /* no prepend, no metadata => nothing to do */
       batch->list.head = batch->list.tail = NULL;
       break;
-    case 1:
+    case 1: {
       /* metadata, but no prepend */
-      batch->list.head = linked_from_md(&metadata[0]);
-      batch->list.tail = linked_from_md(&metadata[count - 1]);
+      grpc_metadata *first_md =
+          get_md_elem(metadata, additional_metadata, 0, count);
+      grpc_metadata *last_md =
+          get_md_elem(metadata, additional_metadata, total_count - 1, count);
+      batch->list.head = linked_from_md(first_md);
+      batch->list.tail = linked_from_md(last_md);
       batch->list.head->prev = NULL;
       batch->list.tail->next = NULL;
       break;
+    }
     case 2:
       /* prepend, but no md */
       batch->list.head = &call->send_extra_metadata[0];
@@ -624,17 +653,22 @@
       batch->list.head->prev = NULL;
       batch->list.tail->next = NULL;
       break;
-    case 3:
+    case 3: {
       /* prepend AND md */
+      grpc_metadata *first_md =
+          get_md_elem(metadata, additional_metadata, 0, count);
+      grpc_metadata *last_md =
+          get_md_elem(metadata, additional_metadata, total_count - 1, count);
       batch->list.head = &call->send_extra_metadata[0];
       call->send_extra_metadata[call->send_extra_metadata_count - 1].next =
-          linked_from_md(&metadata[0]);
-      linked_from_md(&metadata[0])->prev =
+          linked_from_md(first_md);
+      linked_from_md(first_md)->prev =
           &call->send_extra_metadata[call->send_extra_metadata_count - 1];
-      batch->list.tail = linked_from_md(&metadata[count - 1]);
+      batch->list.tail = linked_from_md(last_md);
       batch->list.head->prev = NULL;
       batch->list.tail->next = NULL;
       break;
+    }
     default:
       GPR_UNREACHABLE_CODE(return 0);
   }
@@ -703,48 +737,102 @@
   return r;
 }
 
-typedef struct cancel_closure {
+typedef struct termination_closure {
   grpc_closure closure;
   grpc_call *call;
   grpc_status_code status;
-} cancel_closure;
+  gpr_slice optional_message;
+  grpc_closure *op_closure;
+  enum { TC_CANCEL, TC_CLOSE } type;
+} termination_closure;
 
-static void done_cancel(grpc_exec_ctx *exec_ctx, void *ccp, bool success) {
-  cancel_closure *cc = ccp;
-  GRPC_CALL_INTERNAL_UNREF(exec_ctx, cc->call, "cancel");
-  gpr_free(cc);
+static void done_termination(grpc_exec_ctx *exec_ctx, void *tcp, bool success) {
+  termination_closure *tc = tcp;
+  if (tc->type == TC_CANCEL) {
+    GRPC_CALL_INTERNAL_UNREF(exec_ctx, tc->call, "cancel");
+  }
+  if (tc->type == TC_CLOSE) {
+    GRPC_CALL_INTERNAL_UNREF(exec_ctx, tc->call, "close");
+  }
+  gpr_slice_unref(tc->optional_message);
+  if (tc->op_closure != NULL) {
+    grpc_exec_ctx_enqueue(exec_ctx, tc->op_closure, true, NULL);
+  }
+  gpr_free(tc);
 }
 
-static void send_cancel(grpc_exec_ctx *exec_ctx, void *ccp, bool success) {
+static void send_cancel(grpc_exec_ctx *exec_ctx, void *tcp, bool success) {
   grpc_transport_stream_op op;
-  cancel_closure *cc = ccp;
+  termination_closure *tc = tcp;
   memset(&op, 0, sizeof(op));
-  op.cancel_with_status = cc->status;
+  op.cancel_with_status = tc->status;
   /* reuse closure to catch completion */
-  grpc_closure_init(&cc->closure, done_cancel, cc);
-  op.on_complete = &cc->closure;
-  execute_op(exec_ctx, cc->call, &op);
+  grpc_closure_init(&tc->closure, done_termination, tc);
+  op.on_complete = &tc->closure;
+  execute_op(exec_ctx, tc->call, &op);
+}
+
+static void send_close(grpc_exec_ctx *exec_ctx, void *tcp, bool success) {
+  grpc_transport_stream_op op;
+  termination_closure *tc = tcp;
+  memset(&op, 0, sizeof(op));
+  tc->optional_message = gpr_slice_ref(tc->optional_message);
+  grpc_transport_stream_op_add_close(&op, tc->status, &tc->optional_message);
+  /* reuse closure to catch completion */
+  grpc_closure_init(&tc->closure, done_termination, tc);
+  tc->op_closure = op.on_complete;
+  op.on_complete = &tc->closure;
+  execute_op(exec_ctx, tc->call, &op);
+}
+
+static grpc_call_error terminate_with_status(grpc_exec_ctx *exec_ctx,
+                                             termination_closure *tc) {
+  grpc_mdstr *details = NULL;
+  if (GPR_SLICE_LENGTH(tc->optional_message) > 0) {
+    tc->optional_message = gpr_slice_ref(tc->optional_message);
+    details = grpc_mdstr_from_slice(tc->optional_message);
+  }
+
+  set_status_code(tc->call, STATUS_FROM_API_OVERRIDE, (uint32_t)tc->status);
+  set_status_details(tc->call, STATUS_FROM_API_OVERRIDE, details);
+
+  if (tc->type == TC_CANCEL) {
+    grpc_closure_init(&tc->closure, send_cancel, tc);
+    GRPC_CALL_INTERNAL_REF(tc->call, "cancel");
+  } else if (tc->type == TC_CLOSE) {
+    grpc_closure_init(&tc->closure, send_close, tc);
+    GRPC_CALL_INTERNAL_REF(tc->call, "close");
+  }
+  grpc_exec_ctx_enqueue(exec_ctx, &tc->closure, true, NULL);
+  return GRPC_CALL_OK;
 }
 
 static grpc_call_error cancel_with_status(grpc_exec_ctx *exec_ctx, grpc_call *c,
                                           grpc_status_code status,
                                           const char *description) {
-  grpc_mdstr *details =
-      description ? grpc_mdstr_from_string(description) : NULL;
-  cancel_closure *cc = gpr_malloc(sizeof(*cc));
-
+  termination_closure *tc = gpr_malloc(sizeof(*tc));
+  memset(tc, 0, sizeof(termination_closure));
+  tc->type = TC_CANCEL;
+  tc->call = c;
+  tc->optional_message = gpr_slice_from_copied_string(description);
   GPR_ASSERT(status != GRPC_STATUS_OK);
+  tc->status = status;
 
-  set_status_code(c, STATUS_FROM_API_OVERRIDE, (uint32_t)status);
-  set_status_details(c, STATUS_FROM_API_OVERRIDE, details);
+  return terminate_with_status(exec_ctx, tc);
+}
 
-  grpc_closure_init(&cc->closure, send_cancel, cc);
-  cc->call = c;
-  cc->status = status;
-  GRPC_CALL_INTERNAL_REF(c, "cancel");
-  grpc_exec_ctx_enqueue(exec_ctx, &cc->closure, true, NULL);
+static grpc_call_error close_with_status(grpc_exec_ctx *exec_ctx, grpc_call *c,
+                                         grpc_status_code status,
+                                         const char *description) {
+  termination_closure *tc = gpr_malloc(sizeof(*tc));
+  memset(tc, 0, sizeof(termination_closure));
+  tc->type = TC_CLOSE;
+  tc->call = c;
+  tc->optional_message = gpr_slice_from_copied_string(description);
+  GPR_ASSERT(status != GRPC_STATUS_OK);
+  tc->status = status;
 
-  return GRPC_CALL_OK;
+  return terminate_with_status(exec_ctx, tc);
 }
 
 static void execute_op(grpc_exec_ctx *exec_ctx, grpc_call *call,
@@ -885,9 +973,9 @@
   if (elem == NULL) {
     return NULL;
   } else if (elem->key == GRPC_MDSTR_GRPC_ENCODING) {
-    GPR_TIMER_BEGIN("compression_algorithm", 0);
-    set_compression_algorithm(call, decode_compression(elem));
-    GPR_TIMER_END("compression_algorithm", 0);
+    GPR_TIMER_BEGIN("incoming_compression_algorithm", 0);
+    set_incoming_compression_algorithm(call, decode_compression(elem));
+    GPR_TIMER_END("incoming_compression_algorithm", 0);
     return NULL;
   } else if (elem->key == GRPC_MDSTR_GRPC_ACCEPT_ENCODING) {
     GPR_TIMER_BEGIN("encodings_accepted_by_peer", 0);
@@ -1050,9 +1138,9 @@
   } else {
     call->test_only_last_message_flags = call->receiving_stream->flags;
     if ((call->receiving_stream->flags & GRPC_WRITE_INTERNAL_COMPRESS) &&
-        (call->compression_algorithm > GRPC_COMPRESS_NONE)) {
+        (call->incoming_compression_algorithm > GRPC_COMPRESS_NONE)) {
       *call->receiving_buffer = grpc_raw_compressed_byte_buffer_create(
-          NULL, 0, call->compression_algorithm);
+          NULL, 0, call->incoming_compression_algorithm);
     } else {
       *call->receiving_buffer = grpc_raw_byte_buffer_create(NULL, 0);
     }
@@ -1080,6 +1168,56 @@
   }
 }
 
+static void validate_filtered_metadata(grpc_exec_ctx *exec_ctx,
+                                       batch_control *bctl) {
+  grpc_call *call = bctl->call;
+  /* validate call->incoming_compression_algorithm */
+  if (call->incoming_compression_algorithm != GRPC_COMPRESS_NONE) {
+    const grpc_compression_algorithm algo =
+        call->incoming_compression_algorithm;
+    char *error_msg = NULL;
+    const grpc_compression_options compression_options =
+        grpc_channel_compression_options(call->channel);
+    /* check if algorithm is known */
+    if (algo >= GRPC_COMPRESS_ALGORITHMS_COUNT) {
+      gpr_asprintf(&error_msg, "Invalid compression algorithm value '%d'.",
+                   algo);
+      gpr_log(GPR_ERROR, error_msg);
+      close_with_status(exec_ctx, call, GRPC_STATUS_UNIMPLEMENTED, error_msg);
+    } else if (grpc_compression_options_is_algorithm_enabled(
+                   &compression_options, algo) == 0) {
+      /* check if algorithm is supported by current channel config */
+      char *algo_name;
+      grpc_compression_algorithm_name(algo, &algo_name);
+      gpr_asprintf(&error_msg, "Compression algorithm '%s' is disabled.",
+                   algo_name);
+      gpr_log(GPR_ERROR, error_msg);
+      close_with_status(exec_ctx, call, GRPC_STATUS_UNIMPLEMENTED, error_msg);
+    } else {
+      call->incoming_compression_algorithm = algo;
+    }
+    gpr_free(error_msg);
+  }
+
+  /* make sure the received grpc-encoding is amongst the ones listed in
+   * grpc-accept-encoding */
+  GPR_ASSERT(call->encodings_accepted_by_peer != 0);
+  if (!GPR_BITGET(call->encodings_accepted_by_peer,
+                  call->incoming_compression_algorithm)) {
+    extern int grpc_compression_trace;
+    if (grpc_compression_trace) {
+      char *algo_name;
+      grpc_compression_algorithm_name(call->incoming_compression_algorithm,
+                                      &algo_name);
+      gpr_log(GPR_ERROR,
+              "Compression algorithm (grpc-encoding = '%s') not present in "
+              "the bitset of accepted encodings (grpc-accept-encodings: "
+              "'0x%x')",
+              algo_name, call->encodings_accepted_by_peer);
+    }
+  }
+}
+
 static void receiving_initial_metadata_ready(grpc_exec_ctx *exec_ctx,
                                              void *bctlp, bool success) {
   batch_control *bctl = bctlp;
@@ -1094,24 +1232,10 @@
         &call->metadata_batch[1 /* is_receiving */][0 /* is_trailing */];
     grpc_metadata_batch_filter(md, recv_initial_filter, call);
 
-    /* make sure the received grpc-encoding is amongst the ones listed in
-     * grpc-accept-encoding */
+    GPR_TIMER_BEGIN("validate_filtered_metadata", 0);
+    validate_filtered_metadata(exec_ctx, bctl);
+    GPR_TIMER_END("validate_filtered_metadata", 0);
 
-    GPR_ASSERT(call->encodings_accepted_by_peer != 0);
-    if (!GPR_BITGET(call->encodings_accepted_by_peer,
-                    call->compression_algorithm)) {
-      extern int grpc_compression_trace;
-      if (grpc_compression_trace) {
-        char *algo_name;
-        grpc_compression_algorithm_name(call->compression_algorithm,
-                                        &algo_name);
-        gpr_log(GPR_ERROR,
-                "Compression algorithm (grpc-encoding = '%s') not present in "
-                "the bitset of accepted encodings (grpc-accept-encodings: "
-                "'0x%x')",
-                algo_name, call->encodings_accepted_by_peer);
-      }
-    }
     if (gpr_time_cmp(md->deadline, gpr_inf_future(md->deadline.clock_type)) !=
             0 &&
         !call->is_client) {
@@ -1254,7 +1378,40 @@
           error = GRPC_CALL_ERROR_TOO_MANY_OPERATIONS;
           goto done_with_error;
         }
-        if (op->data.send_initial_metadata.count > INT_MAX) {
+        /* process compression level */
+        grpc_metadata compression_md;
+        memset(&compression_md, 0, sizeof(grpc_metadata));
+        size_t additional_metadata_count = 0;
+        grpc_compression_level effective_compression_level;
+        bool level_set = false;
+        if (op->data.send_initial_metadata.maybe_compression_level.is_set) {
+          effective_compression_level =
+              op->data.send_initial_metadata.maybe_compression_level.level;
+          level_set = true;
+        } else {
+          const grpc_compression_options copts =
+              grpc_channel_compression_options(call->channel);
+          level_set = copts.default_level.is_set;
+          if (level_set) {
+            effective_compression_level = copts.default_level.level;
+          }
+        }
+        if (level_set && !call->is_client) {
+          const grpc_compression_algorithm calgo =
+              compression_algorithm_for_level_locked(
+                  call, effective_compression_level);
+          char *calgo_name;
+          grpc_compression_algorithm_name(calgo, &calgo_name);
+          // the following will be picked up by the compress filter and used as
+          // the call's compression algorithm.
+          compression_md.key = GRPC_COMPRESSION_REQUEST_ALGORITHM_MD_KEY;
+          compression_md.value = calgo_name;
+          compression_md.value_length = strlen(calgo_name);
+          additional_metadata_count++;
+        }
+
+        if (op->data.send_initial_metadata.count + additional_metadata_count >
+            INT_MAX) {
           error = GRPC_CALL_ERROR_INVALID_METADATA;
           goto done_with_error;
         }
@@ -1262,7 +1419,8 @@
         call->sent_initial_metadata = 1;
         if (!prepare_application_metadata(
                 call, (int)op->data.send_initial_metadata.count,
-                op->data.send_initial_metadata.metadata, 0, call->is_client)) {
+                op->data.send_initial_metadata.metadata, 0, call->is_client,
+                &compression_md, (int)additional_metadata_count)) {
           error = GRPC_CALL_ERROR_INVALID_METADATA;
           goto done_with_error;
         }
@@ -1350,7 +1508,8 @@
         if (!prepare_application_metadata(
                 call,
                 (int)op->data.send_status_from_server.trailing_metadata_count,
-                op->data.send_status_from_server.trailing_metadata, 1, 1)) {
+                op->data.send_status_from_server.trailing_metadata, 1, 1, NULL,
+                0)) {
           error = GRPC_CALL_ERROR_INVALID_METADATA;
           goto done_with_error;
         }
@@ -1422,7 +1581,7 @@
         bctl->recv_final_op = 1;
         stream_op.recv_trailing_metadata =
             &call->metadata_batch[1 /* is_receiving */][1 /* is_trailing */];
-        stream_op.collect_stats = &call->stats;
+        stream_op.collect_stats = &call->stats.transport_stream_stats;
         break;
       case GRPC_OP_RECV_CLOSE_ON_SERVER:
         /* Flag validation: currently allow no flags */
@@ -1444,7 +1603,7 @@
         bctl->recv_final_op = 1;
         stream_op.recv_trailing_metadata =
             &call->metadata_batch[1 /* is_receiving */][1 /* is_trailing */];
-        stream_op.collect_stats = &call->stats;
+        stream_op.collect_stats = &call->stats.transport_stream_stats;
         break;
     }
   }
@@ -1539,9 +1698,10 @@
 grpc_compression_algorithm grpc_call_compression_for_level(
     grpc_call *call, grpc_compression_level level) {
   gpr_mu_lock(&call->mu);
-  const uint32_t accepted_encodings = call->encodings_accepted_by_peer;
+  grpc_compression_algorithm algo =
+      compression_algorithm_for_level_locked(call, level);
   gpr_mu_unlock(&call->mu);
-  return grpc_compression_algorithm_for_level(level, accepted_encodings);
+  return algo;
 }
 
 const char *grpc_call_error_to_string(grpc_call_error error) {
diff --git a/src/core/lib/surface/call.h b/src/core/lib/surface/call.h
index 2725e06..b640345 100644
--- a/src/core/lib/surface/call.h
+++ b/src/core/lib/surface/call.h
@@ -53,6 +53,8 @@
 grpc_call *grpc_call_create(grpc_channel *channel, grpc_call *parent_call,
                             uint32_t propagation_mask,
                             grpc_completion_queue *cq,
+                            /* if not NULL, it'll be used in lieu of \a cq */
+                            grpc_pollset_set *pollset_set_alternative,
                             const void *server_transport_data,
                             grpc_mdelem **add_initial_metadata,
                             size_t add_initial_metadata_count,
diff --git a/src/core/lib/surface/channel.c b/src/core/lib/surface/channel.c
index b6b760b..f0b3c2e 100644
--- a/src/core/lib/surface/channel.c
+++ b/src/core/lib/surface/channel.c
@@ -36,16 +36,17 @@
 #include <stdlib.h>
 #include <string.h>
 
+#include <grpc/compression.h>
 #include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
 #include <grpc/support/string_util.h>
 
+#include "src/core/lib/channel/channel_args.h"
 #include "src/core/lib/iomgr/iomgr.h"
 #include "src/core/lib/support/string.h"
 #include "src/core/lib/surface/api_trace.h"
 #include "src/core/lib/surface/call.h"
 #include "src/core/lib/surface/channel_init.h"
-#include "src/core/lib/surface/init.h"
 #include "src/core/lib/transport/static_metadata.h"
 
 /** Cache grpc-status: X mdelems for X = 0..NUM_CACHED_STATUS_ELEMS.
@@ -64,10 +65,12 @@
 struct grpc_channel {
   int is_client;
   uint32_t max_message_length;
+  grpc_compression_options compression_options;
   grpc_mdelem *default_authority;
 
   gpr_mu registered_call_mu;
   registered_call *registered_calls;
+
   char *target;
 };
 
@@ -111,6 +114,7 @@
   channel->registered_calls = NULL;
 
   channel->max_message_length = DEFAULT_MAX_MESSAGE_LENGTH;
+  grpc_compression_options_init(&channel->compression_options);
   if (args) {
     for (size_t i = 0; i < args->num_args; i++) {
       if (0 == strcmp(args->args[i].key, GRPC_ARG_MAX_MESSAGE_LENGTH)) {
@@ -151,6 +155,27 @@
                 ":authority", args->args[i].value.string);
           }
         }
+      } else if (0 == strcmp(args->args[i].key,
+                             GRPC_COMPRESSION_CHANNEL_DEFAULT_LEVEL)) {
+        channel->compression_options.default_level.is_set = true;
+        GPR_ASSERT(args->args[i].value.integer >= 0 &&
+                   args->args[i].value.integer < GRPC_COMPRESS_LEVEL_COUNT);
+        channel->compression_options.default_level.level =
+            (grpc_compression_level)args->args[i].value.integer;
+      } else if (0 == strcmp(args->args[i].key,
+                             GRPC_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM)) {
+        channel->compression_options.default_algorithm.is_set = true;
+        GPR_ASSERT(args->args[i].value.integer >= 0 &&
+                   args->args[i].value.integer <
+                       GRPC_COMPRESS_ALGORITHMS_COUNT);
+        channel->compression_options.default_algorithm.algorithm =
+            (grpc_compression_algorithm)args->args[i].value.integer;
+      } else if (0 ==
+                 strcmp(args->args[i].key,
+                        GRPC_COMPRESSION_CHANNEL_ENABLED_ALGORITHMS_BITSET)) {
+        channel->compression_options.enabled_algorithms_bitset =
+            (uint32_t)args->args[i].value.integer |
+            0x1; /* always support no compression */
       }
     }
     grpc_channel_args_destroy(args);
@@ -166,12 +191,14 @@
 
 static grpc_call *grpc_channel_create_call_internal(
     grpc_channel *channel, grpc_call *parent_call, uint32_t propagation_mask,
-    grpc_completion_queue *cq, grpc_mdelem *path_mdelem,
-    grpc_mdelem *authority_mdelem, gpr_timespec deadline) {
+    grpc_completion_queue *cq, grpc_pollset_set *pollset_set_alternative,
+    grpc_mdelem *path_mdelem, grpc_mdelem *authority_mdelem,
+    gpr_timespec deadline) {
   grpc_mdelem *send_metadata[2];
   size_t num_metadata = 0;
 
   GPR_ASSERT(channel->is_client);
+  GPR_ASSERT(!(cq != NULL && pollset_set_alternative != NULL));
 
   send_metadata[num_metadata++] = path_mdelem;
   if (authority_mdelem != NULL) {
@@ -180,8 +207,9 @@
     send_metadata[num_metadata++] = GRPC_MDELEM_REF(channel->default_authority);
   }
 
-  return grpc_call_create(channel, parent_call, propagation_mask, cq, NULL,
-                          send_metadata, num_metadata, deadline);
+  return grpc_call_create(channel, parent_call, propagation_mask, cq,
+                          pollset_set_alternative, NULL, send_metadata,
+                          num_metadata, deadline);
 }
 
 grpc_call *grpc_channel_create_call(grpc_channel *channel,
@@ -201,7 +229,22 @@
            (int)deadline.clock_type, reserved));
   GPR_ASSERT(!reserved);
   return grpc_channel_create_call_internal(
-      channel, parent_call, propagation_mask, cq,
+      channel, parent_call, propagation_mask, cq, NULL,
+      grpc_mdelem_from_metadata_strings(GRPC_MDSTR_PATH,
+                                        grpc_mdstr_from_string(method)),
+      host ? grpc_mdelem_from_metadata_strings(GRPC_MDSTR_AUTHORITY,
+                                               grpc_mdstr_from_string(host))
+           : NULL,
+      deadline);
+}
+
+grpc_call *grpc_channel_create_pollset_set_call(
+    grpc_channel *channel, grpc_call *parent_call, uint32_t propagation_mask,
+    grpc_pollset_set *pollset_set, const char *method, const char *host,
+    gpr_timespec deadline, void *reserved) {
+  GPR_ASSERT(!reserved);
+  return grpc_channel_create_call_internal(
+      channel, parent_call, propagation_mask, NULL, pollset_set,
       grpc_mdelem_from_metadata_strings(GRPC_MDSTR_PATH,
                                         grpc_mdstr_from_string(method)),
       host ? grpc_mdelem_from_metadata_strings(GRPC_MDSTR_AUTHORITY,
@@ -245,7 +288,7 @@
           (int)deadline.tv_nsec, (int)deadline.clock_type, reserved));
   GPR_ASSERT(!reserved);
   return grpc_channel_create_call_internal(
-      channel, parent_call, propagation_mask, completion_queue,
+      channel, parent_call, propagation_mask, completion_queue, NULL,
       GRPC_MDELEM_REF(rc->path),
       rc->authority ? GRPC_MDELEM_REF(rc->authority) : NULL, deadline);
 }
@@ -306,6 +349,11 @@
   return CHANNEL_STACK_FROM_CHANNEL(channel);
 }
 
+grpc_compression_options grpc_channel_compression_options(
+    const grpc_channel *channel) {
+  return channel->compression_options;
+}
+
 grpc_mdelem *grpc_channel_get_reffed_status_elem(grpc_channel *channel, int i) {
   char tmp[GPR_LTOA_MIN_BUFSIZE];
   switch (i) {
diff --git a/src/core/lib/surface/channel.h b/src/core/lib/surface/channel.h
index 22dae93..7eff7b8 100644
--- a/src/core/lib/surface/channel.h
+++ b/src/core/lib/surface/channel.h
@@ -42,6 +42,11 @@
                                   grpc_channel_stack_type channel_stack_type,
                                   grpc_transport *optional_transport);
 
+grpc_call *grpc_channel_create_pollset_set_call(
+    grpc_channel *channel, grpc_call *parent_call, uint32_t propagation_mask,
+    grpc_pollset_set *pollset_set, const char *method, const char *host,
+    gpr_timespec deadline, void *reserved);
+
 /** Get a (borrowed) pointer to this channels underlying channel stack */
 grpc_channel_stack *grpc_channel_get_channel_stack(grpc_channel *channel);
 
@@ -71,4 +76,8 @@
   grpc_channel_internal_unref(exec_ctx, channel)
 #endif
 
+/** Return the channel's compression options. */
+grpc_compression_options grpc_channel_compression_options(
+    const grpc_channel *channel);
+
 #endif /* GRPC_CORE_LIB_SURFACE_CHANNEL_H */
diff --git a/src/core/lib/surface/lame_client.c b/src/core/lib/surface/lame_client.c
index f50ec54..8223555 100644
--- a/src/core/lib/surface/lame_client.c
+++ b/src/core/lib/surface/lame_client.c
@@ -91,8 +91,8 @@
                                     grpc_channel_element *elem,
                                     grpc_transport_op *op) {
   if (op->on_connectivity_state_change) {
-    GPR_ASSERT(*op->connectivity_state != GRPC_CHANNEL_FATAL_FAILURE);
-    *op->connectivity_state = GRPC_CHANNEL_FATAL_FAILURE;
+    GPR_ASSERT(*op->connectivity_state != GRPC_CHANNEL_SHUTDOWN);
+    *op->connectivity_state = GRPC_CHANNEL_SHUTDOWN;
     op->on_connectivity_state_change->cb(
         exec_ctx, op->on_connectivity_state_change->cb_arg, 1);
   }
@@ -108,6 +108,7 @@
                            grpc_call_element_args *args) {}
 
 static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
+                              const grpc_call_stats *stats,
                               void *and_free_memory) {
   gpr_free(and_free_memory);
 }
@@ -127,7 +128,7 @@
     lame_start_transport_op,
     sizeof(call_data),
     init_call_elem,
-    grpc_call_stack_ignore_set_pollset,
+    grpc_call_stack_ignore_set_pollset_or_pollset_set,
     destroy_call_elem,
     sizeof(channel_data),
     init_channel_elem,
diff --git a/src/core/lib/surface/server.c b/src/core/lib/surface/server.c
index 505b501..88d898b 100644
--- a/src/core/lib/surface/server.c
+++ b/src/core/lib/surface/server.c
@@ -793,9 +793,9 @@
                           const void *transport_server_data) {
   channel_data *chand = cd;
   /* create a call */
-  grpc_call *call =
-      grpc_call_create(chand->channel, NULL, 0, NULL, transport_server_data,
-                       NULL, 0, gpr_inf_future(GPR_CLOCK_MONOTONIC));
+  grpc_call *call = grpc_call_create(chand->channel, NULL, 0, NULL, NULL,
+                                     transport_server_data, NULL, 0,
+                                     gpr_inf_future(GPR_CLOCK_MONOTONIC));
   grpc_call_element *elem =
       grpc_call_stack_element(grpc_call_get_call_stack(call), 0);
   call_data *calld = elem->call_data;
@@ -812,7 +812,7 @@
                                          bool iomgr_status_ignored) {
   channel_data *chand = cd;
   grpc_server *server = chand->server;
-  if (chand->connectivity_state != GRPC_CHANNEL_FATAL_FAILURE) {
+  if (chand->connectivity_state != GRPC_CHANNEL_SHUTDOWN) {
     grpc_transport_op op;
     memset(&op, 0, sizeof(op));
     op.on_connectivity_state_change = &chand->channel_connectivity_changed,
@@ -845,7 +845,7 @@
 }
 
 static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
-                              void *ignored) {
+                              const grpc_call_stats *stats, void *ignored) {
   channel_data *chand = elem->channel_data;
   call_data *calld = elem->call_data;
 
@@ -910,7 +910,7 @@
     grpc_channel_next_op,
     sizeof(call_data),
     init_call_elem,
-    grpc_call_stack_ignore_set_pollset,
+    grpc_call_stack_ignore_set_pollset_or_pollset_set,
     destroy_call_elem,
     sizeof(channel_data),
     init_channel_elem,
diff --git a/src/core/lib/transport/connectivity_state.c b/src/core/lib/transport/connectivity_state.c
index e24ee63..74a5ef5 100644
--- a/src/core/lib/transport/connectivity_state.c
+++ b/src/core/lib/transport/connectivity_state.c
@@ -51,7 +51,7 @@
       return "READY";
     case GRPC_CHANNEL_TRANSIENT_FAILURE:
       return "TRANSIENT_FAILURE";
-    case GRPC_CHANNEL_FATAL_FAILURE:
+    case GRPC_CHANNEL_SHUTDOWN:
       return "FATAL_FAILURE";
   }
   GPR_UNREACHABLE_CODE(return "UNKNOWN");
@@ -72,8 +72,8 @@
   while ((w = tracker->watchers)) {
     tracker->watchers = w->next;
 
-    if (GRPC_CHANNEL_FATAL_FAILURE != *w->current) {
-      *w->current = GRPC_CHANNEL_FATAL_FAILURE;
+    if (GRPC_CHANNEL_SHUTDOWN != *w->current) {
+      *w->current = GRPC_CHANNEL_SHUTDOWN;
       success = 1;
     } else {
       success = 0;
@@ -153,7 +153,7 @@
   if (tracker->current_state == state) {
     return;
   }
-  GPR_ASSERT(tracker->current_state != GRPC_CHANNEL_FATAL_FAILURE);
+  GPR_ASSERT(tracker->current_state != GRPC_CHANNEL_SHUTDOWN);
   tracker->current_state = state;
   while ((w = tracker->watchers) != NULL) {
     *w->current = tracker->current_state;
diff --git a/src/core/lib/transport/metadata.c b/src/core/lib/transport/metadata.c
index 82c8e23..79de54b 100644
--- a/src/core/lib/transport/metadata.c
+++ b/src/core/lib/transport/metadata.c
@@ -129,7 +129,10 @@
   internal_metadata **elems;
   size_t count;
   size_t capacity;
-  size_t free;
+  /** Estimate of the number of unreferenced mdelems in the hash table.
+      This will eventually converge to the exact number, but it's instantaneous
+      accuracy is not guaranteed */
+  gpr_atm free_estimate;
 } mdtab_shard;
 
 #define LOG2_STRTAB_SHARD_COUNT 5
@@ -217,7 +220,7 @@
     mdtab_shard *shard = &g_mdtab_shard[i];
     gpr_mu_init(&shard->mu);
     shard->count = 0;
-    shard->free = 0;
+    gpr_atm_no_barrier_store(&shard->free_estimate, 0);
     shard->capacity = INITIAL_MDTAB_CAPACITY;
     shard->elems = gpr_malloc(sizeof(*shard->elems) * shard->capacity);
     memset(shard->elems, 0, sizeof(*shard->elems) * shard->capacity);
@@ -281,10 +284,8 @@
           grpc_mdstr_as_c_string((grpc_mdstr *)md->key),
           grpc_mdstr_as_c_string((grpc_mdstr *)md->value));
 #endif
-  if (0 == gpr_atm_no_barrier_fetch_add(&md->refcnt, 2)) {
-    shard->free--;
-  } else {
-    GPR_ASSERT(1 != gpr_atm_no_barrier_fetch_add(&md->refcnt, -1));
+  if (0 == gpr_atm_no_barrier_fetch_add(&md->refcnt, 1)) {
+    gpr_atm_no_barrier_fetch_add(&shard->free_estimate, -1);
   }
 }
 
@@ -447,6 +448,7 @@
   size_t i;
   internal_metadata **prev_next;
   internal_metadata *md, *next;
+  gpr_atm num_freed = 0;
 
   GPR_TIMER_BEGIN("gc_mdtab", 0);
   for (i = 0; i < shard->capacity; i++) {
@@ -463,13 +465,14 @@
         }
         gpr_free(md);
         *prev_next = next;
-        shard->free--;
+        num_freed++;
         shard->count--;
       } else {
         prev_next = &md->bucket_next;
       }
     }
   }
+  gpr_atm_no_barrier_fetch_add(&shard->free_estimate, -num_freed);
   GPR_TIMER_END("gc_mdtab", 0);
 }
 
@@ -504,7 +507,8 @@
 }
 
 static void rehash_mdtab(mdtab_shard *shard) {
-  if (shard->free > shard->capacity / 4) {
+  if (gpr_atm_no_barrier_load(&shard->free_estimate) >
+      (gpr_atm)(shard->capacity / 4)) {
     gc_mdtab(shard);
   } else {
     grow_mdtab(shard);
@@ -553,7 +557,7 @@
 
   /* not found: create a new pair */
   md = gpr_malloc(sizeof(internal_metadata));
-  gpr_atm_rel_store(&md->refcnt, 2);
+  gpr_atm_rel_store(&md->refcnt, 1);
   md->key = key;
   md->value = value;
   md->user_data = 0;
@@ -645,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) >= 2);
+  assert(gpr_atm_no_barrier_load(&md->refcnt) >= 1);
   gpr_atm_no_barrier_fetch_add(&md->refcnt, 1);
   return gmd;
 }
@@ -662,18 +666,13 @@
           grpc_mdstr_as_c_string((grpc_mdstr *)md->key),
           grpc_mdstr_as_c_string((grpc_mdstr *)md->value));
 #endif
-  if (2 == gpr_atm_full_fetch_add(&md->refcnt, -1)) {
-    uint32_t hash = GRPC_MDSTR_KV_HASH(md->key->hash, md->value->hash);
+  uint32_t hash = GRPC_MDSTR_KV_HASH(md->key->hash, md->value->hash);
+  if (1 == gpr_atm_full_fetch_add(&md->refcnt, -1)) {
+    /* 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 =
         &g_mdtab_shard[SHARD_IDX(hash, LOG2_MDTAB_SHARD_COUNT)];
-    GPR_TIMER_BEGIN("grpc_mdelem_unref.to_zero", 0);
-    gpr_mu_lock(&shard->mu);
-    if (1 == gpr_atm_no_barrier_load(&md->refcnt)) {
-      shard->free++;
-      gpr_atm_no_barrier_store(&md->refcnt, 0);
-    }
-    gpr_mu_unlock(&shard->mu);
-    GPR_TIMER_END("grpc_mdelem_unref.to_zero", 0);
+    gpr_atm_no_barrier_fetch_add(&shard->free_estimate, 1);
   }
 }
 
diff --git a/src/core/lib/transport/static_metadata.c b/src/core/lib/transport/static_metadata.c
index 73b0041..c5f16e5 100644
--- a/src/core/lib/transport/static_metadata.c
+++ b/src/core/lib/transport/static_metadata.c
@@ -48,7 +48,7 @@
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
     0, 0, 0, 0, 0, 0, 4, 8, 6, 2, 4, 8, 6, 0, 0, 0, 0, 0, 0, 0,
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
 
 const uint8_t grpc_static_metadata_elem_indices[GRPC_STATIC_MDELEM_COUNT * 2] =
     {11, 35, 10, 35, 12, 35, 12, 49, 13, 35, 14, 35, 15, 35, 16, 35, 17, 35,
@@ -56,10 +56,10 @@
      30, 18, 30, 35, 31, 35, 32, 35, 36, 35, 37, 35, 38, 35, 39, 35, 42, 33,
      42, 34, 42, 48, 42, 53, 42, 54, 42, 55, 42, 56, 43, 33, 43, 48, 43, 53,
      46, 0,  46, 1,  46, 2,  50, 35, 57, 35, 58, 35, 59, 35, 60, 35, 61, 35,
-     62, 35, 63, 35, 64, 35, 65, 35, 66, 40, 66, 68, 66, 71, 67, 79, 67, 80,
-     69, 35, 70, 35, 72, 35, 73, 35, 74, 35, 75, 35, 76, 41, 76, 51, 76, 52,
-     77, 35, 78, 35, 81, 3,  81, 4,  81, 5,  81, 6,  81, 7,  81, 8,  81, 9,
-     82, 35, 83, 84, 85, 35, 86, 35, 87, 35, 88, 35, 89, 35};
+     62, 35, 63, 35, 64, 35, 65, 35, 66, 35, 67, 40, 67, 69, 67, 72, 68, 80,
+     68, 81, 70, 35, 71, 35, 73, 35, 74, 35, 75, 35, 76, 35, 77, 41, 77, 51,
+     77, 52, 78, 35, 79, 35, 82, 3,  82, 4,  82, 5,  82, 6,  82, 7,  82, 8,
+     82, 9,  83, 35, 84, 85, 86, 35, 87, 35, 88, 35, 89, 35, 90, 35};
 
 const char *const grpc_static_metadata_strings[GRPC_STATIC_MDSTR_COUNT] = {
     "0",
@@ -126,6 +126,7 @@
     "if-unmodified-since",
     "last-modified",
     "link",
+    "load-reporting",
     "location",
     "max-forwards",
     ":method",
diff --git a/src/core/lib/transport/static_metadata.h b/src/core/lib/transport/static_metadata.h
index f9d8bcd..5ff0d2f 100644
--- a/src/core/lib/transport/static_metadata.h
+++ b/src/core/lib/transport/static_metadata.h
@@ -44,7 +44,7 @@
 
 #include "src/core/lib/transport/metadata.h"
 
-#define GRPC_STATIC_MDSTR_COUNT 90
+#define GRPC_STATIC_MDSTR_COUNT 91
 extern grpc_mdstr grpc_static_mdstr_table[GRPC_STATIC_MDSTR_COUNT];
 /* "0" */
 #define GRPC_MDSTR_0 (&grpc_static_mdstr_table[0])
@@ -175,60 +175,62 @@
 #define GRPC_MDSTR_LAST_MODIFIED (&grpc_static_mdstr_table[62])
 /* "link" */
 #define GRPC_MDSTR_LINK (&grpc_static_mdstr_table[63])
+/* "load-reporting" */
+#define GRPC_MDSTR_LOAD_REPORTING (&grpc_static_mdstr_table[64])
 /* "location" */
-#define GRPC_MDSTR_LOCATION (&grpc_static_mdstr_table[64])
+#define GRPC_MDSTR_LOCATION (&grpc_static_mdstr_table[65])
 /* "max-forwards" */
-#define GRPC_MDSTR_MAX_FORWARDS (&grpc_static_mdstr_table[65])
+#define GRPC_MDSTR_MAX_FORWARDS (&grpc_static_mdstr_table[66])
 /* ":method" */
-#define GRPC_MDSTR_METHOD (&grpc_static_mdstr_table[66])
+#define GRPC_MDSTR_METHOD (&grpc_static_mdstr_table[67])
 /* ":path" */
-#define GRPC_MDSTR_PATH (&grpc_static_mdstr_table[67])
+#define GRPC_MDSTR_PATH (&grpc_static_mdstr_table[68])
 /* "POST" */
-#define GRPC_MDSTR_POST (&grpc_static_mdstr_table[68])
+#define GRPC_MDSTR_POST (&grpc_static_mdstr_table[69])
 /* "proxy-authenticate" */
-#define GRPC_MDSTR_PROXY_AUTHENTICATE (&grpc_static_mdstr_table[69])
+#define GRPC_MDSTR_PROXY_AUTHENTICATE (&grpc_static_mdstr_table[70])
 /* "proxy-authorization" */
-#define GRPC_MDSTR_PROXY_AUTHORIZATION (&grpc_static_mdstr_table[70])
+#define GRPC_MDSTR_PROXY_AUTHORIZATION (&grpc_static_mdstr_table[71])
 /* "PUT" */
-#define GRPC_MDSTR_PUT (&grpc_static_mdstr_table[71])
+#define GRPC_MDSTR_PUT (&grpc_static_mdstr_table[72])
 /* "range" */
-#define GRPC_MDSTR_RANGE (&grpc_static_mdstr_table[72])
+#define GRPC_MDSTR_RANGE (&grpc_static_mdstr_table[73])
 /* "referer" */
-#define GRPC_MDSTR_REFERER (&grpc_static_mdstr_table[73])
+#define GRPC_MDSTR_REFERER (&grpc_static_mdstr_table[74])
 /* "refresh" */
-#define GRPC_MDSTR_REFRESH (&grpc_static_mdstr_table[74])
+#define GRPC_MDSTR_REFRESH (&grpc_static_mdstr_table[75])
 /* "retry-after" */
-#define GRPC_MDSTR_RETRY_AFTER (&grpc_static_mdstr_table[75])
+#define GRPC_MDSTR_RETRY_AFTER (&grpc_static_mdstr_table[76])
 /* ":scheme" */
-#define GRPC_MDSTR_SCHEME (&grpc_static_mdstr_table[76])
+#define GRPC_MDSTR_SCHEME (&grpc_static_mdstr_table[77])
 /* "server" */
-#define GRPC_MDSTR_SERVER (&grpc_static_mdstr_table[77])
+#define GRPC_MDSTR_SERVER (&grpc_static_mdstr_table[78])
 /* "set-cookie" */
-#define GRPC_MDSTR_SET_COOKIE (&grpc_static_mdstr_table[78])
+#define GRPC_MDSTR_SET_COOKIE (&grpc_static_mdstr_table[79])
 /* "/" */
-#define GRPC_MDSTR_SLASH (&grpc_static_mdstr_table[79])
+#define GRPC_MDSTR_SLASH (&grpc_static_mdstr_table[80])
 /* "/index.html" */
-#define GRPC_MDSTR_SLASH_INDEX_DOT_HTML (&grpc_static_mdstr_table[80])
+#define GRPC_MDSTR_SLASH_INDEX_DOT_HTML (&grpc_static_mdstr_table[81])
 /* ":status" */
-#define GRPC_MDSTR_STATUS (&grpc_static_mdstr_table[81])
+#define GRPC_MDSTR_STATUS (&grpc_static_mdstr_table[82])
 /* "strict-transport-security" */
-#define GRPC_MDSTR_STRICT_TRANSPORT_SECURITY (&grpc_static_mdstr_table[82])
+#define GRPC_MDSTR_STRICT_TRANSPORT_SECURITY (&grpc_static_mdstr_table[83])
 /* "te" */
-#define GRPC_MDSTR_TE (&grpc_static_mdstr_table[83])
+#define GRPC_MDSTR_TE (&grpc_static_mdstr_table[84])
 /* "trailers" */
-#define GRPC_MDSTR_TRAILERS (&grpc_static_mdstr_table[84])
+#define GRPC_MDSTR_TRAILERS (&grpc_static_mdstr_table[85])
 /* "transfer-encoding" */
-#define GRPC_MDSTR_TRANSFER_ENCODING (&grpc_static_mdstr_table[85])
+#define GRPC_MDSTR_TRANSFER_ENCODING (&grpc_static_mdstr_table[86])
 /* "user-agent" */
-#define GRPC_MDSTR_USER_AGENT (&grpc_static_mdstr_table[86])
+#define GRPC_MDSTR_USER_AGENT (&grpc_static_mdstr_table[87])
 /* "vary" */
-#define GRPC_MDSTR_VARY (&grpc_static_mdstr_table[87])
+#define GRPC_MDSTR_VARY (&grpc_static_mdstr_table[88])
 /* "via" */
-#define GRPC_MDSTR_VIA (&grpc_static_mdstr_table[88])
+#define GRPC_MDSTR_VIA (&grpc_static_mdstr_table[89])
 /* "www-authenticate" */
-#define GRPC_MDSTR_WWW_AUTHENTICATE (&grpc_static_mdstr_table[89])
+#define GRPC_MDSTR_WWW_AUTHENTICATE (&grpc_static_mdstr_table[90])
 
-#define GRPC_STATIC_MDELEM_COUNT 79
+#define GRPC_STATIC_MDELEM_COUNT 80
 extern grpc_mdelem grpc_static_mdelem_table[GRPC_STATIC_MDELEM_COUNT];
 extern uintptr_t grpc_static_mdelem_user_data[GRPC_STATIC_MDELEM_COUNT];
 /* "accept-charset": "" */
@@ -333,71 +335,73 @@
 #define GRPC_MDELEM_LAST_MODIFIED_EMPTY (&grpc_static_mdelem_table[45])
 /* "link": "" */
 #define GRPC_MDELEM_LINK_EMPTY (&grpc_static_mdelem_table[46])
+/* "load-reporting": "" */
+#define GRPC_MDELEM_LOAD_REPORTING_EMPTY (&grpc_static_mdelem_table[47])
 /* "location": "" */
-#define GRPC_MDELEM_LOCATION_EMPTY (&grpc_static_mdelem_table[47])
+#define GRPC_MDELEM_LOCATION_EMPTY (&grpc_static_mdelem_table[48])
 /* "max-forwards": "" */
-#define GRPC_MDELEM_MAX_FORWARDS_EMPTY (&grpc_static_mdelem_table[48])
+#define GRPC_MDELEM_MAX_FORWARDS_EMPTY (&grpc_static_mdelem_table[49])
 /* ":method": "GET" */
-#define GRPC_MDELEM_METHOD_GET (&grpc_static_mdelem_table[49])
+#define GRPC_MDELEM_METHOD_GET (&grpc_static_mdelem_table[50])
 /* ":method": "POST" */
-#define GRPC_MDELEM_METHOD_POST (&grpc_static_mdelem_table[50])
+#define GRPC_MDELEM_METHOD_POST (&grpc_static_mdelem_table[51])
 /* ":method": "PUT" */
-#define GRPC_MDELEM_METHOD_PUT (&grpc_static_mdelem_table[51])
+#define GRPC_MDELEM_METHOD_PUT (&grpc_static_mdelem_table[52])
 /* ":path": "/" */
-#define GRPC_MDELEM_PATH_SLASH (&grpc_static_mdelem_table[52])
+#define GRPC_MDELEM_PATH_SLASH (&grpc_static_mdelem_table[53])
 /* ":path": "/index.html" */
-#define GRPC_MDELEM_PATH_SLASH_INDEX_DOT_HTML (&grpc_static_mdelem_table[53])
+#define GRPC_MDELEM_PATH_SLASH_INDEX_DOT_HTML (&grpc_static_mdelem_table[54])
 /* "proxy-authenticate": "" */
-#define GRPC_MDELEM_PROXY_AUTHENTICATE_EMPTY (&grpc_static_mdelem_table[54])
+#define GRPC_MDELEM_PROXY_AUTHENTICATE_EMPTY (&grpc_static_mdelem_table[55])
 /* "proxy-authorization": "" */
-#define GRPC_MDELEM_PROXY_AUTHORIZATION_EMPTY (&grpc_static_mdelem_table[55])
+#define GRPC_MDELEM_PROXY_AUTHORIZATION_EMPTY (&grpc_static_mdelem_table[56])
 /* "range": "" */
-#define GRPC_MDELEM_RANGE_EMPTY (&grpc_static_mdelem_table[56])
+#define GRPC_MDELEM_RANGE_EMPTY (&grpc_static_mdelem_table[57])
 /* "referer": "" */
-#define GRPC_MDELEM_REFERER_EMPTY (&grpc_static_mdelem_table[57])
+#define GRPC_MDELEM_REFERER_EMPTY (&grpc_static_mdelem_table[58])
 /* "refresh": "" */
-#define GRPC_MDELEM_REFRESH_EMPTY (&grpc_static_mdelem_table[58])
+#define GRPC_MDELEM_REFRESH_EMPTY (&grpc_static_mdelem_table[59])
 /* "retry-after": "" */
-#define GRPC_MDELEM_RETRY_AFTER_EMPTY (&grpc_static_mdelem_table[59])
+#define GRPC_MDELEM_RETRY_AFTER_EMPTY (&grpc_static_mdelem_table[60])
 /* ":scheme": "grpc" */
-#define GRPC_MDELEM_SCHEME_GRPC (&grpc_static_mdelem_table[60])
+#define GRPC_MDELEM_SCHEME_GRPC (&grpc_static_mdelem_table[61])
 /* ":scheme": "http" */
-#define GRPC_MDELEM_SCHEME_HTTP (&grpc_static_mdelem_table[61])
+#define GRPC_MDELEM_SCHEME_HTTP (&grpc_static_mdelem_table[62])
 /* ":scheme": "https" */
-#define GRPC_MDELEM_SCHEME_HTTPS (&grpc_static_mdelem_table[62])
+#define GRPC_MDELEM_SCHEME_HTTPS (&grpc_static_mdelem_table[63])
 /* "server": "" */
-#define GRPC_MDELEM_SERVER_EMPTY (&grpc_static_mdelem_table[63])
+#define GRPC_MDELEM_SERVER_EMPTY (&grpc_static_mdelem_table[64])
 /* "set-cookie": "" */
-#define GRPC_MDELEM_SET_COOKIE_EMPTY (&grpc_static_mdelem_table[64])
+#define GRPC_MDELEM_SET_COOKIE_EMPTY (&grpc_static_mdelem_table[65])
 /* ":status": "200" */
-#define GRPC_MDELEM_STATUS_200 (&grpc_static_mdelem_table[65])
+#define GRPC_MDELEM_STATUS_200 (&grpc_static_mdelem_table[66])
 /* ":status": "204" */
-#define GRPC_MDELEM_STATUS_204 (&grpc_static_mdelem_table[66])
+#define GRPC_MDELEM_STATUS_204 (&grpc_static_mdelem_table[67])
 /* ":status": "206" */
-#define GRPC_MDELEM_STATUS_206 (&grpc_static_mdelem_table[67])
+#define GRPC_MDELEM_STATUS_206 (&grpc_static_mdelem_table[68])
 /* ":status": "304" */
-#define GRPC_MDELEM_STATUS_304 (&grpc_static_mdelem_table[68])
+#define GRPC_MDELEM_STATUS_304 (&grpc_static_mdelem_table[69])
 /* ":status": "400" */
-#define GRPC_MDELEM_STATUS_400 (&grpc_static_mdelem_table[69])
+#define GRPC_MDELEM_STATUS_400 (&grpc_static_mdelem_table[70])
 /* ":status": "404" */
-#define GRPC_MDELEM_STATUS_404 (&grpc_static_mdelem_table[70])
+#define GRPC_MDELEM_STATUS_404 (&grpc_static_mdelem_table[71])
 /* ":status": "500" */
-#define GRPC_MDELEM_STATUS_500 (&grpc_static_mdelem_table[71])
+#define GRPC_MDELEM_STATUS_500 (&grpc_static_mdelem_table[72])
 /* "strict-transport-security": "" */
 #define GRPC_MDELEM_STRICT_TRANSPORT_SECURITY_EMPTY \
-  (&grpc_static_mdelem_table[72])
+  (&grpc_static_mdelem_table[73])
 /* "te": "trailers" */
-#define GRPC_MDELEM_TE_TRAILERS (&grpc_static_mdelem_table[73])
+#define GRPC_MDELEM_TE_TRAILERS (&grpc_static_mdelem_table[74])
 /* "transfer-encoding": "" */
-#define GRPC_MDELEM_TRANSFER_ENCODING_EMPTY (&grpc_static_mdelem_table[74])
+#define GRPC_MDELEM_TRANSFER_ENCODING_EMPTY (&grpc_static_mdelem_table[75])
 /* "user-agent": "" */
-#define GRPC_MDELEM_USER_AGENT_EMPTY (&grpc_static_mdelem_table[75])
+#define GRPC_MDELEM_USER_AGENT_EMPTY (&grpc_static_mdelem_table[76])
 /* "vary": "" */
-#define GRPC_MDELEM_VARY_EMPTY (&grpc_static_mdelem_table[76])
+#define GRPC_MDELEM_VARY_EMPTY (&grpc_static_mdelem_table[77])
 /* "via": "" */
-#define GRPC_MDELEM_VIA_EMPTY (&grpc_static_mdelem_table[77])
+#define GRPC_MDELEM_VIA_EMPTY (&grpc_static_mdelem_table[78])
 /* "www-authenticate": "" */
-#define GRPC_MDELEM_WWW_AUTHENTICATE_EMPTY (&grpc_static_mdelem_table[78])
+#define GRPC_MDELEM_WWW_AUTHENTICATE_EMPTY (&grpc_static_mdelem_table[79])
 
 extern const uint8_t
     grpc_static_metadata_elem_indices[GRPC_STATIC_MDELEM_COUNT * 2];
diff --git a/src/core/lib/transport/transport.c b/src/core/lib/transport/transport.c
index e6d524a..b65e157 100644
--- a/src/core/lib/transport/transport.c
+++ b/src/core/lib/transport/transport.c
@@ -125,10 +125,19 @@
   transport->vtable->perform_op(exec_ctx, transport, op);
 }
 
-void grpc_transport_set_pollset(grpc_exec_ctx *exec_ctx,
-                                grpc_transport *transport, grpc_stream *stream,
-                                grpc_pollset *pollset) {
-  transport->vtable->set_pollset(exec_ctx, transport, stream, pollset);
+void grpc_transport_set_pops(grpc_exec_ctx *exec_ctx, grpc_transport *transport,
+                             grpc_stream *stream,
+                             grpc_polling_entity *pollent) {
+  grpc_pollset *pollset;
+  grpc_pollset_set *pollset_set;
+  if ((pollset = grpc_polling_entity_pollset(pollent)) != NULL) {
+    transport->vtable->set_pollset(exec_ctx, transport, stream, pollset);
+  } else if ((pollset_set = grpc_polling_entity_pollset_set(pollent)) != NULL) {
+    transport->vtable->set_pollset_set(exec_ctx, transport, stream,
+                                       pollset_set);
+  } else {
+    abort();
+  }
 }
 
 void grpc_transport_destroy_stream(grpc_exec_ctx *exec_ctx,
diff --git a/src/core/lib/transport/transport.h b/src/core/lib/transport/transport.h
index 482a9d1..ed06fc3 100644
--- a/src/core/lib/transport/transport.h
+++ b/src/core/lib/transport/transport.h
@@ -37,6 +37,7 @@
 #include <stddef.h>
 
 #include "src/core/lib/channel/context.h"
+#include "src/core/lib/iomgr/polling_entity.h"
 #include "src/core/lib/iomgr/pollset.h"
 #include "src/core/lib/iomgr/pollset_set.h"
 #include "src/core/lib/transport/byte_stream.h"
@@ -197,9 +198,8 @@
                                grpc_stream_refcount *refcount,
                                const void *server_data);
 
-void grpc_transport_set_pollset(grpc_exec_ctx *exec_ctx,
-                                grpc_transport *transport, grpc_stream *stream,
-                                grpc_pollset *pollset);
+void grpc_transport_set_pops(grpc_exec_ctx *exec_ctx, grpc_transport *transport,
+                             grpc_stream *stream, grpc_polling_entity *pollent);
 
 /* Destroy transport data for a stream.
 
diff --git a/src/core/lib/transport/transport_impl.h b/src/core/lib/transport/transport_impl.h
index 956155e..fc71406 100644
--- a/src/core/lib/transport/transport_impl.h
+++ b/src/core/lib/transport/transport_impl.h
@@ -53,6 +53,10 @@
   void (*set_pollset)(grpc_exec_ctx *exec_ctx, grpc_transport *self,
                       grpc_stream *stream, grpc_pollset *pollset);
 
+  /* implementation of grpc_transport_set_pollset */
+  void (*set_pollset_set)(grpc_exec_ctx *exec_ctx, grpc_transport *self,
+                          grpc_stream *stream, grpc_pollset_set *pollset_set);
+
   /* implementation of grpc_transport_perform_stream_op */
   void (*perform_stream_op)(grpc_exec_ctx *exec_ctx, grpc_transport *self,
                             grpc_stream *stream, grpc_transport_stream_op *op);
diff --git a/include/grpc/support/log_win32.h b/src/core/plugin_registry/grpc_cronet_plugin_registry.c
similarity index 75%
copy from include/grpc/support/log_win32.h
copy to src/core/plugin_registry/grpc_cronet_plugin_registry.c
index e5c25e0..d0b5f5c 100644
--- a/include/grpc/support/log_win32.h
+++ b/src/core/plugin_registry/grpc_cronet_plugin_registry.c
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,21 +31,16 @@
  *
  */
 
-#ifndef GRPC_SUPPORT_LOG_WIN32_H
-#define GRPC_SUPPORT_LOG_WIN32_H
+#include <grpc/grpc.h>
 
-#ifdef __cplusplus
-extern "C" {
-#endif
+extern void grpc_chttp2_plugin_init(void);
+extern void grpc_chttp2_plugin_shutdown(void);
+extern void grpc_client_config_init(void);
+extern void grpc_client_config_shutdown(void);
 
-/* Returns a string allocated with gpr_malloc that contains a UTF-8
- * formatted error message, corresponding to the error messageid.
- * Use in conjunction with GetLastError() et al.
- */
-GPRAPI char *gpr_format_message(int messageid);
-
-#ifdef __cplusplus
+void grpc_register_built_in_plugins(void) {
+  grpc_register_plugin(grpc_chttp2_plugin_init,
+                       grpc_chttp2_plugin_shutdown);
+  grpc_register_plugin(grpc_client_config_init,
+                       grpc_client_config_shutdown);
 }
-#endif
-
-#endif /* GRPC_SUPPORT_LOG_WIN32_H */
diff --git a/src/core/plugin_registry/grpc_plugin_registry.c b/src/core/plugin_registry/grpc_plugin_registry.c
index 822aa6d..905cd59 100644
--- a/src/core/plugin_registry/grpc_plugin_registry.c
+++ b/src/core/plugin_registry/grpc_plugin_registry.c
@@ -45,6 +45,8 @@
 extern void grpc_resolver_dns_native_shutdown(void);
 extern void grpc_resolver_sockaddr_init(void);
 extern void grpc_resolver_sockaddr_shutdown(void);
+extern void grpc_load_reporting_plugin_init(void);
+extern void grpc_load_reporting_plugin_shutdown(void);
 extern void census_grpc_plugin_init(void);
 extern void census_grpc_plugin_shutdown(void);
 
@@ -61,6 +63,8 @@
                        grpc_resolver_dns_native_shutdown);
   grpc_register_plugin(grpc_resolver_sockaddr_init,
                        grpc_resolver_sockaddr_shutdown);
+  grpc_register_plugin(grpc_load_reporting_plugin_init,
+                       grpc_load_reporting_plugin_shutdown);
   grpc_register_plugin(census_grpc_plugin_init,
                        census_grpc_plugin_shutdown);
 }
diff --git a/src/core/plugin_registry/grpc_unsecure_plugin_registry.c b/src/core/plugin_registry/grpc_unsecure_plugin_registry.c
index a6108ae..7995078 100644
--- a/src/core/plugin_registry/grpc_unsecure_plugin_registry.c
+++ b/src/core/plugin_registry/grpc_unsecure_plugin_registry.c
@@ -41,6 +41,8 @@
 extern void grpc_resolver_dns_native_shutdown(void);
 extern void grpc_resolver_sockaddr_init(void);
 extern void grpc_resolver_sockaddr_shutdown(void);
+extern void grpc_load_reporting_plugin_init(void);
+extern void grpc_load_reporting_plugin_shutdown(void);
 extern void grpc_lb_policy_pick_first_init(void);
 extern void grpc_lb_policy_pick_first_shutdown(void);
 extern void grpc_lb_policy_round_robin_init(void);
@@ -57,6 +59,8 @@
                        grpc_resolver_dns_native_shutdown);
   grpc_register_plugin(grpc_resolver_sockaddr_init,
                        grpc_resolver_sockaddr_shutdown);
+  grpc_register_plugin(grpc_load_reporting_plugin_init,
+                       grpc_load_reporting_plugin_shutdown);
   grpc_register_plugin(grpc_lb_policy_pick_first_init,
                        grpc_lb_policy_pick_first_shutdown);
   grpc_register_plugin(grpc_lb_policy_round_robin_init,
diff --git a/src/cpp/client/client_context.cc b/src/cpp/client/client_context.cc
index 32c7794..d3e5ce0 100644
--- a/src/cpp/client/client_context.cc
+++ b/src/cpp/client/client_context.cc
@@ -33,15 +33,14 @@
 
 #include <grpc++/client_context.h>
 
-#include <grpc++/security/credentials.h>
-#include <grpc++/server_context.h>
-#include <grpc++/support/time.h>
 #include <grpc/compression.h>
 #include <grpc/grpc.h>
 #include <grpc/support/alloc.h>
 #include <grpc/support/string_util.h>
 
-#include "src/core/lib/channel/compress_filter.h"
+#include <grpc++/security/credentials.h>
+#include <grpc++/server_context.h>
+#include <grpc++/support/time.h>
 
 namespace grpc {
 
@@ -112,7 +111,7 @@
     abort();
   }
   GPR_ASSERT(algorithm_name != nullptr);
-  AddMetadata(GRPC_COMPRESS_REQUEST_ALGORITHM_KEY, algorithm_name);
+  AddMetadata(GRPC_COMPRESSION_REQUEST_ALGORITHM_MD_KEY, algorithm_name);
 }
 
 void ClientContext::TryCancel() {
diff --git a/include/grpc/support/log_win32.h b/src/cpp/client/create_channel_posix.cc
similarity index 69%
copy from include/grpc/support/log_win32.h
copy to src/cpp/client/create_channel_posix.cc
index e5c25e0..60cfed3 100644
--- a/include/grpc/support/log_win32.h
+++ b/src/cpp/client/create_channel_posix.cc
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,21 +31,26 @@
  *
  */
 
-#ifndef GRPC_SUPPORT_LOG_WIN32_H
-#define GRPC_SUPPORT_LOG_WIN32_H
+#include <grpc++/channel.h>
+#include <grpc++/create_channel.h>
+#include <grpc++/impl/grpc_library.h>
+#include <grpc/grpc.h>
+#include <grpc/grpc_posix.h>
 
-#ifdef __cplusplus
-extern "C" {
-#endif
+#include "src/cpp/client/create_channel_internal.h"
 
-/* Returns a string allocated with gpr_malloc that contains a UTF-8
- * formatted error message, corresponding to the error messageid.
- * Use in conjunction with GetLastError() et al.
- */
-GPRAPI char *gpr_format_message(int messageid);
+namespace grpc {
 
-#ifdef __cplusplus
+#ifdef GPR_SUPPORT_CHANNELS_FROM_FD
+
+std::shared_ptr<Channel> CreateInsecureChannelFromFd(const grpc::string& target,
+                                                     int fd) {
+  internal::GrpcLibrary init_lib;
+  init_lib.init();
+  return CreateChannelInternal(
+      "", grpc_insecure_channel_create_from_fd(target.c_str(), fd, nullptr));
 }
-#endif
 
-#endif /* GRPC_SUPPORT_LOG_WIN32_H */
+#endif  // GPR_SUPPORT_CHANNELS_FROM_FD
+
+}  // namespace grpc
diff --git a/src/cpp/common/core_codegen.cc b/src/cpp/common/core_codegen.cc
index 8e8d42e..cc35aa6 100644
--- a/src/cpp/common/core_codegen.cc
+++ b/src/cpp/common/core_codegen.cc
@@ -31,7 +31,7 @@
  *
  */
 
-#include "src/cpp/common/core_codegen.h"
+#include <grpc++/impl/codegen/core_codegen.h>
 
 #include <stdlib.h>
 
diff --git a/src/cpp/ext/proto_server_reflection.cc b/src/cpp/ext/proto_server_reflection.cc
new file mode 100644
index 0000000..348a035
--- /dev/null
+++ b/src/cpp/ext/proto_server_reflection.cc
@@ -0,0 +1,227 @@
+/*
+ *
+ * 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 <unordered_set>
+#include <vector>
+
+#include <grpc++/grpc++.h>
+
+#include "src/cpp/ext/proto_server_reflection.h"
+
+using grpc::Status;
+using grpc::StatusCode;
+using grpc::reflection::v1alpha::ServerReflectionRequest;
+using grpc::reflection::v1alpha::ExtensionRequest;
+using grpc::reflection::v1alpha::ServerReflectionResponse;
+using grpc::reflection::v1alpha::ListServiceResponse;
+using grpc::reflection::v1alpha::ServiceResponse;
+using grpc::reflection::v1alpha::ExtensionNumberResponse;
+using grpc::reflection::v1alpha::ErrorResponse;
+using grpc::reflection::v1alpha::FileDescriptorResponse;
+
+namespace grpc {
+
+ProtoServerReflection::ProtoServerReflection()
+    : descriptor_pool_(protobuf::DescriptorPool::generated_pool()) {}
+
+void ProtoServerReflection::SetServiceList(
+    const std::vector<grpc::string>* services) {
+  services_ = services;
+}
+
+Status ProtoServerReflection::ServerReflectionInfo(
+    ServerContext* context,
+    ServerReaderWriter<ServerReflectionResponse, ServerReflectionRequest>*
+        stream) {
+  ServerReflectionRequest request;
+  ServerReflectionResponse response;
+  Status status;
+  while (stream->Read(&request)) {
+    switch (request.message_request_case()) {
+      case ServerReflectionRequest::MessageRequestCase::kFileByFilename:
+        status = GetFileByName(context, request.file_by_filename(), &response);
+        break;
+      case ServerReflectionRequest::MessageRequestCase::kFileContainingSymbol:
+        status = GetFileContainingSymbol(
+            context, request.file_containing_symbol(), &response);
+        break;
+      case ServerReflectionRequest::MessageRequestCase::
+          kFileContainingExtension:
+        status = GetFileContainingExtension(
+            context, &request.file_containing_extension(), &response);
+        break;
+      case ServerReflectionRequest::MessageRequestCase::
+          kAllExtensionNumbersOfType:
+        status = GetAllExtensionNumbers(
+            context, request.all_extension_numbers_of_type(),
+            response.mutable_all_extension_numbers_response());
+        break;
+      case ServerReflectionRequest::MessageRequestCase::kListServices:
+        status =
+            ListService(context, response.mutable_list_services_response());
+        break;
+      default:
+        status = Status(StatusCode::UNIMPLEMENTED, "");
+    }
+
+    if (!status.ok()) {
+      FillErrorResponse(status, response.mutable_error_response());
+    }
+    response.set_valid_host(request.host());
+    response.set_allocated_original_request(
+        new ServerReflectionRequest(request));
+    stream->Write(response);
+  }
+
+  return Status::OK;
+}
+
+void ProtoServerReflection::FillErrorResponse(const Status& status,
+                                              ErrorResponse* error_response) {
+  error_response->set_error_code(status.error_code());
+  error_response->set_error_message(status.error_message());
+}
+
+Status ProtoServerReflection::ListService(ServerContext* context,
+                                          ListServiceResponse* response) {
+  if (services_ == nullptr) {
+    return Status(StatusCode::NOT_FOUND, "Services not found.");
+  }
+  for (auto it = services_->begin(); it != services_->end(); ++it) {
+    ServiceResponse* service_response = response->add_service();
+    service_response->set_name(*it);
+  }
+  return Status::OK;
+}
+
+Status ProtoServerReflection::GetFileByName(
+    ServerContext* context, const grpc::string& filename,
+    ServerReflectionResponse* response) {
+  if (descriptor_pool_ == nullptr) {
+    return Status::CANCELLED;
+  }
+
+  const protobuf::FileDescriptor* file_desc =
+      descriptor_pool_->FindFileByName(filename);
+  if (file_desc == nullptr) {
+    return Status(StatusCode::NOT_FOUND, "File not found.");
+  }
+  std::unordered_set<grpc::string> seen_files;
+  FillFileDescriptorResponse(file_desc, response, &seen_files);
+  return Status::OK;
+}
+
+Status ProtoServerReflection::GetFileContainingSymbol(
+    ServerContext* context, const grpc::string& symbol,
+    ServerReflectionResponse* response) {
+  if (descriptor_pool_ == nullptr) {
+    return Status::CANCELLED;
+  }
+
+  const protobuf::FileDescriptor* file_desc =
+      descriptor_pool_->FindFileContainingSymbol(symbol);
+  if (file_desc == nullptr) {
+    return Status(StatusCode::NOT_FOUND, "Symbol not found.");
+  }
+  std::unordered_set<grpc::string> seen_files;
+  FillFileDescriptorResponse(file_desc, response, &seen_files);
+  return Status::OK;
+}
+
+Status ProtoServerReflection::GetFileContainingExtension(
+    ServerContext* context, const ExtensionRequest* request,
+    ServerReflectionResponse* response) {
+  if (descriptor_pool_ == nullptr) {
+    return Status::CANCELLED;
+  }
+
+  const protobuf::Descriptor* desc =
+      descriptor_pool_->FindMessageTypeByName(request->containing_type());
+  if (desc == nullptr) {
+    return Status(StatusCode::NOT_FOUND, "Type not found.");
+  }
+
+  const protobuf::FieldDescriptor* field_desc =
+      descriptor_pool_->FindExtensionByNumber(desc,
+                                              request->extension_number());
+  if (field_desc == nullptr) {
+    return Status(StatusCode::NOT_FOUND, "Extension not found.");
+  }
+  std::unordered_set<grpc::string> seen_files;
+  FillFileDescriptorResponse(field_desc->file(), response, &seen_files);
+  return Status::OK;
+}
+
+Status ProtoServerReflection::GetAllExtensionNumbers(
+    ServerContext* context, const grpc::string& type,
+    ExtensionNumberResponse* response) {
+  if (descriptor_pool_ == nullptr) {
+    return Status::CANCELLED;
+  }
+
+  const protobuf::Descriptor* desc =
+      descriptor_pool_->FindMessageTypeByName(type);
+  if (desc == nullptr) {
+    return Status(StatusCode::NOT_FOUND, "Type not found.");
+  }
+
+  std::vector<const protobuf::FieldDescriptor*> extensions;
+  descriptor_pool_->FindAllExtensions(desc, &extensions);
+  for (auto extension : extensions) {
+    response->add_extension_number(extension->number());
+  }
+  response->set_base_type_name(type);
+  return Status::OK;
+}
+
+void ProtoServerReflection::FillFileDescriptorResponse(
+    const protobuf::FileDescriptor* file_desc,
+    ServerReflectionResponse* response,
+    std::unordered_set<grpc::string>* seen_files) {
+  if (seen_files->find(file_desc->name()) != seen_files->end()) {
+    return;
+  }
+  seen_files->insert(file_desc->name());
+
+  protobuf::FileDescriptorProto file_desc_proto;
+  grpc::string data;
+  file_desc->CopyTo(&file_desc_proto);
+  file_desc_proto.SerializeToString(&data);
+  response->mutable_file_descriptor_response()->add_file_descriptor_proto(data);
+
+  for (int i = 0; i < file_desc->dependency_count(); ++i) {
+    FillFileDescriptorResponse(file_desc->dependency(i), response, seen_files);
+  }
+}
+
+}  // namespace grpc
diff --git a/src/cpp/ext/proto_server_reflection.h b/src/cpp/ext/proto_server_reflection.h
new file mode 100644
index 0000000..23c1305
--- /dev/null
+++ b/src/cpp/ext/proto_server_reflection.h
@@ -0,0 +1,94 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef GRPC_INTERNAL_CPP_EXT_PROTO_SERVER_REFLECTION_H
+#define GRPC_INTERNAL_CPP_EXT_PROTO_SERVER_REFLECTION_H
+
+#include <unordered_set>
+#include <vector>
+
+#include <grpc++/ext/reflection.grpc.pb.h>
+#include <grpc++/grpc++.h>
+
+namespace grpc {
+
+class ProtoServerReflection GRPC_FINAL
+    : public reflection::v1alpha::ServerReflection::Service {
+ public:
+  ProtoServerReflection();
+
+  // Add the full names of registered services
+  void SetServiceList(const std::vector<grpc::string>* services);
+
+  // implementation of ServerReflectionInfo(stream ServerReflectionRequest) rpc
+  // in ServerReflection service
+  Status ServerReflectionInfo(
+      ServerContext* context,
+      ServerReaderWriter<reflection::v1alpha::ServerReflectionResponse,
+                         reflection::v1alpha::ServerReflectionRequest>* stream)
+      GRPC_OVERRIDE;
+
+ private:
+  Status ListService(ServerContext* context,
+                     reflection::v1alpha::ListServiceResponse* response);
+
+  Status GetFileByName(ServerContext* context, const grpc::string& file_name,
+                       reflection::v1alpha::ServerReflectionResponse* response);
+
+  Status GetFileContainingSymbol(
+      ServerContext* context, const grpc::string& symbol,
+      reflection::v1alpha::ServerReflectionResponse* response);
+
+  Status GetFileContainingExtension(
+      ServerContext* context,
+      const reflection::v1alpha::ExtensionRequest* request,
+      reflection::v1alpha::ServerReflectionResponse* response);
+
+  Status GetAllExtensionNumbers(
+      ServerContext* context, const grpc::string& type,
+      reflection::v1alpha::ExtensionNumberResponse* response);
+
+  void FillFileDescriptorResponse(
+      const protobuf::FileDescriptor* file_desc,
+      reflection::v1alpha::ServerReflectionResponse* response,
+      std::unordered_set<grpc::string>* seen_files);
+
+  void FillErrorResponse(const Status& status,
+                         reflection::v1alpha::ErrorResponse* error_response);
+
+  const protobuf::DescriptorPool* descriptor_pool_;
+  const std::vector<string>* services_;
+};
+
+}  // namespace grpc
+
+#endif  // GRPC_INTERNAL_CPP_EXT_PROTO_SERVER_REFLECTION_H
diff --git a/src/cpp/ext/proto_server_reflection_plugin.cc b/src/cpp/ext/proto_server_reflection_plugin.cc
new file mode 100644
index 0000000..f31d102
--- /dev/null
+++ b/src/cpp/ext/proto_server_reflection_plugin.cc
@@ -0,0 +1,97 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <grpc++/ext/proto_server_reflection_plugin.h>
+#include <grpc++/impl/server_builder_plugin.h>
+#include <grpc++/impl/server_initializer.h>
+#include <grpc++/server.h>
+
+#include "src/cpp/ext/proto_server_reflection.h"
+
+namespace grpc {
+namespace reflection {
+
+ProtoServerReflectionPlugin::ProtoServerReflectionPlugin()
+    : reflection_service_(new grpc::ProtoServerReflection()) {}
+
+grpc::string ProtoServerReflectionPlugin::name() {
+  return "proto_server_reflection";
+}
+
+void ProtoServerReflectionPlugin::InitServer(grpc::ServerInitializer* si) {
+  si->RegisterService(reflection_service_);
+}
+
+void ProtoServerReflectionPlugin::Finish(grpc::ServerInitializer* si) {
+  reflection_service_->SetServiceList(si->GetServiceList());
+}
+
+void ProtoServerReflectionPlugin::ChangeArguments(const grpc::string& name,
+                                                  void* value) {}
+
+bool ProtoServerReflectionPlugin::has_sync_methods() const {
+  if (reflection_service_ != nullptr) {
+    return reflection_service_->has_synchronous_methods();
+  }
+  return false;
+}
+
+bool ProtoServerReflectionPlugin::has_async_methods() const {
+  if (reflection_service_ != nullptr) {
+    return reflection_service_->has_async_methods();
+  }
+  return false;
+}
+
+static std::unique_ptr<::grpc::ServerBuilderPlugin> CreateProtoReflection() {
+  return std::unique_ptr<::grpc::ServerBuilderPlugin>(
+      new ProtoServerReflectionPlugin());
+}
+
+void InitProtoReflectionServerBuilderPlugin() {
+  static bool already_here = false;
+  if (already_here) return;
+  already_here = true;
+  ::grpc::ServerBuilder::InternalAddPluginFactory(&CreateProtoReflection);
+}
+
+// Force InitProtoReflectionServerBuilderPlugin() to be called at static
+// initialization time.
+struct StaticProtoReflectionPluginInitializer {
+  StaticProtoReflectionPluginInitializer() {
+    InitProtoReflectionServerBuilderPlugin();
+  }
+} static_proto_reflection_plugin_initializer;
+
+}  // namespace reflection
+}  // namespace grpc
diff --git a/src/cpp/ext/reflection.grpc.pb.cc b/src/cpp/ext/reflection.grpc.pb.cc
new file mode 100644
index 0000000..b046dfc
--- /dev/null
+++ b/src/cpp/ext/reflection.grpc.pb.cc
@@ -0,0 +1,97 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+
+// Generated by the gRPC protobuf plugin.
+// If you make any local change, they will be lost.
+// source: reflection.proto
+
+#include <grpc++/ext/reflection.pb.h>
+#include <grpc++/ext/reflection.grpc.pb.h>
+
+#include <grpc++/impl/codegen/async_stream.h>
+#include <grpc++/impl/codegen/async_unary_call.h>
+#include <grpc++/impl/codegen/channel_interface.h>
+#include <grpc++/impl/codegen/client_unary_call.h>
+#include <grpc++/impl/codegen/method_handler_impl.h>
+#include <grpc++/impl/codegen/rpc_service_method.h>
+#include <grpc++/impl/codegen/service_type.h>
+#include <grpc++/impl/codegen/sync_stream.h>
+namespace grpc {
+namespace reflection {
+namespace v1alpha {
+
+static const char* ServerReflection_method_names[] = {
+  "/grpc.reflection.v1alpha.ServerReflection/ServerReflectionInfo",
+};
+
+std::unique_ptr< ServerReflection::Stub> ServerReflection::NewStub(const std::shared_ptr< ::grpc::ChannelInterface>& channel, const ::grpc::StubOptions& options) {
+  std::unique_ptr< ServerReflection::Stub> stub(new ServerReflection::Stub(channel));
+  return stub;
+}
+
+ServerReflection::Stub::Stub(const std::shared_ptr< ::grpc::ChannelInterface>& channel)
+  : channel_(channel), rpcmethod_ServerReflectionInfo_(ServerReflection_method_names[0], ::grpc::RpcMethod::BIDI_STREAMING, channel)
+  {}
+
+::grpc::ClientReaderWriter< ::grpc::reflection::v1alpha::ServerReflectionRequest, ::grpc::reflection::v1alpha::ServerReflectionResponse>* ServerReflection::Stub::ServerReflectionInfoRaw(::grpc::ClientContext* context) {
+  return new ::grpc::ClientReaderWriter< ::grpc::reflection::v1alpha::ServerReflectionRequest, ::grpc::reflection::v1alpha::ServerReflectionResponse>(channel_.get(), rpcmethod_ServerReflectionInfo_, context);
+}
+
+::grpc::ClientAsyncReaderWriter< ::grpc::reflection::v1alpha::ServerReflectionRequest, ::grpc::reflection::v1alpha::ServerReflectionResponse>* ServerReflection::Stub::AsyncServerReflectionInfoRaw(::grpc::ClientContext* context, ::grpc::CompletionQueue* cq, void* tag) {
+  return new ::grpc::ClientAsyncReaderWriter< ::grpc::reflection::v1alpha::ServerReflectionRequest, ::grpc::reflection::v1alpha::ServerReflectionResponse>(channel_.get(), cq, rpcmethod_ServerReflectionInfo_, context, tag);
+}
+
+ServerReflection::Service::Service() {
+  (void)ServerReflection_method_names;
+  AddMethod(new ::grpc::RpcServiceMethod(
+      ServerReflection_method_names[0],
+      ::grpc::RpcMethod::BIDI_STREAMING,
+      new ::grpc::BidiStreamingHandler< ServerReflection::Service, ::grpc::reflection::v1alpha::ServerReflectionRequest, ::grpc::reflection::v1alpha::ServerReflectionResponse>(
+          std::mem_fn(&ServerReflection::Service::ServerReflectionInfo), this)));
+}
+
+ServerReflection::Service::~Service() {
+}
+
+::grpc::Status ServerReflection::Service::ServerReflectionInfo(::grpc::ServerContext* context, ::grpc::ServerReaderWriter< ::grpc::reflection::v1alpha::ServerReflectionResponse, ::grpc::reflection::v1alpha::ServerReflectionRequest>* stream) {
+  (void) context;
+  (void) stream;
+  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+}
+
+
+}  // namespace grpc
+}  // namespace reflection
+}  // namespace v1alpha
+
diff --git a/src/cpp/ext/reflection.pb.cc b/src/cpp/ext/reflection.pb.cc
new file mode 100644
index 0000000..b73a65d
--- /dev/null
+++ b/src/cpp/ext/reflection.pb.cc
@@ -0,0 +1,3946 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: reflection.proto
+
+#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION
+#include <grpc++/ext/reflection.pb.h>
+
+#include <algorithm>
+
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/port.h>
+#include <google/protobuf/stubs/once.h>
+#include <google/protobuf/io/coded_stream.h>
+#include <google/protobuf/wire_format_lite_inl.h>
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/generated_message_reflection.h>
+#include <google/protobuf/reflection_ops.h>
+#include <google/protobuf/wire_format.h>
+// @@protoc_insertion_point(includes)
+
+namespace grpc {
+namespace reflection {
+namespace v1alpha {
+
+namespace {
+
+const ::google::protobuf::Descriptor* ServerReflectionRequest_descriptor_ = NULL;
+const ::google::protobuf::internal::GeneratedMessageReflection*
+  ServerReflectionRequest_reflection_ = NULL;
+struct ServerReflectionRequestOneofInstance {
+  ::google::protobuf::internal::ArenaStringPtr file_by_filename_;
+  ::google::protobuf::internal::ArenaStringPtr file_containing_symbol_;
+  const ::grpc::reflection::v1alpha::ExtensionRequest* file_containing_extension_;
+  ::google::protobuf::internal::ArenaStringPtr all_extension_numbers_of_type_;
+  ::google::protobuf::internal::ArenaStringPtr list_services_;
+}* ServerReflectionRequest_default_oneof_instance_ = NULL;
+const ::google::protobuf::Descriptor* ExtensionRequest_descriptor_ = NULL;
+const ::google::protobuf::internal::GeneratedMessageReflection*
+  ExtensionRequest_reflection_ = NULL;
+const ::google::protobuf::Descriptor* ServerReflectionResponse_descriptor_ = NULL;
+const ::google::protobuf::internal::GeneratedMessageReflection*
+  ServerReflectionResponse_reflection_ = NULL;
+struct ServerReflectionResponseOneofInstance {
+  const ::grpc::reflection::v1alpha::FileDescriptorResponse* file_descriptor_response_;
+  const ::grpc::reflection::v1alpha::ExtensionNumberResponse* all_extension_numbers_response_;
+  const ::grpc::reflection::v1alpha::ListServiceResponse* list_services_response_;
+  const ::grpc::reflection::v1alpha::ErrorResponse* error_response_;
+}* ServerReflectionResponse_default_oneof_instance_ = NULL;
+const ::google::protobuf::Descriptor* FileDescriptorResponse_descriptor_ = NULL;
+const ::google::protobuf::internal::GeneratedMessageReflection*
+  FileDescriptorResponse_reflection_ = NULL;
+const ::google::protobuf::Descriptor* ExtensionNumberResponse_descriptor_ = NULL;
+const ::google::protobuf::internal::GeneratedMessageReflection*
+  ExtensionNumberResponse_reflection_ = NULL;
+const ::google::protobuf::Descriptor* ListServiceResponse_descriptor_ = NULL;
+const ::google::protobuf::internal::GeneratedMessageReflection*
+  ListServiceResponse_reflection_ = NULL;
+const ::google::protobuf::Descriptor* ServiceResponse_descriptor_ = NULL;
+const ::google::protobuf::internal::GeneratedMessageReflection*
+  ServiceResponse_reflection_ = NULL;
+const ::google::protobuf::Descriptor* ErrorResponse_descriptor_ = NULL;
+const ::google::protobuf::internal::GeneratedMessageReflection*
+  ErrorResponse_reflection_ = NULL;
+
+}  // namespace
+
+
+void protobuf_AssignDesc_reflection_2eproto() {
+  protobuf_AddDesc_reflection_2eproto();
+  const ::google::protobuf::FileDescriptor* file =
+    ::google::protobuf::DescriptorPool::generated_pool()->FindFileByName(
+      "reflection.proto");
+  GOOGLE_CHECK(file != NULL);
+  ServerReflectionRequest_descriptor_ = file->message_type(0);
+  static const int ServerReflectionRequest_offsets_[7] = {
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServerReflectionRequest, host_),
+    PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET(ServerReflectionRequest_default_oneof_instance_, file_by_filename_),
+    PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET(ServerReflectionRequest_default_oneof_instance_, file_containing_symbol_),
+    PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET(ServerReflectionRequest_default_oneof_instance_, file_containing_extension_),
+    PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET(ServerReflectionRequest_default_oneof_instance_, all_extension_numbers_of_type_),
+    PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET(ServerReflectionRequest_default_oneof_instance_, list_services_),
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServerReflectionRequest, message_request_),
+  };
+  ServerReflectionRequest_reflection_ =
+    ::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection(
+      ServerReflectionRequest_descriptor_,
+      ServerReflectionRequest::default_instance_,
+      ServerReflectionRequest_offsets_,
+      -1,
+      -1,
+      -1,
+      ServerReflectionRequest_default_oneof_instance_,
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServerReflectionRequest, _oneof_case_[0]),
+      sizeof(ServerReflectionRequest),
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServerReflectionRequest, _internal_metadata_),
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServerReflectionRequest, _is_default_instance_));
+  ExtensionRequest_descriptor_ = file->message_type(1);
+  static const int ExtensionRequest_offsets_[2] = {
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ExtensionRequest, containing_type_),
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ExtensionRequest, extension_number_),
+  };
+  ExtensionRequest_reflection_ =
+    ::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection(
+      ExtensionRequest_descriptor_,
+      ExtensionRequest::default_instance_,
+      ExtensionRequest_offsets_,
+      -1,
+      -1,
+      -1,
+      sizeof(ExtensionRequest),
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ExtensionRequest, _internal_metadata_),
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ExtensionRequest, _is_default_instance_));
+  ServerReflectionResponse_descriptor_ = file->message_type(2);
+  static const int ServerReflectionResponse_offsets_[7] = {
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServerReflectionResponse, valid_host_),
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServerReflectionResponse, original_request_),
+    PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET(ServerReflectionResponse_default_oneof_instance_, file_descriptor_response_),
+    PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET(ServerReflectionResponse_default_oneof_instance_, all_extension_numbers_response_),
+    PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET(ServerReflectionResponse_default_oneof_instance_, list_services_response_),
+    PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET(ServerReflectionResponse_default_oneof_instance_, error_response_),
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServerReflectionResponse, message_response_),
+  };
+  ServerReflectionResponse_reflection_ =
+    ::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection(
+      ServerReflectionResponse_descriptor_,
+      ServerReflectionResponse::default_instance_,
+      ServerReflectionResponse_offsets_,
+      -1,
+      -1,
+      -1,
+      ServerReflectionResponse_default_oneof_instance_,
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServerReflectionResponse, _oneof_case_[0]),
+      sizeof(ServerReflectionResponse),
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServerReflectionResponse, _internal_metadata_),
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServerReflectionResponse, _is_default_instance_));
+  FileDescriptorResponse_descriptor_ = file->message_type(3);
+  static const int FileDescriptorResponse_offsets_[1] = {
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorResponse, file_descriptor_proto_),
+  };
+  FileDescriptorResponse_reflection_ =
+    ::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection(
+      FileDescriptorResponse_descriptor_,
+      FileDescriptorResponse::default_instance_,
+      FileDescriptorResponse_offsets_,
+      -1,
+      -1,
+      -1,
+      sizeof(FileDescriptorResponse),
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorResponse, _internal_metadata_),
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorResponse, _is_default_instance_));
+  ExtensionNumberResponse_descriptor_ = file->message_type(4);
+  static const int ExtensionNumberResponse_offsets_[2] = {
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ExtensionNumberResponse, base_type_name_),
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ExtensionNumberResponse, extension_number_),
+  };
+  ExtensionNumberResponse_reflection_ =
+    ::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection(
+      ExtensionNumberResponse_descriptor_,
+      ExtensionNumberResponse::default_instance_,
+      ExtensionNumberResponse_offsets_,
+      -1,
+      -1,
+      -1,
+      sizeof(ExtensionNumberResponse),
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ExtensionNumberResponse, _internal_metadata_),
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ExtensionNumberResponse, _is_default_instance_));
+  ListServiceResponse_descriptor_ = file->message_type(5);
+  static const int ListServiceResponse_offsets_[1] = {
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ListServiceResponse, service_),
+  };
+  ListServiceResponse_reflection_ =
+    ::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection(
+      ListServiceResponse_descriptor_,
+      ListServiceResponse::default_instance_,
+      ListServiceResponse_offsets_,
+      -1,
+      -1,
+      -1,
+      sizeof(ListServiceResponse),
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ListServiceResponse, _internal_metadata_),
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ListServiceResponse, _is_default_instance_));
+  ServiceResponse_descriptor_ = file->message_type(6);
+  static const int ServiceResponse_offsets_[1] = {
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceResponse, name_),
+  };
+  ServiceResponse_reflection_ =
+    ::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection(
+      ServiceResponse_descriptor_,
+      ServiceResponse::default_instance_,
+      ServiceResponse_offsets_,
+      -1,
+      -1,
+      -1,
+      sizeof(ServiceResponse),
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceResponse, _internal_metadata_),
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceResponse, _is_default_instance_));
+  ErrorResponse_descriptor_ = file->message_type(7);
+  static const int ErrorResponse_offsets_[2] = {
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ErrorResponse, error_code_),
+    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ErrorResponse, error_message_),
+  };
+  ErrorResponse_reflection_ =
+    ::google::protobuf::internal::GeneratedMessageReflection::NewGeneratedMessageReflection(
+      ErrorResponse_descriptor_,
+      ErrorResponse::default_instance_,
+      ErrorResponse_offsets_,
+      -1,
+      -1,
+      -1,
+      sizeof(ErrorResponse),
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ErrorResponse, _internal_metadata_),
+      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ErrorResponse, _is_default_instance_));
+}
+
+namespace {
+
+GOOGLE_PROTOBUF_DECLARE_ONCE(protobuf_AssignDescriptors_once_);
+inline void protobuf_AssignDescriptorsOnce() {
+  ::google::protobuf::GoogleOnceInit(&protobuf_AssignDescriptors_once_,
+                 &protobuf_AssignDesc_reflection_2eproto);
+}
+
+void protobuf_RegisterTypes(const ::std::string&) {
+  protobuf_AssignDescriptorsOnce();
+  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
+      ServerReflectionRequest_descriptor_, &ServerReflectionRequest::default_instance());
+  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
+      ExtensionRequest_descriptor_, &ExtensionRequest::default_instance());
+  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
+      ServerReflectionResponse_descriptor_, &ServerReflectionResponse::default_instance());
+  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
+      FileDescriptorResponse_descriptor_, &FileDescriptorResponse::default_instance());
+  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
+      ExtensionNumberResponse_descriptor_, &ExtensionNumberResponse::default_instance());
+  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
+      ListServiceResponse_descriptor_, &ListServiceResponse::default_instance());
+  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
+      ServiceResponse_descriptor_, &ServiceResponse::default_instance());
+  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
+      ErrorResponse_descriptor_, &ErrorResponse::default_instance());
+}
+
+}  // namespace
+
+void protobuf_ShutdownFile_reflection_2eproto() {
+  delete ServerReflectionRequest::default_instance_;
+  delete ServerReflectionRequest_default_oneof_instance_;
+  delete ServerReflectionRequest_reflection_;
+  delete ExtensionRequest::default_instance_;
+  delete ExtensionRequest_reflection_;
+  delete ServerReflectionResponse::default_instance_;
+  delete ServerReflectionResponse_default_oneof_instance_;
+  delete ServerReflectionResponse_reflection_;
+  delete FileDescriptorResponse::default_instance_;
+  delete FileDescriptorResponse_reflection_;
+  delete ExtensionNumberResponse::default_instance_;
+  delete ExtensionNumberResponse_reflection_;
+  delete ListServiceResponse::default_instance_;
+  delete ListServiceResponse_reflection_;
+  delete ServiceResponse::default_instance_;
+  delete ServiceResponse_reflection_;
+  delete ErrorResponse::default_instance_;
+  delete ErrorResponse_reflection_;
+}
+
+void protobuf_AddDesc_reflection_2eproto() {
+  static bool already_here = false;
+  if (already_here) return;
+  already_here = true;
+  GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+  ::google::protobuf::DescriptorPool::InternalAddGeneratedFile(
+    "\n\020reflection.proto\022\027grpc.reflection.v1al"
+    "pha\"\212\002\n\027ServerReflectionRequest\022\014\n\004host\030"
+    "\001 \001(\t\022\032\n\020file_by_filename\030\003 \001(\tH\000\022 \n\026fil"
+    "e_containing_symbol\030\004 \001(\tH\000\022N\n\031file_cont"
+    "aining_extension\030\005 \001(\0132).grpc.reflection"
+    ".v1alpha.ExtensionRequestH\000\022\'\n\035all_exten"
+    "sion_numbers_of_type\030\006 \001(\tH\000\022\027\n\rlist_ser"
+    "vices\030\007 \001(\tH\000B\021\n\017message_request\"E\n\020Exte"
+    "nsionRequest\022\027\n\017containing_type\030\001 \001(\t\022\030\n"
+    "\020extension_number\030\002 \001(\005\"\321\003\n\030ServerReflec"
+    "tionResponse\022\022\n\nvalid_host\030\001 \001(\t\022J\n\020orig"
+    "inal_request\030\002 \001(\01320.grpc.reflection.v1a"
+    "lpha.ServerReflectionRequest\022S\n\030file_des"
+    "criptor_response\030\004 \001(\0132/.grpc.reflection"
+    ".v1alpha.FileDescriptorResponseH\000\022Z\n\036all"
+    "_extension_numbers_response\030\005 \001(\01320.grpc"
+    ".reflection.v1alpha.ExtensionNumberRespo"
+    "nseH\000\022N\n\026list_services_response\030\006 \001(\0132,."
+    "grpc.reflection.v1alpha.ListServiceRespo"
+    "nseH\000\022@\n\016error_response\030\007 \001(\0132&.grpc.ref"
+    "lection.v1alpha.ErrorResponseH\000B\022\n\020messa"
+    "ge_response\"7\n\026FileDescriptorResponse\022\035\n"
+    "\025file_descriptor_proto\030\001 \003(\014\"K\n\027Extensio"
+    "nNumberResponse\022\026\n\016base_type_name\030\001 \001(\t\022"
+    "\030\n\020extension_number\030\002 \003(\005\"P\n\023ListService"
+    "Response\0229\n\007service\030\001 \003(\0132(.grpc.reflect"
+    "ion.v1alpha.ServiceResponse\"\037\n\017ServiceRe"
+    "sponse\022\014\n\004name\030\001 \001(\t\":\n\rErrorResponse\022\022\n"
+    "\nerror_code\030\001 \001(\005\022\025\n\rerror_message\030\002 \001(\t"
+    "2\223\001\n\020ServerReflection\022\177\n\024ServerReflectio"
+    "nInfo\0220.grpc.reflection.v1alpha.ServerRe"
+    "flectionRequest\0321.grpc.reflection.v1alph"
+    "a.ServerReflectionResponse(\0010\001b\006proto3", 1318);
+  ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(
+    "reflection.proto", &protobuf_RegisterTypes);
+  ServerReflectionRequest::default_instance_ = new ServerReflectionRequest();
+  ServerReflectionRequest_default_oneof_instance_ = new ServerReflectionRequestOneofInstance();
+  ExtensionRequest::default_instance_ = new ExtensionRequest();
+  ServerReflectionResponse::default_instance_ = new ServerReflectionResponse();
+  ServerReflectionResponse_default_oneof_instance_ = new ServerReflectionResponseOneofInstance();
+  FileDescriptorResponse::default_instance_ = new FileDescriptorResponse();
+  ExtensionNumberResponse::default_instance_ = new ExtensionNumberResponse();
+  ListServiceResponse::default_instance_ = new ListServiceResponse();
+  ServiceResponse::default_instance_ = new ServiceResponse();
+  ErrorResponse::default_instance_ = new ErrorResponse();
+  ServerReflectionRequest::default_instance_->InitAsDefaultInstance();
+  ExtensionRequest::default_instance_->InitAsDefaultInstance();
+  ServerReflectionResponse::default_instance_->InitAsDefaultInstance();
+  FileDescriptorResponse::default_instance_->InitAsDefaultInstance();
+  ExtensionNumberResponse::default_instance_->InitAsDefaultInstance();
+  ListServiceResponse::default_instance_->InitAsDefaultInstance();
+  ServiceResponse::default_instance_->InitAsDefaultInstance();
+  ErrorResponse::default_instance_->InitAsDefaultInstance();
+  ::google::protobuf::internal::OnShutdown(&protobuf_ShutdownFile_reflection_2eproto);
+}
+
+// Force AddDescriptors() to be called at static initialization time.
+struct StaticDescriptorInitializer_reflection_2eproto {
+  StaticDescriptorInitializer_reflection_2eproto() {
+    protobuf_AddDesc_reflection_2eproto();
+  }
+} static_descriptor_initializer_reflection_2eproto_;
+
+namespace {
+
+static void MergeFromFail(int line) GOOGLE_ATTRIBUTE_COLD;
+static void MergeFromFail(int line) {
+  GOOGLE_CHECK(false) << __FILE__ << ":" << line;
+}
+
+}  // namespace
+
+
+// ===================================================================
+
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int ServerReflectionRequest::kHostFieldNumber;
+const int ServerReflectionRequest::kFileByFilenameFieldNumber;
+const int ServerReflectionRequest::kFileContainingSymbolFieldNumber;
+const int ServerReflectionRequest::kFileContainingExtensionFieldNumber;
+const int ServerReflectionRequest::kAllExtensionNumbersOfTypeFieldNumber;
+const int ServerReflectionRequest::kListServicesFieldNumber;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+ServerReflectionRequest::ServerReflectionRequest()
+  : ::google::protobuf::Message(), _internal_metadata_(NULL) {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:grpc.reflection.v1alpha.ServerReflectionRequest)
+}
+
+void ServerReflectionRequest::InitAsDefaultInstance() {
+  _is_default_instance_ = true;
+  ServerReflectionRequest_default_oneof_instance_->file_by_filename_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  ServerReflectionRequest_default_oneof_instance_->file_containing_symbol_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  ServerReflectionRequest_default_oneof_instance_->file_containing_extension_ = const_cast< ::grpc::reflection::v1alpha::ExtensionRequest*>(&::grpc::reflection::v1alpha::ExtensionRequest::default_instance());
+  ServerReflectionRequest_default_oneof_instance_->all_extension_numbers_of_type_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  ServerReflectionRequest_default_oneof_instance_->list_services_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+
+ServerReflectionRequest::ServerReflectionRequest(const ServerReflectionRequest& from)
+  : ::google::protobuf::Message(),
+    _internal_metadata_(NULL) {
+  SharedCtor();
+  MergeFrom(from);
+  // @@protoc_insertion_point(copy_constructor:grpc.reflection.v1alpha.ServerReflectionRequest)
+}
+
+void ServerReflectionRequest::SharedCtor() {
+    _is_default_instance_ = false;
+  ::google::protobuf::internal::GetEmptyString();
+  _cached_size_ = 0;
+  host_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  clear_has_message_request();
+}
+
+ServerReflectionRequest::~ServerReflectionRequest() {
+  // @@protoc_insertion_point(destructor:grpc.reflection.v1alpha.ServerReflectionRequest)
+  SharedDtor();
+}
+
+void ServerReflectionRequest::SharedDtor() {
+  host_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (has_message_request()) {
+    clear_message_request();
+  }
+  if (this != default_instance_) {
+  }
+}
+
+void ServerReflectionRequest::SetCachedSize(int size) const {
+  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+  _cached_size_ = size;
+  GOOGLE_SAFE_CONCURRENT_WRITES_END();
+}
+const ::google::protobuf::Descriptor* ServerReflectionRequest::descriptor() {
+  protobuf_AssignDescriptorsOnce();
+  return ServerReflectionRequest_descriptor_;
+}
+
+const ServerReflectionRequest& ServerReflectionRequest::default_instance() {
+  if (default_instance_ == NULL) protobuf_AddDesc_reflection_2eproto();
+  return *default_instance_;
+}
+
+ServerReflectionRequest* ServerReflectionRequest::default_instance_ = NULL;
+
+ServerReflectionRequest* ServerReflectionRequest::New(::google::protobuf::Arena* arena) const {
+  ServerReflectionRequest* n = new ServerReflectionRequest;
+  if (arena != NULL) {
+    arena->Own(n);
+  }
+  return n;
+}
+
+void ServerReflectionRequest::clear_message_request() {
+// @@protoc_insertion_point(one_of_clear_start:grpc.reflection.v1alpha.ServerReflectionRequest)
+  switch(message_request_case()) {
+    case kFileByFilename: {
+      message_request_.file_by_filename_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+      break;
+    }
+    case kFileContainingSymbol: {
+      message_request_.file_containing_symbol_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+      break;
+    }
+    case kFileContainingExtension: {
+      delete message_request_.file_containing_extension_;
+      break;
+    }
+    case kAllExtensionNumbersOfType: {
+      message_request_.all_extension_numbers_of_type_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+      break;
+    }
+    case kListServices: {
+      message_request_.list_services_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+      break;
+    }
+    case MESSAGE_REQUEST_NOT_SET: {
+      break;
+    }
+  }
+  _oneof_case_[0] = MESSAGE_REQUEST_NOT_SET;
+}
+
+
+void ServerReflectionRequest::Clear() {
+// @@protoc_insertion_point(message_clear_start:grpc.reflection.v1alpha.ServerReflectionRequest)
+  host_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  clear_message_request();
+}
+
+bool ServerReflectionRequest::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:grpc.reflection.v1alpha.ServerReflectionRequest)
+  for (;;) {
+    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // optional string host = 1;
+      case 1: {
+        if (tag == 10) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_host()));
+          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+            this->host().data(), this->host().length(),
+            ::google::protobuf::internal::WireFormatLite::PARSE,
+            "grpc.reflection.v1alpha.ServerReflectionRequest.host"));
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(26)) goto parse_file_by_filename;
+        break;
+      }
+
+      // optional string file_by_filename = 3;
+      case 3: {
+        if (tag == 26) {
+         parse_file_by_filename:
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_file_by_filename()));
+          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+            this->file_by_filename().data(), this->file_by_filename().length(),
+            ::google::protobuf::internal::WireFormatLite::PARSE,
+            "grpc.reflection.v1alpha.ServerReflectionRequest.file_by_filename"));
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(34)) goto parse_file_containing_symbol;
+        break;
+      }
+
+      // optional string file_containing_symbol = 4;
+      case 4: {
+        if (tag == 34) {
+         parse_file_containing_symbol:
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_file_containing_symbol()));
+          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+            this->file_containing_symbol().data(), this->file_containing_symbol().length(),
+            ::google::protobuf::internal::WireFormatLite::PARSE,
+            "grpc.reflection.v1alpha.ServerReflectionRequest.file_containing_symbol"));
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(42)) goto parse_file_containing_extension;
+        break;
+      }
+
+      // optional .grpc.reflection.v1alpha.ExtensionRequest file_containing_extension = 5;
+      case 5: {
+        if (tag == 42) {
+         parse_file_containing_extension:
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
+               input, mutable_file_containing_extension()));
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(50)) goto parse_all_extension_numbers_of_type;
+        break;
+      }
+
+      // optional string all_extension_numbers_of_type = 6;
+      case 6: {
+        if (tag == 50) {
+         parse_all_extension_numbers_of_type:
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_all_extension_numbers_of_type()));
+          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+            this->all_extension_numbers_of_type().data(), this->all_extension_numbers_of_type().length(),
+            ::google::protobuf::internal::WireFormatLite::PARSE,
+            "grpc.reflection.v1alpha.ServerReflectionRequest.all_extension_numbers_of_type"));
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(58)) goto parse_list_services;
+        break;
+      }
+
+      // optional string list_services = 7;
+      case 7: {
+        if (tag == 58) {
+         parse_list_services:
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_list_services()));
+          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+            this->list_services().data(), this->list_services().length(),
+            ::google::protobuf::internal::WireFormatLite::PARSE,
+            "grpc.reflection.v1alpha.ServerReflectionRequest.list_services"));
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectAtEnd()) goto success;
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0 ||
+            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:grpc.reflection.v1alpha.ServerReflectionRequest)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:grpc.reflection.v1alpha.ServerReflectionRequest)
+  return false;
+#undef DO_
+}
+
+void ServerReflectionRequest::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:grpc.reflection.v1alpha.ServerReflectionRequest)
+  // optional string host = 1;
+  if (this->host().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->host().data(), this->host().length(),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "grpc.reflection.v1alpha.ServerReflectionRequest.host");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      1, this->host(), output);
+  }
+
+  // optional string file_by_filename = 3;
+  if (has_file_by_filename()) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->file_by_filename().data(), this->file_by_filename().length(),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "grpc.reflection.v1alpha.ServerReflectionRequest.file_by_filename");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      3, this->file_by_filename(), output);
+  }
+
+  // optional string file_containing_symbol = 4;
+  if (has_file_containing_symbol()) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->file_containing_symbol().data(), this->file_containing_symbol().length(),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "grpc.reflection.v1alpha.ServerReflectionRequest.file_containing_symbol");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      4, this->file_containing_symbol(), output);
+  }
+
+  // optional .grpc.reflection.v1alpha.ExtensionRequest file_containing_extension = 5;
+  if (has_file_containing_extension()) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      5, *message_request_.file_containing_extension_, output);
+  }
+
+  // optional string all_extension_numbers_of_type = 6;
+  if (has_all_extension_numbers_of_type()) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->all_extension_numbers_of_type().data(), this->all_extension_numbers_of_type().length(),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "grpc.reflection.v1alpha.ServerReflectionRequest.all_extension_numbers_of_type");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      6, this->all_extension_numbers_of_type(), output);
+  }
+
+  // optional string list_services = 7;
+  if (has_list_services()) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->list_services().data(), this->list_services().length(),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "grpc.reflection.v1alpha.ServerReflectionRequest.list_services");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      7, this->list_services(), output);
+  }
+
+  // @@protoc_insertion_point(serialize_end:grpc.reflection.v1alpha.ServerReflectionRequest)
+}
+
+::google::protobuf::uint8* ServerReflectionRequest::SerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:grpc.reflection.v1alpha.ServerReflectionRequest)
+  // optional string host = 1;
+  if (this->host().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->host().data(), this->host().length(),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "grpc.reflection.v1alpha.ServerReflectionRequest.host");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        1, this->host(), target);
+  }
+
+  // optional string file_by_filename = 3;
+  if (has_file_by_filename()) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->file_by_filename().data(), this->file_by_filename().length(),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "grpc.reflection.v1alpha.ServerReflectionRequest.file_by_filename");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        3, this->file_by_filename(), target);
+  }
+
+  // optional string file_containing_symbol = 4;
+  if (has_file_containing_symbol()) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->file_containing_symbol().data(), this->file_containing_symbol().length(),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "grpc.reflection.v1alpha.ServerReflectionRequest.file_containing_symbol");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        4, this->file_containing_symbol(), target);
+  }
+
+  // optional .grpc.reflection.v1alpha.ExtensionRequest file_containing_extension = 5;
+  if (has_file_containing_extension()) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      WriteMessageNoVirtualToArray(
+        5, *message_request_.file_containing_extension_, target);
+  }
+
+  // optional string all_extension_numbers_of_type = 6;
+  if (has_all_extension_numbers_of_type()) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->all_extension_numbers_of_type().data(), this->all_extension_numbers_of_type().length(),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "grpc.reflection.v1alpha.ServerReflectionRequest.all_extension_numbers_of_type");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        6, this->all_extension_numbers_of_type(), target);
+  }
+
+  // optional string list_services = 7;
+  if (has_list_services()) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->list_services().data(), this->list_services().length(),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "grpc.reflection.v1alpha.ServerReflectionRequest.list_services");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        7, this->list_services(), target);
+  }
+
+  // @@protoc_insertion_point(serialize_to_array_end:grpc.reflection.v1alpha.ServerReflectionRequest)
+  return target;
+}
+
+int ServerReflectionRequest::ByteSize() const {
+// @@protoc_insertion_point(message_byte_size_start:grpc.reflection.v1alpha.ServerReflectionRequest)
+  int total_size = 0;
+
+  // optional string host = 1;
+  if (this->host().size() > 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::StringSize(
+        this->host());
+  }
+
+  switch (message_request_case()) {
+    // optional string file_by_filename = 3;
+    case kFileByFilename: {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormatLite::StringSize(
+          this->file_by_filename());
+      break;
+    }
+    // optional string file_containing_symbol = 4;
+    case kFileContainingSymbol: {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormatLite::StringSize(
+          this->file_containing_symbol());
+      break;
+    }
+    // optional .grpc.reflection.v1alpha.ExtensionRequest file_containing_extension = 5;
+    case kFileContainingExtension: {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
+          *message_request_.file_containing_extension_);
+      break;
+    }
+    // optional string all_extension_numbers_of_type = 6;
+    case kAllExtensionNumbersOfType: {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormatLite::StringSize(
+          this->all_extension_numbers_of_type());
+      break;
+    }
+    // optional string list_services = 7;
+    case kListServices: {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormatLite::StringSize(
+          this->list_services());
+      break;
+    }
+    case MESSAGE_REQUEST_NOT_SET: {
+      break;
+    }
+  }
+  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+  _cached_size_ = total_size;
+  GOOGLE_SAFE_CONCURRENT_WRITES_END();
+  return total_size;
+}
+
+void ServerReflectionRequest::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:grpc.reflection.v1alpha.ServerReflectionRequest)
+  if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+  const ServerReflectionRequest* source = 
+      ::google::protobuf::internal::DynamicCastToGenerated<const ServerReflectionRequest>(
+          &from);
+  if (source == NULL) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:grpc.reflection.v1alpha.ServerReflectionRequest)
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:grpc.reflection.v1alpha.ServerReflectionRequest)
+    MergeFrom(*source);
+  }
+}
+
+void ServerReflectionRequest::MergeFrom(const ServerReflectionRequest& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:grpc.reflection.v1alpha.ServerReflectionRequest)
+  if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+  switch (from.message_request_case()) {
+    case kFileByFilename: {
+      set_file_by_filename(from.file_by_filename());
+      break;
+    }
+    case kFileContainingSymbol: {
+      set_file_containing_symbol(from.file_containing_symbol());
+      break;
+    }
+    case kFileContainingExtension: {
+      mutable_file_containing_extension()->::grpc::reflection::v1alpha::ExtensionRequest::MergeFrom(from.file_containing_extension());
+      break;
+    }
+    case kAllExtensionNumbersOfType: {
+      set_all_extension_numbers_of_type(from.all_extension_numbers_of_type());
+      break;
+    }
+    case kListServices: {
+      set_list_services(from.list_services());
+      break;
+    }
+    case MESSAGE_REQUEST_NOT_SET: {
+      break;
+    }
+  }
+  if (from.host().size() > 0) {
+
+    host_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.host_);
+  }
+}
+
+void ServerReflectionRequest::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:grpc.reflection.v1alpha.ServerReflectionRequest)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void ServerReflectionRequest::CopyFrom(const ServerReflectionRequest& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:grpc.reflection.v1alpha.ServerReflectionRequest)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool ServerReflectionRequest::IsInitialized() const {
+
+  return true;
+}
+
+void ServerReflectionRequest::Swap(ServerReflectionRequest* other) {
+  if (other == this) return;
+  InternalSwap(other);
+}
+void ServerReflectionRequest::InternalSwap(ServerReflectionRequest* other) {
+  host_.Swap(&other->host_);
+  std::swap(message_request_, other->message_request_);
+  std::swap(_oneof_case_[0], other->_oneof_case_[0]);
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  std::swap(_cached_size_, other->_cached_size_);
+}
+
+::google::protobuf::Metadata ServerReflectionRequest::GetMetadata() const {
+  protobuf_AssignDescriptorsOnce();
+  ::google::protobuf::Metadata metadata;
+  metadata.descriptor = ServerReflectionRequest_descriptor_;
+  metadata.reflection = ServerReflectionRequest_reflection_;
+  return metadata;
+}
+
+#if PROTOBUF_INLINE_NOT_IN_HEADERS
+// ServerReflectionRequest
+
+// optional string host = 1;
+void ServerReflectionRequest::clear_host() {
+  host_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ const ::std::string& ServerReflectionRequest::host() const {
+  // @@protoc_insertion_point(field_get:grpc.reflection.v1alpha.ServerReflectionRequest.host)
+  return host_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ void ServerReflectionRequest::set_host(const ::std::string& value) {
+  
+  host_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:grpc.reflection.v1alpha.ServerReflectionRequest.host)
+}
+ void ServerReflectionRequest::set_host(const char* value) {
+  
+  host_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:grpc.reflection.v1alpha.ServerReflectionRequest.host)
+}
+ void ServerReflectionRequest::set_host(const char* value, size_t size) {
+  
+  host_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:grpc.reflection.v1alpha.ServerReflectionRequest.host)
+}
+ ::std::string* ServerReflectionRequest::mutable_host() {
+  
+  // @@protoc_insertion_point(field_mutable:grpc.reflection.v1alpha.ServerReflectionRequest.host)
+  return host_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ ::std::string* ServerReflectionRequest::release_host() {
+  // @@protoc_insertion_point(field_release:grpc.reflection.v1alpha.ServerReflectionRequest.host)
+  
+  return host_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ void ServerReflectionRequest::set_allocated_host(::std::string* host) {
+  if (host != NULL) {
+    
+  } else {
+    
+  }
+  host_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), host);
+  // @@protoc_insertion_point(field_set_allocated:grpc.reflection.v1alpha.ServerReflectionRequest.host)
+}
+
+// optional string file_by_filename = 3;
+bool ServerReflectionRequest::has_file_by_filename() const {
+  return message_request_case() == kFileByFilename;
+}
+void ServerReflectionRequest::set_has_file_by_filename() {
+  _oneof_case_[0] = kFileByFilename;
+}
+void ServerReflectionRequest::clear_file_by_filename() {
+  if (has_file_by_filename()) {
+    message_request_.file_by_filename_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+    clear_has_message_request();
+  }
+}
+ const ::std::string& ServerReflectionRequest::file_by_filename() const {
+  // @@protoc_insertion_point(field_get:grpc.reflection.v1alpha.ServerReflectionRequest.file_by_filename)
+  if (has_file_by_filename()) {
+    return message_request_.file_by_filename_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  }
+  return *&::google::protobuf::internal::GetEmptyStringAlreadyInited();
+}
+ void ServerReflectionRequest::set_file_by_filename(const ::std::string& value) {
+  // @@protoc_insertion_point(field_set:grpc.reflection.v1alpha.ServerReflectionRequest.file_by_filename)
+  if (!has_file_by_filename()) {
+    clear_message_request();
+    set_has_file_by_filename();
+    message_request_.file_by_filename_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  }
+  message_request_.file_by_filename_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:grpc.reflection.v1alpha.ServerReflectionRequest.file_by_filename)
+}
+ void ServerReflectionRequest::set_file_by_filename(const char* value) {
+  if (!has_file_by_filename()) {
+    clear_message_request();
+    set_has_file_by_filename();
+    message_request_.file_by_filename_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  }
+  message_request_.file_by_filename_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:grpc.reflection.v1alpha.ServerReflectionRequest.file_by_filename)
+}
+ void ServerReflectionRequest::set_file_by_filename(const char* value, size_t size) {
+  if (!has_file_by_filename()) {
+    clear_message_request();
+    set_has_file_by_filename();
+    message_request_.file_by_filename_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  }
+  message_request_.file_by_filename_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(
+      reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:grpc.reflection.v1alpha.ServerReflectionRequest.file_by_filename)
+}
+ ::std::string* ServerReflectionRequest::mutable_file_by_filename() {
+  if (!has_file_by_filename()) {
+    clear_message_request();
+    set_has_file_by_filename();
+    message_request_.file_by_filename_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  }
+  // @@protoc_insertion_point(field_mutable:grpc.reflection.v1alpha.ServerReflectionRequest.file_by_filename)
+  return message_request_.file_by_filename_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ ::std::string* ServerReflectionRequest::release_file_by_filename() {
+  // @@protoc_insertion_point(field_release:grpc.reflection.v1alpha.ServerReflectionRequest.file_by_filename)
+  if (has_file_by_filename()) {
+    clear_has_message_request();
+    return message_request_.file_by_filename_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  } else {
+    return NULL;
+  }
+}
+ void ServerReflectionRequest::set_allocated_file_by_filename(::std::string* file_by_filename) {
+  if (!has_file_by_filename()) {
+    message_request_.file_by_filename_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  }
+  clear_message_request();
+  if (file_by_filename != NULL) {
+    set_has_file_by_filename();
+    message_request_.file_by_filename_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+        file_by_filename);
+  }
+  // @@protoc_insertion_point(field_set_allocated:grpc.reflection.v1alpha.ServerReflectionRequest.file_by_filename)
+}
+
+// optional string file_containing_symbol = 4;
+bool ServerReflectionRequest::has_file_containing_symbol() const {
+  return message_request_case() == kFileContainingSymbol;
+}
+void ServerReflectionRequest::set_has_file_containing_symbol() {
+  _oneof_case_[0] = kFileContainingSymbol;
+}
+void ServerReflectionRequest::clear_file_containing_symbol() {
+  if (has_file_containing_symbol()) {
+    message_request_.file_containing_symbol_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+    clear_has_message_request();
+  }
+}
+ const ::std::string& ServerReflectionRequest::file_containing_symbol() const {
+  // @@protoc_insertion_point(field_get:grpc.reflection.v1alpha.ServerReflectionRequest.file_containing_symbol)
+  if (has_file_containing_symbol()) {
+    return message_request_.file_containing_symbol_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  }
+  return *&::google::protobuf::internal::GetEmptyStringAlreadyInited();
+}
+ void ServerReflectionRequest::set_file_containing_symbol(const ::std::string& value) {
+  // @@protoc_insertion_point(field_set:grpc.reflection.v1alpha.ServerReflectionRequest.file_containing_symbol)
+  if (!has_file_containing_symbol()) {
+    clear_message_request();
+    set_has_file_containing_symbol();
+    message_request_.file_containing_symbol_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  }
+  message_request_.file_containing_symbol_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:grpc.reflection.v1alpha.ServerReflectionRequest.file_containing_symbol)
+}
+ void ServerReflectionRequest::set_file_containing_symbol(const char* value) {
+  if (!has_file_containing_symbol()) {
+    clear_message_request();
+    set_has_file_containing_symbol();
+    message_request_.file_containing_symbol_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  }
+  message_request_.file_containing_symbol_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:grpc.reflection.v1alpha.ServerReflectionRequest.file_containing_symbol)
+}
+ void ServerReflectionRequest::set_file_containing_symbol(const char* value, size_t size) {
+  if (!has_file_containing_symbol()) {
+    clear_message_request();
+    set_has_file_containing_symbol();
+    message_request_.file_containing_symbol_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  }
+  message_request_.file_containing_symbol_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(
+      reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:grpc.reflection.v1alpha.ServerReflectionRequest.file_containing_symbol)
+}
+ ::std::string* ServerReflectionRequest::mutable_file_containing_symbol() {
+  if (!has_file_containing_symbol()) {
+    clear_message_request();
+    set_has_file_containing_symbol();
+    message_request_.file_containing_symbol_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  }
+  // @@protoc_insertion_point(field_mutable:grpc.reflection.v1alpha.ServerReflectionRequest.file_containing_symbol)
+  return message_request_.file_containing_symbol_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ ::std::string* ServerReflectionRequest::release_file_containing_symbol() {
+  // @@protoc_insertion_point(field_release:grpc.reflection.v1alpha.ServerReflectionRequest.file_containing_symbol)
+  if (has_file_containing_symbol()) {
+    clear_has_message_request();
+    return message_request_.file_containing_symbol_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  } else {
+    return NULL;
+  }
+}
+ void ServerReflectionRequest::set_allocated_file_containing_symbol(::std::string* file_containing_symbol) {
+  if (!has_file_containing_symbol()) {
+    message_request_.file_containing_symbol_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  }
+  clear_message_request();
+  if (file_containing_symbol != NULL) {
+    set_has_file_containing_symbol();
+    message_request_.file_containing_symbol_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+        file_containing_symbol);
+  }
+  // @@protoc_insertion_point(field_set_allocated:grpc.reflection.v1alpha.ServerReflectionRequest.file_containing_symbol)
+}
+
+// optional .grpc.reflection.v1alpha.ExtensionRequest file_containing_extension = 5;
+bool ServerReflectionRequest::has_file_containing_extension() const {
+  return message_request_case() == kFileContainingExtension;
+}
+void ServerReflectionRequest::set_has_file_containing_extension() {
+  _oneof_case_[0] = kFileContainingExtension;
+}
+void ServerReflectionRequest::clear_file_containing_extension() {
+  if (has_file_containing_extension()) {
+    delete message_request_.file_containing_extension_;
+    clear_has_message_request();
+  }
+}
+ const ::grpc::reflection::v1alpha::ExtensionRequest& ServerReflectionRequest::file_containing_extension() const {
+  // @@protoc_insertion_point(field_get:grpc.reflection.v1alpha.ServerReflectionRequest.file_containing_extension)
+  return has_file_containing_extension()
+      ? *message_request_.file_containing_extension_
+      : ::grpc::reflection::v1alpha::ExtensionRequest::default_instance();
+}
+::grpc::reflection::v1alpha::ExtensionRequest* ServerReflectionRequest::mutable_file_containing_extension() {
+  if (!has_file_containing_extension()) {
+    clear_message_request();
+    set_has_file_containing_extension();
+    message_request_.file_containing_extension_ = new ::grpc::reflection::v1alpha::ExtensionRequest;
+  }
+  // @@protoc_insertion_point(field_mutable:grpc.reflection.v1alpha.ServerReflectionRequest.file_containing_extension)
+  return message_request_.file_containing_extension_;
+}
+::grpc::reflection::v1alpha::ExtensionRequest* ServerReflectionRequest::release_file_containing_extension() {
+  // @@protoc_insertion_point(field_release:grpc.reflection.v1alpha.ServerReflectionRequest.file_containing_extension)
+  if (has_file_containing_extension()) {
+    clear_has_message_request();
+    ::grpc::reflection::v1alpha::ExtensionRequest* temp = message_request_.file_containing_extension_;
+    message_request_.file_containing_extension_ = NULL;
+    return temp;
+  } else {
+    return NULL;
+  }
+}
+void ServerReflectionRequest::set_allocated_file_containing_extension(::grpc::reflection::v1alpha::ExtensionRequest* file_containing_extension) {
+  clear_message_request();
+  if (file_containing_extension) {
+    set_has_file_containing_extension();
+    message_request_.file_containing_extension_ = file_containing_extension;
+  }
+  // @@protoc_insertion_point(field_set_allocated:grpc.reflection.v1alpha.ServerReflectionRequest.file_containing_extension)
+}
+
+// optional string all_extension_numbers_of_type = 6;
+bool ServerReflectionRequest::has_all_extension_numbers_of_type() const {
+  return message_request_case() == kAllExtensionNumbersOfType;
+}
+void ServerReflectionRequest::set_has_all_extension_numbers_of_type() {
+  _oneof_case_[0] = kAllExtensionNumbersOfType;
+}
+void ServerReflectionRequest::clear_all_extension_numbers_of_type() {
+  if (has_all_extension_numbers_of_type()) {
+    message_request_.all_extension_numbers_of_type_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+    clear_has_message_request();
+  }
+}
+ const ::std::string& ServerReflectionRequest::all_extension_numbers_of_type() const {
+  // @@protoc_insertion_point(field_get:grpc.reflection.v1alpha.ServerReflectionRequest.all_extension_numbers_of_type)
+  if (has_all_extension_numbers_of_type()) {
+    return message_request_.all_extension_numbers_of_type_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  }
+  return *&::google::protobuf::internal::GetEmptyStringAlreadyInited();
+}
+ void ServerReflectionRequest::set_all_extension_numbers_of_type(const ::std::string& value) {
+  // @@protoc_insertion_point(field_set:grpc.reflection.v1alpha.ServerReflectionRequest.all_extension_numbers_of_type)
+  if (!has_all_extension_numbers_of_type()) {
+    clear_message_request();
+    set_has_all_extension_numbers_of_type();
+    message_request_.all_extension_numbers_of_type_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  }
+  message_request_.all_extension_numbers_of_type_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:grpc.reflection.v1alpha.ServerReflectionRequest.all_extension_numbers_of_type)
+}
+ void ServerReflectionRequest::set_all_extension_numbers_of_type(const char* value) {
+  if (!has_all_extension_numbers_of_type()) {
+    clear_message_request();
+    set_has_all_extension_numbers_of_type();
+    message_request_.all_extension_numbers_of_type_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  }
+  message_request_.all_extension_numbers_of_type_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:grpc.reflection.v1alpha.ServerReflectionRequest.all_extension_numbers_of_type)
+}
+ void ServerReflectionRequest::set_all_extension_numbers_of_type(const char* value, size_t size) {
+  if (!has_all_extension_numbers_of_type()) {
+    clear_message_request();
+    set_has_all_extension_numbers_of_type();
+    message_request_.all_extension_numbers_of_type_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  }
+  message_request_.all_extension_numbers_of_type_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(
+      reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:grpc.reflection.v1alpha.ServerReflectionRequest.all_extension_numbers_of_type)
+}
+ ::std::string* ServerReflectionRequest::mutable_all_extension_numbers_of_type() {
+  if (!has_all_extension_numbers_of_type()) {
+    clear_message_request();
+    set_has_all_extension_numbers_of_type();
+    message_request_.all_extension_numbers_of_type_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  }
+  // @@protoc_insertion_point(field_mutable:grpc.reflection.v1alpha.ServerReflectionRequest.all_extension_numbers_of_type)
+  return message_request_.all_extension_numbers_of_type_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ ::std::string* ServerReflectionRequest::release_all_extension_numbers_of_type() {
+  // @@protoc_insertion_point(field_release:grpc.reflection.v1alpha.ServerReflectionRequest.all_extension_numbers_of_type)
+  if (has_all_extension_numbers_of_type()) {
+    clear_has_message_request();
+    return message_request_.all_extension_numbers_of_type_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  } else {
+    return NULL;
+  }
+}
+ void ServerReflectionRequest::set_allocated_all_extension_numbers_of_type(::std::string* all_extension_numbers_of_type) {
+  if (!has_all_extension_numbers_of_type()) {
+    message_request_.all_extension_numbers_of_type_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  }
+  clear_message_request();
+  if (all_extension_numbers_of_type != NULL) {
+    set_has_all_extension_numbers_of_type();
+    message_request_.all_extension_numbers_of_type_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+        all_extension_numbers_of_type);
+  }
+  // @@protoc_insertion_point(field_set_allocated:grpc.reflection.v1alpha.ServerReflectionRequest.all_extension_numbers_of_type)
+}
+
+// optional string list_services = 7;
+bool ServerReflectionRequest::has_list_services() const {
+  return message_request_case() == kListServices;
+}
+void ServerReflectionRequest::set_has_list_services() {
+  _oneof_case_[0] = kListServices;
+}
+void ServerReflectionRequest::clear_list_services() {
+  if (has_list_services()) {
+    message_request_.list_services_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+    clear_has_message_request();
+  }
+}
+ const ::std::string& ServerReflectionRequest::list_services() const {
+  // @@protoc_insertion_point(field_get:grpc.reflection.v1alpha.ServerReflectionRequest.list_services)
+  if (has_list_services()) {
+    return message_request_.list_services_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  }
+  return *&::google::protobuf::internal::GetEmptyStringAlreadyInited();
+}
+ void ServerReflectionRequest::set_list_services(const ::std::string& value) {
+  // @@protoc_insertion_point(field_set:grpc.reflection.v1alpha.ServerReflectionRequest.list_services)
+  if (!has_list_services()) {
+    clear_message_request();
+    set_has_list_services();
+    message_request_.list_services_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  }
+  message_request_.list_services_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:grpc.reflection.v1alpha.ServerReflectionRequest.list_services)
+}
+ void ServerReflectionRequest::set_list_services(const char* value) {
+  if (!has_list_services()) {
+    clear_message_request();
+    set_has_list_services();
+    message_request_.list_services_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  }
+  message_request_.list_services_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:grpc.reflection.v1alpha.ServerReflectionRequest.list_services)
+}
+ void ServerReflectionRequest::set_list_services(const char* value, size_t size) {
+  if (!has_list_services()) {
+    clear_message_request();
+    set_has_list_services();
+    message_request_.list_services_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  }
+  message_request_.list_services_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(
+      reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:grpc.reflection.v1alpha.ServerReflectionRequest.list_services)
+}
+ ::std::string* ServerReflectionRequest::mutable_list_services() {
+  if (!has_list_services()) {
+    clear_message_request();
+    set_has_list_services();
+    message_request_.list_services_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  }
+  // @@protoc_insertion_point(field_mutable:grpc.reflection.v1alpha.ServerReflectionRequest.list_services)
+  return message_request_.list_services_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ ::std::string* ServerReflectionRequest::release_list_services() {
+  // @@protoc_insertion_point(field_release:grpc.reflection.v1alpha.ServerReflectionRequest.list_services)
+  if (has_list_services()) {
+    clear_has_message_request();
+    return message_request_.list_services_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  } else {
+    return NULL;
+  }
+}
+ void ServerReflectionRequest::set_allocated_list_services(::std::string* list_services) {
+  if (!has_list_services()) {
+    message_request_.list_services_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  }
+  clear_message_request();
+  if (list_services != NULL) {
+    set_has_list_services();
+    message_request_.list_services_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+        list_services);
+  }
+  // @@protoc_insertion_point(field_set_allocated:grpc.reflection.v1alpha.ServerReflectionRequest.list_services)
+}
+
+bool ServerReflectionRequest::has_message_request() const {
+  return message_request_case() != MESSAGE_REQUEST_NOT_SET;
+}
+void ServerReflectionRequest::clear_has_message_request() {
+  _oneof_case_[0] = MESSAGE_REQUEST_NOT_SET;
+}
+ServerReflectionRequest::MessageRequestCase ServerReflectionRequest::message_request_case() const {
+  return ServerReflectionRequest::MessageRequestCase(_oneof_case_[0]);
+}
+#endif  // PROTOBUF_INLINE_NOT_IN_HEADERS
+
+// ===================================================================
+
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int ExtensionRequest::kContainingTypeFieldNumber;
+const int ExtensionRequest::kExtensionNumberFieldNumber;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+ExtensionRequest::ExtensionRequest()
+  : ::google::protobuf::Message(), _internal_metadata_(NULL) {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:grpc.reflection.v1alpha.ExtensionRequest)
+}
+
+void ExtensionRequest::InitAsDefaultInstance() {
+  _is_default_instance_ = true;
+}
+
+ExtensionRequest::ExtensionRequest(const ExtensionRequest& from)
+  : ::google::protobuf::Message(),
+    _internal_metadata_(NULL) {
+  SharedCtor();
+  MergeFrom(from);
+  // @@protoc_insertion_point(copy_constructor:grpc.reflection.v1alpha.ExtensionRequest)
+}
+
+void ExtensionRequest::SharedCtor() {
+    _is_default_instance_ = false;
+  ::google::protobuf::internal::GetEmptyString();
+  _cached_size_ = 0;
+  containing_type_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  extension_number_ = 0;
+}
+
+ExtensionRequest::~ExtensionRequest() {
+  // @@protoc_insertion_point(destructor:grpc.reflection.v1alpha.ExtensionRequest)
+  SharedDtor();
+}
+
+void ExtensionRequest::SharedDtor() {
+  containing_type_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (this != default_instance_) {
+  }
+}
+
+void ExtensionRequest::SetCachedSize(int size) const {
+  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+  _cached_size_ = size;
+  GOOGLE_SAFE_CONCURRENT_WRITES_END();
+}
+const ::google::protobuf::Descriptor* ExtensionRequest::descriptor() {
+  protobuf_AssignDescriptorsOnce();
+  return ExtensionRequest_descriptor_;
+}
+
+const ExtensionRequest& ExtensionRequest::default_instance() {
+  if (default_instance_ == NULL) protobuf_AddDesc_reflection_2eproto();
+  return *default_instance_;
+}
+
+ExtensionRequest* ExtensionRequest::default_instance_ = NULL;
+
+ExtensionRequest* ExtensionRequest::New(::google::protobuf::Arena* arena) const {
+  ExtensionRequest* n = new ExtensionRequest;
+  if (arena != NULL) {
+    arena->Own(n);
+  }
+  return n;
+}
+
+void ExtensionRequest::Clear() {
+// @@protoc_insertion_point(message_clear_start:grpc.reflection.v1alpha.ExtensionRequest)
+  containing_type_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  extension_number_ = 0;
+}
+
+bool ExtensionRequest::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:grpc.reflection.v1alpha.ExtensionRequest)
+  for (;;) {
+    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // optional string containing_type = 1;
+      case 1: {
+        if (tag == 10) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_containing_type()));
+          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+            this->containing_type().data(), this->containing_type().length(),
+            ::google::protobuf::internal::WireFormatLite::PARSE,
+            "grpc.reflection.v1alpha.ExtensionRequest.containing_type"));
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(16)) goto parse_extension_number;
+        break;
+      }
+
+      // optional int32 extension_number = 2;
+      case 2: {
+        if (tag == 16) {
+         parse_extension_number:
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
+                 input, &extension_number_)));
+
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectAtEnd()) goto success;
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0 ||
+            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:grpc.reflection.v1alpha.ExtensionRequest)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:grpc.reflection.v1alpha.ExtensionRequest)
+  return false;
+#undef DO_
+}
+
+void ExtensionRequest::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:grpc.reflection.v1alpha.ExtensionRequest)
+  // optional string containing_type = 1;
+  if (this->containing_type().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->containing_type().data(), this->containing_type().length(),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "grpc.reflection.v1alpha.ExtensionRequest.containing_type");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      1, this->containing_type(), output);
+  }
+
+  // optional int32 extension_number = 2;
+  if (this->extension_number() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteInt32(2, this->extension_number(), output);
+  }
+
+  // @@protoc_insertion_point(serialize_end:grpc.reflection.v1alpha.ExtensionRequest)
+}
+
+::google::protobuf::uint8* ExtensionRequest::SerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:grpc.reflection.v1alpha.ExtensionRequest)
+  // optional string containing_type = 1;
+  if (this->containing_type().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->containing_type().data(), this->containing_type().length(),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "grpc.reflection.v1alpha.ExtensionRequest.containing_type");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        1, this->containing_type(), target);
+  }
+
+  // optional int32 extension_number = 2;
+  if (this->extension_number() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(2, this->extension_number(), target);
+  }
+
+  // @@protoc_insertion_point(serialize_to_array_end:grpc.reflection.v1alpha.ExtensionRequest)
+  return target;
+}
+
+int ExtensionRequest::ByteSize() const {
+// @@protoc_insertion_point(message_byte_size_start:grpc.reflection.v1alpha.ExtensionRequest)
+  int total_size = 0;
+
+  // optional string containing_type = 1;
+  if (this->containing_type().size() > 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::StringSize(
+        this->containing_type());
+  }
+
+  // optional int32 extension_number = 2;
+  if (this->extension_number() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::Int32Size(
+        this->extension_number());
+  }
+
+  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+  _cached_size_ = total_size;
+  GOOGLE_SAFE_CONCURRENT_WRITES_END();
+  return total_size;
+}
+
+void ExtensionRequest::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:grpc.reflection.v1alpha.ExtensionRequest)
+  if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+  const ExtensionRequest* source = 
+      ::google::protobuf::internal::DynamicCastToGenerated<const ExtensionRequest>(
+          &from);
+  if (source == NULL) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:grpc.reflection.v1alpha.ExtensionRequest)
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:grpc.reflection.v1alpha.ExtensionRequest)
+    MergeFrom(*source);
+  }
+}
+
+void ExtensionRequest::MergeFrom(const ExtensionRequest& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:grpc.reflection.v1alpha.ExtensionRequest)
+  if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+  if (from.containing_type().size() > 0) {
+
+    containing_type_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.containing_type_);
+  }
+  if (from.extension_number() != 0) {
+    set_extension_number(from.extension_number());
+  }
+}
+
+void ExtensionRequest::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:grpc.reflection.v1alpha.ExtensionRequest)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void ExtensionRequest::CopyFrom(const ExtensionRequest& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:grpc.reflection.v1alpha.ExtensionRequest)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool ExtensionRequest::IsInitialized() const {
+
+  return true;
+}
+
+void ExtensionRequest::Swap(ExtensionRequest* other) {
+  if (other == this) return;
+  InternalSwap(other);
+}
+void ExtensionRequest::InternalSwap(ExtensionRequest* other) {
+  containing_type_.Swap(&other->containing_type_);
+  std::swap(extension_number_, other->extension_number_);
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  std::swap(_cached_size_, other->_cached_size_);
+}
+
+::google::protobuf::Metadata ExtensionRequest::GetMetadata() const {
+  protobuf_AssignDescriptorsOnce();
+  ::google::protobuf::Metadata metadata;
+  metadata.descriptor = ExtensionRequest_descriptor_;
+  metadata.reflection = ExtensionRequest_reflection_;
+  return metadata;
+}
+
+#if PROTOBUF_INLINE_NOT_IN_HEADERS
+// ExtensionRequest
+
+// optional string containing_type = 1;
+void ExtensionRequest::clear_containing_type() {
+  containing_type_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ const ::std::string& ExtensionRequest::containing_type() const {
+  // @@protoc_insertion_point(field_get:grpc.reflection.v1alpha.ExtensionRequest.containing_type)
+  return containing_type_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ void ExtensionRequest::set_containing_type(const ::std::string& value) {
+  
+  containing_type_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:grpc.reflection.v1alpha.ExtensionRequest.containing_type)
+}
+ void ExtensionRequest::set_containing_type(const char* value) {
+  
+  containing_type_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:grpc.reflection.v1alpha.ExtensionRequest.containing_type)
+}
+ void ExtensionRequest::set_containing_type(const char* value, size_t size) {
+  
+  containing_type_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:grpc.reflection.v1alpha.ExtensionRequest.containing_type)
+}
+ ::std::string* ExtensionRequest::mutable_containing_type() {
+  
+  // @@protoc_insertion_point(field_mutable:grpc.reflection.v1alpha.ExtensionRequest.containing_type)
+  return containing_type_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ ::std::string* ExtensionRequest::release_containing_type() {
+  // @@protoc_insertion_point(field_release:grpc.reflection.v1alpha.ExtensionRequest.containing_type)
+  
+  return containing_type_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ void ExtensionRequest::set_allocated_containing_type(::std::string* containing_type) {
+  if (containing_type != NULL) {
+    
+  } else {
+    
+  }
+  containing_type_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), containing_type);
+  // @@protoc_insertion_point(field_set_allocated:grpc.reflection.v1alpha.ExtensionRequest.containing_type)
+}
+
+// optional int32 extension_number = 2;
+void ExtensionRequest::clear_extension_number() {
+  extension_number_ = 0;
+}
+ ::google::protobuf::int32 ExtensionRequest::extension_number() const {
+  // @@protoc_insertion_point(field_get:grpc.reflection.v1alpha.ExtensionRequest.extension_number)
+  return extension_number_;
+}
+ void ExtensionRequest::set_extension_number(::google::protobuf::int32 value) {
+  
+  extension_number_ = value;
+  // @@protoc_insertion_point(field_set:grpc.reflection.v1alpha.ExtensionRequest.extension_number)
+}
+
+#endif  // PROTOBUF_INLINE_NOT_IN_HEADERS
+
+// ===================================================================
+
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int ServerReflectionResponse::kValidHostFieldNumber;
+const int ServerReflectionResponse::kOriginalRequestFieldNumber;
+const int ServerReflectionResponse::kFileDescriptorResponseFieldNumber;
+const int ServerReflectionResponse::kAllExtensionNumbersResponseFieldNumber;
+const int ServerReflectionResponse::kListServicesResponseFieldNumber;
+const int ServerReflectionResponse::kErrorResponseFieldNumber;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+ServerReflectionResponse::ServerReflectionResponse()
+  : ::google::protobuf::Message(), _internal_metadata_(NULL) {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:grpc.reflection.v1alpha.ServerReflectionResponse)
+}
+
+void ServerReflectionResponse::InitAsDefaultInstance() {
+  _is_default_instance_ = true;
+  original_request_ = const_cast< ::grpc::reflection::v1alpha::ServerReflectionRequest*>(&::grpc::reflection::v1alpha::ServerReflectionRequest::default_instance());
+  ServerReflectionResponse_default_oneof_instance_->file_descriptor_response_ = const_cast< ::grpc::reflection::v1alpha::FileDescriptorResponse*>(&::grpc::reflection::v1alpha::FileDescriptorResponse::default_instance());
+  ServerReflectionResponse_default_oneof_instance_->all_extension_numbers_response_ = const_cast< ::grpc::reflection::v1alpha::ExtensionNumberResponse*>(&::grpc::reflection::v1alpha::ExtensionNumberResponse::default_instance());
+  ServerReflectionResponse_default_oneof_instance_->list_services_response_ = const_cast< ::grpc::reflection::v1alpha::ListServiceResponse*>(&::grpc::reflection::v1alpha::ListServiceResponse::default_instance());
+  ServerReflectionResponse_default_oneof_instance_->error_response_ = const_cast< ::grpc::reflection::v1alpha::ErrorResponse*>(&::grpc::reflection::v1alpha::ErrorResponse::default_instance());
+}
+
+ServerReflectionResponse::ServerReflectionResponse(const ServerReflectionResponse& from)
+  : ::google::protobuf::Message(),
+    _internal_metadata_(NULL) {
+  SharedCtor();
+  MergeFrom(from);
+  // @@protoc_insertion_point(copy_constructor:grpc.reflection.v1alpha.ServerReflectionResponse)
+}
+
+void ServerReflectionResponse::SharedCtor() {
+    _is_default_instance_ = false;
+  ::google::protobuf::internal::GetEmptyString();
+  _cached_size_ = 0;
+  valid_host_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  original_request_ = NULL;
+  clear_has_message_response();
+}
+
+ServerReflectionResponse::~ServerReflectionResponse() {
+  // @@protoc_insertion_point(destructor:grpc.reflection.v1alpha.ServerReflectionResponse)
+  SharedDtor();
+}
+
+void ServerReflectionResponse::SharedDtor() {
+  valid_host_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (has_message_response()) {
+    clear_message_response();
+  }
+  if (this != default_instance_) {
+    delete original_request_;
+  }
+}
+
+void ServerReflectionResponse::SetCachedSize(int size) const {
+  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+  _cached_size_ = size;
+  GOOGLE_SAFE_CONCURRENT_WRITES_END();
+}
+const ::google::protobuf::Descriptor* ServerReflectionResponse::descriptor() {
+  protobuf_AssignDescriptorsOnce();
+  return ServerReflectionResponse_descriptor_;
+}
+
+const ServerReflectionResponse& ServerReflectionResponse::default_instance() {
+  if (default_instance_ == NULL) protobuf_AddDesc_reflection_2eproto();
+  return *default_instance_;
+}
+
+ServerReflectionResponse* ServerReflectionResponse::default_instance_ = NULL;
+
+ServerReflectionResponse* ServerReflectionResponse::New(::google::protobuf::Arena* arena) const {
+  ServerReflectionResponse* n = new ServerReflectionResponse;
+  if (arena != NULL) {
+    arena->Own(n);
+  }
+  return n;
+}
+
+void ServerReflectionResponse::clear_message_response() {
+// @@protoc_insertion_point(one_of_clear_start:grpc.reflection.v1alpha.ServerReflectionResponse)
+  switch(message_response_case()) {
+    case kFileDescriptorResponse: {
+      delete message_response_.file_descriptor_response_;
+      break;
+    }
+    case kAllExtensionNumbersResponse: {
+      delete message_response_.all_extension_numbers_response_;
+      break;
+    }
+    case kListServicesResponse: {
+      delete message_response_.list_services_response_;
+      break;
+    }
+    case kErrorResponse: {
+      delete message_response_.error_response_;
+      break;
+    }
+    case MESSAGE_RESPONSE_NOT_SET: {
+      break;
+    }
+  }
+  _oneof_case_[0] = MESSAGE_RESPONSE_NOT_SET;
+}
+
+
+void ServerReflectionResponse::Clear() {
+// @@protoc_insertion_point(message_clear_start:grpc.reflection.v1alpha.ServerReflectionResponse)
+  valid_host_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (GetArenaNoVirtual() == NULL && original_request_ != NULL) delete original_request_;
+  original_request_ = NULL;
+  clear_message_response();
+}
+
+bool ServerReflectionResponse::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:grpc.reflection.v1alpha.ServerReflectionResponse)
+  for (;;) {
+    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // optional string valid_host = 1;
+      case 1: {
+        if (tag == 10) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_valid_host()));
+          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+            this->valid_host().data(), this->valid_host().length(),
+            ::google::protobuf::internal::WireFormatLite::PARSE,
+            "grpc.reflection.v1alpha.ServerReflectionResponse.valid_host"));
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(18)) goto parse_original_request;
+        break;
+      }
+
+      // optional .grpc.reflection.v1alpha.ServerReflectionRequest original_request = 2;
+      case 2: {
+        if (tag == 18) {
+         parse_original_request:
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
+               input, mutable_original_request()));
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(34)) goto parse_file_descriptor_response;
+        break;
+      }
+
+      // optional .grpc.reflection.v1alpha.FileDescriptorResponse file_descriptor_response = 4;
+      case 4: {
+        if (tag == 34) {
+         parse_file_descriptor_response:
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
+               input, mutable_file_descriptor_response()));
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(42)) goto parse_all_extension_numbers_response;
+        break;
+      }
+
+      // optional .grpc.reflection.v1alpha.ExtensionNumberResponse all_extension_numbers_response = 5;
+      case 5: {
+        if (tag == 42) {
+         parse_all_extension_numbers_response:
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
+               input, mutable_all_extension_numbers_response()));
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(50)) goto parse_list_services_response;
+        break;
+      }
+
+      // optional .grpc.reflection.v1alpha.ListServiceResponse list_services_response = 6;
+      case 6: {
+        if (tag == 50) {
+         parse_list_services_response:
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
+               input, mutable_list_services_response()));
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(58)) goto parse_error_response;
+        break;
+      }
+
+      // optional .grpc.reflection.v1alpha.ErrorResponse error_response = 7;
+      case 7: {
+        if (tag == 58) {
+         parse_error_response:
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
+               input, mutable_error_response()));
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectAtEnd()) goto success;
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0 ||
+            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:grpc.reflection.v1alpha.ServerReflectionResponse)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:grpc.reflection.v1alpha.ServerReflectionResponse)
+  return false;
+#undef DO_
+}
+
+void ServerReflectionResponse::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:grpc.reflection.v1alpha.ServerReflectionResponse)
+  // optional string valid_host = 1;
+  if (this->valid_host().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->valid_host().data(), this->valid_host().length(),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "grpc.reflection.v1alpha.ServerReflectionResponse.valid_host");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      1, this->valid_host(), output);
+  }
+
+  // optional .grpc.reflection.v1alpha.ServerReflectionRequest original_request = 2;
+  if (this->has_original_request()) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      2, *this->original_request_, output);
+  }
+
+  // optional .grpc.reflection.v1alpha.FileDescriptorResponse file_descriptor_response = 4;
+  if (has_file_descriptor_response()) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      4, *message_response_.file_descriptor_response_, output);
+  }
+
+  // optional .grpc.reflection.v1alpha.ExtensionNumberResponse all_extension_numbers_response = 5;
+  if (has_all_extension_numbers_response()) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      5, *message_response_.all_extension_numbers_response_, output);
+  }
+
+  // optional .grpc.reflection.v1alpha.ListServiceResponse list_services_response = 6;
+  if (has_list_services_response()) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      6, *message_response_.list_services_response_, output);
+  }
+
+  // optional .grpc.reflection.v1alpha.ErrorResponse error_response = 7;
+  if (has_error_response()) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      7, *message_response_.error_response_, output);
+  }
+
+  // @@protoc_insertion_point(serialize_end:grpc.reflection.v1alpha.ServerReflectionResponse)
+}
+
+::google::protobuf::uint8* ServerReflectionResponse::SerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:grpc.reflection.v1alpha.ServerReflectionResponse)
+  // optional string valid_host = 1;
+  if (this->valid_host().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->valid_host().data(), this->valid_host().length(),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "grpc.reflection.v1alpha.ServerReflectionResponse.valid_host");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        1, this->valid_host(), target);
+  }
+
+  // optional .grpc.reflection.v1alpha.ServerReflectionRequest original_request = 2;
+  if (this->has_original_request()) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      WriteMessageNoVirtualToArray(
+        2, *this->original_request_, target);
+  }
+
+  // optional .grpc.reflection.v1alpha.FileDescriptorResponse file_descriptor_response = 4;
+  if (has_file_descriptor_response()) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      WriteMessageNoVirtualToArray(
+        4, *message_response_.file_descriptor_response_, target);
+  }
+
+  // optional .grpc.reflection.v1alpha.ExtensionNumberResponse all_extension_numbers_response = 5;
+  if (has_all_extension_numbers_response()) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      WriteMessageNoVirtualToArray(
+        5, *message_response_.all_extension_numbers_response_, target);
+  }
+
+  // optional .grpc.reflection.v1alpha.ListServiceResponse list_services_response = 6;
+  if (has_list_services_response()) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      WriteMessageNoVirtualToArray(
+        6, *message_response_.list_services_response_, target);
+  }
+
+  // optional .grpc.reflection.v1alpha.ErrorResponse error_response = 7;
+  if (has_error_response()) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      WriteMessageNoVirtualToArray(
+        7, *message_response_.error_response_, target);
+  }
+
+  // @@protoc_insertion_point(serialize_to_array_end:grpc.reflection.v1alpha.ServerReflectionResponse)
+  return target;
+}
+
+int ServerReflectionResponse::ByteSize() const {
+// @@protoc_insertion_point(message_byte_size_start:grpc.reflection.v1alpha.ServerReflectionResponse)
+  int total_size = 0;
+
+  // optional string valid_host = 1;
+  if (this->valid_host().size() > 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::StringSize(
+        this->valid_host());
+  }
+
+  // optional .grpc.reflection.v1alpha.ServerReflectionRequest original_request = 2;
+  if (this->has_original_request()) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
+        *this->original_request_);
+  }
+
+  switch (message_response_case()) {
+    // optional .grpc.reflection.v1alpha.FileDescriptorResponse file_descriptor_response = 4;
+    case kFileDescriptorResponse: {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
+          *message_response_.file_descriptor_response_);
+      break;
+    }
+    // optional .grpc.reflection.v1alpha.ExtensionNumberResponse all_extension_numbers_response = 5;
+    case kAllExtensionNumbersResponse: {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
+          *message_response_.all_extension_numbers_response_);
+      break;
+    }
+    // optional .grpc.reflection.v1alpha.ListServiceResponse list_services_response = 6;
+    case kListServicesResponse: {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
+          *message_response_.list_services_response_);
+      break;
+    }
+    // optional .grpc.reflection.v1alpha.ErrorResponse error_response = 7;
+    case kErrorResponse: {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
+          *message_response_.error_response_);
+      break;
+    }
+    case MESSAGE_RESPONSE_NOT_SET: {
+      break;
+    }
+  }
+  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+  _cached_size_ = total_size;
+  GOOGLE_SAFE_CONCURRENT_WRITES_END();
+  return total_size;
+}
+
+void ServerReflectionResponse::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:grpc.reflection.v1alpha.ServerReflectionResponse)
+  if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+  const ServerReflectionResponse* source = 
+      ::google::protobuf::internal::DynamicCastToGenerated<const ServerReflectionResponse>(
+          &from);
+  if (source == NULL) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:grpc.reflection.v1alpha.ServerReflectionResponse)
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:grpc.reflection.v1alpha.ServerReflectionResponse)
+    MergeFrom(*source);
+  }
+}
+
+void ServerReflectionResponse::MergeFrom(const ServerReflectionResponse& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:grpc.reflection.v1alpha.ServerReflectionResponse)
+  if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+  switch (from.message_response_case()) {
+    case kFileDescriptorResponse: {
+      mutable_file_descriptor_response()->::grpc::reflection::v1alpha::FileDescriptorResponse::MergeFrom(from.file_descriptor_response());
+      break;
+    }
+    case kAllExtensionNumbersResponse: {
+      mutable_all_extension_numbers_response()->::grpc::reflection::v1alpha::ExtensionNumberResponse::MergeFrom(from.all_extension_numbers_response());
+      break;
+    }
+    case kListServicesResponse: {
+      mutable_list_services_response()->::grpc::reflection::v1alpha::ListServiceResponse::MergeFrom(from.list_services_response());
+      break;
+    }
+    case kErrorResponse: {
+      mutable_error_response()->::grpc::reflection::v1alpha::ErrorResponse::MergeFrom(from.error_response());
+      break;
+    }
+    case MESSAGE_RESPONSE_NOT_SET: {
+      break;
+    }
+  }
+  if (from.valid_host().size() > 0) {
+
+    valid_host_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.valid_host_);
+  }
+  if (from.has_original_request()) {
+    mutable_original_request()->::grpc::reflection::v1alpha::ServerReflectionRequest::MergeFrom(from.original_request());
+  }
+}
+
+void ServerReflectionResponse::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:grpc.reflection.v1alpha.ServerReflectionResponse)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void ServerReflectionResponse::CopyFrom(const ServerReflectionResponse& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:grpc.reflection.v1alpha.ServerReflectionResponse)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool ServerReflectionResponse::IsInitialized() const {
+
+  return true;
+}
+
+void ServerReflectionResponse::Swap(ServerReflectionResponse* other) {
+  if (other == this) return;
+  InternalSwap(other);
+}
+void ServerReflectionResponse::InternalSwap(ServerReflectionResponse* other) {
+  valid_host_.Swap(&other->valid_host_);
+  std::swap(original_request_, other->original_request_);
+  std::swap(message_response_, other->message_response_);
+  std::swap(_oneof_case_[0], other->_oneof_case_[0]);
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  std::swap(_cached_size_, other->_cached_size_);
+}
+
+::google::protobuf::Metadata ServerReflectionResponse::GetMetadata() const {
+  protobuf_AssignDescriptorsOnce();
+  ::google::protobuf::Metadata metadata;
+  metadata.descriptor = ServerReflectionResponse_descriptor_;
+  metadata.reflection = ServerReflectionResponse_reflection_;
+  return metadata;
+}
+
+#if PROTOBUF_INLINE_NOT_IN_HEADERS
+// ServerReflectionResponse
+
+// optional string valid_host = 1;
+void ServerReflectionResponse::clear_valid_host() {
+  valid_host_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ const ::std::string& ServerReflectionResponse::valid_host() const {
+  // @@protoc_insertion_point(field_get:grpc.reflection.v1alpha.ServerReflectionResponse.valid_host)
+  return valid_host_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ void ServerReflectionResponse::set_valid_host(const ::std::string& value) {
+  
+  valid_host_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:grpc.reflection.v1alpha.ServerReflectionResponse.valid_host)
+}
+ void ServerReflectionResponse::set_valid_host(const char* value) {
+  
+  valid_host_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:grpc.reflection.v1alpha.ServerReflectionResponse.valid_host)
+}
+ void ServerReflectionResponse::set_valid_host(const char* value, size_t size) {
+  
+  valid_host_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:grpc.reflection.v1alpha.ServerReflectionResponse.valid_host)
+}
+ ::std::string* ServerReflectionResponse::mutable_valid_host() {
+  
+  // @@protoc_insertion_point(field_mutable:grpc.reflection.v1alpha.ServerReflectionResponse.valid_host)
+  return valid_host_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ ::std::string* ServerReflectionResponse::release_valid_host() {
+  // @@protoc_insertion_point(field_release:grpc.reflection.v1alpha.ServerReflectionResponse.valid_host)
+  
+  return valid_host_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ void ServerReflectionResponse::set_allocated_valid_host(::std::string* valid_host) {
+  if (valid_host != NULL) {
+    
+  } else {
+    
+  }
+  valid_host_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), valid_host);
+  // @@protoc_insertion_point(field_set_allocated:grpc.reflection.v1alpha.ServerReflectionResponse.valid_host)
+}
+
+// optional .grpc.reflection.v1alpha.ServerReflectionRequest original_request = 2;
+bool ServerReflectionResponse::has_original_request() const {
+  return !_is_default_instance_ && original_request_ != NULL;
+}
+void ServerReflectionResponse::clear_original_request() {
+  if (GetArenaNoVirtual() == NULL && original_request_ != NULL) delete original_request_;
+  original_request_ = NULL;
+}
+const ::grpc::reflection::v1alpha::ServerReflectionRequest& ServerReflectionResponse::original_request() const {
+  // @@protoc_insertion_point(field_get:grpc.reflection.v1alpha.ServerReflectionResponse.original_request)
+  return original_request_ != NULL ? *original_request_ : *default_instance_->original_request_;
+}
+::grpc::reflection::v1alpha::ServerReflectionRequest* ServerReflectionResponse::mutable_original_request() {
+  
+  if (original_request_ == NULL) {
+    original_request_ = new ::grpc::reflection::v1alpha::ServerReflectionRequest;
+  }
+  // @@protoc_insertion_point(field_mutable:grpc.reflection.v1alpha.ServerReflectionResponse.original_request)
+  return original_request_;
+}
+::grpc::reflection::v1alpha::ServerReflectionRequest* ServerReflectionResponse::release_original_request() {
+  // @@protoc_insertion_point(field_release:grpc.reflection.v1alpha.ServerReflectionResponse.original_request)
+  
+  ::grpc::reflection::v1alpha::ServerReflectionRequest* temp = original_request_;
+  original_request_ = NULL;
+  return temp;
+}
+void ServerReflectionResponse::set_allocated_original_request(::grpc::reflection::v1alpha::ServerReflectionRequest* original_request) {
+  delete original_request_;
+  original_request_ = original_request;
+  if (original_request) {
+    
+  } else {
+    
+  }
+  // @@protoc_insertion_point(field_set_allocated:grpc.reflection.v1alpha.ServerReflectionResponse.original_request)
+}
+
+// optional .grpc.reflection.v1alpha.FileDescriptorResponse file_descriptor_response = 4;
+bool ServerReflectionResponse::has_file_descriptor_response() const {
+  return message_response_case() == kFileDescriptorResponse;
+}
+void ServerReflectionResponse::set_has_file_descriptor_response() {
+  _oneof_case_[0] = kFileDescriptorResponse;
+}
+void ServerReflectionResponse::clear_file_descriptor_response() {
+  if (has_file_descriptor_response()) {
+    delete message_response_.file_descriptor_response_;
+    clear_has_message_response();
+  }
+}
+ const ::grpc::reflection::v1alpha::FileDescriptorResponse& ServerReflectionResponse::file_descriptor_response() const {
+  // @@protoc_insertion_point(field_get:grpc.reflection.v1alpha.ServerReflectionResponse.file_descriptor_response)
+  return has_file_descriptor_response()
+      ? *message_response_.file_descriptor_response_
+      : ::grpc::reflection::v1alpha::FileDescriptorResponse::default_instance();
+}
+::grpc::reflection::v1alpha::FileDescriptorResponse* ServerReflectionResponse::mutable_file_descriptor_response() {
+  if (!has_file_descriptor_response()) {
+    clear_message_response();
+    set_has_file_descriptor_response();
+    message_response_.file_descriptor_response_ = new ::grpc::reflection::v1alpha::FileDescriptorResponse;
+  }
+  // @@protoc_insertion_point(field_mutable:grpc.reflection.v1alpha.ServerReflectionResponse.file_descriptor_response)
+  return message_response_.file_descriptor_response_;
+}
+::grpc::reflection::v1alpha::FileDescriptorResponse* ServerReflectionResponse::release_file_descriptor_response() {
+  // @@protoc_insertion_point(field_release:grpc.reflection.v1alpha.ServerReflectionResponse.file_descriptor_response)
+  if (has_file_descriptor_response()) {
+    clear_has_message_response();
+    ::grpc::reflection::v1alpha::FileDescriptorResponse* temp = message_response_.file_descriptor_response_;
+    message_response_.file_descriptor_response_ = NULL;
+    return temp;
+  } else {
+    return NULL;
+  }
+}
+void ServerReflectionResponse::set_allocated_file_descriptor_response(::grpc::reflection::v1alpha::FileDescriptorResponse* file_descriptor_response) {
+  clear_message_response();
+  if (file_descriptor_response) {
+    set_has_file_descriptor_response();
+    message_response_.file_descriptor_response_ = file_descriptor_response;
+  }
+  // @@protoc_insertion_point(field_set_allocated:grpc.reflection.v1alpha.ServerReflectionResponse.file_descriptor_response)
+}
+
+// optional .grpc.reflection.v1alpha.ExtensionNumberResponse all_extension_numbers_response = 5;
+bool ServerReflectionResponse::has_all_extension_numbers_response() const {
+  return message_response_case() == kAllExtensionNumbersResponse;
+}
+void ServerReflectionResponse::set_has_all_extension_numbers_response() {
+  _oneof_case_[0] = kAllExtensionNumbersResponse;
+}
+void ServerReflectionResponse::clear_all_extension_numbers_response() {
+  if (has_all_extension_numbers_response()) {
+    delete message_response_.all_extension_numbers_response_;
+    clear_has_message_response();
+  }
+}
+ const ::grpc::reflection::v1alpha::ExtensionNumberResponse& ServerReflectionResponse::all_extension_numbers_response() const {
+  // @@protoc_insertion_point(field_get:grpc.reflection.v1alpha.ServerReflectionResponse.all_extension_numbers_response)
+  return has_all_extension_numbers_response()
+      ? *message_response_.all_extension_numbers_response_
+      : ::grpc::reflection::v1alpha::ExtensionNumberResponse::default_instance();
+}
+::grpc::reflection::v1alpha::ExtensionNumberResponse* ServerReflectionResponse::mutable_all_extension_numbers_response() {
+  if (!has_all_extension_numbers_response()) {
+    clear_message_response();
+    set_has_all_extension_numbers_response();
+    message_response_.all_extension_numbers_response_ = new ::grpc::reflection::v1alpha::ExtensionNumberResponse;
+  }
+  // @@protoc_insertion_point(field_mutable:grpc.reflection.v1alpha.ServerReflectionResponse.all_extension_numbers_response)
+  return message_response_.all_extension_numbers_response_;
+}
+::grpc::reflection::v1alpha::ExtensionNumberResponse* ServerReflectionResponse::release_all_extension_numbers_response() {
+  // @@protoc_insertion_point(field_release:grpc.reflection.v1alpha.ServerReflectionResponse.all_extension_numbers_response)
+  if (has_all_extension_numbers_response()) {
+    clear_has_message_response();
+    ::grpc::reflection::v1alpha::ExtensionNumberResponse* temp = message_response_.all_extension_numbers_response_;
+    message_response_.all_extension_numbers_response_ = NULL;
+    return temp;
+  } else {
+    return NULL;
+  }
+}
+void ServerReflectionResponse::set_allocated_all_extension_numbers_response(::grpc::reflection::v1alpha::ExtensionNumberResponse* all_extension_numbers_response) {
+  clear_message_response();
+  if (all_extension_numbers_response) {
+    set_has_all_extension_numbers_response();
+    message_response_.all_extension_numbers_response_ = all_extension_numbers_response;
+  }
+  // @@protoc_insertion_point(field_set_allocated:grpc.reflection.v1alpha.ServerReflectionResponse.all_extension_numbers_response)
+}
+
+// optional .grpc.reflection.v1alpha.ListServiceResponse list_services_response = 6;
+bool ServerReflectionResponse::has_list_services_response() const {
+  return message_response_case() == kListServicesResponse;
+}
+void ServerReflectionResponse::set_has_list_services_response() {
+  _oneof_case_[0] = kListServicesResponse;
+}
+void ServerReflectionResponse::clear_list_services_response() {
+  if (has_list_services_response()) {
+    delete message_response_.list_services_response_;
+    clear_has_message_response();
+  }
+}
+ const ::grpc::reflection::v1alpha::ListServiceResponse& ServerReflectionResponse::list_services_response() const {
+  // @@protoc_insertion_point(field_get:grpc.reflection.v1alpha.ServerReflectionResponse.list_services_response)
+  return has_list_services_response()
+      ? *message_response_.list_services_response_
+      : ::grpc::reflection::v1alpha::ListServiceResponse::default_instance();
+}
+::grpc::reflection::v1alpha::ListServiceResponse* ServerReflectionResponse::mutable_list_services_response() {
+  if (!has_list_services_response()) {
+    clear_message_response();
+    set_has_list_services_response();
+    message_response_.list_services_response_ = new ::grpc::reflection::v1alpha::ListServiceResponse;
+  }
+  // @@protoc_insertion_point(field_mutable:grpc.reflection.v1alpha.ServerReflectionResponse.list_services_response)
+  return message_response_.list_services_response_;
+}
+::grpc::reflection::v1alpha::ListServiceResponse* ServerReflectionResponse::release_list_services_response() {
+  // @@protoc_insertion_point(field_release:grpc.reflection.v1alpha.ServerReflectionResponse.list_services_response)
+  if (has_list_services_response()) {
+    clear_has_message_response();
+    ::grpc::reflection::v1alpha::ListServiceResponse* temp = message_response_.list_services_response_;
+    message_response_.list_services_response_ = NULL;
+    return temp;
+  } else {
+    return NULL;
+  }
+}
+void ServerReflectionResponse::set_allocated_list_services_response(::grpc::reflection::v1alpha::ListServiceResponse* list_services_response) {
+  clear_message_response();
+  if (list_services_response) {
+    set_has_list_services_response();
+    message_response_.list_services_response_ = list_services_response;
+  }
+  // @@protoc_insertion_point(field_set_allocated:grpc.reflection.v1alpha.ServerReflectionResponse.list_services_response)
+}
+
+// optional .grpc.reflection.v1alpha.ErrorResponse error_response = 7;
+bool ServerReflectionResponse::has_error_response() const {
+  return message_response_case() == kErrorResponse;
+}
+void ServerReflectionResponse::set_has_error_response() {
+  _oneof_case_[0] = kErrorResponse;
+}
+void ServerReflectionResponse::clear_error_response() {
+  if (has_error_response()) {
+    delete message_response_.error_response_;
+    clear_has_message_response();
+  }
+}
+ const ::grpc::reflection::v1alpha::ErrorResponse& ServerReflectionResponse::error_response() const {
+  // @@protoc_insertion_point(field_get:grpc.reflection.v1alpha.ServerReflectionResponse.error_response)
+  return has_error_response()
+      ? *message_response_.error_response_
+      : ::grpc::reflection::v1alpha::ErrorResponse::default_instance();
+}
+::grpc::reflection::v1alpha::ErrorResponse* ServerReflectionResponse::mutable_error_response() {
+  if (!has_error_response()) {
+    clear_message_response();
+    set_has_error_response();
+    message_response_.error_response_ = new ::grpc::reflection::v1alpha::ErrorResponse;
+  }
+  // @@protoc_insertion_point(field_mutable:grpc.reflection.v1alpha.ServerReflectionResponse.error_response)
+  return message_response_.error_response_;
+}
+::grpc::reflection::v1alpha::ErrorResponse* ServerReflectionResponse::release_error_response() {
+  // @@protoc_insertion_point(field_release:grpc.reflection.v1alpha.ServerReflectionResponse.error_response)
+  if (has_error_response()) {
+    clear_has_message_response();
+    ::grpc::reflection::v1alpha::ErrorResponse* temp = message_response_.error_response_;
+    message_response_.error_response_ = NULL;
+    return temp;
+  } else {
+    return NULL;
+  }
+}
+void ServerReflectionResponse::set_allocated_error_response(::grpc::reflection::v1alpha::ErrorResponse* error_response) {
+  clear_message_response();
+  if (error_response) {
+    set_has_error_response();
+    message_response_.error_response_ = error_response;
+  }
+  // @@protoc_insertion_point(field_set_allocated:grpc.reflection.v1alpha.ServerReflectionResponse.error_response)
+}
+
+bool ServerReflectionResponse::has_message_response() const {
+  return message_response_case() != MESSAGE_RESPONSE_NOT_SET;
+}
+void ServerReflectionResponse::clear_has_message_response() {
+  _oneof_case_[0] = MESSAGE_RESPONSE_NOT_SET;
+}
+ServerReflectionResponse::MessageResponseCase ServerReflectionResponse::message_response_case() const {
+  return ServerReflectionResponse::MessageResponseCase(_oneof_case_[0]);
+}
+#endif  // PROTOBUF_INLINE_NOT_IN_HEADERS
+
+// ===================================================================
+
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int FileDescriptorResponse::kFileDescriptorProtoFieldNumber;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+FileDescriptorResponse::FileDescriptorResponse()
+  : ::google::protobuf::Message(), _internal_metadata_(NULL) {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:grpc.reflection.v1alpha.FileDescriptorResponse)
+}
+
+void FileDescriptorResponse::InitAsDefaultInstance() {
+  _is_default_instance_ = true;
+}
+
+FileDescriptorResponse::FileDescriptorResponse(const FileDescriptorResponse& from)
+  : ::google::protobuf::Message(),
+    _internal_metadata_(NULL) {
+  SharedCtor();
+  MergeFrom(from);
+  // @@protoc_insertion_point(copy_constructor:grpc.reflection.v1alpha.FileDescriptorResponse)
+}
+
+void FileDescriptorResponse::SharedCtor() {
+    _is_default_instance_ = false;
+  ::google::protobuf::internal::GetEmptyString();
+  _cached_size_ = 0;
+}
+
+FileDescriptorResponse::~FileDescriptorResponse() {
+  // @@protoc_insertion_point(destructor:grpc.reflection.v1alpha.FileDescriptorResponse)
+  SharedDtor();
+}
+
+void FileDescriptorResponse::SharedDtor() {
+  if (this != default_instance_) {
+  }
+}
+
+void FileDescriptorResponse::SetCachedSize(int size) const {
+  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+  _cached_size_ = size;
+  GOOGLE_SAFE_CONCURRENT_WRITES_END();
+}
+const ::google::protobuf::Descriptor* FileDescriptorResponse::descriptor() {
+  protobuf_AssignDescriptorsOnce();
+  return FileDescriptorResponse_descriptor_;
+}
+
+const FileDescriptorResponse& FileDescriptorResponse::default_instance() {
+  if (default_instance_ == NULL) protobuf_AddDesc_reflection_2eproto();
+  return *default_instance_;
+}
+
+FileDescriptorResponse* FileDescriptorResponse::default_instance_ = NULL;
+
+FileDescriptorResponse* FileDescriptorResponse::New(::google::protobuf::Arena* arena) const {
+  FileDescriptorResponse* n = new FileDescriptorResponse;
+  if (arena != NULL) {
+    arena->Own(n);
+  }
+  return n;
+}
+
+void FileDescriptorResponse::Clear() {
+// @@protoc_insertion_point(message_clear_start:grpc.reflection.v1alpha.FileDescriptorResponse)
+  file_descriptor_proto_.Clear();
+}
+
+bool FileDescriptorResponse::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:grpc.reflection.v1alpha.FileDescriptorResponse)
+  for (;;) {
+    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // repeated bytes file_descriptor_proto = 1;
+      case 1: {
+        if (tag == 10) {
+         parse_file_descriptor_proto:
+          DO_(::google::protobuf::internal::WireFormatLite::ReadBytes(
+                input, this->add_file_descriptor_proto()));
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(10)) goto parse_file_descriptor_proto;
+        if (input->ExpectAtEnd()) goto success;
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0 ||
+            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:grpc.reflection.v1alpha.FileDescriptorResponse)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:grpc.reflection.v1alpha.FileDescriptorResponse)
+  return false;
+#undef DO_
+}
+
+void FileDescriptorResponse::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:grpc.reflection.v1alpha.FileDescriptorResponse)
+  // repeated bytes file_descriptor_proto = 1;
+  for (int i = 0; i < this->file_descriptor_proto_size(); i++) {
+    ::google::protobuf::internal::WireFormatLite::WriteBytes(
+      1, this->file_descriptor_proto(i), output);
+  }
+
+  // @@protoc_insertion_point(serialize_end:grpc.reflection.v1alpha.FileDescriptorResponse)
+}
+
+::google::protobuf::uint8* FileDescriptorResponse::SerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:grpc.reflection.v1alpha.FileDescriptorResponse)
+  // repeated bytes file_descriptor_proto = 1;
+  for (int i = 0; i < this->file_descriptor_proto_size(); i++) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      WriteBytesToArray(1, this->file_descriptor_proto(i), target);
+  }
+
+  // @@protoc_insertion_point(serialize_to_array_end:grpc.reflection.v1alpha.FileDescriptorResponse)
+  return target;
+}
+
+int FileDescriptorResponse::ByteSize() const {
+// @@protoc_insertion_point(message_byte_size_start:grpc.reflection.v1alpha.FileDescriptorResponse)
+  int total_size = 0;
+
+  // repeated bytes file_descriptor_proto = 1;
+  total_size += 1 * this->file_descriptor_proto_size();
+  for (int i = 0; i < this->file_descriptor_proto_size(); i++) {
+    total_size += ::google::protobuf::internal::WireFormatLite::BytesSize(
+      this->file_descriptor_proto(i));
+  }
+
+  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+  _cached_size_ = total_size;
+  GOOGLE_SAFE_CONCURRENT_WRITES_END();
+  return total_size;
+}
+
+void FileDescriptorResponse::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:grpc.reflection.v1alpha.FileDescriptorResponse)
+  if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+  const FileDescriptorResponse* source = 
+      ::google::protobuf::internal::DynamicCastToGenerated<const FileDescriptorResponse>(
+          &from);
+  if (source == NULL) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:grpc.reflection.v1alpha.FileDescriptorResponse)
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:grpc.reflection.v1alpha.FileDescriptorResponse)
+    MergeFrom(*source);
+  }
+}
+
+void FileDescriptorResponse::MergeFrom(const FileDescriptorResponse& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:grpc.reflection.v1alpha.FileDescriptorResponse)
+  if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+  file_descriptor_proto_.MergeFrom(from.file_descriptor_proto_);
+}
+
+void FileDescriptorResponse::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:grpc.reflection.v1alpha.FileDescriptorResponse)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void FileDescriptorResponse::CopyFrom(const FileDescriptorResponse& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:grpc.reflection.v1alpha.FileDescriptorResponse)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool FileDescriptorResponse::IsInitialized() const {
+
+  return true;
+}
+
+void FileDescriptorResponse::Swap(FileDescriptorResponse* other) {
+  if (other == this) return;
+  InternalSwap(other);
+}
+void FileDescriptorResponse::InternalSwap(FileDescriptorResponse* other) {
+  file_descriptor_proto_.UnsafeArenaSwap(&other->file_descriptor_proto_);
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  std::swap(_cached_size_, other->_cached_size_);
+}
+
+::google::protobuf::Metadata FileDescriptorResponse::GetMetadata() const {
+  protobuf_AssignDescriptorsOnce();
+  ::google::protobuf::Metadata metadata;
+  metadata.descriptor = FileDescriptorResponse_descriptor_;
+  metadata.reflection = FileDescriptorResponse_reflection_;
+  return metadata;
+}
+
+#if PROTOBUF_INLINE_NOT_IN_HEADERS
+// FileDescriptorResponse
+
+// repeated bytes file_descriptor_proto = 1;
+int FileDescriptorResponse::file_descriptor_proto_size() const {
+  return file_descriptor_proto_.size();
+}
+void FileDescriptorResponse::clear_file_descriptor_proto() {
+  file_descriptor_proto_.Clear();
+}
+ const ::std::string& FileDescriptorResponse::file_descriptor_proto(int index) const {
+  // @@protoc_insertion_point(field_get:grpc.reflection.v1alpha.FileDescriptorResponse.file_descriptor_proto)
+  return file_descriptor_proto_.Get(index);
+}
+ ::std::string* FileDescriptorResponse::mutable_file_descriptor_proto(int index) {
+  // @@protoc_insertion_point(field_mutable:grpc.reflection.v1alpha.FileDescriptorResponse.file_descriptor_proto)
+  return file_descriptor_proto_.Mutable(index);
+}
+ void FileDescriptorResponse::set_file_descriptor_proto(int index, const ::std::string& value) {
+  // @@protoc_insertion_point(field_set:grpc.reflection.v1alpha.FileDescriptorResponse.file_descriptor_proto)
+  file_descriptor_proto_.Mutable(index)->assign(value);
+}
+ void FileDescriptorResponse::set_file_descriptor_proto(int index, const char* value) {
+  file_descriptor_proto_.Mutable(index)->assign(value);
+  // @@protoc_insertion_point(field_set_char:grpc.reflection.v1alpha.FileDescriptorResponse.file_descriptor_proto)
+}
+ void FileDescriptorResponse::set_file_descriptor_proto(int index, const void* value, size_t size) {
+  file_descriptor_proto_.Mutable(index)->assign(
+    reinterpret_cast<const char*>(value), size);
+  // @@protoc_insertion_point(field_set_pointer:grpc.reflection.v1alpha.FileDescriptorResponse.file_descriptor_proto)
+}
+ ::std::string* FileDescriptorResponse::add_file_descriptor_proto() {
+  // @@protoc_insertion_point(field_add_mutable:grpc.reflection.v1alpha.FileDescriptorResponse.file_descriptor_proto)
+  return file_descriptor_proto_.Add();
+}
+ void FileDescriptorResponse::add_file_descriptor_proto(const ::std::string& value) {
+  file_descriptor_proto_.Add()->assign(value);
+  // @@protoc_insertion_point(field_add:grpc.reflection.v1alpha.FileDescriptorResponse.file_descriptor_proto)
+}
+ void FileDescriptorResponse::add_file_descriptor_proto(const char* value) {
+  file_descriptor_proto_.Add()->assign(value);
+  // @@protoc_insertion_point(field_add_char:grpc.reflection.v1alpha.FileDescriptorResponse.file_descriptor_proto)
+}
+ void FileDescriptorResponse::add_file_descriptor_proto(const void* value, size_t size) {
+  file_descriptor_proto_.Add()->assign(reinterpret_cast<const char*>(value), size);
+  // @@protoc_insertion_point(field_add_pointer:grpc.reflection.v1alpha.FileDescriptorResponse.file_descriptor_proto)
+}
+ const ::google::protobuf::RepeatedPtrField< ::std::string>&
+FileDescriptorResponse::file_descriptor_proto() const {
+  // @@protoc_insertion_point(field_list:grpc.reflection.v1alpha.FileDescriptorResponse.file_descriptor_proto)
+  return file_descriptor_proto_;
+}
+ ::google::protobuf::RepeatedPtrField< ::std::string>*
+FileDescriptorResponse::mutable_file_descriptor_proto() {
+  // @@protoc_insertion_point(field_mutable_list:grpc.reflection.v1alpha.FileDescriptorResponse.file_descriptor_proto)
+  return &file_descriptor_proto_;
+}
+
+#endif  // PROTOBUF_INLINE_NOT_IN_HEADERS
+
+// ===================================================================
+
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int ExtensionNumberResponse::kBaseTypeNameFieldNumber;
+const int ExtensionNumberResponse::kExtensionNumberFieldNumber;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+ExtensionNumberResponse::ExtensionNumberResponse()
+  : ::google::protobuf::Message(), _internal_metadata_(NULL) {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:grpc.reflection.v1alpha.ExtensionNumberResponse)
+}
+
+void ExtensionNumberResponse::InitAsDefaultInstance() {
+  _is_default_instance_ = true;
+}
+
+ExtensionNumberResponse::ExtensionNumberResponse(const ExtensionNumberResponse& from)
+  : ::google::protobuf::Message(),
+    _internal_metadata_(NULL) {
+  SharedCtor();
+  MergeFrom(from);
+  // @@protoc_insertion_point(copy_constructor:grpc.reflection.v1alpha.ExtensionNumberResponse)
+}
+
+void ExtensionNumberResponse::SharedCtor() {
+    _is_default_instance_ = false;
+  ::google::protobuf::internal::GetEmptyString();
+  _cached_size_ = 0;
+  base_type_name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+
+ExtensionNumberResponse::~ExtensionNumberResponse() {
+  // @@protoc_insertion_point(destructor:grpc.reflection.v1alpha.ExtensionNumberResponse)
+  SharedDtor();
+}
+
+void ExtensionNumberResponse::SharedDtor() {
+  base_type_name_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (this != default_instance_) {
+  }
+}
+
+void ExtensionNumberResponse::SetCachedSize(int size) const {
+  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+  _cached_size_ = size;
+  GOOGLE_SAFE_CONCURRENT_WRITES_END();
+}
+const ::google::protobuf::Descriptor* ExtensionNumberResponse::descriptor() {
+  protobuf_AssignDescriptorsOnce();
+  return ExtensionNumberResponse_descriptor_;
+}
+
+const ExtensionNumberResponse& ExtensionNumberResponse::default_instance() {
+  if (default_instance_ == NULL) protobuf_AddDesc_reflection_2eproto();
+  return *default_instance_;
+}
+
+ExtensionNumberResponse* ExtensionNumberResponse::default_instance_ = NULL;
+
+ExtensionNumberResponse* ExtensionNumberResponse::New(::google::protobuf::Arena* arena) const {
+  ExtensionNumberResponse* n = new ExtensionNumberResponse;
+  if (arena != NULL) {
+    arena->Own(n);
+  }
+  return n;
+}
+
+void ExtensionNumberResponse::Clear() {
+// @@protoc_insertion_point(message_clear_start:grpc.reflection.v1alpha.ExtensionNumberResponse)
+  base_type_name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  extension_number_.Clear();
+}
+
+bool ExtensionNumberResponse::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:grpc.reflection.v1alpha.ExtensionNumberResponse)
+  for (;;) {
+    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // optional string base_type_name = 1;
+      case 1: {
+        if (tag == 10) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_base_type_name()));
+          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+            this->base_type_name().data(), this->base_type_name().length(),
+            ::google::protobuf::internal::WireFormatLite::PARSE,
+            "grpc.reflection.v1alpha.ExtensionNumberResponse.base_type_name"));
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(18)) goto parse_extension_number;
+        break;
+      }
+
+      // repeated int32 extension_number = 2;
+      case 2: {
+        if (tag == 18) {
+         parse_extension_number:
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPackedPrimitive<
+                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
+                 input, this->mutable_extension_number())));
+        } else if (tag == 16) {
+          DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitiveNoInline<
+                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
+                 1, 18, input, this->mutable_extension_number())));
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectAtEnd()) goto success;
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0 ||
+            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:grpc.reflection.v1alpha.ExtensionNumberResponse)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:grpc.reflection.v1alpha.ExtensionNumberResponse)
+  return false;
+#undef DO_
+}
+
+void ExtensionNumberResponse::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:grpc.reflection.v1alpha.ExtensionNumberResponse)
+  // optional string base_type_name = 1;
+  if (this->base_type_name().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->base_type_name().data(), this->base_type_name().length(),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "grpc.reflection.v1alpha.ExtensionNumberResponse.base_type_name");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      1, this->base_type_name(), output);
+  }
+
+  // repeated int32 extension_number = 2;
+  if (this->extension_number_size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteTag(2, ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED, output);
+    output->WriteVarint32(_extension_number_cached_byte_size_);
+  }
+  for (int i = 0; i < this->extension_number_size(); i++) {
+    ::google::protobuf::internal::WireFormatLite::WriteInt32NoTag(
+      this->extension_number(i), output);
+  }
+
+  // @@protoc_insertion_point(serialize_end:grpc.reflection.v1alpha.ExtensionNumberResponse)
+}
+
+::google::protobuf::uint8* ExtensionNumberResponse::SerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:grpc.reflection.v1alpha.ExtensionNumberResponse)
+  // optional string base_type_name = 1;
+  if (this->base_type_name().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->base_type_name().data(), this->base_type_name().length(),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "grpc.reflection.v1alpha.ExtensionNumberResponse.base_type_name");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        1, this->base_type_name(), target);
+  }
+
+  // repeated int32 extension_number = 2;
+  if (this->extension_number_size() > 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteTagToArray(
+      2,
+      ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED,
+      target);
+    target = ::google::protobuf::io::CodedOutputStream::WriteVarint32ToArray(
+      _extension_number_cached_byte_size_, target);
+  }
+  for (int i = 0; i < this->extension_number_size(); i++) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      WriteInt32NoTagToArray(this->extension_number(i), target);
+  }
+
+  // @@protoc_insertion_point(serialize_to_array_end:grpc.reflection.v1alpha.ExtensionNumberResponse)
+  return target;
+}
+
+int ExtensionNumberResponse::ByteSize() const {
+// @@protoc_insertion_point(message_byte_size_start:grpc.reflection.v1alpha.ExtensionNumberResponse)
+  int total_size = 0;
+
+  // optional string base_type_name = 1;
+  if (this->base_type_name().size() > 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::StringSize(
+        this->base_type_name());
+  }
+
+  // repeated int32 extension_number = 2;
+  {
+    int data_size = 0;
+    for (int i = 0; i < this->extension_number_size(); i++) {
+      data_size += ::google::protobuf::internal::WireFormatLite::
+        Int32Size(this->extension_number(i));
+    }
+    if (data_size > 0) {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormatLite::Int32Size(data_size);
+    }
+    GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+    _extension_number_cached_byte_size_ = data_size;
+    GOOGLE_SAFE_CONCURRENT_WRITES_END();
+    total_size += data_size;
+  }
+
+  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+  _cached_size_ = total_size;
+  GOOGLE_SAFE_CONCURRENT_WRITES_END();
+  return total_size;
+}
+
+void ExtensionNumberResponse::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:grpc.reflection.v1alpha.ExtensionNumberResponse)
+  if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+  const ExtensionNumberResponse* source = 
+      ::google::protobuf::internal::DynamicCastToGenerated<const ExtensionNumberResponse>(
+          &from);
+  if (source == NULL) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:grpc.reflection.v1alpha.ExtensionNumberResponse)
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:grpc.reflection.v1alpha.ExtensionNumberResponse)
+    MergeFrom(*source);
+  }
+}
+
+void ExtensionNumberResponse::MergeFrom(const ExtensionNumberResponse& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:grpc.reflection.v1alpha.ExtensionNumberResponse)
+  if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+  extension_number_.MergeFrom(from.extension_number_);
+  if (from.base_type_name().size() > 0) {
+
+    base_type_name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.base_type_name_);
+  }
+}
+
+void ExtensionNumberResponse::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:grpc.reflection.v1alpha.ExtensionNumberResponse)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void ExtensionNumberResponse::CopyFrom(const ExtensionNumberResponse& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:grpc.reflection.v1alpha.ExtensionNumberResponse)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool ExtensionNumberResponse::IsInitialized() const {
+
+  return true;
+}
+
+void ExtensionNumberResponse::Swap(ExtensionNumberResponse* other) {
+  if (other == this) return;
+  InternalSwap(other);
+}
+void ExtensionNumberResponse::InternalSwap(ExtensionNumberResponse* other) {
+  base_type_name_.Swap(&other->base_type_name_);
+  extension_number_.UnsafeArenaSwap(&other->extension_number_);
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  std::swap(_cached_size_, other->_cached_size_);
+}
+
+::google::protobuf::Metadata ExtensionNumberResponse::GetMetadata() const {
+  protobuf_AssignDescriptorsOnce();
+  ::google::protobuf::Metadata metadata;
+  metadata.descriptor = ExtensionNumberResponse_descriptor_;
+  metadata.reflection = ExtensionNumberResponse_reflection_;
+  return metadata;
+}
+
+#if PROTOBUF_INLINE_NOT_IN_HEADERS
+// ExtensionNumberResponse
+
+// optional string base_type_name = 1;
+void ExtensionNumberResponse::clear_base_type_name() {
+  base_type_name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ const ::std::string& ExtensionNumberResponse::base_type_name() const {
+  // @@protoc_insertion_point(field_get:grpc.reflection.v1alpha.ExtensionNumberResponse.base_type_name)
+  return base_type_name_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ void ExtensionNumberResponse::set_base_type_name(const ::std::string& value) {
+  
+  base_type_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:grpc.reflection.v1alpha.ExtensionNumberResponse.base_type_name)
+}
+ void ExtensionNumberResponse::set_base_type_name(const char* value) {
+  
+  base_type_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:grpc.reflection.v1alpha.ExtensionNumberResponse.base_type_name)
+}
+ void ExtensionNumberResponse::set_base_type_name(const char* value, size_t size) {
+  
+  base_type_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:grpc.reflection.v1alpha.ExtensionNumberResponse.base_type_name)
+}
+ ::std::string* ExtensionNumberResponse::mutable_base_type_name() {
+  
+  // @@protoc_insertion_point(field_mutable:grpc.reflection.v1alpha.ExtensionNumberResponse.base_type_name)
+  return base_type_name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ ::std::string* ExtensionNumberResponse::release_base_type_name() {
+  // @@protoc_insertion_point(field_release:grpc.reflection.v1alpha.ExtensionNumberResponse.base_type_name)
+  
+  return base_type_name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ void ExtensionNumberResponse::set_allocated_base_type_name(::std::string* base_type_name) {
+  if (base_type_name != NULL) {
+    
+  } else {
+    
+  }
+  base_type_name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), base_type_name);
+  // @@protoc_insertion_point(field_set_allocated:grpc.reflection.v1alpha.ExtensionNumberResponse.base_type_name)
+}
+
+// repeated int32 extension_number = 2;
+int ExtensionNumberResponse::extension_number_size() const {
+  return extension_number_.size();
+}
+void ExtensionNumberResponse::clear_extension_number() {
+  extension_number_.Clear();
+}
+ ::google::protobuf::int32 ExtensionNumberResponse::extension_number(int index) const {
+  // @@protoc_insertion_point(field_get:grpc.reflection.v1alpha.ExtensionNumberResponse.extension_number)
+  return extension_number_.Get(index);
+}
+ void ExtensionNumberResponse::set_extension_number(int index, ::google::protobuf::int32 value) {
+  extension_number_.Set(index, value);
+  // @@protoc_insertion_point(field_set:grpc.reflection.v1alpha.ExtensionNumberResponse.extension_number)
+}
+ void ExtensionNumberResponse::add_extension_number(::google::protobuf::int32 value) {
+  extension_number_.Add(value);
+  // @@protoc_insertion_point(field_add:grpc.reflection.v1alpha.ExtensionNumberResponse.extension_number)
+}
+ const ::google::protobuf::RepeatedField< ::google::protobuf::int32 >&
+ExtensionNumberResponse::extension_number() const {
+  // @@protoc_insertion_point(field_list:grpc.reflection.v1alpha.ExtensionNumberResponse.extension_number)
+  return extension_number_;
+}
+ ::google::protobuf::RepeatedField< ::google::protobuf::int32 >*
+ExtensionNumberResponse::mutable_extension_number() {
+  // @@protoc_insertion_point(field_mutable_list:grpc.reflection.v1alpha.ExtensionNumberResponse.extension_number)
+  return &extension_number_;
+}
+
+#endif  // PROTOBUF_INLINE_NOT_IN_HEADERS
+
+// ===================================================================
+
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int ListServiceResponse::kServiceFieldNumber;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+ListServiceResponse::ListServiceResponse()
+  : ::google::protobuf::Message(), _internal_metadata_(NULL) {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:grpc.reflection.v1alpha.ListServiceResponse)
+}
+
+void ListServiceResponse::InitAsDefaultInstance() {
+  _is_default_instance_ = true;
+}
+
+ListServiceResponse::ListServiceResponse(const ListServiceResponse& from)
+  : ::google::protobuf::Message(),
+    _internal_metadata_(NULL) {
+  SharedCtor();
+  MergeFrom(from);
+  // @@protoc_insertion_point(copy_constructor:grpc.reflection.v1alpha.ListServiceResponse)
+}
+
+void ListServiceResponse::SharedCtor() {
+    _is_default_instance_ = false;
+  _cached_size_ = 0;
+}
+
+ListServiceResponse::~ListServiceResponse() {
+  // @@protoc_insertion_point(destructor:grpc.reflection.v1alpha.ListServiceResponse)
+  SharedDtor();
+}
+
+void ListServiceResponse::SharedDtor() {
+  if (this != default_instance_) {
+  }
+}
+
+void ListServiceResponse::SetCachedSize(int size) const {
+  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+  _cached_size_ = size;
+  GOOGLE_SAFE_CONCURRENT_WRITES_END();
+}
+const ::google::protobuf::Descriptor* ListServiceResponse::descriptor() {
+  protobuf_AssignDescriptorsOnce();
+  return ListServiceResponse_descriptor_;
+}
+
+const ListServiceResponse& ListServiceResponse::default_instance() {
+  if (default_instance_ == NULL) protobuf_AddDesc_reflection_2eproto();
+  return *default_instance_;
+}
+
+ListServiceResponse* ListServiceResponse::default_instance_ = NULL;
+
+ListServiceResponse* ListServiceResponse::New(::google::protobuf::Arena* arena) const {
+  ListServiceResponse* n = new ListServiceResponse;
+  if (arena != NULL) {
+    arena->Own(n);
+  }
+  return n;
+}
+
+void ListServiceResponse::Clear() {
+// @@protoc_insertion_point(message_clear_start:grpc.reflection.v1alpha.ListServiceResponse)
+  service_.Clear();
+}
+
+bool ListServiceResponse::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:grpc.reflection.v1alpha.ListServiceResponse)
+  for (;;) {
+    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // repeated .grpc.reflection.v1alpha.ServiceResponse service = 1;
+      case 1: {
+        if (tag == 10) {
+          DO_(input->IncrementRecursionDepth());
+         parse_loop_service:
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth(
+                input, add_service()));
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(10)) goto parse_loop_service;
+        input->UnsafeDecrementRecursionDepth();
+        if (input->ExpectAtEnd()) goto success;
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0 ||
+            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:grpc.reflection.v1alpha.ListServiceResponse)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:grpc.reflection.v1alpha.ListServiceResponse)
+  return false;
+#undef DO_
+}
+
+void ListServiceResponse::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:grpc.reflection.v1alpha.ListServiceResponse)
+  // repeated .grpc.reflection.v1alpha.ServiceResponse service = 1;
+  for (unsigned int i = 0, n = this->service_size(); i < n; i++) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      1, this->service(i), output);
+  }
+
+  // @@protoc_insertion_point(serialize_end:grpc.reflection.v1alpha.ListServiceResponse)
+}
+
+::google::protobuf::uint8* ListServiceResponse::SerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:grpc.reflection.v1alpha.ListServiceResponse)
+  // repeated .grpc.reflection.v1alpha.ServiceResponse service = 1;
+  for (unsigned int i = 0, n = this->service_size(); i < n; i++) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      WriteMessageNoVirtualToArray(
+        1, this->service(i), target);
+  }
+
+  // @@protoc_insertion_point(serialize_to_array_end:grpc.reflection.v1alpha.ListServiceResponse)
+  return target;
+}
+
+int ListServiceResponse::ByteSize() const {
+// @@protoc_insertion_point(message_byte_size_start:grpc.reflection.v1alpha.ListServiceResponse)
+  int total_size = 0;
+
+  // repeated .grpc.reflection.v1alpha.ServiceResponse service = 1;
+  total_size += 1 * this->service_size();
+  for (int i = 0; i < this->service_size(); i++) {
+    total_size +=
+      ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
+        this->service(i));
+  }
+
+  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+  _cached_size_ = total_size;
+  GOOGLE_SAFE_CONCURRENT_WRITES_END();
+  return total_size;
+}
+
+void ListServiceResponse::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:grpc.reflection.v1alpha.ListServiceResponse)
+  if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+  const ListServiceResponse* source = 
+      ::google::protobuf::internal::DynamicCastToGenerated<const ListServiceResponse>(
+          &from);
+  if (source == NULL) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:grpc.reflection.v1alpha.ListServiceResponse)
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:grpc.reflection.v1alpha.ListServiceResponse)
+    MergeFrom(*source);
+  }
+}
+
+void ListServiceResponse::MergeFrom(const ListServiceResponse& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:grpc.reflection.v1alpha.ListServiceResponse)
+  if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+  service_.MergeFrom(from.service_);
+}
+
+void ListServiceResponse::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:grpc.reflection.v1alpha.ListServiceResponse)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void ListServiceResponse::CopyFrom(const ListServiceResponse& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:grpc.reflection.v1alpha.ListServiceResponse)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool ListServiceResponse::IsInitialized() const {
+
+  return true;
+}
+
+void ListServiceResponse::Swap(ListServiceResponse* other) {
+  if (other == this) return;
+  InternalSwap(other);
+}
+void ListServiceResponse::InternalSwap(ListServiceResponse* other) {
+  service_.UnsafeArenaSwap(&other->service_);
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  std::swap(_cached_size_, other->_cached_size_);
+}
+
+::google::protobuf::Metadata ListServiceResponse::GetMetadata() const {
+  protobuf_AssignDescriptorsOnce();
+  ::google::protobuf::Metadata metadata;
+  metadata.descriptor = ListServiceResponse_descriptor_;
+  metadata.reflection = ListServiceResponse_reflection_;
+  return metadata;
+}
+
+#if PROTOBUF_INLINE_NOT_IN_HEADERS
+// ListServiceResponse
+
+// repeated .grpc.reflection.v1alpha.ServiceResponse service = 1;
+int ListServiceResponse::service_size() const {
+  return service_.size();
+}
+void ListServiceResponse::clear_service() {
+  service_.Clear();
+}
+const ::grpc::reflection::v1alpha::ServiceResponse& ListServiceResponse::service(int index) const {
+  // @@protoc_insertion_point(field_get:grpc.reflection.v1alpha.ListServiceResponse.service)
+  return service_.Get(index);
+}
+::grpc::reflection::v1alpha::ServiceResponse* ListServiceResponse::mutable_service(int index) {
+  // @@protoc_insertion_point(field_mutable:grpc.reflection.v1alpha.ListServiceResponse.service)
+  return service_.Mutable(index);
+}
+::grpc::reflection::v1alpha::ServiceResponse* ListServiceResponse::add_service() {
+  // @@protoc_insertion_point(field_add:grpc.reflection.v1alpha.ListServiceResponse.service)
+  return service_.Add();
+}
+::google::protobuf::RepeatedPtrField< ::grpc::reflection::v1alpha::ServiceResponse >*
+ListServiceResponse::mutable_service() {
+  // @@protoc_insertion_point(field_mutable_list:grpc.reflection.v1alpha.ListServiceResponse.service)
+  return &service_;
+}
+const ::google::protobuf::RepeatedPtrField< ::grpc::reflection::v1alpha::ServiceResponse >&
+ListServiceResponse::service() const {
+  // @@protoc_insertion_point(field_list:grpc.reflection.v1alpha.ListServiceResponse.service)
+  return service_;
+}
+
+#endif  // PROTOBUF_INLINE_NOT_IN_HEADERS
+
+// ===================================================================
+
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int ServiceResponse::kNameFieldNumber;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+ServiceResponse::ServiceResponse()
+  : ::google::protobuf::Message(), _internal_metadata_(NULL) {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:grpc.reflection.v1alpha.ServiceResponse)
+}
+
+void ServiceResponse::InitAsDefaultInstance() {
+  _is_default_instance_ = true;
+}
+
+ServiceResponse::ServiceResponse(const ServiceResponse& from)
+  : ::google::protobuf::Message(),
+    _internal_metadata_(NULL) {
+  SharedCtor();
+  MergeFrom(from);
+  // @@protoc_insertion_point(copy_constructor:grpc.reflection.v1alpha.ServiceResponse)
+}
+
+void ServiceResponse::SharedCtor() {
+    _is_default_instance_ = false;
+  ::google::protobuf::internal::GetEmptyString();
+  _cached_size_ = 0;
+  name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+
+ServiceResponse::~ServiceResponse() {
+  // @@protoc_insertion_point(destructor:grpc.reflection.v1alpha.ServiceResponse)
+  SharedDtor();
+}
+
+void ServiceResponse::SharedDtor() {
+  name_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (this != default_instance_) {
+  }
+}
+
+void ServiceResponse::SetCachedSize(int size) const {
+  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+  _cached_size_ = size;
+  GOOGLE_SAFE_CONCURRENT_WRITES_END();
+}
+const ::google::protobuf::Descriptor* ServiceResponse::descriptor() {
+  protobuf_AssignDescriptorsOnce();
+  return ServiceResponse_descriptor_;
+}
+
+const ServiceResponse& ServiceResponse::default_instance() {
+  if (default_instance_ == NULL) protobuf_AddDesc_reflection_2eproto();
+  return *default_instance_;
+}
+
+ServiceResponse* ServiceResponse::default_instance_ = NULL;
+
+ServiceResponse* ServiceResponse::New(::google::protobuf::Arena* arena) const {
+  ServiceResponse* n = new ServiceResponse;
+  if (arena != NULL) {
+    arena->Own(n);
+  }
+  return n;
+}
+
+void ServiceResponse::Clear() {
+// @@protoc_insertion_point(message_clear_start:grpc.reflection.v1alpha.ServiceResponse)
+  name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+
+bool ServiceResponse::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:grpc.reflection.v1alpha.ServiceResponse)
+  for (;;) {
+    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // optional string name = 1;
+      case 1: {
+        if (tag == 10) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_name()));
+          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+            this->name().data(), this->name().length(),
+            ::google::protobuf::internal::WireFormatLite::PARSE,
+            "grpc.reflection.v1alpha.ServiceResponse.name"));
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectAtEnd()) goto success;
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0 ||
+            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:grpc.reflection.v1alpha.ServiceResponse)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:grpc.reflection.v1alpha.ServiceResponse)
+  return false;
+#undef DO_
+}
+
+void ServiceResponse::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:grpc.reflection.v1alpha.ServiceResponse)
+  // optional string name = 1;
+  if (this->name().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->name().data(), this->name().length(),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "grpc.reflection.v1alpha.ServiceResponse.name");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      1, this->name(), output);
+  }
+
+  // @@protoc_insertion_point(serialize_end:grpc.reflection.v1alpha.ServiceResponse)
+}
+
+::google::protobuf::uint8* ServiceResponse::SerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:grpc.reflection.v1alpha.ServiceResponse)
+  // optional string name = 1;
+  if (this->name().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->name().data(), this->name().length(),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "grpc.reflection.v1alpha.ServiceResponse.name");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        1, this->name(), target);
+  }
+
+  // @@protoc_insertion_point(serialize_to_array_end:grpc.reflection.v1alpha.ServiceResponse)
+  return target;
+}
+
+int ServiceResponse::ByteSize() const {
+// @@protoc_insertion_point(message_byte_size_start:grpc.reflection.v1alpha.ServiceResponse)
+  int total_size = 0;
+
+  // optional string name = 1;
+  if (this->name().size() > 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::StringSize(
+        this->name());
+  }
+
+  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+  _cached_size_ = total_size;
+  GOOGLE_SAFE_CONCURRENT_WRITES_END();
+  return total_size;
+}
+
+void ServiceResponse::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:grpc.reflection.v1alpha.ServiceResponse)
+  if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+  const ServiceResponse* source = 
+      ::google::protobuf::internal::DynamicCastToGenerated<const ServiceResponse>(
+          &from);
+  if (source == NULL) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:grpc.reflection.v1alpha.ServiceResponse)
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:grpc.reflection.v1alpha.ServiceResponse)
+    MergeFrom(*source);
+  }
+}
+
+void ServiceResponse::MergeFrom(const ServiceResponse& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:grpc.reflection.v1alpha.ServiceResponse)
+  if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+  if (from.name().size() > 0) {
+
+    name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.name_);
+  }
+}
+
+void ServiceResponse::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:grpc.reflection.v1alpha.ServiceResponse)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void ServiceResponse::CopyFrom(const ServiceResponse& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:grpc.reflection.v1alpha.ServiceResponse)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool ServiceResponse::IsInitialized() const {
+
+  return true;
+}
+
+void ServiceResponse::Swap(ServiceResponse* other) {
+  if (other == this) return;
+  InternalSwap(other);
+}
+void ServiceResponse::InternalSwap(ServiceResponse* other) {
+  name_.Swap(&other->name_);
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  std::swap(_cached_size_, other->_cached_size_);
+}
+
+::google::protobuf::Metadata ServiceResponse::GetMetadata() const {
+  protobuf_AssignDescriptorsOnce();
+  ::google::protobuf::Metadata metadata;
+  metadata.descriptor = ServiceResponse_descriptor_;
+  metadata.reflection = ServiceResponse_reflection_;
+  return metadata;
+}
+
+#if PROTOBUF_INLINE_NOT_IN_HEADERS
+// ServiceResponse
+
+// optional string name = 1;
+void ServiceResponse::clear_name() {
+  name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ const ::std::string& ServiceResponse::name() const {
+  // @@protoc_insertion_point(field_get:grpc.reflection.v1alpha.ServiceResponse.name)
+  return name_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ void ServiceResponse::set_name(const ::std::string& value) {
+  
+  name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:grpc.reflection.v1alpha.ServiceResponse.name)
+}
+ void ServiceResponse::set_name(const char* value) {
+  
+  name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:grpc.reflection.v1alpha.ServiceResponse.name)
+}
+ void ServiceResponse::set_name(const char* value, size_t size) {
+  
+  name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:grpc.reflection.v1alpha.ServiceResponse.name)
+}
+ ::std::string* ServiceResponse::mutable_name() {
+  
+  // @@protoc_insertion_point(field_mutable:grpc.reflection.v1alpha.ServiceResponse.name)
+  return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ ::std::string* ServiceResponse::release_name() {
+  // @@protoc_insertion_point(field_release:grpc.reflection.v1alpha.ServiceResponse.name)
+  
+  return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ void ServiceResponse::set_allocated_name(::std::string* name) {
+  if (name != NULL) {
+    
+  } else {
+    
+  }
+  name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name);
+  // @@protoc_insertion_point(field_set_allocated:grpc.reflection.v1alpha.ServiceResponse.name)
+}
+
+#endif  // PROTOBUF_INLINE_NOT_IN_HEADERS
+
+// ===================================================================
+
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int ErrorResponse::kErrorCodeFieldNumber;
+const int ErrorResponse::kErrorMessageFieldNumber;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+ErrorResponse::ErrorResponse()
+  : ::google::protobuf::Message(), _internal_metadata_(NULL) {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:grpc.reflection.v1alpha.ErrorResponse)
+}
+
+void ErrorResponse::InitAsDefaultInstance() {
+  _is_default_instance_ = true;
+}
+
+ErrorResponse::ErrorResponse(const ErrorResponse& from)
+  : ::google::protobuf::Message(),
+    _internal_metadata_(NULL) {
+  SharedCtor();
+  MergeFrom(from);
+  // @@protoc_insertion_point(copy_constructor:grpc.reflection.v1alpha.ErrorResponse)
+}
+
+void ErrorResponse::SharedCtor() {
+    _is_default_instance_ = false;
+  ::google::protobuf::internal::GetEmptyString();
+  _cached_size_ = 0;
+  error_code_ = 0;
+  error_message_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+
+ErrorResponse::~ErrorResponse() {
+  // @@protoc_insertion_point(destructor:grpc.reflection.v1alpha.ErrorResponse)
+  SharedDtor();
+}
+
+void ErrorResponse::SharedDtor() {
+  error_message_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (this != default_instance_) {
+  }
+}
+
+void ErrorResponse::SetCachedSize(int size) const {
+  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+  _cached_size_ = size;
+  GOOGLE_SAFE_CONCURRENT_WRITES_END();
+}
+const ::google::protobuf::Descriptor* ErrorResponse::descriptor() {
+  protobuf_AssignDescriptorsOnce();
+  return ErrorResponse_descriptor_;
+}
+
+const ErrorResponse& ErrorResponse::default_instance() {
+  if (default_instance_ == NULL) protobuf_AddDesc_reflection_2eproto();
+  return *default_instance_;
+}
+
+ErrorResponse* ErrorResponse::default_instance_ = NULL;
+
+ErrorResponse* ErrorResponse::New(::google::protobuf::Arena* arena) const {
+  ErrorResponse* n = new ErrorResponse;
+  if (arena != NULL) {
+    arena->Own(n);
+  }
+  return n;
+}
+
+void ErrorResponse::Clear() {
+// @@protoc_insertion_point(message_clear_start:grpc.reflection.v1alpha.ErrorResponse)
+  error_code_ = 0;
+  error_message_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+
+bool ErrorResponse::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:grpc.reflection.v1alpha.ErrorResponse)
+  for (;;) {
+    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // optional int32 error_code = 1;
+      case 1: {
+        if (tag == 8) {
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
+                 input, &error_code_)));
+
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectTag(18)) goto parse_error_message;
+        break;
+      }
+
+      // optional string error_message = 2;
+      case 2: {
+        if (tag == 18) {
+         parse_error_message:
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_error_message()));
+          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+            this->error_message().data(), this->error_message().length(),
+            ::google::protobuf::internal::WireFormatLite::PARSE,
+            "grpc.reflection.v1alpha.ErrorResponse.error_message"));
+        } else {
+          goto handle_unusual;
+        }
+        if (input->ExpectAtEnd()) goto success;
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0 ||
+            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormatLite::SkipField(input, tag));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:grpc.reflection.v1alpha.ErrorResponse)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:grpc.reflection.v1alpha.ErrorResponse)
+  return false;
+#undef DO_
+}
+
+void ErrorResponse::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:grpc.reflection.v1alpha.ErrorResponse)
+  // optional int32 error_code = 1;
+  if (this->error_code() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteInt32(1, this->error_code(), output);
+  }
+
+  // optional string error_message = 2;
+  if (this->error_message().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->error_message().data(), this->error_message().length(),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "grpc.reflection.v1alpha.ErrorResponse.error_message");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      2, this->error_message(), output);
+  }
+
+  // @@protoc_insertion_point(serialize_end:grpc.reflection.v1alpha.ErrorResponse)
+}
+
+::google::protobuf::uint8* ErrorResponse::SerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:grpc.reflection.v1alpha.ErrorResponse)
+  // optional int32 error_code = 1;
+  if (this->error_code() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(1, this->error_code(), target);
+  }
+
+  // optional string error_message = 2;
+  if (this->error_message().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->error_message().data(), this->error_message().length(),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "grpc.reflection.v1alpha.ErrorResponse.error_message");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        2, this->error_message(), target);
+  }
+
+  // @@protoc_insertion_point(serialize_to_array_end:grpc.reflection.v1alpha.ErrorResponse)
+  return target;
+}
+
+int ErrorResponse::ByteSize() const {
+// @@protoc_insertion_point(message_byte_size_start:grpc.reflection.v1alpha.ErrorResponse)
+  int total_size = 0;
+
+  // optional int32 error_code = 1;
+  if (this->error_code() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::Int32Size(
+        this->error_code());
+  }
+
+  // optional string error_message = 2;
+  if (this->error_message().size() > 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::StringSize(
+        this->error_message());
+  }
+
+  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
+  _cached_size_ = total_size;
+  GOOGLE_SAFE_CONCURRENT_WRITES_END();
+  return total_size;
+}
+
+void ErrorResponse::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:grpc.reflection.v1alpha.ErrorResponse)
+  if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+  const ErrorResponse* source = 
+      ::google::protobuf::internal::DynamicCastToGenerated<const ErrorResponse>(
+          &from);
+  if (source == NULL) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:grpc.reflection.v1alpha.ErrorResponse)
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:grpc.reflection.v1alpha.ErrorResponse)
+    MergeFrom(*source);
+  }
+}
+
+void ErrorResponse::MergeFrom(const ErrorResponse& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:grpc.reflection.v1alpha.ErrorResponse)
+  if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
+  if (from.error_code() != 0) {
+    set_error_code(from.error_code());
+  }
+  if (from.error_message().size() > 0) {
+
+    error_message_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.error_message_);
+  }
+}
+
+void ErrorResponse::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:grpc.reflection.v1alpha.ErrorResponse)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void ErrorResponse::CopyFrom(const ErrorResponse& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:grpc.reflection.v1alpha.ErrorResponse)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool ErrorResponse::IsInitialized() const {
+
+  return true;
+}
+
+void ErrorResponse::Swap(ErrorResponse* other) {
+  if (other == this) return;
+  InternalSwap(other);
+}
+void ErrorResponse::InternalSwap(ErrorResponse* other) {
+  std::swap(error_code_, other->error_code_);
+  error_message_.Swap(&other->error_message_);
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  std::swap(_cached_size_, other->_cached_size_);
+}
+
+::google::protobuf::Metadata ErrorResponse::GetMetadata() const {
+  protobuf_AssignDescriptorsOnce();
+  ::google::protobuf::Metadata metadata;
+  metadata.descriptor = ErrorResponse_descriptor_;
+  metadata.reflection = ErrorResponse_reflection_;
+  return metadata;
+}
+
+#if PROTOBUF_INLINE_NOT_IN_HEADERS
+// ErrorResponse
+
+// optional int32 error_code = 1;
+void ErrorResponse::clear_error_code() {
+  error_code_ = 0;
+}
+ ::google::protobuf::int32 ErrorResponse::error_code() const {
+  // @@protoc_insertion_point(field_get:grpc.reflection.v1alpha.ErrorResponse.error_code)
+  return error_code_;
+}
+ void ErrorResponse::set_error_code(::google::protobuf::int32 value) {
+  
+  error_code_ = value;
+  // @@protoc_insertion_point(field_set:grpc.reflection.v1alpha.ErrorResponse.error_code)
+}
+
+// optional string error_message = 2;
+void ErrorResponse::clear_error_message() {
+  error_message_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ const ::std::string& ErrorResponse::error_message() const {
+  // @@protoc_insertion_point(field_get:grpc.reflection.v1alpha.ErrorResponse.error_message)
+  return error_message_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ void ErrorResponse::set_error_message(const ::std::string& value) {
+  
+  error_message_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:grpc.reflection.v1alpha.ErrorResponse.error_message)
+}
+ void ErrorResponse::set_error_message(const char* value) {
+  
+  error_message_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:grpc.reflection.v1alpha.ErrorResponse.error_message)
+}
+ void ErrorResponse::set_error_message(const char* value, size_t size) {
+  
+  error_message_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:grpc.reflection.v1alpha.ErrorResponse.error_message)
+}
+ ::std::string* ErrorResponse::mutable_error_message() {
+  
+  // @@protoc_insertion_point(field_mutable:grpc.reflection.v1alpha.ErrorResponse.error_message)
+  return error_message_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ ::std::string* ErrorResponse::release_error_message() {
+  // @@protoc_insertion_point(field_release:grpc.reflection.v1alpha.ErrorResponse.error_message)
+  
+  return error_message_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+ void ErrorResponse::set_allocated_error_message(::std::string* error_message) {
+  if (error_message != NULL) {
+    
+  } else {
+    
+  }
+  error_message_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), error_message);
+  // @@protoc_insertion_point(field_set_allocated:grpc.reflection.v1alpha.ErrorResponse.error_message)
+}
+
+#endif  // PROTOBUF_INLINE_NOT_IN_HEADERS
+
+// @@protoc_insertion_point(namespace_scope)
+
+}  // namespace v1alpha
+}  // namespace reflection
+}  // namespace grpc
+
+// @@protoc_insertion_point(global_scope)
diff --git a/src/cpp/server/server.cc b/src/cpp/server/server.cc
index f6c3e57..50fc473 100644
--- a/src/cpp/server/server.cc
+++ b/src/cpp/server/server.cc
@@ -329,6 +329,10 @@
   g_callbacks.reset(callbacks);
 }
 
+grpc_server* Server::c_server() { return server_; }
+
+CompletionQueue* Server::completion_queue() { return &cq_; }
+
 static grpc_server_register_method_payload_handling PayloadHandlingForMethod(
     RpcServiceMethod* method) {
   switch (method->method_type()) {
diff --git a/src/cpp/server/server_builder.cc b/src/cpp/server/server_builder.cc
index 54feac3..2799817 100644
--- a/src/cpp/server/server_builder.cc
+++ b/src/cpp/server/server_builder.cc
@@ -37,6 +37,8 @@
 #include <grpc++/server.h>
 #include <grpc/support/cpu.h>
 #include <grpc/support/log.h>
+
+#include "include/grpc/support/useful.h"
 #include "src/cpp/server/thread_pool_interface.h"
 
 namespace grpc {
@@ -52,12 +54,18 @@
 
 ServerBuilder::ServerBuilder()
     : max_message_size_(-1), generic_service_(nullptr) {
-  grpc_compression_options_init(&compression_options_);
   gpr_once_init(&once_init_plugin_list, do_plugin_list_init);
   for (auto factory : (*g_plugin_factory_list)) {
     std::unique_ptr<ServerBuilderPlugin> plugin = factory();
     plugins_[plugin->name()] = std::move(plugin);
   }
+  // all compression algorithms enabled by default.
+  enabled_compression_algorithms_bitset_ =
+      (1u << GRPC_COMPRESS_ALGORITHMS_COUNT) - 1;
+  memset(&maybe_default_compression_level_, 0,
+         sizeof(maybe_default_compression_level_));
+  memset(&maybe_default_compression_algorithm_, 0,
+         sizeof(maybe_default_compression_algorithm_));
 }
 
 std::unique_ptr<ServerCompletionQueue> ServerBuilder::AddCompletionQueue(
@@ -67,35 +75,65 @@
   return std::unique_ptr<ServerCompletionQueue>(cq);
 }
 
-void ServerBuilder::RegisterService(Service* service) {
+ServerBuilder& ServerBuilder::RegisterService(Service* service) {
   services_.emplace_back(new NamedService(service));
+  return *this;
 }
 
-void ServerBuilder::RegisterService(const grpc::string& addr,
-                                    Service* service) {
+ServerBuilder& ServerBuilder::RegisterService(const grpc::string& addr,
+                                              Service* service) {
   services_.emplace_back(new NamedService(addr, service));
+  return *this;
 }
 
-void ServerBuilder::RegisterAsyncGenericService(AsyncGenericService* service) {
+ServerBuilder& ServerBuilder::RegisterAsyncGenericService(
+    AsyncGenericService* service) {
   if (generic_service_) {
     gpr_log(GPR_ERROR,
             "Adding multiple AsyncGenericService is unsupported for now. "
             "Dropping the service %p",
             service);
-    return;
+  } else {
+    generic_service_ = service;
   }
-  generic_service_ = service;
+  return *this;
 }
 
-void ServerBuilder::SetOption(std::unique_ptr<ServerBuilderOption> option) {
+ServerBuilder& ServerBuilder::SetOption(
+    std::unique_ptr<ServerBuilderOption> option) {
   options_.push_back(std::move(option));
+  return *this;
 }
 
-void ServerBuilder::AddListeningPort(const grpc::string& addr,
-                                     std::shared_ptr<ServerCredentials> creds,
-                                     int* selected_port) {
+ServerBuilder& ServerBuilder::SetCompressionAlgorithmSupportStatus(
+    grpc_compression_algorithm algorithm, bool enabled) {
+  if (enabled) {
+    GPR_BITSET(&enabled_compression_algorithms_bitset_, algorithm);
+  } else {
+    GPR_BITCLEAR(&enabled_compression_algorithms_bitset_, algorithm);
+  }
+  return *this;
+}
+
+ServerBuilder& ServerBuilder::SetDefaultCompressionLevel(
+    grpc_compression_level level) {
+  maybe_default_compression_level_.level = level;
+  return *this;
+}
+
+ServerBuilder& ServerBuilder::SetDefaultCompressionAlgorithm(
+    grpc_compression_algorithm algorithm) {
+  maybe_default_compression_algorithm_.is_set = true;
+  maybe_default_compression_algorithm_.algorithm = algorithm;
+  return *this;
+}
+
+ServerBuilder& ServerBuilder::AddListeningPort(
+    const grpc::string& addr, std::shared_ptr<ServerCredentials> creds,
+    int* selected_port) {
   Port port = {addr, creds, selected_port};
   ports_.push_back(port);
+  return *this;
 }
 
 std::unique_ptr<Server> ServerBuilder::BuildAndStart() {
@@ -128,7 +166,15 @@
     args.SetInt(GRPC_ARG_MAX_MESSAGE_LENGTH, max_message_size_);
   }
   args.SetInt(GRPC_COMPRESSION_CHANNEL_ENABLED_ALGORITHMS_BITSET,
-              compression_options_.enabled_algorithms_bitset);
+              enabled_compression_algorithms_bitset_);
+  if (maybe_default_compression_level_.is_set) {
+    args.SetInt(GRPC_COMPRESSION_CHANNEL_DEFAULT_LEVEL,
+                maybe_default_compression_level_.level);
+  }
+  if (maybe_default_compression_algorithm_.is_set) {
+    args.SetInt(GRPC_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM,
+                maybe_default_compression_algorithm_.algorithm);
+  }
   std::unique_ptr<Server> server(
       new Server(thread_pool.release(), true, max_message_size_, &args));
   ServerInitializer* initializer = server->initializer();
diff --git a/src/cpp/server/server_context.cc b/src/cpp/server/server_context.cc
index 204fef1..43117fd 100644
--- a/src/cpp/server/server_context.cc
+++ b/src/cpp/server/server_context.cc
@@ -42,7 +42,6 @@
 #include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
 
-#include "src/core/lib/channel/compress_filter.h"
 #include "src/core/lib/surface/call.h"
 
 namespace grpc {
@@ -196,6 +195,9 @@
 }
 
 void ServerContext::set_compression_level(grpc_compression_level level) {
+  // TODO(dgq): get rid of grpc_call_compression_for_level and propagate the
+  // compression level by adding a new argument to
+  // CallOpSendInitialMetadata::SendInitialMetadata.
   const grpc_compression_algorithm algorithm_for_level =
       grpc_call_compression_for_level(call_, level);
   set_compression_algorithm(algorithm_for_level);
@@ -210,7 +212,7 @@
     abort();
   }
   GPR_ASSERT(algorithm_name != NULL);
-  AddInitialMetadata(GRPC_COMPRESS_REQUEST_ALGORITHM_KEY, algorithm_name);
+  AddInitialMetadata(GRPC_COMPRESSION_REQUEST_ALGORITHM_MD_KEY, algorithm_name);
 }
 
 grpc::string ServerContext::peer() const {
diff --git a/include/grpc/support/atm_win32.h b/src/cpp/server/server_posix.cc
similarity index 79%
copy from include/grpc/support/atm_win32.h
copy to src/cpp/server/server_posix.cc
index 13526d9..8cb9753 100644
--- a/include/grpc/support/atm_win32.h
+++ b/src/cpp/server/server_posix.cc
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,9 +31,19 @@
  *
  */
 
-#ifndef GRPC_SUPPORT_ATM_WIN32_H
-#define GRPC_SUPPORT_ATM_WIN32_H
+#include <grpc++/server_posix.h>
 
-#include <grpc/impl/codegen/atm_win32.h>
+#include <grpc/grpc_posix.h>
 
-#endif /* GRPC_SUPPORT_ATM_WIN32_H */
+namespace grpc {
+
+#ifdef GPR_SUPPORT_CHANNELS_FROM_FD
+
+void AddInsecureChannelFromFd(Server* server, int fd) {
+  grpc_server_add_insecure_channel_from_fd(
+      server->c_server(), server->completion_queue()->cq(), fd);
+
+#endif  // GPR_SUPPORT_CHANNELS_FROM_FD
+}
+
+}  // namespace grpc
diff --git a/src/csharp/Grpc.Core.Tests/AppDomainUnloadTest.cs b/src/csharp/Grpc.Core.Tests/AppDomainUnloadTest.cs
new file mode 100644
index 0000000..e605a31
--- /dev/null
+++ b/src/csharp/Grpc.Core.Tests/AppDomainUnloadTest.cs
@@ -0,0 +1,90 @@
+#region Copyright notice and license
+
+// Copyright 2015, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#endregion
+
+using System;
+using System.Diagnostics;
+using System.Linq;
+using System.Reflection;
+using System.Threading;
+using System.Threading.Tasks;
+using Grpc.Core;
+using Grpc.Core.Internal;
+using Grpc.Core.Utils;
+using NUnit.Framework;
+
+namespace Grpc.Core.Tests
+{
+    public class AppDomainUnloadTest
+    {
+        [Test]
+        public void AppDomainUnloadHookCanCleanupAbandonedCall()
+        {
+            var setup = new AppDomainSetup
+            {
+                ApplicationBase = AppDomain.CurrentDomain.BaseDirectory
+            };
+            var childDomain = AppDomain.CreateDomain("test", null, setup);
+            var remoteObj = childDomain.CreateInstance(typeof(AppDomainTestClass).Assembly.GetName().Name, typeof(AppDomainTestClass).FullName);
+
+            // Try to unload the appdomain once we've created a server and a channel inside the appdomain.
+            AppDomain.Unload(childDomain);
+        }
+
+        public class AppDomainTestClass
+        {
+            const string Host = "127.0.0.1";
+
+            /// <summary>
+            /// Creates a server and a channel and initiates a call. The code is invoked from inside of an AppDomain
+            /// to test if AppDomain.Unload() work if Grpc is being used.
+            /// </summary>
+            public AppDomainTestClass()
+            {
+                var helper = new MockServiceHelper(Host);
+                var server = helper.GetServer();
+                server.Start();
+                var channel = helper.GetChannel();
+
+                var readyToShutdown = new TaskCompletionSource<object>();
+                helper.DuplexStreamingHandler = new DuplexStreamingServerMethod<string, string>(async (requestStream, responseStream, context) =>
+                {
+                    readyToShutdown.SetResult(null);
+                    await requestStream.ToListAsync();
+                });
+
+                var call = Calls.AsyncDuplexStreamingCall(helper.CreateDuplexStreamingCall());
+                readyToShutdown.Task.Wait();  // make sure handler is running
+            }
+        }
+    }
+}
diff --git a/src/csharp/Grpc.Core.Tests/ChannelTest.cs b/src/csharp/Grpc.Core.Tests/ChannelTest.cs
index 850d70c..db0ef3a 100644
--- a/src/csharp/Grpc.Core.Tests/ChannelTest.cs
+++ b/src/csharp/Grpc.Core.Tests/ChannelTest.cs
@@ -71,7 +71,7 @@
         public void WaitForStateChangedAsync_InvalidArgument()
         {
             var channel = new Channel("localhost", ChannelCredentials.Insecure);
-            Assert.ThrowsAsync(typeof(ArgumentException), async () => await channel.WaitForStateChangedAsync(ChannelState.FatalFailure));
+            Assert.ThrowsAsync(typeof(ArgumentException), async () => await channel.WaitForStateChangedAsync(ChannelState.Shutdown));
             channel.ShutdownAsync().Wait();
         }
 
@@ -102,11 +102,11 @@
         }
 
         [Test]
-        public async Task StateIsFatalFailureAfterShutdown()
+        public async Task StateIsShutdownAfterShutdown()
         {
             var channel = new Channel("localhost", ChannelCredentials.Insecure);
             await channel.ShutdownAsync();
-            Assert.AreEqual(ChannelState.FatalFailure, channel.State);
+            Assert.AreEqual(ChannelState.Shutdown, channel.State);
         }
 
         [Test]
diff --git a/src/csharp/Grpc.Core.Tests/ClientServerTest.cs b/src/csharp/Grpc.Core.Tests/ClientServerTest.cs
index d92addb..dcdddc7 100644
--- a/src/csharp/Grpc.Core.Tests/ClientServerTest.cs
+++ b/src/csharp/Grpc.Core.Tests/ClientServerTest.cs
@@ -235,8 +235,16 @@
             await barrier.Task;  // make sure the handler has started.
             cts.Cancel();
 
-            var ex = Assert.ThrowsAsync<RpcException>(async () => await call.ResponseAsync);
-            Assert.AreEqual(StatusCode.Cancelled, ex.Status.StatusCode);
+            try
+            {
+                // cannot use Assert.ThrowsAsync because it uses Task.Wait and would deadlock.
+                await call.ResponseAsync;
+                Assert.Fail();
+            }
+            catch (RpcException ex)
+            {
+                Assert.AreEqual(StatusCode.Cancelled, ex.Status.StatusCode);
+            }
         }
 
         [Test]
@@ -265,9 +273,15 @@
             await handlerStartedBarrier.Task;
             cts.Cancel();
 
-            var ex = Assert.ThrowsAsync<RpcException>(async () => await call.ResponseAsync);
-            Assert.AreEqual(StatusCode.Cancelled, ex.Status.StatusCode);
-
+            try
+            {
+                await call.ResponseAsync;
+                Assert.Fail();
+            }
+            catch (RpcException ex)
+            {
+                Assert.AreEqual(StatusCode.Cancelled, ex.Status.StatusCode);
+            }
             Assert.AreEqual("SUCCESS", await successTcs.Task);
         }
 
diff --git a/src/csharp/Grpc.Core.Tests/ContextPropagationTest.cs b/src/csharp/Grpc.Core.Tests/ContextPropagationTest.cs
index cec8c7c..6a15629 100644
--- a/src/csharp/Grpc.Core.Tests/ContextPropagationTest.cs
+++ b/src/csharp/Grpc.Core.Tests/ContextPropagationTest.cs
@@ -105,7 +105,15 @@
             var parentCall = Calls.AsyncClientStreamingCall(helper.CreateClientStreamingCall(new CallOptions(cancellationToken: cts.Token)));
             await readyToCancelTcs.Task;
             cts.Cancel();
-            Assert.ThrowsAsync(typeof(RpcException), async () => await parentCall);
+            try
+            {
+                // cannot use Assert.ThrowsAsync because it uses Task.Wait and would deadlock.
+                await parentCall;
+                Assert.Fail();
+            }
+            catch (RpcException)
+            {
+            }
             Assert.AreEqual("CHILD_CALL_CANCELLED", await successTcs.Task);
         }
 
diff --git a/src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj b/src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj
index 47131fc..074c960 100644
--- a/src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj
+++ b/src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj
@@ -86,6 +86,10 @@
     <Compile Include="NUnitMain.cs" />
     <Compile Include="Internal\FakeNativeCall.cs" />
     <Compile Include="Internal\AsyncCallServerTest.cs" />
+    <Compile Include="ShutdownHookServerTest.cs" />
+    <Compile Include="ShutdownHookPendingCallTest.cs" />
+    <Compile Include="ShutdownHookClientTest.cs" />
+    <Compile Include="AppDomainUnloadTest.cs" />
   </ItemGroup>
   <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
   <ItemGroup>
diff --git a/src/csharp/Grpc.Core.Tests/GrpcEnvironmentTest.cs b/src/csharp/Grpc.Core.Tests/GrpcEnvironmentTest.cs
index ab12c12..3ec2cf4 100644
--- a/src/csharp/Grpc.Core.Tests/GrpcEnvironmentTest.cs
+++ b/src/csharp/Grpc.Core.Tests/GrpcEnvironmentTest.cs
@@ -32,7 +32,7 @@
 #endregion
 
 using System;
-using System.Threading;
+using System.Linq;
 using Grpc.Core;
 using NUnit.Framework;
 
@@ -44,8 +44,12 @@
         public void InitializeAndShutdownGrpcEnvironment()
         {
             var env = GrpcEnvironment.AddRef();
-            Assert.IsNotNull(env.CompletionQueue);
-            GrpcEnvironment.Release();
+            Assert.IsTrue(env.CompletionQueues.Count > 0);
+            for (int i = 0; i < env.CompletionQueues.Count; i++)
+            {
+                Assert.IsNotNull(env.CompletionQueues.ElementAt(i));
+            }
+            GrpcEnvironment.ReleaseAsync().Wait();
         }
 
         [Test]
@@ -54,8 +58,8 @@
             var env1 = GrpcEnvironment.AddRef();
             var env2 = GrpcEnvironment.AddRef();
             Assert.AreSame(env1, env2);
-            GrpcEnvironment.Release();
-            GrpcEnvironment.Release();
+            GrpcEnvironment.ReleaseAsync().Wait();
+            GrpcEnvironment.ReleaseAsync().Wait();
         }
 
         [Test]
@@ -64,10 +68,10 @@
             Assert.AreEqual(0, GrpcEnvironment.GetRefCount());
 
             var env1 = GrpcEnvironment.AddRef();
-            GrpcEnvironment.Release();
+            GrpcEnvironment.ReleaseAsync().Wait();
 
             var env2 = GrpcEnvironment.AddRef();
-            GrpcEnvironment.Release();
+            GrpcEnvironment.ReleaseAsync().Wait();
 
             Assert.AreNotSame(env1, env2);
         }
@@ -76,7 +80,7 @@
         public void ReleaseWithoutAddRef()
         {
             Assert.AreEqual(0, GrpcEnvironment.GetRefCount());
-            Assert.Throws(typeof(InvalidOperationException), () => GrpcEnvironment.Release());
+            Assert.ThrowsAsync(typeof(InvalidOperationException), async () => await GrpcEnvironment.ReleaseAsync());
         }
 
         [Test]
diff --git a/src/csharp/Grpc.Core.Tests/Internal/AsyncCallServerTest.cs b/src/csharp/Grpc.Core.Tests/Internal/AsyncCallServerTest.cs
index 0e20476..c35aaf6 100644
--- a/src/csharp/Grpc.Core.Tests/Internal/AsyncCallServerTest.cs
+++ b/src/csharp/Grpc.Core.Tests/Internal/AsyncCallServerTest.cs
@@ -53,8 +53,6 @@
         [SetUp]
         public void Init()
         {
-            var environment = GrpcEnvironment.AddRef();
-
             // Create a fake server just so we have an instance to refer to.
             // The server won't actually be used at all.
             server = new Server()
@@ -66,7 +64,6 @@
             fakeCall = new FakeNativeCall();
             asyncCallServer = new AsyncCallServer<string, string>(
                 Marshallers.StringMarshaller.Serializer, Marshallers.StringMarshaller.Deserializer,
-                environment,
                 server);
             asyncCallServer.InitializeForTesting(fakeCall);
         }
@@ -75,7 +72,6 @@
         public void Cleanup()
         {
             server.ShutdownAsync().Wait();
-            GrpcEnvironment.Release();
         }
 
         [Test]
@@ -136,7 +132,6 @@
         public void WriteAfterCancelNotificationFails()
         {
             var finishedTask = asyncCallServer.ServerSideCallAsync();
-            var requestStream = new ServerRequestStream<string, string>(asyncCallServer);
             var responseStream = new ServerResponseStream<string, string>(asyncCallServer);
 
             fakeCall.ReceivedCloseOnServerHandler(true, cancelled: true);
@@ -181,6 +176,21 @@
             AssertFinished(asyncCallServer, fakeCall, finishedTask);
         }
 
+        [Test]
+        public void WriteAfterWriteStatusThrowsInvalidOperationException()
+        {
+            var finishedTask = asyncCallServer.ServerSideCallAsync();
+            var responseStream = new ServerResponseStream<string, string>(asyncCallServer);
+
+            asyncCallServer.SendStatusFromServerAsync(Status.DefaultSuccess, new Metadata(), null);
+            Assert.ThrowsAsync(typeof(InvalidOperationException), async () => await responseStream.WriteAsync("request1"));
+
+            fakeCall.SendStatusFromServerHandler(true);
+            fakeCall.ReceivedCloseOnServerHandler(true, cancelled: true);
+
+            AssertFinished(asyncCallServer, fakeCall, finishedTask);
+        }
+
         static void AssertFinished(AsyncCallServer<string, string> asyncCallServer, FakeNativeCall fakeCall, Task finishedTask)
         {
             Assert.IsTrue(fakeCall.IsDisposed);
diff --git a/src/csharp/Grpc.Core.Tests/Internal/AsyncCallTest.cs b/src/csharp/Grpc.Core.Tests/Internal/AsyncCallTest.cs
index 777a1c8..81897f8 100644
--- a/src/csharp/Grpc.Core.Tests/Internal/AsyncCallTest.cs
+++ b/src/csharp/Grpc.Core.Tests/Internal/AsyncCallTest.cs
@@ -33,7 +33,6 @@
 
 using System;
 using System.Collections.Generic;
-using System.Runtime.InteropServices;
 using System.Threading.Tasks;
 
 using Grpc.Core.Internal;
@@ -82,7 +81,7 @@
             Assert.ThrowsAsync(typeof(InvalidOperationException),
                 async () => await asyncCall.ReadMessageAsync());
             Assert.Throws(typeof(InvalidOperationException),
-                () => asyncCall.StartSendMessage("abc", new WriteFlags(), (x,y) => {}));
+                () => asyncCall.SendMessageAsync("abc", new WriteFlags()));
         }
 
         [Test]
@@ -103,7 +102,7 @@
             var resultTask = asyncCall.UnaryCallAsync("request1");
             fakeCall.UnaryResponseClientHandler(true,
                 CreateClientSideStatus(StatusCode.InvalidArgument),
-                CreateResponsePayload(),
+                null,
                 new Metadata());
 
             AssertUnaryResponseError(asyncCall, fakeCall, resultTask, StatusCode.InvalidArgument);
@@ -148,7 +147,7 @@
             var resultTask = asyncCall.ClientStreamingCallAsync();
             fakeCall.UnaryResponseClientHandler(true,
                 CreateClientSideStatus(StatusCode.InvalidArgument),
-                CreateResponsePayload(),
+                null,
                 new Metadata());
 
             AssertUnaryResponseError(asyncCall, fakeCall, resultTask, StatusCode.InvalidArgument);
@@ -193,7 +192,7 @@
 
             fakeCall.UnaryResponseClientHandler(true,
                 CreateClientSideStatus(StatusCode.Internal),
-                CreateResponsePayload(),
+                null,
                 new Metadata());
 
             AssertUnaryResponseError(asyncCall, fakeCall, resultTask, StatusCode.Internal);
@@ -211,7 +210,9 @@
                 new Metadata());
 
             AssertUnaryResponseSuccess(asyncCall, fakeCall, resultTask);
-            var ex = Assert.Throws<RpcException>(() => requestStream.WriteAsync("request1"));
+
+            var writeTask = requestStream.WriteAsync("request1");
+            var ex = Assert.ThrowsAsync<RpcException>(async () => await writeTask);
             Assert.AreEqual(Status.DefaultSuccess, ex.Status);
         }
 
@@ -223,11 +224,13 @@
 
             fakeCall.UnaryResponseClientHandler(true,
                 new ClientSideStatus(new Status(StatusCode.OutOfRange, ""), new Metadata()),
-                CreateResponsePayload(),
+                null,
                 new Metadata());
 
             AssertUnaryResponseError(asyncCall, fakeCall, resultTask, StatusCode.OutOfRange);
-            var ex = Assert.Throws<RpcException>(() => requestStream.WriteAsync("request1"));
+
+            var writeTask = requestStream.WriteAsync("request1");
+            var ex = Assert.ThrowsAsync<RpcException>(async () => await writeTask);
             Assert.AreEqual(StatusCode.OutOfRange, ex.Status.StatusCode);
         }
 
@@ -267,7 +270,7 @@
         }
 
         [Test]
-        public void ClientStreaming_WriteAfterCancellationRequestThrowsOperationCancelledException()
+        public void ClientStreaming_WriteAfterCancellationRequestThrowsTaskCanceledException()
         {
             var resultTask = asyncCall.ClientStreamingCallAsync();
             var requestStream = new ClientRequestStream<string, string>(asyncCall);
@@ -275,11 +278,12 @@
             asyncCall.Cancel();
             Assert.IsTrue(fakeCall.IsCancelled);
 
-            Assert.Throws(typeof(OperationCanceledException), () => requestStream.WriteAsync("request1"));
+            var writeTask = requestStream.WriteAsync("request1");
+            Assert.ThrowsAsync(typeof(TaskCanceledException), async () => await writeTask);
 
             fakeCall.UnaryResponseClientHandler(true,
                 CreateClientSideStatus(StatusCode.Cancelled),
-                CreateResponsePayload(),
+                null,
                 new Metadata());
 
             AssertUnaryResponseError(asyncCall, fakeCall, resultTask, StatusCode.Cancelled);
@@ -290,7 +294,7 @@
         {
             asyncCall.StartServerStreamingCall("request1");
             Assert.Throws(typeof(InvalidOperationException),
-                () => asyncCall.StartSendMessage("abc", new WriteFlags(), (x,y) => {}));
+                () => asyncCall.SendMessageAsync("abc", new WriteFlags()));
         }
 
         [Test]
@@ -390,12 +394,13 @@
 
             AssertStreamingResponseSuccess(asyncCall, fakeCall, readTask);
 
-            var ex = Assert.ThrowsAsync<RpcException>(async () => await requestStream.WriteAsync("request1"));
+            var writeTask = requestStream.WriteAsync("request1");
+            var ex = Assert.ThrowsAsync<RpcException>(async () => await writeTask);
             Assert.AreEqual(Status.DefaultSuccess, ex.Status);
         }
 
         [Test]
-        public void DuplexStreaming_CompleteAfterReceivingStatusFails()
+        public void DuplexStreaming_CompleteAfterReceivingStatusSuceeds()
         {
             asyncCall.StartDuplexStreamingCall();
             var requestStream = new ClientRequestStream<string, string>(asyncCall);
@@ -411,7 +416,7 @@
         }
 
         [Test]
-        public void DuplexStreaming_WriteAfterCancellationRequestThrowsOperationCancelledException()
+        public void DuplexStreaming_WriteAfterCancellationRequestThrowsTaskCanceledException()
         {
             asyncCall.StartDuplexStreamingCall();
             var requestStream = new ClientRequestStream<string, string>(asyncCall);
@@ -419,7 +424,9 @@
 
             asyncCall.Cancel();
             Assert.IsTrue(fakeCall.IsCancelled);
-            Assert.Throws(typeof(OperationCanceledException), () => requestStream.WriteAsync("request1"));
+
+            var writeTask = requestStream.WriteAsync("request1");
+            Assert.ThrowsAsync(typeof(TaskCanceledException), async () => await writeTask);
 
             var readTask = responseStream.MoveNext();
             fakeCall.ReceivedMessageHandler(true, null);
diff --git a/src/csharp/Grpc.Core.Tests/Internal/CompletionQueueSafeHandleTest.cs b/src/csharp/Grpc.Core.Tests/Internal/CompletionQueueSafeHandleTest.cs
index 195119f..e9ec59e 100644
--- a/src/csharp/Grpc.Core.Tests/Internal/CompletionQueueSafeHandleTest.cs
+++ b/src/csharp/Grpc.Core.Tests/Internal/CompletionQueueSafeHandleTest.cs
@@ -48,7 +48,7 @@
             GrpcEnvironment.AddRef();
             var cq = CompletionQueueSafeHandle.Create();
             cq.Dispose();
-            GrpcEnvironment.Release();
+            GrpcEnvironment.ReleaseAsync().Wait();
         }
 
         [Test]
@@ -59,7 +59,7 @@
             cq.Shutdown();
             var ev = cq.Next();
             cq.Dispose();
-            GrpcEnvironment.Release();
+            GrpcEnvironment.ReleaseAsync().Wait();
             Assert.AreEqual(CompletionQueueEvent.CompletionType.Shutdown, ev.type);
             Assert.AreNotEqual(IntPtr.Zero, ev.success);
             Assert.AreEqual(IntPtr.Zero, ev.tag);
diff --git a/src/csharp/Grpc.Core.Tests/MarshallingErrorsTest.cs b/src/csharp/Grpc.Core.Tests/MarshallingErrorsTest.cs
index 0663e77..d770f82 100644
--- a/src/csharp/Grpc.Core.Tests/MarshallingErrorsTest.cs
+++ b/src/csharp/Grpc.Core.Tests/MarshallingErrorsTest.cs
@@ -134,7 +134,15 @@
         {
             helper.ClientStreamingHandler = new ClientStreamingServerMethod<string, string>(async (requestStream, context) =>
             {
-                Assert.ThrowsAsync<IOException>(async () => await requestStream.MoveNext());
+                try
+                {
+                    // cannot use Assert.ThrowsAsync because it uses Task.Wait and would deadlock.
+                    await requestStream.MoveNext();
+                    Assert.Fail();
+                }
+                catch (IOException)
+                {
+                }
                 return "RESPONSE";
             });
 
diff --git a/src/csharp/Grpc.Core.Tests/MockServiceHelper.cs b/src/csharp/Grpc.Core.Tests/MockServiceHelper.cs
index 3047314..4d90470 100644
--- a/src/csharp/Grpc.Core.Tests/MockServiceHelper.cs
+++ b/src/csharp/Grpc.Core.Tests/MockServiceHelper.cs
@@ -102,7 +102,7 @@
                 marshaller,
                 marshaller);
 
-            serviceDefinition = ServerServiceDefinition.CreateBuilder(ServiceName)
+            serviceDefinition = ServerServiceDefinition.CreateBuilder()
                 .AddMethod(unaryMethod, (request, context) => unaryHandler(request, context))
                 .AddMethod(clientStreamingMethod, (requestStream, context) => clientStreamingHandler(requestStream, context))
                 .AddMethod(serverStreamingMethod, (request, responseStream, context) => serverStreamingHandler(request, responseStream, context))
diff --git a/src/csharp/Grpc.Core.Tests/PInvokeTest.cs b/src/csharp/Grpc.Core.Tests/PInvokeTest.cs
index d2b2fc6..d3735c7 100644
--- a/src/csharp/Grpc.Core.Tests/PInvokeTest.cs
+++ b/src/csharp/Grpc.Core.Tests/PInvokeTest.cs
@@ -65,7 +65,7 @@
                     cq.Dispose();
                 });
 
-            GrpcEnvironment.Release();
+            GrpcEnvironment.ReleaseAsync().Wait();
         }
 
         /// <summary>
diff --git a/src/csharp/Grpc.Core.Tests/ServerTest.cs b/src/csharp/Grpc.Core.Tests/ServerTest.cs
index b40508a..3b51aa6 100644
--- a/src/csharp/Grpc.Core.Tests/ServerTest.cs
+++ b/src/csharp/Grpc.Core.Tests/ServerTest.cs
@@ -89,9 +89,24 @@
             };
             server.Start();
             Assert.Throws(typeof(InvalidOperationException), () => server.Ports.Add("localhost", 9999, ServerCredentials.Insecure));
-            Assert.Throws(typeof(InvalidOperationException), () => server.Services.Add(ServerServiceDefinition.CreateBuilder("serviceName").Build()));
+            Assert.Throws(typeof(InvalidOperationException), () => server.Services.Add(ServerServiceDefinition.CreateBuilder().Build()));
 
             server.ShutdownAsync().Wait();
         }
+
+        [Test]
+        public void UnstartedServerCanBeShutdown()
+        {
+            var server = new Server();
+            server.ShutdownAsync().Wait();
+            Assert.Throws(typeof(InvalidOperationException), () => server.Start());
+        }
+
+        [Test]
+        public void UnstartedServerDoesNotPreventShutdown()
+        {
+            // just create a server, don't start it, and make sure it doesn't prevent shutdown.
+            var server = new Server();
+        }
     }
 }
diff --git a/src/proto/grpc/testing/perf_db.proto b/src/csharp/Grpc.Core.Tests/ShutdownHookClientTest.cs
similarity index 62%
rename from src/proto/grpc/testing/perf_db.proto
rename to src/csharp/Grpc.Core.Tests/ShutdownHookClientTest.cs
index 0ba8596..12b8452 100644
--- a/src/proto/grpc/testing/perf_db.proto
+++ b/src/csharp/Grpc.Core.Tests/ShutdownHookClientTest.cs
@@ -1,3 +1,5 @@
+#region Copyright notice and license
+
 // Copyright 2015, Google Inc.
 // All rights reserved.
 //
@@ -27,43 +29,29 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-syntax = "proto3";
+#endregion
 
-import "src/proto/grpc/testing/control.proto";
+using System;
+using System.Diagnostics;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+using Grpc.Core;
+using Grpc.Core.Internal;
+using Grpc.Core.Utils;
+using NUnit.Framework;
 
-package grpc.testing;
+namespace Grpc.Core.Tests
+{
+    public class ShutdownHookClientTest
+    {
+        const string Host = "127.0.0.1";
 
-service PerfDbTransfer {
-  // Sends client info
-  rpc RecordSingleClientData(SingleUserRecordRequest)
-      returns (SingleUserRecordReply) {}
+        [Test]
+        public void ProcessExitHookCanCleanupAbandonedChannels()
+        {
+            var channel = new Channel(Host, 1000, ChannelCredentials.Insecure);
+            var channel2 = new Channel(Host, 1001, ChannelCredentials.Insecure);
+        }
+    }
 }
-
-// Metrics to be stored
-message Metrics {
-  double qps = 1;
-  double qps_per_core = 2;
-  double perc_lat_50 = 3;
-  double perc_lat_90 = 4;
-  double perc_lat_95 = 5;
-  double perc_lat_99 = 6;
-  double perc_lat_99_point_9 = 7;
-  double server_system_time = 8;
-  double server_user_time = 9;
-  double client_system_time = 10;
-  double client_user_time = 11;
-}
-
-// Request for storing a single user's data
-message SingleUserRecordRequest {
-  string hashed_id = 1;
-  string test_name = 2;
-  string sys_info = 3;
-  string tag = 4;
-  Metrics metrics = 5;
-  ClientConfig client_config = 6;
-  ServerConfig server_config = 7;
-}
-
-// Reply to request for storing single user's data
-message SingleUserRecordReply {}
diff --git a/src/csharp/Grpc.Core.Tests/ShutdownHookPendingCallTest.cs b/src/csharp/Grpc.Core.Tests/ShutdownHookPendingCallTest.cs
new file mode 100644
index 0000000..1752338
--- /dev/null
+++ b/src/csharp/Grpc.Core.Tests/ShutdownHookPendingCallTest.cs
@@ -0,0 +1,69 @@
+#region Copyright notice and license
+
+// Copyright 2015, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#endregion
+
+using System;
+using System.Diagnostics;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+using Grpc.Core;
+using Grpc.Core.Internal;
+using Grpc.Core.Utils;
+using NUnit.Framework;
+
+namespace Grpc.Core.Tests
+{
+    public class ShutdownHookPendingCallTest
+    {
+        const string Host = "127.0.0.1";
+
+        [Test]
+        public void ProcessExitHookCanCleanupAbandonedCall()
+        {
+            var helper = new MockServiceHelper(Host);
+            var server = helper.GetServer();
+            server.Start();
+            var channel = helper.GetChannel();
+
+            var readyToShutdown = new TaskCompletionSource<object>();
+            helper.DuplexStreamingHandler = new DuplexStreamingServerMethod<string, string>(async (requestStream, responseStream, context) =>
+            {
+                readyToShutdown.SetResult(null);
+                await requestStream.ToListAsync();
+            });
+
+            var call = Calls.AsyncDuplexStreamingCall(helper.CreateDuplexStreamingCall());
+            readyToShutdown.Task.Wait();  // make sure handler is running
+        }
+    }
+}
diff --git a/src/proto/grpc/testing/perf_db.proto b/src/csharp/Grpc.Core.Tests/ShutdownHookServerTest.cs
similarity index 62%
copy from src/proto/grpc/testing/perf_db.proto
copy to src/csharp/Grpc.Core.Tests/ShutdownHookServerTest.cs
index 0ba8596..e7ea7a0 100644
--- a/src/proto/grpc/testing/perf_db.proto
+++ b/src/csharp/Grpc.Core.Tests/ShutdownHookServerTest.cs
@@ -1,3 +1,5 @@
+#region Copyright notice and license
+
 // Copyright 2015, Google Inc.
 // All rights reserved.
 //
@@ -27,43 +29,30 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-syntax = "proto3";
+#endregion
 
-import "src/proto/grpc/testing/control.proto";
+using System;
+using System.Diagnostics;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+using Grpc.Core;
+using Grpc.Core.Internal;
+using Grpc.Core.Utils;
+using NUnit.Framework;
 
-package grpc.testing;
+namespace Grpc.Core.Tests
+{
+    public class ShutdownHookServerTest
+    {
+        const string Host = "127.0.0.1";
 
-service PerfDbTransfer {
-  // Sends client info
-  rpc RecordSingleClientData(SingleUserRecordRequest)
-      returns (SingleUserRecordReply) {}
+        [Test]
+        public void ProcessExitHookCanCleanupAbandonedServers()
+        {
+            var helper = new MockServiceHelper(Host);
+            var server = helper.GetServer();
+            server.Start();
+        }
+    }
 }
-
-// Metrics to be stored
-message Metrics {
-  double qps = 1;
-  double qps_per_core = 2;
-  double perc_lat_50 = 3;
-  double perc_lat_90 = 4;
-  double perc_lat_95 = 5;
-  double perc_lat_99 = 6;
-  double perc_lat_99_point_9 = 7;
-  double server_system_time = 8;
-  double server_user_time = 9;
-  double client_system_time = 10;
-  double client_user_time = 11;
-}
-
-// Request for storing a single user's data
-message SingleUserRecordRequest {
-  string hashed_id = 1;
-  string test_name = 2;
-  string sys_info = 3;
-  string tag = 4;
-  Metrics metrics = 5;
-  ClientConfig client_config = 6;
-  ServerConfig server_config = 7;
-}
-
-// Reply to request for storing single user's data
-message SingleUserRecordReply {}
diff --git a/src/csharp/Grpc.Core/AsyncClientStreamingCall.cs b/src/csharp/Grpc.Core/AsyncClientStreamingCall.cs
index 5646fed..02b08d2 100644
--- a/src/csharp/Grpc.Core/AsyncClientStreamingCall.cs
+++ b/src/csharp/Grpc.Core/AsyncClientStreamingCall.cs
@@ -127,6 +127,10 @@
         /// Otherwise, requests cancellation of the call which should terminate all pending async operations associated with the call.
         /// As a result, all resources being used by the call should be released eventually.
         /// </summary>
+        /// <remarks>
+        /// Normally, there is no need for you to dispose the call unless you want to utilize the
+        /// "Cancel" semantics of invoking <c>Dispose</c>.
+        /// </remarks>
         public void Dispose()
         {
             disposeAction.Invoke();
diff --git a/src/csharp/Grpc.Core/AsyncDuplexStreamingCall.cs b/src/csharp/Grpc.Core/AsyncDuplexStreamingCall.cs
index e75108c..68fd6d0 100644
--- a/src/csharp/Grpc.Core/AsyncDuplexStreamingCall.cs
+++ b/src/csharp/Grpc.Core/AsyncDuplexStreamingCall.cs
@@ -117,6 +117,10 @@
         /// Otherwise, requests cancellation of the call which should terminate all pending async operations associated with the call.
         /// As a result, all resources being used by the call should be released eventually.
         /// </summary>
+        /// <remarks>
+        /// Normally, there is no need for you to dispose the call unless you want to utilize the
+        /// "Cancel" semantics of invoking <c>Dispose</c>.
+        /// </remarks>
         public void Dispose()
         {
             disposeAction.Invoke();
diff --git a/src/csharp/Grpc.Core/AsyncServerStreamingCall.cs b/src/csharp/Grpc.Core/AsyncServerStreamingCall.cs
index f953091..5777c72 100644
--- a/src/csharp/Grpc.Core/AsyncServerStreamingCall.cs
+++ b/src/csharp/Grpc.Core/AsyncServerStreamingCall.cs
@@ -103,6 +103,10 @@
         /// Otherwise, requests cancellation of the call which should terminate all pending async operations associated with the call.
         /// As a result, all resources being used by the call should be released eventually.
         /// </summary>
+        /// <remarks>
+        /// Normally, there is no need for you to dispose the call unless you want to utilize the
+        /// "Cancel" semantics of invoking <c>Dispose</c>.
+        /// </remarks>
         public void Dispose()
         {
             disposeAction.Invoke();
diff --git a/src/csharp/Grpc.Core/AsyncUnaryCall.cs b/src/csharp/Grpc.Core/AsyncUnaryCall.cs
index 97df8f5..d180c27 100644
--- a/src/csharp/Grpc.Core/AsyncUnaryCall.cs
+++ b/src/csharp/Grpc.Core/AsyncUnaryCall.cs
@@ -112,6 +112,10 @@
         /// Otherwise, requests cancellation of the call which should terminate all pending async operations associated with the call.
         /// As a result, all resources being used by the call should be released eventually.
         /// </summary>
+        /// <remarks>
+        /// Normally, there is no need for you to dispose the call unless you want to utilize the
+        /// "Cancel" semantics of invoking <c>Dispose</c>.
+        /// </remarks>
         public void Dispose()
         {
             disposeAction.Invoke();
diff --git a/src/csharp/Grpc.Core/CallOptions.cs b/src/csharp/Grpc.Core/CallOptions.cs
index 9ca8884..35548cf 100644
--- a/src/csharp/Grpc.Core/CallOptions.cs
+++ b/src/csharp/Grpc.Core/CallOptions.cs
@@ -88,7 +88,13 @@
         }
 
         /// <summary>
-        /// Token that can be used for cancelling the call.
+        /// Token that can be used for cancelling the call on the client side.
+        /// Cancelling the token will request cancellation
+        /// of the remote call. Best effort will be made to deliver the cancellation
+        /// notification to the server and interaction of the call with the server side
+        /// will be terminated. Unless the call finishes before the cancellation could
+        /// happen (there is an inherent race),
+        /// the call will finish with <c>StatusCode.Cancelled</c> status.
         /// </summary>
         public CancellationToken CancellationToken
         {
diff --git a/src/csharp/Grpc.Core/Channel.cs b/src/csharp/Grpc.Core/Channel.cs
index 93a6e6a..4f29c35 100644
--- a/src/csharp/Grpc.Core/Channel.cs
+++ b/src/csharp/Grpc.Core/Channel.cs
@@ -31,7 +31,6 @@
 
 using System;
 using System.Collections.Generic;
-using System.Linq;
 using System.Threading;
 using System.Threading.Tasks;
 
@@ -56,6 +55,7 @@
 
         readonly string target;
         readonly GrpcEnvironment environment;
+        readonly CompletionQueueSafeHandle completionQueue;
         readonly ChannelSafeHandle handle;
         readonly Dictionary<string, ChannelOption> options;
 
@@ -67,14 +67,26 @@
         /// </summary>
         /// <param name="target">Target of the channel.</param>
         /// <param name="credentials">Credentials to secure the channel.</param>
+        public Channel(string target, ChannelCredentials credentials) :
+            this(target, credentials, null)
+        {
+        }
+
+        /// <summary>
+        /// Creates a channel that connects to a specific host.
+        /// Port will default to 80 for an unsecure channel and to 443 for a secure channel.
+        /// </summary>
+        /// <param name="target">Target of the channel.</param>
+        /// <param name="credentials">Credentials to secure the channel.</param>
         /// <param name="options">Channel options.</param>
-        public Channel(string target, ChannelCredentials credentials, IEnumerable<ChannelOption> options = null)
+        public Channel(string target, ChannelCredentials credentials, IEnumerable<ChannelOption> options)
         {
             this.target = GrpcPreconditions.CheckNotNull(target, "target");
             this.options = CreateOptionsDictionary(options);
             EnsureUserAgentChannelOption(this.options);
             this.environment = GrpcEnvironment.AddRef();
 
+            this.completionQueue = this.environment.PickCompletionQueue();
             using (var nativeCredentials = credentials.ToNativeCredentials())
             using (var nativeChannelArgs = ChannelOptions.CreateChannelArgs(this.options.Values))
             {
@@ -87,6 +99,18 @@
                     this.handle = ChannelSafeHandle.CreateInsecure(target, nativeChannelArgs);
                 }
             }
+            GrpcEnvironment.RegisterChannel(this);
+        }
+
+        /// <summary>
+        /// Creates a channel that connects to a specific host and port.
+        /// </summary>
+        /// <param name="host">The name or IP address of the host.</param>
+        /// <param name="port">The port.</param>
+        /// <param name="credentials">Credentials to secure the channel.</param>
+        public Channel(string host, int port, ChannelCredentials credentials) :
+            this(host, port, credentials, null)
+        {
         }
 
         /// <summary>
@@ -96,14 +120,14 @@
         /// <param name="port">The port.</param>
         /// <param name="credentials">Credentials to secure the channel.</param>
         /// <param name="options">Channel options.</param>
-        public Channel(string host, int port, ChannelCredentials credentials, IEnumerable<ChannelOption> options = null) :
+        public Channel(string host, int port, ChannelCredentials credentials, IEnumerable<ChannelOption> options) :
             this(string.Format("{0}:{1}", host, port), credentials, options)
         {
         }
 
         /// <summary>
         /// Gets current connectivity state of this channel.
-        /// After channel is has been shutdown, <c>ChannelState.FatalFailure</c> will be returned.
+        /// After channel is has been shutdown, <c>ChannelState.Shutdown</c> will be returned.
         /// </summary>
         public ChannelState State
         {
@@ -120,8 +144,8 @@
         /// </summary>
         public Task WaitForStateChangedAsync(ChannelState lastObservedState, DateTime? deadline = null)
         {
-            GrpcPreconditions.CheckArgument(lastObservedState != ChannelState.FatalFailure,
-                "FatalFailure is a terminal state. No further state changes can occur.");
+            GrpcPreconditions.CheckArgument(lastObservedState != ChannelState.Shutdown,
+                "Shutdown is a terminal state. No further state changes can occur.");
             var tcs = new TaskCompletionSource<object>();
             var deadlineTimespec = deadline.HasValue ? Timespec.FromDateTime(deadline.Value) : Timespec.InfFuture;
             var handler = new BatchCompletionDelegate((success, ctx) =>
@@ -135,7 +159,7 @@
                     tcs.SetCanceled();
                 }
             });
-            handle.WatchConnectivityState(lastObservedState, deadlineTimespec, environment.CompletionQueue, environment.CompletionRegistry, handler);
+            handle.WatchConnectivityState(lastObservedState, deadlineTimespec, completionQueue, handler);
             return tcs.Task;
         }
 
@@ -171,7 +195,7 @@
         /// <summary>
         /// Allows explicitly requesting channel to connect without starting an RPC.
         /// Returned task completes once state Ready was seen. If the deadline is reached,
-        /// or channel enters the FatalFailure state, the task is cancelled.
+        /// or channel enters the Shutdown state, the task is cancelled.
         /// There is no need to call this explicitly unless your use case requires that.
         /// Starting an RPC on a new channel will request connection implicitly.
         /// </summary>
@@ -181,9 +205,9 @@
             var currentState = GetConnectivityState(true);
             while (currentState != ChannelState.Ready)
             {
-                if (currentState == ChannelState.FatalFailure)
+                if (currentState == ChannelState.Shutdown)
                 {
-                    throw new OperationCanceledException("Channel has reached FatalFailure state.");
+                    throw new OperationCanceledException("Channel has reached Shutdown state.");
                 }
                 await WaitForStateChangedAsync(currentState, deadline).ConfigureAwait(false);
                 currentState = GetConnectivityState(false);
@@ -191,9 +215,16 @@
         }
 
         /// <summary>
-        /// Waits until there are no more active calls for this channel and then cleans up
-        /// resources used by this channel.
+        /// Shuts down the channel cleanly. It is strongly recommended to shutdown
+        /// all previously created channels before exiting from the process.
         /// </summary>
+        /// <remarks>
+        /// This method doesn't wait for all calls on this channel to finish (nor does
+        /// it explicitly cancel all outstanding calls). It is user's responsibility to make sure
+        /// all the calls on this channel have finished (successfully or with an error)
+        /// before shutting down the channel to ensure channel shutdown won't impact
+        /// the outcome of those remote calls.
+        /// </remarks>
         public async Task ShutdownAsync()
         {
             lock (myLock)
@@ -201,6 +232,7 @@
                 GrpcPreconditions.CheckState(!shutdownRequested);
                 shutdownRequested = true;
             }
+            GrpcEnvironment.UnregisterChannel(this);
 
             shutdownTokenSource.Cancel();
 
@@ -212,7 +244,7 @@
 
             handle.Dispose();
 
-            await Task.Run(() => GrpcEnvironment.Release()).ConfigureAwait(false);
+            await GrpcEnvironment.ReleaseAsync().ConfigureAwait(false);
         }
 
         internal ChannelSafeHandle Handle
@@ -231,6 +263,14 @@
             }
         }
 
+        internal CompletionQueueSafeHandle CompletionQueue
+        {
+            get
+            {
+                return this.completionQueue;
+            }
+        }
+
         internal void AddCallReference(object call)
         {
             activeCallCounter.Increment();
@@ -255,7 +295,7 @@
             }
             catch (ObjectDisposedException)
             {
-                return ChannelState.FatalFailure;
+                return ChannelState.Shutdown;
             }
         }
 
diff --git a/src/csharp/Grpc.Core/ChannelState.cs b/src/csharp/Grpc.Core/ChannelState.cs
index d293b98..a6c3b2a 100644
--- a/src/csharp/Grpc.Core/ChannelState.cs
+++ b/src/csharp/Grpc.Core/ChannelState.cs
@@ -64,6 +64,6 @@
         /// <summary>
         /// Channel has seen a failure that it cannot recover from
         /// </summary>
-        FatalFailure
+        Shutdown
     }
 }
diff --git a/src/csharp/Grpc.Core/Grpc.Core.csproj b/src/csharp/Grpc.Core/Grpc.Core.csproj
index 4bf30e8..a796911 100644
--- a/src/csharp/Grpc.Core/Grpc.Core.csproj
+++ b/src/csharp/Grpc.Core/Grpc.Core.csproj
@@ -86,7 +86,6 @@
     <Compile Include="Utils\BenchmarkUtil.cs" />
     <Compile Include="ChannelCredentials.cs" />
     <Compile Include="Internal\ChannelArgsSafeHandle.cs" />
-    <Compile Include="Internal\AsyncCompletion.cs" />
     <Compile Include="Internal\AsyncCallBase.cs" />
     <Compile Include="Internal\AsyncCallServer.cs" />
     <Compile Include="Internal\AsyncCall.cs" />
@@ -137,6 +136,8 @@
     <Compile Include="Internal\ClientSideStatus.cs" />
     <Compile Include="Internal\ClockType.cs" />
     <Compile Include="Internal\CallError.cs" />
+    <Compile Include="Logging\LogLevel.cs" />
+    <Compile Include="Logging\LogLevelFilterLogger.cs" />
   </ItemGroup>
   <ItemGroup>
     <None Include="Grpc.Core.nuspec" />
diff --git a/src/csharp/Grpc.Core/GrpcEnvironment.cs b/src/csharp/Grpc.Core/GrpcEnvironment.cs
index bee0ef1..e9e4cb4 100644
--- a/src/csharp/Grpc.Core/GrpcEnvironment.cs
+++ b/src/csharp/Grpc.Core/GrpcEnvironment.cs
@@ -32,6 +32,8 @@
 #endregion
 
 using System;
+using System.Collections.Generic;
+using System.Linq;
 using System.Runtime.InteropServices;
 using System.Threading.Tasks;
 using Grpc.Core.Internal;
@@ -45,18 +47,24 @@
     /// </summary>
     public class GrpcEnvironment
     {
+        const LogLevel DefaultLogLevel = LogLevel.Info;
         const int MinDefaultThreadPoolSize = 4;
 
         static object staticLock = new object();
         static GrpcEnvironment instance;
         static int refCount;
         static int? customThreadPoolSize;
+        static int? customCompletionQueueCount;
+        static readonly HashSet<Channel> registeredChannels = new HashSet<Channel>();
+        static readonly HashSet<Server> registeredServers = new HashSet<Server>();
 
-        static ILogger logger = new ConsoleLogger();
+        static ILogger logger = new LogLevelFilterLogger(new ConsoleLogger(), DefaultLogLevel);
 
+        readonly object myLock = new object();
         readonly GrpcThreadPool threadPool;
-        readonly CompletionRegistry completionRegistry;
         readonly DebugStats debugStats = new DebugStats();
+        readonly AtomicCounter cqPickerCounter = new AtomicCounter();
+
         bool isClosed;
 
         /// <summary>
@@ -65,6 +73,8 @@
         /// </summary>
         internal static GrpcEnvironment AddRef()
         {
+            ShutdownHooks.Register();
+
             lock (staticLock)
             {
                 refCount++;
@@ -77,21 +87,26 @@
         }
 
         /// <summary>
-        /// Decrements the reference count for currently active environment and shuts down the gRPC environment if reference count drops to zero.
-        /// (and blocks until the environment has been fully shutdown).
+        /// Decrements the reference count for currently active environment and asynchronously shuts down the gRPC environment if reference count drops to zero.
         /// </summary>
-        internal static void Release()
+        internal static async Task ReleaseAsync()
         {
+            GrpcEnvironment instanceToShutdown = null;
             lock (staticLock)
             {
                 GrpcPreconditions.CheckState(refCount > 0);
                 refCount--;
                 if (refCount == 0)
                 {
-                    instance.Close();
+                    instanceToShutdown = instance;
                     instance = null;
                 }
             }
+
+            if (instanceToShutdown != null)
+            {
+                await instanceToShutdown.ShutdownAsync();
+            }
         }
 
         internal static int GetRefCount()
@@ -102,6 +117,68 @@
             }
         }
 
+        internal static void RegisterChannel(Channel channel)
+        {
+            lock (staticLock)
+            {
+                GrpcPreconditions.CheckNotNull(channel);
+                registeredChannels.Add(channel);
+            }
+        }
+
+        internal static void UnregisterChannel(Channel channel)
+        {
+            lock (staticLock)
+            {
+                GrpcPreconditions.CheckNotNull(channel);
+                GrpcPreconditions.CheckArgument(registeredChannels.Remove(channel), "Channel not found in the registered channels set.");
+            }
+        }
+
+        internal static void RegisterServer(Server server)
+        {
+            lock (staticLock)
+            {
+                GrpcPreconditions.CheckNotNull(server);
+                registeredServers.Add(server);
+            }
+        }
+
+        internal static void UnregisterServer(Server server)
+        {
+            lock (staticLock)
+            {
+                GrpcPreconditions.CheckNotNull(server);
+                GrpcPreconditions.CheckArgument(registeredServers.Remove(server), "Server not found in the registered servers set.");
+            }
+        }
+
+        /// <summary>
+        /// Requests shutdown of all channels created by the current process.
+        /// </summary>
+        public static Task ShutdownChannelsAsync()
+        {
+            HashSet<Channel> snapshot = null;
+            lock (staticLock)
+            {
+                snapshot = new HashSet<Channel>(registeredChannels);
+            }
+            return Task.WhenAll(snapshot.Select((channel) => channel.ShutdownAsync()));
+        }
+
+        /// <summary>
+        /// Requests immediate shutdown of all servers created by the current process.
+        /// </summary>
+        public static Task KillServersAsync()
+        {
+            HashSet<Server> snapshot = null;
+            lock (staticLock)
+            {
+                snapshot = new HashSet<Server>(registeredServers);
+            }
+            return Task.WhenAll(snapshot.Select((server) => server.KillAsync()));
+        }
+
         /// <summary>
         /// Gets application-wide logger used by gRPC.
         /// </summary>
@@ -141,36 +218,59 @@
         }
 
         /// <summary>
+        /// Sets the number of completion queues in the  gRPC thread pool that polls for internal RPC events.
+        /// Can be only invoke before the <c>GrpcEnviroment</c> is started and cannot be changed afterwards.
+        /// Setting the number of completions queues is an advanced setting and you should only use it if you know what you are doing.
+        /// Most users should rely on the default value provided by gRPC library.
+        /// Note: this method is part of an experimental API that can change or be removed without any prior notice.
+        /// </summary>
+        public static void SetCompletionQueueCount(int completionQueueCount)
+        {
+            lock (staticLock)
+            {
+                GrpcPreconditions.CheckState(instance == null, "Can only be set before GrpcEnvironment is initialized");
+                GrpcPreconditions.CheckArgument(completionQueueCount > 0, "threadCount needs to be a positive number");
+                customCompletionQueueCount = completionQueueCount;
+            }
+        }
+
+        /// <summary>
         /// Creates gRPC environment.
         /// </summary>
         private GrpcEnvironment()
         {
             GrpcNativeInit();
-            completionRegistry = new CompletionRegistry(this);
-            threadPool = new GrpcThreadPool(this, GetThreadPoolSizeOrDefault());
+            threadPool = new GrpcThreadPool(this, GetThreadPoolSizeOrDefault(), GetCompletionQueueCountOrDefault());
             threadPool.Start();
         }
 
         /// <summary>
-        /// Gets the completion registry used by this gRPC environment.
+        /// Gets the completion queues used by this gRPC environment.
         /// </summary>
-        internal CompletionRegistry CompletionRegistry
+        internal IReadOnlyCollection<CompletionQueueSafeHandle> CompletionQueues
         {
             get
             {
-                return this.completionRegistry;
+                return this.threadPool.CompletionQueues;
+            }
+        }
+
+        internal bool IsAlive
+        {
+            get
+            {
+                return this.threadPool.IsAlive;
             }
         }
 
         /// <summary>
-        /// Gets the completion queue used by this gRPC environment.
+        /// Picks a completion queue in a round-robin fashion.
+        /// Shouldn't be invoked on a per-call basis (used at per-channel basis).
         /// </summary>
-        internal CompletionQueueSafeHandle CompletionQueue
+        internal CompletionQueueSafeHandle PickCompletionQueue()
         {
-            get
-            {
-                return this.threadPool.CompletionQueue;
-            }
+            var cqIndex = (int) ((cqPickerCounter.Increment() - 1) % this.threadPool.CompletionQueues.Count);
+            return this.threadPool.CompletionQueues.ElementAt(cqIndex);
         }
 
         /// <summary>
@@ -206,13 +306,13 @@
         /// <summary>
         /// Shuts down this environment.
         /// </summary>
-        private void Close()
+        private async Task ShutdownAsync()
         {
             if (isClosed)
             {
                 throw new InvalidOperationException("Close has already been called");
             }
-            threadPool.Stop();
+            await threadPool.StopAsync().ConfigureAwait(false);
             GrpcNativeShutdown();
             isClosed = true;
 
@@ -230,5 +330,42 @@
             // more work, but seems to work reasonably well for a start.
             return Math.Max(MinDefaultThreadPoolSize, Environment.ProcessorCount / 2);
         }
+
+        private int GetCompletionQueueCountOrDefault()
+        {
+            if (customCompletionQueueCount.HasValue)
+            {
+                return customCompletionQueueCount.Value;
+            }
+            // by default, create a completion queue for each thread
+            return GetThreadPoolSizeOrDefault();
+        }
+
+        private static class ShutdownHooks
+        {
+            static object staticLock = new object();
+            static bool hooksRegistered;
+
+            public static void Register()
+            {
+                lock (staticLock)
+                {
+                    if (!hooksRegistered)
+                    {
+                        AppDomain.CurrentDomain.ProcessExit += ShutdownHookHandler;
+                        AppDomain.CurrentDomain.DomainUnload += ShutdownHookHandler;
+                    }
+                    hooksRegistered = true;
+                }
+            }
+
+            /// <summary>
+            /// Handler for AppDomain.DomainUnload and AppDomain.ProcessExit hooks.
+            /// </summary>
+            private static void ShutdownHookHandler(object sender, EventArgs e)
+            {
+                Task.WaitAll(GrpcEnvironment.ShutdownChannelsAsync(), GrpcEnvironment.KillServersAsync());
+            }
+        }
     }
 }
diff --git a/src/csharp/Grpc.Core/Internal/AsyncCall.cs b/src/csharp/Grpc.Core/Internal/AsyncCall.cs
index 5535186..895be69 100644
--- a/src/csharp/Grpc.Core/Internal/AsyncCall.cs
+++ b/src/csharp/Grpc.Core/Internal/AsyncCall.cs
@@ -32,12 +32,7 @@
 #endregion
 
 using System;
-using System.Diagnostics;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-using System.Threading;
 using System.Threading.Tasks;
-using Grpc.Core.Internal;
 using Grpc.Core.Logging;
 using Grpc.Core.Profiling;
 using Grpc.Core.Utils;
@@ -57,9 +52,11 @@
         // Completion of a pending unary response if not null.
         TaskCompletionSource<TResponse> unaryResponseTcs;
 
+        // TODO(jtattermusch): this field doesn't need to be initialized for unary response calls.
         // Indicates that response streaming call has finished.
         TaskCompletionSource<object> streamingCallFinishedTcs = new TaskCompletionSource<object>();
 
+        // TODO(jtattermusch): this field could be lazy-initialized (only if someone requests the response headers).
         // Response headers set here once received.
         TaskCompletionSource<Metadata> responseHeadersTcs = new TaskCompletionSource<Metadata>();
 
@@ -67,7 +64,7 @@
         ClientSideStatus? finishedStatus;
 
         public AsyncCall(CallInvocationDetails<TRequest, TResponse> callDetails)
-            : base(callDetails.RequestMarshaller.Serializer, callDetails.ResponseMarshaller.Deserializer, callDetails.Channel.Environment)
+            : base(callDetails.RequestMarshaller.Serializer, callDetails.ResponseMarshaller.Deserializer)
         {
             this.details = callDetails.WithOptions(callDetails.Options.Normalize());
             this.initialMetadataSent = true;  // we always send metadata at the very beginning of the call.
@@ -144,7 +141,7 @@
                 GrpcPreconditions.CheckState(!started);
                 started = true;
 
-                Initialize(environment.CompletionQueue);
+                Initialize(details.Channel.CompletionQueue);
 
                 halfcloseRequested = true;
                 readingDone = true;
@@ -171,7 +168,7 @@
                 GrpcPreconditions.CheckState(!started);
                 started = true;
 
-                Initialize(environment.CompletionQueue);
+                Initialize(details.Channel.CompletionQueue);
 
                 readingDone = true;
 
@@ -195,7 +192,7 @@
                 GrpcPreconditions.CheckState(!started);
                 started = true;
 
-                Initialize(environment.CompletionQueue);
+                Initialize(details.Channel.CompletionQueue);
 
                 halfcloseRequested = true;
 
@@ -220,7 +217,7 @@
                 GrpcPreconditions.CheckState(!started);
                 started = true;
 
-                Initialize(environment.CompletionQueue);
+                Initialize(details.Channel.CompletionQueue);
 
                 using (var metadataArray = MetadataArraySafeHandle.Create(details.Options.Headers))
                 {
@@ -232,11 +229,10 @@
 
         /// <summary>
         /// Sends a streaming request. Only one pending send action is allowed at any given time.
-        /// completionDelegate is called when the operation finishes.
         /// </summary>
-        public void StartSendMessage(TRequest msg, WriteFlags writeFlags, AsyncCompletionDelegate<object> completionDelegate)
+        public Task SendMessageAsync(TRequest msg, WriteFlags writeFlags)
         {
-            StartSendMessageInternal(msg, writeFlags, completionDelegate);
+            return SendMessageInternalAsync(msg, writeFlags);
         }
 
         /// <summary>
@@ -250,29 +246,32 @@
         /// <summary>
         /// Sends halfclose, indicating client is done with streaming requests.
         /// Only one pending send action is allowed at any given time.
-        /// completionDelegate is called when the operation finishes.
         /// </summary>
-        public void StartSendCloseFromClient(AsyncCompletionDelegate<object> completionDelegate)
+        public Task SendCloseFromClientAsync()
         {
             lock (myLock)
             {
-                GrpcPreconditions.CheckNotNull(completionDelegate, "Completion delegate cannot be null");
-                CheckSendingAllowed(allowFinished: true);
+                GrpcPreconditions.CheckState(started);
 
-                if (!disposed && !finished)
+                var earlyResult = CheckSendPreconditionsClientSide();
+                if (earlyResult != null)
                 {
-                    call.StartSendCloseFromClient(HandleSendCloseFromClientFinished);
+                    return earlyResult;
                 }
-                else
+
+                if (disposed || finished)
                 {
                     // In case the call has already been finished by the serverside,
-                    // the halfclose has already been done implicitly, so we only
-                    // emit the notification for the completion delegate.
-                    Task.Run(() => HandleSendCloseFromClientFinished(true));
+                    // the halfclose has already been done implicitly, so just return
+                    // completed task here.
+                    halfcloseRequested = true;
+                    return Task.FromResult<object>(null);
                 }
+                call.StartSendCloseFromClient(HandleSendCloseFromClientFinished);
 
                 halfcloseRequested = true;
-                sendCompletionDelegate = completionDelegate;
+                streamingWriteTcs = new TaskCompletionSource<object>();
+                return streamingWriteTcs.Task;
             }
         }
 
@@ -342,6 +341,45 @@
             get { return true; }
         }
 
+        protected override Task CheckSendAllowedOrEarlyResult()
+        {
+            var earlyResult = CheckSendPreconditionsClientSide();
+            if (earlyResult != null)
+            {
+                return earlyResult;
+            }
+
+            if (finishedStatus.HasValue)
+            {
+                // throwing RpcException if we already received status on client
+                // side makes the most sense.
+                // Note that this throws even for StatusCode.OK.
+                // Writing after the call has finished is not a programming error because server can close
+                // the call anytime, so don't throw directly, but let the write task finish with an error.
+                var tcs = new TaskCompletionSource<object>();
+                tcs.SetException(new RpcException(finishedStatus.Value.Status));
+                return tcs.Task;
+            }
+
+            return null;
+        }
+
+        private Task CheckSendPreconditionsClientSide()
+        {
+            GrpcPreconditions.CheckState(!halfcloseRequested, "Request stream has already been completed.");
+            GrpcPreconditions.CheckState(streamingWriteTcs == null, "Only one write can be pending at a time.");
+
+            if (cancelRequested)
+            {
+                // Return a cancelled task.
+                var tcs = new TaskCompletionSource<object>();
+                tcs.SetCanceled();
+                return tcs.Task;
+            }
+
+            return null;
+        }
+
         private void Initialize(CompletionQueueSafeHandle cq)
         {
             using (Profilers.ForCurrentThread().NewScope("AsyncCall.Initialize"))
@@ -368,7 +406,7 @@
                 var credentials = details.Options.Credentials;
                 using (var nativeCredentials = credentials != null ? credentials.ToNativeCredentials() : null)
                 {
-                    var result = details.Channel.Handle.CreateCall(environment.CompletionRegistry,
+                    var result = details.Channel.Handle.CreateCall(
                                  parentCall, ContextPropagationToken.DefaultMask, cq,
                                  details.Method, details.Host, Timespec.FromDateTime(details.Options.Deadline.Value), nativeCredentials);
                     return result;
@@ -400,6 +438,7 @@
         /// </summary>
         private void HandleReceivedResponseHeaders(bool success, Metadata responseHeaders)
         {
+            // TODO(jtattermusch): handle success==false
             responseHeadersTcs.SetResult(responseHeaders);
         }
 
@@ -443,19 +482,6 @@
             }
         }
 
-        protected override void CheckSendingAllowed(bool allowFinished)
-        {
-            base.CheckSendingAllowed(true);
-
-            // throwing RpcException if we already received status on client
-            // side makes the most sense.
-            // Note that this throws even for StatusCode.OK.
-            if (!allowFinished && finishedStatus.HasValue)
-            {
-                throw new RpcException(finishedStatus.Value.Status);
-            }
-        }
-
         /// <summary>
         /// Handles receive status completion for calls with streaming response.
         /// </summary>
diff --git a/src/csharp/Grpc.Core/Internal/AsyncCallBase.cs b/src/csharp/Grpc.Core/Internal/AsyncCallBase.cs
index 4de2370..cb8366c 100644
--- a/src/csharp/Grpc.Core/Internal/AsyncCallBase.cs
+++ b/src/csharp/Grpc.Core/Internal/AsyncCallBase.cs
@@ -58,7 +58,6 @@
         readonly Func<TWrite, byte[]> serializer;
         readonly Func<byte[], TRead> deserializer;
 
-        protected readonly GrpcEnvironment environment;
         protected readonly object myLock = new object();
 
         protected INativeCall call;
@@ -67,8 +66,8 @@
         protected bool started;
         protected bool cancelRequested;
 
-        protected AsyncCompletionDelegate<object> sendCompletionDelegate;  // Completion of a pending send or sendclose if not null.
         protected TaskCompletionSource<TRead> streamingReadTcs;  // Completion of a pending streaming read if not null.
+        protected TaskCompletionSource<object> streamingWriteTcs;  // Completion of a pending streaming write or send close from client if not null.
         protected TaskCompletionSource<object> sendStatusFromServerTcs;
 
         protected bool readingDone;  // True if last read (i.e. read with null payload) was already received.
@@ -78,11 +77,10 @@
         protected bool initialMetadataSent;
         protected long streamingWritesCounter;  // Number of streaming send operations started so far.
 
-        public AsyncCallBase(Func<TWrite, byte[]> serializer, Func<byte[], TRead> deserializer, GrpcEnvironment environment)
+        public AsyncCallBase(Func<TWrite, byte[]> serializer, Func<byte[], TRead> deserializer)
         {
             this.serializer = GrpcPreconditions.CheckNotNull(serializer);
             this.deserializer = GrpcPreconditions.CheckNotNull(deserializer);
-            this.environment = GrpcPreconditions.CheckNotNull(environment);
         }
 
         /// <summary>
@@ -128,28 +126,31 @@
 
         /// <summary>
         /// Initiates sending a message. Only one send operation can be active at a time.
-        /// completionDelegate is invoked upon completion.
         /// </summary>
-        protected void StartSendMessageInternal(TWrite msg, WriteFlags writeFlags, AsyncCompletionDelegate<object> completionDelegate)
+        protected Task SendMessageInternalAsync(TWrite msg, WriteFlags writeFlags)
         {
             byte[] payload = UnsafeSerialize(msg);
 
             lock (myLock)
             {
-                GrpcPreconditions.CheckNotNull(completionDelegate, "Completion delegate cannot be null");
-                CheckSendingAllowed(allowFinished: false);
+                GrpcPreconditions.CheckState(started);
+                var earlyResult = CheckSendAllowedOrEarlyResult();
+                if (earlyResult != null)
+                {
+                    return earlyResult;
+                }
 
                 call.StartSendMessage(HandleSendFinished, payload, writeFlags, !initialMetadataSent);
 
-                sendCompletionDelegate = completionDelegate;
                 initialMetadataSent = true;
                 streamingWritesCounter++;
+                streamingWriteTcs = new TaskCompletionSource<object>();
+                return streamingWriteTcs.Task;
             }
         }
 
         /// <summary>
         /// Initiates reading a message. Only one read operation can be active at a time.
-        /// completionDelegate is invoked upon completion.
         /// </summary>
         protected Task<TRead> ReadMessageInternalAsync()
         {
@@ -159,7 +160,7 @@
                 if (readingDone)
                 {
                     // the last read that returns null or throws an exception is idempotent
-                    // and maintain its state.
+                    // and maintains its state.
                     GrpcPreconditions.CheckState(streamingReadTcs != null, "Call does not support streaming reads.");
                     return streamingReadTcs.Task;
                 }
@@ -183,7 +184,7 @@
             {
                 if (!disposed && call != null)
                 {
-                    bool noMoreSendCompletions = sendCompletionDelegate == null && (halfcloseRequested || cancelRequested || finished);
+                    bool noMoreSendCompletions = streamingWriteTcs == null && (halfcloseRequested || cancelRequested || finished);
                     if (noMoreSendCompletions && readingDone && finished)
                     {
                         ReleaseResources();
@@ -213,24 +214,11 @@
         {
         }
 
-        protected virtual void CheckSendingAllowed(bool allowFinished)
-        {
-            GrpcPreconditions.CheckState(started);
-            CheckNotCancelled();
-            GrpcPreconditions.CheckState(!disposed || allowFinished);
-
-            GrpcPreconditions.CheckState(!halfcloseRequested, "Already halfclosed.");
-            GrpcPreconditions.CheckState(!finished || allowFinished, "Already finished.");
-            GrpcPreconditions.CheckState(sendCompletionDelegate == null, "Only one write can be pending at a time");
-        }
-
-        protected void CheckNotCancelled()
-        {
-            if (cancelRequested)
-            {
-                throw new OperationCanceledException("Remote call has been cancelled.");
-            }
-        }
+        /// <summary>
+        /// Checks if sending is allowed and possibly returns a Task that allows short-circuiting the send
+        /// logic by directly returning the write operation result task. Normally, null is returned.
+        /// </summary>
+        protected abstract Task CheckSendAllowedOrEarlyResult();
 
         protected byte[] UnsafeSerialize(TWrite msg)
         {
@@ -259,39 +247,27 @@
             }
         }
 
-        protected void FireCompletion<T>(AsyncCompletionDelegate<T> completionDelegate, T value, Exception error)
-        {
-            try
-            {
-                completionDelegate(value, error);
-            }
-            catch (Exception e)
-            {
-                Logger.Error(e, "Exception occured while invoking completion delegate.");
-            }
-        }
-
         /// <summary>
         /// Handles send completion.
         /// </summary>
         protected void HandleSendFinished(bool success)
         {
-            AsyncCompletionDelegate<object> origCompletionDelegate = null;
+            TaskCompletionSource<object> origTcs = null;
             lock (myLock)
             {
-                origCompletionDelegate = sendCompletionDelegate;
-                sendCompletionDelegate = null;
+                origTcs = streamingWriteTcs;
+                streamingWriteTcs = null;
 
                 ReleaseResourcesIfPossible();
             }
 
             if (!success)
             {
-                FireCompletion(origCompletionDelegate, null, new InvalidOperationException("Send failed"));
+                origTcs.SetException(new InvalidOperationException("Send failed"));
             }
             else
             {
-                FireCompletion(origCompletionDelegate, null, null);
+                origTcs.SetResult(null);
             }
         }
 
@@ -300,22 +276,23 @@
         /// </summary>
         protected void HandleSendCloseFromClientFinished(bool success)
         {
-            AsyncCompletionDelegate<object> origCompletionDelegate = null;
+            TaskCompletionSource<object> origTcs = null;
             lock (myLock)
             {
-                origCompletionDelegate = sendCompletionDelegate;
-                sendCompletionDelegate = null;
+                origTcs = streamingWriteTcs;
+                streamingWriteTcs = null;
 
                 ReleaseResourcesIfPossible();
             }
 
             if (!success)
             {
-                FireCompletion(origCompletionDelegate, null, new InvalidOperationException("Sending close from client has failed."));
+                // TODO(jtattermusch): this method is same as HandleSendFinished (only the error message differs).
+                origTcs.SetException(new InvalidOperationException("Sending close from client has failed."));
             }
             else
             {
-                FireCompletion(origCompletionDelegate, null, null);
+                origTcs.SetResult(null);
             }
         }
 
diff --git a/src/csharp/Grpc.Core/Internal/AsyncCallServer.cs b/src/csharp/Grpc.Core/Internal/AsyncCallServer.cs
index b1566b4..56c23ba 100644
--- a/src/csharp/Grpc.Core/Internal/AsyncCallServer.cs
+++ b/src/csharp/Grpc.Core/Internal/AsyncCallServer.cs
@@ -51,14 +51,14 @@
         readonly CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
         readonly Server server;
 
-        public AsyncCallServer(Func<TResponse, byte[]> serializer, Func<byte[], TRequest> deserializer, GrpcEnvironment environment, Server server) : base(serializer, deserializer, environment)
+        public AsyncCallServer(Func<TResponse, byte[]> serializer, Func<byte[], TRequest> deserializer, Server server) : base(serializer, deserializer)
         {
             this.server = GrpcPreconditions.CheckNotNull(server);
         }
 
-        public void Initialize(CallSafeHandle call)
+        public void Initialize(CallSafeHandle call, CompletionQueueSafeHandle completionQueue)
         {
-            call.Initialize(environment.CompletionRegistry, environment.CompletionQueue);
+            call.Initialize(completionQueue);
 
             server.AddCallReference(this);
             InitializeInternal(call);
@@ -91,11 +91,10 @@
 
         /// <summary>
         /// Sends a streaming response. Only one pending send action is allowed at any given time.
-        /// completionDelegate is called when the operation finishes.
         /// </summary>
-        public void StartSendMessage(TResponse msg, WriteFlags writeFlags, AsyncCompletionDelegate<object> completionDelegate)
+        public Task SendMessageAsync(TResponse msg, WriteFlags writeFlags)
         {
-            StartSendMessageInternal(msg, writeFlags, completionDelegate);
+            return SendMessageInternalAsync(msg, writeFlags);
         }
 
         /// <summary>
@@ -110,20 +109,22 @@
         /// Initiates sending a initial metadata. 
         /// Even though C-core allows sending metadata in parallel to sending messages, we will treat sending metadata as a send message operation
         /// to make things simpler.
-        /// completionDelegate is invoked upon completion.
         /// </summary>
-        public void StartSendInitialMetadata(Metadata headers, AsyncCompletionDelegate<object> completionDelegate)
+        public Task SendInitialMetadataAsync(Metadata headers)
         {
             lock (myLock)
             {
                 GrpcPreconditions.CheckNotNull(headers, "metadata");
-                GrpcPreconditions.CheckNotNull(completionDelegate, "Completion delegate cannot be null");
 
+                GrpcPreconditions.CheckState(started);
                 GrpcPreconditions.CheckState(!initialMetadataSent, "Response headers can only be sent once per call.");
                 GrpcPreconditions.CheckState(streamingWritesCounter == 0, "Response headers can only be sent before the first write starts.");
-                CheckSendingAllowed(allowFinished: false);
 
-                GrpcPreconditions.CheckNotNull(completionDelegate, "Completion delegate cannot be null");
+                var earlyResult = CheckSendAllowedOrEarlyResult();
+                if (earlyResult != null)
+                {
+                    return earlyResult;
+                }
 
                 using (var metadataArray = MetadataArraySafeHandle.Create(headers))
                 {
@@ -131,7 +132,8 @@
                 }
 
                 this.initialMetadataSent = true;
-                sendCompletionDelegate = completionDelegate;
+                streamingWriteTcs = new TaskCompletionSource<object>();
+                return streamingWriteTcs.Task;
             }
         }
 
@@ -196,6 +198,16 @@
             server.RemoveCallReference(this);
         }
 
+        protected override Task CheckSendAllowedOrEarlyResult()
+        {
+            GrpcPreconditions.CheckState(!halfcloseRequested, "Response stream has already been completed.");
+            GrpcPreconditions.CheckState(!finished, "Already finished.");
+            GrpcPreconditions.CheckState(streamingWriteTcs == null, "Only one write can be pending at a time");
+            GrpcPreconditions.CheckState(!disposed);
+
+            return null;
+        }
+
         /// <summary>
         /// Handles the server side close completion.
         /// </summary>
diff --git a/src/csharp/Grpc.Core/Internal/AsyncCompletion.cs b/src/csharp/Grpc.Core/Internal/AsyncCompletion.cs
deleted file mode 100644
index 7e86fdd..0000000
--- a/src/csharp/Grpc.Core/Internal/AsyncCompletion.cs
+++ /dev/null
@@ -1,94 +0,0 @@
-#region Copyright notice and license
-
-// Copyright 2015, Google Inc.
-// All rights reserved.
-// 
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// 
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-// 
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#endregion
-
-using System;
-using System.Diagnostics;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-using System.Threading;
-using System.Threading.Tasks;
-using Grpc.Core.Internal;
-using Grpc.Core.Utils;
-
-namespace Grpc.Core.Internal
-{
-    /// <summary>
-    /// If error != null, there's been an error or operation has been cancelled.
-    /// </summary>
-    internal delegate void AsyncCompletionDelegate<T>(T result, Exception error);
-
-    /// <summary>
-    /// Helper for transforming AsyncCompletionDelegate into full-fledged Task.
-    /// </summary>
-    internal class AsyncCompletionTaskSource<T>
-    {
-        readonly TaskCompletionSource<T> tcs = new TaskCompletionSource<T>();
-        readonly AsyncCompletionDelegate<T> completionDelegate;
-
-        public AsyncCompletionTaskSource()
-        {
-            completionDelegate = new AsyncCompletionDelegate<T>(HandleCompletion);
-        }
-
-        public Task<T> Task
-        {
-            get
-            {
-                return tcs.Task;
-            }
-        }
-
-        public AsyncCompletionDelegate<T> CompletionDelegate
-        {
-            get
-            {
-                return completionDelegate;
-            }
-        }
-
-        private void HandleCompletion(T value, Exception error)
-        {
-            if (error == null)
-            {
-                tcs.SetResult(value);
-                return;
-            }
-            if (error is OperationCanceledException)
-            {
-                tcs.SetCanceled();
-                return;
-            }
-            tcs.SetException(error);
-        }
-    }
-}
diff --git a/src/csharp/Grpc.Core/Internal/CallSafeHandle.cs b/src/csharp/Grpc.Core/Internal/CallSafeHandle.cs
index 244b97d..82361f5 100644
--- a/src/csharp/Grpc.Core/Internal/CallSafeHandle.cs
+++ b/src/csharp/Grpc.Core/Internal/CallSafeHandle.cs
@@ -47,16 +47,14 @@
         static readonly NativeMethods Native = NativeMethods.Get();
 
         const uint GRPC_WRITE_BUFFER_HINT = 1;
-        CompletionRegistry completionRegistry;
         CompletionQueueSafeHandle completionQueue;
 
         private CallSafeHandle()
         {
         }
 
-        public void Initialize(CompletionRegistry completionRegistry, CompletionQueueSafeHandle completionQueue)
+        public void Initialize(CompletionQueueSafeHandle completionQueue)
         {
-            this.completionRegistry = completionRegistry;
             this.completionQueue = completionQueue;
         }
 
@@ -70,7 +68,7 @@
             using (completionQueue.NewScope())
             {
                 var ctx = BatchContextSafeHandle.Create();
-                completionRegistry.RegisterBatchCompletion(ctx, (success, context) => callback(success, context.GetReceivedStatusOnClient(), context.GetReceivedMessage(), context.GetReceivedInitialMetadata()));
+                completionQueue.CompletionRegistry.RegisterBatchCompletion(ctx, (success, context) => callback(success, context.GetReceivedStatusOnClient(), context.GetReceivedMessage(), context.GetReceivedInitialMetadata()));
                 Native.grpcsharp_call_start_unary(this, ctx, payload, new UIntPtr((ulong)payload.Length), metadataArray, writeFlags)
                     .CheckOk();
             }
@@ -90,7 +88,7 @@
             using (completionQueue.NewScope())
             {
                 var ctx = BatchContextSafeHandle.Create();
-                completionRegistry.RegisterBatchCompletion(ctx, (success, context) => callback(success, context.GetReceivedStatusOnClient(), context.GetReceivedMessage(), context.GetReceivedInitialMetadata()));
+                completionQueue.CompletionRegistry.RegisterBatchCompletion(ctx, (success, context) => callback(success, context.GetReceivedStatusOnClient(), context.GetReceivedMessage(), context.GetReceivedInitialMetadata()));
                 Native.grpcsharp_call_start_client_streaming(this, ctx, metadataArray).CheckOk();
             }
         }
@@ -100,7 +98,7 @@
             using (completionQueue.NewScope())
             {
                 var ctx = BatchContextSafeHandle.Create();
-                completionRegistry.RegisterBatchCompletion(ctx, (success, context) => callback(success, context.GetReceivedStatusOnClient()));
+                completionQueue.CompletionRegistry.RegisterBatchCompletion(ctx, (success, context) => callback(success, context.GetReceivedStatusOnClient()));
                 Native.grpcsharp_call_start_server_streaming(this, ctx, payload, new UIntPtr((ulong)payload.Length), metadataArray, writeFlags).CheckOk();
             }
         }
@@ -110,7 +108,7 @@
             using (completionQueue.NewScope())
             {
                 var ctx = BatchContextSafeHandle.Create();
-                completionRegistry.RegisterBatchCompletion(ctx, (success, context) => callback(success, context.GetReceivedStatusOnClient()));
+                completionQueue.CompletionRegistry.RegisterBatchCompletion(ctx, (success, context) => callback(success, context.GetReceivedStatusOnClient()));
                 Native.grpcsharp_call_start_duplex_streaming(this, ctx, metadataArray).CheckOk();
             }
         }
@@ -120,7 +118,7 @@
             using (completionQueue.NewScope())
             {
                 var ctx = BatchContextSafeHandle.Create();
-                completionRegistry.RegisterBatchCompletion(ctx, (success, context) => callback(success));
+                completionQueue.CompletionRegistry.RegisterBatchCompletion(ctx, (success, context) => callback(success));
                 Native.grpcsharp_call_send_message(this, ctx, payload, new UIntPtr((ulong)payload.Length), writeFlags, sendEmptyInitialMetadata).CheckOk();
             }
         }
@@ -130,7 +128,7 @@
             using (completionQueue.NewScope())
             {
                 var ctx = BatchContextSafeHandle.Create();
-                completionRegistry.RegisterBatchCompletion(ctx, (success, context) => callback(success));
+                completionQueue.CompletionRegistry.RegisterBatchCompletion(ctx, (success, context) => callback(success));
                 Native.grpcsharp_call_send_close_from_client(this, ctx).CheckOk();
             }
         }
@@ -142,7 +140,7 @@
             {
                 var ctx = BatchContextSafeHandle.Create();
                 var optionalPayloadLength = optionalPayload != null ? new UIntPtr((ulong)optionalPayload.Length) : UIntPtr.Zero;
-                completionRegistry.RegisterBatchCompletion(ctx, (success, context) => callback(success));
+                completionQueue.CompletionRegistry.RegisterBatchCompletion(ctx, (success, context) => callback(success));
                 Native.grpcsharp_call_send_status_from_server(this, ctx, status.StatusCode, status.Detail, metadataArray, sendEmptyInitialMetadata,
                     optionalPayload, optionalPayloadLength, writeFlags).CheckOk();
             }
@@ -153,7 +151,7 @@
             using (completionQueue.NewScope())
             {
                 var ctx = BatchContextSafeHandle.Create();
-                completionRegistry.RegisterBatchCompletion(ctx, (success, context) => callback(success, context.GetReceivedMessage()));
+                completionQueue.CompletionRegistry.RegisterBatchCompletion(ctx, (success, context) => callback(success, context.GetReceivedMessage()));
                 Native.grpcsharp_call_recv_message(this, ctx).CheckOk();
             }
         }
@@ -163,7 +161,7 @@
             using (completionQueue.NewScope())
             {
                 var ctx = BatchContextSafeHandle.Create();
-                completionRegistry.RegisterBatchCompletion(ctx, (success, context) => callback(success, context.GetReceivedInitialMetadata()));
+                completionQueue.CompletionRegistry.RegisterBatchCompletion(ctx, (success, context) => callback(success, context.GetReceivedInitialMetadata()));
                 Native.grpcsharp_call_recv_initial_metadata(this, ctx).CheckOk();
             }
         }
@@ -173,7 +171,7 @@
             using (completionQueue.NewScope())
             {
                 var ctx = BatchContextSafeHandle.Create();
-                completionRegistry.RegisterBatchCompletion(ctx, (success, context) => callback(success, context.GetReceivedCloseOnServerCancelled()));
+                completionQueue.CompletionRegistry.RegisterBatchCompletion(ctx, (success, context) => callback(success, context.GetReceivedCloseOnServerCancelled()));
                 Native.grpcsharp_call_start_serverside(this, ctx).CheckOk();
             }
         }
@@ -183,7 +181,7 @@
             using (completionQueue.NewScope())
             {
                 var ctx = BatchContextSafeHandle.Create();
-                completionRegistry.RegisterBatchCompletion(ctx, (success, context) => callback(success));
+                completionQueue.CompletionRegistry.RegisterBatchCompletion(ctx, (success, context) => callback(success));
                 Native.grpcsharp_call_send_initial_metadata(this, ctx, metadataArray).CheckOk();
             }
         }
diff --git a/src/csharp/Grpc.Core/Internal/ChannelSafeHandle.cs b/src/csharp/Grpc.Core/Internal/ChannelSafeHandle.cs
index 1dbd1f4..62864df 100644
--- a/src/csharp/Grpc.Core/Internal/ChannelSafeHandle.cs
+++ b/src/csharp/Grpc.Core/Internal/ChannelSafeHandle.cs
@@ -63,7 +63,7 @@
             return Native.grpcsharp_secure_channel_create(credentials, target, channelArgs);
         }
 
-        public CallSafeHandle CreateCall(CompletionRegistry registry, CallSafeHandle parentCall, ContextPropagationFlags propagationMask, CompletionQueueSafeHandle cq, string method, string host, Timespec deadline, CallCredentialsSafeHandle credentials)
+        public CallSafeHandle CreateCall(CallSafeHandle parentCall, ContextPropagationFlags propagationMask, CompletionQueueSafeHandle cq, string method, string host, Timespec deadline, CallCredentialsSafeHandle credentials)
         {
             using (Profilers.ForCurrentThread().NewScope("ChannelSafeHandle.CreateCall"))
             {
@@ -72,7 +72,7 @@
                 {
                     result.SetCredentials(credentials);
                 }
-                result.Initialize(registry, cq);
+                result.Initialize(cq);
                 return result;
             }
         }
@@ -82,11 +82,10 @@
             return Native.grpcsharp_channel_check_connectivity_state(this, tryToConnect ? 1 : 0);
         }
 
-        public void WatchConnectivityState(ChannelState lastObservedState, Timespec deadline, CompletionQueueSafeHandle cq,
-            CompletionRegistry completionRegistry, BatchCompletionDelegate callback)
+        public void WatchConnectivityState(ChannelState lastObservedState, Timespec deadline, CompletionQueueSafeHandle cq, BatchCompletionDelegate callback)
         {
             var ctx = BatchContextSafeHandle.Create();
-            completionRegistry.RegisterBatchCompletion(ctx, callback);
+            cq.CompletionRegistry.RegisterBatchCompletion(ctx, callback);
             Native.grpcsharp_channel_watch_connectivity_state(this, lastObservedState, deadline, cq, ctx);
         }
 
diff --git a/src/csharp/Grpc.Core/Internal/ClientRequestStream.cs b/src/csharp/Grpc.Core/Internal/ClientRequestStream.cs
index 013f00f..924de02 100644
--- a/src/csharp/Grpc.Core/Internal/ClientRequestStream.cs
+++ b/src/csharp/Grpc.Core/Internal/ClientRequestStream.cs
@@ -50,16 +50,12 @@
 
         public Task WriteAsync(TRequest message)
         {
-            var taskSource = new AsyncCompletionTaskSource<object>();
-            call.StartSendMessage(message, GetWriteFlags(), taskSource.CompletionDelegate);
-            return taskSource.Task;
+            return call.SendMessageAsync(message, GetWriteFlags());
         }
 
         public Task CompleteAsync()
         {
-            var taskSource = new AsyncCompletionTaskSource<object>();
-            call.StartSendCloseFromClient(taskSource.CompletionDelegate);
-            return taskSource.Task;
+            return call.SendCloseFromClientAsync();
         }
 
         public WriteOptions WriteOptions
diff --git a/src/csharp/Grpc.Core/Internal/CompletionQueueSafeHandle.cs b/src/csharp/Grpc.Core/Internal/CompletionQueueSafeHandle.cs
index 91364cd..46f5624 100644
--- a/src/csharp/Grpc.Core/Internal/CompletionQueueSafeHandle.cs
+++ b/src/csharp/Grpc.Core/Internal/CompletionQueueSafeHandle.cs
@@ -45,6 +45,7 @@
         static readonly NativeMethods Native = NativeMethods.Get();
 
         AtomicCounter shutdownRefcount = new AtomicCounter(1);
+        CompletionRegistry completionRegistry;
 
         private CompletionQueueSafeHandle()
         {
@@ -53,7 +54,13 @@
         public static CompletionQueueSafeHandle Create()
         {
             return Native.grpcsharp_completion_queue_create();
+        }
 
+        public static CompletionQueueSafeHandle Create(CompletionRegistry completionRegistry)
+        {
+            var cq = Native.grpcsharp_completion_queue_create();
+            cq.completionRegistry = completionRegistry;
+            return cq;
         }
 
         public CompletionQueueEvent Next()
@@ -83,6 +90,15 @@
             DecrementShutdownRefcount();
         }
 
+        /// <summary>
+        /// Completion registry associated with this completion queue.
+        /// Doesn't need to be set if only using Pluck() operations.
+        /// </summary>
+        public CompletionRegistry CompletionRegistry
+        {
+            get { return completionRegistry; }
+        }
+
         protected override bool ReleaseHandle()
         {
             Native.grpcsharp_completion_queue_destroy(handle);
diff --git a/src/csharp/Grpc.Core/Internal/GrpcThreadPool.cs b/src/csharp/Grpc.Core/Internal/GrpcThreadPool.cs
index b538726..a446c1f 100644
--- a/src/csharp/Grpc.Core/Internal/GrpcThreadPool.cs
+++ b/src/csharp/Grpc.Core/Internal/GrpcThreadPool.cs
@@ -33,15 +33,16 @@
 
 using System;
 using System.Collections.Generic;
-using System.Runtime.InteropServices;
+using System.Linq;
 using System.Threading;
 using System.Threading.Tasks;
 using Grpc.Core.Logging;
+using Grpc.Core.Utils;
 
 namespace Grpc.Core.Internal
 {
     /// <summary>
-    /// Pool of threads polling on the same completion queue.
+    /// Pool of threads polling on a set of completions queues.
     /// </summary>
     internal class GrpcThreadPool
     {
@@ -51,25 +52,33 @@
         readonly object myLock = new object();
         readonly List<Thread> threads = new List<Thread>();
         readonly int poolSize;
+        readonly int completionQueueCount;
 
-        CompletionQueueSafeHandle cq;
+        bool stopRequested;
 
-        public GrpcThreadPool(GrpcEnvironment environment, int poolSize)
+        IReadOnlyCollection<CompletionQueueSafeHandle> completionQueues;
+
+        /// <summary>
+        /// Creates a thread pool threads polling on a set of completions queues.
+        /// </summary>
+        /// <param name="environment">Environment.</param>
+        /// <param name="poolSize">Pool size.</param>
+        /// <param name="completionQueueCount">Completion queue count.</param>
+        public GrpcThreadPool(GrpcEnvironment environment, int poolSize, int completionQueueCount)
         {
             this.environment = environment;
             this.poolSize = poolSize;
+            this.completionQueueCount = completionQueueCount;
+            GrpcPreconditions.CheckArgument(poolSize >= completionQueueCount,
+                "Thread pool size cannot be smaller than the number of completion queues used.");
         }
 
         public void Start()
         {
             lock (myLock)
             {
-                if (cq != null)
-                {
-                    throw new InvalidOperationException("Already started.");
-                }
-
-                cq = CompletionQueueSafeHandle.Create();
+                GrpcPreconditions.CheckState(completionQueues == null, "Already started.");
+                completionQueues = CreateCompletionQueueList(environment, completionQueueCount);
 
                 for (int i = 0; i < poolSize; i++)
                 {
@@ -78,41 +87,73 @@
             }
         }
 
-        public void Stop()
+        public Task StopAsync()
         {
             lock (myLock)
             {
-                cq.Shutdown();
+                GrpcPreconditions.CheckState(!stopRequested, "Stop already requested.");
+                stopRequested = true;
+
+                foreach (var cq in completionQueues)
+                {
+                    cq.Shutdown();
+                }
+            }
+
+            return Task.Run(() =>
+            {
                 foreach (var thread in threads)
                 {
                     thread.Join();
                 }
 
-                cq.Dispose();
-            }
+                foreach (var cq in completionQueues)
+                {
+                    cq.Dispose();
+                }
+            });
         }
 
-        internal CompletionQueueSafeHandle CompletionQueue
+        /// <summary>
+        /// Returns true if there is at least one thread pool thread that hasn't
+        /// already stopped.
+        /// Threads can either stop because all completion queues shut down or
+        /// because all foreground threads have already shutdown and process is
+        /// going to exit.
+        /// </summary>
+        internal bool IsAlive
         {
             get
             {
-                return cq;
+                return threads.Any(t => t.ThreadState != ThreadState.Stopped);
             }
         }
 
-        private Thread CreateAndStartThread(int i)
+        internal IReadOnlyCollection<CompletionQueueSafeHandle> CompletionQueues
         {
-            var thread = new Thread(new ThreadStart(RunHandlerLoop));
-            thread.IsBackground = false;
+            get
+            {
+                return completionQueues;
+            }
+        }
+
+        private Thread CreateAndStartThread(int threadIndex)
+        {
+            var cqIndex = threadIndex % completionQueues.Count;
+            var cq = completionQueues.ElementAt(cqIndex);
+
+            var thread = new Thread(new ThreadStart(() => RunHandlerLoop(cq)));
+            thread.IsBackground = true;
+            thread.Name = string.Format("grpc {0} (cq {1})", threadIndex, cqIndex);
             thread.Start();
-            thread.Name = "grpc " + i;
+
             return thread;
         }
 
         /// <summary>
         /// Body of the polling thread.
         /// </summary>
-        private void RunHandlerLoop()
+        private void RunHandlerLoop(CompletionQueueSafeHandle cq)
         {
             CompletionQueueEvent ev;
             do
@@ -124,7 +165,7 @@
                     IntPtr tag = ev.tag;
                     try
                     {
-                        var callback = environment.CompletionRegistry.Extract(tag);
+                        var callback = cq.CompletionRegistry.Extract(tag);
                         callback(success);
                     }
                     catch (Exception e)
@@ -135,5 +176,16 @@
             }
             while (ev.type != CompletionQueueEvent.CompletionType.Shutdown);
         }
+
+        private static IReadOnlyCollection<CompletionQueueSafeHandle> CreateCompletionQueueList(GrpcEnvironment environment, int completionQueueCount)
+        {
+            var list = new List<CompletionQueueSafeHandle>();
+            for (int i = 0; i < completionQueueCount; i++)
+            {
+                var completionRegistry = new CompletionRegistry(environment);
+                list.Add(CompletionQueueSafeHandle.Create(completionRegistry));
+            }
+            return list.AsReadOnly();
+        }
     }
 }
diff --git a/src/csharp/Grpc.Core/Internal/NativeMethods.cs b/src/csharp/Grpc.Core/Internal/NativeMethods.cs
index 42fd4d4..65607ed 100644
--- a/src/csharp/Grpc.Core/Internal/NativeMethods.cs
+++ b/src/csharp/Grpc.Core/Internal/NativeMethods.cs
@@ -137,6 +137,7 @@
         public readonly Delegates.grpcsharp_server_credentials_release_delegate grpcsharp_server_credentials_release;
 
         public readonly Delegates.grpcsharp_server_create_delegate grpcsharp_server_create;
+        public readonly Delegates.grpcsharp_server_register_completion_queue_delegate grpcsharp_server_register_completion_queue;
         public readonly Delegates.grpcsharp_server_add_insecure_http2_port_delegate grpcsharp_server_add_insecure_http2_port;
         public readonly Delegates.grpcsharp_server_add_secure_http2_port_delegate grpcsharp_server_add_secure_http2_port;
         public readonly Delegates.grpcsharp_server_start_delegate grpcsharp_server_start;
@@ -244,6 +245,7 @@
                 this.grpcsharp_server_credentials_release = GetMethodDelegate<Delegates.grpcsharp_server_credentials_release_delegate>(library);
 
                 this.grpcsharp_server_create = GetMethodDelegate<Delegates.grpcsharp_server_create_delegate>(library);
+                this.grpcsharp_server_register_completion_queue = GetMethodDelegate<Delegates.grpcsharp_server_register_completion_queue_delegate>(library);
                 this.grpcsharp_server_add_insecure_http2_port = GetMethodDelegate<Delegates.grpcsharp_server_add_insecure_http2_port_delegate>(library);
                 this.grpcsharp_server_add_secure_http2_port = GetMethodDelegate<Delegates.grpcsharp_server_add_secure_http2_port_delegate>(library);
                 this.grpcsharp_server_start = GetMethodDelegate<Delegates.grpcsharp_server_start_delegate>(library);
@@ -348,6 +350,7 @@
                 this.grpcsharp_server_credentials_release = PInvokeMethods.grpcsharp_server_credentials_release;
 
                 this.grpcsharp_server_create = PInvokeMethods.grpcsharp_server_create;
+                this.grpcsharp_server_register_completion_queue = PInvokeMethods.grpcsharp_server_register_completion_queue;
                 this.grpcsharp_server_add_insecure_http2_port = PInvokeMethods.grpcsharp_server_add_insecure_http2_port;
                 this.grpcsharp_server_add_secure_http2_port = PInvokeMethods.grpcsharp_server_add_secure_http2_port;
                 this.grpcsharp_server_start = PInvokeMethods.grpcsharp_server_start;
@@ -493,7 +496,8 @@
             public delegate ServerCredentialsSafeHandle grpcsharp_ssl_server_credentials_create_delegate(string pemRootCerts, string[] keyCertPairCertChainArray, string[] keyCertPairPrivateKeyArray, UIntPtr numKeyCertPairs, bool forceClientAuth);
             public delegate void grpcsharp_server_credentials_release_delegate(IntPtr credentials);
 
-            public delegate ServerSafeHandle grpcsharp_server_create_delegate(CompletionQueueSafeHandle cq, ChannelArgsSafeHandle args);
+            public delegate ServerSafeHandle grpcsharp_server_create_delegate(ChannelArgsSafeHandle args);
+            public delegate void grpcsharp_server_register_completion_queue_delegate(ServerSafeHandle server, CompletionQueueSafeHandle cq);
             public delegate int grpcsharp_server_add_insecure_http2_port_delegate(ServerSafeHandle server, string addr);
             public delegate int grpcsharp_server_add_secure_http2_port_delegate(ServerSafeHandle server, string addr, ServerCredentialsSafeHandle creds);
             public delegate void grpcsharp_server_start_delegate(ServerSafeHandle server);
@@ -773,7 +777,10 @@
             // ServerSafeHandle
 
             [DllImport("grpc_csharp_ext.dll")]
-            public static extern ServerSafeHandle grpcsharp_server_create(CompletionQueueSafeHandle cq, ChannelArgsSafeHandle args);
+            public static extern ServerSafeHandle grpcsharp_server_create(ChannelArgsSafeHandle args);
+
+            [DllImport("grpc_csharp_ext.dll")]
+            public static extern void grpcsharp_server_register_completion_queue(ServerSafeHandle server, CompletionQueueSafeHandle cq);
 
             [DllImport("grpc_csharp_ext.dll")]
             public static extern int grpcsharp_server_add_insecure_http2_port(ServerSafeHandle server, string addr);
diff --git a/src/csharp/Grpc.Core/Internal/ServerCallHandler.cs b/src/csharp/Grpc.Core/Internal/ServerCallHandler.cs
index febebba..6a2f520 100644
--- a/src/csharp/Grpc.Core/Internal/ServerCallHandler.cs
+++ b/src/csharp/Grpc.Core/Internal/ServerCallHandler.cs
@@ -44,7 +44,7 @@
 {
     internal interface IServerCallHandler
     {
-        Task HandleCall(ServerRpcNew newRpc, GrpcEnvironment environment);
+        Task HandleCall(ServerRpcNew newRpc, CompletionQueueSafeHandle cq);
     }
 
     internal class UnaryServerCallHandler<TRequest, TResponse> : IServerCallHandler
@@ -62,14 +62,14 @@
             this.handler = handler;
         }
 
-        public async Task HandleCall(ServerRpcNew newRpc, GrpcEnvironment environment)
+        public async Task HandleCall(ServerRpcNew newRpc, CompletionQueueSafeHandle cq)
         {
             var asyncCall = new AsyncCallServer<TRequest, TResponse>(
                 method.ResponseMarshaller.Serializer,
                 method.RequestMarshaller.Deserializer,
-                environment, newRpc.Server);
+                newRpc.Server);
 
-            asyncCall.Initialize(newRpc.Call);
+            asyncCall.Initialize(newRpc.Call, cq);
             var finishedTask = asyncCall.ServerSideCallAsync();
             var requestStream = new ServerRequestStream<TRequest, TResponse>(asyncCall);
             var responseStream = new ServerResponseStream<TRequest, TResponse>(asyncCall);
@@ -121,14 +121,14 @@
             this.handler = handler;
         }
 
-        public async Task HandleCall(ServerRpcNew newRpc, GrpcEnvironment environment)
+        public async Task HandleCall(ServerRpcNew newRpc, CompletionQueueSafeHandle cq)
         {
             var asyncCall = new AsyncCallServer<TRequest, TResponse>(
                 method.ResponseMarshaller.Serializer,
                 method.RequestMarshaller.Deserializer,
-                environment, newRpc.Server);
+                newRpc.Server);
 
-            asyncCall.Initialize(newRpc.Call);
+            asyncCall.Initialize(newRpc.Call, cq);
             var finishedTask = asyncCall.ServerSideCallAsync();
             var requestStream = new ServerRequestStream<TRequest, TResponse>(asyncCall);
             var responseStream = new ServerResponseStream<TRequest, TResponse>(asyncCall);
@@ -179,14 +179,14 @@
             this.handler = handler;
         }
 
-        public async Task HandleCall(ServerRpcNew newRpc, GrpcEnvironment environment)
+        public async Task HandleCall(ServerRpcNew newRpc, CompletionQueueSafeHandle cq)
         {
             var asyncCall = new AsyncCallServer<TRequest, TResponse>(
                 method.ResponseMarshaller.Serializer,
                 method.RequestMarshaller.Deserializer,
-                environment, newRpc.Server);
+                newRpc.Server);
 
-            asyncCall.Initialize(newRpc.Call);
+            asyncCall.Initialize(newRpc.Call, cq);
             var finishedTask = asyncCall.ServerSideCallAsync();
             var requestStream = new ServerRequestStream<TRequest, TResponse>(asyncCall);
             var responseStream = new ServerResponseStream<TRequest, TResponse>(asyncCall);
@@ -237,14 +237,14 @@
             this.handler = handler;
         }
 
-        public async Task HandleCall(ServerRpcNew newRpc, GrpcEnvironment environment)
+        public async Task HandleCall(ServerRpcNew newRpc, CompletionQueueSafeHandle cq)
         {
             var asyncCall = new AsyncCallServer<TRequest, TResponse>(
                 method.ResponseMarshaller.Serializer,
                 method.RequestMarshaller.Deserializer,
-                environment, newRpc.Server);
+                newRpc.Server);
 
-            asyncCall.Initialize(newRpc.Call);
+            asyncCall.Initialize(newRpc.Call, cq);
             var finishedTask = asyncCall.ServerSideCallAsync();
             var requestStream = new ServerRequestStream<TRequest, TResponse>(asyncCall);
             var responseStream = new ServerResponseStream<TRequest, TResponse>(asyncCall);
@@ -281,13 +281,13 @@
     {
         public static readonly NoSuchMethodCallHandler Instance = new NoSuchMethodCallHandler();
 
-        public async Task HandleCall(ServerRpcNew newRpc, GrpcEnvironment environment)
+        public async Task HandleCall(ServerRpcNew newRpc, CompletionQueueSafeHandle cq)
         {
             // We don't care about the payload type here.
             var asyncCall = new AsyncCallServer<byte[], byte[]>(
-                (payload) => payload, (payload) => payload, environment, newRpc.Server);
+                (payload) => payload, (payload) => payload, newRpc.Server);
             
-            asyncCall.Initialize(newRpc.Call);
+            asyncCall.Initialize(newRpc.Call, cq);
             var finishedTask = asyncCall.ServerSideCallAsync();
             await asyncCall.SendStatusFromServerAsync(new Status(StatusCode.Unimplemented, ""), Metadata.Empty, null).ConfigureAwait(false);
             await finishedTask.ConfigureAwait(false);
diff --git a/src/csharp/Grpc.Core/Internal/ServerResponseStream.cs b/src/csharp/Grpc.Core/Internal/ServerResponseStream.cs
index ecfee0b..25b79b4 100644
--- a/src/csharp/Grpc.Core/Internal/ServerResponseStream.cs
+++ b/src/csharp/Grpc.Core/Internal/ServerResponseStream.cs
@@ -52,16 +52,12 @@
 
         public Task WriteAsync(TResponse message)
         {
-            var taskSource = new AsyncCompletionTaskSource<object>();
-            call.StartSendMessage(message, GetWriteFlags(), taskSource.CompletionDelegate);
-            return taskSource.Task;
+            return call.SendMessageAsync(message, GetWriteFlags());
         }
 
         public Task WriteResponseHeadersAsync(Metadata responseHeaders)
         {
-            var taskSource = new AsyncCompletionTaskSource<object>();
-            call.StartSendInitialMetadata(responseHeaders, taskSource.CompletionDelegate);
-            return taskSource.Task;
+            return call.SendInitialMetadataAsync(responseHeaders);
         }
 
         public WriteOptions WriteOptions
diff --git a/src/csharp/Grpc.Core/Internal/ServerSafeHandle.cs b/src/csharp/Grpc.Core/Internal/ServerSafeHandle.cs
index 6b5f70e..8581302 100644
--- a/src/csharp/Grpc.Core/Internal/ServerSafeHandle.cs
+++ b/src/csharp/Grpc.Core/Internal/ServerSafeHandle.cs
@@ -31,12 +31,6 @@
 
 #endregion
 
-using System;
-using System.Collections.Concurrent;
-using System.Diagnostics;
-using System.Runtime.InteropServices;
-using Grpc.Core.Utils;
-
 namespace Grpc.Core.Internal
 {
     /// <summary>
@@ -50,12 +44,17 @@
         {
         }
 
-        public static ServerSafeHandle NewServer(CompletionQueueSafeHandle cq, ChannelArgsSafeHandle args)
+        public static ServerSafeHandle NewServer(ChannelArgsSafeHandle args)
         {
             // Increment reference count for the native gRPC environment to make sure we don't do grpc_shutdown() before destroying the server handle.
             // Doing so would make object finalizer crash if we end up abandoning the handle.
             GrpcEnvironment.GrpcNativeInit();
-            return Native.grpcsharp_server_create(cq, args);
+            return Native.grpcsharp_server_create(args);
+        }
+
+        public void RegisterCompletionQueue(CompletionQueueSafeHandle cq)
+        {
+            Native.grpcsharp_server_register_completion_queue(this, cq);
         }
 
         public int AddInsecurePort(string addr)
@@ -73,18 +72,18 @@
             Native.grpcsharp_server_start(this);
         }
     
-        public void ShutdownAndNotify(BatchCompletionDelegate callback, GrpcEnvironment environment)
+        public void ShutdownAndNotify(BatchCompletionDelegate callback, CompletionQueueSafeHandle completionQueue)
         {
             var ctx = BatchContextSafeHandle.Create();
-            environment.CompletionRegistry.RegisterBatchCompletion(ctx, callback);
-            Native.grpcsharp_server_shutdown_and_notify_callback(this, environment.CompletionQueue, ctx);
+            completionQueue.CompletionRegistry.RegisterBatchCompletion(ctx, callback);
+            Native.grpcsharp_server_shutdown_and_notify_callback(this, completionQueue, ctx);
         }
 
-        public void RequestCall(BatchCompletionDelegate callback, GrpcEnvironment environment)
+        public void RequestCall(BatchCompletionDelegate callback, CompletionQueueSafeHandle completionQueue)
         {
             var ctx = BatchContextSafeHandle.Create();
-            environment.CompletionRegistry.RegisterBatchCompletion(ctx, callback);
-            Native.grpcsharp_server_request_call(this, environment.CompletionQueue, ctx).CheckOk();
+            completionQueue.CompletionRegistry.RegisterBatchCompletion(ctx, callback);
+            Native.grpcsharp_server_request_call(this, completionQueue, ctx).CheckOk();
         }
 
         protected override bool ReleaseHandle()
diff --git a/src/proto/grpc/testing/perf_db.proto b/src/csharp/Grpc.Core/Logging/LogLevel.cs
similarity index 61%
copy from src/proto/grpc/testing/perf_db.proto
copy to src/csharp/Grpc.Core/Logging/LogLevel.cs
index 0ba8596..d64e1f5 100644
--- a/src/proto/grpc/testing/perf_db.proto
+++ b/src/csharp/Grpc.Core/Logging/LogLevel.cs
@@ -1,3 +1,5 @@
+#region Copyright notice and license
+
 // Copyright 2015, Google Inc.
 // All rights reserved.
 //
@@ -27,43 +29,31 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-syntax = "proto3";
+#endregion
 
-import "src/proto/grpc/testing/control.proto";
+using System;
+using System.Collections.Generic;
 
-package grpc.testing;
-
-service PerfDbTransfer {
-  // Sends client info
-  rpc RecordSingleClientData(SingleUserRecordRequest)
-      returns (SingleUserRecordReply) {}
+namespace Grpc.Core.Logging
+{
+    /// <summary>Standard logging levels.</summary>
+    public enum LogLevel
+    {
+        /// <summary>
+        /// Debug severity.
+        /// </summary>
+        Debug = 0,
+        /// <summary>
+        /// Info severity.
+        /// </summary>
+        Info,
+        /// <summary>
+        /// Warning severity.
+        /// </summary>
+        Warning,
+        /// <summary>
+        /// Error severity.
+        /// </summary>
+        Error
+    }
 }
-
-// Metrics to be stored
-message Metrics {
-  double qps = 1;
-  double qps_per_core = 2;
-  double perc_lat_50 = 3;
-  double perc_lat_90 = 4;
-  double perc_lat_95 = 5;
-  double perc_lat_99 = 6;
-  double perc_lat_99_point_9 = 7;
-  double server_system_time = 8;
-  double server_user_time = 9;
-  double client_system_time = 10;
-  double client_user_time = 11;
-}
-
-// Request for storing a single user's data
-message SingleUserRecordRequest {
-  string hashed_id = 1;
-  string test_name = 2;
-  string sys_info = 3;
-  string tag = 4;
-  Metrics metrics = 5;
-  ClientConfig client_config = 6;
-  ServerConfig server_config = 7;
-}
-
-// Reply to request for storing single user's data
-message SingleUserRecordReply {}
diff --git a/src/csharp/Grpc.Core/Logging/LogLevelFilterLogger.cs b/src/csharp/Grpc.Core/Logging/LogLevelFilterLogger.cs
new file mode 100644
index 0000000..4eeb79c
--- /dev/null
+++ b/src/csharp/Grpc.Core/Logging/LogLevelFilterLogger.cs
@@ -0,0 +1,160 @@
+#region Copyright notice and license
+
+// Copyright 2015, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using Grpc.Core.Utils;
+
+namespace Grpc.Core.Logging
+{
+    /// <summary>Logger that filters out messages below certain log level.</summary>
+    public class LogLevelFilterLogger : ILogger
+    {
+        readonly ILogger innerLogger;
+        readonly LogLevel logLevel;
+
+        /// <summary>
+        /// Creates and instance of <c>LogLevelFilter.</c>
+        /// </summary>
+        public LogLevelFilterLogger(ILogger logger, LogLevel logLevel)
+        {
+            this.innerLogger = GrpcPreconditions.CheckNotNull(logger);
+            this.logLevel = logLevel;
+        }
+
+        /// <summary>
+        /// Returns a logger associated with the specified type.
+        /// </summary>
+        public virtual ILogger ForType<T>()
+        {
+            var newInnerLogger = innerLogger.ForType<T>();
+            if (object.ReferenceEquals(this.innerLogger, newInnerLogger))
+            {
+                return this;
+            }
+            return new LogLevelFilterLogger(newInnerLogger, logLevel);
+        }
+
+        /// <summary>Logs a message with severity Debug.</summary>
+        public void Debug(string message)
+        {
+            if (logLevel <= LogLevel.Debug)
+            {
+                innerLogger.Debug(message);
+            }
+        }
+
+        /// <summary>Logs a formatted message with severity Debug.</summary>
+        public void Debug(string format, params object[] formatArgs)
+        {
+            if (logLevel <= LogLevel.Debug)
+            {
+                innerLogger.Debug(format, formatArgs);
+            }
+        }
+
+        /// <summary>Logs a message with severity Info.</summary>
+        public void Info(string message)
+        {
+            if (logLevel <= LogLevel.Info)
+            {
+                innerLogger.Info(message);
+            }
+        }
+
+        /// <summary>Logs a formatted message with severity Info.</summary>
+        public void Info(string format, params object[] formatArgs)
+        {
+            if (logLevel <= LogLevel.Info)
+            {
+                innerLogger.Info(format, formatArgs);
+            }
+        }
+
+        /// <summary>Logs a message with severity Warning.</summary>
+        public void Warning(string message)
+        {
+            if (logLevel <= LogLevel.Warning)
+            {
+                innerLogger.Warning(message);
+            }
+        }
+
+        /// <summary>Logs a formatted message with severity Warning.</summary>
+        public void Warning(string format, params object[] formatArgs)
+        {
+            if (logLevel <= LogLevel.Warning)
+            {
+                innerLogger.Warning(format, formatArgs);
+            }
+        }
+
+        /// <summary>Logs a message and an associated exception with severity Warning.</summary>
+        public void Warning(Exception exception, string message)
+        {
+            if (logLevel <= LogLevel.Warning)
+            {
+                innerLogger.Warning(exception, message);
+            }
+        }
+
+        /// <summary>Logs a message with severity Error.</summary>
+        public void Error(string message)
+        {
+            if (logLevel <= LogLevel.Error)
+            {
+                innerLogger.Error(message);
+            }
+        }
+
+        /// <summary>Logs a formatted message with severity Error.</summary>
+        public void Error(string format, params object[] formatArgs)
+        {
+            if (logLevel <= LogLevel.Error)
+            {
+                innerLogger.Error(format, formatArgs);
+            }
+        }
+
+        /// <summary>Logs a message and an associated exception with severity Error.</summary>
+        public void Error(Exception exception, string message)
+        {
+            if (logLevel <= LogLevel.Error)
+            {
+                innerLogger.Error(exception, message);
+            }
+        }
+    }
+}
diff --git a/src/csharp/Grpc.Core/Metadata.cs b/src/csharp/Grpc.Core/Metadata.cs
index e982fa0..f73f720 100644
--- a/src/csharp/Grpc.Core/Metadata.cs
+++ b/src/csharp/Grpc.Core/Metadata.cs
@@ -95,6 +95,7 @@
 
         public void Insert(int index, Metadata.Entry item)
         {
+            GrpcPreconditions.CheckNotNull(item);
             CheckWriteable();
             entries.Insert(index, item);
         }
@@ -114,6 +115,7 @@
 
             set
             {
+                GrpcPreconditions.CheckNotNull(value);
                 CheckWriteable();
                 entries[index] = value;
             }
@@ -121,6 +123,7 @@
 
         public void Add(Metadata.Entry item)
         {
+            GrpcPreconditions.CheckNotNull(item);
             CheckWriteable();
             entries.Add(item);
         }
@@ -187,7 +190,7 @@
         /// <summary>
         /// Metadata entry
         /// </summary>
-        public struct Entry
+        public class Entry
         {
             private static readonly Encoding Encoding = Encoding.ASCII;
             private static readonly Regex ValidKeyRegex = new Regex("^[a-z0-9_-]+$");
diff --git a/src/csharp/Grpc.Core/Server.cs b/src/csharp/Grpc.Core/Server.cs
index d538a46..3b554e5 100644
--- a/src/csharp/Grpc.Core/Server.cs
+++ b/src/csharp/Grpc.Core/Server.cs
@@ -34,8 +34,7 @@
 using System;
 using System.Collections;
 using System.Collections.Generic;
-using System.Diagnostics;
-using System.Runtime.InteropServices;
+using System.Linq;
 using System.Threading.Tasks;
 using Grpc.Core.Internal;
 using Grpc.Core.Logging;
@@ -48,7 +47,7 @@
     /// </summary>
     public class Server
     {
-        const int InitialAllowRpcTokenCount = 10;
+        const int InitialAllowRpcTokenCountPerCq = 10;
         static readonly ILogger Logger = GrpcEnvironment.Logger.ForType<Server>();
 
         readonly AtomicCounter activeCallCounter = new AtomicCounter();
@@ -68,11 +67,19 @@
         bool startRequested;
         volatile bool shutdownRequested;
 
+
         /// <summary>
-        /// Create a new server.
+        /// Creates a new server.
+        /// </summary>
+        public Server() : this(null)
+        {
+        }
+
+        /// <summary>
+        /// Creates a new server.
         /// </summary>
         /// <param name="options">Channel options.</param>
-        public Server(IEnumerable<ChannelOption> options = null)
+        public Server(IEnumerable<ChannelOption> options)
         {
             this.serviceDefinitions = new ServiceDefinitionCollection(this);
             this.ports = new ServerPortCollection(this);
@@ -80,8 +87,14 @@
             this.options = options != null ? new List<ChannelOption>(options) : new List<ChannelOption>();
             using (var channelArgs = ChannelOptions.CreateChannelArgs(this.options))
             {
-                this.handle = ServerSafeHandle.NewServer(environment.CompletionQueue, channelArgs);
+                this.handle = ServerSafeHandle.NewServer(channelArgs);
             }
+
+            foreach (var cq in environment.CompletionQueues)
+            {
+                this.handle.RegisterCompletionQueue(cq);
+            }
+            GrpcEnvironment.RegisterServer(this);
         }
 
         /// <summary>
@@ -127,15 +140,19 @@
             lock (myLock)
             {
                 GrpcPreconditions.CheckState(!startRequested);
+                GrpcPreconditions.CheckState(!shutdownRequested);
                 startRequested = true;
                 
                 handle.Start();
 
                 // Starting with more than one AllowOneRpc tokens can significantly increase
                 // unary RPC throughput.
-                for (int i = 0; i < InitialAllowRpcTokenCount; i++)
+                for (int i = 0; i < InitialAllowRpcTokenCountPerCq; i++)
                 {
-                    AllowOneRpc();
+                    foreach (var cq in environment.CompletionQueues)
+                    {
+                        AllowOneRpc(cq);
+                    }
                 }
             }
         }
@@ -145,41 +162,24 @@
         /// cleans up used resources. The returned task finishes when shutdown procedure
         /// is complete.
         /// </summary>
-        public async Task ShutdownAsync()
+        /// <remarks>
+        /// It is strongly recommended to shutdown all previously created servers before exiting from the process.
+        /// </remarks>
+        public Task ShutdownAsync()
         {
-            lock (myLock)
-            {
-                GrpcPreconditions.CheckState(startRequested);
-                GrpcPreconditions.CheckState(!shutdownRequested);
-                shutdownRequested = true;
-            }
-
-            handle.ShutdownAndNotify(HandleServerShutdown, environment);
-            await shutdownTcs.Task.ConfigureAwait(false);
-            DisposeHandle();
-
-            await Task.Run(() => GrpcEnvironment.Release()).ConfigureAwait(false);
+            return ShutdownInternalAsync(false);
         }
 
         /// <summary>
         /// Requests server shutdown while cancelling all the in-progress calls.
         /// The returned task finishes when shutdown procedure is complete.
         /// </summary>
-        public async Task KillAsync()
+        /// <remarks>
+        /// It is strongly recommended to shutdown all previously created servers before exiting from the process.
+        /// </remarks>
+        public Task KillAsync()
         {
-            lock (myLock)
-            {
-                GrpcPreconditions.CheckState(startRequested);
-                GrpcPreconditions.CheckState(!shutdownRequested);
-                shutdownRequested = true;
-            }
-
-            handle.ShutdownAndNotify(HandleServerShutdown, environment);
-            handle.CancelAllCalls();
-            await shutdownTcs.Task.ConfigureAwait(false);
-            DisposeHandle();
-
-            await Task.Run(() => GrpcEnvironment.Release()).ConfigureAwait(false);
+            return ShutdownInternalAsync(true);
         }
 
         internal void AddCallReference(object call)
@@ -198,6 +198,51 @@
         }
 
         /// <summary>
+        /// Shuts down the server.
+        /// </summary>
+        private async Task ShutdownInternalAsync(bool kill)
+        {
+            lock (myLock)
+            {
+                GrpcPreconditions.CheckState(!shutdownRequested);
+                shutdownRequested = true;
+            }
+            GrpcEnvironment.UnregisterServer(this);
+
+            var cq = environment.CompletionQueues.First();  // any cq will do
+            handle.ShutdownAndNotify(HandleServerShutdown, cq);
+            if (kill)
+            {
+                handle.CancelAllCalls();
+            }
+            await ShutdownCompleteOrEnvironmentDeadAsync().ConfigureAwait(false);
+
+            DisposeHandle();
+
+            await GrpcEnvironment.ReleaseAsync().ConfigureAwait(false);
+        }
+
+        /// <summary>
+        /// In case the environment's threadpool becomes dead, the shutdown completion will
+        /// never be delivered, but we need to release the environment's handle anyway.
+        /// </summary>
+        private async Task ShutdownCompleteOrEnvironmentDeadAsync()
+        {
+            while (true)
+            {
+                var task = await Task.WhenAny(shutdownTcs.Task, Task.Delay(20)).ConfigureAwait(false);
+                if (shutdownTcs.Task == task)
+                {
+                    return;
+                }
+                if (!environment.IsAlive)
+                {
+                    return;
+                }
+            }
+        }
+
+        /// <summary>
         /// Adds a service definition.
         /// </summary>
         private void AddServiceDefinitionInternal(ServerServiceDefinition serviceDefinition)
@@ -244,11 +289,11 @@
         /// <summary>
         /// Allows one new RPC call to be received by server.
         /// </summary>
-        private void AllowOneRpc()
+        private void AllowOneRpc(CompletionQueueSafeHandle cq)
         {
             if (!shutdownRequested)
             {
-                handle.RequestCall(HandleNewServerRpc, environment);
+                handle.RequestCall((success, ctx) => HandleNewServerRpc(success, ctx, cq), cq);
             }
         }
 
@@ -265,7 +310,7 @@
         /// <summary>
         /// Selects corresponding handler for given call and handles the call.
         /// </summary>
-        private async Task HandleCallAsync(ServerRpcNew newRpc)
+        private async Task HandleCallAsync(ServerRpcNew newRpc, CompletionQueueSafeHandle cq)
         {
             try
             {
@@ -274,7 +319,7 @@
                 {
                     callHandler = NoSuchMethodCallHandler.Instance;
                 }
-                await callHandler.HandleCall(newRpc, environment).ConfigureAwait(false);
+                await callHandler.HandleCall(newRpc, cq).ConfigureAwait(false);
             }
             catch (Exception e)
             {
@@ -285,9 +330,9 @@
         /// <summary>
         /// Handles the native callback.
         /// </summary>
-        private void HandleNewServerRpc(bool success, BatchContextSafeHandle ctx)
+        private void HandleNewServerRpc(bool success, BatchContextSafeHandle ctx, CompletionQueueSafeHandle cq)
         {
-			Task.Run(() => AllowOneRpc());
+			Task.Run(() => AllowOneRpc(cq));
 
             if (success)
             {
@@ -296,7 +341,7 @@
                 // after server shutdown, the callback returns with null call
                 if (!newRpc.Call.IsInvalid)
                 {
-                    HandleCallAsync(newRpc);  // we don't need to await.
+                    HandleCallAsync(newRpc, cq);  // we don't need to await.
                 }
             }
         }
diff --git a/src/csharp/Grpc.Core/ServerServiceDefinition.cs b/src/csharp/Grpc.Core/ServerServiceDefinition.cs
index deb1431..ac08c04 100644
--- a/src/csharp/Grpc.Core/ServerServiceDefinition.cs
+++ b/src/csharp/Grpc.Core/ServerServiceDefinition.cs
@@ -63,11 +63,10 @@
         /// <summary>
         /// Creates a new builder object for <c>ServerServiceDefinition</c>.
         /// </summary>
-        /// <param name="serviceName">The service name.</param>
         /// <returns>The builder object.</returns>
-        public static Builder CreateBuilder(string serviceName)
+        public static Builder CreateBuilder()
         {
-            return new Builder(serviceName);
+            return new Builder();
         }
 
         /// <summary>
@@ -75,16 +74,13 @@
         /// </summary>
         public class Builder
         {
-            readonly string serviceName;
             readonly Dictionary<string, IServerCallHandler> callHandlers = new Dictionary<string, IServerCallHandler>();
 
             /// <summary>
             /// Creates a new instance of builder.
             /// </summary>
-            /// <param name="serviceName">The service name.</param>
-            public Builder(string serviceName)
+            public Builder()
             {
-                this.serviceName = serviceName;
             }
 
             /// <summary>
diff --git a/src/csharp/Grpc.Core/WriteOptions.cs b/src/csharp/Grpc.Core/WriteOptions.cs
index 7523ada..4c9706d 100644
--- a/src/csharp/Grpc.Core/WriteOptions.cs
+++ b/src/csharp/Grpc.Core/WriteOptions.cs
@@ -1,6 +1,6 @@
 #region Copyright notice and license
 
-// Copyright 2015, Google Inc.
+// Copyright 2015-2016, Google Inc.
 // All rights reserved.
 //
 // Redistribution and use in source and binary forms, with or without
@@ -64,7 +64,7 @@
         /// </summary>
         public static readonly WriteOptions Default = new WriteOptions();
             
-        private WriteFlags flags;
+        private readonly WriteFlags flags;
 
         /// <summary>
         /// Initializes a new instance of <c>WriteOptions</c> class.
diff --git a/src/csharp/Grpc.Examples/MathGrpc.cs b/src/csharp/Grpc.Examples/MathGrpc.cs
index d700a18..4bbefcb 100644
--- a/src/csharp/Grpc.Examples/MathGrpc.cs
+++ b/src/csharp/Grpc.Examples/MathGrpc.cs
@@ -81,103 +81,12 @@
       get { return global::Math.MathReflection.Descriptor.Services[0]; }
     }
 
-    /// <summary>Client for Math</summary>
-    [System.Obsolete("Client side interfaced will be removed in the next release. Use client class directly.")]
-    public interface IMathClient
-    {
-      /// <summary>
-      ///  Div divides args.dividend by args.divisor and returns the quotient and
-      ///  remainder.
-      /// </summary>
-      global::Math.DivReply Div(global::Math.DivArgs request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
-      /// <summary>
-      ///  Div divides args.dividend by args.divisor and returns the quotient and
-      ///  remainder.
-      /// </summary>
-      global::Math.DivReply Div(global::Math.DivArgs request, CallOptions options);
-      /// <summary>
-      ///  Div divides args.dividend by args.divisor and returns the quotient and
-      ///  remainder.
-      /// </summary>
-      AsyncUnaryCall<global::Math.DivReply> DivAsync(global::Math.DivArgs request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
-      /// <summary>
-      ///  Div divides args.dividend by args.divisor and returns the quotient and
-      ///  remainder.
-      /// </summary>
-      AsyncUnaryCall<global::Math.DivReply> DivAsync(global::Math.DivArgs request, CallOptions options);
-      /// <summary>
-      ///  DivMany accepts an arbitrary number of division args from the client stream
-      ///  and sends back the results in the reply stream.  The stream continues until
-      ///  the client closes its end; the server does the same after sending all the
-      ///  replies.  The stream ends immediately if either end aborts.
-      /// </summary>
-      AsyncDuplexStreamingCall<global::Math.DivArgs, global::Math.DivReply> DivMany(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
-      /// <summary>
-      ///  DivMany accepts an arbitrary number of division args from the client stream
-      ///  and sends back the results in the reply stream.  The stream continues until
-      ///  the client closes its end; the server does the same after sending all the
-      ///  replies.  The stream ends immediately if either end aborts.
-      /// </summary>
-      AsyncDuplexStreamingCall<global::Math.DivArgs, global::Math.DivReply> DivMany(CallOptions options);
-      /// <summary>
-      ///  Fib generates numbers in the Fibonacci sequence.  If args.limit > 0, Fib
-      ///  generates up to limit numbers; otherwise it continues until the call is
-      ///  canceled.  Unlike Fib above, Fib has no final FibReply.
-      /// </summary>
-      AsyncServerStreamingCall<global::Math.Num> Fib(global::Math.FibArgs request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
-      /// <summary>
-      ///  Fib generates numbers in the Fibonacci sequence.  If args.limit > 0, Fib
-      ///  generates up to limit numbers; otherwise it continues until the call is
-      ///  canceled.  Unlike Fib above, Fib has no final FibReply.
-      /// </summary>
-      AsyncServerStreamingCall<global::Math.Num> Fib(global::Math.FibArgs request, CallOptions options);
-      /// <summary>
-      ///  Sum sums a stream of numbers, returning the final result once the stream
-      ///  is closed.
-      /// </summary>
-      AsyncClientStreamingCall<global::Math.Num, global::Math.Num> Sum(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
-      /// <summary>
-      ///  Sum sums a stream of numbers, returning the final result once the stream
-      ///  is closed.
-      /// </summary>
-      AsyncClientStreamingCall<global::Math.Num, global::Math.Num> Sum(CallOptions options);
-    }
-
-    /// <summary>Interface of server-side implementations of Math</summary>
-    [System.Obsolete("Service implementations should inherit from the generated abstract base class instead.")]
-    public interface IMath
-    {
-      /// <summary>
-      ///  Div divides args.dividend by args.divisor and returns the quotient and
-      ///  remainder.
-      /// </summary>
-      global::System.Threading.Tasks.Task<global::Math.DivReply> Div(global::Math.DivArgs request, ServerCallContext context);
-      /// <summary>
-      ///  DivMany accepts an arbitrary number of division args from the client stream
-      ///  and sends back the results in the reply stream.  The stream continues until
-      ///  the client closes its end; the server does the same after sending all the
-      ///  replies.  The stream ends immediately if either end aborts.
-      /// </summary>
-      global::System.Threading.Tasks.Task DivMany(IAsyncStreamReader<global::Math.DivArgs> requestStream, IServerStreamWriter<global::Math.DivReply> responseStream, ServerCallContext context);
-      /// <summary>
-      ///  Fib generates numbers in the Fibonacci sequence.  If args.limit > 0, Fib
-      ///  generates up to limit numbers; otherwise it continues until the call is
-      ///  canceled.  Unlike Fib above, Fib has no final FibReply.
-      /// </summary>
-      global::System.Threading.Tasks.Task Fib(global::Math.FibArgs request, IServerStreamWriter<global::Math.Num> responseStream, ServerCallContext context);
-      /// <summary>
-      ///  Sum sums a stream of numbers, returning the final result once the stream
-      ///  is closed.
-      /// </summary>
-      global::System.Threading.Tasks.Task<global::Math.Num> Sum(IAsyncStreamReader<global::Math.Num> requestStream, ServerCallContext context);
-    }
-
     /// <summary>Base class for server-side implementations of Math</summary>
     public abstract class MathBase
     {
       /// <summary>
-      ///  Div divides args.dividend by args.divisor and returns the quotient and
-      ///  remainder.
+      ///  Div divides DivArgs.dividend by DivArgs.divisor and returns the quotient
+      ///  and remainder.
       /// </summary>
       public virtual global::System.Threading.Tasks.Task<global::Math.DivReply> Div(global::Math.DivArgs request, ServerCallContext context)
       {
@@ -196,7 +105,7 @@
       }
 
       /// <summary>
-      ///  Fib generates numbers in the Fibonacci sequence.  If args.limit > 0, Fib
+      ///  Fib generates numbers in the Fibonacci sequence.  If FibArgs.limit > 0, Fib
       ///  generates up to limit numbers; otherwise it continues until the call is
       ///  canceled.  Unlike Fib above, Fib has no final FibReply.
       /// </summary>
@@ -217,9 +126,7 @@
     }
 
     /// <summary>Client for Math</summary>
-    #pragma warning disable 0618
-    public class MathClient : ClientBase<MathClient>, IMathClient
-    #pragma warning restore 0618
+    public class MathClient : ClientBase<MathClient>
     {
       public MathClient(Channel channel) : base(channel)
       {
@@ -237,32 +144,32 @@
       }
 
       /// <summary>
-      ///  Div divides args.dividend by args.divisor and returns the quotient and
-      ///  remainder.
+      ///  Div divides DivArgs.dividend by DivArgs.divisor and returns the quotient
+      ///  and remainder.
       /// </summary>
       public virtual global::Math.DivReply Div(global::Math.DivArgs request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         return Div(request, new CallOptions(headers, deadline, cancellationToken));
       }
       /// <summary>
-      ///  Div divides args.dividend by args.divisor and returns the quotient and
-      ///  remainder.
+      ///  Div divides DivArgs.dividend by DivArgs.divisor and returns the quotient
+      ///  and remainder.
       /// </summary>
       public virtual global::Math.DivReply Div(global::Math.DivArgs request, CallOptions options)
       {
         return CallInvoker.BlockingUnaryCall(__Method_Div, null, options, request);
       }
       /// <summary>
-      ///  Div divides args.dividend by args.divisor and returns the quotient and
-      ///  remainder.
+      ///  Div divides DivArgs.dividend by DivArgs.divisor and returns the quotient
+      ///  and remainder.
       /// </summary>
       public virtual AsyncUnaryCall<global::Math.DivReply> DivAsync(global::Math.DivArgs request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
       {
         return DivAsync(request, new CallOptions(headers, deadline, cancellationToken));
       }
       /// <summary>
-      ///  Div divides args.dividend by args.divisor and returns the quotient and
-      ///  remainder.
+      ///  Div divides DivArgs.dividend by DivArgs.divisor and returns the quotient
+      ///  and remainder.
       /// </summary>
       public virtual AsyncUnaryCall<global::Math.DivReply> DivAsync(global::Math.DivArgs request, CallOptions options)
       {
@@ -289,7 +196,7 @@
         return CallInvoker.AsyncDuplexStreamingCall(__Method_DivMany, null, options);
       }
       /// <summary>
-      ///  Fib generates numbers in the Fibonacci sequence.  If args.limit > 0, Fib
+      ///  Fib generates numbers in the Fibonacci sequence.  If FibArgs.limit > 0, Fib
       ///  generates up to limit numbers; otherwise it continues until the call is
       ///  canceled.  Unlike Fib above, Fib has no final FibReply.
       /// </summary>
@@ -298,7 +205,7 @@
         return Fib(request, new CallOptions(headers, deadline, cancellationToken));
       }
       /// <summary>
-      ///  Fib generates numbers in the Fibonacci sequence.  If args.limit > 0, Fib
+      ///  Fib generates numbers in the Fibonacci sequence.  If FibArgs.limit > 0, Fib
       ///  generates up to limit numbers; otherwise it continues until the call is
       ///  canceled.  Unlike Fib above, Fib has no final FibReply.
       /// </summary>
@@ -335,23 +242,9 @@
     }
 
     /// <summary>Creates service definition that can be registered with a server</summary>
-    #pragma warning disable 0618
-    public static ServerServiceDefinition BindService(IMath serviceImpl)
-    #pragma warning restore 0618
-    {
-      return ServerServiceDefinition.CreateBuilder(__ServiceName)
-          .AddMethod(__Method_Div, serviceImpl.Div)
-          .AddMethod(__Method_DivMany, serviceImpl.DivMany)
-          .AddMethod(__Method_Fib, serviceImpl.Fib)
-          .AddMethod(__Method_Sum, serviceImpl.Sum).Build();
-    }
-
-    /// <summary>Creates service definition that can be registered with a server</summary>
-    #pragma warning disable 0618
     public static ServerServiceDefinition BindService(MathBase serviceImpl)
-    #pragma warning restore 0618
     {
-      return ServerServiceDefinition.CreateBuilder(__ServiceName)
+      return ServerServiceDefinition.CreateBuilder()
           .AddMethod(__Method_Div, serviceImpl.Div)
           .AddMethod(__Method_DivMany, serviceImpl.DivMany)
           .AddMethod(__Method_Fib, serviceImpl.Fib)
diff --git a/src/csharp/Grpc.HealthCheck/HealthGrpc.cs b/src/csharp/Grpc.HealthCheck/HealthGrpc.cs
index 51c6a39..d0ade7d 100644
--- a/src/csharp/Grpc.HealthCheck/HealthGrpc.cs
+++ b/src/csharp/Grpc.HealthCheck/HealthGrpc.cs
@@ -58,23 +58,6 @@
       get { return global::Grpc.Health.V1.HealthReflection.Descriptor.Services[0]; }
     }
 
-    /// <summary>Client for Health</summary>
-    [System.Obsolete("Client side interfaced will be removed in the next release. Use client class directly.")]
-    public interface IHealthClient
-    {
-      global::Grpc.Health.V1.HealthCheckResponse Check(global::Grpc.Health.V1.HealthCheckRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
-      global::Grpc.Health.V1.HealthCheckResponse Check(global::Grpc.Health.V1.HealthCheckRequest request, CallOptions options);
-      AsyncUnaryCall<global::Grpc.Health.V1.HealthCheckResponse> CheckAsync(global::Grpc.Health.V1.HealthCheckRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
-      AsyncUnaryCall<global::Grpc.Health.V1.HealthCheckResponse> CheckAsync(global::Grpc.Health.V1.HealthCheckRequest request, CallOptions options);
-    }
-
-    /// <summary>Interface of server-side implementations of Health</summary>
-    [System.Obsolete("Service implementations should inherit from the generated abstract base class instead.")]
-    public interface IHealth
-    {
-      global::System.Threading.Tasks.Task<global::Grpc.Health.V1.HealthCheckResponse> Check(global::Grpc.Health.V1.HealthCheckRequest request, ServerCallContext context);
-    }
-
     /// <summary>Base class for server-side implementations of Health</summary>
     public abstract class HealthBase
     {
@@ -86,9 +69,7 @@
     }
 
     /// <summary>Client for Health</summary>
-    #pragma warning disable 0618
-    public class HealthClient : ClientBase<HealthClient>, IHealthClient
-    #pragma warning restore 0618
+    public class HealthClient : ClientBase<HealthClient>
     {
       public HealthClient(Channel channel) : base(channel)
       {
@@ -134,20 +115,9 @@
     }
 
     /// <summary>Creates service definition that can be registered with a server</summary>
-    #pragma warning disable 0618
-    public static ServerServiceDefinition BindService(IHealth serviceImpl)
-    #pragma warning restore 0618
-    {
-      return ServerServiceDefinition.CreateBuilder(__ServiceName)
-          .AddMethod(__Method_Check, serviceImpl.Check).Build();
-    }
-
-    /// <summary>Creates service definition that can be registered with a server</summary>
-    #pragma warning disable 0618
     public static ServerServiceDefinition BindService(HealthBase serviceImpl)
-    #pragma warning restore 0618
     {
-      return ServerServiceDefinition.CreateBuilder(__ServiceName)
+      return ServerServiceDefinition.CreateBuilder()
           .AddMethod(__Method_Check, serviceImpl.Check).Build();
     }
 
diff --git a/src/csharp/Grpc.IntegrationTesting/GenericService.cs b/src/csharp/Grpc.IntegrationTesting/GenericService.cs
index c612826..53fa1ee 100644
--- a/src/csharp/Grpc.IntegrationTesting/GenericService.cs
+++ b/src/csharp/Grpc.IntegrationTesting/GenericService.cs
@@ -64,7 +64,7 @@
 
         public static ServerServiceDefinition BindHandler(DuplexStreamingServerMethod<byte[], byte[]> handler)
         {
-            return ServerServiceDefinition.CreateBuilder(StreamingCallMethod.ServiceName)
+            return ServerServiceDefinition.CreateBuilder()
                 .AddMethod(StreamingCallMethod, handler).Build();
         }
     }
diff --git a/src/csharp/Grpc.IntegrationTesting/InteropClient.cs b/src/csharp/Grpc.IntegrationTesting/InteropClient.cs
index 1541cfd..aea40af 100644
--- a/src/csharp/Grpc.IntegrationTesting/InteropClient.cs
+++ b/src/csharp/Grpc.IntegrationTesting/InteropClient.cs
@@ -471,8 +471,16 @@
 
                 cts.Cancel();
 
-                var ex = Assert.ThrowsAsync<RpcException>(async () => await call.ResponseStream.MoveNext());
-                Assert.AreEqual(StatusCode.Cancelled, ex.Status.StatusCode);
+                try
+                {
+                    // cannot use Assert.ThrowsAsync because it uses Task.Wait and would deadlock.
+                    await call.ResponseStream.MoveNext();
+                    Assert.Fail();
+                }
+                catch (RpcException ex)
+                {
+                    Assert.AreEqual(StatusCode.Cancelled, ex.Status.StatusCode);
+                }
             }
             Console.WriteLine("Passed!");
         }
@@ -497,9 +505,16 @@
                     // Deadline was reached before write has started. Eat the exception and continue.
                 }
 
-                var ex = Assert.ThrowsAsync<RpcException>(async () => await call.ResponseStream.MoveNext());
-                // We can't guarantee the status code always DeadlineExceeded. See issue #2685.
-                Assert.Contains(ex.Status.StatusCode, new[] { StatusCode.DeadlineExceeded, StatusCode.Internal });
+                try
+                {
+                    await call.ResponseStream.MoveNext();
+                    Assert.Fail();
+                }
+                catch (RpcException ex)
+                {
+                    // We can't guarantee the status code always DeadlineExceeded. See issue #2685.
+                    Assert.Contains(ex.Status.StatusCode, new[] { StatusCode.DeadlineExceeded, StatusCode.Internal });
+                }
             }
             Console.WriteLine("Passed!");
         }
@@ -577,9 +592,17 @@
                 await call.RequestStream.WriteAsync(request);
                 await call.RequestStream.CompleteAsync();
 
-                var e = Assert.ThrowsAsync<RpcException>(async () => await call.ResponseStream.ToListAsync());
-                Assert.AreEqual(StatusCode.Unknown, e.Status.StatusCode);
-                Assert.AreEqual(echoStatus.Message, e.Status.Detail);
+                try
+                {
+                    // cannot use Assert.ThrowsAsync because it uses Task.Wait and would deadlock.
+                    await call.ResponseStream.ToListAsync();
+                    Assert.Fail();
+                }
+                catch (RpcException e)
+                {
+                    Assert.AreEqual(StatusCode.Unknown, e.Status.StatusCode);
+                    Assert.AreEqual(echoStatus.Message, e.Status.Detail);
+                }
             }
 
             Console.WriteLine("Passed!");
diff --git a/src/csharp/Grpc.IntegrationTesting/MetricsGrpc.cs b/src/csharp/Grpc.IntegrationTesting/MetricsGrpc.cs
index 9d31d1c..22bd27e 100644
--- a/src/csharp/Grpc.IntegrationTesting/MetricsGrpc.cs
+++ b/src/csharp/Grpc.IntegrationTesting/MetricsGrpc.cs
@@ -72,53 +72,6 @@
       get { return global::Grpc.Testing.MetricsReflection.Descriptor.Services[0]; }
     }
 
-    /// <summary>Client for MetricsService</summary>
-    [System.Obsolete("Client side interfaced will be removed in the next release. Use client class directly.")]
-    public interface IMetricsServiceClient
-    {
-      /// <summary>
-      ///  Returns the values of all the gauges that are currently being maintained by
-      ///  the service
-      /// </summary>
-      AsyncServerStreamingCall<global::Grpc.Testing.GaugeResponse> GetAllGauges(global::Grpc.Testing.EmptyMessage request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
-      /// <summary>
-      ///  Returns the values of all the gauges that are currently being maintained by
-      ///  the service
-      /// </summary>
-      AsyncServerStreamingCall<global::Grpc.Testing.GaugeResponse> GetAllGauges(global::Grpc.Testing.EmptyMessage request, CallOptions options);
-      /// <summary>
-      ///  Returns the value of one gauge
-      /// </summary>
-      global::Grpc.Testing.GaugeResponse GetGauge(global::Grpc.Testing.GaugeRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
-      /// <summary>
-      ///  Returns the value of one gauge
-      /// </summary>
-      global::Grpc.Testing.GaugeResponse GetGauge(global::Grpc.Testing.GaugeRequest request, CallOptions options);
-      /// <summary>
-      ///  Returns the value of one gauge
-      /// </summary>
-      AsyncUnaryCall<global::Grpc.Testing.GaugeResponse> GetGaugeAsync(global::Grpc.Testing.GaugeRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
-      /// <summary>
-      ///  Returns the value of one gauge
-      /// </summary>
-      AsyncUnaryCall<global::Grpc.Testing.GaugeResponse> GetGaugeAsync(global::Grpc.Testing.GaugeRequest request, CallOptions options);
-    }
-
-    /// <summary>Interface of server-side implementations of MetricsService</summary>
-    [System.Obsolete("Service implementations should inherit from the generated abstract base class instead.")]
-    public interface IMetricsService
-    {
-      /// <summary>
-      ///  Returns the values of all the gauges that are currently being maintained by
-      ///  the service
-      /// </summary>
-      global::System.Threading.Tasks.Task GetAllGauges(global::Grpc.Testing.EmptyMessage request, IServerStreamWriter<global::Grpc.Testing.GaugeResponse> responseStream, ServerCallContext context);
-      /// <summary>
-      ///  Returns the value of one gauge
-      /// </summary>
-      global::System.Threading.Tasks.Task<global::Grpc.Testing.GaugeResponse> GetGauge(global::Grpc.Testing.GaugeRequest request, ServerCallContext context);
-    }
-
     /// <summary>Base class for server-side implementations of MetricsService</summary>
     public abstract class MetricsServiceBase
     {
@@ -142,9 +95,7 @@
     }
 
     /// <summary>Client for MetricsService</summary>
-    #pragma warning disable 0618
-    public class MetricsServiceClient : ClientBase<MetricsServiceClient>, IMetricsServiceClient
-    #pragma warning restore 0618
+    public class MetricsServiceClient : ClientBase<MetricsServiceClient>
     {
       public MetricsServiceClient(Channel channel) : base(channel)
       {
@@ -218,21 +169,9 @@
     }
 
     /// <summary>Creates service definition that can be registered with a server</summary>
-    #pragma warning disable 0618
-    public static ServerServiceDefinition BindService(IMetricsService serviceImpl)
-    #pragma warning restore 0618
-    {
-      return ServerServiceDefinition.CreateBuilder(__ServiceName)
-          .AddMethod(__Method_GetAllGauges, serviceImpl.GetAllGauges)
-          .AddMethod(__Method_GetGauge, serviceImpl.GetGauge).Build();
-    }
-
-    /// <summary>Creates service definition that can be registered with a server</summary>
-    #pragma warning disable 0618
     public static ServerServiceDefinition BindService(MetricsServiceBase serviceImpl)
-    #pragma warning restore 0618
     {
-      return ServerServiceDefinition.CreateBuilder(__ServiceName)
+      return ServerServiceDefinition.CreateBuilder()
           .AddMethod(__Method_GetAllGauges, serviceImpl.GetAllGauges)
           .AddMethod(__Method_GetGauge, serviceImpl.GetGauge).Build();
     }
diff --git a/src/csharp/Grpc.IntegrationTesting/ServicesGrpc.cs b/src/csharp/Grpc.IntegrationTesting/ServicesGrpc.cs
index f7071eb..9c99296 100644
--- a/src/csharp/Grpc.IntegrationTesting/ServicesGrpc.cs
+++ b/src/csharp/Grpc.IntegrationTesting/ServicesGrpc.cs
@@ -67,58 +67,6 @@
       get { return global::Grpc.Testing.ServicesReflection.Descriptor.Services[0]; }
     }
 
-    /// <summary>Client for BenchmarkService</summary>
-    [System.Obsolete("Client side interfaced will be removed in the next release. Use client class directly.")]
-    public interface IBenchmarkServiceClient
-    {
-      /// <summary>
-      ///  One request followed by one response.
-      ///  The server returns the client payload as-is.
-      /// </summary>
-      global::Grpc.Testing.SimpleResponse UnaryCall(global::Grpc.Testing.SimpleRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
-      /// <summary>
-      ///  One request followed by one response.
-      ///  The server returns the client payload as-is.
-      /// </summary>
-      global::Grpc.Testing.SimpleResponse UnaryCall(global::Grpc.Testing.SimpleRequest request, CallOptions options);
-      /// <summary>
-      ///  One request followed by one response.
-      ///  The server returns the client payload as-is.
-      /// </summary>
-      AsyncUnaryCall<global::Grpc.Testing.SimpleResponse> UnaryCallAsync(global::Grpc.Testing.SimpleRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
-      /// <summary>
-      ///  One request followed by one response.
-      ///  The server returns the client payload as-is.
-      /// </summary>
-      AsyncUnaryCall<global::Grpc.Testing.SimpleResponse> UnaryCallAsync(global::Grpc.Testing.SimpleRequest request, CallOptions options);
-      /// <summary>
-      ///  One request followed by one response.
-      ///  The server returns the client payload as-is.
-      /// </summary>
-      AsyncDuplexStreamingCall<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse> StreamingCall(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
-      /// <summary>
-      ///  One request followed by one response.
-      ///  The server returns the client payload as-is.
-      /// </summary>
-      AsyncDuplexStreamingCall<global::Grpc.Testing.SimpleRequest, global::Grpc.Testing.SimpleResponse> StreamingCall(CallOptions options);
-    }
-
-    /// <summary>Interface of server-side implementations of BenchmarkService</summary>
-    [System.Obsolete("Service implementations should inherit from the generated abstract base class instead.")]
-    public interface IBenchmarkService
-    {
-      /// <summary>
-      ///  One request followed by one response.
-      ///  The server returns the client payload as-is.
-      /// </summary>
-      global::System.Threading.Tasks.Task<global::Grpc.Testing.SimpleResponse> UnaryCall(global::Grpc.Testing.SimpleRequest request, ServerCallContext context);
-      /// <summary>
-      ///  One request followed by one response.
-      ///  The server returns the client payload as-is.
-      /// </summary>
-      global::System.Threading.Tasks.Task StreamingCall(IAsyncStreamReader<global::Grpc.Testing.SimpleRequest> requestStream, IServerStreamWriter<global::Grpc.Testing.SimpleResponse> responseStream, ServerCallContext context);
-    }
-
     /// <summary>Base class for server-side implementations of BenchmarkService</summary>
     public abstract class BenchmarkServiceBase
     {
@@ -143,9 +91,7 @@
     }
 
     /// <summary>Client for BenchmarkService</summary>
-    #pragma warning disable 0618
-    public class BenchmarkServiceClient : ClientBase<BenchmarkServiceClient>, IBenchmarkServiceClient
-    #pragma warning restore 0618
+    public class BenchmarkServiceClient : ClientBase<BenchmarkServiceClient>
     {
       public BenchmarkServiceClient(Channel channel) : base(channel)
       {
@@ -223,21 +169,9 @@
     }
 
     /// <summary>Creates service definition that can be registered with a server</summary>
-    #pragma warning disable 0618
-    public static ServerServiceDefinition BindService(IBenchmarkService serviceImpl)
-    #pragma warning restore 0618
-    {
-      return ServerServiceDefinition.CreateBuilder(__ServiceName)
-          .AddMethod(__Method_UnaryCall, serviceImpl.UnaryCall)
-          .AddMethod(__Method_StreamingCall, serviceImpl.StreamingCall).Build();
-    }
-
-    /// <summary>Creates service definition that can be registered with a server</summary>
-    #pragma warning disable 0618
     public static ServerServiceDefinition BindService(BenchmarkServiceBase serviceImpl)
-    #pragma warning restore 0618
     {
-      return ServerServiceDefinition.CreateBuilder(__ServiceName)
+      return ServerServiceDefinition.CreateBuilder()
           .AddMethod(__Method_UnaryCall, serviceImpl.UnaryCall)
           .AddMethod(__Method_StreamingCall, serviceImpl.StreamingCall).Build();
     }
@@ -289,112 +223,6 @@
       get { return global::Grpc.Testing.ServicesReflection.Descriptor.Services[1]; }
     }
 
-    /// <summary>Client for WorkerService</summary>
-    [System.Obsolete("Client side interfaced will be removed in the next release. Use client class directly.")]
-    public interface IWorkerServiceClient
-    {
-      /// <summary>
-      ///  Start server with specified workload.
-      ///  First request sent specifies the ServerConfig followed by ServerStatus
-      ///  response. After that, a "Mark" can be sent anytime to request the latest
-      ///  stats. Closing the stream will initiate shutdown of the test server
-      ///  and once the shutdown has finished, the OK status is sent to terminate
-      ///  this RPC.
-      /// </summary>
-      AsyncDuplexStreamingCall<global::Grpc.Testing.ServerArgs, global::Grpc.Testing.ServerStatus> RunServer(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
-      /// <summary>
-      ///  Start server with specified workload.
-      ///  First request sent specifies the ServerConfig followed by ServerStatus
-      ///  response. After that, a "Mark" can be sent anytime to request the latest
-      ///  stats. Closing the stream will initiate shutdown of the test server
-      ///  and once the shutdown has finished, the OK status is sent to terminate
-      ///  this RPC.
-      /// </summary>
-      AsyncDuplexStreamingCall<global::Grpc.Testing.ServerArgs, global::Grpc.Testing.ServerStatus> RunServer(CallOptions options);
-      /// <summary>
-      ///  Start client with specified workload.
-      ///  First request sent specifies the ClientConfig followed by ClientStatus
-      ///  response. After that, a "Mark" can be sent anytime to request the latest
-      ///  stats. Closing the stream will initiate shutdown of the test client
-      ///  and once the shutdown has finished, the OK status is sent to terminate
-      ///  this RPC.
-      /// </summary>
-      AsyncDuplexStreamingCall<global::Grpc.Testing.ClientArgs, global::Grpc.Testing.ClientStatus> RunClient(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
-      /// <summary>
-      ///  Start client with specified workload.
-      ///  First request sent specifies the ClientConfig followed by ClientStatus
-      ///  response. After that, a "Mark" can be sent anytime to request the latest
-      ///  stats. Closing the stream will initiate shutdown of the test client
-      ///  and once the shutdown has finished, the OK status is sent to terminate
-      ///  this RPC.
-      /// </summary>
-      AsyncDuplexStreamingCall<global::Grpc.Testing.ClientArgs, global::Grpc.Testing.ClientStatus> RunClient(CallOptions options);
-      /// <summary>
-      ///  Just return the core count - unary call
-      /// </summary>
-      global::Grpc.Testing.CoreResponse CoreCount(global::Grpc.Testing.CoreRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
-      /// <summary>
-      ///  Just return the core count - unary call
-      /// </summary>
-      global::Grpc.Testing.CoreResponse CoreCount(global::Grpc.Testing.CoreRequest request, CallOptions options);
-      /// <summary>
-      ///  Just return the core count - unary call
-      /// </summary>
-      AsyncUnaryCall<global::Grpc.Testing.CoreResponse> CoreCountAsync(global::Grpc.Testing.CoreRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
-      /// <summary>
-      ///  Just return the core count - unary call
-      /// </summary>
-      AsyncUnaryCall<global::Grpc.Testing.CoreResponse> CoreCountAsync(global::Grpc.Testing.CoreRequest request, CallOptions options);
-      /// <summary>
-      ///  Quit this worker
-      /// </summary>
-      global::Grpc.Testing.Void QuitWorker(global::Grpc.Testing.Void request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
-      /// <summary>
-      ///  Quit this worker
-      /// </summary>
-      global::Grpc.Testing.Void QuitWorker(global::Grpc.Testing.Void request, CallOptions options);
-      /// <summary>
-      ///  Quit this worker
-      /// </summary>
-      AsyncUnaryCall<global::Grpc.Testing.Void> QuitWorkerAsync(global::Grpc.Testing.Void request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
-      /// <summary>
-      ///  Quit this worker
-      /// </summary>
-      AsyncUnaryCall<global::Grpc.Testing.Void> QuitWorkerAsync(global::Grpc.Testing.Void request, CallOptions options);
-    }
-
-    /// <summary>Interface of server-side implementations of WorkerService</summary>
-    [System.Obsolete("Service implementations should inherit from the generated abstract base class instead.")]
-    public interface IWorkerService
-    {
-      /// <summary>
-      ///  Start server with specified workload.
-      ///  First request sent specifies the ServerConfig followed by ServerStatus
-      ///  response. After that, a "Mark" can be sent anytime to request the latest
-      ///  stats. Closing the stream will initiate shutdown of the test server
-      ///  and once the shutdown has finished, the OK status is sent to terminate
-      ///  this RPC.
-      /// </summary>
-      global::System.Threading.Tasks.Task RunServer(IAsyncStreamReader<global::Grpc.Testing.ServerArgs> requestStream, IServerStreamWriter<global::Grpc.Testing.ServerStatus> responseStream, ServerCallContext context);
-      /// <summary>
-      ///  Start client with specified workload.
-      ///  First request sent specifies the ClientConfig followed by ClientStatus
-      ///  response. After that, a "Mark" can be sent anytime to request the latest
-      ///  stats. Closing the stream will initiate shutdown of the test client
-      ///  and once the shutdown has finished, the OK status is sent to terminate
-      ///  this RPC.
-      /// </summary>
-      global::System.Threading.Tasks.Task RunClient(IAsyncStreamReader<global::Grpc.Testing.ClientArgs> requestStream, IServerStreamWriter<global::Grpc.Testing.ClientStatus> responseStream, ServerCallContext context);
-      /// <summary>
-      ///  Just return the core count - unary call
-      /// </summary>
-      global::System.Threading.Tasks.Task<global::Grpc.Testing.CoreResponse> CoreCount(global::Grpc.Testing.CoreRequest request, ServerCallContext context);
-      /// <summary>
-      ///  Quit this worker
-      /// </summary>
-      global::System.Threading.Tasks.Task<global::Grpc.Testing.Void> QuitWorker(global::Grpc.Testing.Void request, ServerCallContext context);
-    }
-
     /// <summary>Base class for server-side implementations of WorkerService</summary>
     public abstract class WorkerServiceBase
     {
@@ -443,9 +271,7 @@
     }
 
     /// <summary>Client for WorkerService</summary>
-    #pragma warning disable 0618
-    public class WorkerServiceClient : ClientBase<WorkerServiceClient>, IWorkerServiceClient
-    #pragma warning restore 0618
+    public class WorkerServiceClient : ClientBase<WorkerServiceClient>
     {
       public WorkerServiceClient(Channel channel) : base(channel)
       {
@@ -579,23 +405,9 @@
     }
 
     /// <summary>Creates service definition that can be registered with a server</summary>
-    #pragma warning disable 0618
-    public static ServerServiceDefinition BindService(IWorkerService serviceImpl)
-    #pragma warning restore 0618
-    {
-      return ServerServiceDefinition.CreateBuilder(__ServiceName)
-          .AddMethod(__Method_RunServer, serviceImpl.RunServer)
-          .AddMethod(__Method_RunClient, serviceImpl.RunClient)
-          .AddMethod(__Method_CoreCount, serviceImpl.CoreCount)
-          .AddMethod(__Method_QuitWorker, serviceImpl.QuitWorker).Build();
-    }
-
-    /// <summary>Creates service definition that can be registered with a server</summary>
-    #pragma warning disable 0618
     public static ServerServiceDefinition BindService(WorkerServiceBase serviceImpl)
-    #pragma warning restore 0618
     {
-      return ServerServiceDefinition.CreateBuilder(__ServiceName)
+      return ServerServiceDefinition.CreateBuilder()
           .AddMethod(__Method_RunServer, serviceImpl.RunServer)
           .AddMethod(__Method_RunClient, serviceImpl.RunClient)
           .AddMethod(__Method_CoreCount, serviceImpl.CoreCount)
diff --git a/src/csharp/Grpc.IntegrationTesting/TestGrpc.cs b/src/csharp/Grpc.IntegrationTesting/TestGrpc.cs
index cf43a77..6c25201 100644
--- a/src/csharp/Grpc.IntegrationTesting/TestGrpc.cs
+++ b/src/csharp/Grpc.IntegrationTesting/TestGrpc.cs
@@ -105,127 +105,6 @@
       get { return global::Grpc.Testing.TestReflection.Descriptor.Services[0]; }
     }
 
-    /// <summary>Client for TestService</summary>
-    [System.Obsolete("Client side interfaced will be removed in the next release. Use client class directly.")]
-    public interface ITestServiceClient
-    {
-      /// <summary>
-      ///  One empty request followed by one empty response.
-      /// </summary>
-      global::Grpc.Testing.Empty EmptyCall(global::Grpc.Testing.Empty request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
-      /// <summary>
-      ///  One empty request followed by one empty response.
-      /// </summary>
-      global::Grpc.Testing.Empty EmptyCall(global::Grpc.Testing.Empty request, CallOptions options);
-      /// <summary>
-      ///  One empty request followed by one empty response.
-      /// </summary>
-      AsyncUnaryCall<global::Grpc.Testing.Empty> EmptyCallAsync(global::Grpc.Testing.Empty request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
-      /// <summary>
-      ///  One empty request followed by one empty response.
-      /// </summary>
-      AsyncUnaryCall<global::Grpc.Testing.Empty> EmptyCallAsync(global::Grpc.Testing.Empty request, CallOptions options);
-      /// <summary>
-      ///  One request followed by one response.
-      /// </summary>
-      global::Grpc.Testing.SimpleResponse UnaryCall(global::Grpc.Testing.SimpleRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
-      /// <summary>
-      ///  One request followed by one response.
-      /// </summary>
-      global::Grpc.Testing.SimpleResponse UnaryCall(global::Grpc.Testing.SimpleRequest request, CallOptions options);
-      /// <summary>
-      ///  One request followed by one response.
-      /// </summary>
-      AsyncUnaryCall<global::Grpc.Testing.SimpleResponse> UnaryCallAsync(global::Grpc.Testing.SimpleRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
-      /// <summary>
-      ///  One request followed by one response.
-      /// </summary>
-      AsyncUnaryCall<global::Grpc.Testing.SimpleResponse> UnaryCallAsync(global::Grpc.Testing.SimpleRequest request, CallOptions options);
-      /// <summary>
-      ///  One request followed by a sequence of responses (streamed download).
-      ///  The server returns the payload with client desired type and sizes.
-      /// </summary>
-      AsyncServerStreamingCall<global::Grpc.Testing.StreamingOutputCallResponse> StreamingOutputCall(global::Grpc.Testing.StreamingOutputCallRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
-      /// <summary>
-      ///  One request followed by a sequence of responses (streamed download).
-      ///  The server returns the payload with client desired type and sizes.
-      /// </summary>
-      AsyncServerStreamingCall<global::Grpc.Testing.StreamingOutputCallResponse> StreamingOutputCall(global::Grpc.Testing.StreamingOutputCallRequest request, CallOptions options);
-      /// <summary>
-      ///  A sequence of requests followed by one response (streamed upload).
-      ///  The server returns the aggregated size of client payload as the result.
-      /// </summary>
-      AsyncClientStreamingCall<global::Grpc.Testing.StreamingInputCallRequest, global::Grpc.Testing.StreamingInputCallResponse> StreamingInputCall(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
-      /// <summary>
-      ///  A sequence of requests followed by one response (streamed upload).
-      ///  The server returns the aggregated size of client payload as the result.
-      /// </summary>
-      AsyncClientStreamingCall<global::Grpc.Testing.StreamingInputCallRequest, global::Grpc.Testing.StreamingInputCallResponse> StreamingInputCall(CallOptions options);
-      /// <summary>
-      ///  A sequence of requests with each request served by the server immediately.
-      ///  As one request could lead to multiple responses, this interface
-      ///  demonstrates the idea of full duplexing.
-      /// </summary>
-      AsyncDuplexStreamingCall<global::Grpc.Testing.StreamingOutputCallRequest, global::Grpc.Testing.StreamingOutputCallResponse> FullDuplexCall(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
-      /// <summary>
-      ///  A sequence of requests with each request served by the server immediately.
-      ///  As one request could lead to multiple responses, this interface
-      ///  demonstrates the idea of full duplexing.
-      /// </summary>
-      AsyncDuplexStreamingCall<global::Grpc.Testing.StreamingOutputCallRequest, global::Grpc.Testing.StreamingOutputCallResponse> FullDuplexCall(CallOptions options);
-      /// <summary>
-      ///  A sequence of requests followed by a sequence of responses.
-      ///  The server buffers all the client requests and then serves them in order. A
-      ///  stream of responses are returned to the client when the server starts with
-      ///  first request.
-      /// </summary>
-      AsyncDuplexStreamingCall<global::Grpc.Testing.StreamingOutputCallRequest, global::Grpc.Testing.StreamingOutputCallResponse> HalfDuplexCall(Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
-      /// <summary>
-      ///  A sequence of requests followed by a sequence of responses.
-      ///  The server buffers all the client requests and then serves them in order. A
-      ///  stream of responses are returned to the client when the server starts with
-      ///  first request.
-      /// </summary>
-      AsyncDuplexStreamingCall<global::Grpc.Testing.StreamingOutputCallRequest, global::Grpc.Testing.StreamingOutputCallResponse> HalfDuplexCall(CallOptions options);
-    }
-
-    /// <summary>Interface of server-side implementations of TestService</summary>
-    [System.Obsolete("Service implementations should inherit from the generated abstract base class instead.")]
-    public interface ITestService
-    {
-      /// <summary>
-      ///  One empty request followed by one empty response.
-      /// </summary>
-      global::System.Threading.Tasks.Task<global::Grpc.Testing.Empty> EmptyCall(global::Grpc.Testing.Empty request, ServerCallContext context);
-      /// <summary>
-      ///  One request followed by one response.
-      /// </summary>
-      global::System.Threading.Tasks.Task<global::Grpc.Testing.SimpleResponse> UnaryCall(global::Grpc.Testing.SimpleRequest request, ServerCallContext context);
-      /// <summary>
-      ///  One request followed by a sequence of responses (streamed download).
-      ///  The server returns the payload with client desired type and sizes.
-      /// </summary>
-      global::System.Threading.Tasks.Task StreamingOutputCall(global::Grpc.Testing.StreamingOutputCallRequest request, IServerStreamWriter<global::Grpc.Testing.StreamingOutputCallResponse> responseStream, ServerCallContext context);
-      /// <summary>
-      ///  A sequence of requests followed by one response (streamed upload).
-      ///  The server returns the aggregated size of client payload as the result.
-      /// </summary>
-      global::System.Threading.Tasks.Task<global::Grpc.Testing.StreamingInputCallResponse> StreamingInputCall(IAsyncStreamReader<global::Grpc.Testing.StreamingInputCallRequest> requestStream, ServerCallContext context);
-      /// <summary>
-      ///  A sequence of requests with each request served by the server immediately.
-      ///  As one request could lead to multiple responses, this interface
-      ///  demonstrates the idea of full duplexing.
-      /// </summary>
-      global::System.Threading.Tasks.Task FullDuplexCall(IAsyncStreamReader<global::Grpc.Testing.StreamingOutputCallRequest> requestStream, IServerStreamWriter<global::Grpc.Testing.StreamingOutputCallResponse> responseStream, ServerCallContext context);
-      /// <summary>
-      ///  A sequence of requests followed by a sequence of responses.
-      ///  The server buffers all the client requests and then serves them in order. A
-      ///  stream of responses are returned to the client when the server starts with
-      ///  first request.
-      /// </summary>
-      global::System.Threading.Tasks.Task HalfDuplexCall(IAsyncStreamReader<global::Grpc.Testing.StreamingOutputCallRequest> requestStream, IServerStreamWriter<global::Grpc.Testing.StreamingOutputCallResponse> responseStream, ServerCallContext context);
-    }
-
     /// <summary>Base class for server-side implementations of TestService</summary>
     public abstract class TestServiceBase
     {
@@ -287,9 +166,7 @@
     }
 
     /// <summary>Client for TestService</summary>
-    #pragma warning disable 0618
-    public class TestServiceClient : ClientBase<TestServiceClient>, ITestServiceClient
-    #pragma warning restore 0618
+    public class TestServiceClient : ClientBase<TestServiceClient>
     {
       public TestServiceClient(Channel channel) : base(channel)
       {
@@ -445,25 +322,9 @@
     }
 
     /// <summary>Creates service definition that can be registered with a server</summary>
-    #pragma warning disable 0618
-    public static ServerServiceDefinition BindService(ITestService serviceImpl)
-    #pragma warning restore 0618
-    {
-      return ServerServiceDefinition.CreateBuilder(__ServiceName)
-          .AddMethod(__Method_EmptyCall, serviceImpl.EmptyCall)
-          .AddMethod(__Method_UnaryCall, serviceImpl.UnaryCall)
-          .AddMethod(__Method_StreamingOutputCall, serviceImpl.StreamingOutputCall)
-          .AddMethod(__Method_StreamingInputCall, serviceImpl.StreamingInputCall)
-          .AddMethod(__Method_FullDuplexCall, serviceImpl.FullDuplexCall)
-          .AddMethod(__Method_HalfDuplexCall, serviceImpl.HalfDuplexCall).Build();
-    }
-
-    /// <summary>Creates service definition that can be registered with a server</summary>
-    #pragma warning disable 0618
     public static ServerServiceDefinition BindService(TestServiceBase serviceImpl)
-    #pragma warning restore 0618
     {
-      return ServerServiceDefinition.CreateBuilder(__ServiceName)
+      return ServerServiceDefinition.CreateBuilder()
           .AddMethod(__Method_EmptyCall, serviceImpl.EmptyCall)
           .AddMethod(__Method_UnaryCall, serviceImpl.UnaryCall)
           .AddMethod(__Method_StreamingOutputCall, serviceImpl.StreamingOutputCall)
@@ -496,38 +357,6 @@
       get { return global::Grpc.Testing.TestReflection.Descriptor.Services[1]; }
     }
 
-    /// <summary>Client for UnimplementedService</summary>
-    [System.Obsolete("Client side interfaced will be removed in the next release. Use client class directly.")]
-    public interface IUnimplementedServiceClient
-    {
-      /// <summary>
-      ///  A call that no server should implement
-      /// </summary>
-      global::Grpc.Testing.Empty UnimplementedCall(global::Grpc.Testing.Empty request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
-      /// <summary>
-      ///  A call that no server should implement
-      /// </summary>
-      global::Grpc.Testing.Empty UnimplementedCall(global::Grpc.Testing.Empty request, CallOptions options);
-      /// <summary>
-      ///  A call that no server should implement
-      /// </summary>
-      AsyncUnaryCall<global::Grpc.Testing.Empty> UnimplementedCallAsync(global::Grpc.Testing.Empty request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
-      /// <summary>
-      ///  A call that no server should implement
-      /// </summary>
-      AsyncUnaryCall<global::Grpc.Testing.Empty> UnimplementedCallAsync(global::Grpc.Testing.Empty request, CallOptions options);
-    }
-
-    /// <summary>Interface of server-side implementations of UnimplementedService</summary>
-    [System.Obsolete("Service implementations should inherit from the generated abstract base class instead.")]
-    public interface IUnimplementedService
-    {
-      /// <summary>
-      ///  A call that no server should implement
-      /// </summary>
-      global::System.Threading.Tasks.Task<global::Grpc.Testing.Empty> UnimplementedCall(global::Grpc.Testing.Empty request, ServerCallContext context);
-    }
-
     /// <summary>Base class for server-side implementations of UnimplementedService</summary>
     public abstract class UnimplementedServiceBase
     {
@@ -542,9 +371,7 @@
     }
 
     /// <summary>Client for UnimplementedService</summary>
-    #pragma warning disable 0618
-    public class UnimplementedServiceClient : ClientBase<UnimplementedServiceClient>, IUnimplementedServiceClient
-    #pragma warning restore 0618
+    public class UnimplementedServiceClient : ClientBase<UnimplementedServiceClient>
     {
       public UnimplementedServiceClient(Channel channel) : base(channel)
       {
@@ -602,20 +429,9 @@
     }
 
     /// <summary>Creates service definition that can be registered with a server</summary>
-    #pragma warning disable 0618
-    public static ServerServiceDefinition BindService(IUnimplementedService serviceImpl)
-    #pragma warning restore 0618
-    {
-      return ServerServiceDefinition.CreateBuilder(__ServiceName)
-          .AddMethod(__Method_UnimplementedCall, serviceImpl.UnimplementedCall).Build();
-    }
-
-    /// <summary>Creates service definition that can be registered with a server</summary>
-    #pragma warning disable 0618
     public static ServerServiceDefinition BindService(UnimplementedServiceBase serviceImpl)
-    #pragma warning restore 0618
     {
-      return ServerServiceDefinition.CreateBuilder(__ServiceName)
+      return ServerServiceDefinition.CreateBuilder()
           .AddMethod(__Method_UnimplementedCall, serviceImpl.UnimplementedCall).Build();
     }
 
@@ -651,28 +467,6 @@
       get { return global::Grpc.Testing.TestReflection.Descriptor.Services[2]; }
     }
 
-    /// <summary>Client for ReconnectService</summary>
-    [System.Obsolete("Client side interfaced will be removed in the next release. Use client class directly.")]
-    public interface IReconnectServiceClient
-    {
-      global::Grpc.Testing.Empty Start(global::Grpc.Testing.ReconnectParams request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
-      global::Grpc.Testing.Empty Start(global::Grpc.Testing.ReconnectParams request, CallOptions options);
-      AsyncUnaryCall<global::Grpc.Testing.Empty> StartAsync(global::Grpc.Testing.ReconnectParams request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
-      AsyncUnaryCall<global::Grpc.Testing.Empty> StartAsync(global::Grpc.Testing.ReconnectParams request, CallOptions options);
-      global::Grpc.Testing.ReconnectInfo Stop(global::Grpc.Testing.Empty request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
-      global::Grpc.Testing.ReconnectInfo Stop(global::Grpc.Testing.Empty request, CallOptions options);
-      AsyncUnaryCall<global::Grpc.Testing.ReconnectInfo> StopAsync(global::Grpc.Testing.Empty request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken));
-      AsyncUnaryCall<global::Grpc.Testing.ReconnectInfo> StopAsync(global::Grpc.Testing.Empty request, CallOptions options);
-    }
-
-    /// <summary>Interface of server-side implementations of ReconnectService</summary>
-    [System.Obsolete("Service implementations should inherit from the generated abstract base class instead.")]
-    public interface IReconnectService
-    {
-      global::System.Threading.Tasks.Task<global::Grpc.Testing.Empty> Start(global::Grpc.Testing.ReconnectParams request, ServerCallContext context);
-      global::System.Threading.Tasks.Task<global::Grpc.Testing.ReconnectInfo> Stop(global::Grpc.Testing.Empty request, ServerCallContext context);
-    }
-
     /// <summary>Base class for server-side implementations of ReconnectService</summary>
     public abstract class ReconnectServiceBase
     {
@@ -689,9 +483,7 @@
     }
 
     /// <summary>Client for ReconnectService</summary>
-    #pragma warning disable 0618
-    public class ReconnectServiceClient : ClientBase<ReconnectServiceClient>, IReconnectServiceClient
-    #pragma warning restore 0618
+    public class ReconnectServiceClient : ClientBase<ReconnectServiceClient>
     {
       public ReconnectServiceClient(Channel channel) : base(channel)
       {
@@ -753,21 +545,9 @@
     }
 
     /// <summary>Creates service definition that can be registered with a server</summary>
-    #pragma warning disable 0618
-    public static ServerServiceDefinition BindService(IReconnectService serviceImpl)
-    #pragma warning restore 0618
-    {
-      return ServerServiceDefinition.CreateBuilder(__ServiceName)
-          .AddMethod(__Method_Start, serviceImpl.Start)
-          .AddMethod(__Method_Stop, serviceImpl.Stop).Build();
-    }
-
-    /// <summary>Creates service definition that can be registered with a server</summary>
-    #pragma warning disable 0618
     public static ServerServiceDefinition BindService(ReconnectServiceBase serviceImpl)
-    #pragma warning restore 0618
     {
-      return ServerServiceDefinition.CreateBuilder(__ServiceName)
+      return ServerServiceDefinition.CreateBuilder()
           .AddMethod(__Method_Start, serviceImpl.Start)
           .AddMethod(__Method_Stop, serviceImpl.Stop).Build();
     }
diff --git a/src/csharp/ext/grpc_csharp_ext.c b/src/csharp/ext/grpc_csharp_ext.c
index 5b8ff9b..4782654 100644
--- a/src/csharp/ext/grpc_csharp_ext.c
+++ b/src/csharp/ext/grpc_csharp_ext.c
@@ -45,7 +45,7 @@
 
 #include <string.h>
 
-#ifdef GPR_WIN32
+#ifdef GPR_WINDOWS
 #define GPR_EXPORT __declspec(dllexport)
 #define GPR_CALLTYPE __stdcall
 #endif
@@ -503,6 +503,7 @@
                            grpc_metadata_array *initial_metadata, uint32_t write_flags) {
   /* TODO: don't use magic number */
   grpc_op ops[6];
+  memset(ops, 0, sizeof(ops));
   ops[0].op = GRPC_OP_SEND_INITIAL_METADATA;
   grpcsharp_metadata_array_move(&(ctx->send_initial_metadata),
                                 initial_metadata);
@@ -555,6 +556,7 @@
                                       grpc_metadata_array *initial_metadata) {
   /* TODO: don't use magic number */
   grpc_op ops[4];
+  memset(ops, 0, sizeof(ops));
   ops[0].op = GRPC_OP_SEND_INITIAL_METADATA;
   grpcsharp_metadata_array_move(&(ctx->send_initial_metadata),
                                 initial_metadata);
@@ -596,6 +598,7 @@
     size_t send_buffer_len, grpc_metadata_array *initial_metadata, uint32_t write_flags) {
   /* TODO: don't use magic number */
   grpc_op ops[4];
+  memset(ops, 0, sizeof(ops));
   ops[0].op = GRPC_OP_SEND_INITIAL_METADATA;
   grpcsharp_metadata_array_move(&(ctx->send_initial_metadata),
                                 initial_metadata);
@@ -638,6 +641,7 @@
                                       grpc_metadata_array *initial_metadata) {
   /* TODO: don't use magic number */
   grpc_op ops[2];
+  memset(ops, 0, sizeof(ops));
   ops[0].op = GRPC_OP_SEND_INITIAL_METADATA;
   grpcsharp_metadata_array_move(&(ctx->send_initial_metadata),
                                 initial_metadata);
@@ -684,6 +688,7 @@
                             int32_t send_empty_initial_metadata) {
   /* TODO: don't use magic number */
   grpc_op ops[2];
+  memset(ops, 0, sizeof(ops));
   size_t nops = send_empty_initial_metadata ? 2 : 1;
   ops[0].op = GRPC_OP_SEND_MESSAGE;
   ctx->send_message = string_to_byte_buffer(send_buffer, send_buffer_len);
@@ -691,8 +696,6 @@
   ops[0].flags = write_flags;
   ops[0].reserved = NULL;
   ops[1].op = GRPC_OP_SEND_INITIAL_METADATA;
-  ops[1].data.send_initial_metadata.count = 0;
-  ops[1].data.send_initial_metadata.metadata = NULL;
   ops[1].flags = 0;
   ops[1].reserved = NULL;
 
@@ -719,6 +722,7 @@
     size_t optional_send_buffer_len, uint32_t write_flags) {
   /* TODO: don't use magic number */
   grpc_op ops[3];
+  memset(ops, 0, sizeof(ops));
   size_t nops = 1;
   ops[0].op = GRPC_OP_SEND_STATUS_FROM_SERVER;
   ops[0].data.send_status_from_server.status = status_code;
@@ -743,8 +747,6 @@
   }
   if (send_empty_initial_metadata) {
     ops[nops].op = GRPC_OP_SEND_INITIAL_METADATA;
-    ops[nops].data.send_initial_metadata.count = 0;
-    ops[nops].data.send_initial_metadata.metadata = NULL;
     ops[nops].flags = 0;
     ops[nops].reserved = NULL;
     nops++;
@@ -784,6 +786,7 @@
                                      grpc_metadata_array *initial_metadata) {
   /* TODO: don't use magic number */
   grpc_op ops[1];
+  memset(ops, 0, sizeof(ops));
   ops[0].op = GRPC_OP_SEND_INITIAL_METADATA;
   grpcsharp_metadata_array_move(&(ctx->send_initial_metadata),
                                 initial_metadata);
@@ -806,11 +809,14 @@
 /* Server */
 
 GPR_EXPORT grpc_server *GPR_CALLTYPE
-grpcsharp_server_create(grpc_completion_queue *cq,
-                        const grpc_channel_args *args) {
-  grpc_server *server = grpc_server_create(args, NULL);
+grpcsharp_server_create(const grpc_channel_args *args) {
+  return grpc_server_create(args, NULL);
+}
+
+GPR_EXPORT void GPR_CALLTYPE
+grpcsharp_server_register_completion_queue(grpc_server *server,
+                                           grpc_completion_queue *cq) {
   grpc_server_register_completion_queue(server, cq, NULL);
-  return server;
 }
 
 GPR_EXPORT int32_t GPR_CALLTYPE
diff --git a/src/csharp/tests.json b/src/csharp/tests.json
index f6af340..7e7aee1 100644
--- a/src/csharp/tests.json
+++ b/src/csharp/tests.json
@@ -7,6 +7,7 @@
     "Grpc.Core.Internal.Tests.CompletionQueueSafeHandleTest",
     "Grpc.Core.Internal.Tests.MetadataArraySafeHandleTest",
     "Grpc.Core.Internal.Tests.TimespecTest",
+    "Grpc.Core.Tests.AppDomainUnloadTest",
     "Grpc.Core.Tests.CallCredentialsTest",
     "Grpc.Core.Tests.CallOptionsTest",
     "Grpc.Core.Tests.ChannelCredentialsTest",
@@ -25,6 +26,9 @@
     "Grpc.Core.Tests.ResponseHeadersTest",
     "Grpc.Core.Tests.SanityTest",
     "Grpc.Core.Tests.ServerTest",
+    "Grpc.Core.Tests.ShutdownHookClientTest",
+    "Grpc.Core.Tests.ShutdownHookPendingCallTest",
+    "Grpc.Core.Tests.ShutdownHookServerTest",
     "Grpc.Core.Tests.ShutdownTest",
     "Grpc.Core.Tests.TimeoutsTest",
     "Grpc.Core.Tests.UserAgentStringTest"
diff --git a/src/node/ext/byte_buffer.cc b/src/node/ext/byte_buffer.cc
index 8e0b691..3479a67 100644
--- a/src/node/ext/byte_buffer.cc
+++ b/src/node/ext/byte_buffer.cc
@@ -72,17 +72,13 @@
   if (buffer == NULL) {
     return scope.Escape(Nan::Null());
   }
-  size_t length = grpc_byte_buffer_length(buffer);
-  char *result = new char[length];
-  size_t offset = 0;
   grpc_byte_buffer_reader reader;
   grpc_byte_buffer_reader_init(&reader, buffer);
-  gpr_slice next;
-  while (grpc_byte_buffer_reader_next(&reader, &next) != 0) {
-    memcpy(result + offset, GPR_SLICE_START_PTR(next), GPR_SLICE_LENGTH(next));
-    offset += GPR_SLICE_LENGTH(next);
-    gpr_slice_unref(next);
-  }
+  gpr_slice slice = grpc_byte_buffer_reader_readall(&reader);
+  size_t length = GPR_SLICE_LENGTH(slice);
+  char *result = new char[length];
+  memcpy(result, GPR_SLICE_START_PTR(slice), length);
+  gpr_slice_unref(slice);
   return scope.Escape(MakeFastBuffer(
       Nan::NewBuffer(result, length, delete_buffer, NULL).ToLocalChecked()));
 }
diff --git a/src/node/ext/node_grpc.cc b/src/node/ext/node_grpc.cc
index 6b6e427..f18ce01 100644
--- a/src/node/ext/node_grpc.cc
+++ b/src/node/ext/node_grpc.cc
@@ -220,7 +220,7 @@
   Nan::Set(channel_state, Nan::New("TRANSIENT_FAILURE").ToLocalChecked(),
            TRANSIENT_FAILURE);
   Local<Value> FATAL_FAILURE(
-      Nan::New<Uint32, uint32_t>(GRPC_CHANNEL_FATAL_FAILURE));
+      Nan::New<Uint32, uint32_t>(GRPC_CHANNEL_SHUTDOWN));
   Nan::Set(channel_state, Nan::New("FATAL_FAILURE").ToLocalChecked(),
            FATAL_FAILURE);
 }
diff --git a/src/node/ext/server.cc b/src/node/ext/server.cc
index b9e1fe9..dd1b777 100644
--- a/src/node/ext/server.cc
+++ b/src/node/ext/server.cc
@@ -35,15 +35,15 @@
 
 #include "server.h"
 
-#include <node.h>
 #include <nan.h>
+#include <node.h>
 
 #include <vector>
+#include "call.h"
+#include "completion_queue_async_worker.h"
 #include "grpc/grpc.h"
 #include "grpc/grpc_security.h"
 #include "grpc/support/log.h"
-#include "call.h"
-#include "completion_queue_async_worker.h"
 #include "server_credentials.h"
 #include "timeval.h"
 
@@ -100,8 +100,8 @@
     Nan::Set(obj, Nan::New("host").ToLocalChecked(),
              Nan::New(details.host).ToLocalChecked());
     Nan::Set(obj, Nan::New("deadline").ToLocalChecked(),
-             Nan::New<Date>(
-                 TimespecToMilliseconds(details.deadline)).ToLocalChecked());
+             Nan::New<Date>(TimespecToMilliseconds(details.deadline))
+                 .ToLocalChecked());
     Nan::Set(obj, Nan::New("metadata").ToLocalChecked(),
              ParseMetadata(&request_metadata));
     return scope.Escape(obj);
@@ -117,14 +117,13 @@
   grpc_metadata_array request_metadata;
 
  protected:
-  std::string GetTypeString() const {
-    return "new_call";
-  }
+  std::string GetTypeString() const { return "new_call"; }
 };
 
 Server::Server(grpc_server *server) : wrapped_server(server) {
   shutdown_queue = grpc_completion_queue_create(NULL);
-  grpc_server_register_completion_queue(server, shutdown_queue, NULL);
+  grpc_server_register_non_listening_completion_queue(server, shutdown_queue,
+                                                      NULL);
 }
 
 Server::~Server() {
@@ -156,8 +155,7 @@
 }
 
 void Server::ShutdownServer() {
-  grpc_server_shutdown_and_notify(this->wrapped_server,
-                                  this->shutdown_queue,
+  grpc_server_shutdown_and_notify(this->wrapped_server, this->shutdown_queue,
                                   NULL);
   grpc_server_cancel_all_calls(this->wrapped_server);
   grpc_completion_queue_pluck(this->shutdown_queue, NULL,
@@ -170,8 +168,8 @@
   if (!info.IsConstructCall()) {
     const int argc = 1;
     Local<Value> argv[argc] = {info[0]};
-    MaybeLocal<Object> maybe_instance = constructor->GetFunction()->NewInstance(
-        argc, argv);
+    MaybeLocal<Object> maybe_instance =
+        constructor->GetFunction()->NewInstance(argc, argv);
     if (maybe_instance.IsEmpty()) {
       // There's probably a pending exception
       return;
@@ -185,8 +183,9 @@
   grpc_channel_args *channel_args;
   if (!ParseChannelArgs(info[0], &channel_args)) {
     DeallocateChannelArgs(channel_args);
-    return Nan::ThrowTypeError("Server options must be an object with "
-                               "string keys and integer or string values");
+    return Nan::ThrowTypeError(
+        "Server options must be an object with "
+        "string keys and integer or string values");
   }
   wrapped_server = grpc_server_create(channel_args, NULL);
   DeallocateChannelArgs(channel_args);
@@ -218,8 +217,7 @@
 
 NAN_METHOD(Server::AddHttp2Port) {
   if (!HasInstance(info.This())) {
-    return Nan::ThrowTypeError(
-        "addHttp2Port can only be called on a Server");
+    return Nan::ThrowTypeError("addHttp2Port can only be called on a Server");
   }
   if (!info[0]->IsString()) {
     return Nan::ThrowTypeError(
@@ -239,8 +237,7 @@
                                                *Utf8String(info[0]));
   } else {
     port = grpc_server_add_secure_http2_port(server->wrapped_server,
-                                             *Utf8String(info[0]),
-                                             creds);
+                                             *Utf8String(info[0]), creds);
   }
   info.GetReturnValue().Set(Nan::New<Number>(port));
 }
@@ -262,8 +259,7 @@
   Server *server = ObjectWrap::Unwrap<Server>(info.This());
   unique_ptr<OpVec> ops(new OpVec());
   grpc_server_shutdown_and_notify(
-      server->wrapped_server,
-      CompletionQueueAsyncWorker::GetQueue(),
+      server->wrapped_server, CompletionQueueAsyncWorker::GetQueue(),
       new struct tag(new Nan::Callback(info[0].As<Function>()), ops.release(),
                      shared_ptr<Resources>(nullptr)));
   CompletionQueueAsyncWorker::Next();
diff --git a/src/node/test/math/math_grpc_pb.js b/src/node/test/math/math_grpc_pb.js
index 083ed66..17a4bf7 100644
--- a/src/node/test/math/math_grpc_pb.js
+++ b/src/node/test/math/math_grpc_pb.js
@@ -1,94 +1,135 @@
 // GENERATED CODE -- DO NOT EDIT!
 
+// Original file comments:
+// 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.
+//
 'use strict';
 var grpc = require('grpc');
-var math_pb = require('./math_pb.js');
+var math_math_pb = require('../math/math_pb.js');
 
 function serialize_DivArgs(arg) {
-  if (!(arg instanceof math_pb.DivArgs)) {
+  if (!(arg instanceof math_math_pb.DivArgs)) {
     throw new Error('Expected argument of type DivArgs');
   }
   return new Buffer(arg.serializeBinary());
 }
 
 function deserialize_DivArgs(buffer_arg) {
-  return math_pb.DivArgs.deserializeBinary(new Uint8Array(buffer_arg));
+  return math_math_pb.DivArgs.deserializeBinary(new Uint8Array(buffer_arg));
 }
 
 function serialize_DivReply(arg) {
-  if (!(arg instanceof math_pb.DivReply)) {
+  if (!(arg instanceof math_math_pb.DivReply)) {
     throw new Error('Expected argument of type DivReply');
   }
   return new Buffer(arg.serializeBinary());
 }
 
 function deserialize_DivReply(buffer_arg) {
-  return math_pb.DivReply.deserializeBinary(new Uint8Array(buffer_arg));
+  return math_math_pb.DivReply.deserializeBinary(new Uint8Array(buffer_arg));
 }
 
 function serialize_FibArgs(arg) {
-  if (!(arg instanceof math_pb.FibArgs)) {
+  if (!(arg instanceof math_math_pb.FibArgs)) {
     throw new Error('Expected argument of type FibArgs');
   }
   return new Buffer(arg.serializeBinary());
 }
 
 function deserialize_FibArgs(buffer_arg) {
-  return math_pb.FibArgs.deserializeBinary(new Uint8Array(buffer_arg));
+  return math_math_pb.FibArgs.deserializeBinary(new Uint8Array(buffer_arg));
 }
 
 function serialize_Num(arg) {
-  if (!(arg instanceof math_pb.Num)) {
+  if (!(arg instanceof math_math_pb.Num)) {
     throw new Error('Expected argument of type Num');
   }
   return new Buffer(arg.serializeBinary());
 }
 
 function deserialize_Num(buffer_arg) {
-  return math_pb.Num.deserializeBinary(new Uint8Array(buffer_arg));
+  return math_math_pb.Num.deserializeBinary(new Uint8Array(buffer_arg));
 }
 
 
 var MathService = exports.MathService = {
+  // Div divides args.dividend by args.divisor and returns the quotient and
+  // remainder.
   div: {
     path: '/math.Math/Div',
     requestStream: false,
     responseStream: false,
-    requestType: math_pb.DivArgs,
-    responseType: math_pb.DivReply,
+    requestType: math_math_pb.DivArgs,
+    responseType: math_math_pb.DivReply,
     requestSerialize: serialize_DivArgs,
     requestDeserialize: deserialize_DivArgs,
     responseSerialize: serialize_DivReply,
     responseDeserialize: deserialize_DivReply,
   },
+  // DivMany accepts an arbitrary number of division args from the client stream
+  // and sends back the results in the reply stream.  The stream continues until
+  // the client closes its end; the server does the same after sending all the
+  // replies.  The stream ends immediately if either end aborts.
   divMany: {
     path: '/math.Math/DivMany',
     requestStream: true,
     responseStream: true,
-    requestType: math_pb.DivArgs,
-    responseType: math_pb.DivReply,
+    requestType: math_math_pb.DivArgs,
+    responseType: math_math_pb.DivReply,
     requestSerialize: serialize_DivArgs,
     requestDeserialize: deserialize_DivArgs,
     responseSerialize: serialize_DivReply,
     responseDeserialize: deserialize_DivReply,
   },
+  // Fib generates numbers in the Fibonacci sequence.  If args.limit > 0, Fib
+  // generates up to limit numbers; otherwise it continues until the call is
+  // canceled.  Unlike Fib above, Fib has no final FibReply.
   fib: {
     path: '/math.Math/Fib',
     requestStream: false,
     responseStream: true,
-    requestType: math_pb.FibArgs,
-    responseType: math_pb.Num,
+    requestType: math_math_pb.FibArgs,
+    responseType: math_math_pb.Num,
     requestSerialize: serialize_FibArgs,
     requestDeserialize: deserialize_FibArgs,
     responseSerialize: serialize_Num,
     responseDeserialize: deserialize_Num,
   },
+  // Sum sums a stream of numbers, returning the final result once the stream
+  // is closed.
   sum: {
     path: '/math.Math/Sum',
     requestStream: true,
     responseStream: false,
-    requestType: math_pb.Num,
-    responseType: math_pb.Num,
+    requestType: math_math_pb.Num,
+    responseType: math_math_pb.Num,
     requestSerialize: serialize_Num,
     requestDeserialize: deserialize_Num,
     responseSerialize: serialize_Num,
diff --git a/src/node/test/math/math_pb.js b/src/node/test/math/math_pb.js
index 3489143..ccc05c6 100644
--- a/src/node/test/math/math_pb.js
+++ b/src/node/test/math/math_pb.js
@@ -65,7 +65,7 @@
   };
 
   if (includeInstance) {
-    obj.$jspbMessageInstance = msg
+    obj.$jspbMessageInstance = msg;
   }
   return obj;
 };
@@ -251,7 +251,7 @@
   };
 
   if (includeInstance) {
-    obj.$jspbMessageInstance = msg
+    obj.$jspbMessageInstance = msg;
   }
   return obj;
 };
@@ -436,7 +436,7 @@
   };
 
   if (includeInstance) {
-    obj.$jspbMessageInstance = msg
+    obj.$jspbMessageInstance = msg;
   }
   return obj;
 };
@@ -595,7 +595,7 @@
   };
 
   if (includeInstance) {
-    obj.$jspbMessageInstance = msg
+    obj.$jspbMessageInstance = msg;
   }
   return obj;
 };
@@ -754,7 +754,7 @@
   };
 
   if (includeInstance) {
-    obj.$jspbMessageInstance = msg
+    obj.$jspbMessageInstance = msg;
   }
   return obj;
 };
diff --git a/src/python/grpcio/grpc/_adapter/_implementations.py b/src/objective-c/CronetFramework.podspec
similarity index 70%
copy from src/python/grpcio/grpc/_adapter/_implementations.py
copy to src/objective-c/CronetFramework.podspec
index b85f228..20af764 100644
--- a/src/python/grpcio/grpc/_adapter/_implementations.py
+++ b/src/objective-c/CronetFramework.podspec
@@ -1,4 +1,4 @@
-# Copyright 2015, Google Inc.
+# Copyright 2016, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
@@ -27,22 +27,17 @@
 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-import collections
 
-from grpc.beta import interfaces
-
-class AuthMetadataContext(collections.namedtuple(
-    'AuthMetadataContext', [
-        'service_url',
-        'method_name'
-    ]), interfaces.GRPCAuthMetadataContext):
-  pass
-
-
-class AuthMetadataPluginCallback(interfaces.GRPCAuthMetadataContext):
-
-  def __init__(self, callback):
-    self._callback = callback
-
-  def __call__(self, metadata, error):
-    self._callback(metadata, error)
+Pod::Spec.new do |s|
+  s.name         = "CronetFramework"
+  s.version      = "0.0.2"
+  s.summary      = "Cronet, precompiled and used as a framework."
+  s.homepage     = "http://chromium.org"
+  s.license      = { :type => 'BSD' }
+  s.vendored_framework = "Cronet.framework"
+  s.author             = "The Chromium Authors"
+  s.ios.deployment_target = "8.0"
+  s.source       = { :http => 'https://storage.googleapis.com/grpc-precompiled-binaries/cronet/Cronet.framework.zip' }
+  s.preserve_paths = "Cronet.framework"
+  s.public_header_files = "Cronet.framework/Headers/**/*{.h}"
+end
diff --git a/include/grpc/support/log_win32.h b/src/objective-c/GRPCClient/GRPCCall+Cronet.h
similarity index 70%
copy from include/grpc/support/log_win32.h
copy to src/objective-c/GRPCClient/GRPCCall+Cronet.h
index e5c25e0..2d8f7ac 100644
--- a/include/grpc/support/log_win32.h
+++ b/src/objective-c/GRPCClient/GRPCCall+Cronet.h
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -30,22 +30,28 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  */
+#ifdef GRPC_COMPILE_WITH_CRONET
+#import <Cronet/Cronet.h>
 
-#ifndef GRPC_SUPPORT_LOG_WIN32_H
-#define GRPC_SUPPORT_LOG_WIN32_H
+#import "GRPCCall.h"
 
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Returns a string allocated with gpr_malloc that contains a UTF-8
- * formatted error message, corresponding to the error messageid.
- * Use in conjunction with GetLastError() et al.
+/**
+ * Methods for using cronet transport.
  */
-GPRAPI char *gpr_format_message(int messageid);
+@interface GRPCCall (Cronet)
 
-#ifdef __cplusplus
-}
+/**
+ * This method should be called before issuing the first RPC. It should be
+ * called only once. Create an instance of Cronet engine in your app elsewhere
+ * and pass the instance pointer in the cronet_engine parameter. Once set,
+ * all subsequent RPCs will use Cronet transport. The method is not thread
+ * safe.
+ */
++(void)useCronetWithEngine:(cronet_engine *)engine;
+
++(cronet_engine *)cronetEngine;
+
++(BOOL)isUsingCronet;
+
+@end
 #endif
-
-#endif /* GRPC_SUPPORT_LOG_WIN32_H */
diff --git a/include/grpc/support/log_win32.h b/src/objective-c/GRPCClient/GRPCCall+Cronet.m
similarity index 77%
copy from include/grpc/support/log_win32.h
copy to src/objective-c/GRPCClient/GRPCCall+Cronet.m
index e5c25e0..76ca1a2 100644
--- a/include/grpc/support/log_win32.h
+++ b/src/objective-c/GRPCClient/GRPCCall+Cronet.m
@@ -1,6 +1,6 @@
 /*
  *
- * Copyright 2015, Google Inc.
+ * Copyright 2016, Google Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -31,21 +31,26 @@
  *
  */
 
-#ifndef GRPC_SUPPORT_LOG_WIN32_H
-#define GRPC_SUPPORT_LOG_WIN32_H
+#import "GRPCCall+Cronet.h"
 
-#ifdef __cplusplus
-extern "C" {
-#endif
+#ifdef GRPC_COMPILE_WITH_CRONET
+static BOOL useCronet = NO;
+static cronet_engine *globalCronetEngine;
 
-/* Returns a string allocated with gpr_malloc that contains a UTF-8
- * formatted error message, corresponding to the error messageid.
- * Use in conjunction with GetLastError() et al.
- */
-GPRAPI char *gpr_format_message(int messageid);
+@implementation GRPCCall (Cronet)
 
-#ifdef __cplusplus
++ (void)useCronetWithEngine:(cronet_engine *)engine {
+  useCronet = YES;
+  globalCronetEngine = engine;
 }
-#endif
 
-#endif /* GRPC_SUPPORT_LOG_WIN32_H */
++ (cronet_engine *)cronetEngine {
+  return globalCronetEngine;
+}
+
++ (BOOL)isUsingCronet {
+  return useCronet;
+}
+
+@end
+#endif
diff --git a/src/objective-c/GRPCClient/GRPCCall.h b/src/objective-c/GRPCClient/GRPCCall.h
index 7a77ae6..b9e741d 100644
--- a/src/objective-c/GRPCClient/GRPCCall.h
+++ b/src/objective-c/GRPCClient/GRPCCall.h
@@ -220,6 +220,8 @@
  * messages to the response side of the call indefinitely (depending on the semantics of the
  * specific remote method called).
  * To finish a call right away, invoke cancel.
+ * host parameter should not contain the scheme (http:// or https://), only the name or IP addr
+ * and the port number, for example @"localhost:5050".
  */
 - (instancetype)initWithHost:(NSString *)host
                         path:(NSString *)path
diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.h b/src/objective-c/GRPCClient/private/GRPCChannel.h
index 70d1a9b..40e78a9 100644
--- a/src/objective-c/GRPCClient/private/GRPCChannel.h
+++ b/src/objective-c/GRPCClient/private/GRPCChannel.h
@@ -56,6 +56,13 @@
 + (nullable GRPCChannel *)secureChannelWithHost:(nonnull NSString *)host;
 
 /**
+ * Creates a secure channel to the specified @c host using Cronet as a transport mechanism.
+ */
+#ifdef GRPC_COMPILE_WITH_CRONET
++ (nullable GRPCChannel *)secureCronetChannelWithHost:(NSString *)host
+                                          channelArgs:(NSDictionary *)channelArgs;
+#endif
+/**
  * Creates a secure channel to the specified @c host using the specified @c credentials and
  * @c channelArgs. Only in tests should @c GRPC_SSL_TARGET_NAME_OVERRIDE_ARG channel arg be set.
  */
diff --git a/src/objective-c/GRPCClient/private/GRPCChannel.m b/src/objective-c/GRPCClient/private/GRPCChannel.m
index 203ef58..d3192c9 100644
--- a/src/objective-c/GRPCClient/private/GRPCChannel.m
+++ b/src/objective-c/GRPCClient/private/GRPCChannel.m
@@ -34,10 +34,17 @@
 #import "GRPCChannel.h"
 
 #include <grpc/grpc_security.h>
+#ifdef GRPC_COMPILE_WITH_CRONET
+#include <grpc/grpc_cronet.h>
+#endif
 #include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
 #include <grpc/support/string_util.h>
 
+#ifdef GRPC_COMPILE_WITH_CRONET
+#import <Cronet/Cronet.h>
+#import <GRPCClient/GRPCCall+Cronet.h>
+#endif
 #import "GRPCCompletionQueue.h"
 
 void freeChannelArgs(grpc_channel_args *channel_args) {
@@ -99,6 +106,24 @@
   grpc_channel_args *_channelArgs;
 }
 
+#ifdef GRPC_COMPILE_WITH_CRONET
+- (instancetype)initWithHost:(NSString *)host
+                cronetEngine:(cronet_engine *)cronetEngine
+                 channelArgs:(NSDictionary *)channelArgs {
+  if (!host) {
+    [NSException raise:NSInvalidArgumentException format:@"host argument missing"];
+  }
+
+  if (self = [super init]) {
+    _channelArgs = buildChannelArgs(channelArgs);
+    _host = [host copy];
+    _unmanagedChannel = grpc_cronet_secure_channel_create(cronetEngine, _host.UTF8String, _channelArgs,
+                                                     NULL);
+  }
+
+  return self;
+}
+#endif
 
 - (instancetype)initWithHost:(NSString *)host
                       secure:(BOOL)secure
@@ -133,6 +158,19 @@
   freeChannelArgs(_channelArgs);
 }
 
+#ifdef GRPC_COMPILE_WITH_CRONET
++ (GRPCChannel *)secureCronetChannelWithHost:(NSString *)host
+                                 channelArgs:(NSDictionary *)channelArgs {
+  cronet_engine *engine = [GRPCCall cronetEngine];
+  if (!engine) {
+    [NSException raise:NSInvalidArgumentException
+                format:@"cronet_engine is NULL. Set it first."];
+    return nil;
+  }
+  return [[GRPCChannel alloc] initWithHost:host cronetEngine:engine channelArgs:channelArgs];
+}
+#endif
+
 + (GRPCChannel *)secureChannelWithHost:(NSString *)host {
   return [[GRPCChannel alloc] initWithHost:host secure:YES credentials:NULL channelArgs:NULL];
 }
diff --git a/src/objective-c/GRPCClient/private/GRPCHost.m b/src/objective-c/GRPCClient/private/GRPCHost.m
index 43166cb..fef6385 100644
--- a/src/objective-c/GRPCClient/private/GRPCHost.m
+++ b/src/objective-c/GRPCClient/private/GRPCHost.m
@@ -36,7 +36,10 @@
 #include <grpc/grpc.h>
 #include <grpc/grpc_security.h>
 #import <GRPCClient/GRPCCall.h>
+#ifdef GRPC_COMPILE_WITH_CRONET
 #import <GRPCClient/GRPCCall+ChannelArg.h>
+#import <GRPCClient/GRPCCall+Cronet.h>
+#endif
 
 #import "GRPCChannel.h"
 #import "GRPCCompletionQueue.h"
@@ -200,15 +203,26 @@
 
 - (GRPCChannel *)newChannel {
   NSDictionary *args = [self channelArgs];
+#ifdef GRPC_COMPILE_WITH_CRONET
+  BOOL useCronet = [GRPCCall isUsingCronet];
+#endif
   if (_secure) {
       GRPCChannel *channel;
       @synchronized(self) {
         if (_channelCreds == nil) {
           [self setTLSPEMRootCerts:nil withPrivateKey:nil withCertChain:nil error:nil];
         }
-        channel = [GRPCChannel secureChannelWithHost:_address
-                                          credentials:_channelCreds
-                                          channelArgs:args];
+#ifdef GRPC_COMPILE_WITH_CRONET
+        if (useCronet) {
+          channel = [GRPCChannel secureCronetChannelWithHost:_address
+                                                 channelArgs:args];
+        } else
+#endif
+        {
+          channel = [GRPCChannel secureChannelWithHost:_address
+                                            credentials:_channelCreds
+                                            channelArgs:args];
+        }
       }
       return channel;
   } else {
diff --git a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m
index 16e5bff..a3fa593 100644
--- a/src/objective-c/GRPCClient/private/GRPCWrappedCall.m
+++ b/src/objective-c/GRPCClient/private/GRPCWrappedCall.m
@@ -72,6 +72,8 @@
     _op.op = GRPC_OP_SEND_INITIAL_METADATA;
     _op.data.send_initial_metadata.count = metadata.count;
     _op.data.send_initial_metadata.metadata = metadata.grpc_metadataArray;
+    _op.data.send_initial_metadata.maybe_compression_level.is_set = false;
+    _op.data.send_initial_metadata.maybe_compression_level.level = 0;
     _handler = handler;
   }
   return self;
diff --git a/src/objective-c/ProtoRPC/ProtoMethod.h b/src/objective-c/ProtoRPC/ProtoMethod.h
index a0ed2cf..f9fdbb3 100644
--- a/src/objective-c/ProtoRPC/ProtoMethod.h
+++ b/src/objective-c/ProtoRPC/ProtoMethod.h
@@ -37,6 +37,7 @@
  * A fully-qualified proto service method name. Full qualification is needed because a gRPC endpoint
  * can implement multiple services.
  */
+__attribute__((deprecated("Please use GRPCProtoMethod.")))
 @interface ProtoMethod : NSObject
 @property(nonatomic, readonly) NSString *package;
 @property(nonatomic, readonly) NSString *service;
@@ -48,3 +49,11 @@
                         service:(NSString *)service
                          method:(NSString *)method;
 @end
+
+/**
+ * This subclass is empty now. Eventually we'll remove ProtoMethod class
+ * to avoid potential naming conflict
+ */
+@interface GRPCProtoMethod : ProtoMethod
+
+@end
diff --git a/src/objective-c/ProtoRPC/ProtoMethod.m b/src/objective-c/ProtoRPC/ProtoMethod.m
index 4b7ed63..e9978f3 100644
--- a/src/objective-c/ProtoRPC/ProtoMethod.m
+++ b/src/objective-c/ProtoRPC/ProtoMethod.m
@@ -53,3 +53,7 @@
   }
 }
 @end
+
+@implementation GRPCProtoMethod
+
+@end
diff --git a/src/objective-c/ProtoRPC/ProtoRPC.h b/src/objective-c/ProtoRPC/ProtoRPC.h
index bd926b7..5f91f6b 100644
--- a/src/objective-c/ProtoRPC/ProtoRPC.h
+++ b/src/objective-c/ProtoRPC/ProtoRPC.h
@@ -36,13 +36,26 @@
 
 #import "ProtoMethod.h"
 
+__attribute__((deprecated("Please use GRPCProtoCall.")))
 @interface ProtoRPC : GRPCCall
 
+/**
+ * host parameter should not contain the scheme (http:// or https://), only the name or IP addr
+ * and the port number, for example @"localhost:5050".
+ */
 - (instancetype)initWithHost:(NSString *)host
-                      method:(ProtoMethod *)method
+                      method:(GRPCProtoMethod *)method
               requestsWriter:(GRXWriter *)requestsWriter
                responseClass:(Class)responseClass
           responsesWriteable:(id<GRXWriteable>)responsesWriteable NS_DESIGNATED_INITIALIZER;
 
 - (void)start;
 @end
+
+/**
+ * This subclass is empty now. Eventually we'll remove ProtoRPC class
+ * to avoid potential naming conflict
+ */
+@interface GRPCProtoCall : ProtoRPC
+
+@end
diff --git a/src/objective-c/ProtoRPC/ProtoRPC.m b/src/objective-c/ProtoRPC/ProtoRPC.m
index 9bf66f3..fb0b566 100644
--- a/src/objective-c/ProtoRPC/ProtoRPC.m
+++ b/src/objective-c/ProtoRPC/ProtoRPC.m
@@ -70,7 +70,7 @@
 
 // Designated initializer
 - (instancetype)initWithHost:(NSString *)host
-                      method:(ProtoMethod *)method
+                      method:(GRPCProtoMethod *)method
               requestsWriter:(GRXWriter *)requestsWriter
                responseClass:(Class)responseClass
           responsesWriteable:(id<GRXWriteable>)responsesWriteable {
@@ -117,3 +117,7 @@
   _responseWriteable = nil;
 }
 @end
+
+@implementation GRPCProtoCall
+
+@end
diff --git a/src/objective-c/ProtoRPC/ProtoService.h b/src/objective-c/ProtoRPC/ProtoService.h
index 2e8cb33..87d06e1 100644
--- a/src/objective-c/ProtoRPC/ProtoService.h
+++ b/src/objective-c/ProtoRPC/ProtoService.h
@@ -33,17 +33,28 @@
 
 #import <Foundation/Foundation.h>
 
-@class ProtoRPC;
+@class GRPCProtoCall;
 @protocol GRXWriteable;
 @class GRXWriter;
 
+
+__attribute__((deprecated("Please use GRPCProtoService.")))
 @interface ProtoService : NSObject
 - (instancetype)initWithHost:(NSString *)host
                  packageName:(NSString *)packageName
                  serviceName:(NSString *)serviceName NS_DESIGNATED_INITIALIZER;
 
-- (ProtoRPC *)RPCToMethod:(NSString *)method
+- (GRPCProtoCall *)RPCToMethod:(NSString *)method
            requestsWriter:(GRXWriter *)requestsWriter
   	        responseClass:(Class)responseClass
   	   responsesWriteable:(id<GRXWriteable>)responsesWriteable;
 @end
+
+
+/**
+ * This subclass is empty now. Eventually we'll remove ProtoService class
+ * to avoid potential naming conflict
+ */
+@interface GRPCProtoService : ProtoService
+
+@end
diff --git a/src/objective-c/ProtoRPC/ProtoService.m b/src/objective-c/ProtoRPC/ProtoService.m
index fccc6aa..597c3cf 100644
--- a/src/objective-c/ProtoRPC/ProtoService.m
+++ b/src/objective-c/ProtoRPC/ProtoService.m
@@ -79,3 +79,7 @@
                      responsesWriteable:responsesWriteable];
 }
 @end
+
+@implementation GRPCProtoService
+
+@end
diff --git a/src/objective-c/tests/InteropTests.m b/src/objective-c/tests/InteropTests.m
index 4f096b9..781c500 100644
--- a/src/objective-c/tests/InteropTests.m
+++ b/src/objective-c/tests/InteropTests.m
@@ -35,7 +35,9 @@
 
 #include <grpc/status.h>
 
+#import <Cronet/Cronet.h>
 #import <GRPCClient/GRPCCall+Tests.h>
+#import <GRPCClient/GRPCCall+Cronet.h>
 #import <ProtoRPC/ProtoRPC.h>
 #import <RemoteTest/Empty.pbobjc.h>
 #import <RemoteTest/Messages.pbobjc.h>
@@ -78,6 +80,8 @@
 
 #pragma mark Tests
 
+static cronet_engine *cronetEngine = NULL;
+
 @implementation InteropTests {
   RMTTestService *_service;
 }
@@ -88,6 +92,15 @@
 
 - (void)setUp {
   _service = self.class.host ? [RMTTestService serviceWithHost:self.class.host] : nil;
+#ifdef GRPC_COMPILE_WITH_CRONET
+  if (cronetEngine == NULL) {
+    // Cronet setup
+    [Cronet setHttp2Enabled:YES];
+    [Cronet start];
+    cronetEngine = [Cronet getGlobalEngine];
+    [GRPCCall useCronetWithEngine:cronetEngine];
+  }
+#endif
 }
 
 - (void)testEmptyUnaryRPC {
@@ -245,6 +258,8 @@
   [self waitForExpectationsWithTimeout:4 handler:nil];
 }
 
+#ifndef GRPC_COMPILE_WITH_CRONET
+// TODO(makdharma@): Fix this test
 - (void)testEmptyStreamRPC {
   XCTAssertNotNil(self.class.host);
   __weak XCTestExpectation *expectation = [self expectationWithDescription:@"EmptyStream"];
@@ -258,6 +273,7 @@
   }];
   [self waitForExpectationsWithTimeout:2 handler:nil];
 }
+#endif
 
 - (void)testCancelAfterBeginRPC {
   XCTAssertNotNil(self.class.host);
diff --git a/src/objective-c/tests/Podfile b/src/objective-c/tests/Podfile
index 7ec7a25..508641d 100644
--- a/src/objective-c/tests/Podfile
+++ b/src/objective-c/tests/Podfile
@@ -3,6 +3,7 @@
 
 pod 'Protobuf', :path => "../../../third_party/protobuf"
 pod 'BoringSSL', :podspec => ".."
+pod 'CronetFramework', :podspec => ".."
 pod 'gRPC', :path => "../../.."
 pod 'RemoteTest', :path => "RemoteTestClient"
 
diff --git a/src/php/ext/grpc/call.c b/src/php/ext/grpc/call.c
index 884130e..0ec5022 100644
--- a/src/php/ext/grpc/call.c
+++ b/src/php/ext/grpc/call.c
@@ -292,6 +292,7 @@
   grpc_metadata_array_init(&recv_trailing_metadata);
   MAKE_STD_ZVAL(result);
   object_init(result);
+  memset(ops, 0, sizeof(ops));
   /* "a" == 1 array */
   if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &array) ==
       FAILURE) {
diff --git a/src/php/ext/grpc/php_grpc.c b/src/php/ext/grpc/php_grpc.c
index 762c013..f4cb5b2 100644
--- a/src/php/ext/grpc/php_grpc.c
+++ b/src/php/ext/grpc/php_grpc.c
@@ -227,7 +227,7 @@
                          GRPC_CHANNEL_TRANSIENT_FAILURE,
                          CONST_CS | CONST_PERSISTENT);
   REGISTER_LONG_CONSTANT("Grpc\\CHANNEL_FATAL_FAILURE",
-                         GRPC_CHANNEL_FATAL_FAILURE,
+                         GRPC_CHANNEL_SHUTDOWN,
                          CONST_CS | CONST_PERSISTENT);
 
   grpc_init_call(TSRMLS_C);
diff --git a/src/php/lib/Grpc/BaseStub.php b/src/php/lib/Grpc/BaseStub.php
index 2de1b33..70644fa 100755
--- a/src/php/lib/Grpc/BaseStub.php
+++ b/src/php/lib/Grpc/BaseStub.php
@@ -52,8 +52,9 @@
      *  - 'update_metadata': (optional) a callback function which takes in a
      * metadata array, and returns an updated metadata array
      *  - 'grpc.primary_user_agent': (optional) a user-agent string
+     * @param $channel Channel An already created Channel object
      */
-    public function __construct($hostname, $opts)
+    public function __construct($hostname, $opts, $channel = null)
     {
         $this->hostname = $hostname;
         $this->update_metadata = null;
@@ -77,7 +78,15 @@
                                  'required. Please see one of the '.
                                  'ChannelCredentials::create methods');
         }
-        $this->channel = new Channel($hostname, $opts);
+        if ($channel) {
+            if (!is_a($channel, 'Channel')) {
+                throw new \Exception("The channel argument is not a".
+                                     "Channel object");
+            }
+            $this->channel = $channel;
+        } else {
+            $this->channel = new Channel($hostname, $opts);
+        }
     }
 
     /**
diff --git a/src/php/tests/interop/interop_client.php b/src/php/tests/interop/interop_client.php
index 565bfce..c5bb7c4 100755
--- a/src/php/tests/interop/interop_client.php
+++ b/src/php/tests/interop/interop_client.php
@@ -477,7 +477,8 @@
     return $stub;
 }
 
-function interop_main($args, $stub = false) {
+function interop_main($args, $stub = false)
+{
     if (!$stub) {
         $stub = _makeStub($args);
     }
diff --git a/src/php/tests/interop/metrics_client.php b/src/php/tests/interop/metrics_client.php
index 46f4212..19510dc 100644
--- a/src/php/tests/interop/metrics_client.php
+++ b/src/php/tests/interop/metrics_client.php
@@ -39,11 +39,11 @@
 
 $socket = socket_create(AF_INET, SOCK_STREAM, 0);
 if (@!socket_connect($socket, $server_host, $server_port)) {
-  echo "Cannot connect to merics server...\n";
-  exit(1);
+    echo "Cannot connect to merics server...\n";
+    exit(1);
 }
 socket_write($socket, 'qps');
 while ($out = socket_read($socket, 1024)) {
-  echo "$out\n";
+    echo "$out\n";
 }
 socket_close($socket);
diff --git a/src/php/tests/interop/stress_client.php b/src/php/tests/interop/stress_client.php
index 2339f0d..419ef5b 100644
--- a/src/php/tests/interop/stress_client.php
+++ b/src/php/tests/interop/stress_client.php
@@ -32,50 +32,52 @@
  *
  */
 
-include_once('interop_client.php');
+include_once 'interop_client.php';
 
-function stress_main($args) {
-  mt_srand();
-  set_time_limit(0);
+function stress_main($args)
+{
+    mt_srand();
+    set_time_limit(0);
 
-  // open socket to listen as metrics server
-  $socket = socket_create(AF_INET, SOCK_STREAM, 0);
-  socket_set_option($socket, SOL_SOCKET, SO_REUSEADDR, 1);
-  if (@!socket_bind($socket, 'localhost', $args['metrics_port'])) {
-    echo "Cannot create socket for metrics server...\n";
-    exit(1);
-  }
-  socket_listen($socket);
-  socket_set_nonblock($socket);
-
-  $start_time = microtime(true);
-  $count = 0;
-  $deadline = $args['test_duration_secs'] ?
-              ($start_time + $args['test_duration_secs']) : false;
-  $num_test_cases = count($args['test_cases']);
-  $stub = false;
-
-  while (true) {
-    $current_time = microtime(true);
-    if ($deadline && $current_time > $deadline) {
-      break;
+    // open socket to listen as metrics server
+    $socket = socket_create(AF_INET, SOCK_STREAM, 0);
+    socket_set_option($socket, SOL_SOCKET, SO_REUSEADDR, 1);
+    if (@!socket_bind($socket, 'localhost', $args['metrics_port'])) {
+        echo "Cannot create socket for metrics server...\n";
+        exit(1);
     }
-    if ($client_connection = socket_accept($socket)) {
-      // there is an incoming request, respond with qps metrics
-      $input = socket_read($client_connection, 1024);
-      $qps = round($count / ($current_time - $start_time));
-      socket_write($client_connection, "qps: $qps");
-      socket_close($client_connection);
-    } else {
-      // do actual work, run one interop test case
-      $args['test_case'] =
-          $args['test_cases'][mt_rand(0, $num_test_cases - 1)];
-      $stub = @interop_main($args, $stub);
-      $count++;
+    socket_listen($socket);
+    socket_set_nonblock($socket);
+
+    $start_time = microtime(true);
+    $count = 0;
+    $deadline = $args['test_duration_secs'] ?
+                ($start_time + $args['test_duration_secs']) : false;
+    $num_test_cases = count($args['test_cases']);
+    $stub = false;
+
+    while (true) {
+        $current_time = microtime(true);
+        if ($deadline && $current_time > $deadline) {
+            break;
+        }
+        if ($client_connection = socket_accept($socket)) {
+            // there is an incoming request, respond with qps metrics
+            $input = socket_read($client_connection, 1024);
+            $qps = round($count / ($current_time - $start_time));
+            socket_write($client_connection, "qps: $qps");
+            socket_close($client_connection);
+        } else {
+            // do actual work, run one interop test case
+            $args['test_case'] =
+                $args['test_cases'][mt_rand(0, $num_test_cases - 1)];
+            $stub = @interop_main($args, $stub);
+            ++$count;
+        }
     }
-  }
-  socket_close($socket);
-  echo "Number of interop tests run in $args[test_duration_secs] seconds: $count.\n";
+    socket_close($socket);
+    echo "Number of interop tests run in $args[test_duration_secs] ".
+        "seconds: $count.\n";
 }
 
 // process command line arguments
@@ -85,31 +87,32 @@
    'metrics_port::',
    'test_duration_secs::',
    'num_channels_per_server::',
-   'num_stubs_per_channel::']);
+   'num_stubs_per_channel::',
+  ]);
 
 $args = [];
 
 if (empty($raw_args['server_addresses'])) {
-  $args['server_host'] = 'localhost';
-  $args['server_port'] = '8080';
+    $args['server_host'] = 'localhost';
+    $args['server_port'] = '8080';
 } else {
-  $parts = explode(':', $raw_args['server_addresses']);
-  $args['server_host'] = $parts[0];
-  $args['server_port'] = (count($parts) == 2) ? $parts[1] : '';
+    $parts = explode(':', $raw_args['server_addresses']);
+    $args['server_host'] = $parts[0];
+    $args['server_port'] = (count($parts) == 2) ? $parts[1] : '';
 }
 
 $args['metrics_port'] = empty($raw_args['metrics_port']) ?
-  '8081' : $args['metrics_port'];
+    '8081' : $args['metrics_port'];
 
 $args['test_duration_secs'] = empty($raw_args['test_duration_secs']) ||
-  $raw_args['test_duration_secs'] == -1 ?
-  false : $raw_args['test_duration_secs'];
+    $raw_args['test_duration_secs'] == -1 ?
+    false : $raw_args['test_duration_secs'];
 
 $test_cases = [];
 $test_case_strs = explode(',', $raw_args['test_cases']);
 foreach ($test_case_strs as $test_case_str) {
-  $parts = explode(':', $test_case_str);
-  $test_cases = array_merge($test_cases, array_fill(0, $parts[1], $parts[0]));
+    $parts = explode(':', $test_case_str);
+    $test_cases = array_merge($test_cases, array_fill(0, $parts[1], $parts[0]));
 }
 $args['test_cases'] = $test_cases;
 
diff --git a/src/proto/census/census.options b/src/proto/census/census.options
new file mode 100644
index 0000000..a1f8039
--- /dev/null
+++ b/src/proto/census/census.options
@@ -0,0 +1,3 @@
+google.census.Tag.key max_size:255
+google.census.Tag.value max_size:255
+google.census.View.tag_key max_count:15
diff --git a/src/proto/census/census.proto b/src/proto/census/census.proto
new file mode 100644
index 0000000..c869d85
--- /dev/null
+++ b/src/proto/census/census.proto
@@ -0,0 +1,313 @@
+// 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.
+
+syntax = "proto3";
+
+package google.census;
+
+// All the census protos.
+//
+// Nomenclature note: capitalized names below (like Metric) are protos.
+//
+// Census lets you define a Metric - something which can be measured, like the
+// latency of an RPC, the number of CPU cycles spent on an operation, or
+// anything else you care to measure. You can record individual instances of
+// measurements (a double value) for every metric of interest. These
+// individual measurements are aggregated together into an Aggregation. There
+// are two Aggregation types available: Distribution (describes the
+// distribution of all measurements, possibly with a histogram) and
+// IntervalStats (the count and mean of measurements across specified time
+// periods). An Aggregation is described by an AggregationDescriptor.
+//
+// You can define how your stats are broken down by Tag values and which
+// Aggregations to use through a View. The corresponding combination of
+// Metric/View/Aggregation which is available to census clients is called a
+// ViewAggregation.
+
+
+// The following two types are copied from
+// google/protobuf/{duration,timestamp}.proto. Ideally, we would be able to
+// import them, but this causes compilation issues on C-based systems
+// (e.g. https://koti.kapsi.fi/jpa/nanopb/), which cannot process the C++
+// headers generated from the standard protobuf distribution. See the relevant
+// proto files for full documentation of these types.
+
+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;
+
+  // Signed fractions of a second at nanosecond resolution of the span
+  // of time. Durations less than one second are represented with a 0
+  // `seconds` field and a positive or negative `nanos` field. For durations
+  // of one second or more, a non-zero value for the `nanos` field must be
+  // of the same sign as the `seconds` field. Must be from -999,999,999
+  // to +999,999,999 inclusive.
+  int32 nanos = 2;
+}
+
+message Timestamp {
+  // Represents seconds of UTC time since Unix epoch
+  // 1970-01-01T00:00:00Z. Must be from from 0001-01-01T00:00:00Z to
+  // 9999-12-31T23:59:59Z inclusive.
+  int64 seconds = 1;
+
+  // Non-negative fractions of a second at nanosecond resolution. Negative
+  // second values with fractions must still have non-negative nanos values
+  // that count forward in time. Must be from 0 to 999,999,999
+  // inclusive.
+  int32 nanos = 2;
+}
+
+// Describes a metric
+message Metric {
+  // name of metric, e.g. rpc_latency, cpu.
+  string name = 1;
+
+  // More detailed description of the metric, used in documentation.
+  string description = 2;
+
+  // Fundamental units of measurement supported by Census
+  // TODO(aveitch): expand this to include other S.I. units?
+  message BasicUnit {
+    enum Measure {
+      UNKNOWN = 0;
+      BITS = 1;
+      BYTES = 2;
+      SECS = 3;
+      CORES = 4;
+      MAX_UNITS = 5;
+    }
+    Measure type = 1;
+  }
+
+  // MeasurementUnit lets you build compound units of the form
+  //   10^n * (A * B * ...) / (X * Y * ...),
+  // where the elements in the numerator and denominator are all BasicUnits.  A
+  // MeasurementUnit must have at least one BasicUnit in its numerator.
+  //
+  // To specify multiplication in the numerator or denominator, simply specify
+  // multiple numerator or denominator fields.  For example:
+  //
+  // - byte-seconds (i.e. bytes * seconds):
+  //     numerator: BYTES
+  //     numerator: SECS
+  //
+  // - events/sec^2 (i.e. rate of change of events/sec):
+  //     numerator: COUNT
+  //     denominator: SECS
+  //     denominator: SECS
+  //
+  // To specify multiples (in power of 10) units, specify a non-zero prefix
+  // value, for example:
+  //
+  // - MB/s (i.e. megabytes / s):
+  //     prefix: 6
+  //     numerator: BYTES
+  //     denominator: SECS
+  //
+  // - nanoseconds
+  //     prefix: -9
+  //     numerator: SECS
+  message MeasurementUnit {
+    int32 prefix = 1;
+    repeated BasicUnit numerator = 2;
+    repeated BasicUnit denominator = 3;
+  }
+
+  // The units in which the Metric value is reported.
+  MeasurementUnit unit = 3;
+
+  // Metrics will be assigned an ID when registered. Invalid if <= 0.
+  int32 id = 4;
+}
+
+// An Aggregation summarizes a series of individual Metric measurements, an
+// AggregationDescriptor describes an Aggregation.
+message AggregationDescriptor {
+  // At most one set of options. If neither option is set, a default type
+  // of Distribution (without a histogram component) will be used.
+  oneof options {
+    // Defines the histogram bucket boundaries for Distributions.
+    BucketBoundaries bucket_boundaries = 1;
+    // Defines the time windows to record for IntervalStats.
+    IntervalBoundaries interval_boundaries = 2;
+  }
+
+  // A Distribution may optionally contain a histogram of the values in the
+  // population. The bucket boundaries for that histogram is described by
+  // `bucket_boundaries`.
+  //
+  // Describes histogram bucket boundaries. Defines `size(bounds) + 1` (= N)
+  // buckets (for size(bounds) >= 1; if size(bounds) == 0, then no histogram
+  // will be defined. The boundaries for bucket index i are:
+  //
+  // [-infinity, bounds[i]) for i == 0
+  // [bounds[i-1], bounds[i]) for 0 < i < N-2
+  // [bounds[i-1], +infinity) for i == N-1
+  //
+  // i.e. an underflow bucket (number 0), zero or more finite buckets (1
+  // through N - 2, and an overflow bucket (N - 1), with inclusive lower
+  // bounds and exclusive upper bounds.
+  //
+  // There must be at least one element in `bounds`.  If `bounds` has only one
+  // element, there are no finite buckets, and that single element is the
+  // common boundary of the overflow and underflow buckets.
+  message BucketBoundaries {
+    // The values must be monotonically increasing.
+    repeated double bounds = 1;
+  }
+
+  // For Interval stats, describe the size of each window.
+  message IntervalBoundaries {
+    // For each time window, specify a duration in seconds.
+    repeated double window_size = 1;
+  }
+}
+
+// Distribution contains summary statistics for a population of values and,
+// optionally, a histogram representing the distribution of those values across
+// a specified set of histogram buckets, as defined in
+// Aggregation.bucket_options.
+//
+// The summary statistics are the count, mean, sum of the squared deviation from
+// the mean, the minimum, and the maximum of the set of population of values.
+//
+// Although it is not forbidden, it is generally a bad idea to include
+// non-finite values (infinities or NaNs) in the population of values, as this
+// will render the `mean` field meaningless.
+message Distribution {
+  // The number of values in the population. Must be non-negative.
+  int64 count = 1;
+
+  // The arithmetic mean of the values in the population. If `count` is zero
+  // then this field must be zero.
+  double mean = 2;
+
+  // Describes a range of population values.
+  message Range {
+    // The minimum of the population values.
+    double min = 1;
+    // The maximum of the population values.
+    double max = 2;
+  }
+
+  // The range of the population values. If `count` is zero, this field will not
+  // be defined.
+  Range range = 3;
+
+  // A Distribution may optionally contain a histogram of the values in the
+  // population.  The histogram is given in `bucket_count` as counts of values
+  // that fall into one of a sequence of non-overlapping buckets, as described
+  // by `AggregationDescriptor.options.bucket_boundaries`.
+  // The sum of the values in `bucket_counts` must equal the value in `count`.
+  //
+  // Bucket counts are given in order under the numbering scheme described
+  // above (the underflow bucket has number 0; the finite buckets, if any,
+  // have numbers 1 through N-2; the overflow bucket has number N-1).
+  //
+  // The size of `bucket_count` must be no greater than N as defined in
+  // `bucket_boundaries`.
+  //
+  // Any suffix of trailing zero bucket_count fields may be omitted.
+  repeated int64 bucket_count = 4;
+}
+
+// Record summary stats over various time windows.
+message IntervalStats {
+  // Summary statistic over a single time window.
+  message Window {
+    // The window duration.
+    Duration window_size = 1;
+    // The number of measurements in this window.
+    int64 count = 2;
+    // The arithmetic mean of all measurements in the window.
+    double mean = 3;
+  }
+
+  // Full set of windows for this metric.
+  repeated Window window = 1;
+}
+
+// A Tag: key-value pair.
+message Tag {
+  string key = 1;
+  string value = 2;
+}
+
+// A View specifies an Aggregation and a set of tag keys. The Aggregation will
+// be broken down by the unique set of matching tag values for each measurement.
+message View {
+  // Name of view.
+  string name = 1;
+
+  // More detailed description, for documentation purposes.
+  string description = 2;
+
+  // ID of Metric to associate with this View.
+  int32 metric_id = 3;
+
+  // Aggregation type to associate with this View.
+  AggregationDescriptor aggregation = 4;
+
+  // Tag keys to match with a given Metric. If no keys are specified, then all
+  // stats for the Metric are recorded. Keys must be unique.
+  repeated string tag_key = 5;
+}
+
+// An Aggregation summarizes a series of individual Metric measures.
+message Aggregation {
+  // Name of this aggregation.
+  string name = 1;
+
+  // More detailed description, for documentation purposes.
+  string description = 2;
+
+  // The data for this Aggregation.
+  oneof data {
+    Distribution distribution = 3;
+    IntervalStats interval_stats = 4;
+  }
+
+  // Tags associated with this Aggregation.
+  repeated Tag tag = 5;
+}
+
+// A ViewAggregations represents all the Aggregations for a particular view.
+message ViewAggregations {
+  // Aggregations - each will have a unique set of tag values for the tag_keys
+  // associated with the corresponding View.
+  repeated Aggregation aggregation = 1;
+
+  // Start and end timestamps over which the value was accumulated. These
+  // values are not relevant/defined for IntervalStats aggregations, which are
+  // always accumulated over a fixed time period.
+  Timestamp start = 2;
+  Timestamp end = 3;
+}
diff --git a/src/proto/grpc/testing/messages.proto b/src/proto/grpc/testing/messages.proto
index a063b47..e109015 100644
--- a/src/proto/grpc/testing/messages.proto
+++ b/src/proto/grpc/testing/messages.proto
@@ -41,17 +41,6 @@
 
   // Uncompressable binary format.
   UNCOMPRESSABLE = 1;
-
-  // Randomly chosen from all other formats defined in this enum.
-  RANDOM = 2;
-}
-
-// Compression algorithms
-enum CompressionType {
-  // No compression
-  NONE = 0;
-  GZIP = 1;
-  DEFLATE = 2;
 }
 
 // A block of data, to simply increase gRPC message size.
@@ -88,8 +77,8 @@
   // Whether SimpleResponse should include OAuth scope.
   bool fill_oauth_scope = 5;
 
-  // Compression algorithm to be used by the server for the response (stream)
-  CompressionType response_compression = 6;
+  // Whether to request the server to compress the response.
+  bool request_compressed_response = 6;
 
   // Whether server should return a given status
   EchoStatus response_status = 7;
@@ -145,8 +134,8 @@
   // Optional input payload sent along with the request.
   Payload payload = 3;
 
-  // Compression algorithm to be used by the server for the response (stream)
-  CompressionType response_compression = 6;
+  // Whether to request the server to compress the response.
+  bool request_compressed_response = 6;
 
   // Whether server should return a given status
   EchoStatus response_status = 7;
diff --git a/src/proto/math/math.proto b/src/proto/math/math.proto
index 311e148..269c60b 100644
--- a/src/proto/math/math.proto
+++ b/src/proto/math/math.proto
@@ -55,8 +55,8 @@
 }
 
 service Math {
-  // Div divides args.dividend by args.divisor and returns the quotient and
-  // remainder.
+  // Div divides DivArgs.dividend by DivArgs.divisor and returns the quotient
+  // and remainder.
   rpc Div (DivArgs) returns (DivReply) {
   }
 
@@ -67,7 +67,7 @@
   rpc DivMany (stream DivArgs) returns (stream DivReply) {
   }
 
-  // Fib generates numbers in the Fibonacci sequence.  If args.limit > 0, Fib
+  // Fib generates numbers in the Fibonacci sequence.  If FibArgs.limit > 0, Fib
   // generates up to limit numbers; otherwise it continues until the call is
   // canceled.  Unlike Fib above, Fib has no final FibReply.
   rpc Fib (FibArgs) returns (stream Num) {
diff --git a/src/python/grpcio/commands.py b/src/python/grpcio/commands.py
index 295dab2..3e974eb 100644
--- a/src/python/grpcio/commands.py
+++ b/src/python/grpcio/commands.py
@@ -191,7 +191,7 @@
       except subprocess.CalledProcessError as e:
         sys.stderr.write(
             'warning: Command:\n{}\nMessage:\n{}\nOutput:\n{}'.format(
-                command, e.message, e.output))
+                command, str(e), e.output))
 
     # Generated proto directories dont include __init__.py, but
     # these are needed for python package resolution
diff --git a/src/python/grpcio/grpc/__init__.py b/src/python/grpcio/grpc/__init__.py
index b844a14..5ba5a4e 100644
--- a/src/python/grpcio/grpc/__init__.py
+++ b/src/python/grpcio/grpc/__init__.py
@@ -27,5 +27,1073 @@
 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
+"""gRPC's Python API."""
+
 __import__('pkg_resources').declare_namespace(__name__)
 
+import abc
+import enum
+
+import six
+
+from grpc._cython import cygrpc as _cygrpc
+
+
+############################## Future Interface  ###############################
+
+
+class FutureTimeoutError(Exception):
+  """Indicates that a method call on a Future timed out."""
+
+
+class FutureCancelledError(Exception):
+  """Indicates that the computation underlying a Future was cancelled."""
+
+
+class Future(six.with_metaclass(abc.ABCMeta)):
+  """A representation of a computation in another control flow.
+
+  Computations represented by a Future may be yet to be begun, may be ongoing,
+  or may have already completed.
+  """
+
+  @abc.abstractmethod
+  def cancel(self):
+    """Attempts to cancel the computation.
+
+    This method does not block.
+
+    Returns:
+      True if the computation has not yet begun, will not be allowed to take
+        place, and determination of both was possible without blocking. False
+        under all other circumstances including but not limited to the
+        computation's already having begun, the computation's already having
+        finished, and the computation's having been scheduled for execution on a
+        remote system for which a determination of whether or not it commenced
+        before being cancelled cannot be made without blocking.
+    """
+    raise NotImplementedError()
+
+  @abc.abstractmethod
+  def cancelled(self):
+    """Describes whether the computation was cancelled.
+
+    This method does not block.
+
+    Returns:
+      True if the computation was cancelled any time before its result became
+        immediately available. False under all other circumstances including but
+        not limited to this object's cancel method not having been called and
+        the computation's result having become immediately available.
+    """
+    raise NotImplementedError()
+
+  @abc.abstractmethod
+  def running(self):
+    """Describes whether the computation is taking place.
+
+    This method does not block.
+
+    Returns:
+      True if the computation is scheduled to take place in the future or is
+        taking place now, or False if the computation took place in the past or
+        was cancelled.
+    """
+    raise NotImplementedError()
+
+  @abc.abstractmethod
+  def done(self):
+    """Describes whether the computation has taken place.
+
+    This method does not block.
+
+    Returns:
+      True if the computation is known to have either completed or have been
+        unscheduled or interrupted. False if the computation may possibly be
+        executing or scheduled to execute later.
+    """
+    raise NotImplementedError()
+
+  @abc.abstractmethod
+  def result(self, timeout=None):
+    """Accesses the outcome of the computation or raises its exception.
+
+    This method may return immediately or may block.
+
+    Args:
+      timeout: The length of time in seconds to wait for the computation to
+        finish or be cancelled, or None if this method should block until the
+        computation has finished or is cancelled no matter how long that takes.
+
+    Returns:
+      The return value of the computation.
+
+    Raises:
+      FutureTimeoutError: If a timeout value is passed and the computation does
+        not terminate within the allotted time.
+      FutureCancelledError: If the computation was cancelled.
+      Exception: If the computation raised an exception, this call will raise
+        the same exception.
+    """
+    raise NotImplementedError()
+
+  @abc.abstractmethod
+  def exception(self, timeout=None):
+    """Return the exception raised by the computation.
+
+    This method may return immediately or may block.
+
+    Args:
+      timeout: The length of time in seconds to wait for the computation to
+        terminate or be cancelled, or None if this method should block until
+        the computation is terminated or is cancelled no matter how long that
+        takes.
+
+    Returns:
+      The exception raised by the computation, or None if the computation did
+        not raise an exception.
+
+    Raises:
+      FutureTimeoutError: If a timeout value is passed and the computation does
+        not terminate within the allotted time.
+      FutureCancelledError: If the computation was cancelled.
+    """
+    raise NotImplementedError()
+
+  @abc.abstractmethod
+  def traceback(self, timeout=None):
+    """Access the traceback of the exception raised by the computation.
+
+    This method may return immediately or may block.
+
+    Args:
+      timeout: The length of time in seconds to wait for the computation to
+        terminate or be cancelled, or None if this method should block until
+        the computation is terminated or is cancelled no matter how long that
+        takes.
+
+    Returns:
+      The traceback of the exception raised by the computation, or None if the
+        computation did not raise an exception.
+
+    Raises:
+      FutureTimeoutError: If a timeout value is passed and the computation does
+        not terminate within the allotted time.
+      FutureCancelledError: If the computation was cancelled.
+    """
+    raise NotImplementedError()
+
+  @abc.abstractmethod
+  def add_done_callback(self, fn):
+    """Adds a function to be called at completion of the computation.
+
+    The callback will be passed this Future object describing the outcome of
+    the computation.
+
+    If the computation has already completed, the callback will be called
+    immediately.
+
+    Args:
+      fn: A callable taking this Future object as its single parameter.
+    """
+    raise NotImplementedError()
+
+
+################################  gRPC Enums  ##################################
+
+
+@enum.unique
+class ChannelConnectivity(enum.Enum):
+  """Mirrors grpc_connectivity_state in the gRPC Core.
+
+  Attributes:
+    IDLE: The channel is idle.
+    CONNECTING: The channel is connecting.
+    READY: The channel is ready to conduct RPCs.
+    TRANSIENT_FAILURE: The channel has seen a failure from which it expects to
+      recover.
+    FATAL_FAILURE: The channel has seen a failure from which it cannot recover.
+  """
+  IDLE              = (_cygrpc.ConnectivityState.idle, 'idle')
+  CONNECTING        = (_cygrpc.ConnectivityState.connecting, 'connecting')
+  READY             = (_cygrpc.ConnectivityState.ready, 'ready')
+  TRANSIENT_FAILURE = (
+      _cygrpc.ConnectivityState.transient_failure, 'transient failure')
+  FATAL_FAILURE     = (_cygrpc.ConnectivityState.fatal_failure, 'fatal failure')
+
+
+@enum.unique
+class StatusCode(enum.Enum):
+  """Mirrors grpc_status_code in the gRPC Core."""
+  OK                  = (_cygrpc.StatusCode.ok, 'ok')
+  CANCELLED           = (_cygrpc.StatusCode.cancelled, 'cancelled')
+  UNKNOWN             = (_cygrpc.StatusCode.unknown, 'unknown')
+  INVALID_ARGUMENT    = (
+      _cygrpc.StatusCode.invalid_argument, 'invalid argument')
+  DEADLINE_EXCEEDED   = (
+      _cygrpc.StatusCode.deadline_exceeded, 'deadline exceeded')
+  NOT_FOUND           = (_cygrpc.StatusCode.not_found, 'not found')
+  ALREADY_EXISTS      = (_cygrpc.StatusCode.already_exists, 'already exists')
+  PERMISSION_DENIED   = (
+      _cygrpc.StatusCode.permission_denied, 'permission denied')
+  RESOURCE_EXHAUSTED  = (
+      _cygrpc.StatusCode.resource_exhausted, 'resource exhausted')
+  FAILED_PRECONDITION = (
+      _cygrpc.StatusCode.failed_precondition, 'failed precondition')
+  ABORTED             = (_cygrpc.StatusCode.aborted, 'aborted')
+  OUT_OF_RANGE        = (_cygrpc.StatusCode.out_of_range, 'out of range')
+  UNIMPLEMENTED       = (_cygrpc.StatusCode.unimplemented, 'unimplemented')
+  INTERNAL            = (_cygrpc.StatusCode.internal, 'internal')
+  UNAVAILABLE         = (_cygrpc.StatusCode.unavailable, 'unavailable')
+  DATA_LOSS           = (_cygrpc.StatusCode.data_loss, 'data loss')
+  UNAUTHENTICATED     = (_cygrpc.StatusCode.unauthenticated, 'unauthenticated')
+
+
+#############################  gRPC Exceptions  ################################
+
+
+class RpcError(Exception):
+  """Raised by the gRPC library to indicate non-OK-status RPC termination."""
+
+
+##############################  Shared Context  ################################
+
+
+class RpcContext(six.with_metaclass(abc.ABCMeta)):
+  """Provides RPC-related information and action."""
+
+  @abc.abstractmethod
+  def is_active(self):
+    """Describes whether the RPC is active or has terminated."""
+    raise NotImplementedError()
+
+  @abc.abstractmethod
+  def time_remaining(self):
+    """Describes the length of allowed time remaining for the RPC.
+
+    Returns:
+      A nonnegative float indicating the length of allowed time in seconds
+      remaining for the RPC to complete before it is considered to have timed
+      out, or None if no deadline was specified for the RPC.
+    """
+    raise NotImplementedError()
+
+  @abc.abstractmethod
+  def cancel(self):
+    """Cancels the RPC.
+
+    Idempotent and has no effect if the RPC has already terminated.
+    """
+    raise NotImplementedError()
+
+  @abc.abstractmethod
+  def add_callback(self, callback):
+    """Registers a callback to be called on RPC termination.
+
+    Args:
+      callback: A no-parameter callable to be called on RPC termination.
+
+    Returns:
+      True if the callback was added and will be called later; False if the
+        callback was not added and will not later be called (because the RPC
+        already terminated or some other reason).
+    """
+    raise NotImplementedError()
+
+
+#########################  Invocation-Side Context  ############################
+
+
+class Call(six.with_metaclass(abc.ABCMeta, RpcContext)):
+  """Invocation-side utility object for an RPC."""
+
+  @abc.abstractmethod
+  def initial_metadata(self):
+    """Accesses the initial metadata from the service-side of the RPC.
+
+    This method blocks until the value is available.
+
+    Returns:
+      The initial metadata as a sequence of pairs of bytes.
+    """
+    raise NotImplementedError()
+
+  @abc.abstractmethod
+  def trailing_metadata(self):
+    """Accesses the trailing metadata from the service-side of the RPC.
+
+    This method blocks until the value is available.
+
+    Returns:
+      The trailing metadata as a sequence of pairs of bytes.
+    """
+    raise NotImplementedError()
+
+  @abc.abstractmethod
+  def code(self):
+    """Accesses the status code emitted by the service-side of the RPC.
+
+    This method blocks until the value is available.
+
+    Returns:
+      The StatusCode value for the RPC.
+    """
+    raise NotImplementedError()
+
+  @abc.abstractmethod
+  def details(self):
+    """Accesses the details value emitted by the service-side of the RPC.
+
+    This method blocks until the value is available.
+
+    Returns:
+      The bytes of the details of the RPC.
+    """
+    raise NotImplementedError()
+
+
+############  Authentication & Authorization Interfaces & Classes  #############
+
+
+class ChannelCredentials(object):
+  """A value encapsulating the data required to create a secure Channel.
+
+  This class has no supported interface - it exists to define the type of its
+  instances and its instances exist to be passed to other functions.
+  """
+
+  def __init__(self, credentials):
+    self._credentials = credentials
+
+
+class CallCredentials(object):
+  """A value encapsulating data asserting an identity over a channel.
+
+  A CallCredentials may be composed with ChannelCredentials to always assert
+  identity for every call over that Channel.
+
+  This class has no supported interface - it exists to define the type of its
+  instances and its instances exist to be passed to other functions.
+  """
+
+  def __init__(self, credentials):
+    self._credentials = credentials
+
+
+class AuthMetadataContext(six.with_metaclass(abc.ABCMeta)):
+  """Provides information to call credentials metadata plugins.
+
+  Attributes:
+    service_url: A string URL of the service being called into.
+    method_name: A string of the fully qualified method name being called.
+  """
+
+
+class AuthMetadataPluginCallback(six.with_metaclass(abc.ABCMeta)):
+  """Callback object received by a metadata plugin."""
+
+  def __call__(self, metadata, error):
+    """Inform the gRPC runtime of the metadata to construct a CallCredentials.
+
+    Args:
+      metadata: An iterable of 2-sequences (e.g. tuples) of metadata key/value
+        pairs.
+      error: An Exception to indicate error or None to indicate success.
+    """
+    raise NotImplementedError()
+
+
+class AuthMetadataPlugin(six.with_metaclass(abc.ABCMeta)):
+  """A specification for custom authentication."""
+
+  def __call__(self, context, callback):
+    """Implements authentication by passing metadata to a callback.
+
+    Implementations of this method must not block.
+
+    Args:
+      context: An AuthMetadataContext providing information on the RPC that the
+        plugin is being called to authenticate.
+      callback: An AuthMetadataPluginCallback to be invoked either synchronously
+        or asynchronously.
+    """
+    raise NotImplementedError()
+
+
+class ServerCredentials(object):
+  """A value encapsulating the data required to open a secure port on a Server.
+
+  This class has no supported interface - it exists to define the type of its
+  instances and its instances exist to be passed to other functions.
+  """
+
+  def __init__(self, credentials):
+    self._credentials = credentials
+
+
+########################  Multi-Callable Interfaces  ###########################
+
+
+class UnaryUnaryMultiCallable(six.with_metaclass(abc.ABCMeta)):
+  """Affords invoking a unary-unary RPC."""
+
+  @abc.abstractmethod
+  def __call__(
+      self, request, timeout=None, metadata=None, credentials=None,
+      with_call=False):
+    """Synchronously invokes the underlying RPC.
+
+    Args:
+      request: The request value for the RPC.
+      timeout: An optional duration of time in seconds to allow for the RPC.
+      metadata: An optional sequence of pairs of bytes to be transmitted to the
+        service-side of the RPC.
+      credentials: An optional CallCredentials for the RPC.
+      with_call: Whether or not to include return a Call for the RPC in addition
+        to the response.
+
+    Returns:
+      The response value for the RPC, and a Call for the RPC if with_call was
+        set to True at invocation.
+
+    Raises:
+      RpcError: Indicating that the RPC terminated with non-OK status. The
+        raised RpcError will also be a Call for the RPC affording the RPC's
+        metadata, status code, and details.
+    """
+    raise NotImplementedError()
+
+  @abc.abstractmethod
+  def future(self, request, timeout=None, metadata=None, credentials=None):
+    """Asynchronously invokes the underlying RPC.
+
+    Args:
+      request: The request value for the RPC.
+      timeout: An optional duration of time in seconds to allow for the RPC.
+      metadata: An optional sequence of pairs of bytes to be transmitted to the
+        service-side of the RPC.
+      credentials: An optional CallCredentials for the RPC.
+
+    Returns:
+      An object that is both a Call for the RPC and a Future. In the event of
+        RPC completion, the return Future's result value will be the response
+        message of the RPC. Should the event terminate with non-OK status, the
+        returned Future's exception value will be an RpcError.
+    """
+    raise NotImplementedError()
+
+
+class UnaryStreamMultiCallable(six.with_metaclass(abc.ABCMeta)):
+  """Affords invoking a unary-stream RPC."""
+
+  @abc.abstractmethod
+  def __call__(self, request, timeout=None, metadata=None, credentials=None):
+    """Invokes the underlying RPC.
+
+    Args:
+      request: The request value for the RPC.
+      timeout: An optional duration of time in seconds to allow for the RPC.
+      metadata: An optional sequence of pairs of bytes to be transmitted to the
+        service-side of the RPC.
+      credentials: An optional CallCredentials for the RPC.
+
+    Returns:
+      An object that is both a Call for the RPC and an iterator of response
+        values. Drawing response values from the returned iterator may raise
+        RpcError indicating termination of the RPC with non-OK status.
+    """
+    raise NotImplementedError()
+
+
+class StreamUnaryMultiCallable(six.with_metaclass(abc.ABCMeta)):
+  """Affords invoking a stream-unary RPC in any call style."""
+
+  @abc.abstractmethod
+  def __call__(
+      self, request_iterator, timeout=None, metadata=None, credentials=None,
+      with_call=False):
+    """Synchronously invokes the underlying RPC.
+
+    Args:
+      request_iterator: An iterator that yields request values for the RPC.
+      timeout: An optional duration of time in seconds to allow for the RPC.
+      metadata: An optional sequence of pairs of bytes to be transmitted to the
+        service-side of the RPC.
+      credentials: An optional CallCredentials for the RPC.
+      with_call: Whether or not to include return a Call for the RPC in addition
+        to the response.
+
+    Returns:
+      The response value for the RPC, and a Call for the RPC if with_call was
+        set to True at invocation.
+
+    Raises:
+      RpcError: Indicating that the RPC terminated with non-OK status. The
+        raised RpcError will also be a Call for the RPC affording the RPC's
+        metadata, status code, and details.
+    """
+    raise NotImplementedError()
+
+  @abc.abstractmethod
+  def future(
+      self, request_iterator, timeout=None, metadata=None, credentials=None):
+    """Asynchronously invokes the underlying RPC.
+
+    Args:
+      request_iterator: An iterator that yields request values for the RPC.
+      timeout: An optional duration of time in seconds to allow for the RPC.
+      metadata: An optional sequence of pairs of bytes to be transmitted to the
+        service-side of the RPC.
+      credentials: An optional CallCredentials for the RPC.
+
+    Returns:
+      An object that is both a Call for the RPC and a Future. In the event of
+        RPC completion, the return Future's result value will be the response
+        message of the RPC. Should the event terminate with non-OK status, the
+        returned Future's exception value will be an RpcError.
+    """
+    raise NotImplementedError()
+
+
+class StreamStreamMultiCallable(six.with_metaclass(abc.ABCMeta)):
+  """Affords invoking a stream-stream RPC in any call style."""
+
+  @abc.abstractmethod
+  def __call__(
+      self, request_iterator, timeout=None, metadata=None, credentials=None):
+    """Invokes the underlying RPC.
+
+    Args:
+      request_iterator: An iterator that yields request values for the RPC.
+      timeout: An optional duration of time in seconds to allow for the RPC.
+      metadata: An optional sequence of pairs of bytes to be transmitted to the
+        service-side of the RPC.
+      credentials: An optional CallCredentials for the RPC.
+
+    Returns:
+      An object that is both a Call for the RPC and an iterator of response
+        values. Drawing response values from the returned iterator may raise
+        RpcError indicating termination of the RPC with non-OK status.
+    """
+    raise NotImplementedError()
+
+
+#############################  Channel Interface  ##############################
+
+
+class Channel(six.with_metaclass(abc.ABCMeta)):
+  """Affords RPC invocation via generic methods."""
+
+  @abc.abstractmethod
+  def subscribe(self, callback, try_to_connect=False):
+    """Subscribes to this Channel's connectivity.
+
+    Args:
+      callback: A callable to be invoked and passed a ChannelConnectivity value
+        describing this Channel's connectivity. The callable will be invoked
+        immediately upon subscription and again for every change to this
+        Channel's connectivity thereafter until it is unsubscribed or this
+        Channel object goes out of scope.
+      try_to_connect: A boolean indicating whether or not this Channel should
+        attempt to connect if it is not already connected and ready to conduct
+        RPCs.
+    """
+    raise NotImplementedError()
+
+  @abc.abstractmethod
+  def unsubscribe(self, callback):
+    """Unsubscribes a callback from this Channel's connectivity.
+
+    Args:
+      callback: A callable previously registered with this Channel from having
+        been passed to its "subscribe" method.
+    """
+    raise NotImplementedError()
+
+  @abc.abstractmethod
+  def unary_unary(
+      self, method, request_serializer=None, response_deserializer=None):
+    """Creates a UnaryUnaryMultiCallable for a unary-unary method.
+
+    Args:
+      method: The name of the RPC method.
+
+    Returns:
+      A UnaryUnaryMultiCallable value for the named unary-unary method.
+    """
+    raise NotImplementedError()
+
+  @abc.abstractmethod
+  def unary_stream(
+      self, method, request_serializer=None, response_deserializer=None):
+    """Creates a UnaryStreamMultiCallable for a unary-stream method.
+
+    Args:
+      method: The name of the RPC method.
+
+    Returns:
+      A UnaryStreamMultiCallable value for the name unary-stream method.
+    """
+    raise NotImplementedError()
+
+  @abc.abstractmethod
+  def stream_unary(
+      self, method, request_serializer=None, response_deserializer=None):
+    """Creates a StreamUnaryMultiCallable for a stream-unary method.
+
+    Args:
+      method: The name of the RPC method.
+
+    Returns:
+      A StreamUnaryMultiCallable value for the named stream-unary method.
+    """
+    raise NotImplementedError()
+
+  @abc.abstractmethod
+  def stream_stream(
+      self, method, request_serializer=None, response_deserializer=None):
+    """Creates a StreamStreamMultiCallable for a stream-stream method.
+
+    Args:
+      method: The name of the RPC method.
+
+    Returns:
+      A StreamStreamMultiCallable value for the named stream-stream method.
+    """
+    raise NotImplementedError()
+
+
+##########################  Service-Side Context  ##############################
+
+
+class ServicerContext(six.with_metaclass(abc.ABCMeta, RpcContext)):
+  """A context object passed to method implementations."""
+
+  @abc.abstractmethod
+  def invocation_metadata(self):
+    """Accesses the metadata from the invocation-side of the RPC.
+
+    Returns:
+      The invocation metadata object as a sequence of pairs of bytes.
+    """
+    raise NotImplementedError()
+
+  @abc.abstractmethod
+  def peer(self):
+    """Identifies the peer that invoked the RPC being serviced.
+
+    Returns:
+      A string identifying the peer that invoked the RPC being serviced.
+    """
+    raise NotImplementedError()
+
+  @abc.abstractmethod
+  def send_initial_metadata(self, initial_metadata):
+    """Sends the initial metadata value to the invocation-side of the RPC.
+
+    This method need not be called by method implementations if they have no
+    service-side initial metadata to transmit.
+
+    Args:
+      initial_metadata: The initial metadata of the RPC as a sequence of pairs
+        of bytes.
+    """
+    raise NotImplementedError()
+
+  @abc.abstractmethod
+  def set_trailing_metadata(self, trailing_metadata):
+    """Accepts the trailing metadata value of the RPC.
+
+    This method need not be called by method implementations if they have no
+    service-side trailing metadata to transmit.
+
+    Args:
+      trailing_metadata: The trailing metadata of the RPC as a sequence of pairs
+        of bytes.
+    """
+    raise NotImplementedError()
+
+  @abc.abstractmethod
+  def set_code(self, code):
+    """Accepts the status code of the RPC.
+
+    This method need not be called by method implementations if they wish the
+    gRPC runtime to determine the status code of the RPC.
+
+    Args:
+      code: The integer status code of the RPC to be transmitted to the
+        invocation side of the RPC.
+    """
+    raise NotImplementedError()
+
+  @abc.abstractmethod
+  def set_details(self, details):
+    """Accepts the service-side details of the RPC.
+
+    This method need not be called by method implementations if they have no
+    details to transmit.
+
+    Args:
+      details: The details bytes of the RPC to be transmitted to
+        the invocation side of the RPC.
+    """
+    raise NotImplementedError()
+
+
+#####################  Service-Side Handler Interfaces  ########################
+
+
+class RpcMethodHandler(six.with_metaclass(abc.ABCMeta)):
+  """An implementation of a single RPC method.
+
+  Attributes:
+    request_streaming: Whether the RPC supports exactly one request message or
+      any arbitrary number of request messages.
+    response_streaming: Whether the RPC supports exactly one response message or
+      any arbitrary number of response messages.
+    request_deserializer: A callable behavior that accepts a byte string and
+      returns an object suitable to be passed to this object's business logic,
+      or None to indicate that this object's business logic should be passed the
+      raw request bytes.
+    response_serializer: A callable behavior that accepts an object produced by
+      this object's business logic and returns a byte string, or None to
+      indicate that the byte strings produced by this object's business logic
+      should be transmitted on the wire as they are.
+    unary_unary: This object's application-specific business logic as a callable
+      value that takes a request value and a ServicerContext object and returns
+      a response value. Only non-None if both request_streaming and
+      response_streaming are False.
+    unary_stream: This object's application-specific business logic as a
+      callable value that takes a request value and a ServicerContext object and
+      returns an iterator of response values. Only non-None if request_streaming
+      is False and response_streaming is True.
+    stream_unary: This object's application-specific business logic as a
+      callable value that takes an iterator of request values and a
+      ServicerContext object and returns a response value. Only non-None if
+      request_streaming is True and response_streaming is False.
+    stream_stream: This object's application-specific business logic as a
+      callable value that takes an iterator of request values and a
+      ServicerContext object and returns an iterator of response values. Only
+      non-None if request_streaming and response_streaming are both True.
+  """
+
+
+class HandlerCallDetails(six.with_metaclass(abc.ABCMeta)):
+  """Describes an RPC that has just arrived for service.
+  Attributes:
+    method: The method name of the RPC.
+    invocation_metadata: The metadata from the invocation side of the RPC.
+  """
+
+
+class GenericRpcHandler(six.with_metaclass(abc.ABCMeta)):
+  """An implementation of arbitrarily many RPC methods."""
+
+  @abc.abstractmethod
+  def service(self, handler_call_details):
+    """Services an RPC (or not).
+
+    Args:
+      handler_call_details: A HandlerCallDetails describing the RPC.
+
+    Returns:
+      An RpcMethodHandler with which the RPC may be serviced, or None to
+        indicate that this object will not be servicing the RPC.
+    """
+    raise NotImplementedError()
+
+
+#############################  Server Interface  ###############################
+
+
+class Server(six.with_metaclass(abc.ABCMeta)):
+  """Services RPCs."""
+
+  @abc.abstractmethod
+  def add_generic_rpc_handlers(self, generic_rpc_handlers):
+    """Registers GenericRpcHandlers with this Server.
+
+    This method is only safe to call before the server is started.
+
+    Args:
+      generic_rpc_handlers: An iterable of GenericRpcHandlers that will be used
+        to service RPCs after this Server is started.
+    """
+    raise NotImplementedError()
+
+  @abc.abstractmethod
+  def add_insecure_port(self, address):
+    """Reserves a port for insecure RPC service once this Server becomes active.
+
+    This method may only be called before calling this Server's start method is
+    called.
+
+    Args:
+      address: The address for which to open a port.
+
+    Returns:
+      An integer port on which RPCs will be serviced after this link has been
+        started. This is typically the same number as the port number contained
+        in the passed address, but will likely be different if the port number
+        contained in the passed address was zero.
+    """
+    raise NotImplementedError()
+
+  @abc.abstractmethod
+  def add_secure_port(self, address, server_credentials):
+    """Reserves a port for secure RPC service after this Server becomes active.
+
+    This method may only be called before calling this Server's start method is
+    called.
+
+    Args:
+      address: The address for which to open a port.
+      server_credentials: A ServerCredentials.
+
+    Returns:
+      An integer port on which RPCs will be serviced after this link has been
+        started. This is typically the same number as the port number contained
+        in the passed address, but will likely be different if the port number
+        contained in the passed address was zero.
+    """
+    raise NotImplementedError()
+
+  @abc.abstractmethod
+  def start(self):
+    """Starts this Server's service of RPCs.
+
+    This method may only be called while the server is not serving RPCs (i.e. it
+    is not idempotent).
+    """
+    raise NotImplementedError()
+
+  @abc.abstractmethod
+  def stop(self, grace):
+    """Stops this Server's service of RPCs.
+
+    All calls to this method immediately stop service of new RPCs. When existing
+    RPCs are aborted is controlled by the grace period parameter passed to this
+    method.
+
+    This method may be called at any time and is idempotent. Passing a smaller
+    grace value than has been passed in a previous call will have the effect of
+    stopping the Server sooner. Passing a larger grace value than has been
+    passed in a previous call will not have the effect of stopping the server
+    later.
+
+    Args:
+      grace: A duration of time in seconds to allow existing RPCs to complete
+        before being aborted by this Server's stopping. If None, this method
+        will block until the server is completely stopped.
+
+    Returns:
+      A threading.Event that will be set when this Server has completely
+      stopped. The returned event may not be set until after the full grace
+      period (if some ongoing RPC continues for the full length of the period)
+      of it may be set much sooner (such as if this Server had no RPCs underway
+      at the time it was stopped or if all RPCs that it had underway completed
+      very early in the grace period).
+    """
+    raise NotImplementedError()
+
+
+#################################  Functions    ################################
+
+
+def ssl_channel_credentials(
+    root_certificates=None, private_key=None, certificate_chain=None):
+  """Creates a ChannelCredentials for use with an SSL-enabled Channel.
+
+  Args:
+    root_certificates: The PEM-encoded root certificates or unset to ask for
+      them to be retrieved from a default location.
+    private_key: The PEM-encoded private key to use or unset if no private key
+      should be used.
+    certificate_chain: The PEM-encoded certificate chain to use or unset if no
+      certificate chain should be used.
+
+  Returns:
+    A ChannelCredentials for use with an SSL-enabled Channel.
+  """
+  if private_key is not None or certificate_chain is not None:
+    pair = _cygrpc.SslPemKeyCertPair(private_key, certificate_chain)
+  else:
+    pair = None
+  return ChannelCredentials(
+      _cygrpc.channel_credentials_ssl(root_certificates, pair))
+
+
+def metadata_call_credentials(metadata_plugin, name=None):
+  """Construct CallCredentials from an AuthMetadataPlugin.
+
+  Args:
+    metadata_plugin: An AuthMetadataPlugin to use as the authentication behavior
+      in the created CallCredentials.
+    name: A name for the plugin.
+
+  Returns:
+    A CallCredentials.
+  """
+  from grpc import _plugin_wrapping
+  if name is None:
+    try:
+      effective_name = metadata_plugin.__name__
+    except AttributeError:
+      effective_name = metadata_plugin.__class__.__name__
+  else:
+    effective_name = name
+  return CallCredentials(
+      _plugin_wrapping.call_credentials_metadata_plugin(
+          metadata_plugin, effective_name))
+
+
+def access_token_call_credentials(access_token):
+  """Construct CallCredentials from an access token.
+
+  Args:
+    access_token: A string to place directly in the http request
+      authorization header, ie "Authorization: Bearer <access_token>".
+
+  Returns:
+    A CallCredentials.
+  """
+  from grpc import _auth
+  return metadata_call_credentials(
+      _auth.AccessTokenCallCredentials(access_token))
+
+
+def composite_call_credentials(call_credentials, additional_call_credentials):
+  """Compose two CallCredentials to make a new one.
+
+  Args:
+    call_credentials: A CallCredentials object.
+    additional_call_credentials: Another CallCredentials object to compose on
+      top of call_credentials.
+
+  Returns:
+    A new CallCredentials composed of the two given CallCredentials.
+  """
+  return CallCredentials(
+      _cygrpc.call_credentials_composite(
+          call_credentials._credentials,
+          additional_call_credentials._credentials))
+
+
+def composite_channel_credentials(channel_credentials, call_credentials):
+  """Compose a ChannelCredentials and a CallCredentials.
+
+  Args:
+    channel_credentials: A ChannelCredentials.
+    call_credentials: A CallCredentials.
+
+  Returns:
+    A ChannelCredentials composed of the given ChannelCredentials and
+      CallCredentials.
+  """
+  return ChannelCredentials(
+      _cygrpc.channel_credentials_composite(
+          channel_credentials._credentials, call_credentials._credentials))
+
+
+def ssl_server_credentials(
+    private_key_certificate_chain_pairs, root_certificates=None,
+    require_client_auth=False):
+  """Creates a ServerCredentials for use with an SSL-enabled Server.
+
+  Args:
+    private_key_certificate_chain_pairs: A nonempty sequence each element of
+      which is a pair the first element of which is a PEM-encoded private key
+      and the second element of which is the corresponding PEM-encoded
+      certificate chain.
+    root_certificates: PEM-encoded client root certificates to be used for
+      verifying authenticated clients. If omitted, require_client_auth must also
+      be omitted or be False.
+    require_client_auth: A boolean indicating whether or not to require clients
+      to be authenticated. May only be True if root_certificates is not None.
+
+  Returns:
+    A ServerCredentials for use with an SSL-enabled Server.
+  """
+  if len(private_key_certificate_chain_pairs) == 0:
+    raise ValueError(
+        'At least one private key-certificate chain pair is required!')
+  elif require_client_auth and root_certificates is None:
+    raise ValueError(
+        'Illegal to require client auth without providing root certificates!')
+  else:
+    return ServerCredentials(
+        _cygrpc.server_credentials_ssl(
+        root_certificates,
+        [_cygrpc.SslPemKeyCertPair(key, pem)
+         for key, pem in private_key_certificate_chain_pairs],
+        require_client_auth))
+
+
+def channel_ready_future(channel):
+  """Creates a Future tracking when a Channel is ready.
+
+  Cancelling the returned Future does not tell the given Channel to abandon
+  attempts it may have been making to connect; cancelling merely deactivates the
+  returned Future's subscription to the given Channel's connectivity.
+
+  Args:
+    channel: A Channel.
+
+  Returns:
+    A Future that matures when the given Channel has connectivity
+      ChannelConnectivity.READY.
+  """
+  from grpc import _utilities
+  return _utilities.channel_ready_future(channel)
+
+
+def insecure_channel(target, options=None):
+  """Creates an insecure Channel to a server.
+
+  Args:
+    target: The target to which to connect.
+    options: A sequence of string-value pairs according to which to configure
+      the created channel.
+
+  Returns:
+    A Channel to the target through which RPCs may be conducted.
+  """
+  from grpc import _channel
+  return _channel.Channel(target, None, options)
+
+
+def secure_channel(target, credentials, options=None):
+  """Creates an insecure Channel to a server.
+
+  Args:
+    target: The target to which to connect.
+    credentials: A ChannelCredentials instance.
+    options: A sequence of string-value pairs according to which to configure
+      the created channel.
+
+  Returns:
+    A Channel to the target through which RPCs may be conducted.
+  """
+  from grpc import _channel
+  return _channel.Channel(target, credentials, options)
+
+
+def server(generic_rpc_handlers, thread_pool, options=None):
+  """Creates a Server with which RPCs can be serviced.
+
+  The GenericRpcHandlers passed to this function needn't be the only
+  GenericRpcHandlers that will be used to serve RPCs; others may be added later
+  by calling add_generic_rpc_handlers any time before the returned server is
+  started.
+
+  Args:
+    generic_rpc_handlers: Some number of GenericRpcHandlers that will be used
+      to service RPCs after the returned Server is started.
+    thread_pool: A futures.ThreadPoolExecutor to be used by the returned Server
+      to service RPCs.
+
+  Returns:
+    A Server with which RPCs can be serviced.
+  """
+  from grpc import _server
+  return _server.Server(generic_rpc_handlers, thread_pool)
diff --git a/src/python/grpcio/grpc/_adapter/_low.py b/src/python/grpcio/grpc/_adapter/_low.py
index 00788bd..4841016 100644
--- a/src/python/grpcio/grpc/_adapter/_low.py
+++ b/src/python/grpcio/grpc/_adapter/_low.py
@@ -30,8 +30,8 @@
 import threading
 
 from grpc import _grpcio_metadata
+from grpc import _plugin_wrapping
 from grpc._cython import cygrpc
-from grpc._adapter import _implementations
 from grpc._adapter import _types
 
 _USER_AGENT = 'Python-gRPC-{}'.format(_grpcio_metadata.__version__)
@@ -57,78 +57,8 @@
   return cygrpc.channel_credentials_ssl(root_certificates, pair)
 
 
-class _WrappedCygrpcCallback(object):
-
-  def __init__(self, cygrpc_callback):
-    self.is_called = False
-    self.error = None
-    self.is_called_lock = threading.Lock()
-    self.cygrpc_callback = cygrpc_callback
-
-  def _invoke_failure(self, error):
-    # TODO(atash) translate different Exception superclasses into different
-    # status codes.
-    self.cygrpc_callback(
-        cygrpc.Metadata([]), cygrpc.StatusCode.internal, error.message)
-
-  def _invoke_success(self, metadata):
-    try:
-      cygrpc_metadata = cygrpc.Metadata(
-          cygrpc.Metadatum(key, value)
-          for key, value in metadata)
-    except Exception as error:
-      self._invoke_failure(error)
-      return
-    self.cygrpc_callback(cygrpc_metadata, cygrpc.StatusCode.ok, '')
-
-  def __call__(self, metadata, error):
-    with self.is_called_lock:
-      if self.is_called:
-        raise RuntimeError('callback should only ever be invoked once')
-      if self.error:
-        self._invoke_failure(self.error)
-        return
-      self.is_called = True
-    if error is None:
-      self._invoke_success(metadata)
-    else:
-      self._invoke_failure(error)
-
-  def notify_failure(self, error):
-    with self.is_called_lock:
-      if not self.is_called:
-        self.error = error
-
-
-class _WrappedPlugin(object):
-
-  def __init__(self, plugin):
-    self.plugin = plugin
-
-  def __call__(self, context, cygrpc_callback):
-    wrapped_cygrpc_callback = _WrappedCygrpcCallback(cygrpc_callback)
-    wrapped_context = _implementations.AuthMetadataContext(context.service_url,
-                                                           context.method_name)
-    try:
-      self.plugin(
-          wrapped_context,
-          _implementations.AuthMetadataPluginCallback(wrapped_cygrpc_callback))
-    except Exception as error:
-      wrapped_cygrpc_callback.notify_failure(error)
-      raise
-
-
-def call_credentials_metadata_plugin(plugin, name):
-  """
-  Args:
-    plugin: A callable accepting a _types.AuthMetadataContext
-      object and a callback (itself accepting a list of metadata key/value
-      2-tuples and a None-able exception value). The callback must be eventually
-      called, but need not be called in plugin's invocation.
-      plugin's invocation must be non-blocking.
-  """
-  return cygrpc.call_credentials_metadata_plugin(
-      cygrpc.CredentialsMetadataPlugin(_WrappedPlugin(plugin), name))
+call_credentials_metadata_plugin = (
+    _plugin_wrapping.call_credentials_metadata_plugin)
 
 
 class CompletionQueue(_types.CompletionQueue):
diff --git a/src/python/grpcio/grpc/_auth.py b/src/python/grpcio/grpc/_auth.py
new file mode 100644
index 0000000..dea3221
--- /dev/null
+++ b/src/python/grpcio/grpc/_auth.py
@@ -0,0 +1,86 @@
+# Copyright 2016, Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"""GRPCAuthMetadataPlugins for standard authentication."""
+
+import inspect
+from concurrent import futures
+
+import grpc
+
+
+def _sign_request(callback, token, error):
+  metadata = (('authorization', 'Bearer {}'.format(token)),)
+  callback(metadata, error)
+
+
+class GoogleCallCredentials(grpc.AuthMetadataPlugin):
+  """Metadata wrapper for GoogleCredentials from the oauth2client library."""
+
+  def __init__(self, credentials):
+    self._credentials = credentials
+    self._pool = futures.ThreadPoolExecutor(max_workers=1)
+
+    # Hack to determine if these are JWT creds and we need to pass
+    # additional_claims when getting a token
+    if 'additional_claims' in inspect.getargspec(
+        credentials.get_access_token).args:
+      self._is_jwt = True
+    else:
+      self._is_jwt = False
+
+  def __call__(self, context, callback):
+    # MetadataPlugins cannot block (see grpc.beta.interfaces.py)
+    if self._is_jwt:
+      future = self._pool.submit(self._credentials.get_access_token,
+                                 additional_claims={'aud': context.service_url})
+    else:
+      future = self._pool.submit(self._credentials.get_access_token)
+    future.add_done_callback(lambda x: self._get_token_callback(callback, x))
+
+  def _get_token_callback(self, callback, future):
+    try:
+      access_token = future.result().access_token
+    except Exception as e:
+      _sign_request(callback, None, e)
+    else:
+      _sign_request(callback, access_token, None)
+
+  def __del__(self):
+    self._pool.shutdown(wait=False)
+
+
+class AccessTokenCallCredentials(grpc.AuthMetadataPlugin):
+  """Metadata wrapper for raw access token credentials."""
+
+  def __init__(self, access_token):
+    self._access_token = access_token
+
+  def __call__(self, context, callback):
+    _sign_request(callback, self._access_token, None)
diff --git a/src/python/grpcio/grpc/_channel.py b/src/python/grpcio/grpc/_channel.py
new file mode 100644
index 0000000..d9315d2
--- /dev/null
+++ b/src/python/grpcio/grpc/_channel.py
@@ -0,0 +1,852 @@
+# 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.
+
+"""Invocation-side implementation of gRPC Python."""
+
+import sys
+import threading
+import time
+
+import grpc
+from grpc import _common
+from grpc import _grpcio_metadata
+from grpc.framework.foundation import callable_util
+from grpc._cython import cygrpc
+
+_USER_AGENT = 'Python-gRPC-{}'.format(_grpcio_metadata.__version__)
+
+_EMPTY_FLAGS = 0
+_INFINITE_FUTURE = cygrpc.Timespec(float('+inf'))
+_EMPTY_METADATA = cygrpc.Metadata(())
+
+_UNARY_UNARY_INITIAL_DUE = (
+    cygrpc.OperationType.send_initial_metadata,
+    cygrpc.OperationType.send_message,
+    cygrpc.OperationType.send_close_from_client,
+    cygrpc.OperationType.receive_initial_metadata,
+    cygrpc.OperationType.receive_message,
+    cygrpc.OperationType.receive_status_on_client,
+)
+_UNARY_STREAM_INITIAL_DUE = (
+    cygrpc.OperationType.send_initial_metadata,
+    cygrpc.OperationType.send_message,
+    cygrpc.OperationType.send_close_from_client,
+    cygrpc.OperationType.receive_initial_metadata,
+    cygrpc.OperationType.receive_status_on_client,
+)
+_STREAM_UNARY_INITIAL_DUE = (
+    cygrpc.OperationType.send_initial_metadata,
+    cygrpc.OperationType.receive_initial_metadata,
+    cygrpc.OperationType.receive_message,
+    cygrpc.OperationType.receive_status_on_client,
+)
+_STREAM_STREAM_INITIAL_DUE = (
+    cygrpc.OperationType.send_initial_metadata,
+    cygrpc.OperationType.receive_initial_metadata,
+    cygrpc.OperationType.receive_status_on_client,
+)
+
+_CHANNEL_SUBSCRIPTION_CALLBACK_ERROR_LOG_MESSAGE = (
+    'Exception calling channel subscription callback!')
+
+
+def _deadline(timeout):
+  if timeout is None:
+    return None, _INFINITE_FUTURE
+  else:
+    deadline = time.time() + timeout
+    return deadline, cygrpc.Timespec(deadline)
+
+
+def _unknown_code_details(unknown_cygrpc_code, details):
+  return 'Server sent unknown code {} and details "{}"'.format(
+      unknown_cygrpc_code, details)
+
+
+def _wait_once_until(condition, until):
+  if until is None:
+    condition.wait()
+  else:
+    remaining = until - time.time()
+    if remaining < 0:
+      raise grpc.FutureTimeoutError()
+    else:
+      condition.wait(timeout=remaining)
+
+
+class _RPCState(object):
+
+  def __init__(self, due, initial_metadata, trailing_metadata, code, details):
+    self.condition = threading.Condition()
+    # The cygrpc.OperationType objects representing events due from the RPC's
+    # completion queue.
+    self.due = set(due)
+    self.initial_metadata = initial_metadata
+    self.response = None
+    self.trailing_metadata = trailing_metadata
+    self.code = code
+    self.details = details
+    # The semantics of grpc.Future.cancel and grpc.Future.cancelled are
+    # slightly wonky, so they have to be tracked separately from the rest of the
+    # result of the RPC. This field tracks whether cancellation was requested
+    # prior to termination of the RPC.
+    self.cancelled = False
+    self.callbacks = []
+
+
+def _abort(state, code, details):
+  if state.code is None:
+    state.code = code
+    state.details = details
+    if state.initial_metadata is None:
+      state.initial_metadata = _EMPTY_METADATA
+    state.trailing_metadata = _EMPTY_METADATA
+
+
+def _handle_event(event, state, response_deserializer):
+  callbacks = []
+  for batch_operation in event.batch_operations:
+    operation_type = batch_operation.type
+    state.due.remove(operation_type)
+    if operation_type == cygrpc.OperationType.receive_initial_metadata:
+      state.initial_metadata = batch_operation.received_metadata
+    elif operation_type == cygrpc.OperationType.receive_message:
+      serialized_response = batch_operation.received_message.bytes()
+      if serialized_response is not None:
+        response = _common.deserialize(
+            serialized_response, response_deserializer)
+        if response is None:
+          details = 'Exception deserializing response!'
+          _abort(state, grpc.StatusCode.INTERNAL, details)
+        else:
+          state.response = response
+    elif operation_type == cygrpc.OperationType.receive_status_on_client:
+      state.trailing_metadata = batch_operation.received_metadata
+      if state.code is None:
+        code = _common.CYGRPC_STATUS_CODE_TO_STATUS_CODE.get(
+            batch_operation.received_status_code)
+        if code is None:
+          state.code = grpc.StatusCode.UNKNOWN
+          state.details = _unknown_code_details(
+              batch_operation.received_status_code,
+              batch_operation.received_status_details)
+        else:
+          state.code = code
+          state.details = batch_operation.received_status_details
+      callbacks.extend(state.callbacks)
+      state.callbacks = None
+  return callbacks
+
+
+def _event_handler(state, call, response_deserializer):
+  def handle_event(event):
+    with state.condition:
+      callbacks = _handle_event(event, state, response_deserializer)
+      state.condition.notify_all()
+      done = not state.due
+    for callback in callbacks:
+      callback()
+    return call if done else None
+  return handle_event
+
+
+def _consume_request_iterator(
+    request_iterator, state, call, request_serializer):
+  event_handler = _event_handler(state, call, None)
+  def consume_request_iterator():
+    for request in request_iterator:
+      serialized_request = _common.serialize(request, request_serializer)
+      with state.condition:
+        if state.code is None and not state.cancelled:
+          if serialized_request is None:
+            call.cancel()
+            details = 'Exception serializing request!'
+            _abort(state, grpc.StatusCode.INTERNAL, details)
+            return
+          else:
+            operations = (
+                cygrpc.operation_send_message(
+                    serialized_request, _EMPTY_FLAGS),
+            )
+            call.start_batch(cygrpc.Operations(operations), event_handler)
+            state.due.add(cygrpc.OperationType.send_message)
+            while True:
+              state.condition.wait()
+              if state.code is None:
+                if cygrpc.OperationType.send_message not in state.due:
+                  break
+              else:
+                return
+        else:
+          return
+    with state.condition:
+      if state.code is None:
+        operations = (
+            cygrpc.operation_send_close_from_client(_EMPTY_FLAGS),
+        )
+        call.start_batch(cygrpc.Operations(operations), event_handler)
+        state.due.add(cygrpc.OperationType.send_close_from_client)
+  thread = threading.Thread(target=consume_request_iterator)
+  thread.start()
+
+
+class _Rendezvous(grpc.RpcError, grpc.Future, grpc.Call):
+
+  def __init__(self, state, call, response_deserializer, deadline):
+    super(_Rendezvous, self).__init__()
+    self._state = state
+    self._call = call
+    self._response_deserializer = response_deserializer
+    self._deadline = deadline
+
+  def cancel(self):
+    with self._state.condition:
+      if self._state.code is None:
+        self._call.cancel()
+        self._state.cancelled = True
+        _abort(self._state, grpc.StatusCode.CANCELLED, 'Cancelled!')
+        self._state.condition.notify_all()
+      return False
+
+  def cancelled(self):
+    with self._state.condition:
+      return self._state.cancelled
+
+  def running(self):
+    with self._state.condition:
+      return self._state.code is None
+
+  def done(self):
+    with self._state.condition:
+      return self._state.code is not None
+
+  def result(self, timeout=None):
+    until = None if timeout is None else time.time() + timeout
+    with self._state.condition:
+      while True:
+        if self._state.code is None:
+          _wait_once_until(self._state.condition, until)
+        elif self._state.code is grpc.StatusCode.OK:
+          return self._state.response
+        elif self._state.cancelled:
+          raise grpc.FutureCancelledError()
+        else:
+          raise self
+
+  def exception(self, timeout=None):
+    until = None if timeout is None else time.time() + timeout
+    with self._state.condition:
+      while True:
+        if self._state.code is None:
+          _wait_once_until(self._state.condition, until)
+        elif self._state.code is grpc.StatusCode.OK:
+          return None
+        elif self._state.cancelled:
+          raise grpc.FutureCancelledError()
+        else:
+          return self
+
+  def traceback(self, timeout=None):
+    until = None if timeout is None else time.time() + timeout
+    with self._state.condition:
+      while True:
+        if self._state.code is None:
+          _wait_once_until(self._state.condition, until)
+        elif self._state.code is grpc.StatusCode.OK:
+          return None
+        elif self._state.cancelled:
+          raise grpc.FutureCancelledError()
+        else:
+          try:
+            raise self
+          except grpc.RpcError:
+            return sys.exc_info()[2]
+
+  def add_done_callback(self, fn):
+    with self._state.condition:
+      if self._state.code is None:
+        self._state.callbacks.append(lambda: fn(self))
+        return
+
+    fn(self)
+
+  def _next(self):
+    with self._state.condition:
+      if self._state.code is None:
+        event_handler = _event_handler(
+            self._state, self._call, self._response_deserializer)
+        self._call.start_batch(
+            cygrpc.Operations(
+                (cygrpc.operation_receive_message(_EMPTY_FLAGS),)),
+            event_handler)
+        self._state.due.add(cygrpc.OperationType.receive_message)
+      elif self._state.code is grpc.StatusCode.OK:
+        raise StopIteration()
+      else:
+        raise self
+      while True:
+        self._state.condition.wait()
+        if self._state.response is not None:
+          response = self._state.response
+          self._state.response = None
+          return response
+        elif cygrpc.OperationType.receive_message not in self._state.due:
+          if self._state.code is grpc.StatusCode.OK:
+            raise StopIteration()
+          elif self._state.code is not None:
+            raise self
+
+  def __iter__(self):
+    return self
+
+  def __next__(self):
+    return self._next()
+
+  def next(self):
+    return self._next()
+
+  def is_active(self):
+    with self._state.condition:
+      return self._state.code is None
+
+  def time_remaining(self):
+    if self._deadline is None:
+      return None
+    else:
+      return max(self._deadline - time.time(), 0)
+
+  def add_cancellation_callback(self, callback):
+    with self._state.condition:
+      if self._state.callbacks is None:
+        return False
+      else:
+        self._state.callbacks.append(lambda unused_future: callback())
+        return True
+
+  def initial_metadata(self):
+    with self._state.condition:
+      while self._state.initial_metadata is None:
+        self._state.condition.wait()
+      return self._state.initial_metadata
+
+  def trailing_metadata(self):
+    with self._state.condition:
+      while self._state.trailing_metadata is None:
+        self._state.condition.wait()
+      return self._state.trailing_metadata
+
+  def code(self):
+    with self._state.condition:
+      while self._state.code is None:
+        self._state.condition.wait()
+      return self._state.code
+
+  def details(self):
+    with self._state.condition:
+      while self._state.details is None:
+        self._state.condition.wait()
+      return self._state.details
+
+  def _repr(self):
+    with self._state.condition:
+      if self._state.code is None:
+        return '<_Rendezvous object of in-flight RPC>'
+      else:
+        return '<_Rendezvous of RPC that terminated with ({}, {})>'.format(
+            self._state.code, self._state.details)
+
+  def __repr__(self):
+    return self._repr()
+
+  def __str__(self):
+    return self._repr()
+
+  def __del__(self):
+    with self._state.condition:
+      if self._state.code is None:
+        self._call.cancel()
+        self._state.cancelled = True
+        self._state.code = grpc.StatusCode.CANCELLED
+        self._state.condition.notify_all()
+
+
+def _start_unary_request(request, timeout, request_serializer):
+  deadline, deadline_timespec = _deadline(timeout)
+  serialized_request = _common.serialize(request, request_serializer)
+  if serialized_request is None:
+    state = _RPCState(
+        (), _EMPTY_METADATA, _EMPTY_METADATA, grpc.StatusCode.INTERNAL,
+        'Exception serializing request!')
+    rendezvous = _Rendezvous(state, None, None, deadline)
+    return deadline, deadline_timespec, None, rendezvous
+  else:
+    return deadline, deadline_timespec, serialized_request, None
+
+
+def _end_unary_response_blocking(state, with_call, deadline):
+  if state.code is grpc.StatusCode.OK:
+    if with_call:
+      rendezvous = _Rendezvous(state, None, None, deadline)
+      return state.response, rendezvous
+    else:
+      return state.response
+  else:
+    raise _Rendezvous(state, None, None, deadline)
+
+
+class _UnaryUnaryMultiCallable(grpc.UnaryUnaryMultiCallable):
+
+  def __init__(
+      self, channel, create_managed_call, method, request_serializer,
+      response_deserializer):
+    self._channel = channel
+    self._create_managed_call = create_managed_call
+    self._method = method
+    self._request_serializer = request_serializer
+    self._response_deserializer = response_deserializer
+
+  def _prepare(self, request, timeout, metadata):
+    deadline, deadline_timespec, serialized_request, rendezvous = (
+        _start_unary_request(request, timeout, self._request_serializer))
+    if serialized_request is None:
+      return None, None, None, None, rendezvous
+    else:
+      state = _RPCState(_UNARY_UNARY_INITIAL_DUE, None, None, None, None)
+      operations = (
+          cygrpc.operation_send_initial_metadata(
+              _common.metadata(metadata), _EMPTY_FLAGS),
+          cygrpc.operation_send_message(serialized_request, _EMPTY_FLAGS),
+          cygrpc.operation_send_close_from_client(_EMPTY_FLAGS),
+          cygrpc.operation_receive_initial_metadata(_EMPTY_FLAGS),
+          cygrpc.operation_receive_message(_EMPTY_FLAGS),
+          cygrpc.operation_receive_status_on_client(_EMPTY_FLAGS),
+      )
+      return state, operations, deadline, deadline_timespec, None
+
+  def __call__(
+      self, request, timeout=None, metadata=None, credentials=None,
+      with_call=False):
+    state, operations, deadline, deadline_timespec, rendezvous = self._prepare(
+        request, timeout, metadata)
+    if rendezvous:
+      raise rendezvous
+    else:
+      completion_queue = cygrpc.CompletionQueue()
+      call = self._channel.create_call(
+          None, 0, completion_queue, self._method, None, deadline_timespec)
+      if credentials is not None:
+        call.set_credentials(credentials._credentials)
+      call.start_batch(cygrpc.Operations(operations), None)
+      _handle_event(completion_queue.poll(), state, self._response_deserializer)
+      return _end_unary_response_blocking(state, with_call, deadline)
+
+  def future(self, request, timeout=None, metadata=None, credentials=None):
+    state, operations, deadline, deadline_timespec, rendezvous = self._prepare(
+        request, timeout, metadata)
+    if rendezvous:
+      return rendezvous
+    else:
+      call = self._create_managed_call(
+          None, 0, self._method, None, deadline_timespec)
+      if credentials is not None:
+        call.set_credentials(credentials._credentials)
+      event_handler = _event_handler(state, call, self._response_deserializer)
+      with state.condition:
+        call.start_batch(cygrpc.Operations(operations), event_handler)
+      return _Rendezvous(state, call, self._response_deserializer, deadline)
+
+
+class _UnaryStreamMultiCallable(grpc.UnaryStreamMultiCallable):
+
+  def __init__(
+      self, channel, create_managed_call, method, request_serializer,
+      response_deserializer):
+    self._channel = channel
+    self._create_managed_call = create_managed_call
+    self._method = method
+    self._request_serializer = request_serializer
+    self._response_deserializer = response_deserializer
+
+  def __call__(self, request, timeout=None, metadata=None, credentials=None):
+    deadline, deadline_timespec, serialized_request, rendezvous = (
+        _start_unary_request(request, timeout, self._request_serializer))
+    if serialized_request is None:
+      raise rendezvous
+    else:
+      state = _RPCState(_UNARY_STREAM_INITIAL_DUE, None, None, None, None)
+      call = self._create_managed_call(
+          None, 0, self._method, None, deadline_timespec)
+      if credentials is not None:
+        call.set_credentials(credentials._credentials)
+      event_handler = _event_handler(state, call, self._response_deserializer)
+      with state.condition:
+        call.start_batch(
+            cygrpc.Operations(
+                (cygrpc.operation_receive_initial_metadata(_EMPTY_FLAGS),)),
+            event_handler)
+        operations = (
+            cygrpc.operation_send_initial_metadata(
+                _common.metadata(metadata), _EMPTY_FLAGS),
+            cygrpc.operation_send_message(serialized_request, _EMPTY_FLAGS),
+            cygrpc.operation_send_close_from_client(_EMPTY_FLAGS),
+            cygrpc.operation_receive_status_on_client(_EMPTY_FLAGS),
+        )
+        call.start_batch(cygrpc.Operations(operations), event_handler)
+      return _Rendezvous(state, call, self._response_deserializer, deadline)
+
+
+class _StreamUnaryMultiCallable(grpc.StreamUnaryMultiCallable):
+
+  def __init__(
+      self, channel, create_managed_call, method, request_serializer,
+      response_deserializer):
+    self._channel = channel
+    self._create_managed_call = create_managed_call
+    self._method = method
+    self._request_serializer = request_serializer
+    self._response_deserializer = response_deserializer
+
+  def __call__(
+      self, request_iterator, timeout=None, metadata=None, credentials=None,
+      with_call=False):
+    deadline, deadline_timespec = _deadline(timeout)
+    state = _RPCState(_STREAM_UNARY_INITIAL_DUE, None, None, None, None)
+    completion_queue = cygrpc.CompletionQueue()
+    call = self._channel.create_call(
+        None, 0, completion_queue, self._method, None, deadline_timespec)
+    if credentials is not None:
+      call.set_credentials(credentials._credentials)
+    with state.condition:
+      call.start_batch(
+          cygrpc.Operations(
+              (cygrpc.operation_receive_initial_metadata(_EMPTY_FLAGS),)),
+          None)
+      operations = (
+          cygrpc.operation_send_initial_metadata(
+              _common.metadata(metadata), _EMPTY_FLAGS),
+          cygrpc.operation_receive_message(_EMPTY_FLAGS),
+          cygrpc.operation_receive_status_on_client(_EMPTY_FLAGS),
+      )
+      call.start_batch(cygrpc.Operations(operations), None)
+      _consume_request_iterator(
+          request_iterator, state, call, self._request_serializer)
+    while True:
+      event = completion_queue.poll()
+      with state.condition:
+        _handle_event(event, state, self._response_deserializer)
+        state.condition.notify_all()
+        if not state.due:
+          break
+    return _end_unary_response_blocking(state, with_call, deadline)
+
+  def future(
+      self, request_iterator, timeout=None, metadata=None, credentials=None):
+    deadline, deadline_timespec = _deadline(timeout)
+    state = _RPCState(_STREAM_UNARY_INITIAL_DUE, None, None, None, None)
+    call = self._create_managed_call(
+        None, 0, self._method, None, deadline_timespec)
+    if credentials is not None:
+      call.set_credentials(credentials._credentials)
+    event_handler = _event_handler(state, call, self._response_deserializer)
+    with state.condition:
+      call.start_batch(
+          cygrpc.Operations(
+              (cygrpc.operation_receive_initial_metadata(_EMPTY_FLAGS),)),
+          event_handler)
+      operations = (
+          cygrpc.operation_send_initial_metadata(
+              _common.metadata(metadata), _EMPTY_FLAGS),
+          cygrpc.operation_receive_message(_EMPTY_FLAGS),
+          cygrpc.operation_receive_status_on_client(_EMPTY_FLAGS),
+      )
+      call.start_batch(cygrpc.Operations(operations), event_handler)
+      _consume_request_iterator(
+          request_iterator, state, call, self._request_serializer)
+    return _Rendezvous(state, call, self._response_deserializer, deadline)
+
+
+class _StreamStreamMultiCallable(grpc.StreamStreamMultiCallable):
+
+  def __init__(
+      self, channel, create_managed_call, method, request_serializer,
+      response_deserializer):
+    self._channel = channel
+    self._create_managed_call = create_managed_call
+    self._method = method
+    self._request_serializer = request_serializer
+    self._response_deserializer = response_deserializer
+
+  def __call__(
+      self, request_iterator, timeout=None, metadata=None, credentials=None):
+    deadline, deadline_timespec = _deadline(timeout)
+    state = _RPCState(_STREAM_STREAM_INITIAL_DUE, None, None, None, None)
+    call = self._create_managed_call(
+        None, 0, self._method, None, deadline_timespec)
+    if credentials is not None:
+      call.set_credentials(credentials._credentials)
+    event_handler = _event_handler(state, call, self._response_deserializer)
+    with state.condition:
+      call.start_batch(
+          cygrpc.Operations(
+              (cygrpc.operation_receive_initial_metadata(_EMPTY_FLAGS),)),
+          event_handler)
+      operations = (
+          cygrpc.operation_send_initial_metadata(
+              _common.metadata(metadata), _EMPTY_FLAGS),
+          cygrpc.operation_receive_status_on_client(_EMPTY_FLAGS),
+      )
+      call.start_batch(cygrpc.Operations(operations), event_handler)
+      _consume_request_iterator(
+          request_iterator, state, call, self._request_serializer)
+    return _Rendezvous(state, call, self._response_deserializer, deadline)
+
+
+class _ChannelCallState(object):
+
+  def __init__(self, channel):
+    self.lock = threading.Lock()
+    self.channel = channel
+    self.completion_queue = cygrpc.CompletionQueue()
+    self.managed_calls = None
+
+
+def _call_spin(state):
+  while True:
+    event = state.completion_queue.poll()
+    completed_call = event.tag(event)
+    if completed_call is not None:
+      with state.lock:
+        state.managed_calls.remove(completed_call)
+        if not state.managed_calls:
+          state.managed_calls = None
+          return
+
+
+def _create_channel_managed_call(state):
+  def create_channel_managed_call(parent, flags, method, host, deadline):
+    """Creates a managed cygrpc.Call.
+
+    Callers of this function must conduct at least one operation on the returned
+    call. The tags associated with operations conducted on the returned call
+    must be no-argument callables that return None to indicate that this channel
+    should continue polling for events associated with the call and return the
+    call itself to indicate that no more events associated with the call will be
+    generated.
+
+    Args:
+      parent: A cygrpc.Call to be used as the parent of the created call.
+      flags: An integer bitfield of call flags.
+      method: The RPC method.
+      host: A host string for the created call.
+      deadline: A cygrpc.Timespec to be the deadline of the created call.
+
+    Returns:
+      A cygrpc.Call with which to conduct an RPC.
+    """
+    with state.lock:
+      call = state.channel.create_call(
+          parent, flags, state.completion_queue, method, host, deadline)
+      if state.managed_calls is None:
+        state.managed_calls = set((call,))
+        spin_thread = threading.Thread(target=_call_spin, args=(state,))
+        spin_thread.start()
+      else:
+        state.managed_calls.add(call)
+      return call
+  return create_channel_managed_call
+
+
+class _ChannelConnectivityState(object):
+
+  def __init__(self, channel):
+    self.lock = threading.Lock()
+    self.channel = channel
+    self.polling = False
+    self.connectivity = None
+    self.try_to_connect = False
+    self.callbacks_and_connectivities = []
+    self.delivering = False
+
+
+def _deliveries(state):
+  callbacks_needing_update = []
+  for callback_and_connectivity in state.callbacks_and_connectivities:
+    callback, callback_connectivity, = callback_and_connectivity
+    if callback_connectivity is not state.connectivity:
+      callbacks_needing_update.append(callback)
+      callback_and_connectivity[1] = state.connectivity
+  return callbacks_needing_update
+
+
+def _deliver(state, initial_connectivity, initial_callbacks):
+  connectivity = initial_connectivity
+  callbacks = initial_callbacks
+  while True:
+    for callback in callbacks:
+      callable_util.call_logging_exceptions(
+          callback, _CHANNEL_SUBSCRIPTION_CALLBACK_ERROR_LOG_MESSAGE,
+          connectivity)
+    with state.lock:
+      callbacks = _deliveries(state)
+      if callbacks:
+        connectivity = state.connectivity
+      else:
+        state.delivering = False
+        return
+
+
+def _spawn_delivery(state, callbacks):
+  delivering_thread = threading.Thread(
+      target=_deliver, args=(state, state.connectivity, callbacks,))
+  delivering_thread.start()
+  state.delivering = True
+
+
+# NOTE(https://github.com/grpc/grpc/issues/3064): We'd rather not poll.
+def _poll_connectivity(state, channel, initial_try_to_connect):
+  try_to_connect = initial_try_to_connect
+  connectivity = channel.check_connectivity_state(try_to_connect)
+  with state.lock:
+    state.connectivity = (
+        _common.CYGRPC_CONNECTIVITY_STATE_TO_CHANNEL_CONNECTIVITY[
+            connectivity])
+    callbacks = tuple(
+        callback for callback, unused_but_known_to_be_none_connectivity
+        in state.callbacks_and_connectivities)
+    for callback_and_connectivity in state.callbacks_and_connectivities:
+      callback_and_connectivity[1] = state.connectivity
+    if callbacks:
+      _spawn_delivery(state, callbacks)
+  completion_queue = cygrpc.CompletionQueue()
+  while True:
+    channel.watch_connectivity_state(
+        connectivity, cygrpc.Timespec(time.time() + 0.2),
+        completion_queue, None)
+    event = completion_queue.poll()
+    with state.lock:
+      if not state.callbacks_and_connectivities and not state.try_to_connect:
+        state.polling = False
+        state.connectivity = None
+        break
+      try_to_connect = state.try_to_connect
+      state.try_to_connect = False
+    if event.success or try_to_connect:
+      connectivity = channel.check_connectivity_state(try_to_connect)
+      with state.lock:
+        state.connectivity = (
+            _common.CYGRPC_CONNECTIVITY_STATE_TO_CHANNEL_CONNECTIVITY[
+                connectivity])
+        if not state.delivering:
+          callbacks = _deliveries(state)
+          if callbacks:
+            _spawn_delivery(state, callbacks)
+
+
+def _subscribe(state, callback, try_to_connect):
+  with state.lock:
+    if not state.callbacks_and_connectivities and not state.polling:
+      polling_thread = threading.Thread(
+          target=_poll_connectivity,
+          args=(state, state.channel, bool(try_to_connect)))
+      polling_thread.start()
+      state.polling = True
+      state.callbacks_and_connectivities.append([callback, None])
+    elif not state.delivering and state.connectivity is not None:
+      _spawn_delivery(state, (callback,))
+      state.try_to_connect |= bool(try_to_connect)
+      state.callbacks_and_connectivities.append(
+          [callback, state.connectivity])
+    else:
+      state.try_to_connect |= bool(try_to_connect)
+      state.callbacks_and_connectivities.append([callback, None])
+
+
+def _unsubscribe(state, callback):
+  with state.lock:
+    for index, (subscribed_callback, unused_connectivity) in enumerate(
+        state.callbacks_and_connectivities):
+      if callback == subscribed_callback:
+        state.callbacks_and_connectivities.pop(index)
+        break
+
+
+def _moot(state):
+  with state.lock:
+    del state.callbacks_and_connectivities[:]
+
+
+def _options(options):
+  if options is None:
+    pairs = ((cygrpc.ChannelArgKey.primary_user_agent_string, _USER_AGENT),)
+  else:
+    pairs = list(options) + [
+        (cygrpc.ChannelArgKey.primary_user_agent_string, _USER_AGENT)]
+  return cygrpc.ChannelArgs(
+      cygrpc.ChannelArg(arg_name, arg_value) for arg_name, arg_value in pairs)
+
+
+class Channel(grpc.Channel):
+
+  def __init__(self, target, options, credentials):
+    self._channel = cygrpc.Channel(target, _options(options), credentials)
+    self._call_state = _ChannelCallState(self._channel)
+    self._connectivity_state = _ChannelConnectivityState(self._channel)
+
+  def subscribe(self, callback, try_to_connect=None):
+    _subscribe(self._connectivity_state, callback, try_to_connect)
+
+  def unsubscribe(self, callback):
+    _unsubscribe(self._connectivity_state, callback)
+
+  def unary_unary(
+      self, method, request_serializer=None, response_deserializer=None):
+    return _UnaryUnaryMultiCallable(
+        self._channel, _create_channel_managed_call(self._call_state), method,
+        request_serializer, response_deserializer)
+
+  def unary_stream(
+      self, method, request_serializer=None, response_deserializer=None):
+    return _UnaryStreamMultiCallable(
+        self._channel, _create_channel_managed_call(self._call_state), method,
+        request_serializer, response_deserializer)
+
+  def stream_unary(
+      self, method, request_serializer=None, response_deserializer=None):
+    return _StreamUnaryMultiCallable(
+        self._channel, _create_channel_managed_call(self._call_state), method,
+        request_serializer, response_deserializer)
+
+  def stream_stream(
+      self, method, request_serializer=None, response_deserializer=None):
+    return _StreamStreamMultiCallable(
+        self._channel, _create_channel_managed_call(self._call_state), method,
+        request_serializer, response_deserializer)
+
+  def __del__(self):
+    _moot(self._connectivity_state)
diff --git a/src/python/grpcio/grpc/_common.py b/src/python/grpcio/grpc/_common.py
new file mode 100644
index 0000000..b8688a0
--- /dev/null
+++ b/src/python/grpcio/grpc/_common.py
@@ -0,0 +1,112 @@
+# 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.
+
+"""Shared implementation."""
+
+import logging
+
+import six
+
+import grpc
+from grpc._cython import cygrpc
+
+_EMPTY_METADATA = cygrpc.Metadata(())
+
+CYGRPC_CONNECTIVITY_STATE_TO_CHANNEL_CONNECTIVITY = {
+    cygrpc.ConnectivityState.idle: grpc.ChannelConnectivity.IDLE,
+    cygrpc.ConnectivityState.connecting: grpc.ChannelConnectivity.CONNECTING,
+    cygrpc.ConnectivityState.ready: grpc.ChannelConnectivity.READY,
+    cygrpc.ConnectivityState.transient_failure:
+        grpc.ChannelConnectivity.TRANSIENT_FAILURE,
+    cygrpc.ConnectivityState.fatal_failure:
+        grpc.ChannelConnectivity.FATAL_FAILURE,
+}
+
+CYGRPC_STATUS_CODE_TO_STATUS_CODE = {
+    cygrpc.StatusCode.ok: grpc.StatusCode.OK,
+    cygrpc.StatusCode.cancelled: grpc.StatusCode.CANCELLED,
+    cygrpc.StatusCode.unknown: grpc.StatusCode.UNKNOWN,
+    cygrpc.StatusCode.invalid_argument: grpc.StatusCode.INVALID_ARGUMENT,
+    cygrpc.StatusCode.deadline_exceeded: grpc.StatusCode.DEADLINE_EXCEEDED,
+    cygrpc.StatusCode.not_found: grpc.StatusCode.NOT_FOUND,
+    cygrpc.StatusCode.already_exists: grpc.StatusCode.ALREADY_EXISTS,
+    cygrpc.StatusCode.permission_denied: grpc.StatusCode.PERMISSION_DENIED,
+    cygrpc.StatusCode.unauthenticated: grpc.StatusCode.UNAUTHENTICATED,
+    cygrpc.StatusCode.resource_exhausted: grpc.StatusCode.RESOURCE_EXHAUSTED,
+    cygrpc.StatusCode.failed_precondition: grpc.StatusCode.FAILED_PRECONDITION,
+    cygrpc.StatusCode.aborted: grpc.StatusCode.ABORTED,
+    cygrpc.StatusCode.out_of_range: grpc.StatusCode.OUT_OF_RANGE,
+    cygrpc.StatusCode.unimplemented: grpc.StatusCode.UNIMPLEMENTED,
+    cygrpc.StatusCode.internal: grpc.StatusCode.INTERNAL,
+    cygrpc.StatusCode.unavailable: grpc.StatusCode.UNAVAILABLE,
+    cygrpc.StatusCode.data_loss: grpc.StatusCode.DATA_LOSS,
+}
+STATUS_CODE_TO_CYGRPC_STATUS_CODE = {
+    grpc_code: cygrpc_code
+    for cygrpc_code, grpc_code in six.iteritems(
+        CYGRPC_STATUS_CODE_TO_STATUS_CODE)
+}
+
+
+def metadata(application_metadata):
+  return _EMPTY_METADATA if application_metadata is None else cygrpc.Metadata(
+      cygrpc.Metadatum(key, value) for key, value in application_metadata)
+
+
+def _transform(message, transformer, exception_message):
+  if transformer is None:
+    return message
+  else:
+    try:
+      return transformer(message)
+    except Exception:  # pylint: disable=broad-except
+      logging.exception(exception_message)
+      return None
+
+
+def serialize(message, serializer):
+  return _transform(message, serializer, 'Exception serializing message!')
+
+
+def deserialize(serialized_message, deserializer):
+  return _transform(serialized_message, deserializer,
+                    'Exception deserializing message!')
+
+
+def _encode(s):
+  if isinstance(s, bytes):
+    return s
+  else:
+    return s.encode('ascii')
+
+
+def fully_qualified_method(group, method):
+  group = _encode(group)
+  method = _encode(method)
+  return b'/' + group + b'/' + method
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/call.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/call.pyx.pxi
index 1bfe634..a09bbc7 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/call.pyx.pxi
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/call.pyx.pxi
@@ -55,6 +55,7 @@
   def cancel(
       self, grpc_status_code error_code=GRPC_STATUS__DO_NOT_USE,
       details=None):
+    details = str_to_bytes(details)
     if not self.is_valid:
       raise ValueError("invalid call object cannot be used from Python")
     if (details is None) != (error_code == GRPC_STATUS__DO_NOT_USE):
@@ -63,12 +64,6 @@
     cdef grpc_call_error result
     cdef char *c_details = NULL
     if error_code != GRPC_STATUS__DO_NOT_USE:
-      if isinstance(details, bytes):
-        pass
-      elif isinstance(details, basestring):
-        details = details.encode()
-      else:
-        raise TypeError("expected details to be str or bytes")
       self.references.append(details)
       c_details = details
       with nogil:
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi
index c26bc08..866cff0 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi
@@ -34,18 +34,13 @@
 
   def __cinit__(self, target, ChannelArgs arguments=None,
                 ChannelCredentials channel_credentials=None):
+    target = str_to_bytes(target)
     cdef grpc_channel_args *c_arguments = NULL
     cdef char *c_target = NULL
     self.c_channel = NULL
     self.references = []
     if arguments is not None:
       c_arguments = &arguments.c_args
-    if isinstance(target, bytes):
-      pass
-    elif isinstance(target, basestring):
-      target = target.encode()
-    else:
-      raise TypeError("expected target to be str or bytes")
     c_target = target
     if channel_credentials is None:
       with nogil:
@@ -62,25 +57,14 @@
   def create_call(self, Call parent, int flags,
                   CompletionQueue queue not None,
                   method, host, Timespec deadline not None):
+    method = str_to_bytes(method)
+    host = str_to_bytes(host)
     if queue.is_shutting_down:
       raise ValueError("queue must not be shutting down or shutdown")
-    if isinstance(method, bytes):
-      pass
-    elif isinstance(method, basestring):
-      method = method.encode()
-    else:
-      raise TypeError("expected method to be str or bytes")
     cdef char *method_c_string = method
     cdef char *host_c_string = NULL
-    if host is None:
-      pass
-    elif isinstance(host, bytes):
+    if host is not None:
       host_c_string = host
-    elif isinstance(host, basestring):
-      host = host.encode()
-      host_c_string = host
-    else:
-      raise TypeError("expected host to be str, bytes, or None")
     cdef Call operation_call = Call()
     operation_call.references = [self, method, host, queue]
     cdef grpc_call *parent_call = NULL
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pxd.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pxd.pxi
index c793c8f..d377a67 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pxd.pxi
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pxd.pxi
@@ -54,7 +54,7 @@
 cdef class CredentialsMetadataPlugin:
 
   cdef object plugin_callback
-  cdef str plugin_name
+  cdef bytes plugin_name
 
   cdef grpc_metadata_credentials_plugin make_c_plugin(self)
 
@@ -68,4 +68,4 @@
     void *state, grpc_auth_metadata_context context,
     grpc_credentials_plugin_metadata_cb cb, void *user_data) with gil
 
-cdef void plugin_destroy_c_plugin_state(void *state)
+cdef void plugin_destroy_c_plugin_state(void *state) with gil
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi
index 94d13b5..470382d 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi
@@ -82,7 +82,7 @@
 
 cdef class CredentialsMetadataPlugin:
 
-  def __cinit__(self, object plugin_callback, str name):
+  def __cinit__(self, object plugin_callback, name):
     """
     Args:
       plugin_callback (callable): Callback accepting a service URL (str/bytes)
@@ -93,6 +93,7 @@
         successful).
       name (str): Plugin name.
     """
+    name = str_to_bytes(name)
     if not callable(plugin_callback):
       raise ValueError('expected callable plugin_callback')
     self.plugin_callback = plugin_callback
@@ -129,7 +130,8 @@
     grpc_credentials_plugin_metadata_cb cb, void *user_data) with gil:
   def python_callback(
       Metadata metadata, grpc_status_code status,
-      const char *error_details):
+      error_details):
+    error_details = str_to_bytes(error_details)
     cb(user_data, metadata.c_metadata_array.metadata,
        metadata.c_metadata_array.count, status, error_details)
   cdef CredentialsMetadataPlugin self = <CredentialsMetadataPlugin>state
@@ -137,7 +139,7 @@
   cy_context.context = context
   self.plugin_callback(cy_context, python_callback)
 
-cdef void plugin_destroy_c_plugin_state(void *state):
+cdef void plugin_destroy_c_plugin_state(void *state) with gil:
   cpython.Py_DECREF(<CredentialsMetadataPlugin>state)
 
 def channel_credentials_google_default():
@@ -148,14 +150,7 @@
 
 def channel_credentials_ssl(pem_root_certificates,
                             SslPemKeyCertPair ssl_pem_key_cert_pair):
-  if pem_root_certificates is None:
-    pass
-  elif isinstance(pem_root_certificates, bytes):
-    pass
-  elif isinstance(pem_root_certificates, basestring):
-    pem_root_certificates = pem_root_certificates.encode()
-  else:
-    raise TypeError("expected str or bytes for pem_root_certificates")
+  pem_root_certificates = str_to_bytes(pem_root_certificates)
   cdef ChannelCredentials credentials = ChannelCredentials()
   cdef const char *c_pem_root_certificates = NULL
   if pem_root_certificates is not None:
@@ -207,12 +202,7 @@
 
 def call_credentials_service_account_jwt_access(
     json_key, Timespec token_lifetime not None):
-  if isinstance(json_key, bytes):
-    pass
-  elif isinstance(json_key, basestring):
-    json_key = json_key.encode()
-  else:
-    raise TypeError("expected json_key to be str or bytes")
+  json_key = str_to_bytes(json_key)
   cdef CallCredentials credentials = CallCredentials()
   cdef char *json_key_c_string = json_key
   with nogil:
@@ -223,12 +213,7 @@
   return credentials
 
 def call_credentials_google_refresh_token(json_refresh_token):
-  if isinstance(json_refresh_token, bytes):
-    pass
-  elif isinstance(json_refresh_token, basestring):
-    json_refresh_token = json_refresh_token.encode()
-  else:
-    raise TypeError("expected json_refresh_token to be str or bytes")
+  json_refresh_token = str_to_bytes(json_refresh_token)
   cdef CallCredentials credentials = CallCredentials()
   cdef char *json_refresh_token_c_string = json_refresh_token
   with nogil:
@@ -238,18 +223,8 @@
   return credentials
 
 def call_credentials_google_iam(authorization_token, authority_selector):
-  if isinstance(authorization_token, bytes):
-    pass
-  elif isinstance(authorization_token, basestring):
-    authorization_token = authorization_token.encode()
-  else:
-    raise TypeError("expected authorization_token to be str or bytes")
-  if isinstance(authority_selector, bytes):
-    pass
-  elif isinstance(authority_selector, basestring):
-    authority_selector = authority_selector.encode()
-  else:
-    raise TypeError("expected authority_selector to be str or bytes")
+  authorization_token = str_to_bytes(authorization_token)
+  authority_selector = str_to_bytes(authority_selector)
   cdef CallCredentials credentials = CallCredentials()
   cdef char *authorization_token_c_string = authorization_token
   cdef char *authority_selector_c_string = authority_selector
@@ -272,16 +247,10 @@
 
 def server_credentials_ssl(pem_root_certs, pem_key_cert_pairs,
                            bint force_client_auth):
+  pem_root_certs = str_to_bytes(pem_root_certs)
   cdef char *c_pem_root_certs = NULL
-  if pem_root_certs is None:
-    pass
-  elif isinstance(pem_root_certs, bytes):
+  if pem_root_certs is not None: 
     c_pem_root_certs = pem_root_certs
-  elif isinstance(pem_root_certs, basestring):
-    pem_root_certs = pem_root_certs.encode()
-    c_pem_root_certs = pem_root_certs
-  else:
-    raise TypeError("expected pem_root_certs to be str or bytes")
   pem_key_cert_pairs = list(pem_key_cert_pairs)
   for pair in pem_key_cert_pairs:
     if not isinstance(pair, SslPemKeyCertPair):
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi
index 66e6e6b..05b8886 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi
@@ -208,7 +208,7 @@
     GRPC_CHANNEL_CONNECTING
     GRPC_CHANNEL_READY
     GRPC_CHANNEL_TRANSIENT_FAILURE
-    GRPC_CHANNEL_FATAL_FAILURE
+    GRPC_CHANNEL_SHUTDOWN
 
   ctypedef struct grpc_metadata:
     const char *key
@@ -336,6 +336,8 @@
   void grpc_server_register_completion_queue(grpc_server *server,
                                              grpc_completion_queue *cq,
                                              void *reserved) nogil
+  void grpc_server_register_non_listening_completion_queue(
+      grpc_server *server, grpc_completion_queue *cq, void *reserved) nogil
   int grpc_server_add_insecure_http2_port(
       grpc_server *server, const char *addr) nogil
   void grpc_server_start(grpc_server *server) nogil
diff --git a/src/python/grpcio/grpc/_adapter/_implementations.py b/src/python/grpcio/grpc/_cython/_cygrpc/grpc_string.pyx.pxi
similarity index 75%
copy from src/python/grpcio/grpc/_adapter/_implementations.py
copy to src/python/grpcio/grpc/_cython/_cygrpc/grpc_string.pyx.pxi
index b85f228..274f038 100644
--- a/src/python/grpcio/grpc/_adapter/_implementations.py
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/grpc_string.pyx.pxi
@@ -1,4 +1,4 @@
-# Copyright 2015, Google Inc.
+# Copyright 2016, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
@@ -27,22 +27,13 @@
 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-import collections
 
-from grpc.beta import interfaces
-
-class AuthMetadataContext(collections.namedtuple(
-    'AuthMetadataContext', [
-        'service_url',
-        'method_name'
-    ]), interfaces.GRPCAuthMetadataContext):
-  pass
-
-
-class AuthMetadataPluginCallback(interfaces.GRPCAuthMetadataContext):
-
-  def __init__(self, callback):
-    self._callback = callback
-
-  def __call__(self, metadata, error):
-    self._callback(metadata, error)
+# This function will ascii encode unicode string inputs if neccesary.
+# In Python3, unicode strings are the default str type.
+cdef bytes str_to_bytes(object s):
+  if s is None or isinstance(s, bytes):
+    return s
+  elif isinstance(s, unicode):
+    return s.encode('ascii')
+  else:
+    raise TypeError('Expected bytes, str, or unicode, not {}'.format(type(s)))
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/records.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/records.pyx.pxi
index c7539f0..2e52953 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/records.pyx.pxi
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/records.pyx.pxi
@@ -33,7 +33,7 @@
   connecting = GRPC_CHANNEL_CONNECTING
   ready = GRPC_CHANNEL_READY
   transient_failure = GRPC_CHANNEL_TRANSIENT_FAILURE
-  fatal_failure = GRPC_CHANNEL_FATAL_FAILURE
+  fatal_failure = GRPC_CHANNEL_SHUTDOWN
 
 
 class ChannelArgKey:
@@ -235,18 +235,13 @@
     if data is None:
       self.c_byte_buffer = NULL
       return
-    if isinstance(data, bytes):
-      pass
-    elif isinstance(data, basestring):
-      data = data.encode()
-    elif isinstance(data, ByteBuffer):
+    if isinstance(data, ByteBuffer):
       data = (<ByteBuffer>data).bytes()
       if data is None:
         self.c_byte_buffer = NULL
         return
     else:
-      raise TypeError("expected value to be of type str, bytes, or "
-                      "ByteBuffer, not {}".format(type(data)))
+      data = str_to_bytes(data)
 
     cdef char *c_data = data
     cdef gpr_slice data_slice
@@ -274,6 +269,7 @@
           data_slice_length = gpr_slice_length(data_slice)
           with gil:
             result += (<char *>data_slice_pointer)[:data_slice_length]
+          gpr_slice_unref(data_slice)
       with nogil:
         grpc_byte_buffer_reader_destroy(&reader)
       return bytes(result)
@@ -301,19 +297,8 @@
 cdef class SslPemKeyCertPair:
 
   def __cinit__(self, private_key, certificate_chain):
-    if isinstance(private_key, bytes):
-      self.private_key = private_key
-    elif isinstance(private_key, basestring):
-      self.private_key = private_key.encode()
-    else:
-      raise TypeError("expected private_key to be of type str or bytes")
-    if isinstance(certificate_chain, bytes):
-      self.certificate_chain = certificate_chain
-    elif isinstance(certificate_chain, basestring):
-      self.certificate_chain = certificate_chain.encode()
-    else:
-      raise TypeError("expected certificate_chain to be of type str or bytes "
-                      "or int")
+    self.private_key = str_to_bytes(private_key)
+    self.certificate_chain = str_to_bytes(certificate_chain)
     self.c_pair.private_key = self.private_key
     self.c_pair.certificate_chain = self.certificate_chain
 
@@ -321,27 +306,16 @@
 cdef class ChannelArg:
 
   def __cinit__(self, key, value):
-    if isinstance(key, bytes):
-      self.key = key
-    elif isinstance(key, basestring):
-      self.key = key.encode()
-    else:
-      raise TypeError("expected key to be of type str or bytes")
-    if isinstance(value, bytes):
-      self.value = value
-      self.c_arg.type = GRPC_ARG_STRING
-      self.c_arg.value.string = self.value
-    elif isinstance(value, basestring):
-      self.value = value.encode()
-      self.c_arg.type = GRPC_ARG_STRING
-      self.c_arg.value.string = self.value
-    elif isinstance(value, int):
+    self.key = str_to_bytes(key)
+    self.c_arg.key = self.key
+    if isinstance(value, int):
       self.value = int(value)
       self.c_arg.type = GRPC_ARG_INTEGER
       self.c_arg.value.integer = self.value
     else:
-      raise TypeError("expected value to be of type str or bytes or int")
-    self.c_arg.key = self.key
+      self.value = str_to_bytes(value)
+      self.c_arg.type = GRPC_ARG_STRING
+      self.c_arg.value.string = self.value
 
 
 cdef class ChannelArgs:
@@ -374,18 +348,8 @@
 cdef class Metadatum:
 
   def __cinit__(self, key, value):
-    if isinstance(key, bytes):
-      self._key = key
-    elif isinstance(key, basestring):
-      self._key = key.encode()
-    else:
-      raise TypeError("expected key to be of type str or bytes")
-    if isinstance(value, bytes):
-      self._value = value
-    elif isinstance(value, basestring):
-      self._value = value.encode()
-    else:
-      raise TypeError("expected value to be of type str or bytes")
+    self._key = str_to_bytes(key)
+    self._value = str_to_bytes(value)
     self.c_metadata.key = self._key
     self.c_metadata.value = self._value
     self.c_metadata.value_length = len(self._value)
@@ -600,12 +564,7 @@
 
 def operation_send_status_from_server(
     Metadata metadata, grpc_status_code code, details, int flags):
-  if isinstance(details, bytes):
-    pass
-  elif isinstance(details, basestring):
-    details = details.encode()
-  else:
-    raise TypeError("expected a str or bytes object for details")
+  details = str_to_bytes(details)
   cdef Operation op = Operation()
   op.c_op.type = GRPC_OP_SEND_STATUS_FROM_SERVER
   op.c_op.flags = flags
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi
index 8419a59..c8a73e6 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi
@@ -81,11 +81,20 @@
           self.c_server, queue.c_completion_queue, NULL)
     self.registered_completion_queues.append(queue)
 
+  def register_non_listening_completion_queue(
+      self, CompletionQueue queue not None):
+    if self.is_started:
+      raise ValueError("cannot register completion queues after start")
+    with nogil:
+      grpc_server_register_non_listening_completion_queue(
+          self.c_server, queue.c_completion_queue, NULL)
+    self.registered_completion_queues.append(queue)
+
   def start(self):
     if self.is_started:
       raise ValueError("the server has already started")
     self.backup_shutdown_queue = CompletionQueue()
-    self.register_completion_queue(self.backup_shutdown_queue)
+    self.register_non_listening_completion_queue(self.backup_shutdown_queue)
     self.is_started = True
     with nogil:
       grpc_server_start(self.c_server)
@@ -94,12 +103,7 @@
 
   def add_http2_port(self, address,
                      ServerCredentials server_credentials=None):
-    if isinstance(address, bytes):
-      pass
-    elif isinstance(address, basestring):
-      address = address.encode()
-    else:
-      raise TypeError("expected address to be a str or bytes")
+    address = str_to_bytes(address)
     self.references.append(address)
     cdef int result
     cdef char *address_c_string = address
@@ -169,4 +173,3 @@
           time.sleep(0)
       with nogil:
         grpc_server_destroy(self.c_server)
-
diff --git a/src/python/grpcio/grpc/_cython/cygrpc.pyx b/src/python/grpcio/grpc/_cython/cygrpc.pyx
index 8823ea5..cf146f5 100644
--- a/src/python/grpcio/grpc/_cython/cygrpc.pyx
+++ b/src/python/grpcio/grpc/_cython/cygrpc.pyx
@@ -35,6 +35,7 @@
 
 # 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"
diff --git a/src/python/grpcio/grpc/_cython/imports.generated.c b/src/python/grpcio/grpc/_cython/imports.generated.c
index f71cf12..5c49f6c 100644
--- a/src/python/grpcio/grpc/_cython/imports.generated.c
+++ b/src/python/grpcio/grpc/_cython/imports.generated.c
@@ -35,7 +35,7 @@
 
 #include "imports.generated.h"
 
-#ifdef GPR_WIN32
+#ifdef GPR_WINDOWS
 
 census_initialize_type census_initialize_import;
 census_shutdown_type census_shutdown_import;
@@ -126,7 +126,8 @@
 grpc_header_nonbin_value_is_legal_type grpc_header_nonbin_value_is_legal_import;
 grpc_is_binary_header_type grpc_is_binary_header_import;
 grpc_call_error_to_string_type grpc_call_error_to_string_import;
-grpc_cronet_secure_channel_create_type grpc_cronet_secure_channel_create_import;
+grpc_insecure_channel_create_from_fd_type grpc_insecure_channel_create_from_fd_import;
+grpc_server_add_insecure_channel_from_fd_type grpc_server_add_insecure_channel_from_fd_import;
 grpc_auth_property_iterator_next_type grpc_auth_property_iterator_next_import;
 grpc_auth_context_property_iterator_type grpc_auth_context_property_iterator_import;
 grpc_auth_context_peer_identity_type grpc_auth_context_peer_identity_import;
@@ -398,7 +399,8 @@
   grpc_header_nonbin_value_is_legal_import = (grpc_header_nonbin_value_is_legal_type) GetProcAddress(library, "grpc_header_nonbin_value_is_legal");
   grpc_is_binary_header_import = (grpc_is_binary_header_type) GetProcAddress(library, "grpc_is_binary_header");
   grpc_call_error_to_string_import = (grpc_call_error_to_string_type) GetProcAddress(library, "grpc_call_error_to_string");
-  grpc_cronet_secure_channel_create_import = (grpc_cronet_secure_channel_create_type) GetProcAddress(library, "grpc_cronet_secure_channel_create");
+  grpc_insecure_channel_create_from_fd_import = (grpc_insecure_channel_create_from_fd_type) GetProcAddress(library, "grpc_insecure_channel_create_from_fd");
+  grpc_server_add_insecure_channel_from_fd_import = (grpc_server_add_insecure_channel_from_fd_type) GetProcAddress(library, "grpc_server_add_insecure_channel_from_fd");
   grpc_auth_property_iterator_next_import = (grpc_auth_property_iterator_next_type) GetProcAddress(library, "grpc_auth_property_iterator_next");
   grpc_auth_context_property_iterator_import = (grpc_auth_context_property_iterator_type) GetProcAddress(library, "grpc_auth_context_property_iterator");
   grpc_auth_context_peer_identity_import = (grpc_auth_context_peer_identity_type) GetProcAddress(library, "grpc_auth_context_peer_identity");
@@ -581,4 +583,4 @@
 }
 #endif  /* __cpluslus */
 
-#endif /* !GPR_WIN32 */
+#endif /* !GPR_WINDOWS */
diff --git a/src/python/grpcio/grpc/_cython/imports.generated.h b/src/python/grpcio/grpc/_cython/imports.generated.h
index a364075..16bb5cd 100644
--- a/src/python/grpcio/grpc/_cython/imports.generated.h
+++ b/src/python/grpcio/grpc/_cython/imports.generated.h
@@ -36,14 +36,14 @@
 
 #include <grpc/support/port_platform.h>
 
-#ifdef GPR_WIN32
+#ifdef GPR_WINDOWS
 
 #include <windows.h>
 
 #include <grpc/census.h>
 #include <grpc/compression.h>
 #include <grpc/grpc.h>
-#include <grpc/grpc_cronet.h>
+#include <grpc/grpc_posix.h>
 #include <grpc/grpc_security.h>
 #include <grpc/impl/codegen/alloc.h>
 #include <grpc/impl/codegen/byte_buffer.h>
@@ -57,7 +57,7 @@
 #include <grpc/support/cpu.h>
 #include <grpc/support/histogram.h>
 #include <grpc/support/host_port.h>
-#include <grpc/support/log_win32.h>
+#include <grpc/support/log_windows.h>
 #include <grpc/support/string_util.h>
 #include <grpc/support/subprocess.h>
 #include <grpc/support/thd.h>
@@ -329,9 +329,12 @@
 typedef const char *(*grpc_call_error_to_string_type)(grpc_call_error error);
 extern grpc_call_error_to_string_type grpc_call_error_to_string_import;
 #define grpc_call_error_to_string grpc_call_error_to_string_import
-typedef grpc_channel *(*grpc_cronet_secure_channel_create_type)(void *engine, const char *target, const grpc_channel_args *args, void *reserved);
-extern grpc_cronet_secure_channel_create_type grpc_cronet_secure_channel_create_import;
-#define grpc_cronet_secure_channel_create grpc_cronet_secure_channel_create_import
+typedef grpc_channel *(*grpc_insecure_channel_create_from_fd_type)(const char *target, int fd, const grpc_channel_args *args);
+extern grpc_insecure_channel_create_from_fd_type grpc_insecure_channel_create_from_fd_import;
+#define grpc_insecure_channel_create_from_fd grpc_insecure_channel_create_from_fd_import
+typedef void(*grpc_server_add_insecure_channel_from_fd_type)(grpc_server *server, grpc_completion_queue *cq, int fd);
+extern grpc_server_add_insecure_channel_from_fd_type grpc_server_add_insecure_channel_from_fd_import;
+#define grpc_server_add_insecure_channel_from_fd grpc_server_add_insecure_channel_from_fd_import
 typedef const grpc_auth_property *(*grpc_auth_property_iterator_next_type)(grpc_auth_property_iterator *it);
 extern grpc_auth_property_iterator_next_type grpc_auth_property_iterator_next_import;
 #define grpc_auth_property_iterator_next grpc_auth_property_iterator_next_import
@@ -871,7 +874,7 @@
 }
 #endif  /* __cpluslus */
 
-#else /* !GPR_WIN32 */
+#else /* !GPR_WINDOWS */
 
 #include <grpc/byte_buffer.h>
 #include <grpc/byte_buffer_reader.h>
@@ -883,6 +886,6 @@
 #include <grpc/support/time.h>
 #include <grpc/status.h>
 
-#endif /* !GPR_WIN32 */
+#endif /* !GPR_WINDOWS */
 
 #endif
diff --git a/src/python/grpcio/grpc/_cython/loader.c b/src/python/grpcio/grpc/_cython/loader.c
index 3b72806..b909ad5 100644
--- a/src/python/grpcio/grpc/_cython/loader.c
+++ b/src/python/grpcio/grpc/_cython/loader.c
@@ -37,7 +37,7 @@
 extern "C" {
 #endif  /* __cpluslus  */
 
-#if GPR_WIN32
+#if GPR_WINDOWS
 
 int pygrpc_load_core(char *path) {
   HMODULE grpc_c;
@@ -60,7 +60,7 @@
 
 int pygrpc_load_core(char *path) { return 1; }
 
-#endif  /* !GPR_WIN32 */
+#endif  /* !GPR_WINDOWS */
 
 #ifdef __cplusplus
 }
diff --git a/src/python/grpcio/grpc/_links/service.py b/src/python/grpcio/grpc/_links/service.py
index 11310e2..5fc4994 100644
--- a/src/python/grpcio/grpc/_links/service.py
+++ b/src/python/grpcio/grpc/_links/service.py
@@ -33,6 +33,7 @@
 import enum
 import logging
 import threading
+import six
 import time
 
 from grpc._adapter import _intermediary_low
@@ -177,7 +178,10 @@
     call = service_acceptance.call
     call.accept(self._completion_queue, call)
     try:
-      group, method = service_acceptance.method.split(b'/')[1:3]
+      service_method = service_acceptance.method
+      if six.PY3:
+          service_method = service_method.decode('latin1')
+      group, method = service_method.split('/')[1:3]
     except ValueError:
       logging.info('Illegal path "%s"!', service_acceptance.method)
       return
diff --git a/src/python/grpcio/grpc/_plugin_wrapping.py b/src/python/grpcio/grpc/_plugin_wrapping.py
new file mode 100644
index 0000000..4e9cfe7
--- /dev/null
+++ b/src/python/grpcio/grpc/_plugin_wrapping.py
@@ -0,0 +1,123 @@
+# Copyright 2015, Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import collections
+import threading
+
+import grpc
+from grpc._cython import cygrpc
+
+
+class AuthMetadataContext(
+    collections.namedtuple(
+        'AuthMetadataContext', ('service_url', 'method_name',)),
+    grpc.AuthMetadataContext):
+  pass
+
+
+class AuthMetadataPluginCallback(grpc.AuthMetadataContext):
+
+  def __init__(self, callback):
+    self._callback = callback
+
+  def __call__(self, metadata, error):
+    self._callback(metadata, error)
+
+
+class _WrappedCygrpcCallback(object):
+
+  def __init__(self, cygrpc_callback):
+    self.is_called = False
+    self.error = None
+    self.is_called_lock = threading.Lock()
+    self.cygrpc_callback = cygrpc_callback
+
+  def _invoke_failure(self, error):
+    # TODO(atash) translate different Exception superclasses into different
+    # status codes.
+    self.cygrpc_callback(
+        cygrpc.Metadata([]), cygrpc.StatusCode.internal, error.message)
+
+  def _invoke_success(self, metadata):
+    try:
+      cygrpc_metadata = cygrpc.Metadata(
+          cygrpc.Metadatum(key, value)
+          for key, value in metadata)
+    except Exception as error:
+      self._invoke_failure(error)
+      return
+    self.cygrpc_callback(cygrpc_metadata, cygrpc.StatusCode.ok, '')
+
+  def __call__(self, metadata, error):
+    with self.is_called_lock:
+      if self.is_called:
+        raise RuntimeError('callback should only ever be invoked once')
+      if self.error:
+        self._invoke_failure(self.error)
+        return
+      self.is_called = True
+    if error is None:
+      self._invoke_success(metadata)
+    else:
+      self._invoke_failure(error)
+
+  def notify_failure(self, error):
+    with self.is_called_lock:
+      if not self.is_called:
+        self.error = error
+
+
+class _WrappedPlugin(object):
+
+  def __init__(self, plugin):
+    self.plugin = plugin
+
+  def __call__(self, context, cygrpc_callback):
+    wrapped_cygrpc_callback = _WrappedCygrpcCallback(cygrpc_callback)
+    wrapped_context = AuthMetadataContext(
+        context.service_url, context.method_name)
+    try:
+      self.plugin(
+          wrapped_context, AuthMetadataPluginCallback(wrapped_cygrpc_callback))
+    except Exception as error:
+      wrapped_cygrpc_callback.notify_failure(error)
+      raise
+
+
+def call_credentials_metadata_plugin(plugin, name):
+  """
+  Args:
+    plugin: A callable accepting a grpc.AuthMetadataContext
+      object and a callback (itself accepting a list of metadata key/value
+      2-tuples and a None-able exception value). The callback must be eventually
+      called, but need not be called in plugin's invocation.
+      plugin's invocation must be non-blocking.
+  """
+  return cygrpc.call_credentials_metadata_plugin(
+      cygrpc.CredentialsMetadataPlugin(_WrappedPlugin(plugin), name))
diff --git a/src/python/grpcio/grpc/_server.py b/src/python/grpcio/grpc/_server.py
new file mode 100644
index 0000000..2f99e5b
--- /dev/null
+++ b/src/python/grpcio/grpc/_server.py
@@ -0,0 +1,747 @@
+# 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.
+
+"""Service-side implementation of gRPC Python."""
+
+import collections
+import enum
+import logging
+import threading
+import time
+
+import grpc
+from grpc import _common
+from grpc._cython import cygrpc
+from grpc.framework.foundation import callable_util
+
+_SHUTDOWN_TAG = 'shutdown'
+_REQUEST_CALL_TAG = 'request_call'
+
+_RECEIVE_CLOSE_ON_SERVER_TOKEN = 'receive_close_on_server'
+_SEND_INITIAL_METADATA_TOKEN = 'send_initial_metadata'
+_RECEIVE_MESSAGE_TOKEN = 'receive_message'
+_SEND_MESSAGE_TOKEN = 'send_message'
+_SEND_INITIAL_METADATA_AND_SEND_MESSAGE_TOKEN = (
+    'send_initial_metadata * send_message')
+_SEND_STATUS_FROM_SERVER_TOKEN = 'send_status_from_server'
+_SEND_INITIAL_METADATA_AND_SEND_STATUS_FROM_SERVER_TOKEN = (
+    'send_initial_metadata * send_status_from_server')
+
+_OPEN = 'open'
+_CLOSED = 'closed'
+_CANCELLED = 'cancelled'
+
+_EMPTY_FLAGS = 0
+_EMPTY_METADATA = cygrpc.Metadata(())
+
+
+def _serialized_request(request_event):
+  return request_event.batch_operations[0].received_message.bytes()
+
+
+def _application_code(code):
+  cygrpc_code = _common.STATUS_CODE_TO_CYGRPC_STATUS_CODE.get(code)
+  return cygrpc.StatusCode.unknown if cygrpc_code is None else cygrpc_code
+
+
+def _completion_code(state):
+  if state.code is None:
+    return cygrpc.StatusCode.ok
+  else:
+    return _application_code(state.code)
+
+
+def _abortion_code(state, code):
+  if state.code is None:
+    return code
+  else:
+    return _application_code(state.code)
+
+
+def _details(state):
+  return '' if state.details is None else state.details
+
+
+class _HandlerCallDetails(
+    collections.namedtuple(
+        '_HandlerCallDetails', ('method', 'invocation_metadata',)),
+    grpc.HandlerCallDetails):
+  pass
+
+
+class _RPCState(object):
+
+  def __init__(self):
+    self.condition = threading.Condition()
+    self.due = set()
+    self.request = None
+    self.client = _OPEN
+    self.initial_metadata_allowed = True
+    self.disable_next_compression = False
+    self.trailing_metadata = None
+    self.code = None
+    self.details = None
+    self.statused = False
+    self.rpc_errors = []
+    self.callbacks = []
+
+
+def _raise_rpc_error(state):
+  rpc_error = grpc.RpcError()
+  state.rpc_errors.append(rpc_error)
+  raise rpc_error
+
+
+def _possibly_finish_call(state, token):
+  state.due.remove(token)
+  if (state.client is _CANCELLED or state.statused) and not state.due:
+    callbacks = state.callbacks
+    state.callbacks = None
+    return state, callbacks
+  else:
+    return None, ()
+
+
+def _send_status_from_server(state, token):
+  def send_status_from_server(unused_send_status_from_server_event):
+    with state.condition:
+      return _possibly_finish_call(state, token)
+  return send_status_from_server
+
+
+def _abort(state, call, code, details):
+  if state.client is not _CANCELLED:
+    effective_code = _abortion_code(state, code)
+    effective_details = details if state.details is None else state.details
+    if state.initial_metadata_allowed:
+      operations = (
+          cygrpc.operation_send_initial_metadata(
+              _EMPTY_METADATA, _EMPTY_FLAGS),
+          cygrpc.operation_send_status_from_server(
+              _common.metadata(state.trailing_metadata), effective_code,
+              effective_details, _EMPTY_FLAGS),
+      )
+      token = _SEND_INITIAL_METADATA_AND_SEND_STATUS_FROM_SERVER_TOKEN
+    else:
+      operations = (
+          cygrpc.operation_send_status_from_server(
+              _common.metadata(state.trailing_metadata), effective_code,
+              effective_details, _EMPTY_FLAGS),
+      )
+      token = _SEND_STATUS_FROM_SERVER_TOKEN
+    call.start_batch(
+        cygrpc.Operations(operations),
+        _send_status_from_server(state, token))
+    state.statused = True
+    state.due.add(token)
+
+
+def _receive_close_on_server(state):
+  def receive_close_on_server(receive_close_on_server_event):
+    with state.condition:
+      if receive_close_on_server_event.batch_operations[0].received_cancelled:
+        state.client = _CANCELLED
+      elif state.client is _OPEN:
+        state.client = _CLOSED
+      state.condition.notify_all()
+      return _possibly_finish_call(state, _RECEIVE_CLOSE_ON_SERVER_TOKEN)
+  return receive_close_on_server
+
+
+def _receive_message(state, call, request_deserializer):
+  def receive_message(receive_message_event):
+    serialized_request = _serialized_request(receive_message_event)
+    if serialized_request is None:
+      with state.condition:
+        if state.client is _OPEN:
+          state.client = _CLOSED
+        state.condition.notify_all()
+        return _possibly_finish_call(state, _RECEIVE_MESSAGE_TOKEN)
+    else:
+      request = _common.deserialize(serialized_request, request_deserializer)
+      with state.condition:
+        if request is None:
+          _abort(
+              state, call, cygrpc.StatusCode.internal,
+              'Exception deserializing request!')
+        else:
+          state.request = request
+        state.condition.notify_all()
+        return _possibly_finish_call(state, _RECEIVE_MESSAGE_TOKEN)
+  return receive_message
+
+
+def _send_initial_metadata(state):
+  def send_initial_metadata(unused_send_initial_metadata_event):
+    with state.condition:
+      return _possibly_finish_call(state, _SEND_INITIAL_METADATA_TOKEN)
+  return send_initial_metadata
+
+
+def _send_message(state, token):
+  def send_message(unused_send_message_event):
+    with state.condition:
+      state.condition.notify_all()
+      return _possibly_finish_call(state, token)
+  return send_message
+
+
+class _Context(grpc.ServicerContext):
+
+  def __init__(self, rpc_event, state, request_deserializer):
+    self._rpc_event = rpc_event
+    self._state = state
+    self._request_deserializer = request_deserializer
+
+  def is_active(self):
+    with self._state.condition:
+      return self._state.client is not _CANCELLED and not self._state.statused
+
+  def time_remaining(self):
+    return max(self._rpc_event.request_call_details.deadline - time.time(), 0)
+
+  def cancel(self):
+    self._rpc_event.operation_call.cancel()
+
+  def add_callback(self, callback):
+    with self._state.condition:
+      if self._state.callbacks is None:
+        return False
+      else:
+        self._state.callbacks.append(callback)
+        return True
+
+  def disable_next_message_compression(self):
+    with self._state.condition:
+      self._state.disable_next_compression = True
+
+  def invocation_metadata(self):
+    return self._rpc_event.request_metadata
+
+  def peer(self):
+    return self._rpc_event.operation_call.peer()
+
+  def send_initial_metadata(self, initial_metadata):
+    with self._state.condition:
+      if self._state.client is _CANCELLED:
+        _raise_rpc_error(self._state)
+      else:
+        if self._state.initial_metadata_allowed:
+          operation = cygrpc.operation_send_initial_metadata(
+              _common.metadata(initial_metadata), _EMPTY_FLAGS)
+          self._rpc_event.operation_call.start_batch(
+              cygrpc.Operations((operation,)),
+              _send_initial_metadata(self._state))
+          self._state.initial_metadata_allowed = False
+          self._state.due.add(_SEND_INITIAL_METADATA_TOKEN)
+        else:
+          raise ValueError('Initial metadata no longer allowed!')
+
+  def set_trailing_metadata(self, trailing_metadata):
+    with self._state.condition:
+      self._state.trailing_metadata = trailing_metadata
+
+  def set_code(self, code):
+    with self._state.condition:
+      self._state.code = code
+
+  def set_details(self, details):
+    with self._state.condition:
+      self._state.details = details
+
+
+class _RequestIterator(object):
+
+  def __init__(self, state, call, request_deserializer):
+    self._state = state
+    self._call = call
+    self._request_deserializer = request_deserializer
+
+  def _raise_or_start_receive_message(self):
+    if self._state.client is _CANCELLED:
+      _raise_rpc_error(self._state)
+    elif self._state.client is _CLOSED or self._state.statused:
+      raise StopIteration()
+    else:
+      self._call.start_batch(
+          cygrpc.Operations((cygrpc.operation_receive_message(_EMPTY_FLAGS),)),
+          _receive_message(self._state, self._call, self._request_deserializer))
+      self._state.due.add(_RECEIVE_MESSAGE_TOKEN)
+
+  def _look_for_request(self):
+    if self._state.client is _CANCELLED:
+      _raise_rpc_error(self._state)
+    elif (self._state.request is None and
+          _RECEIVE_MESSAGE_TOKEN not in self._state.due):
+      raise StopIteration()
+    else:
+      request = self._state.request
+      self._state.request = None
+      return request
+
+  def _next(self):
+    with self._state.condition:
+      self._raise_or_start_receive_message()
+      while True:
+        self._state.condition.wait()
+        request = self._look_for_request()
+        if request is not None:
+          return request
+
+  def __iter__(self):
+    return self
+
+  def __next__(self):
+    return self._next()
+
+  def next(self):
+    return self._next()
+
+
+def _unary_request(rpc_event, state, request_deserializer):
+  def unary_request():
+    with state.condition:
+      if state.client is _CANCELLED or state.statused:
+        return None
+      else:
+        start_batch_result = rpc_event.operation_call.start_batch(
+            cygrpc.Operations(
+                (cygrpc.operation_receive_message(_EMPTY_FLAGS),)),
+            _receive_message(
+                state, rpc_event.operation_call, request_deserializer))
+        state.due.add(_RECEIVE_MESSAGE_TOKEN)
+        while True:
+          state.condition.wait()
+          if state.request is None:
+            if state.client is _CLOSED:
+              details = '"{}" requires exactly one request message.'.format(
+                  rpc_event.request_call_details.method)
+              # TODO(5992#issuecomment-220761992): really, what status code?
+              _abort(
+                  state, rpc_event.operation_call,
+                  cygrpc.StatusCode.unavailable, details)
+              return None
+            elif state.client is _CANCELLED:
+              return None
+          else:
+            request = state.request
+            state.request = None
+            return request
+  return unary_request
+
+
+def _call_behavior(rpc_event, state, behavior, argument, request_deserializer):
+  context = _Context(rpc_event, state, request_deserializer)
+  try:
+    return behavior(argument, context), True
+  except Exception as e:  # pylint: disable=broad-except
+    with state.condition:
+      if e not in state.rpc_errors:
+        details = 'Exception calling application: {}'.format(e)
+        logging.exception(details)
+        _abort(
+            state, rpc_event.operation_call, cygrpc.StatusCode.unknown, details)
+    return None, False
+
+
+def _take_response_from_response_iterator(rpc_event, state, response_iterator):
+  try:
+    return next(response_iterator), True
+  except StopIteration:
+    return None, True
+  except Exception as e:  # pylint: disable=broad-except
+    with state.condition:
+      if e not in state.rpc_errors:
+        details = 'Exception iterating responses: {}'.format(e)
+        logging.exception(details)
+        _abort(
+            state, rpc_event.operation_call, cygrpc.StatusCode.unknown, details)
+    return None, False
+
+
+def _serialize_response(rpc_event, state, response, response_serializer):
+  serialized_response = _common.serialize(response, response_serializer)
+  if serialized_response is None:
+    with state.condition:
+      _abort(
+          state, rpc_event.operation_call, cygrpc.StatusCode.internal,
+          'Failed to serialize response!')
+    return None
+  else:
+    return serialized_response
+
+
+def _send_response(rpc_event, state, serialized_response):
+  with state.condition:
+    if state.client is _CANCELLED or state.statused:
+      return False
+    else:
+      if state.initial_metadata_allowed:
+        operations = (
+            cygrpc.operation_send_initial_metadata(
+                _EMPTY_METADATA, _EMPTY_FLAGS),
+            cygrpc.operation_send_message(serialized_response, _EMPTY_FLAGS),
+        )
+        state.initial_metadata_allowed = False
+        token = _SEND_INITIAL_METADATA_AND_SEND_MESSAGE_TOKEN
+      else:
+        operations = (
+            cygrpc.operation_send_message(serialized_response, _EMPTY_FLAGS),
+        )
+        token = _SEND_MESSAGE_TOKEN
+      rpc_event.operation_call.start_batch(
+          cygrpc.Operations(operations), _send_message(state, token))
+      state.due.add(token)
+      while True:
+        state.condition.wait()
+        if token not in state.due:
+          return state.client is not _CANCELLED and not state.statused
+
+
+def _status(rpc_event, state, serialized_response):
+  with state.condition:
+    if state.client is not _CANCELLED:
+      trailing_metadata = _common.metadata(state.trailing_metadata)
+      code = _completion_code(state)
+      details = _details(state)
+      operations = [
+          cygrpc.operation_send_status_from_server(
+              trailing_metadata, code, details, _EMPTY_FLAGS),
+      ]
+      if state.initial_metadata_allowed:
+        operations.append(
+            cygrpc.operation_send_initial_metadata(
+                _EMPTY_METADATA, _EMPTY_FLAGS))
+      if serialized_response is not None:
+        operations.append(cygrpc.operation_send_message(
+            serialized_response, _EMPTY_FLAGS))
+      rpc_event.operation_call.start_batch(
+          cygrpc.Operations(operations),
+          _send_status_from_server(state, _SEND_STATUS_FROM_SERVER_TOKEN))
+      state.statused = True
+      state.due.add(_SEND_STATUS_FROM_SERVER_TOKEN)
+
+
+def _unary_response_in_pool(
+    rpc_event, state, behavior, argument_thunk, request_deserializer,
+    response_serializer):
+  argument = argument_thunk()
+  if argument is not None:
+    response, proceed = _call_behavior(
+        rpc_event, state, behavior, argument, request_deserializer)
+    if proceed:
+      serialized_response = _serialize_response(
+          rpc_event, state, response, response_serializer)
+      if serialized_response is not None:
+        _status(rpc_event, state, serialized_response)
+  return
+
+
+def _stream_response_in_pool(
+    rpc_event, state, behavior, argument_thunk, request_deserializer,
+    response_serializer):
+  argument = argument_thunk()
+  if argument is not None:
+    response_iterator, proceed = _call_behavior(
+        rpc_event, state, behavior, argument, request_deserializer)
+    if proceed:
+      while True:
+        response, proceed = _take_response_from_response_iterator(
+            rpc_event, state, response_iterator)
+        if proceed:
+          if response is None:
+            _status(rpc_event, state, None)
+            break
+          else:
+            serialized_response = _serialize_response(
+                rpc_event, state, response, response_serializer)
+            if serialized_response is not None:
+              proceed = _send_response(rpc_event, state, serialized_response)
+              if not proceed:
+                break
+            else:
+              break
+        else:
+          break
+
+
+def _handle_unary_unary(rpc_event, state, method_handler, thread_pool):
+  unary_request = _unary_request(
+      rpc_event, state, method_handler.request_deserializer)
+  thread_pool.submit(
+      _unary_response_in_pool, rpc_event, state, method_handler.unary_unary,
+      unary_request, method_handler.request_deserializer,
+      method_handler.response_serializer)
+
+
+def _handle_unary_stream(rpc_event, state, method_handler, thread_pool):
+  unary_request = _unary_request(
+      rpc_event, state, method_handler.request_deserializer)
+  thread_pool.submit(
+      _stream_response_in_pool, rpc_event, state, method_handler.unary_stream,
+      unary_request, method_handler.request_deserializer,
+      method_handler.response_serializer)
+
+
+def _handle_stream_unary(rpc_event, state, method_handler, thread_pool):
+  request_iterator = _RequestIterator(
+      state, rpc_event.operation_call, method_handler.request_deserializer)
+  thread_pool.submit(
+      _unary_response_in_pool, rpc_event, state, method_handler.stream_unary,
+      lambda: request_iterator, method_handler.request_deserializer,
+      method_handler.response_serializer)
+
+
+def _handle_stream_stream(rpc_event, state, method_handler, thread_pool):
+  request_iterator = _RequestIterator(
+      state, rpc_event.operation_call, method_handler.request_deserializer)
+  thread_pool.submit(
+      _stream_response_in_pool, rpc_event, state, method_handler.stream_stream,
+      lambda: request_iterator, method_handler.request_deserializer,
+      method_handler.response_serializer)
+
+
+def _find_method_handler(rpc_event, generic_handlers):
+  for generic_handler in generic_handlers:
+    method_handler = generic_handler.service(
+        _HandlerCallDetails(
+            rpc_event.request_call_details.method, rpc_event.request_metadata))
+    if method_handler is not None:
+      return method_handler
+  else:
+    return None
+
+
+def _handle_unrecognized_method(rpc_event):
+  operations = (
+      cygrpc.operation_send_initial_metadata(_EMPTY_METADATA, _EMPTY_FLAGS),
+      cygrpc.operation_receive_close_on_server(_EMPTY_FLAGS),
+      cygrpc.operation_send_status_from_server(
+          _EMPTY_METADATA, cygrpc.StatusCode.unimplemented,
+          'Method not found!', _EMPTY_FLAGS),
+  )
+  rpc_state = _RPCState()
+  rpc_event.operation_call.start_batch(
+      operations, lambda ignored_event: (rpc_state, (),))
+  return rpc_state
+
+
+def _handle_with_method_handler(rpc_event, method_handler, thread_pool):
+  state = _RPCState()
+  with state.condition:
+    rpc_event.operation_call.start_batch(
+        cygrpc.Operations(
+            (cygrpc.operation_receive_close_on_server(_EMPTY_FLAGS),)),
+        _receive_close_on_server(state))
+    state.due.add(_RECEIVE_CLOSE_ON_SERVER_TOKEN)
+    if method_handler.request_streaming:
+      if method_handler.response_streaming:
+        _handle_stream_stream(rpc_event, state, method_handler, thread_pool)
+      else:
+        _handle_stream_unary(rpc_event, state, method_handler, thread_pool)
+    else:
+      if method_handler.response_streaming:
+        _handle_unary_stream(rpc_event, state, method_handler, thread_pool)
+      else:
+        _handle_unary_unary(rpc_event, state, method_handler, thread_pool)
+    return state
+
+
+def _handle_call(rpc_event, generic_handlers, thread_pool):
+  if rpc_event.request_call_details.method is not None:
+    method_handler = _find_method_handler(rpc_event, generic_handlers)
+    if method_handler is None:
+      return _handle_unrecognized_method(rpc_event)
+    else:
+      return _handle_with_method_handler(rpc_event, method_handler, thread_pool)
+  else:
+    return None
+
+
+@enum.unique
+class _ServerStage(enum.Enum):
+  STOPPED = 'stopped'
+  STARTED = 'started'
+  GRACE = 'grace'
+
+
+class _ServerState(object):
+
+  def __init__(self, completion_queue, server, generic_handlers, thread_pool):
+    self.lock = threading.Lock()
+    self.completion_queue = completion_queue
+    self.server = server
+    self.generic_handlers = list(generic_handlers)
+    self.thread_pool = thread_pool
+    self.stage = _ServerStage.STOPPED
+    self.shutdown_events = None
+
+    # TODO(https://github.com/grpc/grpc/issues/6597): eliminate these fields.
+    self.rpc_states = set()
+    self.due = set()
+
+
+def _add_generic_handlers(state, generic_handlers):
+  with state.lock:
+    state.generic_handlers.extend(generic_handlers)
+
+
+def _add_insecure_port(state, address):
+  with state.lock:
+    return state.server.add_http2_port(address)
+
+
+def _add_secure_port(state, address, server_credentials):
+  with state.lock:
+    return state.server.add_http2_port(address, server_credentials._credentials)
+
+
+def _request_call(state):
+  state.server.request_call(
+      state.completion_queue, state.completion_queue, _REQUEST_CALL_TAG)
+  state.due.add(_REQUEST_CALL_TAG)
+
+
+# TODO(https://github.com/grpc/grpc/issues/6597): delete this function.
+def _stop_serving(state):
+  if not state.rpc_states and not state.due:
+    for shutdown_event in state.shutdown_events:
+      shutdown_event.set()
+    state.stage = _ServerStage.STOPPED
+    return True
+  else:
+    return False
+
+
+def _serve(state):
+  while True:
+    event = state.completion_queue.poll()
+    if event.tag is _SHUTDOWN_TAG:
+      with state.lock:
+        state.due.remove(_SHUTDOWN_TAG)
+        if _stop_serving(state):
+          return
+    elif event.tag is _REQUEST_CALL_TAG:
+      with state.lock:
+        state.due.remove(_REQUEST_CALL_TAG)
+        rpc_state = _handle_call(
+            event, state.generic_handlers, state.thread_pool)
+        if rpc_state is not None:
+          state.rpc_states.add(rpc_state)
+        if state.stage is _ServerStage.STARTED:
+          _request_call(state)
+        elif _stop_serving(state):
+          return
+    else:
+      rpc_state, callbacks = event.tag(event)
+      for callback in callbacks:
+        callable_util.call_logging_exceptions(
+            callback, 'Exception calling callback!')
+      if rpc_state is not None:
+        with state.lock:
+          state.rpc_states.remove(rpc_state)
+          if _stop_serving(state):
+            return
+
+
+def _start(state):
+  with state.lock:
+    if state.stage is not _ServerStage.STOPPED:
+      raise ValueError('Cannot start already-started server!')
+    state.server.start()
+    state.stage = _ServerStage.STARTED
+    _request_call(state)
+    thread = threading.Thread(target=_serve, args=(state,))
+    thread.start()
+
+
+def _stop(state, grace):
+  with state.lock:
+    if state.stage is _ServerStage.STOPPED:
+      shutdown_event = threading.Event()
+      shutdown_event.set()
+      return shutdown_event
+    else:
+      if state.stage is _ServerStage.STARTED:
+        state.server.shutdown(state.completion_queue, _SHUTDOWN_TAG)
+        state.stage = _ServerStage.GRACE
+        state.shutdown_events = []
+        state.due.add(_SHUTDOWN_TAG)
+      shutdown_event = threading.Event()
+      state.shutdown_events.append(shutdown_event)
+      if grace is None:
+        state.server.cancel_all_calls()
+        # TODO(https://github.com/grpc/grpc/issues/6597): delete this loop.
+        for rpc_state in state.rpc_states:
+          with rpc_state.condition:
+            rpc_state.client = _CANCELLED
+            rpc_state.condition.notify_all()
+      else:
+        def cancel_all_calls_after_grace():
+          shutdown_event.wait(timeout=grace)
+          with state.lock:
+            state.server.cancel_all_calls()
+            # TODO(https://github.com/grpc/grpc/issues/6597): delete this loop.
+            for rpc_state in state.rpc_states:
+              with rpc_state.condition:
+                rpc_state.client = _CANCELLED
+                rpc_state.condition.notify_all()
+        thread = threading.Thread(target=cancel_all_calls_after_grace)
+        thread.start()
+        return shutdown_event
+  shutdown_event.wait()
+  return shutdown_event
+
+
+class Server(grpc.Server):
+
+  def __init__(self, generic_handlers, thread_pool):
+    completion_queue = cygrpc.CompletionQueue()
+    server = cygrpc.Server()
+    server.register_completion_queue(completion_queue)
+    self._state = _ServerState(
+        completion_queue, server, generic_handlers, thread_pool)
+
+  def add_generic_rpc_handlers(self, generic_rpc_handlers):
+    _add_generic_handlers(self._state, generic_rpc_handlers)
+
+  def add_insecure_port(self, address):
+    return _add_insecure_port(self._state, address)
+
+  def add_secure_port(self, address, server_credentials):
+    return _add_secure_port(self._state, address, server_credentials)
+
+  def start(self):
+    _start(self._state)
+
+  def stop(self, grace):
+    return _stop(self._state, grace)
+
+  def __del__(self):
+    _stop(self._state, None)
diff --git a/src/python/grpcio/grpc/_utilities.py b/src/python/grpcio/grpc/_utilities.py
new file mode 100644
index 0000000..a4ca9b7
--- /dev/null
+++ b/src/python/grpcio/grpc/_utilities.py
@@ -0,0 +1,147 @@
+# 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.
+
+"""Internal utilities for gRPC Python."""
+
+import threading
+import time
+
+import grpc
+from grpc.framework.foundation import callable_util
+
+_DONE_CALLBACK_EXCEPTION_LOG_MESSAGE = (
+    'Exception calling connectivity future "done" callback!')
+
+
+class _ChannelReadyFuture(grpc.Future):
+
+  def __init__(self, channel):
+    self._condition = threading.Condition()
+    self._channel = channel
+
+    self._matured = False
+    self._cancelled = False
+    self._done_callbacks = []
+
+  def _block(self, timeout):
+    until = None if timeout is None else time.time() + timeout
+    with self._condition:
+      while True:
+        if self._cancelled:
+          raise grpc.FutureCancelledError()
+        elif self._matured:
+          return
+        else:
+          if until is None:
+            self._condition.wait()
+          else:
+            remaining = until - time.time()
+            if remaining < 0:
+              raise grpc.FutureTimeoutError()
+            else:
+              self._condition.wait(timeout=remaining)
+
+  def _update(self, connectivity):
+    with self._condition:
+      if (not self._cancelled and
+          connectivity is grpc.ChannelConnectivity.READY):
+        self._matured = True
+        self._channel.unsubscribe(self._update)
+        self._condition.notify_all()
+        done_callbacks = tuple(self._done_callbacks)
+        self._done_callbacks = None
+      else:
+        return
+
+    for done_callback in done_callbacks:
+      callable_util.call_logging_exceptions(
+          done_callback, _DONE_CALLBACK_EXCEPTION_LOG_MESSAGE, self)
+
+  def cancel(self):
+    with self._condition:
+      if not self._matured:
+        self._cancelled = True
+        self._channel.unsubscribe(self._update)
+        self._condition.notify_all()
+        done_callbacks = tuple(self._done_callbacks)
+        self._done_callbacks = None
+      else:
+        return False
+
+    for done_callback in done_callbacks:
+      callable_util.call_logging_exceptions(
+          done_callback, _DONE_CALLBACK_EXCEPTION_LOG_MESSAGE, self)
+
+  def cancelled(self):
+    with self._condition:
+      return self._cancelled
+
+  def running(self):
+    with self._condition:
+      return not self._cancelled and not self._matured
+
+  def done(self):
+    with self._condition:
+      return self._cancelled or self._matured
+
+  def result(self, timeout=None):
+    self._block(timeout)
+    return None
+
+  def exception(self, timeout=None):
+    self._block(timeout)
+    return None
+
+  def traceback(self, timeout=None):
+    self._block(timeout)
+    return None
+
+  def add_done_callback(self, fn):
+    with self._condition:
+      if not self._cancelled and not self._matured:
+        self._done_callbacks.append(fn)
+        return
+
+    fn(self)
+
+  def start(self):
+    with self._condition:
+      self._channel.subscribe(self._update, try_to_connect=True)
+
+  def __del__(self):
+    with self._condition:
+      if not self._cancelled and not self._matured:
+        self._channel.unsubscribe(self._update)
+
+
+def channel_ready_future(channel):
+  ready_future = _ChannelReadyFuture(channel)
+  ready_future.start()
+  return ready_future
+
diff --git a/src/python/grpcio/grpc/beta/_client_adaptations.py b/src/python/grpcio/grpc/beta/_client_adaptations.py
new file mode 100644
index 0000000..024808c
--- /dev/null
+++ b/src/python/grpcio/grpc/beta/_client_adaptations.py
@@ -0,0 +1,563 @@
+# 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.
+
+"""Translates gRPC's client-side API into gRPC's client-side Beta API."""
+
+import grpc
+from grpc import _common
+from grpc._cython import cygrpc
+from grpc.beta import interfaces
+from grpc.framework.common import cardinality
+from grpc.framework.foundation import future
+from grpc.framework.interfaces.face import face
+
+_STATUS_CODE_TO_ABORTION_KIND_AND_ABORTION_ERROR_CLASS = {
+    grpc.StatusCode.CANCELLED: (
+        face.Abortion.Kind.CANCELLED, face.CancellationError),
+    grpc.StatusCode.UNKNOWN: (
+        face.Abortion.Kind.REMOTE_FAILURE, face.RemoteError),
+    grpc.StatusCode.DEADLINE_EXCEEDED: (
+        face.Abortion.Kind.EXPIRED, face.ExpirationError),
+    grpc.StatusCode.UNIMPLEMENTED: (
+        face.Abortion.Kind.LOCAL_FAILURE, face.LocalError),
+}
+
+
+def _effective_metadata(metadata, metadata_transformer):
+  non_none_metadata = () if metadata is None else metadata
+  if metadata_transformer is None:
+    return non_none_metadata
+  else:
+    return metadata_transformer(non_none_metadata)
+
+
+def _credentials(grpc_call_options):
+  return None if grpc_call_options is None else grpc_call_options.credentials
+
+
+def _abortion(rpc_error_call):
+  code = rpc_error_call.code()
+  pair = _STATUS_CODE_TO_ABORTION_KIND_AND_ABORTION_ERROR_CLASS.get(code)
+  error_kind = face.Abortion.Kind.LOCAL_FAILURE if pair is None else pair[0]
+  return face.Abortion(
+      error_kind, rpc_error_call.initial_metadata(),
+      rpc_error_call.trailing_metadata(), code, rpc_error_code.details())
+
+
+def _abortion_error(rpc_error_call):
+  code = rpc_error_call.code()
+  pair = _STATUS_CODE_TO_ABORTION_KIND_AND_ABORTION_ERROR_CLASS.get(code)
+  exception_class = face.AbortionError if pair is None else pair[1]
+  return exception_class(
+      rpc_error_call.initial_metadata(), rpc_error_call.trailing_metadata(),
+      code, rpc_error_call.details())
+
+
+class _InvocationProtocolContext(interfaces.GRPCInvocationContext):
+
+  def disable_next_request_compression(self):
+    pass  # TODO(https://github.com/grpc/grpc/issues/4078): design, implement.
+
+
+class _Rendezvous(future.Future, face.Call):
+
+  def __init__(self, response_future, response_iterator, call):
+    self._future = response_future
+    self._iterator = response_iterator
+    self._call = call
+
+  def cancel(self):
+    return self._call.cancel()
+
+  def cancelled(self):
+    return self._future.cancelled()
+
+  def running(self):
+    return self._future.running()
+
+  def done(self):
+    return self._future.done()
+
+  def result(self, timeout=None):
+    try:
+      return self._future.result(timeout=timeout)
+    except grpc.RpcError as rpc_error_call:
+      raise _abortion_error(rpc_error_call)
+    except grpc.FutureTimeoutError:
+      raise future.TimeoutError()
+    except grpc.FutureCancelledError:
+      raise future.CancelledError()
+
+  def exception(self, timeout=None):
+    try:
+      rpc_error_call = self._future.exception(timeout=timeout)
+      return _abortion_error(rpc_error_call)
+    except grpc.FutureTimeoutError:
+      raise future.TimeoutError()
+    except grpc.FutureCancelledError:
+      raise future.CancelledError()
+
+  def traceback(self, timeout=None):
+    try:
+      return self._future.traceback(timeout=timeout)
+    except grpc.FutureTimeoutError:
+      raise future.TimeoutError()
+    except grpc.FutureCancelledError:
+      raise future.CancelledError()
+
+  def add_done_callback(self, fn):
+    self._future.add_done_callback(lambda ignored_callback: fn(self))
+
+  def __iter__(self):
+    return self
+
+  def _next(self):
+    try:
+      return next(self._iterator)
+    except grpc.RpcError as rpc_error_call:
+      raise _abortion_error(rpc_error_call)
+
+  def __next__(self):
+    return self._next()
+
+  def next(self):
+    return self._next()
+
+  def is_active(self):
+    return self._call.is_active()
+
+  def time_remaining(self):
+    return self._call.time_remaining()
+
+  def add_abortion_callback(self, abortion_callback):
+    registered = self._call.add_callback(
+        lambda: abortion_callback(_abortion(self._call)))
+    return None if registered else _abortion(self._call)
+
+  def protocol_context(self):
+    return _InvocationProtocolContext()
+
+  def initial_metadata(self):
+    return self._call.initial_metadata()
+
+  def terminal_metadata(self):
+    return self._call.terminal_metadata()
+
+  def code(self):
+    return self._call.code()
+
+  def details(self):
+    return self._call.details()
+
+
+def _blocking_unary_unary(
+    channel, group, method, timeout, with_call, protocol_options, metadata,
+    metadata_transformer, request, request_serializer, response_deserializer):
+  try:
+    multi_callable = channel.unary_unary(
+        _common.fully_qualified_method(group, method),
+        request_serializer=request_serializer,
+        response_deserializer=response_deserializer)
+    effective_metadata = _effective_metadata(metadata, metadata_transformer)
+    if with_call:
+      response, call = multi_callable(
+          request, timeout=timeout, metadata=effective_metadata,
+          credentials=_credentials(protocol_options), with_call=True)
+      return response, _Rendezvous(None, None, call)
+    else:
+      return multi_callable(
+          request, timeout=timeout, metadata=effective_metadata,
+          credentials=_credentials(protocol_options))
+  except grpc.RpcError as rpc_error_call:
+    raise _abortion_error(rpc_error_call)
+
+
+def _future_unary_unary(
+    channel, group, method, timeout, protocol_options, metadata,
+    metadata_transformer, request, request_serializer, response_deserializer):
+  multi_callable = channel.unary_unary(
+      _common.fully_qualified_method(group, method),
+      request_serializer=request_serializer,
+      response_deserializer=response_deserializer)
+  effective_metadata = _effective_metadata(metadata, metadata_transformer)
+  response_future = multi_callable.future(
+      request, timeout=timeout, metadata=effective_metadata,
+      credentials=_credentials(protocol_options))
+  return _Rendezvous(response_future, None, response_future)
+
+
+def _unary_stream(
+    channel, group, method, timeout, protocol_options, metadata,
+    metadata_transformer, request, request_serializer, response_deserializer):
+  multi_callable = channel.unary_stream(
+      _common.fully_qualified_method(group, method),
+      request_serializer=request_serializer,
+      response_deserializer=response_deserializer)
+  effective_metadata = _effective_metadata(metadata, metadata_transformer)
+  response_iterator = multi_callable(
+      request, timeout=timeout, metadata=effective_metadata,
+      credentials=_credentials(protocol_options))
+  return _Rendezvous(None, response_iterator, response_iterator)
+
+
+def _blocking_stream_unary(
+    channel, group, method, timeout, with_call, protocol_options, metadata,
+    metadata_transformer, request_iterator, request_serializer,
+    response_deserializer):
+  try:
+    multi_callable = channel.stream_unary(
+        _common.fully_qualified_method(group, method),
+        request_serializer=request_serializer,
+        response_deserializer=response_deserializer)
+    effective_metadata = _effective_metadata(metadata, metadata_transformer)
+    if with_call:
+      response, call = multi_callable(
+          request_iterator, timeout=timeout, metadata=effective_metadata,
+          credentials=_credentials(protocol_options), with_call=True)
+      return response, _Rendezvous(None, None, call)
+    else:
+      return multi_callable(
+          request_iterator, timeout=timeout, metadata=effective_metadata,
+          credentials=_credentials(protocol_options))
+  except grpc.RpcError as rpc_error_call:
+    raise _abortion_error(rpc_error_call)
+
+
+def _future_stream_unary(
+    channel, group, method, timeout, protocol_options, metadata,
+    metadata_transformer, request_iterator, request_serializer,
+    response_deserializer):
+  multi_callable = channel.stream_unary(
+      _common.fully_qualified_method(group, method),
+      request_serializer=request_serializer,
+      response_deserializer=response_deserializer)
+  effective_metadata = _effective_metadata(metadata, metadata_transformer)
+  response_future = multi_callable.future(
+      request_iterator, timeout=timeout, metadata=effective_metadata,
+      credentials=_credentials(protocol_options))
+  return _Rendezvous(response_future, None, response_future)
+
+
+def _stream_stream(
+    channel, group, method, timeout, protocol_options, metadata,
+    metadata_transformer, request_iterator, request_serializer,
+    response_deserializer):
+  multi_callable = channel.stream_stream(
+      _common.fully_qualified_method(group, method),
+      request_serializer=request_serializer,
+      response_deserializer=response_deserializer)
+  effective_metadata = _effective_metadata(metadata, metadata_transformer)
+  response_iterator = multi_callable(
+      request_iterator, timeout=timeout, metadata=effective_metadata,
+      credentials=_credentials(protocol_options))
+  return _Rendezvous(None, response_iterator, response_iterator)
+
+
+class _UnaryUnaryMultiCallable(face.UnaryUnaryMultiCallable):
+
+  def __init__(
+      self, channel, group, method, metadata_transformer, request_serializer,
+      response_deserializer):
+    self._channel = channel
+    self._group = group
+    self._method = method
+    self._metadata_transformer = metadata_transformer
+    self._request_serializer = request_serializer
+    self._response_deserializer = response_deserializer
+
+  def __call__(
+      self, request, timeout, metadata=None, with_call=False,
+      protocol_options=None):
+    return _blocking_unary_unary(
+        self._channel, self._group, self._method, timeout, with_call,
+        protocol_options, metadata, self._metadata_transformer, request,
+        self._request_serializer, self._response_deserializer)
+
+  def future(self, request, timeout, metadata=None, protocol_options=None):
+    return _future_unary_unary(
+        self._channel, self._group, self._method, timeout, protocol_options,
+        metadata, self._metadata_transformer, request, self._request_serializer,
+        self._response_deserializer)
+
+  def event(
+      self, request, receiver, abortion_callback, timeout,
+      metadata=None, protocol_options=None):
+    raise NotImplementedError()
+
+
+class _UnaryStreamMultiCallable(face.UnaryStreamMultiCallable):
+
+  def __init__(
+      self, channel, group, method, metadata_transformer, request_serializer,
+      response_deserializer):
+    self._channel = channel
+    self._group = group
+    self._method = method
+    self._metadata_transformer = metadata_transformer
+    self._request_serializer = request_serializer
+    self._response_deserializer = response_deserializer
+
+  def __call__(self, request, timeout, metadata=None, protocol_options=None):
+    return _unary_stream(
+        self._channel, self._group, self._method, timeout, protocol_options,
+        metadata, self._metadata_transformer, request, self._request_serializer,
+        self._response_deserializer)
+
+  def event(
+      self, request, receiver, abortion_callback, timeout,
+      metadata=None, protocol_options=None):
+    raise NotImplementedError()
+
+
+class _StreamUnaryMultiCallable(face.StreamUnaryMultiCallable):
+
+  def __init__(
+      self, channel, group, method, metadata_transformer, request_serializer,
+      response_deserializer):
+    self._channel = channel
+    self._group = group
+    self._method = method
+    self._metadata_transformer = metadata_transformer
+    self._request_serializer = request_serializer
+    self._response_deserializer = response_deserializer
+
+  def __call__(
+      self, request_iterator, timeout, metadata=None, with_call=False,
+      protocol_options=None):
+    return _blocking_stream_unary(
+        self._channel, self._group, self._method, timeout, with_call,
+        protocol_options, metadata, self._metadata_transformer,
+        request_iterator, self._request_serializer, self._response_deserializer)
+
+  def future(
+      self, request_iterator, timeout, metadata=None, protocol_options=None):
+    return _future_stream_unary(
+        self._channel, self._group, self._method, timeout, protocol_options,
+        metadata, self._metadata_transformer, request_iterator,
+        self._request_serializer, self._response_deserializer)
+
+  def event(
+      self, receiver, abortion_callback, timeout, metadata=None,
+      protocol_options=None):
+    raise NotImplementedError()
+
+
+class _StreamStreamMultiCallable(face.StreamStreamMultiCallable):
+
+  def __init__(
+      self, channel, group, method, metadata_transformer, request_serializer,
+      response_deserializer):
+    self._channel = channel
+    self._group = group
+    self._method = method
+    self._metadata_transformer = metadata_transformer
+    self._request_serializer = request_serializer
+    self._response_deserializer = response_deserializer
+
+  def __call__(
+      self, request_iterator, timeout, metadata=None, protocol_options=None):
+    return _stream_stream(
+        self._channel, self._group, self._method, timeout, protocol_options,
+        metadata, self._metadata_transformer, request_iterator,
+        self._request_serializer, self._response_deserializer)
+
+  def event(
+      self, receiver, abortion_callback, timeout, metadata=None,
+      protocol_options=None):
+    raise NotImplementedError()
+
+
+class _GenericStub(face.GenericStub):
+
+  def __init__(
+      self, channel, metadata_transformer, request_serializers,
+      response_deserializers):
+    self._channel = channel
+    self._metadata_transformer = metadata_transformer
+    self._request_serializers = request_serializers or {}
+    self._response_deserializers = response_deserializers or {}
+
+  def blocking_unary_unary(
+      self, group, method, request, timeout, metadata=None,
+      with_call=None, protocol_options=None):
+    request_serializer = self._request_serializers.get((group, method,))
+    response_deserializer = self._response_deserializers.get((group, method,))
+    return _blocking_unary_unary(
+        self._channel, group, method, timeout, with_call, protocol_options,
+        metadata, self._metadata_transformer, request, request_serializer,
+        response_deserializer)
+
+  def future_unary_unary(
+      self, group, method, request, timeout, metadata=None,
+      protocol_options=None):
+    request_serializer = self._request_serializers.get((group, method,))
+    response_deserializer = self._response_deserializers.get((group, method,))
+    return _future_unary_unary(
+        self._channel, group, method, timeout, protocol_options, metadata,
+        self._metadata_transformer, request, request_serializer,
+        response_deserializer)
+
+  def inline_unary_stream(
+      self, group, method, request, timeout, metadata=None,
+      protocol_options=None):
+    request_serializer = self._request_serializers.get((group, method,))
+    response_deserializer = self._response_deserializers.get((group, method,))
+    return _unary_stream(
+        self._channel, group, method, timeout, protocol_options, metadata,
+        self._metadata_transformer, request, request_serializer,
+        response_deserializer)
+
+  def blocking_stream_unary(
+      self, group, method, request_iterator, timeout, metadata=None,
+      with_call=None, protocol_options=None):
+    request_serializer = self._request_serializers.get((group, method,))
+    response_deserializer = self._response_deserializers.get((group, method,))
+    return _blocking_stream_unary(
+        self._channel, group, method, timeout, with_call, protocol_options,
+        metadata, self._metadata_transformer, request_iterator,
+        request_serializer, response_deserializer)
+
+  def future_stream_unary(
+      self, group, method, request_iterator, timeout, metadata=None,
+      protocol_options=None):
+    request_serializer = self._request_serializers.get((group, method,))
+    response_deserializer = self._response_deserializers.get((group, method,))
+    return _future_stream_unary(
+        self._channel, group, method, timeout, protocol_options, metadata,
+        self._metadata_transformer, request_iterator, request_serializer,
+        response_deserializer)
+
+  def inline_stream_stream(
+      self, group, method, request_iterator, timeout, metadata=None,
+      protocol_options=None):
+    request_serializer = self._request_serializers.get((group, method,))
+    response_deserializer = self._response_deserializers.get((group, method,))
+    return _stream_stream(
+        self._channel, group, method, timeout, protocol_options, metadata,
+        self._metadata_transformer, request_iterator, request_serializer,
+        response_deserializer)
+
+  def event_unary_unary(
+      self, group, method, request, receiver, abortion_callback, timeout,
+      metadata=None, protocol_options=None):
+    raise NotImplementedError()
+
+  def event_unary_stream(
+      self, group, method, request, receiver, abortion_callback, timeout,
+      metadata=None, protocol_options=None):
+    raise NotImplementedError()
+
+  def event_stream_unary(
+      self, group, method, receiver, abortion_callback, timeout,
+      metadata=None, protocol_options=None):
+    raise NotImplementedError()
+
+  def event_stream_stream(
+      self, group, method, receiver, abortion_callback, timeout,
+      metadata=None, protocol_options=None):
+    raise NotImplementedError()
+
+  def unary_unary(self, group, method):
+    request_serializer = self._request_serializers.get((group, method,))
+    response_deserializer = self._response_deserializers.get((group, method,))
+    return _UnaryUnaryMultiCallable(
+        self._channel, group, method, self._metadata_transformer,
+        request_serializer, response_deserializer)
+
+  def unary_stream(self, group, method):
+    request_serializer = self._request_serializers.get((group, method,))
+    response_deserializer = self._response_deserializers.get((group, method,))
+    return _UnaryStreamMultiCallable(
+        self._channel, group, method, self._metadata_transformer,
+        request_serializer, response_deserializer)
+
+  def stream_unary(self, group, method):
+    request_serializer = self._request_serializers.get((group, method,))
+    response_deserializer = self._response_deserializers.get((group, method,))
+    return _StreamUnaryMultiCallable(
+        self._channel, group, method, self._metadata_transformer,
+        request_serializer, response_deserializer)
+
+  def stream_stream(self, group, method):
+    request_serializer = self._request_serializers.get((group, method,))
+    response_deserializer = self._response_deserializers.get((group, method,))
+    return _StreamStreamMultiCallable(
+        self._channel, group, method, self._metadata_transformer,
+        request_serializer, response_deserializer)
+
+  def __enter__(self):
+    return self
+
+  def __exit__(self, exc_type, exc_val, exc_tb):
+    return False
+
+
+class _DynamicStub(face.DynamicStub):
+
+  def __init__(self, generic_stub, group, cardinalities):
+    self._generic_stub = generic_stub
+    self._group = group
+    self._cardinalities = cardinalities
+
+  def __getattr__(self, attr):
+    method_cardinality = self._cardinalities.get(attr)
+    if method_cardinality is cardinality.Cardinality.UNARY_UNARY:
+      return self._generic_stub.unary_unary(self._group, attr)
+    elif method_cardinality is cardinality.Cardinality.UNARY_STREAM:
+      return self._generic_stub.unary_stream(self._group, attr)
+    elif method_cardinality is cardinality.Cardinality.STREAM_UNARY:
+      return self._generic_stub.stream_unary(self._group, attr)
+    elif method_cardinality is cardinality.Cardinality.STREAM_STREAM:
+      return self._generic_stub.stream_stream(self._group, attr)
+    else:
+      raise AttributeError('_DynamicStub object has no attribute "%s"!' % attr)
+
+  def __enter__(self):
+    return self
+
+  def __exit__(self, exc_type, exc_val, exc_tb):
+    return False
+
+
+def generic_stub(
+    channel, host, metadata_transformer, request_serializers,
+    response_deserializers):
+  return _GenericStub(
+      channel, metadata_transformer, request_serializers,
+      response_deserializers)
+
+
+def dynamic_stub(
+    channel, service, cardinalities, host, metadata_transformer,
+    request_serializers, response_deserializers):
+  return _DynamicStub(
+      _GenericStub(
+          channel, metadata_transformer, request_serializers,
+          response_deserializers),
+      service, cardinalities)
diff --git a/src/python/grpcio/grpc/beta/_server_adaptations.py b/src/python/grpcio/grpc/beta/_server_adaptations.py
new file mode 100644
index 0000000..79e6ca8
--- /dev/null
+++ b/src/python/grpcio/grpc/beta/_server_adaptations.py
@@ -0,0 +1,367 @@
+# 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.
+
+"""Translates gRPC's server-side API into gRPC's server-side Beta API."""
+
+import collections
+import threading
+
+import grpc
+from grpc import _common
+from grpc.beta import interfaces
+from grpc.framework.common import cardinality
+from grpc.framework.common import style
+from grpc.framework.foundation import abandonment
+from grpc.framework.foundation import logging_pool
+from grpc.framework.foundation import stream
+from grpc.framework.interfaces.face import face
+
+_DEFAULT_POOL_SIZE = 8
+
+
+class _ServerProtocolContext(interfaces.GRPCServicerContext):
+
+  def __init__(self, servicer_context):
+    self._servicer_context = servicer_context
+
+  def peer(self):
+    return self._servicer_context.peer()
+
+  def disable_next_response_compression(self):
+    pass  # TODO(https://github.com/grpc/grpc/issues/4078): design, implement.
+
+
+class _FaceServicerContext(face.ServicerContext):
+
+  def __init__(self, servicer_context):
+    self._servicer_context = servicer_context
+
+  def is_active(self):
+    return self._servicer_context.is_active()
+
+  def time_remaining(self):
+    return self._servicer_context.time_remaining()
+
+  def add_abortion_callback(self, abortion_callback):
+    raise NotImplementedError(
+        'add_abortion_callback no longer supported server-side!')
+
+  def cancel(self):
+    self._servicer_context.cancel()
+
+  def protocol_context(self):
+    return _ServerProtocolContext(self._servicer_context)
+
+  def invocation_metadata(self):
+    return self._servicer_context.invocation_metadata()
+
+  def initial_metadata(self, initial_metadata):
+    self._servicer_context.send_initial_metadata(initial_metadata)
+
+  def terminal_metadata(self, terminal_metadata):
+    self._servicer_context.set_terminal_metadata(terminal_metadata)
+
+  def code(self, code):
+    self._servicer_context.set_code(code)
+
+  def details(self, details):
+    self._servicer_context.set_details(details)
+
+
+def _adapt_unary_request_inline(unary_request_inline):
+  def adaptation(request, servicer_context):
+    return unary_request_inline(request, _FaceServicerContext(servicer_context))
+  return adaptation
+
+
+def _adapt_stream_request_inline(stream_request_inline):
+  def adaptation(request_iterator, servicer_context):
+    return stream_request_inline(
+        request_iterator, _FaceServicerContext(servicer_context))
+  return adaptation
+
+
+class _Callback(stream.Consumer):
+
+  def __init__(self):
+    self._condition = threading.Condition()
+    self._values = []
+    self._terminated = False
+    self._cancelled = False
+
+  def consume(self, value):
+    with self._condition:
+      self._values.append(value)
+      self._condition.notify_all()
+
+  def terminate(self):
+    with self._condition:
+      self._terminated = True
+      self._condition.notify_all()
+
+  def consume_and_terminate(self, value):
+    with self._condition:
+      self._values.append(value)
+      self._terminated = True
+      self._condition.notify_all()
+
+  def cancel(self):
+    with self._condition:
+      self._cancelled = True
+      self._condition.notify_all()
+
+  def draw_one_value(self):
+    with self._condition:
+      while True:
+        if self._cancelled:
+          raise abandonment.Abandoned()
+        elif self._values:
+          return self._values.pop(0)
+        elif self._terminated:
+          return None
+        else:
+          self._condition.wait()
+
+  def draw_all_values(self):
+    with self._condition:
+      while True:
+        if self._cancelled:
+          raise abandonment.Abandoned()
+        elif self._terminated:
+          all_values = tuple(self._values)
+          self._values = None
+          return all_values
+        else:
+          self._condition.wait()
+
+
+def _pipe_requests(request_iterator, request_consumer, servicer_context):
+  for request in request_iterator:
+    if not servicer_context.is_active():
+      return
+    request_consumer.consume(request)
+    if not servicer_context.is_active():
+      return
+  request_consumer.terminate()
+
+
+def _adapt_unary_unary_event(unary_unary_event):
+  def adaptation(request, servicer_context):
+    callback = _Callback()
+    if not servicer_context.add_callback(callback.cancel):
+      raise abandonment.Abandoned()
+    unary_unary_event(
+        request, callback.consume_and_terminate,
+        _FaceServicerContext(servicer_context))
+    return callback.draw_all_values()[0]
+  return adaptation
+
+
+def _adapt_unary_stream_event(unary_stream_event):
+  def adaptation(request, servicer_context):
+    callback = _Callback()
+    if not servicer_context.add_callback(callback.cancel):
+      raise abandonment.Abandoned()
+    unary_stream_event(
+        request, callback, _FaceServicerContext(servicer_context))
+    while True:
+      response = callback.draw_one_value()
+      if response is None:
+        return
+      else:
+        yield response
+  return adaptation
+
+
+def _adapt_stream_unary_event(stream_unary_event):
+  def adaptation(request_iterator, servicer_context):
+    callback = _Callback()
+    if not servicer_context.add_callback(callback.cancel):
+      raise abandonment.Abandoned()
+    request_consumer = stream_unary_event(
+        callback.consume_and_terminate, _FaceServicerContext(servicer_context))
+    request_pipe_thread = threading.Thread(
+        target=_pipe_requests,
+        args=(request_iterator, request_consumer, servicer_context,))
+    request_pipe_thread.start()
+    return callback.draw_all_values()[0]
+  return adaptation
+
+
+def _adapt_stream_stream_event(stream_stream_event):
+  def adaptation(request_iterator, servicer_context):
+    callback = _Callback()
+    if not servicer_context.add_callback(callback.cancel):
+      raise abandonment.Abandoned()
+    request_consumer = stream_stream_event(
+        callback, _FaceServicerContext(servicer_context))
+    request_pipe_thread = threading.Thread(
+        target=_pipe_requests,
+        args=(request_iterator, request_consumer, servicer_context,))
+    request_pipe_thread.start()
+    while True:
+      response = callback.draw_one_value()
+      if response is None:
+        return
+      else:
+        yield response
+  return adaptation
+
+
+class _SimpleMethodHandler(
+    collections.namedtuple(
+        '_MethodHandler',
+        ('request_streaming', 'response_streaming', 'request_deserializer',
+         'response_serializer', 'unary_unary', 'unary_stream', 'stream_unary',
+         'stream_stream',)),
+    grpc.RpcMethodHandler):
+  pass
+
+
+def _simple_method_handler(
+    implementation, request_deserializer, response_serializer):
+  if implementation.style is style.Service.INLINE:
+    if implementation.cardinality is cardinality.Cardinality.UNARY_UNARY:
+      return _SimpleMethodHandler(
+          False, False, request_deserializer, response_serializer,
+          _adapt_unary_request_inline(implementation.unary_unary_inline), None,
+          None, None)
+    elif implementation.cardinality is cardinality.Cardinality.UNARY_STREAM:
+      return _SimpleMethodHandler(
+          False, True, request_deserializer, response_serializer, None,
+          _adapt_unary_request_inline(implementation.unary_stream_inline), None,
+          None)
+    elif implementation.cardinality is cardinality.Cardinality.STREAM_UNARY:
+      return _SimpleMethodHandler(
+          True, False, request_deserializer, response_serializer, None, None,
+          _adapt_stream_request_inline(implementation.stream_unary_inline),
+          None)
+    elif implementation.cardinality is cardinality.Cardinality.STREAM_STREAM:
+      return _SimpleMethodHandler(
+          True, True, request_deserializer, response_serializer, None, None,
+          None,
+          _adapt_stream_request_inline(implementation.stream_stream_inline))
+  elif implementation.style is style.Service.EVENT:
+    if implementation.cardinality is cardinality.Cardinality.UNARY_UNARY:
+      return _SimpleMethodHandler(
+          False, False, request_deserializer, response_serializer,
+          _adapt_unary_unary_event(implementation.unary_unary_event), None,
+          None, None)
+    elif implementation.cardinality is cardinality.Cardinality.UNARY_STREAM:
+      return _SimpleMethodHandler(
+          False, True, request_deserializer, response_serializer, None,
+          _adapt_unary_stream_event(implementation.unary_stream_event), None,
+          None)
+    elif implementation.cardinality is cardinality.Cardinality.STREAM_UNARY:
+      return _SimpleMethodHandler(
+          True, False, request_deserializer, response_serializer, None, None,
+          _adapt_stream_unary_event(implementation.stream_unary_event), None)
+    elif implementation.cardinality is cardinality.Cardinality.STREAM_STREAM:
+      return _SimpleMethodHandler(
+          True, True, request_deserializer, response_serializer, None, None,
+          None, _adapt_stream_stream_event(implementation.stream_stream_event))
+
+
+def _flatten_method_pair_map(method_pair_map):
+  method_pair_map = method_pair_map or {}
+  flat_map = {}
+  for method_pair in method_pair_map:
+    method = _common.fully_qualified_method(method_pair[0], method_pair[1])
+    flat_map[method] = method_pair_map[method_pair]
+  return flat_map
+
+
+class _GenericRpcHandler(grpc.GenericRpcHandler):
+
+  def __init__(
+      self, method_implementations, multi_method_implementation,
+      request_deserializers, response_serializers):
+    self._method_implementations = _flatten_method_pair_map(
+        method_implementations)
+    self._request_deserializers = _flatten_method_pair_map(
+        request_deserializers)
+    self._response_serializers = _flatten_method_pair_map(
+        response_serializers)
+    self._multi_method_implementation = multi_method_implementation
+
+  def service(self, handler_call_details):
+    method_implementation = self._method_implementations.get(
+        handler_call_details.method)
+    if method_implementation is not None:
+      return _simple_method_handler(
+          method_implementation,
+          self._request_deserializers.get(handler_call_details.method),
+          self._response_serializers.get(handler_call_details.method))
+    elif self._multi_method_implementation is None:
+      return None
+    else:
+      try:
+        return None  #TODO(nathaniel): call the multimethod.
+      except face.NoSuchMethodError:
+        return None
+
+
+class _Server(interfaces.Server):
+
+  def __init__(self, server):
+    self._server = server
+
+  def add_insecure_port(self, address):
+    return self._server.add_insecure_port(address)
+
+  def add_secure_port(self, address, server_credentials):
+    return self._server.add_secure_port(address, server_credentials)
+
+  def start(self):
+    self._server.start()
+
+  def stop(self, grace):
+    return self._server.stop(grace)
+
+  def __enter__(self):
+    self._server.start()
+    return self
+
+  def __exit__(self, exc_type, exc_val, exc_tb):
+    self._server.stop(None)
+    return False
+
+
+def server(
+    service_implementations, multi_method_implementation, request_deserializers,
+    response_serializers, thread_pool, thread_pool_size):
+  generic_rpc_handler = _GenericRpcHandler(
+      service_implementations, multi_method_implementation,
+      request_deserializers, response_serializers)
+  if thread_pool is None:
+    effective_thread_pool = logging_pool.pool(
+        _DEFAULT_POOL_SIZE if thread_pool_size is None else thread_pool_size)
+  else:
+    effective_thread_pool = thread_pool
+  return _Server(grpc.server((generic_rpc_handler,), effective_thread_pool))
diff --git a/src/python/grpcio/grpc/beta/implementations.py b/src/python/grpcio/grpc/beta/implementations.py
index 822f593..4ae6e7d 100644
--- a/src/python/grpcio/grpc/beta/implementations.py
+++ b/src/python/grpcio/grpc/beta/implementations.py
@@ -35,112 +35,36 @@
 import threading  # pylint: disable=unused-import
 
 # cardinality and face are referenced from specification in this module.
-from grpc._adapter import _intermediary_low
-from grpc._adapter import _low
+import grpc
+from grpc import _auth
 from grpc._adapter import _types
-from grpc.beta import _connectivity_channel
-from grpc.beta import _server
-from grpc.beta import _stub
+from grpc.beta import _client_adaptations
+from grpc.beta import _server_adaptations
 from grpc.beta import interfaces
 from grpc.framework.common import cardinality  # pylint: disable=unused-import
 from grpc.framework.interfaces.face import face  # pylint: disable=unused-import
 
-_CHANNEL_SUBSCRIPTION_CALLBACK_ERROR_LOG_MESSAGE = (
-    'Exception calling channel subscription callback!')
+
+ChannelCredentials = grpc.ChannelCredentials
+ssl_channel_credentials = grpc.ssl_channel_credentials
+CallCredentials = grpc.CallCredentials
+metadata_call_credentials = grpc.metadata_call_credentials
 
 
-class ChannelCredentials(object):
-  """A value encapsulating the data required to create a secure Channel.
-
-  This class and its instances have no supported interface - it exists to define
-  the type of its instances and its instances exist to be passed to other
-  functions.
-  """
-
-  def __init__(self, low_credentials):
-    self._low_credentials = low_credentials
-
-
-def ssl_channel_credentials(root_certificates=None, private_key=None,
-                            certificate_chain=None):
-  """Creates a ChannelCredentials for use with an SSL-enabled Channel.
+def google_call_credentials(credentials):
+  """Construct CallCredentials from GoogleCredentials.
 
   Args:
-    root_certificates: The PEM-encoded root certificates or unset to ask for
-      them to be retrieved from a default location.
-    private_key: The PEM-encoded private key to use or unset if no private key
-      should be used.
-    certificate_chain: The PEM-encoded certificate chain to use or unset if no
-      certificate chain should be used.
-
-  Returns:
-    A ChannelCredentials for use with an SSL-enabled Channel.
-  """
-  return ChannelCredentials(_low.channel_credentials_ssl(
-      root_certificates, private_key, certificate_chain))
-
-
-class CallCredentials(object):
-  """A value encapsulating data asserting an identity over an *established*
-  channel. May be composed with ChannelCredentials to always assert identity for
-  every call over that channel.
-
-  This class and its instances have no supported interface - it exists to define
-  the type of its instances and its instances exist to be passed to other
-  functions.
-  """
-
-  def __init__(self, low_credentials):
-    self._low_credentials = low_credentials
-
-
-def metadata_call_credentials(metadata_plugin, name=None):
-  """Construct CallCredentials from an interfaces.GRPCAuthMetadataPlugin.
-
-  Args:
-    metadata_plugin: An interfaces.GRPCAuthMetadataPlugin to use in constructing
-      the CallCredentials object.
+    credentials: A GoogleCredentials object from the oauth2client library.
 
   Returns:
     A CallCredentials object for use in a GRPCCallOptions object.
   """
-  if name is None:
-    name = metadata_plugin.__name__
-  return CallCredentials(
-      _low.call_credentials_metadata_plugin(metadata_plugin, name))
+  return metadata_call_credentials(_auth.GoogleCallCredentials(credentials))
 
-def composite_call_credentials(call_credentials, additional_call_credentials):
-  """Compose two CallCredentials to make a new one.
-
-  Args:
-    call_credentials: A CallCredentials object.
-    additional_call_credentials: Another CallCredentials object to compose on
-      top of call_credentials.
-
-  Returns:
-    A CallCredentials object for use in a GRPCCallOptions object.
-  """
-  return CallCredentials(
-      _low.call_credentials_composite(
-          call_credentials._low_credentials,
-          additional_call_credentials._low_credentials))
-
-def composite_channel_credentials(channel_credentials,
-                                 additional_call_credentials):
-  """Compose ChannelCredentials on top of client credentials to make a new one.
-
-  Args:
-    channel_credentials: A ChannelCredentials object.
-    additional_call_credentials: A CallCredentials object to compose on
-      top of channel_credentials.
-
-  Returns:
-    A ChannelCredentials object for use in a GRPCCallOptions object.
-  """
-  return ChannelCredentials(
-      _low.channel_credentials_composite(
-          channel_credentials._low_credentials,
-          additional_call_credentials._low_credentials))
+access_token_call_credentials = grpc.access_token_call_credentials
+composite_call_credentials = grpc.composite_call_credentials
+composite_channel_credentials = grpc.composite_channel_credentials
 
 
 class Channel(object):
@@ -151,11 +75,8 @@
   unsupported.
   """
 
-  def __init__(self, low_channel, intermediary_low_channel):
-    self._low_channel = low_channel
-    self._intermediary_low_channel = intermediary_low_channel
-    self._connectivity_channel = _connectivity_channel.ConnectivityChannel(
-        low_channel)
+  def __init__(self, channel):
+    self._channel = channel
 
   def subscribe(self, callback, try_to_connect=None):
     """Subscribes to this Channel's connectivity.
@@ -170,7 +91,7 @@
         attempt to connect if it is not already connected and ready to conduct
         RPCs.
     """
-    self._connectivity_channel.subscribe(callback, try_to_connect)
+    self._channel.subscribe(callback, try_to_connect=try_to_connect)
 
   def unsubscribe(self, callback):
     """Unsubscribes a callback from this Channel's connectivity.
@@ -179,7 +100,7 @@
       callback: A callable previously registered with this Channel from having
         been passed to its "subscribe" method.
     """
-    self._connectivity_channel.unsubscribe(callback)
+    self._channel.unsubscribe(callback)
 
 
 def insecure_channel(host, port):
@@ -193,9 +114,9 @@
   Returns:
     A Channel to the remote host through which RPCs may be conducted.
   """
-  intermediary_low_channel = _intermediary_low.Channel(
-      '%s:%d' % (host, port) if port else host, None)
-  return Channel(intermediary_low_channel._internal, intermediary_low_channel)  # pylint: disable=protected-access
+  channel = grpc.insecure_channel(
+      host if port is None else '%s:%d' % (host, port))
+  return Channel(channel)
 
 
 def secure_channel(host, port, channel_credentials):
@@ -210,10 +131,9 @@
   Returns:
     A secure Channel to the remote host through which RPCs may be conducted.
   """
-  intermediary_low_channel = _intermediary_low.Channel(
-      '%s:%d' % (host, port) if port else host,
-      channel_credentials._low_credentials)
-  return Channel(intermediary_low_channel._internal, intermediary_low_channel)  # pylint: disable=protected-access
+  channel = grpc.secure_channel(
+      host if port is None else '%s:%d' % (host, port), channel_credentials)
+  return Channel(channel)
 
 
 class StubOptions(object):
@@ -277,12 +197,11 @@
     A face.GenericStub on which RPCs can be made.
   """
   effective_options = _EMPTY_STUB_OPTIONS if options is None else options
-  return _stub.generic_stub(
-      channel._intermediary_low_channel, effective_options.host,  # pylint: disable=protected-access
-      effective_options.metadata_transformer,
+  return _client_adaptations.generic_stub(
+      channel._channel,  # pylint: disable=protected-access
+      effective_options.host, effective_options.metadata_transformer,
       effective_options.request_serializers,
-      effective_options.response_deserializers, effective_options.thread_pool,
-      effective_options.thread_pool_size)
+      effective_options.response_deserializers)
 
 
 def dynamic_stub(channel, service, cardinalities, options=None):
@@ -300,55 +219,16 @@
     A face.DynamicStub with which RPCs can be invoked.
   """
   effective_options = StubOptions() if options is None else options
-  return _stub.dynamic_stub(
-      channel._intermediary_low_channel, effective_options.host, service,  # pylint: disable=protected-access
-      cardinalities, effective_options.metadata_transformer,
+  return _client_adaptations.dynamic_stub(
+      channel._channel,  # pylint: disable=protected-access
+      service, cardinalities, effective_options.host,
+      effective_options.metadata_transformer,
       effective_options.request_serializers,
-      effective_options.response_deserializers, effective_options.thread_pool,
-      effective_options.thread_pool_size)
+      effective_options.response_deserializers)
 
 
-class ServerCredentials(object):
-  """A value encapsulating the data required to open a secure port on a Server.
-
-  This class and its instances have no supported interface - it exists to define
-  the type of its instances and its instances exist to be passed to other
-  functions.
-  """
-
-  def __init__(self, low_credentials):
-    self._low_credentials = low_credentials
-
-
-def ssl_server_credentials(
-    private_key_certificate_chain_pairs, root_certificates=None,
-    require_client_auth=False):
-  """Creates a ServerCredentials for use with an SSL-enabled Server.
-
-  Args:
-    private_key_certificate_chain_pairs: A nonempty sequence each element of
-      which is a pair the first element of which is a PEM-encoded private key
-      and the second element of which is the corresponding PEM-encoded
-      certificate chain.
-    root_certificates: PEM-encoded client root certificates to be used for
-      verifying authenticated clients. If omitted, require_client_auth must also
-      be omitted or be False.
-    require_client_auth: A boolean indicating whether or not to require clients
-      to be authenticated. May only be True if root_certificates is not None.
-
-  Returns:
-    A ServerCredentials for use with an SSL-enabled Server.
-  """
-  if len(private_key_certificate_chain_pairs) == 0:
-    raise ValueError(
-        'At least one private key-certificate chain pairis required!')
-  elif require_client_auth and root_certificates is None:
-    raise ValueError(
-        'Illegal to require client auth without providing root certificates!')
-  else:
-    return ServerCredentials(_low.server_credentials_ssl(
-        root_certificates, private_key_certificate_chain_pairs,
-        require_client_auth))
+ServerCredentials = grpc.ServerCredentials
+ssl_server_credentials = grpc.ssl_server_credentials
 
 
 class ServerOptions(object):
@@ -421,9 +301,8 @@
     An interfaces.Server with which RPCs can be serviced.
   """
   effective_options = _EMPTY_SERVER_OPTIONS if options is None else options
-  return _server.server(
+  return _server_adaptations.server(
       service_implementations, effective_options.multi_method_implementation,
       effective_options.request_deserializers,
       effective_options.response_serializers, effective_options.thread_pool,
-      effective_options.thread_pool_size, effective_options.default_timeout,
-      effective_options.maximum_timeout)
+      effective_options.thread_pool_size)
diff --git a/src/python/grpcio/grpc/beta/interfaces.py b/src/python/grpcio/grpc/beta/interfaces.py
index 24de9ad..4343b6c 100644
--- a/src/python/grpcio/grpc/beta/interfaces.py
+++ b/src/python/grpcio/grpc/beta/interfaces.py
@@ -30,53 +30,13 @@
 """Constants and interfaces of the Beta API of gRPC Python."""
 
 import abc
-import enum
 
 import six
 
-from grpc._adapter import _types
+import grpc
 
-
-@enum.unique
-class ChannelConnectivity(enum.Enum):
-  """Mirrors grpc_connectivity_state in the gRPC Core.
-
-  Attributes:
-    IDLE: The channel is idle.
-    CONNECTING: The channel is connecting.
-    READY: The channel is ready to conduct RPCs.
-    TRANSIENT_FAILURE: The channel has seen a failure from which it expects to
-      recover.
-    FATAL_FAILURE: The channel has seen a failure from which it cannot recover.
-  """
-  IDLE = (_types.ConnectivityState.IDLE, 'idle',)
-  CONNECTING = (_types.ConnectivityState.CONNECTING, 'connecting',)
-  READY = (_types.ConnectivityState.READY, 'ready',)
-  TRANSIENT_FAILURE = (
-      _types.ConnectivityState.TRANSIENT_FAILURE, 'transient failure',)
-  FATAL_FAILURE = (_types.ConnectivityState.FATAL_FAILURE, 'fatal failure',)
-
-
-@enum.unique
-class StatusCode(enum.Enum):
-  """Mirrors grpc_status_code in the C core."""
-  OK                  = 0
-  CANCELLED           = 1
-  UNKNOWN             = 2
-  INVALID_ARGUMENT    = 3
-  DEADLINE_EXCEEDED   = 4
-  NOT_FOUND           = 5
-  ALREADY_EXISTS      = 6
-  PERMISSION_DENIED   = 7
-  RESOURCE_EXHAUSTED  = 8
-  FAILED_PRECONDITION = 9
-  ABORTED             = 10
-  OUT_OF_RANGE        = 11
-  UNIMPLEMENTED       = 12
-  INTERNAL            = 13
-  UNAVAILABLE         = 14
-  DATA_LOSS           = 15
-  UNAUTHENTICATED     = 16
+ChannelConnectivity = grpc.ChannelConnectivity
+StatusCode = grpc.StatusCode
 
 
 class GRPCCallOptions(object):
@@ -106,46 +66,9 @@
   """
   return GRPCCallOptions(disable_compression, None, credentials)
 
-
-class GRPCAuthMetadataContext(six.with_metaclass(abc.ABCMeta)):
-  """Provides information to call credentials metadata plugins.
-
-  Attributes:
-    service_url: A string URL of the service being called into.
-    method_name: A string of the fully qualified method name being called.
-  """
-
-
-class GRPCAuthMetadataPluginCallback(six.with_metaclass(abc.ABCMeta)):
-  """Callback object received by a metadata plugin."""
-
-  def __call__(self, metadata, error):
-    """Inform the gRPC runtime of the metadata to construct a CallCredentials.
-
-    Args:
-      metadata: An iterable of 2-sequences (e.g. tuples) of metadata key/value
-        pairs.
-      error: An Exception to indicate error or None to indicate success.
-    """
-    raise NotImplementedError()
-
-
-class GRPCAuthMetadataPlugin(six.with_metaclass(abc.ABCMeta)):
-  """
-  """
-
-  def __call__(self, context, callback):
-    """Invoke the plugin.
-
-    Must not block. Need only be called by the gRPC runtime.
-
-    Args:
-      context: A GRPCAuthMetadataContext providing information on what the
-        plugin is being used for.
-      callback: A GRPCAuthMetadataPluginCallback to be invoked either
-        synchronously or asynchronously.
-    """
-    raise NotImplementedError()
+GRPCAuthMetadataContext = grpc.AuthMetadataContext
+GRPCAuthMetadataPluginCallback = grpc.AuthMetadataPluginCallback
+GRPCAuthMetadataPlugin = grpc.AuthMetadataPlugin
 
 
 class GRPCServicerContext(six.with_metaclass(abc.ABCMeta)):
diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py
index be24dc7..1a04021 100644
--- a/src/python/grpcio/grpc_core_dependencies.py
+++ b/src/python/grpcio/grpc_core_dependencies.py
@@ -42,7 +42,7 @@
   'src/core/lib/support/cpu_windows.c',
   'src/core/lib/support/env_linux.c',
   'src/core/lib/support/env_posix.c',
-  'src/core/lib/support/env_win32.c',
+  'src/core/lib/support/env_windows.c',
   'src/core/lib/support/histogram.c',
   'src/core/lib/support/host_port.c',
   'src/core/lib/support/load_file.c',
@@ -50,31 +50,31 @@
   'src/core/lib/support/log_android.c',
   'src/core/lib/support/log_linux.c',
   'src/core/lib/support/log_posix.c',
-  'src/core/lib/support/log_win32.c',
+  'src/core/lib/support/log_windows.c',
   'src/core/lib/support/murmur_hash.c',
   'src/core/lib/support/slice.c',
   'src/core/lib/support/slice_buffer.c',
   'src/core/lib/support/stack_lockfree.c',
   'src/core/lib/support/string.c',
   'src/core/lib/support/string_posix.c',
-  'src/core/lib/support/string_util_win32.c',
-  'src/core/lib/support/string_win32.c',
+  'src/core/lib/support/string_util_windows.c',
+  'src/core/lib/support/string_windows.c',
   'src/core/lib/support/subprocess_posix.c',
   'src/core/lib/support/subprocess_windows.c',
   'src/core/lib/support/sync.c',
   'src/core/lib/support/sync_posix.c',
-  'src/core/lib/support/sync_win32.c',
+  'src/core/lib/support/sync_windows.c',
   'src/core/lib/support/thd.c',
   'src/core/lib/support/thd_posix.c',
-  'src/core/lib/support/thd_win32.c',
+  'src/core/lib/support/thd_windows.c',
   'src/core/lib/support/time.c',
   'src/core/lib/support/time_posix.c',
   'src/core/lib/support/time_precise.c',
-  'src/core/lib/support/time_win32.c',
+  'src/core/lib/support/time_windows.c',
   'src/core/lib/support/tls_pthread.c',
   'src/core/lib/support/tmpfile_msys.c',
   'src/core/lib/support/tmpfile_posix.c',
-  'src/core/lib/support/tmpfile_win32.c',
+  'src/core/lib/support/tmpfile_windows.c',
   'src/core/lib/support/wrap_memcpy.c',
   'src/core/lib/surface/init.c',
   'src/core/lib/channel/channel_args.c',
@@ -84,7 +84,7 @@
   'src/core/lib/channel/connected_channel.c',
   'src/core/lib/channel/http_client_filter.c',
   'src/core/lib/channel/http_server_filter.c',
-  'src/core/lib/compression/compression_algorithm.c',
+  'src/core/lib/compression/compression.c',
   'src/core/lib/compression/message_compress.c',
   'src/core/lib/debug/trace.c',
   'src/core/lib/http/format_request.c',
@@ -94,6 +94,7 @@
   'src/core/lib/iomgr/endpoint.c',
   'src/core/lib/iomgr/endpoint_pair_posix.c',
   'src/core/lib/iomgr/endpoint_pair_windows.c',
+  'src/core/lib/iomgr/ev_poll_and_epoll_posix.c',
   'src/core/lib/iomgr/ev_poll_posix.c',
   'src/core/lib/iomgr/ev_posix.c',
   'src/core/lib/iomgr/exec_ctx.c',
@@ -102,6 +103,7 @@
   'src/core/lib/iomgr/iomgr.c',
   'src/core/lib/iomgr/iomgr_posix.c',
   'src/core/lib/iomgr/iomgr_windows.c',
+  'src/core/lib/iomgr/polling_entity.c',
   'src/core/lib/iomgr/pollset_set_windows.c',
   'src/core/lib/iomgr/pollset_windows.c',
   'src/core/lib/iomgr/resolve_address_posix.c',
@@ -188,7 +190,7 @@
   'src/core/lib/security/credentials/credentials_metadata.c',
   'src/core/lib/security/credentials/fake/fake_credentials.c',
   'src/core/lib/security/credentials/google_default/credentials_posix.c',
-  'src/core/lib/security/credentials/google_default/credentials_win32.c',
+  'src/core/lib/security/credentials/google_default/credentials_windows.c',
   'src/core/lib/security/credentials/google_default/google_default_credentials.c',
   'src/core/lib/security/credentials/iam/iam_credentials.c',
   'src/core/lib/security/credentials/jwt/json_token.c',
@@ -229,10 +231,9 @@
   'src/core/ext/client_config/subchannel_index.c',
   'src/core/ext/client_config/uri_parser.c',
   'src/core/ext/transport/chttp2/server/insecure/server_chttp2.c',
+  'src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.c',
   'src/core/ext/transport/chttp2/client/insecure/channel_create.c',
-  'src/core/ext/transport/cronet/client/secure/cronet_channel_create.c',
-  'src/core/ext/transport/cronet/transport/cronet_api_dummy.c',
-  'src/core/ext/transport/cronet/transport/cronet_transport.c',
+  'src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c',
   'src/core/ext/lb_policy/grpclb/load_balancer_api.c',
   'src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c',
   'third_party/nanopb/pb_common.c',
@@ -242,7 +243,10 @@
   'src/core/ext/lb_policy/round_robin/round_robin.c',
   'src/core/ext/resolver/dns/native/dns_resolver.c',
   'src/core/ext/resolver/sockaddr/sockaddr_resolver.c',
+  'src/core/ext/load_reporting/load_reporting.c',
+  'src/core/ext/load_reporting/load_reporting_filter.c',
   'src/core/ext/census/context.c',
+  'src/core/ext/census/gen/census.pb.c',
   'src/core/ext/census/grpc_context.c',
   'src/core/ext/census/grpc_filter.c',
   'src/core/ext/census/grpc_plugin.c',
diff --git a/src/python/grpcio/tests/interop/client.py b/src/python/grpcio/tests/interop/client.py
index db29eb4..8aa1ce3 100644
--- a/src/python/grpcio/tests/interop/client.py
+++ b/src/python/grpcio/tests/interop/client.py
@@ -65,39 +65,37 @@
       help='email address of the default service account', type=str)
   return parser.parse_args()
 
-def _oauth_access_token(args):
-  credentials = oauth2client_client.GoogleCredentials.get_application_default()
-  scoped_credentials = credentials.create_scoped([args.oauth_scope])
-  return scoped_credentials.get_access_token().access_token
 
 def _stub(args):
-  if args.oauth_scope:
-    if args.test_case == 'oauth2_auth_token':
-      # TODO(jtattermusch): This testcase sets the auth metadata key-value
-      # manually, which also means that the user would need to do the same
-      # thing every time he/she would like to use and out of band oauth token.
-      # The transformer function that produces the metadata key-value from
-      # the access token should be provided by gRPC auth library.
-      access_token = _oauth_access_token(args)
-      metadata_transformer = lambda x: [
-          ('authorization', 'Bearer %s' % access_token)]
-    else:
-      metadata_transformer = lambda x: [
-          ('authorization', 'Bearer %s' % _oauth_access_token(args))]
+  if args.test_case == 'oauth2_auth_token':
+    creds = oauth2client_client.GoogleCredentials.get_application_default()
+    scoped_creds = creds.create_scoped([args.oauth_scope])
+    access_token = scoped_creds.get_access_token().access_token
+    call_creds = implementations.access_token_call_credentials(access_token)
+  elif args.test_case == 'compute_engine_creds':
+    creds = oauth2client_client.GoogleCredentials.get_application_default()
+    scoped_creds = creds.create_scoped([args.oauth_scope])
+    call_creds = implementations.google_call_credentials(scoped_creds)
+  elif args.test_case == 'jwt_token_creds':
+    creds = oauth2client_client.GoogleCredentials.get_application_default()
+    call_creds = implementations.google_call_credentials(creds)
   else:
-    metadata_transformer = lambda x: []
+    call_creds = None
   if args.use_tls:
     if args.use_test_ca:
       root_certificates = resources.test_root_certificates()
     else:
       root_certificates = None  # will load default roots.
 
+    channel_creds = implementations.ssl_channel_credentials(root_certificates)
+    if call_creds is not None:
+      channel_creds = implementations.composite_channel_credentials(
+          channel_creds, call_creds)
+
     channel = test_utilities.not_really_secure_channel(
-        args.server_host, args.server_port,
-        implementations.ssl_channel_credentials(root_certificates),
+        args.server_host, args.server_port, channel_creds,
         args.server_host_override)
-    stub = test_pb2.beta_create_TestService_stub(
-        channel, metadata_transformer=metadata_transformer)
+    stub = test_pb2.beta_create_TestService_stub(channel)
   else:
     channel = implementations.insecure_channel(
         args.server_host, args.server_port)
diff --git a/src/python/grpcio/tests/interop/methods.py b/src/python/grpcio/tests/interop/methods.py
index 67862ed..7eac511 100644
--- a/src/python/grpcio/tests/interop/methods.py
+++ b/src/python/grpcio/tests/interop/methods.py
@@ -39,6 +39,8 @@
 
 from oauth2client import client as oauth2client_client
 
+from grpc.beta import implementations
+from grpc.beta import interfaces
 from grpc.framework.common import cardinality
 from grpc.framework.interfaces.face import face
 
@@ -88,13 +90,15 @@
     return self.FullDuplexCall(request_iterator, context)
 
 
-def _large_unary_common_behavior(stub, fill_username, fill_oauth_scope):
+def _large_unary_common_behavior(stub, fill_username, fill_oauth_scope,
+                                 protocol_options=None):
   with stub:
     request = messages_pb2.SimpleRequest(
         response_type=messages_pb2.COMPRESSABLE, response_size=314159,
         payload=messages_pb2.Payload(body=b'\x00' * 271828),
         fill_username=fill_username, fill_oauth_scope=fill_oauth_scope)
-    response_future = stub.UnaryCall.future(request, _TIMEOUT)
+    response_future = stub.UnaryCall.future(request, _TIMEOUT,
+                                            protocol_options=protocol_options)
     response = response_future.result()
     if response.payload.type is not messages_pb2.COMPRESSABLE:
       raise ValueError(
@@ -303,7 +307,34 @@
   if args.oauth_scope.find(response.oauth_scope) == -1:
     raise ValueError(
         'expected to find oauth scope "%s" in received "%s"' %
-            (response.oauth_scope, args.oauth_scope))
+        (response.oauth_scope, args.oauth_scope))
+
+
+def _jwt_token_creds(stub, args):
+  json_key_filename = os.environ[
+      oauth2client_client.GOOGLE_APPLICATION_CREDENTIALS]
+  wanted_email = json.load(open(json_key_filename, 'rb'))['client_email']
+  response = _large_unary_common_behavior(stub, True, False)
+  if wanted_email != response.username:
+    raise ValueError(
+        'expected username %s, got %s' % (wanted_email, response.username))
+
+
+def _per_rpc_creds(stub, args):
+  json_key_filename = os.environ[
+      oauth2client_client.GOOGLE_APPLICATION_CREDENTIALS]
+  wanted_email = json.load(open(json_key_filename, 'rb'))['client_email']
+  credentials = oauth2client_client.GoogleCredentials.get_application_default()
+  scoped_credentials = credentials.create_scoped([args.oauth_scope])
+  call_creds = implementations.google_call_credentials(scoped_credentials)
+  options = interfaces.grpc_call_options(disable_compression=False,
+                                         credentials=call_creds)
+  response = _large_unary_common_behavior(stub, True, False,
+                                          protocol_options=options)
+  if wanted_email != response.username:
+    raise ValueError(
+        'expected username %s, got %s' % (wanted_email, response.username))
+
 
 @enum.unique
 class TestCase(enum.Enum):
@@ -317,6 +348,8 @@
   EMPTY_STREAM = 'empty_stream'
   COMPUTE_ENGINE_CREDS = 'compute_engine_creds'
   OAUTH2_AUTH_TOKEN = 'oauth2_auth_token'
+  JWT_TOKEN_CREDS = 'jwt_token_creds'
+  PER_RPC_CREDS = 'per_rpc_creds'
   TIMEOUT_ON_SLEEPING_SERVER = 'timeout_on_sleeping_server'
 
   def test_interoperability(self, stub, args):
@@ -342,5 +375,9 @@
       _compute_engine_creds(stub, args)
     elif self is TestCase.OAUTH2_AUTH_TOKEN:
       _oauth2_auth_token(stub, args)
+    elif self is TestCase.JWT_TOKEN_CREDS:
+      _jwt_token_creds(stub, args)
+    elif self is TestCase.PER_RPC_CREDS:
+      _per_rpc_creds(stub, args)
     else:
       raise NotImplementedError('Test case "%s" not implemented!' % self.name)
diff --git a/src/python/grpcio/tests/qps/benchmark_client.py b/src/python/grpcio/tests/qps/benchmark_client.py
index b372ea0..1b100bb 100644
--- a/src/python/grpcio/tests/qps/benchmark_client.py
+++ b/src/python/grpcio/tests/qps/benchmark_client.py
@@ -31,12 +31,9 @@
 
 import abc
 import time
-try:
-  import Queue as queue  # Python 2.x
-except ImportError:
-  import queue  # Python 3
 
 from concurrent import futures
+from six.moves import queue
 
 from grpc.beta import implementations
 from grpc.framework.interfaces.face import face
@@ -82,6 +79,7 @@
     self._response_callbacks = []
 
   def add_response_callback(self, callback):
+    """callback will be invoked as callback(client, query_time)"""
     self._response_callbacks.append(callback)
 
   @abc.abstractmethod
@@ -95,10 +93,10 @@
   def stop(self):
     pass
 
-  def _handle_response(self, query_time):
+  def _handle_response(self, client, query_time):
     self._hist.add(query_time * 1e9)  # Report times in nanoseconds
     for callback in self._response_callbacks:
-      callback(query_time)
+      callback(client, query_time)
 
 
 class UnarySyncBenchmarkClient(BenchmarkClient):
@@ -121,7 +119,7 @@
     start_time = time.time()
     self._stub.UnaryCall(self._request, _TIMEOUT)
     end_time = time.time()
-    self._handle_response(end_time - start_time)
+    self._handle_response(self, end_time - start_time)
 
 
 class UnaryAsyncBenchmarkClient(BenchmarkClient):
@@ -136,19 +134,20 @@
   def _response_received(self, start_time, resp):
     resp.result()
     end_time = time.time()
-    self._handle_response(end_time - start_time)
+    self._handle_response(self, end_time - start_time)
 
   def stop(self):
     self._stub = None
 
 
-class StreamingSyncBenchmarkClient(BenchmarkClient):
+class _SyncStream(object):
 
-  def __init__(self, server, config, hist):
-    super(StreamingSyncBenchmarkClient, self).__init__(server, config, hist)
+  def __init__(self, stub, generic, request, handle_response):
+    self._stub = stub
+    self._generic = generic
+    self._request = request
+    self._handle_response = handle_response
     self._is_streaming = False
-    self._pool = futures.ThreadPoolExecutor(max_workers=1)
-    # Use a thread-safe queue to put requests on the stream
     self._request_queue = queue.Queue()
     self._send_time_queue = queue.Queue()
 
@@ -158,15 +157,6 @@
 
   def start(self):
     self._is_streaming = True
-    self._pool.submit(self._request_stream)
-
-  def stop(self):
-    self._is_streaming = False
-    self._pool.shutdown(wait=True)
-    self._stub = None
-
-  def _request_stream(self):
-    self._is_streaming = True
     if self._generic:
       stream_callable = self._stub.stream_stream(
           'grpc.testing.BenchmarkService', 'StreamingCall')
@@ -175,8 +165,11 @@
 
     response_stream = stream_callable(self._request_generator(), _TIMEOUT)
     for _ in response_stream:
-      end_time = time.time()
-      self._handle_response(end_time - self._send_time_queue.get_nowait())
+      self._handle_response(
+          self, time.time() - self._send_time_queue.get_nowait())
+
+  def stop(self):
+    self._is_streaming = False
 
   def _request_generator(self):
     while self._is_streaming:
@@ -187,46 +180,28 @@
         pass
 
 
-class AsyncReceiver(face.ResponseReceiver):
-  """Receiver for async stream responses."""
-
-  def __init__(self, send_time_queue, response_handler):
-    self._send_time_queue = send_time_queue
-    self._response_handler = response_handler
-
-  def initial_metadata(self, initial_mdetadata):
-    pass
-
-  def response(self, response):
-    end_time = time.time()
-    self._response_handler(end_time - self._send_time_queue.get_nowait())
-
-  def complete(self, terminal_metadata, code, details):
-    pass
-
-
-class StreamingAsyncBenchmarkClient(BenchmarkClient):
+class StreamingSyncBenchmarkClient(BenchmarkClient):
 
   def __init__(self, server, config, hist):
-    super(StreamingAsyncBenchmarkClient, self).__init__(server, config, hist)
-    self._send_time_queue = queue.Queue()
-    self._receiver = AsyncReceiver(self._send_time_queue, self._handle_response)
-    self._rendezvous = None
+    super(StreamingSyncBenchmarkClient, self).__init__(server, config, hist)
+    self._pool = futures.ThreadPoolExecutor(
+        max_workers=config.outstanding_rpcs_per_channel)
+    self._streams = [_SyncStream(self._stub, self._generic, 
+                                 self._request, self._handle_response)
+                     for _ in xrange(config.outstanding_rpcs_per_channel)]
+    self._curr_stream = 0
 
   def send_request(self):
-    if self._rendezvous is not None:
-      self._send_time_queue.put(time.time())
-      self._rendezvous.consume(self._request)
+    # Use a round_robin scheduler to determine what stream to send on
+    self._streams[self._curr_stream].send_request()
+    self._curr_stream = (self._curr_stream + 1) % len(self._streams)
 
   def start(self):
-    if self._generic:
-      stream_callable = self._stub.stream_stream(
-          'grpc.testing.BenchmarkService', 'StreamingCall')
-    else:
-      stream_callable = self._stub.StreamingCall
-    self._rendezvous = stream_callable.event(
-        self._receiver, lambda *args: None, _TIMEOUT)
+    for stream in self._streams:
+      self._pool.submit(stream.start)
 
   def stop(self):
-    self._rendezvous.terminate()
-    self._rendezvous = None
+    for stream in self._streams:
+      stream.stop()
+    self._pool.shutdown(wait=True)
+    self._stub = None
diff --git a/src/python/grpcio/tests/qps/client_runner.py b/src/python/grpcio/tests/qps/client_runner.py
index 1ede7d2..1fd5868 100644
--- a/src/python/grpcio/tests/qps/client_runner.py
+++ b/src/python/grpcio/tests/qps/client_runner.py
@@ -34,7 +34,7 @@
 """
 
 import abc
-import thread
+import threading
 import time
 
 
@@ -61,15 +61,18 @@
     super(OpenLoopClientRunner, self).__init__(client)
     self._is_running = False
     self._interval_generator = interval_generator
+    self._dispatch_thread = threading.Thread(
+        target=self._dispatch_requests, args=())
 
   def start(self):
     self._is_running = True
     self._client.start()
-    thread.start_new_thread(self._dispatch_requests, ())
-
+    self._dispatch_thread.start()
+   
   def stop(self):
     self._is_running = False
     self._client.stop()
+    self._dispatch_thread.join()
     self._client = None
 
   def _dispatch_requests(self):
@@ -98,7 +101,6 @@
     self._client.stop()
     self._client = None
 
-  def _send_request(self, response_time):
+  def _send_request(self, client, response_time):
     if self._is_running:
-      self._client.send_request()
-
+      client.send_request()
diff --git a/src/python/grpcio/tests/qps/qps_worker.py b/src/python/grpcio/tests/qps/qps_worker.py
index 3dda718..1692637 100644
--- a/src/python/grpcio/tests/qps/qps_worker.py
+++ b/src/python/grpcio/tests/qps/qps_worker.py
@@ -43,9 +43,7 @@
   server.add_insecure_port('[::]:{}'.format(port))
   server.start()
   servicer.wait_for_quit()
-  # Drain outstanding requests for clean exit
-  time.sleep(2)
-  server.stop(0)
+  server.stop(2)
 
 
 if __name__ == '__main__':
diff --git a/src/python/grpcio/tests/qps/worker_server.py b/src/python/grpcio/tests/qps/worker_server.py
index 1f9af54..d41f837 100644
--- a/src/python/grpcio/tests/qps/worker_server.py
+++ b/src/python/grpcio/tests/qps/worker_server.py
@@ -153,9 +153,8 @@
       if config.rpc_type == control_pb2.UNARY:
         client = benchmark_client.UnaryAsyncBenchmarkClient(
             server, config, qps_data)
-      elif config.rpc_type == control_pb2.STREAMING:
-        client = benchmark_client.StreamingAsyncBenchmarkClient(
-            server, config, qps_data)
+      else:
+        raise Exception('Async streaming client not supported')
     else:
       raise Exception('Unsupported client type {}'.format(config.client_type))
 
diff --git a/src/python/grpcio/tests/stress/client.py b/src/python/grpcio/tests/stress/client.py
index e2e0167..0de2532 100644
--- a/src/python/grpcio/tests/stress/client.py
+++ b/src/python/grpcio/tests/stress/client.py
@@ -30,10 +30,10 @@
 """Entry point for running stress tests."""
 
 import argparse
-import Queue
 import threading
 
 from grpc.beta import implementations
+from six.moves import queue
 from src.proto.grpc.testing import metrics_pb2
 from src.proto.grpc.testing import test_pb2
 
@@ -94,7 +94,7 @@
   test_cases = _parse_weighted_test_cases(args.test_cases)
   test_servers = args.server_addresses.split(',')
   # Propagate any client exceptions with a queue
-  exception_queue = Queue.Queue()
+  exception_queue = queue.Queue()
   stop_event = threading.Event()
   hist = histogram.Histogram(1, 1)
   runners = []
@@ -121,7 +121,7 @@
     if timeout_secs < 0:
       timeout_secs = None
     raise exception_queue.get(block=True, timeout=timeout_secs)
-  except Queue.Empty:
+  except queue.Empty:
     # No exceptions thrown, success
     pass
   finally:
diff --git a/src/python/grpcio/tests/tests.json b/src/python/grpcio/tests/tests.json
index 1beb619..53b2998 100644
--- a/src/python/grpcio/tests/tests.json
+++ b/src/python/grpcio/tests/tests.json
@@ -1,4 +1,6 @@
 [
+  "_auth_test.AccessTokenCallCredentialsTest",
+  "_auth_test.GoogleCallCredentialsTest",
   "_base_interface_test.AsyncEasyTest", 
   "_base_interface_test.AsyncPeasyTest", 
   "_base_interface_test.SyncEasyTest", 
@@ -6,6 +8,8 @@
   "_beta_features_test.BetaFeaturesTest", 
   "_beta_features_test.ContextManagementAndLifecycleTest", 
   "_cancel_many_calls_test.CancelManyCallsTest",
+  "_channel_connectivity_test.ChannelConnectivityTest",
+  "_channel_ready_future_test.ChannelReadyFutureTest",
   "_channel_test.ChannelTest", 
   "_connectivity_channel_test.ChannelConnectivityTest", 
   "_core_over_links_base_interface_test.AsyncEasyTest", 
@@ -24,6 +28,7 @@
   "_crust_over_core_over_links_face_interface_test.GenericInvokerFutureInvocationAsynchronousEventServiceTest", 
   "_crust_over_core_over_links_face_interface_test.MultiCallableInvokerBlockingInvocationInlineServiceTest", 
   "_crust_over_core_over_links_face_interface_test.MultiCallableInvokerFutureInvocationAsynchronousEventServiceTest", 
+  "_empty_message_test.EmptyMessageTest",
   "_face_interface_test.DynamicInvokerBlockingInvocationInlineServiceTest", 
   "_face_interface_test.DynamicInvokerFutureInvocationAsynchronousEventServiceTest", 
   "_face_interface_test.GenericInvokerBlockingInvocationInlineServiceTest", 
@@ -31,6 +36,7 @@
   "_face_interface_test.MultiCallableInvokerBlockingInvocationInlineServiceTest", 
   "_face_interface_test.MultiCallableInvokerFutureInvocationAsynchronousEventServiceTest",
   "_health_servicer_test.HealthServicerTest",
+  "_implementations_test.CallCredentialsTest",
   "_implementations_test.ChannelCredentialsTest", 
   "_insecure_interop_test.InsecureInteropTest", 
   "_intermediary_low_test.CancellationTest", 
@@ -43,6 +49,8 @@
   "_low_test.HangingServerShutdown", 
   "_low_test.InsecureServerInsecureClient", 
   "_not_found_test.NotFoundTest", 
+  "_read_some_but_not_all_responses_test.ReadSomeButNotAllResponsesTest",
+  "_rpc_test.RPCTest",
   "_sanity_test.Sanity", 
   "_secure_interop_test.SecureInteropTest", 
   "_transmission_test.RoundTripTest", 
diff --git a/src/python/grpcio/tests/unit/_adapter/_intermediary_low_test.py b/src/python/grpcio/tests/unit/_adapter/_intermediary_low_test.py
index 22d4b01..09ebdef 100644
--- a/src/python/grpcio/tests/unit/_adapter/_intermediary_low_test.py
+++ b/src/python/grpcio/tests/unit/_adapter/_intermediary_low_test.py
@@ -164,15 +164,15 @@
     self.assertIsNotNone(service_accepted)
     self.assertIs(service_accepted.kind, _low.Event.Kind.SERVICE_ACCEPTED)
     self.assertIs(service_accepted.tag, service_tag)
-    self.assertEqual(method, service_accepted.service_acceptance.method)
-    self.assertEqual(self.host, service_accepted.service_acceptance.host)
+    self.assertEqual(method.encode(), service_accepted.service_acceptance.method)
+    self.assertEqual(self.host.encode(), service_accepted.service_acceptance.host)
     self.assertIsNotNone(service_accepted.service_acceptance.call)
     metadata = dict(service_accepted.metadata)
-    self.assertIn(client_metadata_key, metadata)
-    self.assertEqual(client_metadata_value, metadata[client_metadata_key])
-    self.assertIn(client_binary_metadata_key, metadata)
+    self.assertIn(client_metadata_key.encode(), metadata)
+    self.assertEqual(client_metadata_value.encode(), metadata[client_metadata_key.encode()])
+    self.assertIn(client_binary_metadata_key.encode(), metadata)
     self.assertEqual(client_binary_metadata_value,
-                     metadata[client_binary_metadata_key])
+                     metadata[client_binary_metadata_key.encode()])
     server_call = service_accepted.service_acceptance.call
     server_call.accept(self.server_completion_queue, finish_tag)
     server_call.add_metadata(server_leading_metadata_key,
@@ -186,12 +186,12 @@
     self.assertEqual(_low.Event.Kind.METADATA_ACCEPTED, metadata_accepted.kind)
     self.assertEqual(metadata_tag, metadata_accepted.tag)
     metadata = dict(metadata_accepted.metadata)
-    self.assertIn(server_leading_metadata_key, metadata)
-    self.assertEqual(server_leading_metadata_value,
-                     metadata[server_leading_metadata_key])
-    self.assertIn(server_leading_binary_metadata_key, metadata)
+    self.assertIn(server_leading_metadata_key.encode(), metadata)
+    self.assertEqual(server_leading_metadata_value.encode(),
+                     metadata[server_leading_metadata_key.encode()])
+    self.assertIn(server_leading_binary_metadata_key.encode(), metadata)
     self.assertEqual(server_leading_binary_metadata_value,
-                     metadata[server_leading_binary_metadata_key])
+                     metadata[server_leading_binary_metadata_key.encode()])
 
     for datum in test_data:
       client_call.write(datum, write_tag, _low.WriteFlags.WRITE_NO_COMPRESS)
@@ -277,17 +277,17 @@
     self.assertIsNone(read_accepted.bytes)
     self.assertEqual(_low.Event.Kind.FINISH, finish_accepted.kind)
     self.assertEqual(finish_tag, finish_accepted.tag)
-    self.assertEqual(_low.Status(_low.Code.OK, details), finish_accepted.status)
+    self.assertEqual(_low.Status(_low.Code.OK, details.encode()), finish_accepted.status)
     metadata = dict(finish_accepted.metadata)
-    self.assertIn(server_trailing_metadata_key, metadata)
-    self.assertEqual(server_trailing_metadata_value,
-                     metadata[server_trailing_metadata_key])
-    self.assertIn(server_trailing_binary_metadata_key, metadata)
+    self.assertIn(server_trailing_metadata_key.encode(), metadata)
+    self.assertEqual(server_trailing_metadata_value.encode(),
+                     metadata[server_trailing_metadata_key.encode()])
+    self.assertIn(server_trailing_binary_metadata_key.encode(), metadata)
     self.assertEqual(server_trailing_binary_metadata_value,
-                     metadata[server_trailing_binary_metadata_key])
+                     metadata[server_trailing_binary_metadata_key.encode()])
     self.assertSetEqual(set(key for key, _ in finish_accepted.metadata),
-                        set((server_trailing_metadata_key,
-                             server_trailing_binary_metadata_key,)))
+                        set((server_trailing_metadata_key.encode(),
+                             server_trailing_binary_metadata_key.encode(),)))
 
     self.assertSequenceEqual(test_data, server_data)
     self.assertSequenceEqual(test_data, client_data)
@@ -302,7 +302,8 @@
     self._perform_echo_test([_BYTE_SEQUENCE])
 
   def testManyOneByteEchoes(self):
-    self._perform_echo_test(_BYTE_SEQUENCE)
+    self._perform_echo_test(
+        [_BYTE_SEQUENCE[i:i+1] for i in range(len(_BYTE_SEQUENCE))])
 
   def testManyManyByteEchoes(self):
     self._perform_echo_test(_BYTE_SEQUENCE_SEQUENCE)
@@ -409,7 +410,7 @@
 
     finish_event = self.client_events.get()
     self.assertEqual(_low.Event.Kind.FINISH, finish_event.kind)
-    self.assertEqual(_low.Status(_low.Code.CANCELLED, 'Cancelled'),
+    self.assertEqual(_low.Status(_low.Code.CANCELLED, b'Cancelled'),
                                  finish_event.status)
 
     self.assertSequenceEqual(test_data, server_data)
diff --git a/src/python/grpcio/tests/unit/_adapter/_low_test.py b/src/python/grpcio/tests/unit/_adapter/_low_test.py
index ec46617..e09a1f2 100644
--- a/src/python/grpcio/tests/unit/_adapter/_low_test.py
+++ b/src/python/grpcio/tests/unit/_adapter/_low_test.py
@@ -148,11 +148,11 @@
     # Check that Python's user agent string is a part of the full user agent
     # string
     received_initial_metadata_dict = dict(received_initial_metadata)
-    self.assertIn('user-agent', received_initial_metadata_dict)
-    self.assertIn('Python-gRPC-{}'.format(_grpcio_metadata.__version__),
-                  received_initial_metadata_dict['user-agent'])
-    self.assertEqual(method, request_event.call_details.method)
-    self.assertEqual(host, request_event.call_details.host)
+    self.assertIn(b'user-agent', received_initial_metadata_dict)
+    self.assertIn('Python-gRPC-{}'.format(_grpcio_metadata.__version__).encode(),
+                  received_initial_metadata_dict[b'user-agent'])
+    self.assertEqual(method.encode(), request_event.call_details.method)
+    self.assertEqual(host.encode(), request_event.call_details.host)
     self.assertLess(abs(deadline - request_event.call_details.deadline),
                     deadline_tolerance)
 
@@ -198,12 +198,12 @@
             test_common.metadata_transmitted(server_initial_metadata,
                                              client_result.initial_metadata))
       elif client_result.type == _types.OpType.RECV_MESSAGE:
-        self.assertEqual(response, client_result.message)
+        self.assertEqual(response.encode(), client_result.message)
       elif client_result.type == _types.OpType.RECV_STATUS_ON_CLIENT:
         self.assertTrue(
             test_common.metadata_transmitted(server_trailing_metadata,
                                              client_result.trailing_metadata))
-        self.assertEqual(server_status_details, client_result.status.details)
+        self.assertEqual(server_status_details.encode(), client_result.status.details)
         self.assertEqual(server_status_code, client_result.status.code)
     self.assertEqual(set([
           _types.OpType.SEND_INITIAL_METADATA,
@@ -220,7 +220,7 @@
       self.assertNotIn(client_result.type, found_server_op_types)
       found_server_op_types.add(server_result.type)
       if server_result.type == _types.OpType.RECV_MESSAGE:
-        self.assertEqual(request, server_result.message)
+        self.assertEqual(request.encode(), server_result.message)
       elif server_result.type == _types.OpType.RECV_CLOSE_ON_SERVER:
         self.assertFalse(server_result.cancelled)
     self.assertEqual(set([
diff --git a/src/python/grpcio/tests/unit/_auth_test.py b/src/python/grpcio/tests/unit/_auth_test.py
new file mode 100644
index 0000000..c31f7b0
--- /dev/null
+++ b/src/python/grpcio/tests/unit/_auth_test.py
@@ -0,0 +1,96 @@
+# 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.
+
+"""Tests of standard AuthMetadataPlugins."""
+
+import collections
+import threading
+import unittest
+
+from grpc import _auth
+
+
+class MockGoogleCreds(object):
+
+  def get_access_token(self):
+    token = collections.namedtuple('MockAccessTokenInfo',
+                                   ('access_token', 'expires_in'))
+    token.access_token = 'token'
+    return token
+
+
+class MockExceptionGoogleCreds(object):
+
+  def get_access_token(self):
+    raise Exception()
+
+
+class GoogleCallCredentialsTest(unittest.TestCase):
+
+  def test_google_call_credentials_success(self):
+    callback_event = threading.Event()
+
+    def mock_callback(metadata, error):
+      self.assertEqual(metadata, (('authorization', 'Bearer token'),))
+      self.assertIsNone(error)
+      callback_event.set()
+
+    call_creds = _auth.GoogleCallCredentials(MockGoogleCreds())
+    call_creds(None, mock_callback)
+    self.assertTrue(callback_event.wait(1.0))
+
+  def test_google_call_credentials_error(self):
+    callback_event = threading.Event()
+
+    def mock_callback(metadata, error):
+      self.assertIsNotNone(error)
+      callback_event.set()
+
+    call_creds = _auth.GoogleCallCredentials(MockExceptionGoogleCreds())
+    call_creds(None, mock_callback)
+    self.assertTrue(callback_event.wait(1.0))
+
+
+class AccessTokenCallCredentialsTest(unittest.TestCase):
+
+  def test_google_call_credentials_success(self):
+    callback_event = threading.Event()
+
+    def mock_callback(metadata, error):
+      self.assertEqual(metadata, (('authorization', 'Bearer token'),))
+      self.assertIsNone(error)
+      callback_event.set()
+
+    call_creds = _auth.AccessTokenCallCredentials('token')
+    call_creds(None, mock_callback)
+    self.assertTrue(callback_event.wait(1.0))
+
+
+if __name__ == '__main__':
+  unittest.main(verbosity=2)
diff --git a/src/python/grpcio/tests/unit/_channel_connectivity_test.py b/src/python/grpcio/tests/unit/_channel_connectivity_test.py
new file mode 100644
index 0000000..a1575ef
--- /dev/null
+++ b/src/python/grpcio/tests/unit/_channel_connectivity_test.py
@@ -0,0 +1,161 @@
+# Copyright 2015, Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"""Tests of grpc._channel.Channel connectivity."""
+
+import threading
+import time
+import unittest
+from concurrent import futures
+
+import grpc
+from grpc import _channel
+from grpc import _server
+from tests.unit.framework.common import test_constants
+
+
+def _ready_in_connectivities(connectivities):
+  return grpc.ChannelConnectivity.READY in connectivities
+
+
+def _last_connectivity_is_not_ready(connectivities):
+  return connectivities[-1] is not grpc.ChannelConnectivity.READY
+
+
+class _Callback(object):
+
+  def __init__(self):
+    self._condition = threading.Condition()
+    self._connectivities = []
+
+  def update(self, connectivity):
+    with self._condition:
+      self._connectivities.append(connectivity)
+      self._condition.notify()
+
+  def connectivities(self):
+    with self._condition:
+      return tuple(self._connectivities)
+
+  def block_until_connectivities_satisfy(self, predicate):
+    with self._condition:
+      while True:
+        connectivities = tuple(self._connectivities)
+        if predicate(connectivities):
+          return connectivities
+        else:
+          self._condition.wait()
+
+
+class ChannelConnectivityTest(unittest.TestCase):
+
+  def test_lonely_channel_connectivity(self):
+    callback = _Callback()
+
+    channel = _channel.Channel('localhost:12345', None, None)
+    channel.subscribe(callback.update, try_to_connect=False)
+    first_connectivities = callback.block_until_connectivities_satisfy(bool)
+    channel.subscribe(callback.update, try_to_connect=True)
+    second_connectivities = callback.block_until_connectivities_satisfy(
+        lambda connectivities: 2 <= len(connectivities))
+    # Wait for a connection that will never happen.
+    time.sleep(test_constants.SHORT_TIMEOUT)
+    third_connectivities = callback.connectivities()
+    channel.unsubscribe(callback.update)
+    fourth_connectivities = callback.connectivities()
+    channel.unsubscribe(callback.update)
+    fifth_connectivities = callback.connectivities()
+
+    self.assertSequenceEqual(
+        (grpc.ChannelConnectivity.IDLE,), first_connectivities)
+    self.assertNotIn(
+        grpc.ChannelConnectivity.READY, second_connectivities)
+    self.assertNotIn(
+        grpc.ChannelConnectivity.READY, third_connectivities)
+    self.assertNotIn(
+        grpc.ChannelConnectivity.READY, fourth_connectivities)
+    self.assertNotIn(
+        grpc.ChannelConnectivity.READY, fifth_connectivities)
+
+  def test_immediately_connectable_channel_connectivity(self):
+    server = _server.Server((), futures.ThreadPoolExecutor(max_workers=0))
+    port = server.add_insecure_port('[::]:0')
+    server.start()
+    first_callback = _Callback()
+    second_callback = _Callback()
+
+    channel = _channel.Channel('localhost:{}'.format(port), None, None)
+    channel.subscribe(first_callback.update, try_to_connect=False)
+    first_connectivities = first_callback.block_until_connectivities_satisfy(
+        bool)
+    # Wait for a connection that will never happen because try_to_connect=True
+    # has not yet been passed.
+    time.sleep(test_constants.SHORT_TIMEOUT)
+    second_connectivities = first_callback.connectivities()
+    channel.subscribe(second_callback.update, try_to_connect=True)
+    third_connectivities = first_callback.block_until_connectivities_satisfy(
+        lambda connectivities: 2 <= len(connectivities))
+    fourth_connectivities = second_callback.block_until_connectivities_satisfy(
+        bool)
+    # Wait for a connection that will happen (or may already have happened).
+    first_callback.block_until_connectivities_satisfy(_ready_in_connectivities)
+    second_callback.block_until_connectivities_satisfy(_ready_in_connectivities)
+    del channel
+
+    self.assertSequenceEqual(
+        (grpc.ChannelConnectivity.IDLE,), first_connectivities)
+    self.assertSequenceEqual(
+        (grpc.ChannelConnectivity.IDLE,), second_connectivities)
+    self.assertNotIn(
+        grpc.ChannelConnectivity.TRANSIENT_FAILURE, third_connectivities)
+    self.assertNotIn(
+        grpc.ChannelConnectivity.FATAL_FAILURE, third_connectivities)
+    self.assertNotIn(
+        grpc.ChannelConnectivity.TRANSIENT_FAILURE,
+        fourth_connectivities)
+    self.assertNotIn(
+        grpc.ChannelConnectivity.FATAL_FAILURE, fourth_connectivities)
+
+  def test_reachable_then_unreachable_channel_connectivity(self):
+    server = _server.Server((), futures.ThreadPoolExecutor(max_workers=0))
+    port = server.add_insecure_port('[::]:0')
+    server.start()
+    callback = _Callback()
+
+    channel = _channel.Channel('localhost:{}'.format(port), None, None)
+    channel.subscribe(callback.update, try_to_connect=True)
+    callback.block_until_connectivities_satisfy(_ready_in_connectivities)
+    # Now take down the server and confirm that channel readiness is repudiated.
+    server.stop(None)
+    callback.block_until_connectivities_satisfy(_last_connectivity_is_not_ready)
+    channel.unsubscribe(callback.update)
+
+
+if __name__ == '__main__':
+  unittest.main(verbosity=2)
diff --git a/src/python/grpcio/tests/unit/_channel_ready_future_test.py b/src/python/grpcio/tests/unit/_channel_ready_future_test.py
new file mode 100644
index 0000000..b84bc01
--- /dev/null
+++ b/src/python/grpcio/tests/unit/_channel_ready_future_test.py
@@ -0,0 +1,103 @@
+# Copyright 2015, Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"""Tests of grpc.channel_ready_future."""
+
+import threading
+import unittest
+from concurrent import futures
+
+import grpc
+from grpc import _channel
+from grpc import _server
+from tests.unit.framework.common import test_constants
+
+
+class _Callback(object):
+
+  def __init__(self):
+    self._condition = threading.Condition()
+    self._value = None
+
+  def accept_value(self, value):
+    with self._condition:
+      self._value = value
+      self._condition.notify_all()
+
+  def block_until_called(self):
+    with self._condition:
+      while self._value is None:
+        self._condition.wait()
+      return self._value
+
+
+class ChannelReadyFutureTest(unittest.TestCase):
+
+  def test_lonely_channel_connectivity(self):
+    channel = grpc.insecure_channel('localhost:12345')
+    callback = _Callback()
+
+    ready_future = grpc.channel_ready_future(channel)
+    ready_future.add_done_callback(callback.accept_value)
+    with self.assertRaises(grpc.FutureTimeoutError):
+      ready_future.result(test_constants.SHORT_TIMEOUT)
+    self.assertFalse(ready_future.cancelled())
+    self.assertFalse(ready_future.done())
+    self.assertTrue(ready_future.running())
+    ready_future.cancel()
+    value_passed_to_callback = callback.block_until_called()
+    self.assertIs(ready_future, value_passed_to_callback)
+    self.assertTrue(ready_future.cancelled())
+    self.assertTrue(ready_future.done())
+    self.assertFalse(ready_future.running())
+
+  def test_immediately_connectable_channel_connectivity(self):
+    server = _server.Server((), futures.ThreadPoolExecutor(max_workers=0))
+    port = server.add_insecure_port('[::]:0')
+    server.start()
+    channel = grpc.insecure_channel('localhost:{}'.format(port))
+    callback = _Callback()
+
+    ready_future = grpc.channel_ready_future(channel)
+    ready_future.add_done_callback(callback.accept_value)
+    self.assertIsNone(ready_future.result(test_constants.SHORT_TIMEOUT))
+    value_passed_to_callback = callback.block_until_called()
+    self.assertIs(ready_future, value_passed_to_callback)
+    self.assertFalse(ready_future.cancelled())
+    self.assertTrue(ready_future.done())
+    self.assertFalse(ready_future.running())
+    # Cancellation after maturity has no effect.
+    ready_future.cancel()
+    self.assertFalse(ready_future.cancelled())
+    self.assertTrue(ready_future.done())
+    self.assertFalse(ready_future.running())
+
+
+if __name__ == '__main__':
+  unittest.main(verbosity=2)
diff --git a/src/python/grpcio/tests/unit/_cython/_read_some_but_not_all_responses_test.py b/src/python/grpcio/tests/unit/_cython/_read_some_but_not_all_responses_test.py
new file mode 100644
index 0000000..6ae7a90
--- /dev/null
+++ b/src/python/grpcio/tests/unit/_cython/_read_some_but_not_all_responses_test.py
@@ -0,0 +1,251 @@
+# 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.
+
+"""Test a corner-case at the level of the Cython API."""
+
+import threading
+import unittest
+
+from grpc._cython import cygrpc
+
+_INFINITE_FUTURE = cygrpc.Timespec(float('+inf'))
+_EMPTY_FLAGS = 0
+_EMPTY_METADATA = cygrpc.Metadata(())
+
+
+class _ServerDriver(object):
+
+  def __init__(self, completion_queue, shutdown_tag):
+    self._condition = threading.Condition()
+    self._completion_queue = completion_queue
+    self._shutdown_tag = shutdown_tag
+    self._events = []
+    self._saw_shutdown_tag = False
+
+  def start(self):
+    def in_thread():
+      while True:
+        event = self._completion_queue.poll()
+        with self._condition:
+          self._events.append(event)
+          self._condition.notify()
+          if event.tag is self._shutdown_tag:
+            self._saw_shutdown_tag = True
+            break
+    thread = threading.Thread(target=in_thread)
+    thread.start()
+
+  def done(self):
+    with self._condition:
+      return self._saw_shutdown_tag
+
+  def first_event(self):
+    with self._condition:
+      while not self._events:
+        self._condition.wait()
+      return self._events[0]
+
+  def events(self):
+    with self._condition:
+      while not self._saw_shutdown_tag:
+        self._condition.wait()
+      return tuple(self._events)
+
+
+class _QueueDriver(object):
+
+  def __init__(self, condition, completion_queue, due):
+    self._condition = condition
+    self._completion_queue = completion_queue
+    self._due = due
+    self._events = []
+    self._returned = False
+
+  def start(self):
+    def in_thread():
+      while True:
+        event = self._completion_queue.poll()
+        with self._condition:
+          self._events.append(event)
+          self._due.remove(event.tag)
+          self._condition.notify_all()
+          if not self._due:
+            self._returned = True
+            return
+    thread = threading.Thread(target=in_thread)
+    thread.start()
+
+  def done(self):
+    with self._condition:
+      return self._returned
+
+  def event_with_tag(self, tag):
+    with self._condition:
+      while True:
+        for event in self._events:
+          if event.tag is tag:
+            return event
+        self._condition.wait()
+
+  def events(self):
+    with self._condition:
+      while not self._returned:
+        self._condition.wait()
+      return tuple(self._events)
+
+
+class ReadSomeButNotAllResponsesTest(unittest.TestCase):
+
+  def testReadSomeButNotAllResponses(self):
+    server_completion_queue = cygrpc.CompletionQueue()
+    server = cygrpc.Server()
+    server.register_completion_queue(server_completion_queue)
+    port = server.add_http2_port('[::]:0')
+    server.start()
+    channel = cygrpc.Channel('localhost:{}'.format(port))
+
+    server_shutdown_tag = 'server_shutdown_tag'
+    server_driver = _ServerDriver(server_completion_queue, server_shutdown_tag)
+    server_driver.start()
+
+    client_condition = threading.Condition()
+    client_due = set()
+    client_completion_queue = cygrpc.CompletionQueue()
+    client_driver = _QueueDriver(
+        client_condition, client_completion_queue, client_due)
+    client_driver.start()
+
+    server_call_condition = threading.Condition()
+    server_send_initial_metadata_tag = 'server_send_initial_metadata_tag'
+    server_send_first_message_tag = 'server_send_first_message_tag'
+    server_send_second_message_tag = 'server_send_second_message_tag'
+    server_complete_rpc_tag = 'server_complete_rpc_tag'
+    server_call_due = set((
+        server_send_initial_metadata_tag,
+        server_send_first_message_tag,
+        server_send_second_message_tag,
+        server_complete_rpc_tag,
+    ))
+    server_call_completion_queue = cygrpc.CompletionQueue()
+    server_call_driver = _QueueDriver(
+        server_call_condition, server_call_completion_queue, server_call_due)
+    server_call_driver.start()
+
+    server_rpc_tag = 'server_rpc_tag'
+    request_call_result = server.request_call(
+        server_call_completion_queue, server_completion_queue, server_rpc_tag)
+
+    client_call = channel.create_call(
+        None, _EMPTY_FLAGS, client_completion_queue, b'/twinkies', None,
+        _INFINITE_FUTURE)
+    client_receive_initial_metadata_tag = 'client_receive_initial_metadata_tag'
+    client_complete_rpc_tag = 'client_complete_rpc_tag'
+    with client_condition:
+      client_receive_initial_metadata_start_batch_result = (
+          client_call.start_batch(cygrpc.Operations([
+              cygrpc.operation_receive_initial_metadata(_EMPTY_FLAGS),
+          ]), client_receive_initial_metadata_tag))
+      client_due.add(client_receive_initial_metadata_tag)
+      client_complete_rpc_start_batch_result = (
+          client_call.start_batch(cygrpc.Operations([
+              cygrpc.operation_send_initial_metadata(
+                  _EMPTY_METADATA, _EMPTY_FLAGS),
+              cygrpc.operation_send_close_from_client(_EMPTY_FLAGS),
+              cygrpc.operation_receive_status_on_client(_EMPTY_FLAGS),
+          ]), client_complete_rpc_tag))
+      client_due.add(client_complete_rpc_tag)
+
+    server_rpc_event = server_driver.first_event()
+
+    with server_call_condition:
+      server_send_initial_metadata_start_batch_result = (
+          server_rpc_event.operation_call.start_batch(cygrpc.Operations([
+              cygrpc.operation_send_initial_metadata(
+                  _EMPTY_METADATA, _EMPTY_FLAGS),
+          ]), server_send_initial_metadata_tag))
+      server_send_first_message_start_batch_result = (
+          server_rpc_event.operation_call.start_batch(cygrpc.Operations([
+              cygrpc.operation_send_message(b'\x07', _EMPTY_FLAGS),
+          ]), server_send_first_message_tag))
+    server_send_initial_metadata_event = server_call_driver.event_with_tag(
+        server_send_initial_metadata_tag)
+    server_send_first_message_event = server_call_driver.event_with_tag(
+        server_send_first_message_tag)
+    with server_call_condition:
+      server_send_second_message_start_batch_result = (
+          server_rpc_event.operation_call.start_batch(cygrpc.Operations([
+              cygrpc.operation_send_message(b'\x07', _EMPTY_FLAGS),
+          ]), server_send_second_message_tag))
+      server_complete_rpc_start_batch_result = (
+          server_rpc_event.operation_call.start_batch(cygrpc.Operations([
+              cygrpc.operation_receive_close_on_server(_EMPTY_FLAGS),
+              cygrpc.operation_send_status_from_server(
+                  cygrpc.Metadata(()), cygrpc.StatusCode.ok, b'test details',
+                  _EMPTY_FLAGS),
+          ]), server_complete_rpc_tag))
+    server_send_second_message_event = server_call_driver.event_with_tag(
+        server_send_second_message_tag)
+    server_complete_rpc_event = server_call_driver.event_with_tag(
+        server_complete_rpc_tag)
+    server_call_driver.events()
+
+    with client_condition:
+      client_receive_first_message_tag = 'client_receive_first_message_tag'
+      client_receive_first_message_start_batch_result = (
+          client_call.start_batch(cygrpc.Operations([
+              cygrpc.operation_receive_message(_EMPTY_FLAGS),
+          ]), client_receive_first_message_tag))
+      client_due.add(client_receive_first_message_tag)
+    client_receive_first_message_event = client_driver.event_with_tag(
+        client_receive_first_message_tag)
+
+    client_call_cancel_result = client_call.cancel()
+    client_driver.events()
+
+    server.shutdown(server_completion_queue, server_shutdown_tag)
+    server.cancel_all_calls()
+    server_driver.events()
+
+    self.assertEqual(cygrpc.CallError.ok, request_call_result)
+    self.assertEqual(
+        cygrpc.CallError.ok, server_send_initial_metadata_start_batch_result)
+    self.assertEqual(
+        cygrpc.CallError.ok, client_receive_initial_metadata_start_batch_result)
+    self.assertEqual(
+        cygrpc.CallError.ok, client_complete_rpc_start_batch_result)
+    self.assertEqual(cygrpc.CallError.ok, client_call_cancel_result)
+    self.assertIs(server_rpc_tag, server_rpc_event.tag)
+    self.assertEqual(
+        cygrpc.CompletionType.operation_complete, server_rpc_event.type)
+    self.assertIsInstance(server_rpc_event.operation_call, cygrpc.Call)
+    self.assertEqual(0, len(server_rpc_event.batch_operations))
+
+
+if __name__ == '__main__':
+  unittest.main(verbosity=2)
diff --git a/src/python/grpcio/tests/unit/_cython/cygrpc_test.py b/src/python/grpcio/tests/unit/_cython/cygrpc_test.py
index 0a51110..a006a20 100644
--- a/src/python/grpcio/tests/unit/_cython/cygrpc_test.py
+++ b/src/python/grpcio/tests/unit/_cython/cygrpc_test.py
@@ -37,7 +37,7 @@
 from tests.unit import resources
 
 
-_SSL_HOST_OVERRIDE = 'foo.test.google.fr'
+_SSL_HOST_OVERRIDE = b'foo.test.google.fr'
 _CALL_CREDENTIALS_METADATA_KEY = 'call-creds-key'
 _CALL_CREDENTIALS_METADATA_VALUE = 'call-creds-value'
 _EMPTY_FLAGS = 0
@@ -143,22 +143,60 @@
     del completion_queue
 
 
-class InsecureServerInsecureClient(unittest.TestCase):
+class ServerClientMixin(object):
 
-  def setUp(self):
+  def setUpMixin(self, server_credentials, client_credentials, host_override):
     self.server_completion_queue = cygrpc.CompletionQueue()
     self.server = cygrpc.Server()
     self.server.register_completion_queue(self.server_completion_queue)
-    self.port = self.server.add_http2_port('[::]:0')
+    if server_credentials:
+      self.port = self.server.add_http2_port('[::]:0', server_credentials)
+    else:
+      self.port = self.server.add_http2_port('[::]:0')
     self.server.start()
     self.client_completion_queue = cygrpc.CompletionQueue()
-    self.client_channel = cygrpc.Channel('localhost:{}'.format(self.port))
+    if client_credentials:
+      client_channel_arguments = cygrpc.ChannelArgs([
+          cygrpc.ChannelArg(cygrpc.ChannelArgKey.ssl_target_name_override,
+                            host_override)])
+      self.client_channel = cygrpc.Channel(
+          'localhost:{}'.format(self.port), client_channel_arguments,
+          client_credentials)
+    else:
+      self.client_channel = cygrpc.Channel('localhost:{}'.format(self.port))
+    if host_override:
+      self.host_argument = None  # default host
+      self.expected_host = host_override
+    else:
+      # arbitrary host name necessitating no further identification
+      self.host_argument = b'hostess'
+      self.expected_host = self.host_argument
 
-  def tearDown(self):
+  def tearDownMixin(self):
     del self.server
     del self.client_completion_queue
     del self.server_completion_queue
 
+  def _perform_operations(self, operations, call, queue, deadline, description):
+    """Perform the list of operations with given call, queue, and deadline.
+
+    Invocation errors are reported with as an exception with `description` in
+    the message. Performs the operations asynchronously, returning a future.
+    """
+    def performer():
+      tag = object()
+      try:
+        call_result = call.start_batch(cygrpc.Operations(operations), tag)
+        self.assertEqual(cygrpc.CallError.ok, call_result)
+        event = queue.poll(deadline)
+        self.assertEqual(cygrpc.CompletionType.operation_complete, event.type)
+        self.assertTrue(event.success)
+        self.assertIs(tag, event.tag)
+      except Exception as error:
+        raise Exception("Error in '{}': {}".format(description, error.message))
+      return event
+    return test_utilities.SimpleFuture(performer)
+
   def testEcho(self):
     DEADLINE = time.time()+5
     DEADLINE_TOLERANCE = 0.25
@@ -175,7 +213,6 @@
     REQUEST = b'in death a member of project mayhem has a name'
     RESPONSE = b'his name is robert paulson'
     METHOD = b'twinkies'
-    HOST = b'hostess'
 
     cygrpc_deadline = cygrpc.Timespec(DEADLINE)
 
@@ -188,7 +225,8 @@
 
     client_call_tag = object()
     client_call = self.client_channel.create_call(
-        None, 0, self.client_completion_queue, METHOD, HOST, cygrpc_deadline)
+        None, 0, self.client_completion_queue, METHOD, self.host_argument,
+        cygrpc_deadline)
     client_initial_metadata = cygrpc.Metadata([
         cygrpc.Metadatum(CLIENT_METADATA_ASCII_KEY,
                          CLIENT_METADATA_ASCII_VALUE),
@@ -216,173 +254,7 @@
         test_common.metadata_transmitted(client_initial_metadata,
                                          request_event.request_metadata))
     self.assertEqual(METHOD, request_event.request_call_details.method)
-    self.assertEqual(HOST, request_event.request_call_details.host)
-    self.assertLess(
-        abs(DEADLINE - float(request_event.request_call_details.deadline)),
-        DEADLINE_TOLERANCE)
-
-    server_call_tag = object()
-    server_call = request_event.operation_call
-    server_initial_metadata = cygrpc.Metadata([
-        cygrpc.Metadatum(SERVER_INITIAL_METADATA_KEY,
-                         SERVER_INITIAL_METADATA_VALUE)])
-    server_trailing_metadata = cygrpc.Metadata([
-        cygrpc.Metadatum(SERVER_TRAILING_METADATA_KEY,
-                         SERVER_TRAILING_METADATA_VALUE)])
-    server_start_batch_result = server_call.start_batch([
-        cygrpc.operation_send_initial_metadata(server_initial_metadata,
-                                               _EMPTY_FLAGS),
-        cygrpc.operation_receive_message(_EMPTY_FLAGS),
-        cygrpc.operation_send_message(RESPONSE, _EMPTY_FLAGS),
-        cygrpc.operation_receive_close_on_server(_EMPTY_FLAGS),
-        cygrpc.operation_send_status_from_server(
-            server_trailing_metadata, SERVER_STATUS_CODE,
-            SERVER_STATUS_DETAILS, _EMPTY_FLAGS)
-    ], server_call_tag)
-    self.assertEqual(cygrpc.CallError.ok, server_start_batch_result)
-
-    client_event = client_event_future.result()
-    server_event = self.server_completion_queue.poll(cygrpc_deadline)
-
-    self.assertEqual(6, len(client_event.batch_operations))
-    found_client_op_types = set()
-    for client_result in client_event.batch_operations:
-      # we expect each op type to be unique
-      self.assertNotIn(client_result.type, found_client_op_types)
-      found_client_op_types.add(client_result.type)
-      if client_result.type == cygrpc.OperationType.receive_initial_metadata:
-        self.assertTrue(
-            test_common.metadata_transmitted(server_initial_metadata,
-                                             client_result.received_metadata))
-      elif client_result.type == cygrpc.OperationType.receive_message:
-        self.assertEqual(RESPONSE, client_result.received_message.bytes())
-      elif client_result.type == cygrpc.OperationType.receive_status_on_client:
-        self.assertTrue(
-            test_common.metadata_transmitted(server_trailing_metadata,
-                                             client_result.received_metadata))
-        self.assertEqual(SERVER_STATUS_DETAILS,
-                         client_result.received_status_details)
-        self.assertEqual(SERVER_STATUS_CODE, client_result.received_status_code)
-    self.assertEqual(set([
-          cygrpc.OperationType.send_initial_metadata,
-          cygrpc.OperationType.send_message,
-          cygrpc.OperationType.send_close_from_client,
-          cygrpc.OperationType.receive_initial_metadata,
-          cygrpc.OperationType.receive_message,
-          cygrpc.OperationType.receive_status_on_client
-      ]), found_client_op_types)
-
-    self.assertEqual(5, len(server_event.batch_operations))
-    found_server_op_types = set()
-    for server_result in server_event.batch_operations:
-      self.assertNotIn(client_result.type, found_server_op_types)
-      found_server_op_types.add(server_result.type)
-      if server_result.type == cygrpc.OperationType.receive_message:
-        self.assertEqual(REQUEST, server_result.received_message.bytes())
-      elif server_result.type == cygrpc.OperationType.receive_close_on_server:
-        self.assertFalse(server_result.received_cancelled)
-    self.assertEqual(set([
-          cygrpc.OperationType.send_initial_metadata,
-          cygrpc.OperationType.receive_message,
-          cygrpc.OperationType.send_message,
-          cygrpc.OperationType.receive_close_on_server,
-          cygrpc.OperationType.send_status_from_server
-      ]), found_server_op_types)
-
-    del client_call
-    del server_call
-
-
-class SecureServerSecureClient(unittest.TestCase):
-
-  def setUp(self):
-    server_credentials = cygrpc.server_credentials_ssl(
-        None, [cygrpc.SslPemKeyCertPair(resources.private_key(),
-                                        resources.certificate_chain())], False)
-    channel_credentials = cygrpc.channel_credentials_ssl(
-        resources.test_root_certificates(), None)
-    self.server_completion_queue = cygrpc.CompletionQueue()
-    self.server = cygrpc.Server()
-    self.server.register_completion_queue(self.server_completion_queue)
-    self.port = self.server.add_http2_port('[::]:0', server_credentials)
-    self.server.start()
-    self.client_completion_queue = cygrpc.CompletionQueue()
-    client_channel_arguments = cygrpc.ChannelArgs([
-        cygrpc.ChannelArg(cygrpc.ChannelArgKey.ssl_target_name_override,
-                          _SSL_HOST_OVERRIDE)])
-    self.client_channel = cygrpc.Channel(
-        'localhost:{}'.format(self.port), client_channel_arguments,
-        channel_credentials)
-
-  def tearDown(self):
-    del self.server
-    del self.client_completion_queue
-    del self.server_completion_queue
-
-  def testEcho(self):
-    DEADLINE = time.time()+5
-    DEADLINE_TOLERANCE = 0.25
-    CLIENT_METADATA_ASCII_KEY = b'key'
-    CLIENT_METADATA_ASCII_VALUE = b'val'
-    CLIENT_METADATA_BIN_KEY = b'key-bin'
-    CLIENT_METADATA_BIN_VALUE = b'\0'*1000
-    SERVER_INITIAL_METADATA_KEY = b'init_me_me_me'
-    SERVER_INITIAL_METADATA_VALUE = b'whodawha?'
-    SERVER_TRAILING_METADATA_KEY = b'california_is_in_a_drought'
-    SERVER_TRAILING_METADATA_VALUE = b'zomg it is'
-    SERVER_STATUS_CODE = cygrpc.StatusCode.ok
-    SERVER_STATUS_DETAILS = b'our work is never over'
-    REQUEST = b'in death a member of project mayhem has a name'
-    RESPONSE = b'his name is robert paulson'
-    METHOD = b'/twinkies'
-    HOST = None  # Default host
-
-    cygrpc_deadline = cygrpc.Timespec(DEADLINE)
-
-    server_request_tag = object()
-    request_call_result = self.server.request_call(
-        self.server_completion_queue, self.server_completion_queue,
-        server_request_tag)
-
-    self.assertEqual(cygrpc.CallError.ok, request_call_result)
-
-    plugin = cygrpc.CredentialsMetadataPlugin(_metadata_plugin_callback, '')
-    call_credentials = cygrpc.call_credentials_metadata_plugin(plugin)
-
-    client_call_tag = object()
-    client_call = self.client_channel.create_call(
-        None, 0, self.client_completion_queue, METHOD, HOST, cygrpc_deadline)
-    client_call.set_credentials(call_credentials)
-    client_initial_metadata = cygrpc.Metadata([
-        cygrpc.Metadatum(CLIENT_METADATA_ASCII_KEY,
-                         CLIENT_METADATA_ASCII_VALUE),
-        cygrpc.Metadatum(CLIENT_METADATA_BIN_KEY, CLIENT_METADATA_BIN_VALUE)])
-    client_start_batch_result = client_call.start_batch(cygrpc.Operations([
-        cygrpc.operation_send_initial_metadata(client_initial_metadata,
-                                               _EMPTY_FLAGS),
-        cygrpc.operation_send_message(REQUEST, _EMPTY_FLAGS),
-        cygrpc.operation_send_close_from_client(_EMPTY_FLAGS),
-        cygrpc.operation_receive_initial_metadata(_EMPTY_FLAGS),
-        cygrpc.operation_receive_message(_EMPTY_FLAGS),
-        cygrpc.operation_receive_status_on_client(_EMPTY_FLAGS)
-    ]), client_call_tag)
-    self.assertEqual(cygrpc.CallError.ok, client_start_batch_result)
-    client_event_future = test_utilities.CompletionQueuePollFuture(
-        self.client_completion_queue, cygrpc_deadline)
-
-    request_event = self.server_completion_queue.poll(cygrpc_deadline)
-    self.assertEqual(cygrpc.CompletionType.operation_complete,
-                      request_event.type)
-    self.assertIsInstance(request_event.operation_call, cygrpc.Call)
-    self.assertIs(server_request_tag, request_event.tag)
-    self.assertEqual(0, len(request_event.batch_operations))
-    client_metadata_with_credentials = list(client_initial_metadata) + [
-        (_CALL_CREDENTIALS_METADATA_KEY, _CALL_CREDENTIALS_METADATA_VALUE)]
-    self.assertTrue(
-        test_common.metadata_transmitted(client_metadata_with_credentials,
-                                         request_event.request_metadata))
-    self.assertEqual(METHOD, request_event.request_call_details.method)
-    self.assertEqual(_SSL_HOST_OVERRIDE,
+    self.assertEqual(self.expected_host,
                      request_event.request_call_details.host)
     self.assertLess(
         abs(DEADLINE - float(request_event.request_call_details.deadline)),
@@ -459,6 +331,102 @@
     del client_call
     del server_call
 
+  def test6522(self):
+    DEADLINE = time.time()+5
+    DEADLINE_TOLERANCE = 0.25
+    METHOD = b'twinkies'
+
+    cygrpc_deadline = cygrpc.Timespec(DEADLINE)
+    empty_metadata = cygrpc.Metadata([])
+
+    server_request_tag = object()
+    self.server.request_call(
+        self.server_completion_queue, self.server_completion_queue,
+        server_request_tag)
+    client_call = self.client_channel.create_call(
+        None, 0, self.client_completion_queue, METHOD, self.host_argument,
+        cygrpc_deadline)
+
+    # Prologue
+    def perform_client_operations(operations, description):
+      return self._perform_operations(
+          operations, client_call,
+          self.client_completion_queue, cygrpc_deadline, description)
+
+    client_event_future = perform_client_operations([
+            cygrpc.operation_send_initial_metadata(empty_metadata,
+                                                   _EMPTY_FLAGS),
+            cygrpc.operation_receive_initial_metadata(_EMPTY_FLAGS),
+        ], "Client prologue")
+
+    request_event = self.server_completion_queue.poll(cygrpc_deadline)
+    server_call = request_event.operation_call
+
+    def perform_server_operations(operations, description):
+      return self._perform_operations(
+          operations, server_call,
+          self.server_completion_queue, cygrpc_deadline, description)
+
+    server_event_future = perform_server_operations([
+            cygrpc.operation_send_initial_metadata(empty_metadata,
+                                                   _EMPTY_FLAGS),
+        ], "Server prologue")
+
+    client_event_future.result()  # force completion
+    server_event_future.result()
+
+    # Messaging
+    for _ in range(10):
+      client_event_future = perform_client_operations([
+              cygrpc.operation_send_message(b'', _EMPTY_FLAGS),
+              cygrpc.operation_receive_message(_EMPTY_FLAGS),
+          ], "Client message")
+      server_event_future = perform_server_operations([
+              cygrpc.operation_send_message(b'', _EMPTY_FLAGS),
+              cygrpc.operation_receive_message(_EMPTY_FLAGS),
+          ], "Server receive")
+
+      client_event_future.result()  # force completion
+      server_event_future.result()
+
+    # Epilogue
+    client_event_future = perform_client_operations([
+            cygrpc.operation_send_close_from_client(_EMPTY_FLAGS),
+            cygrpc.operation_receive_status_on_client(_EMPTY_FLAGS)
+        ], "Client epilogue")
+
+    server_event_future = perform_server_operations([
+            cygrpc.operation_receive_close_on_server(_EMPTY_FLAGS),
+            cygrpc.operation_send_status_from_server(
+                empty_metadata, cygrpc.StatusCode.ok, b'', _EMPTY_FLAGS)
+        ], "Server epilogue")
+
+    client_event_future.result()  # force completion
+    server_event_future.result()
+
+
+class InsecureServerInsecureClient(unittest.TestCase, ServerClientMixin):
+
+  def setUp(self):
+    self.setUpMixin(None, None, None)
+
+  def tearDown(self):
+    self.tearDownMixin()
+
+
+class SecureServerSecureClient(unittest.TestCase, ServerClientMixin):
+
+  def setUp(self):
+    server_credentials = cygrpc.server_credentials_ssl(
+        None, [cygrpc.SslPemKeyCertPair(resources.private_key(),
+                                        resources.certificate_chain())], False)
+    client_credentials = cygrpc.channel_credentials_ssl(
+        resources.test_root_certificates(), None)
+    self.setUpMixin(server_credentials, client_credentials, _SSL_HOST_OVERRIDE)
+
+  def tearDown(self):
+    self.tearDownMixin()
+
 
 if __name__ == '__main__':
   unittest.main(verbosity=2)
diff --git a/src/python/grpcio/tests/unit/_cython/test_utilities.py b/src/python/grpcio/tests/unit/_cython/test_utilities.py
index 6a09739..6280ce7 100644
--- a/src/python/grpcio/tests/unit/_cython/test_utilities.py
+++ b/src/python/grpcio/tests/unit/_cython/test_utilities.py
@@ -32,15 +32,35 @@
 from grpc._cython import cygrpc
 
 
-class CompletionQueuePollFuture:
+class SimpleFuture(object):
+  """A simple future mechanism."""
 
-  def __init__(self, completion_queue, deadline):
-    def poller_function():
-      self._event_result = completion_queue.poll(deadline)
-    self._event_result = None
-    self._thread = threading.Thread(target=poller_function)
+  def __init__(self, function, *args, **kwargs):
+    def wrapped_function():
+      try:
+        self._result = function(*args, **kwargs)
+      except Exception as error:
+        self._error = error
+    self._result = None
+    self._error = None
+    self._thread = threading.Thread(target=wrapped_function)
     self._thread.start()
 
   def result(self):
+    """The resulting value of this future.
+
+    Re-raises any exceptions.
+    """
     self._thread.join()
-    return self._event_result
+    if self._error:
+      # TODO(atash): re-raise exceptions in a way that preserves tracebacks
+      raise self._error
+    return self._result
+
+
+class CompletionQueuePollFuture(SimpleFuture):
+
+  def __init__(self, completion_queue, deadline):
+    super(CompletionQueuePollFuture, self).__init__(
+        lambda: completion_queue.poll(deadline))
+
diff --git a/src/python/grpcio/tests/unit/_empty_message_test.py b/src/python/grpcio/tests/unit/_empty_message_test.py
new file mode 100644
index 0000000..f324f62
--- /dev/null
+++ b/src/python/grpcio/tests/unit/_empty_message_test.py
@@ -0,0 +1,137 @@
+# Copyright 2016, Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+import unittest
+
+import grpc
+from grpc.framework.foundation import logging_pool
+
+from tests.unit.framework.common import test_constants
+
+_REQUEST = b''
+_RESPONSE = b''
+
+_UNARY_UNARY = b'/test/UnaryUnary'
+_UNARY_STREAM = b'/test/UnaryStream'
+_STREAM_UNARY = b'/test/StreamUnary'
+_STREAM_STREAM = b'/test/StreamStream'
+
+
+def handle_unary_unary(request, servicer_context):
+  return _RESPONSE
+
+
+def handle_unary_stream(request, servicer_context):
+  for _ in range(test_constants.STREAM_LENGTH):
+    yield _RESPONSE
+
+
+def handle_stream_unary(request_iterator, servicer_context):
+  for request in request_iterator:
+    pass
+  return _RESPONSE
+
+
+def handle_stream_stream(request_iterator, servicer_context):
+  for request in request_iterator:
+    yield _RESPONSE
+
+
+class _MethodHandler(grpc.RpcMethodHandler):
+
+  def __init__(self, request_streaming, response_streaming):
+    self.request_streaming = request_streaming
+    self.response_streaming = response_streaming
+    self.request_deserializer = None
+    self.response_serializer = None
+    self.unary_unary = None
+    self.unary_stream = None
+    self.stream_unary = None
+    self.stream_stream = None
+    if self.request_streaming and self.response_streaming:
+      self.stream_stream = handle_stream_stream
+    elif self.request_streaming:
+      self.stream_unary = handle_stream_unary
+    elif self.response_streaming:
+      self.unary_stream = handle_unary_stream
+    else:
+      self.unary_unary = handle_unary_unary
+
+
+class _GenericHandler(grpc.GenericRpcHandler):
+
+  def service(self, handler_call_details):
+    if handler_call_details.method == _UNARY_UNARY:
+      return _MethodHandler(False, False)
+    elif handler_call_details.method == _UNARY_STREAM:
+      return _MethodHandler(False, True)
+    elif handler_call_details.method == _STREAM_UNARY:
+      return _MethodHandler(True, False)
+    elif handler_call_details.method == _STREAM_STREAM:
+      return _MethodHandler(True, True)
+    else:
+      return None
+
+
+class EmptyMessageTest(unittest.TestCase):
+
+  def setUp(self):
+    self._server_pool = logging_pool.pool(test_constants.THREAD_CONCURRENCY)
+    self._server = grpc.server((_GenericHandler(),), self._server_pool)
+    port = self._server.add_insecure_port('[::]:0')
+    self._server.start()
+    self._channel = grpc.insecure_channel('localhost:%d' % port)
+
+  def tearDown(self):
+    self._server.stop(0)
+
+  def testUnaryUnary(self):
+    response = self._channel.unary_unary(_UNARY_UNARY)(_REQUEST)
+    self.assertEqual(_RESPONSE, response)
+
+  def testUnaryStream(self):
+    response_iterator = self._channel.unary_stream(_UNARY_STREAM)(_REQUEST)
+    self.assertSequenceEqual(
+        [_RESPONSE] * test_constants.STREAM_LENGTH, list(response_iterator))
+
+  def testStreamUnary(self):
+    response = self._channel.stream_unary(_STREAM_UNARY)(
+        [_REQUEST] * test_constants.STREAM_LENGTH)
+    self.assertEqual(_RESPONSE, response)
+
+  def testStreamStream(self):
+    response_iterator = self._channel.stream_stream(_STREAM_STREAM)(
+        [_REQUEST] * test_constants.STREAM_LENGTH)
+    self.assertSequenceEqual(
+        [_RESPONSE] * test_constants.STREAM_LENGTH, list(response_iterator))
+
+
+if __name__ == '__main__':
+  unittest.main(verbosity=2)
+
diff --git a/src/python/grpcio/tests/unit/_links/_transmission_test.py b/src/python/grpcio/tests/unit/_links/_transmission_test.py
index 888684d..1f6edd1 100644
--- a/src/python/grpcio/tests/unit/_links/_transmission_test.py
+++ b/src/python/grpcio/tests/unit/_links/_transmission_test.py
@@ -153,7 +153,7 @@
         invocation_mate.tickets()[-1].termination,
         links.Ticket.Termination.COMPLETION)
     self.assertIs(invocation_mate.tickets()[-1].code, test_code)
-    self.assertEqual(invocation_mate.tickets()[-1].message, test_message)
+    self.assertEqual(invocation_mate.tickets()[-1].message, test_message.encode())
 
   def _perform_scenario_test(self, scenario):
     test_operation_id = object()
diff --git a/src/python/grpcio/tests/unit/_rpc_test.py b/src/python/grpcio/tests/unit/_rpc_test.py
new file mode 100644
index 0000000..b33bff4
--- /dev/null
+++ b/src/python/grpcio/tests/unit/_rpc_test.py
@@ -0,0 +1,777 @@
+# 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.
+
+"""Test of gRPC Python's application-layer API."""
+
+from __future__ import division
+
+import itertools
+import threading
+import unittest
+from concurrent import futures
+
+import grpc
+from grpc.framework.foundation import logging_pool
+
+from tests.unit.framework.common import test_constants
+from tests.unit.framework.common import test_control
+
+_SERIALIZE_REQUEST = lambda bytestring: bytestring * 2
+_DESERIALIZE_REQUEST = lambda bytestring: bytestring[len(bytestring) // 2:]
+_SERIALIZE_RESPONSE = lambda bytestring: bytestring * 3
+_DESERIALIZE_RESPONSE = lambda bytestring: bytestring[:len(bytestring) // 3]
+
+_UNARY_UNARY = b'/test/UnaryUnary'
+_UNARY_STREAM = b'/test/UnaryStream'
+_STREAM_UNARY = b'/test/StreamUnary'
+_STREAM_STREAM = b'/test/StreamStream'
+
+
+class _Callback(object):
+
+  def __init__(self):
+    self._condition = threading.Condition()
+    self._value = None
+    self._called = False
+
+  def __call__(self, value):
+    with self._condition:
+      self._value = value
+      self._called = True
+      self._condition.notify_all()
+
+  def value(self):
+    with self._condition:
+      while not self._called:
+        self._condition.wait()
+      return self._value
+
+
+class _Handler(object):
+
+  def __init__(self, control):
+    self._control = control
+
+  def handle_unary_unary(self, request, servicer_context):
+    self._control.control()
+    if servicer_context is not None:
+      servicer_context.set_trailing_metadata(((b'testkey', b'testvalue',),))
+    return request
+
+  def handle_unary_stream(self, request, servicer_context):
+    for _ in range(test_constants.STREAM_LENGTH):
+      self._control.control()
+      yield request
+    self._control.control()
+    if servicer_context is not None:
+      servicer_context.set_trailing_metadata(((b'testkey', b'testvalue',),))
+
+  def handle_stream_unary(self, request_iterator, servicer_context):
+    if servicer_context is not None:
+      servicer_context.invocation_metadata()
+    self._control.control()
+    response_elements = []
+    for request in request_iterator:
+      self._control.control()
+      response_elements.append(request)
+    self._control.control()
+    if servicer_context is not None:
+      servicer_context.set_trailing_metadata(((b'testkey', b'testvalue',),))
+    return b''.join(response_elements)
+
+  def handle_stream_stream(self, request_iterator, servicer_context):
+    self._control.control()
+    if servicer_context is not None:
+      servicer_context.set_trailing_metadata(((b'testkey', b'testvalue',),))
+    for request in request_iterator:
+      self._control.control()
+      yield request
+    self._control.control()
+
+
+class _MethodHandler(grpc.RpcMethodHandler):
+
+  def __init__(
+      self, request_streaming, response_streaming, request_deserializer,
+      response_serializer, unary_unary, unary_stream, stream_unary,
+      stream_stream):
+    self.request_streaming = request_streaming
+    self.response_streaming = response_streaming
+    self.request_deserializer = request_deserializer
+    self.response_serializer = response_serializer
+    self.unary_unary = unary_unary
+    self.unary_stream = unary_stream
+    self.stream_unary = stream_unary
+    self.stream_stream = stream_stream
+
+
+class _GenericHandler(grpc.GenericRpcHandler):
+
+  def __init__(self, handler):
+    self._handler = handler
+
+  def service(self, handler_call_details):
+    if handler_call_details.method == _UNARY_UNARY:
+      return _MethodHandler(
+          False, False, None, None, self._handler.handle_unary_unary, None,
+          None, None)
+    elif handler_call_details.method == _UNARY_STREAM:
+      return _MethodHandler(
+        False, True, _DESERIALIZE_REQUEST, _SERIALIZE_RESPONSE, None,
+        self._handler.handle_unary_stream, None, None)
+    elif handler_call_details.method == _STREAM_UNARY:
+      return _MethodHandler(
+          True, False, _DESERIALIZE_REQUEST, _SERIALIZE_RESPONSE, None, None,
+          self._handler.handle_stream_unary, None)
+    elif handler_call_details.method == _STREAM_STREAM:
+      return _MethodHandler(
+          True, True, None, None, None, None, None,
+          self._handler.handle_stream_stream)
+    else:
+      return None
+
+
+def _unary_unary_multi_callable(channel):
+  return channel.unary_unary(_UNARY_UNARY)
+
+
+def _unary_stream_multi_callable(channel):
+  return channel.unary_stream(
+      _UNARY_STREAM,
+      request_serializer=_SERIALIZE_REQUEST,
+      response_deserializer=_DESERIALIZE_RESPONSE)
+
+
+def _stream_unary_multi_callable(channel):
+  return channel.stream_unary(
+      _STREAM_UNARY,
+      request_serializer=_SERIALIZE_REQUEST,
+      response_deserializer=_DESERIALIZE_RESPONSE)
+
+
+def _stream_stream_multi_callable(channel):
+  return channel.stream_stream(_STREAM_STREAM)
+
+
+class RPCTest(unittest.TestCase):
+
+  def setUp(self):
+    self._control = test_control.PauseFailControl()
+    self._handler = _Handler(self._control)
+    self._server_pool = logging_pool.pool(test_constants.THREAD_CONCURRENCY)
+
+    self._server = grpc.server((), self._server_pool)
+    port = self._server.add_insecure_port(b'[::]:0')
+    self._server.add_generic_rpc_handlers((_GenericHandler(self._handler),))
+    self._server.start()
+
+    self._channel = grpc.insecure_channel('localhost:%d' % port)
+
+  # TODO(nathaniel): Why is this necessary, and only in some development
+  # environments?
+  def tearDown(self):
+    del self._channel
+    del self._server
+    del self._server_pool
+
+  def testUnrecognizedMethod(self):
+    request = b'abc'
+
+    with self.assertRaises(grpc.RpcError) as exception_context:
+      self._channel.unary_unary(b'NoSuchMethod')(request)
+
+    self.assertEqual(
+        grpc.StatusCode.UNIMPLEMENTED, exception_context.exception.code())
+
+  def testSuccessfulUnaryRequestBlockingUnaryResponse(self):
+    request = b'\x07\x08'
+    expected_response = self._handler.handle_unary_unary(request, None)
+
+    multi_callable = _unary_unary_multi_callable(self._channel)
+    response = multi_callable(
+        request, metadata=(
+            (b'test', b'SuccessfulUnaryRequestBlockingUnaryResponse'),))
+
+    self.assertEqual(expected_response, response)
+
+  def testSuccessfulUnaryRequestBlockingUnaryResponseWithCall(self):
+    request = b'\x07\x08'
+    expected_response = self._handler.handle_unary_unary(request, None)
+
+    multi_callable = _unary_unary_multi_callable(self._channel)
+    response, call = multi_callable(
+        request, metadata=(
+            (b'test', b'SuccessfulUnaryRequestBlockingUnaryResponseWithCall'),),
+        with_call=True)
+
+    self.assertEqual(expected_response, response)
+    self.assertIs(grpc.StatusCode.OK, call.code())
+
+  def testSuccessfulUnaryRequestFutureUnaryResponse(self):
+    request = b'\x07\x08'
+    expected_response = self._handler.handle_unary_unary(request, None)
+
+    multi_callable = _unary_unary_multi_callable(self._channel)
+    response_future = multi_callable.future(
+        request, metadata=(
+            (b'test', b'SuccessfulUnaryRequestFutureUnaryResponse'),))
+    response = response_future.result()
+
+    self.assertEqual(expected_response, response)
+
+  def testSuccessfulUnaryRequestStreamResponse(self):
+    request = b'\x37\x58'
+    expected_responses = tuple(self._handler.handle_unary_stream(request, None))
+
+    multi_callable = _unary_stream_multi_callable(self._channel)
+    response_iterator = multi_callable(
+        request,
+        metadata=((b'test', b'SuccessfulUnaryRequestStreamResponse'),))
+    responses = tuple(response_iterator)
+
+    self.assertSequenceEqual(expected_responses, responses)
+
+  def testSuccessfulStreamRequestBlockingUnaryResponse(self):
+    requests = tuple(b'\x07\x08' for _ in range(test_constants.STREAM_LENGTH))
+    expected_response = self._handler.handle_stream_unary(iter(requests), None)
+    request_iterator = iter(requests)
+
+    multi_callable = _stream_unary_multi_callable(self._channel)
+    response = multi_callable(
+        request_iterator,
+        metadata=((b'test', b'SuccessfulStreamRequestBlockingUnaryResponse'),))
+
+    self.assertEqual(expected_response, response)
+
+  def testSuccessfulStreamRequestBlockingUnaryResponseWithCall(self):
+    requests = tuple(b'\x07\x08' for _ in range(test_constants.STREAM_LENGTH))
+    expected_response = self._handler.handle_stream_unary(iter(requests), None)
+    request_iterator = iter(requests)
+
+    multi_callable = _stream_unary_multi_callable(self._channel)
+    response, call = multi_callable(
+        request_iterator,
+        metadata=(
+            (b'test', b'SuccessfulStreamRequestBlockingUnaryResponseWithCall'),
+        ), with_call=True)
+
+    self.assertEqual(expected_response, response)
+    self.assertIs(grpc.StatusCode.OK, call.code())
+
+  def testSuccessfulStreamRequestFutureUnaryResponse(self):
+    requests = tuple(b'\x07\x08' for _ in range(test_constants.STREAM_LENGTH))
+    expected_response = self._handler.handle_stream_unary(iter(requests), None)
+    request_iterator = iter(requests)
+
+    multi_callable = _stream_unary_multi_callable(self._channel)
+    response_future = multi_callable.future(
+        request_iterator,
+        metadata=(
+            (b'test', b'SuccessfulStreamRequestFutureUnaryResponse'),))
+    response = response_future.result()
+
+    self.assertEqual(expected_response, response)
+
+  def testSuccessfulStreamRequestStreamResponse(self):
+    requests = tuple(b'\x77\x58' for _ in range(test_constants.STREAM_LENGTH))
+    expected_responses = tuple(
+        self._handler.handle_stream_stream(iter(requests), None))
+    request_iterator = iter(requests)
+
+    multi_callable = _stream_stream_multi_callable(self._channel)
+    response_iterator = multi_callable(
+        request_iterator,
+        metadata=((b'test', b'SuccessfulStreamRequestStreamResponse'),))
+    responses = tuple(response_iterator)
+
+    self.assertSequenceEqual(expected_responses, responses)
+
+  def testSequentialInvocations(self):
+    first_request = b'\x07\x08'
+    second_request = b'\x0809'
+    expected_first_response = self._handler.handle_unary_unary(
+        first_request, None)
+    expected_second_response = self._handler.handle_unary_unary(
+        second_request, None)
+
+    multi_callable = _unary_unary_multi_callable(self._channel)
+    first_response = multi_callable(
+        first_request, metadata=((b'test', b'SequentialInvocations'),))
+    second_response = multi_callable(
+        second_request, metadata=((b'test', b'SequentialInvocations'),))
+
+    self.assertEqual(expected_first_response, first_response)
+    self.assertEqual(expected_second_response, second_response)
+
+  def testConcurrentBlockingInvocations(self):
+    pool = logging_pool.pool(test_constants.THREAD_CONCURRENCY)
+    requests = tuple(b'\x07\x08' for _ in range(test_constants.STREAM_LENGTH))
+    expected_response = self._handler.handle_stream_unary(iter(requests), None)
+    expected_responses = [expected_response] * test_constants.THREAD_CONCURRENCY
+    response_futures = [None] * test_constants.THREAD_CONCURRENCY
+
+    multi_callable = _stream_unary_multi_callable(self._channel)
+    for index in range(test_constants.THREAD_CONCURRENCY):
+      request_iterator = iter(requests)
+      response_future = pool.submit(
+          multi_callable, request_iterator,
+          metadata=((b'test', b'ConcurrentBlockingInvocations'),))
+      response_futures[index] = response_future
+    responses = tuple(
+        response_future.result() for response_future in response_futures)
+
+    pool.shutdown(wait=True)
+    self.assertSequenceEqual(expected_responses, responses)
+
+  def testConcurrentFutureInvocations(self):
+    requests = tuple(b'\x07\x08' for _ in range(test_constants.STREAM_LENGTH))
+    expected_response = self._handler.handle_stream_unary(iter(requests), None)
+    expected_responses = [expected_response] * test_constants.THREAD_CONCURRENCY
+    response_futures = [None] * test_constants.THREAD_CONCURRENCY
+
+    multi_callable = _stream_unary_multi_callable(self._channel)
+    for index in range(test_constants.THREAD_CONCURRENCY):
+      request_iterator = iter(requests)
+      response_future = multi_callable.future(
+          request_iterator,
+          metadata=((b'test', b'ConcurrentFutureInvocations'),))
+      response_futures[index] = response_future
+    responses = tuple(
+        response_future.result() for response_future in response_futures)
+
+    self.assertSequenceEqual(expected_responses, responses)
+
+  def testWaitingForSomeButNotAllConcurrentFutureInvocations(self):
+    pool = logging_pool.pool(test_constants.THREAD_CONCURRENCY)
+    request = b'\x67\x68'
+    expected_response = self._handler.handle_unary_unary(request, None)
+    response_futures = [None] * test_constants.THREAD_CONCURRENCY
+    lock = threading.Lock()
+    test_is_running_cell = [True]
+    def wrap_future(future):
+      def wrap():
+        try:
+          return future.result()
+        except grpc.RpcError:
+          with lock:
+            if test_is_running_cell[0]:
+              raise
+          return None
+      return wrap
+
+    multi_callable = _unary_unary_multi_callable(self._channel)
+    for index in range(test_constants.THREAD_CONCURRENCY):
+      inner_response_future = multi_callable.future(
+          request,
+          metadata=(
+              (b'test',
+               b'WaitingForSomeButNotAllConcurrentFutureInvocations'),))
+      outer_response_future = pool.submit(wrap_future(inner_response_future))
+      response_futures[index] = outer_response_future
+
+    some_completed_response_futures_iterator = itertools.islice(
+        futures.as_completed(response_futures),
+        test_constants.THREAD_CONCURRENCY // 2)
+    for response_future in some_completed_response_futures_iterator:
+      self.assertEqual(expected_response, response_future.result())
+    with lock:
+      test_is_running_cell[0] = False
+
+  def testConsumingOneStreamResponseUnaryRequest(self):
+    request = b'\x57\x38'
+
+    multi_callable = _unary_stream_multi_callable(self._channel)
+    response_iterator = multi_callable(
+        request,
+        metadata=(
+            (b'test', b'ConsumingOneStreamResponseUnaryRequest'),))
+    next(response_iterator)
+
+  def testConsumingSomeButNotAllStreamResponsesUnaryRequest(self):
+    request = b'\x57\x38'
+
+    multi_callable = _unary_stream_multi_callable(self._channel)
+    response_iterator = multi_callable(
+        request,
+        metadata=(
+            (b'test', b'ConsumingSomeButNotAllStreamResponsesUnaryRequest'),))
+    for _ in range(test_constants.STREAM_LENGTH // 2):
+      next(response_iterator)
+
+  def testConsumingSomeButNotAllStreamResponsesStreamRequest(self):
+    requests = tuple(b'\x67\x88' for _ in range(test_constants.STREAM_LENGTH))
+    request_iterator = iter(requests)
+
+    multi_callable = _stream_stream_multi_callable(self._channel)
+    response_iterator = multi_callable(
+        request_iterator,
+        metadata=(
+            (b'test', b'ConsumingSomeButNotAllStreamResponsesStreamRequest'),))
+    for _ in range(test_constants.STREAM_LENGTH // 2):
+      next(response_iterator)
+
+  def testConsumingTooManyStreamResponsesStreamRequest(self):
+    requests = tuple(b'\x67\x88' for _ in range(test_constants.STREAM_LENGTH))
+    request_iterator = iter(requests)
+
+    multi_callable = _stream_stream_multi_callable(self._channel)
+    response_iterator = multi_callable(
+        request_iterator,
+        metadata=(
+            (b'test', b'ConsumingTooManyStreamResponsesStreamRequest'),))
+    for _ in range(test_constants.STREAM_LENGTH):
+      next(response_iterator)
+    for _ in range(test_constants.STREAM_LENGTH):
+      with self.assertRaises(StopIteration):
+        next(response_iterator)
+
+    self.assertIsNotNone(response_iterator.initial_metadata())
+    self.assertIs(grpc.StatusCode.OK, response_iterator.code())
+    self.assertIsNotNone(response_iterator.details())
+    self.assertIsNotNone(response_iterator.trailing_metadata())
+
+  def testCancelledUnaryRequestUnaryResponse(self):
+    request = b'\x07\x17'
+
+    multi_callable = _unary_unary_multi_callable(self._channel)
+    with self._control.pause():
+      response_future = multi_callable.future(
+          request,
+          metadata=((b'test', b'CancelledUnaryRequestUnaryResponse'),))
+      response_future.cancel()
+
+    self.assertTrue(response_future.cancelled())
+    with self.assertRaises(grpc.FutureCancelledError):
+      response_future.result()
+    self.assertIs(grpc.StatusCode.CANCELLED, response_future.code())
+
+  def testCancelledUnaryRequestStreamResponse(self):
+    request = b'\x07\x19'
+
+    multi_callable = _unary_stream_multi_callable(self._channel)
+    with self._control.pause():
+      response_iterator = multi_callable(
+          request,
+          metadata=((b'test', b'CancelledUnaryRequestStreamResponse'),))
+      self._control.block_until_paused()
+      response_iterator.cancel()
+
+    with self.assertRaises(grpc.RpcError) as exception_context:
+      next(response_iterator)
+    self.assertIs(grpc.StatusCode.CANCELLED, exception_context.exception.code())
+    self.assertIsNotNone(response_iterator.initial_metadata())
+    self.assertIs(grpc.StatusCode.CANCELLED, response_iterator.code())
+    self.assertIsNotNone(response_iterator.details())
+    self.assertIsNotNone(response_iterator.trailing_metadata())
+
+  def testCancelledStreamRequestUnaryResponse(self):
+    requests = tuple(b'\x07\x08' for _ in range(test_constants.STREAM_LENGTH))
+    request_iterator = iter(requests)
+
+    multi_callable = _stream_unary_multi_callable(self._channel)
+    with self._control.pause():
+      response_future = multi_callable.future(
+          request_iterator,
+          metadata=((b'test', b'CancelledStreamRequestUnaryResponse'),))
+      self._control.block_until_paused()
+      response_future.cancel()
+
+    self.assertTrue(response_future.cancelled())
+    with self.assertRaises(grpc.FutureCancelledError):
+      response_future.result()
+    self.assertIsNotNone(response_future.initial_metadata())
+    self.assertIs(grpc.StatusCode.CANCELLED, response_future.code())
+    self.assertIsNotNone(response_future.details())
+    self.assertIsNotNone(response_future.trailing_metadata())
+
+  def testCancelledStreamRequestStreamResponse(self):
+    requests = tuple(b'\x07\x08' for _ in range(test_constants.STREAM_LENGTH))
+    request_iterator = iter(requests)
+
+    multi_callable = _stream_stream_multi_callable(self._channel)
+    with self._control.pause():
+      response_iterator = multi_callable(
+          request_iterator,
+          metadata=((b'test', b'CancelledStreamRequestStreamResponse'),))
+      response_iterator.cancel()
+
+    with self.assertRaises(grpc.RpcError):
+      next(response_iterator)
+    self.assertIsNotNone(response_iterator.initial_metadata())
+    self.assertIs(grpc.StatusCode.CANCELLED, response_iterator.code())
+    self.assertIsNotNone(response_iterator.details())
+    self.assertIsNotNone(response_iterator.trailing_metadata())
+
+  def testExpiredUnaryRequestBlockingUnaryResponse(self):
+    request = b'\x07\x17'
+
+    multi_callable = _unary_unary_multi_callable(self._channel)
+    with self._control.pause():
+      with self.assertRaises(grpc.RpcError) as exception_context:
+        multi_callable(
+            request, timeout=test_constants.SHORT_TIMEOUT,
+            metadata=((b'test', b'ExpiredUnaryRequestBlockingUnaryResponse'),),
+            with_call=True)
+
+    self.assertIsNotNone(exception_context.exception.initial_metadata())
+    self.assertIs(
+        grpc.StatusCode.DEADLINE_EXCEEDED, exception_context.exception.code())
+    self.assertIsNotNone(exception_context.exception.details())
+    self.assertIsNotNone(exception_context.exception.trailing_metadata())
+
+  def testExpiredUnaryRequestFutureUnaryResponse(self):
+    request = b'\x07\x17'
+    callback = _Callback()
+
+    multi_callable = _unary_unary_multi_callable(self._channel)
+    with self._control.pause():
+      response_future = multi_callable.future(
+          request, timeout=test_constants.SHORT_TIMEOUT,
+          metadata=((b'test', b'ExpiredUnaryRequestFutureUnaryResponse'),))
+      response_future.add_done_callback(callback)
+      value_passed_to_callback = callback.value()
+
+    self.assertIs(response_future, value_passed_to_callback)
+    self.assertIsNotNone(response_future.initial_metadata())
+    self.assertIs(grpc.StatusCode.DEADLINE_EXCEEDED, response_future.code())
+    self.assertIsNotNone(response_future.details())
+    self.assertIsNotNone(response_future.trailing_metadata())
+    with self.assertRaises(grpc.RpcError) as exception_context:
+      response_future.result()
+    self.assertIs(
+        grpc.StatusCode.DEADLINE_EXCEEDED, exception_context.exception.code())
+    self.assertIsInstance(response_future.exception(), grpc.RpcError)
+    self.assertIs(
+        grpc.StatusCode.DEADLINE_EXCEEDED, response_future.exception().code())
+
+  def testExpiredUnaryRequestStreamResponse(self):
+    request = b'\x07\x19'
+
+    multi_callable = _unary_stream_multi_callable(self._channel)
+    with self._control.pause():
+      with self.assertRaises(grpc.RpcError) as exception_context:
+        response_iterator = multi_callable(
+            request, timeout=test_constants.SHORT_TIMEOUT,
+            metadata=((b'test', b'ExpiredUnaryRequestStreamResponse'),))
+        next(response_iterator)
+
+    self.assertIs(
+        grpc.StatusCode.DEADLINE_EXCEEDED, exception_context.exception.code())
+    self.assertIs(grpc.StatusCode.DEADLINE_EXCEEDED, response_iterator.code())
+
+  def testExpiredStreamRequestBlockingUnaryResponse(self):
+    requests = tuple(b'\x07\x08' for _ in range(test_constants.STREAM_LENGTH))
+    request_iterator = iter(requests)
+
+    multi_callable = _stream_unary_multi_callable(self._channel)
+    with self._control.pause():
+      with self.assertRaises(grpc.RpcError) as exception_context:
+        multi_callable(
+            request_iterator, timeout=test_constants.SHORT_TIMEOUT,
+            metadata=((b'test', b'ExpiredStreamRequestBlockingUnaryResponse'),))
+
+    self.assertIsNotNone(exception_context.exception.initial_metadata())
+    self.assertIs(
+        grpc.StatusCode.DEADLINE_EXCEEDED, exception_context.exception.code())
+    self.assertIsNotNone(exception_context.exception.details())
+    self.assertIsNotNone(exception_context.exception.trailing_metadata())
+
+  def testExpiredStreamRequestFutureUnaryResponse(self):
+    requests = tuple(b'\x07\x18' for _ in range(test_constants.STREAM_LENGTH))
+    request_iterator = iter(requests)
+    callback = _Callback()
+
+    multi_callable = _stream_unary_multi_callable(self._channel)
+    with self._control.pause():
+      response_future = multi_callable.future(
+          request_iterator, timeout=test_constants.SHORT_TIMEOUT,
+          metadata=((b'test', b'ExpiredStreamRequestFutureUnaryResponse'),))
+      response_future.add_done_callback(callback)
+      value_passed_to_callback = callback.value()
+
+    with self.assertRaises(grpc.RpcError) as exception_context:
+      response_future.result()
+    self.assertIs(grpc.StatusCode.DEADLINE_EXCEEDED, response_future.code())
+    self.assertIs(
+        grpc.StatusCode.DEADLINE_EXCEEDED, exception_context.exception.code())
+    self.assertIsInstance(response_future.exception(), grpc.RpcError)
+    self.assertIs(response_future, value_passed_to_callback)
+    self.assertIsNotNone(response_future.initial_metadata())
+    self.assertIs(grpc.StatusCode.DEADLINE_EXCEEDED, response_future.code())
+    self.assertIsNotNone(response_future.details())
+    self.assertIsNotNone(response_future.trailing_metadata())
+
+  def testExpiredStreamRequestStreamResponse(self):
+    requests = tuple(b'\x67\x18' for _ in range(test_constants.STREAM_LENGTH))
+    request_iterator = iter(requests)
+
+    multi_callable = _stream_stream_multi_callable(self._channel)
+    with self._control.pause():
+      with self.assertRaises(grpc.RpcError) as exception_context:
+        response_iterator = multi_callable(
+            request_iterator, timeout=test_constants.SHORT_TIMEOUT,
+            metadata=((b'test', b'ExpiredStreamRequestStreamResponse'),))
+        next(response_iterator)
+
+    self.assertIs(
+        grpc.StatusCode.DEADLINE_EXCEEDED, exception_context.exception.code())
+    self.assertIs(grpc.StatusCode.DEADLINE_EXCEEDED, response_iterator.code())
+
+  def testFailedUnaryRequestBlockingUnaryResponse(self):
+    request = b'\x37\x17'
+
+    multi_callable = _unary_unary_multi_callable(self._channel)
+    with self._control.fail():
+      with self.assertRaises(grpc.RpcError) as exception_context:
+        multi_callable(
+            request,
+            metadata=((b'test', b'FailedUnaryRequestBlockingUnaryResponse'),),
+            with_call=True)
+
+    self.assertIs(grpc.StatusCode.UNKNOWN, exception_context.exception.code())
+
+  def testFailedUnaryRequestFutureUnaryResponse(self):
+    request = b'\x37\x17'
+    callback = _Callback()
+
+    multi_callable = _unary_unary_multi_callable(self._channel)
+    with self._control.fail():
+      response_future = multi_callable.future(
+          request,
+          metadata=((b'test', b'FailedUnaryRequestFutureUnaryResponse'),))
+      response_future.add_done_callback(callback)
+      value_passed_to_callback = callback.value()
+
+    with self.assertRaises(grpc.RpcError) as exception_context:
+      response_future.result()
+    self.assertIs(
+        grpc.StatusCode.UNKNOWN, exception_context.exception.code())
+    self.assertIsInstance(response_future.exception(), grpc.RpcError)
+    self.assertIs(grpc.StatusCode.UNKNOWN, response_future.exception().code())
+    self.assertIs(response_future, value_passed_to_callback)
+
+  def testFailedUnaryRequestStreamResponse(self):
+    request = b'\x37\x17'
+
+    multi_callable = _unary_stream_multi_callable(self._channel)
+    with self.assertRaises(grpc.RpcError) as exception_context:
+      with self._control.fail():
+        response_iterator = multi_callable(
+            request,
+            metadata=((b'test', b'FailedUnaryRequestStreamResponse'),))
+        next(response_iterator)
+
+    self.assertIs(grpc.StatusCode.UNKNOWN, exception_context.exception.code())
+
+  def testFailedStreamRequestBlockingUnaryResponse(self):
+    requests = tuple(b'\x47\x58' for _ in range(test_constants.STREAM_LENGTH))
+    request_iterator = iter(requests)
+
+    multi_callable = _stream_unary_multi_callable(self._channel)
+    with self._control.fail():
+      with self.assertRaises(grpc.RpcError) as exception_context:
+        multi_callable(
+            request_iterator,
+            metadata=((b'test', b'FailedStreamRequestBlockingUnaryResponse'),))
+
+    self.assertIs(grpc.StatusCode.UNKNOWN, exception_context.exception.code())
+
+  def testFailedStreamRequestFutureUnaryResponse(self):
+    requests = tuple(b'\x07\x18' for _ in range(test_constants.STREAM_LENGTH))
+    request_iterator = iter(requests)
+    callback = _Callback()
+
+    multi_callable = _stream_unary_multi_callable(self._channel)
+    with self._control.fail():
+      response_future = multi_callable.future(
+          request_iterator,
+          metadata=((b'test', b'FailedStreamRequestFutureUnaryResponse'),))
+      response_future.add_done_callback(callback)
+      value_passed_to_callback = callback.value()
+
+    with self.assertRaises(grpc.RpcError) as exception_context:
+      response_future.result()
+    self.assertIs(grpc.StatusCode.UNKNOWN, response_future.code())
+    self.assertIs(
+        grpc.StatusCode.UNKNOWN, exception_context.exception.code())
+    self.assertIsInstance(response_future.exception(), grpc.RpcError)
+    self.assertIs(response_future, value_passed_to_callback)
+
+  def testFailedStreamRequestStreamResponse(self):
+    requests = tuple(b'\x67\x88' for _ in range(test_constants.STREAM_LENGTH))
+    request_iterator = iter(requests)
+
+    multi_callable = _stream_stream_multi_callable(self._channel)
+    with self._control.fail():
+      with self.assertRaises(grpc.RpcError) as exception_context:
+        response_iterator = multi_callable(
+            request_iterator,
+            metadata=((b'test', b'FailedStreamRequestStreamResponse'),))
+        tuple(response_iterator)
+
+    self.assertIs(grpc.StatusCode.UNKNOWN, exception_context.exception.code())
+    self.assertIs(grpc.StatusCode.UNKNOWN, response_iterator.code())
+
+  def testIgnoredUnaryRequestFutureUnaryResponse(self):
+    request = b'\x37\x17'
+
+    multi_callable = _unary_unary_multi_callable(self._channel)
+    multi_callable.future(
+        request,
+        metadata=((b'test', b'IgnoredUnaryRequestFutureUnaryResponse'),))
+
+  def testIgnoredUnaryRequestStreamResponse(self):
+    request = b'\x37\x17'
+
+    multi_callable = _unary_stream_multi_callable(self._channel)
+    multi_callable(
+        request,
+        metadata=((b'test', b'IgnoredUnaryRequestStreamResponse'),))
+
+  def testIgnoredStreamRequestFutureUnaryResponse(self):
+    requests = tuple(b'\x07\x18' for _ in range(test_constants.STREAM_LENGTH))
+    request_iterator = iter(requests)
+
+    multi_callable = _stream_unary_multi_callable(self._channel)
+    multi_callable.future(
+        request_iterator,
+        metadata=((b'test', b'IgnoredStreamRequestFutureUnaryResponse'),))
+
+  def testIgnoredStreamRequestStreamResponse(self):
+    requests = tuple(b'\x67\x88' for _ in range(test_constants.STREAM_LENGTH))
+    request_iterator = iter(requests)
+
+    multi_callable = _stream_stream_multi_callable(self._channel)
+    multi_callable(
+        request_iterator,
+        metadata=((b'test', b'IgnoredStreamRequestStreamResponse'),))
+
+
+if __name__ == '__main__':
+  unittest.main(verbosity=2)
diff --git a/src/python/grpcio/tests/unit/beta/_beta_features_test.py b/src/python/grpcio/tests/unit/beta/_beta_features_test.py
index bb2893a..3a9701b 100644
--- a/src/python/grpcio/tests/unit/beta/_beta_features_test.py
+++ b/src/python/grpcio/tests/unit/beta/_beta_features_test.py
@@ -42,8 +42,8 @@
 
 _SERVER_HOST_OVERRIDE = 'foo.test.google.fr'
 
-_PER_RPC_CREDENTIALS_METADATA_KEY = 'my-call-credentials-metadata-key'
-_PER_RPC_CREDENTIALS_METADATA_VALUE = 'my-call-credentials-metadata-value'
+_PER_RPC_CREDENTIALS_METADATA_KEY = b'my-call-credentials-metadata-key'
+_PER_RPC_CREDENTIALS_METADATA_VALUE = b'my-call-credentials-metadata-value'
 
 _GROUP = 'group'
 _UNARY_UNARY = 'unary-unary'
diff --git a/src/python/grpcio/tests/unit/beta/_implementations_test.py b/src/python/grpcio/tests/unit/beta/_implementations_test.py
index 26be670..127f93e 100644
--- a/src/python/grpcio/tests/unit/beta/_implementations_test.py
+++ b/src/python/grpcio/tests/unit/beta/_implementations_test.py
@@ -29,8 +29,11 @@
 
 """Tests the implementations module of the gRPC Python Beta API."""
 
+import datetime
 import unittest
 
+from oauth2client import client as oauth2client_client
+
 from grpc.beta import implementations
 from tests.unit import resources
 
@@ -49,5 +52,19 @@
         channel_credentials, implementations.ChannelCredentials)
 
 
+class CallCredentialsTest(unittest.TestCase):
+
+  def test_google_call_credentials(self):
+    creds = oauth2client_client.GoogleCredentials(
+        'token', 'client_id', 'secret', 'refresh_token',
+        datetime.datetime(2008, 6, 24), 'https://refresh.uri.com/',
+        'user_agent')
+    call_creds = implementations.google_call_credentials(creds)
+    self.assertIsInstance(call_creds, implementations.CallCredentials)
+
+  def test_access_token_call_credentials(self):
+    call_creds = implementations.access_token_call_credentials('token')
+    self.assertIsInstance(call_creds, implementations.CallCredentials)
+
 if __name__ == '__main__':
   unittest.main(verbosity=2)
diff --git a/src/python/grpcio/tests/unit/beta/_not_found_test.py b/src/python/grpcio/tests/unit/beta/_not_found_test.py
index 44fcd1e..37b8c49 100644
--- a/src/python/grpcio/tests/unit/beta/_not_found_test.py
+++ b/src/python/grpcio/tests/unit/beta/_not_found_test.py
@@ -61,7 +61,7 @@
 
   def test_future_stream_unary_not_found(self):
     rpc_future = self._generic_stub.future_stream_unary(
-        'grupe', 'mevvod', b'def', test_constants.LONG_TIMEOUT)
+        'grupe', 'mevvod', [b'def'], test_constants.LONG_TIMEOUT)
     with self.assertRaises(face.LocalError) as exception_assertion_context:
       rpc_future.result()
     self.assertIs(
diff --git a/src/python/grpcio/tests/unit/beta/test_utilities.py b/src/python/grpcio/tests/unit/beta/test_utilities.py
index 0313e06..66b5f72 100644
--- a/src/python/grpcio/tests/unit/beta/test_utilities.py
+++ b/src/python/grpcio/tests/unit/beta/test_utilities.py
@@ -29,7 +29,7 @@
 
 """Test-appropriate entry points into the gRPC Python Beta API."""
 
-from grpc._adapter import _intermediary_low
+import grpc
 from grpc.beta import implementations
 
 
@@ -48,9 +48,8 @@
     An implementations.Channel to the remote host through which RPCs may be
       conducted.
   """
-  hostport = '%s:%d' % (host, port)
-  intermediary_low_channel = _intermediary_low.Channel(
-      hostport, channel_credentials._low_credentials,
-      server_host_override=server_host_override)
-  return implementations.Channel(
-      intermediary_low_channel._internal, intermediary_low_channel)
+  target = '%s:%d' % (host, port)
+  channel = grpc.secure_channel(
+      target, ((b'grpc.ssl_target_name_override', server_host_override,),),
+      channel_credentials._credentials)
+  return implementations.Channel(channel)
diff --git a/src/python/grpcio/tests/unit/framework/common/test_control.py b/src/python/grpcio/tests/unit/framework/common/test_control.py
index ca5ba3a..088e2f8 100644
--- a/src/python/grpcio/tests/unit/framework/common/test_control.py
+++ b/src/python/grpcio/tests/unit/framework/common/test_control.py
@@ -60,10 +60,16 @@
 
 
 class PauseFailControl(Control):
-  """A Control that can be used to pause or fail code under control."""
+  """A Control that can be used to pause or fail code under control.
+
+  This object is only safe for use from two threads: one of the system under
+  test calling control and the other from the test system calling pause,
+  block_until_paused, and fail.
+  """
 
   def __init__(self):
     self._condition = threading.Condition()
+    self._pause = False
     self._paused = False
     self._fail = False
 
@@ -72,19 +78,31 @@
       if self._fail:
         raise Defect()
 
-      while self._paused:
+      while self._pause:
+        self._paused = True
+        self._condition.notify_all()
         self._condition.wait()
+      self._paused = False
 
   @contextlib.contextmanager
   def pause(self):
     """Pauses code under control while controlling code is in context."""
     with self._condition:
-      self._paused = True
+      self._pause = True
     yield
     with self._condition:
-      self._paused = False
+      self._pause = False
       self._condition.notify_all()
 
+  def block_until_paused(self):
+    """Blocks controlling code until code under control is paused.
+
+    May only be called within the context of a pause call.
+    """
+    with self._condition:
+      while not self._paused:
+        self._condition.wait()
+
   @contextlib.contextmanager
   def fail(self):
     """Fails code under control while controlling code is in context."""
diff --git a/src/python/grpcio/tests/unit/framework/interfaces/base/test_cases.py b/src/python/grpcio/tests/unit/framework/interfaces/base/test_cases.py
index 4f8e26c..5d16bf9 100644
--- a/src/python/grpcio/tests/unit/framework/interfaces/base/test_cases.py
+++ b/src/python/grpcio/tests/unit/framework/interfaces/base/test_cases.py
@@ -29,6 +29,8 @@
 
 """Tests of the base interface of RPC Framework."""
 
+from __future__ import division
+
 import logging
 import random
 import threading
@@ -54,13 +56,13 @@
     return request + request
 
   def deserialize_request(self, serialized_request):
-    return serialized_request[:len(serialized_request) / 2]
+    return serialized_request[:len(serialized_request) // 2]
 
   def serialize_response(self, response):
     return response * 3
 
   def deserialize_response(self, serialized_response):
-    return serialized_response[2 * len(serialized_response) / 3:]
+    return serialized_response[2 * len(serialized_response) // 3:]
 
 
 def _advance(quadruples, operator, controller):
diff --git a/src/python/grpcio/tests/unit/test_common.py b/src/python/grpcio/tests/unit/test_common.py
index 7b4d20d..b779f65 100644
--- a/src/python/grpcio/tests/unit/test_common.py
+++ b/src/python/grpcio/tests/unit/test_common.py
@@ -61,6 +61,10 @@
   original = collections.defaultdict(list)
   for key_value_pair in original_metadata:
     key, value = tuple(key_value_pair)
+    if not isinstance(key, bytes):
+      key = key.encode()
+    if not isinstance(value, bytes):
+      value = value.encode()
     original[key].append(value)
   transmitted = collections.defaultdict(list)
   for key_value_pair in transmitted_metadata:
diff --git a/src/ruby/bin/math_services.rb b/src/ruby/bin/math_services.rb
index 2d48212..34c36ab 100755
--- a/src/ruby/bin/math_services.rb
+++ b/src/ruby/bin/math_services.rb
@@ -1,13 +1,41 @@
 # Generated by the protocol buffer compiler.  DO NOT EDIT!
 # Source: math.proto for package 'math'
+# Original file comments:
+# 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'
 require 'math'
 
 module Math
   module Math
-
-    # TODO: add proto service documentation here
     class Service
 
       include GRPC::GenericService
@@ -16,9 +44,20 @@
       self.unmarshal_class_method = :decode
       self.service_name = 'math.Math'
 
+      # Div divides args.dividend by args.divisor and returns the quotient and
+      # remainder.
       rpc :Div, DivArgs, DivReply
+      # DivMany accepts an arbitrary number of division args from the client stream
+      # and sends back the results in the reply stream.  The stream continues until
+      # the client closes its end; the server does the same after sending all the
+      # replies.  The stream ends immediately if either end aborts.
       rpc :DivMany, stream(DivArgs), stream(DivReply)
+      # Fib generates numbers in the Fibonacci sequence.  If args.limit > 0, Fib
+      # generates up to limit numbers; otherwise it continues until the call is
+      # canceled.  Unlike Fib above, Fib has no final FibReply.
       rpc :Fib, FibArgs, stream(Num)
+      # Sum sums a stream of numbers, returning the final result once the stream
+      # is closed.
       rpc :Sum, stream(Num), Num
     end
 
diff --git a/src/ruby/ext/grpc/rb_call.c b/src/ruby/ext/grpc/rb_call.c
index 1b06273..b436057 100644
--- a/src/ruby/ext/grpc/rb_call.c
+++ b/src/ruby/ext/grpc/rb_call.c
@@ -101,30 +101,14 @@
 static VALUE sym_status;
 static VALUE sym_cancelled;
 
-/* hash_all_calls is a hash of Call address -> reference count that is used to
- * track the creation and destruction of rb_call instances.
- */
-static VALUE hash_all_calls;
-
 /* Destroys a Call. */
 static void grpc_rb_call_destroy(void *p) {
-  grpc_call *call = NULL;
-  VALUE ref_count = Qnil;
+  grpc_call* call = NULL;
   if (p == NULL) {
     return;
-  };
-  call = (grpc_call *)p;
-
-  ref_count = rb_hash_aref(hash_all_calls, OFFT2NUM((VALUE)call));
-  if (ref_count == Qnil) {
-    return; /* No longer in the hash, so already deleted */
-  } else if (NUM2UINT(ref_count) == 1) {
-    rb_hash_delete(hash_all_calls, OFFT2NUM((VALUE)call));
-    grpc_call_destroy(call);
-  } else {
-    rb_hash_aset(hash_all_calls, OFFT2NUM((VALUE)call),
-                 UINT2NUM(NUM2UINT(ref_count) - 1));
   }
+  call = (grpc_call *)p;
+  grpc_call_destroy(call);
 }
 
 static size_t md_ary_datasize(const void *p) {
@@ -151,7 +135,7 @@
      * touches a hash object.
      * TODO(yugui) Directly use st_table and call the free function earlier?
      */
-    0,
+     0,
 #endif
 };
 
@@ -163,12 +147,7 @@
     NULL,
     NULL,
 #ifdef RUBY_TYPED_FREE_IMMEDIATELY
-    /* it is unsafe to specify RUBY_TYPED_FREE_IMMEDIATELY because
-     * grpc_rb_call_destroy
-     * touches a hash object.
-     * TODO(yugui) Directly use st_table and call the free function earlier?
-     */
-    0,
+    RUBY_TYPED_FREE_IMMEDIATELY
 #endif
 };
 
@@ -190,6 +169,11 @@
 static VALUE grpc_rb_call_cancel(VALUE self) {
   grpc_call *call = NULL;
   grpc_call_error err;
+  if (RTYPEDDATA_DATA(self) == NULL) {
+    //This call has been closed
+    return Qnil;
+  }
+
   TypedData_Get_Struct(self, grpc_call, &grpc_call_data_type, call);
   err = grpc_call_cancel(call, NULL);
   if (err != GRPC_CALL_OK) {
@@ -200,11 +184,29 @@
   return Qnil;
 }
 
+/* Releases the c-level resources associated with a call
+   Once a call has been closed, no further requests can be
+   processed.
+*/
+static VALUE grpc_rb_call_close(VALUE self) {
+  grpc_call *call = NULL;
+  TypedData_Get_Struct(self, grpc_call, &grpc_call_data_type, call);
+  if(call != NULL) {
+    grpc_call_destroy(call);
+    RTYPEDDATA_DATA(self) = NULL;
+  }
+  return Qnil;
+}
+
 /* Called to obtain the peer that this call is connected to. */
 static VALUE grpc_rb_call_get_peer(VALUE self) {
   VALUE res = Qnil;
   grpc_call *call = NULL;
   char *peer = NULL;
+  if (RTYPEDDATA_DATA(self) == NULL) {
+    rb_raise(grpc_rb_eCallError, "Cannot get peer value on closed call");
+    return Qnil;
+  }
   TypedData_Get_Struct(self, grpc_call, &grpc_call_data_type, call);
   peer = grpc_call_get_peer(call);
   res = rb_str_new2(peer);
@@ -218,6 +220,10 @@
   grpc_call *call = NULL;
   VALUE res = Qnil;
   grpc_auth_context *ctx = NULL;
+  if (RTYPEDDATA_DATA(self) == NULL) {
+    rb_raise(grpc_rb_eCallError, "Cannot get peer cert on closed call");
+    return Qnil;
+  }
   TypedData_Get_Struct(self, grpc_call, &grpc_call_data_type, call);
 
   ctx = grpc_call_auth_context(call);
@@ -323,6 +329,10 @@
   grpc_call *call = NULL;
   grpc_call_credentials *creds;
   grpc_call_error err;
+  if (RTYPEDDATA_DATA(self) == NULL) {
+    rb_raise(grpc_rb_eCallError, "Cannot set credentials of closed call");
+    return Qnil;
+  }
   TypedData_Get_Struct(self, grpc_call, &grpc_call_data_type, call);
   creds = grpc_rb_get_wrapped_call_credentials(credentials);
   err = grpc_call_set_credentials(call, creds);
@@ -731,7 +741,7 @@
    }
    tag = Object.new
    timeout = 10
-   call.start_batch(cqueue, tag, timeout, ops)
+   call.start_batch(cq, tag, timeout, ops)
 
    Start a batch of operations defined in the array ops; when complete, post a
    completion of type 'tag' to the completion queue bound to the call.
@@ -749,6 +759,10 @@
   VALUE result = Qnil;
   VALUE rb_write_flag = rb_ivar_get(self, id_write_flag);
   unsigned write_flag = 0;
+  if (RTYPEDDATA_DATA(self) == NULL) {
+    rb_raise(grpc_rb_eCallError, "Cannot run batch on closed call");
+    return Qnil;
+  }
   TypedData_Get_Struct(self, grpc_call, &grpc_call_data_type, call);
 
   /* Validate the ops args, adding them to a ruby array */
@@ -888,6 +902,7 @@
   /* Add ruby analogues of the Call methods. */
   rb_define_method(grpc_rb_cCall, "run_batch", grpc_rb_call_run_batch, 4);
   rb_define_method(grpc_rb_cCall, "cancel", grpc_rb_call_cancel, 0);
+  rb_define_method(grpc_rb_cCall, "close", grpc_rb_call_close, 0);
   rb_define_method(grpc_rb_cCall, "peer", grpc_rb_call_get_peer, 0);
   rb_define_method(grpc_rb_cCall, "peer_cert", grpc_rb_call_get_peer_cert, 0);
   rb_define_method(grpc_rb_cCall, "status", grpc_rb_call_get_status, 0);
@@ -925,11 +940,6 @@
       "BatchResult", "send_message", "send_metadata", "send_close",
       "send_status", "message", "metadata", "status", "cancelled", NULL);
 
-  /* The hash for reference counting calls, to ensure they can't be destroyed
-   * more than once */
-  hash_all_calls = rb_hash_new();
-  rb_define_const(grpc_rb_cCall, "INTERNAL_ALL_CALLs", hash_all_calls);
-
   Init_grpc_error_codes();
   Init_grpc_op_codes();
   Init_grpc_write_flags();
@@ -944,16 +954,8 @@
 
 /* Obtains the wrapped object for a given call */
 VALUE grpc_rb_wrap_call(grpc_call *c) {
-  VALUE obj = Qnil;
   if (c == NULL) {
     return Qnil;
   }
-  obj = rb_hash_aref(hash_all_calls, OFFT2NUM((VALUE)c));
-  if (obj == Qnil) { /* Not in the hash add it */
-    rb_hash_aset(hash_all_calls, OFFT2NUM((VALUE)c), UINT2NUM(1));
-  } else {
-    rb_hash_aset(hash_all_calls, OFFT2NUM((VALUE)c),
-                 UINT2NUM(NUM2UINT(obj) + 1));
-  }
   return TypedData_Wrap_Struct(grpc_rb_cCall, &grpc_call_data_type, c);
 }
diff --git a/src/ruby/ext/grpc/rb_channel.c b/src/ruby/ext/grpc/rb_channel.c
index 013321f..6943c93 100644
--- a/src/ruby/ext/grpc/rb_channel.c
+++ b/src/ruby/ext/grpc/rb_channel.c
@@ -373,7 +373,7 @@
   rb_define_const(grpc_rb_mConnectivityStates, "TRANSIENT_FAILURE",
                   LONG2NUM(GRPC_CHANNEL_TRANSIENT_FAILURE));
   rb_define_const(grpc_rb_mConnectivityStates, "FATAL_FAILURE",
-                  LONG2NUM(GRPC_CHANNEL_FATAL_FAILURE));
+                  LONG2NUM(GRPC_CHANNEL_SHUTDOWN));
 }
 
 void Init_grpc_channel() {
diff --git a/src/ruby/ext/grpc/rb_completion_queue.c b/src/ruby/ext/grpc/rb_completion_queue.c
index b6ddbe8..9466402 100644
--- a/src/ruby/ext/grpc/rb_completion_queue.c
+++ b/src/ruby/ext/grpc/rb_completion_queue.c
@@ -150,6 +150,14 @@
 #endif
 };
 
+/* Releases the c-level resources associated with a completion queue */
+static VALUE grpc_rb_completion_queue_close(VALUE self) {
+  grpc_completion_queue* cq = grpc_rb_get_wrapped_completion_queue(self);
+  grpc_rb_completion_queue_destroy(cq);
+  RTYPEDDATA_DATA(self) = NULL;
+  return Qnil;
+}
+
 /* Allocates a completion queue. */
 static VALUE grpc_rb_completion_queue_alloc(VALUE cls) {
   grpc_completion_queue *cq = grpc_completion_queue_create(NULL);
@@ -212,6 +220,11 @@
      this func, so no separate initialization step is necessary. */
   rb_define_alloc_func(grpc_rb_cCompletionQueue,
                        grpc_rb_completion_queue_alloc);
+
+  /* close: Provides a way to close the underlying file descriptor without
+     waiting for ruby garbage collection. */
+  rb_define_method(grpc_rb_cCompletionQueue, "close",
+                   grpc_rb_completion_queue_close, 0);
 }
 
 /* Gets the wrapped completion queue from the ruby wrapper */
diff --git a/src/ruby/ext/grpc/rb_grpc.c b/src/ruby/ext/grpc/rb_grpc.c
index 06a07ac..9246893 100644
--- a/src/ruby/ext/grpc/rb_grpc.c
+++ b/src/ruby/ext/grpc/rb_grpc.c
@@ -318,7 +318,7 @@
   grpc_rb_mGrpcCore = rb_define_module_under(grpc_rb_mGRPC, "Core");
   grpc_rb_sNewServerRpc =
       rb_struct_define("NewServerRpc", "method", "host",
-                       "deadline", "metadata", "call", NULL);
+                       "deadline", "metadata", "call", "cq", NULL);
   grpc_rb_sStatus =
       rb_struct_define("Status", "code", "details", "metadata", NULL);
   sym_code = ID2SYM(rb_intern("code"));
diff --git a/src/ruby/ext/grpc/rb_grpc_imports.generated.c b/src/ruby/ext/grpc/rb_grpc_imports.generated.c
index 3b62984..c13d1a0 100644
--- a/src/ruby/ext/grpc/rb_grpc_imports.generated.c
+++ b/src/ruby/ext/grpc/rb_grpc_imports.generated.c
@@ -33,7 +33,7 @@
 
 #include <grpc/support/port_platform.h>
 
-#ifdef GPR_WIN32
+#ifdef GPR_WINDOWS
 
 #include "rb_grpc_imports.generated.h"
 
@@ -126,7 +126,8 @@
 grpc_header_nonbin_value_is_legal_type grpc_header_nonbin_value_is_legal_import;
 grpc_is_binary_header_type grpc_is_binary_header_import;
 grpc_call_error_to_string_type grpc_call_error_to_string_import;
-grpc_cronet_secure_channel_create_type grpc_cronet_secure_channel_create_import;
+grpc_insecure_channel_create_from_fd_type grpc_insecure_channel_create_from_fd_import;
+grpc_server_add_insecure_channel_from_fd_type grpc_server_add_insecure_channel_from_fd_import;
 grpc_auth_property_iterator_next_type grpc_auth_property_iterator_next_import;
 grpc_auth_context_property_iterator_type grpc_auth_context_property_iterator_import;
 grpc_auth_context_peer_identity_type grpc_auth_context_peer_identity_import;
@@ -394,7 +395,8 @@
   grpc_header_nonbin_value_is_legal_import = (grpc_header_nonbin_value_is_legal_type) GetProcAddress(library, "grpc_header_nonbin_value_is_legal");
   grpc_is_binary_header_import = (grpc_is_binary_header_type) GetProcAddress(library, "grpc_is_binary_header");
   grpc_call_error_to_string_import = (grpc_call_error_to_string_type) GetProcAddress(library, "grpc_call_error_to_string");
-  grpc_cronet_secure_channel_create_import = (grpc_cronet_secure_channel_create_type) GetProcAddress(library, "grpc_cronet_secure_channel_create");
+  grpc_insecure_channel_create_from_fd_import = (grpc_insecure_channel_create_from_fd_type) GetProcAddress(library, "grpc_insecure_channel_create_from_fd");
+  grpc_server_add_insecure_channel_from_fd_import = (grpc_server_add_insecure_channel_from_fd_type) GetProcAddress(library, "grpc_server_add_insecure_channel_from_fd");
   grpc_auth_property_iterator_next_import = (grpc_auth_property_iterator_next_type) GetProcAddress(library, "grpc_auth_property_iterator_next");
   grpc_auth_context_property_iterator_import = (grpc_auth_context_property_iterator_type) GetProcAddress(library, "grpc_auth_context_property_iterator");
   grpc_auth_context_peer_identity_import = (grpc_auth_context_peer_identity_type) GetProcAddress(library, "grpc_auth_context_peer_identity");
@@ -573,4 +575,4 @@
   gpr_thd_join_import = (gpr_thd_join_type) GetProcAddress(library, "gpr_thd_join");
 }
 
-#endif /* GPR_WIN32 */
+#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 1428e6d..9c86a36 100644
--- a/src/ruby/ext/grpc/rb_grpc_imports.generated.h
+++ b/src/ruby/ext/grpc/rb_grpc_imports.generated.h
@@ -36,14 +36,14 @@
 
 #include <grpc/support/port_platform.h>
 
-#ifdef GPR_WIN32
+#ifdef GPR_WINDOWS
 
 #include <windows.h>
 
 #include <grpc/census.h>
 #include <grpc/compression.h>
 #include <grpc/grpc.h>
-#include <grpc/grpc_cronet.h>
+#include <grpc/grpc_posix.h>
 #include <grpc/grpc_security.h>
 #include <grpc/impl/codegen/alloc.h>
 #include <grpc/impl/codegen/byte_buffer.h>
@@ -57,7 +57,7 @@
 #include <grpc/support/cpu.h>
 #include <grpc/support/histogram.h>
 #include <grpc/support/host_port.h>
-#include <grpc/support/log_win32.h>
+#include <grpc/support/log_windows.h>
 #include <grpc/support/string_util.h>
 #include <grpc/support/subprocess.h>
 #include <grpc/support/thd.h>
@@ -329,9 +329,12 @@
 typedef const char *(*grpc_call_error_to_string_type)(grpc_call_error error);
 extern grpc_call_error_to_string_type grpc_call_error_to_string_import;
 #define grpc_call_error_to_string grpc_call_error_to_string_import
-typedef grpc_channel *(*grpc_cronet_secure_channel_create_type)(void *engine, const char *target, const grpc_channel_args *args, void *reserved);
-extern grpc_cronet_secure_channel_create_type grpc_cronet_secure_channel_create_import;
-#define grpc_cronet_secure_channel_create grpc_cronet_secure_channel_create_import
+typedef grpc_channel *(*grpc_insecure_channel_create_from_fd_type)(const char *target, int fd, const grpc_channel_args *args);
+extern grpc_insecure_channel_create_from_fd_type grpc_insecure_channel_create_from_fd_import;
+#define grpc_insecure_channel_create_from_fd grpc_insecure_channel_create_from_fd_import
+typedef void(*grpc_server_add_insecure_channel_from_fd_type)(grpc_server *server, grpc_completion_queue *cq, int fd);
+extern grpc_server_add_insecure_channel_from_fd_type grpc_server_add_insecure_channel_from_fd_import;
+#define grpc_server_add_insecure_channel_from_fd grpc_server_add_insecure_channel_from_fd_import
 typedef const grpc_auth_property *(*grpc_auth_property_iterator_next_type)(grpc_auth_property_iterator *it);
 extern grpc_auth_property_iterator_next_type grpc_auth_property_iterator_next_import;
 #define grpc_auth_property_iterator_next grpc_auth_property_iterator_next_import
@@ -863,6 +866,6 @@
 
 void grpc_rb_load_imports(HMODULE library);
 
-#endif /* GPR_WIN32 */
+#endif /* GPR_WINDOWS */
 
 #endif
diff --git a/src/ruby/ext/grpc/rb_loader.c b/src/ruby/ext/grpc/rb_loader.c
index 242535f..19a6b33 100644
--- a/src/ruby/ext/grpc/rb_loader.c
+++ b/src/ruby/ext/grpc/rb_loader.c
@@ -33,7 +33,7 @@
 
 #include "rb_grpc_imports.generated.h"
 
-#if GPR_WIN32
+#if GPR_WINDOWS
 #include <tchar.h>
 
 int grpc_rb_load_core() {
diff --git a/src/ruby/ext/grpc/rb_server.c b/src/ruby/ext/grpc/rb_server.c
index 0899feb..f108b8a 100644
--- a/src/ruby/ext/grpc/rb_server.c
+++ b/src/ruby/ext/grpc/rb_server.c
@@ -234,7 +234,7 @@
     err = grpc_server_request_call(
         s->wrapped, &call, &st.details, &st.md_ary,
         grpc_rb_get_wrapped_completion_queue(cqueue),
-        grpc_rb_get_wrapped_completion_queue(cqueue),
+        grpc_rb_get_wrapped_completion_queue(s->mark),
         ROBJECT(tag_new));
     if (err != GRPC_CALL_OK) {
       grpc_request_call_stack_cleanup(&st);
@@ -244,7 +244,7 @@
       return Qnil;
     }
 
-    ev = grpc_rb_completion_queue_pluck_event(cqueue, tag_new, timeout);
+    ev = grpc_rb_completion_queue_pluck_event(s->mark, tag_new, timeout);
     if (ev.type == GRPC_QUEUE_TIMEOUT) {
       grpc_request_call_stack_cleanup(&st);
       return Qnil;
@@ -262,7 +262,7 @@
         rb_str_new2(st.details.host),
         rb_funcall(rb_cTime, id_at, 2, INT2NUM(deadline.tv_sec),
                    INT2NUM(deadline.tv_nsec)),
-        grpc_rb_md_ary_to_h(&st.md_ary), grpc_rb_wrap_call(call), NULL);
+        grpc_rb_md_ary_to_h(&st.md_ary), grpc_rb_wrap_call(call), cqueue, NULL);
     grpc_request_call_stack_cleanup(&st);
     return result;
   }
diff --git a/src/ruby/lib/grpc/generic/active_call.rb b/src/ruby/lib/grpc/generic/active_call.rb
index e449e89..b03ddbc 100644
--- a/src/ruby/lib/grpc/generic/active_call.rb
+++ b/src/ruby/lib/grpc/generic/active_call.rb
@@ -103,7 +103,7 @@
     #
     # @param call [Call] the call used by the ActiveCall
     # @param q [CompletionQueue] the completion queue used to accept
-    #          the call
+    #          the call.  This queue will be closed on call completion.
     # @param marshal [Function] f(obj)->string that marshal requests
     # @param unmarshal [Function] f(string)->obj that unmarshals responses
     # @param deadline [Fixnum] the deadline for the call to complete
@@ -191,6 +191,8 @@
       @call.status = batch_result.status
       op_is_done
       batch_result.check_status
+      @call.close
+      @cq.close
     end
 
     # remote_send sends a request to the remote endpoint.
diff --git a/src/ruby/lib/grpc/generic/bidi_call.rb b/src/ruby/lib/grpc/generic/bidi_call.rb
index 1f6d5f3..238f409 100644
--- a/src/ruby/lib/grpc/generic/bidi_call.rb
+++ b/src/ruby/lib/grpc/generic/bidi_call.rb
@@ -69,6 +69,10 @@
       @readq = Queue.new
       @unmarshal = unmarshal
       @metadata_tag = metadata_tag
+      @reads_complete = false
+      @writes_complete = false
+      @complete = false
+      @done_mutex = Mutex.new
     end
 
     # Begins orchestration of the Bidi stream for a client sending requests.
@@ -115,6 +119,16 @@
       @op_notifier.notify(self)
     end
 
+    # signals that a bidi operation is complete (read + write)
+    def finished
+      @done_mutex.synchronize do
+        return unless @reads_complete && @writes_complete && !@complete
+        @call.close
+        @cq.close
+        @complete = true
+      end
+    end
+
     # performs a read using @call.run_batch, ensures metadata is set up
     def read_using_run_batch
       ops = { RECV_MESSAGE => nil }
@@ -163,12 +177,16 @@
                         SEND_CLOSE_FROM_CLIENT => nil)
         GRPC.logger.debug('bidi-write-loop: done')
         notify_done
+        @writes_complete = true
+        finished
       end
       GRPC.logger.debug('bidi-write-loop: finished')
     rescue StandardError => e
       GRPC.logger.warn('bidi-write-loop: failed')
       GRPC.logger.warn(e)
       notify_done
+      @writes_complete = true
+      finished
       raise e
     end
 
@@ -212,6 +230,8 @@
           @readq.push(e)  # let each_queued_msg terminate with this error
         end
         GRPC.logger.debug('bidi-read-loop: finished')
+        @reads_complete = true
+        finished
       end
     end
   end
diff --git a/src/ruby/lib/grpc/generic/rpc_server.rb b/src/ruby/lib/grpc/generic/rpc_server.rb
index 6b0b4ce..ab7333d 100644
--- a/src/ruby/lib/grpc/generic/rpc_server.rb
+++ b/src/ruby/lib/grpc/generic/rpc_server.rb
@@ -355,7 +355,7 @@
       return an_rpc if @pool.jobs_waiting <= @max_waiting_requests
       GRPC.logger.warn("NOT AVAILABLE: too many jobs_waiting: #{an_rpc}")
       noop = proc { |x| x }
-      c = ActiveCall.new(an_rpc.call, @cq, noop, noop, an_rpc.deadline)
+      c = ActiveCall.new(an_rpc.call, an_rpc.cq, noop, noop, an_rpc.deadline)
       c.send_status(GRPC::Core::StatusCodes::RESOURCE_EXHAUSTED, '')
       nil
     end
@@ -366,7 +366,7 @@
       return an_rpc if rpc_descs.key?(mth)
       GRPC.logger.warn("UNIMPLEMENTED: #{an_rpc}")
       noop = proc { |x| x }
-      c = ActiveCall.new(an_rpc.call, @cq, noop, noop, an_rpc.deadline)
+      c = ActiveCall.new(an_rpc.call, an_rpc.cq, noop, noop, an_rpc.deadline)
       c.send_status(GRPC::Core::StatusCodes::UNIMPLEMENTED, '')
       nil
     end
@@ -377,7 +377,8 @@
       loop_tag = Object.new
       while running_state == :running
         begin
-          an_rpc = @server.request_call(@cq, loop_tag, INFINITE_FUTURE)
+          comp_queue = Core::CompletionQueue.new
+          an_rpc = @server.request_call(comp_queue, loop_tag, INFINITE_FUTURE)
           break if (!an_rpc.nil?) && an_rpc.call.nil?
           active_call = new_active_server_call(an_rpc)
           unless active_call.nil?
@@ -416,15 +417,16 @@
       unless @connect_md_proc.nil?
         connect_md = @connect_md_proc.call(an_rpc.method, an_rpc.metadata)
       end
-      an_rpc.call.run_batch(@cq, handle_call_tag, INFINITE_FUTURE,
+      an_rpc.call.run_batch(an_rpc.cq, handle_call_tag, INFINITE_FUTURE,
                             SEND_INITIAL_METADATA => connect_md)
+
       return nil unless available?(an_rpc)
       return nil unless implemented?(an_rpc)
 
       # Create the ActiveCall
       GRPC.logger.info("deadline is #{an_rpc.deadline}; (now=#{Time.now})")
       rpc_desc = rpc_descs[an_rpc.method.to_sym]
-      c = ActiveCall.new(an_rpc.call, @cq,
+      c = ActiveCall.new(an_rpc.call, an_rpc.cq,
                          rpc_desc.marshal_proc, rpc_desc.unmarshal_proc(:input),
                          an_rpc.deadline)
       mth = an_rpc.method.to_sym
diff --git a/src/ruby/pb/grpc/health/v1/health_services.rb b/src/ruby/pb/grpc/health/v1/health_services.rb
index cb79b20..68a3956 100644
--- a/src/ruby/pb/grpc/health/v1/health_services.rb
+++ b/src/ruby/pb/grpc/health/v1/health_services.rb
@@ -1,5 +1,35 @@
 # Generated by the protocol buffer compiler.  DO NOT EDIT!
 # Source: grpc/health/v1/health.proto for package 'grpc.health.v1'
+# Original file comments:
+# 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'
 require 'grpc/health/v1/health'
@@ -8,8 +38,6 @@
   module Health
     module V1
       module Health
-
-        # TODO: add proto service documentation here
         class Service
 
           include GRPC::GenericService
diff --git a/src/ruby/pb/grpc/testing/duplicate/echo_duplicate_services.rb b/src/ruby/pb/grpc/testing/duplicate/echo_duplicate_services.rb
index 9f6e7e0..eb523ff 100644
--- a/src/ruby/pb/grpc/testing/duplicate/echo_duplicate_services.rb
+++ b/src/ruby/pb/grpc/testing/duplicate/echo_duplicate_services.rb
@@ -1,15 +1,45 @@
 # Generated by the protocol buffer compiler.  DO NOT EDIT!
-# Source: src/proto/grpc/testing/duplicate/echo_duplicate.proto for package 'grpc.testing.duplicate'
+# Source: grpc/testing/duplicate/echo_duplicate.proto for package 'grpc.testing.duplicate'
+# Original file comments:
+# Copyright 2015, Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# This is a partial copy of echo.proto with a different package name.
+#
 
 require 'grpc'
-require 'src/proto/grpc/testing/duplicate/echo_duplicate'
+require 'grpc/testing/duplicate/echo_duplicate'
 
 module Grpc
   module Testing
     module Duplicate
       module EchoTestService
-
-        # TODO: add proto service documentation here
         class Service
 
           include GRPC::GenericService
diff --git a/src/ruby/pb/grpc/testing/metrics_services.rb b/src/ruby/pb/grpc/testing/metrics_services.rb
index f5778bb..467b7b3 100644
--- a/src/ruby/pb/grpc/testing/metrics_services.rb
+++ b/src/ruby/pb/grpc/testing/metrics_services.rb
@@ -1,5 +1,41 @@
 # Generated by the protocol buffer compiler.  DO NOT EDIT!
 # Source: grpc/testing/metrics.proto for package 'grpc.testing'
+# Original file comments:
+# 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.
+#
+# Contains the definitions for a metrics service and the type of metrics
+# exposed by the service.
+#
+# Currently, 'Gauge' (i.e a metric that represents the measured value of
+# something at an instant of time) is the only metric type supported by the
+# service.
 
 require 'grpc'
 require 'grpc/testing/metrics'
@@ -7,8 +43,6 @@
 module Grpc
   module Testing
     module MetricsService
-
-      # TODO: add proto service documentation here
       class Service
 
         include GRPC::GenericService
@@ -17,7 +51,10 @@
         self.unmarshal_class_method = :decode
         self.service_name = 'grpc.testing.MetricsService'
 
+        # Returns the values of all the gauges that are currently being maintained by
+        # the service
         rpc :GetAllGauges, EmptyMessage, stream(GaugeResponse)
+        # Returns the value of one gauge
         rpc :GetGauge, GaugeRequest, GaugeResponse
       end
 
diff --git a/src/ruby/pb/src/proto/grpc/testing/empty.rb b/src/ruby/pb/src/proto/grpc/testing/empty.rb
new file mode 100644
index 0000000..9c2568d
--- /dev/null
+++ b/src/ruby/pb/src/proto/grpc/testing/empty.rb
@@ -0,0 +1,15 @@
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/empty.proto
+
+require 'google/protobuf'
+
+Google::Protobuf::DescriptorPool.generated_pool.build do
+  add_message "grpc.testing.Empty" do
+  end
+end
+
+module Grpc
+  module Testing
+    Empty = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.Empty").msgclass
+  end
+end
diff --git a/src/ruby/pb/src/proto/grpc/testing/messages.rb b/src/ruby/pb/src/proto/grpc/testing/messages.rb
new file mode 100644
index 0000000..2bdfe0e
--- /dev/null
+++ b/src/ruby/pb/src/proto/grpc/testing/messages.rb
@@ -0,0 +1,84 @@
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/messages.proto
+
+require 'google/protobuf'
+
+Google::Protobuf::DescriptorPool.generated_pool.build do
+  add_message "grpc.testing.Payload" do
+    optional :type, :enum, 1, "grpc.testing.PayloadType"
+    optional :body, :bytes, 2
+  end
+  add_message "grpc.testing.EchoStatus" do
+    optional :code, :int32, 1
+    optional :message, :string, 2
+  end
+  add_message "grpc.testing.SimpleRequest" do
+    optional :response_type, :enum, 1, "grpc.testing.PayloadType"
+    optional :response_size, :int32, 2
+    optional :payload, :message, 3, "grpc.testing.Payload"
+    optional :fill_username, :bool, 4
+    optional :fill_oauth_scope, :bool, 5
+    optional :response_compression, :enum, 6, "grpc.testing.CompressionType"
+    optional :response_status, :message, 7, "grpc.testing.EchoStatus"
+  end
+  add_message "grpc.testing.SimpleResponse" do
+    optional :payload, :message, 1, "grpc.testing.Payload"
+    optional :username, :string, 2
+    optional :oauth_scope, :string, 3
+  end
+  add_message "grpc.testing.StreamingInputCallRequest" do
+    optional :payload, :message, 1, "grpc.testing.Payload"
+  end
+  add_message "grpc.testing.StreamingInputCallResponse" do
+    optional :aggregated_payload_size, :int32, 1
+  end
+  add_message "grpc.testing.ResponseParameters" do
+    optional :size, :int32, 1
+    optional :interval_us, :int32, 2
+  end
+  add_message "grpc.testing.StreamingOutputCallRequest" do
+    optional :response_type, :enum, 1, "grpc.testing.PayloadType"
+    repeated :response_parameters, :message, 2, "grpc.testing.ResponseParameters"
+    optional :payload, :message, 3, "grpc.testing.Payload"
+    optional :response_compression, :enum, 6, "grpc.testing.CompressionType"
+    optional :response_status, :message, 7, "grpc.testing.EchoStatus"
+  end
+  add_message "grpc.testing.StreamingOutputCallResponse" do
+    optional :payload, :message, 1, "grpc.testing.Payload"
+  end
+  add_message "grpc.testing.ReconnectParams" do
+    optional :max_reconnect_backoff_ms, :int32, 1
+  end
+  add_message "grpc.testing.ReconnectInfo" do
+    optional :passed, :bool, 1
+    repeated :backoff_ms, :int32, 2
+  end
+  add_enum "grpc.testing.PayloadType" do
+    value :COMPRESSABLE, 0
+    value :UNCOMPRESSABLE, 1
+    value :RANDOM, 2
+  end
+  add_enum "grpc.testing.CompressionType" do
+    value :NONE, 0
+    value :GZIP, 1
+    value :DEFLATE, 2
+  end
+end
+
+module Grpc
+  module Testing
+    Payload = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.Payload").msgclass
+    EchoStatus = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.EchoStatus").msgclass
+    SimpleRequest = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.SimpleRequest").msgclass
+    SimpleResponse = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.SimpleResponse").msgclass
+    StreamingInputCallRequest = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.StreamingInputCallRequest").msgclass
+    StreamingInputCallResponse = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.StreamingInputCallResponse").msgclass
+    ResponseParameters = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.ResponseParameters").msgclass
+    StreamingOutputCallRequest = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.StreamingOutputCallRequest").msgclass
+    StreamingOutputCallResponse = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.StreamingOutputCallResponse").msgclass
+    ReconnectParams = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.ReconnectParams").msgclass
+    ReconnectInfo = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.ReconnectInfo").msgclass
+    PayloadType = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.PayloadType").enummodule
+    CompressionType = Google::Protobuf::DescriptorPool.generated_pool.lookup("grpc.testing.CompressionType").enummodule
+  end
+end
diff --git a/src/ruby/pb/src/proto/grpc/testing/test.rb b/src/ruby/pb/src/proto/grpc/testing/test.rb
new file mode 100644
index 0000000..245b5ce
--- /dev/null
+++ b/src/ruby/pb/src/proto/grpc/testing/test.rb
@@ -0,0 +1,14 @@
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: src/proto/grpc/testing/test.proto
+
+require 'google/protobuf'
+
+require 'src/proto/grpc/testing/empty'
+require 'src/proto/grpc/testing/messages'
+Google::Protobuf::DescriptorPool.generated_pool.build do
+end
+
+module Grpc
+  module Testing
+  end
+end
diff --git a/src/ruby/pb/src/proto/grpc/testing/test_services.rb b/src/ruby/pb/src/proto/grpc/testing/test_services.rb
new file mode 100644
index 0000000..2652de5
--- /dev/null
+++ b/src/ruby/pb/src/proto/grpc/testing/test_services.rb
@@ -0,0 +1,110 @@
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# Source: src/proto/grpc/testing/test.proto for package 'grpc.testing'
+# Original file comments:
+# 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.
+#
+# An integration test service that covers all the method signature permutations
+# of unary/streaming requests/responses.
+#
+
+require 'grpc'
+require 'src/proto/grpc/testing/test'
+
+module Grpc
+  module Testing
+    module TestService
+      # A simple service to test the various types of RPCs and experiment with
+      # performance with various types of payload.
+      class Service
+
+        include GRPC::GenericService
+
+        self.marshal_class_method = :encode
+        self.unmarshal_class_method = :decode
+        self.service_name = 'grpc.testing.TestService'
+
+        # One empty request followed by one empty response.
+        rpc :EmptyCall, Empty, Empty
+        # One request followed by one response.
+        rpc :UnaryCall, SimpleRequest, SimpleResponse
+        # One request followed by a sequence of responses (streamed download).
+        # The server returns the payload with client desired type and sizes.
+        rpc :StreamingOutputCall, StreamingOutputCallRequest, stream(StreamingOutputCallResponse)
+        # A sequence of requests followed by one response (streamed upload).
+        # The server returns the aggregated size of client payload as the result.
+        rpc :StreamingInputCall, stream(StreamingInputCallRequest), StreamingInputCallResponse
+        # A sequence of requests with each request served by the server immediately.
+        # As one request could lead to multiple responses, this interface
+        # demonstrates the idea of full duplexing.
+        rpc :FullDuplexCall, stream(StreamingOutputCallRequest), stream(StreamingOutputCallResponse)
+        # A sequence of requests followed by a sequence of responses.
+        # The server buffers all the client requests and then serves them in order. A
+        # stream of responses are returned to the client when the server starts with
+        # first request.
+        rpc :HalfDuplexCall, stream(StreamingOutputCallRequest), stream(StreamingOutputCallResponse)
+      end
+
+      Stub = Service.rpc_stub_class
+    end
+    module UnimplementedService
+      # A simple service NOT implemented at servers so clients can test for
+      # that case.
+      class Service
+
+        include GRPC::GenericService
+
+        self.marshal_class_method = :encode
+        self.unmarshal_class_method = :decode
+        self.service_name = 'grpc.testing.UnimplementedService'
+
+        # A call that no server should implement
+        rpc :UnimplementedCall, Empty, Empty
+      end
+
+      Stub = Service.rpc_stub_class
+    end
+    module ReconnectService
+      # A service used to control reconnect server.
+      class Service
+
+        include GRPC::GenericService
+
+        self.marshal_class_method = :encode
+        self.unmarshal_class_method = :decode
+        self.service_name = 'grpc.testing.ReconnectService'
+
+        rpc :Start, ReconnectParams, Empty
+        rpc :Stop, Empty, ReconnectInfo
+      end
+
+      Stub = Service.rpc_stub_class
+    end
+  end
+end
diff --git a/src/ruby/qps/src/proto/grpc/testing/services_services.rb b/src/ruby/qps/src/proto/grpc/testing/services_services.rb
index 3fd9f20..94b9a1e 100644
--- a/src/ruby/qps/src/proto/grpc/testing/services_services.rb
+++ b/src/ruby/qps/src/proto/grpc/testing/services_services.rb
@@ -1,5 +1,37 @@
 # Generated by the protocol buffer compiler.  DO NOT EDIT!
 # Source: src/proto/grpc/testing/services.proto for package 'grpc.testing'
+# Original file comments:
+# 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.
+#
+# An integration test service that covers all the method signature permutations
+# of unary/streaming requests/responses.
 
 require 'grpc'
 require 'src/proto/grpc/testing/services'
@@ -7,8 +39,6 @@
 module Grpc
   module Testing
     module BenchmarkService
-
-      # TODO: add proto service documentation here
       class Service
 
         include GRPC::GenericService
@@ -17,15 +47,17 @@
         self.unmarshal_class_method = :decode
         self.service_name = 'grpc.testing.BenchmarkService'
 
+        # One request followed by one response.
+        # The server returns the client payload as-is.
         rpc :UnaryCall, SimpleRequest, SimpleResponse
+        # One request followed by one response.
+        # The server returns the client payload as-is.
         rpc :StreamingCall, stream(SimpleRequest), stream(SimpleResponse)
       end
 
       Stub = Service.rpc_stub_class
     end
     module WorkerService
-
-      # TODO: add proto service documentation here
       class Service
 
         include GRPC::GenericService
@@ -34,9 +66,23 @@
         self.unmarshal_class_method = :decode
         self.service_name = 'grpc.testing.WorkerService'
 
+        # Start server with specified workload.
+        # First request sent specifies the ServerConfig followed by ServerStatus
+        # response. After that, a "Mark" can be sent anytime to request the latest
+        # stats. Closing the stream will initiate shutdown of the test server
+        # and once the shutdown has finished, the OK status is sent to terminate
+        # this RPC.
         rpc :RunServer, stream(ServerArgs), stream(ServerStatus)
+        # Start client with specified workload.
+        # First request sent specifies the ClientConfig followed by ClientStatus
+        # response. After that, a "Mark" can be sent anytime to request the latest
+        # stats. Closing the stream will initiate shutdown of the test client
+        # and once the shutdown has finished, the OK status is sent to terminate
+        # this RPC.
         rpc :RunClient, stream(ClientArgs), stream(ClientStatus)
+        # Just return the core count - unary call
         rpc :CoreCount, CoreRequest, CoreResponse
+        # Quit this worker
         rpc :QuitWorker, Void, Void
       end
 
diff --git a/templates/Makefile.template b/templates/Makefile.template
index 0d5f0ec..079fef6 100644
--- a/templates/Makefile.template
+++ b/templates/Makefile.template
@@ -1207,7 +1207,7 @@
   $(LIBDIR)/$(CONFIG)/pkgconfig/grpc_zookeeper.pc:
   	$(E) "[MAKE]    Generating $@"
   	$(Q) mkdir -p $(@D)
-  	$(Q) echo -e "$(GRPC_ZOOKEEPER_PC_FILE)" >$@
+  	$(Q) echo "$(GRPC_ZOOKEEPER_PC_FILE)" | tr , '\n' >$@
 
   $(LIBDIR)/$(CONFIG)/pkgconfig/grpc++.pc:
   	$(E) "[MAKE]    Generating $@"
@@ -1431,17 +1431,19 @@
   	@echo "Your system looks ready to go."
   	@echo
   else
-  	@echo "We couldn't find protoc 3.0.0+ installed on your system. While this"
-  	@echo "won't prevent grpc from working, you won't be able to compile"
-  	@echo "and run any meaningful code with it."
+  	@echo "Warning: it looks like protoc 3.0.0+ isn't installed on your system,"
+  	@echo "which means that you won't be able to compile .proto files for use"
+  	@echo "with gRPC."
   	@echo
+  	@echo "If you are just using pre-compiled protocol buffers, or you otherwise"
+  	@echo "have no need to compile .proto files, you can ignore this."
   	@echo
-  	@echo "Please download and install protobuf 3.0.0+ from:"
+  	@echo "If you do need protobuf for some reason, you can download and install"
+  	@echo "it from:"
   	@echo
   	@echo "   https://github.com/google/protobuf/releases"
   	@echo
-  	@echo "Once you've done so, or if you think this message is in error,"
-  	@echo "you can re-run this check by doing:"
+  	@echo "Once you've done so, you can re-run this check by doing:"
   	@echo
   	@echo "   make verify-install"
   endif
diff --git a/templates/composer.json.template b/templates/composer.json.template
index 275b465..7d2029c 100644
--- a/templates/composer.json.template
+++ b/templates/composer.json.template
@@ -4,7 +4,6 @@
     "name": "grpc/grpc",
     "type": "library",
     "description": "gRPC library for PHP",
-    "version": "${settings.php_version.php()}",
     "keywords": ["rpc"],
     "homepage": "http://grpc.io",
     "license": "BSD-3-Clause",
diff --git a/templates/src/python/grpcio/grpc/_cython/imports.generated.c.template b/templates/src/python/grpcio/grpc/_cython/imports.generated.c.template
index 62fe094..84fa5e6 100644
--- a/templates/src/python/grpcio/grpc/_cython/imports.generated.c.template
+++ b/templates/src/python/grpcio/grpc/_cython/imports.generated.c.template
@@ -37,7 +37,7 @@
 
   #include "imports.generated.h"
 
-  #ifdef GPR_WIN32
+  #ifdef GPR_WINDOWS
 
   %for api in c_apis:
   ${api.name}_type ${api.name}_import;
@@ -57,5 +57,5 @@
   }
   #endif  /* __cpluslus */
 
-  #endif /* !GPR_WIN32 */
+  #endif /* !GPR_WINDOWS */
 
diff --git a/templates/src/python/grpcio/grpc/_cython/imports.generated.h.template b/templates/src/python/grpcio/grpc/_cython/imports.generated.h.template
index 26e717e..d0f60dc 100644
--- a/templates/src/python/grpcio/grpc/_cython/imports.generated.h.template
+++ b/templates/src/python/grpcio/grpc/_cython/imports.generated.h.template
@@ -38,7 +38,7 @@
 
   #include <grpc/support/port_platform.h>
 
-  #ifdef GPR_WIN32
+  #ifdef GPR_WINDOWS
 
   #include <windows.h>
 
@@ -62,7 +62,7 @@
   }
   #endif  /* __cpluslus */
 
-  #else /* !GPR_WIN32 */
+  #else /* !GPR_WINDOWS */
 
   #include <grpc/byte_buffer.h>
   #include <grpc/byte_buffer_reader.h>
@@ -74,6 +74,6 @@
   #include <grpc/support/time.h>
   #include <grpc/status.h>
 
-  #endif /* !GPR_WIN32 */
+  #endif /* !GPR_WINDOWS */
 
   #endif
diff --git a/templates/src/ruby/ext/grpc/rb_grpc_imports.generated.c.template b/templates/src/ruby/ext/grpc/rb_grpc_imports.generated.c.template
index e09a587..232f3e7 100644
--- a/templates/src/ruby/ext/grpc/rb_grpc_imports.generated.c.template
+++ b/templates/src/ruby/ext/grpc/rb_grpc_imports.generated.c.template
@@ -35,7 +35,7 @@
 
   #include <grpc/support/port_platform.h>
 
-  #ifdef GPR_WIN32
+  #ifdef GPR_WINDOWS
 
   #include "rb_grpc_imports.generated.h"
 
@@ -49,4 +49,4 @@
   %endfor
   }
 
-  #endif /* GPR_WIN32 */
+  #endif /* GPR_WINDOWS */
diff --git a/templates/src/ruby/ext/grpc/rb_grpc_imports.generated.h.template b/templates/src/ruby/ext/grpc/rb_grpc_imports.generated.h.template
index 9f17ede..68172fc 100644
--- a/templates/src/ruby/ext/grpc/rb_grpc_imports.generated.h.template
+++ b/templates/src/ruby/ext/grpc/rb_grpc_imports.generated.h.template
@@ -38,7 +38,7 @@
 
   #include <grpc/support/port_platform.h>
 
-  #ifdef GPR_WIN32
+  #ifdef GPR_WINDOWS
 
   #include <windows.h>
 
@@ -54,6 +54,6 @@
 
   void grpc_rb_load_imports(HMODULE library);
 
-  #endif /* GPR_WIN32 */
+  #endif /* GPR_WINDOWS */
 
   #endif
diff --git a/templates/test/core/surface/public_headers_must_be_c89.c.template b/templates/test/core/surface/public_headers_must_be_c89.c.template
index e132256..d33ffda 100644
--- a/templates/test/core/surface/public_headers_must_be_c89.c.template
+++ b/templates/test/core/surface/public_headers_must_be_c89.c.template
@@ -35,7 +35,7 @@
 
   <%
   def is_platform_header(hdr):
-    for platform_identifier in ['_gcc', '_win32', '_pthread',
+    for platform_identifier in ['_gcc', '_windows', '_pthread',
                                 '_zookeeper', '_msvc', '_posix']:
       if platform_identifier in hdr:
         return True
@@ -46,6 +46,7 @@
     if lib.language != 'c': continue
     for hdr in lib.get('public_headers', []):
       if is_platform_header(hdr): continue
+      if 'grpc_cronet.h' in hdr: continue
       assert(hdr[0:len(pfx)] == pfx)
       hdrs.add(hdr[len(pfx):])
   hdrs = sorted(list(hdrs))
diff --git a/templates/tools/dockerfile/test/cxx_ubuntu1604_x64/Dockerfile.template b/templates/tools/dockerfile/test/cxx_ubuntu1604_x64/Dockerfile.template
index c11cefd..e395379 100644
--- a/templates/tools/dockerfile/test/cxx_ubuntu1604_x64/Dockerfile.template
+++ b/templates/tools/dockerfile/test/cxx_ubuntu1604_x64/Dockerfile.template
@@ -34,6 +34,12 @@
   <%include file="../../apt_get_basic.include"/>
   <%include file="../../cxx_deps.include"/>
   <%include file="../../run_tests_addons.include"/>
+  
+  # The clang-3.6 symlink for the default clang version was added
+  # to Ubuntu 16.04 recently, so make sure it's installed.
+  # Also install clang3.7.
+  RUN apt-get update && apt-get -y install clang-3.6 clang-3.7 && apt-get clean
+  
   # Define the default command.
   CMD ["bash"]
   
\ No newline at end of file
diff --git a/templates/vsprojects/buildtests_c.sln.template b/templates/vsprojects/buildtests_c.sln.template
index 21312ab..9b18c74 100644
--- a/templates/vsprojects/buildtests_c.sln.template
+++ b/templates/vsprojects/buildtests_c.sln.template
@@ -2,6 +2,12 @@
 --- |
   <%namespace file="sln_defs.include" import="gen_solution"/>\
   <%
-  solution_projects = [p for p in vsprojects if p.build not in ['protoc', 'fuzzer'] and p.language == 'c' and not p.boringssl and not p.zlib]
+  solution_projects = [
+    p for p in vsprojects
+    if p.build in ['test', 'tool']
+    and p.language == 'c'
+    and not p.boringssl
+    and not p.zlib
+  ]
   %>\
   ${gen_solution(solution_projects, use_dlls='yes')}
diff --git a/templates/vsprojects/grpc_csharp_ext.sln.template b/templates/vsprojects/grpc_csharp_ext.sln.template
index 1013d7b..9b09f5e 100644
--- a/templates/vsprojects/grpc_csharp_ext.sln.template
+++ b/templates/vsprojects/grpc_csharp_ext.sln.template
@@ -2,6 +2,6 @@
 --- |
   <%namespace file="sln_defs.include" import="gen_solution"/>\
   <%
-  solution_projects = [p for p in vsprojects if p.build == 'all' and p.language in ['c', 'csharp']]
+  solution_projects = [p for p in vsprojects if p.build == 'all' and p.language == 'csharp']
   %>\
   ${gen_solution(solution_projects, use_dlls='only')}
diff --git a/templates/vsprojects/sln_defs.include b/templates/vsprojects/sln_defs.include
index a048941..cc52578 100644
--- a/templates/vsprojects/sln_defs.include
+++ b/templates/vsprojects/sln_defs.include
@@ -1,4 +1,4 @@
-<%def name="gen_solution(solution_projects, use_dlls = 'no')">\
+<%def name="gen_solution(solution_top_level_projects, use_dlls = 'no')">\
 ## Template for Visual Studio solution
 ## based on http://msdn.microsoft.com/en-us/library/bb165951(v=vs.90).aspx
 ## NOTE: tabs in this file are needed by Visual Studio to correctly interpret
@@ -12,6 +12,14 @@
 ## Visual Studio uses GUIDs for project types
 ## http://msdn.microsoft.com/en-us/library/hb23x61k%28v=vs.80%29.aspx
 cpp_proj_type = "{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}"
+
+all_projects = set()
+for project in solution_top_level_projects:
+  for dep in project.deps:
+    all_projects.add(dep)
+  all_projects.add(project.name)
+
+solution_projects = [vsproject_dict[project] for project in sorted(list(all_projects))]
 %>\
 % for project in solution_projects:
 Project("${cpp_proj_type}") = "${project.name}", "vcxproj\${project.vs_proj_dir}\${project.name}\${project.name}.vcxproj", "${project.vs_project_guid}"
diff --git a/test/core/bad_client/tests/large_metadata.c b/test/core/bad_client/tests/large_metadata.c
index b7d329c..ded5f17 100644
--- a/test/core/bad_client/tests/large_metadata.c
+++ b/test/core/bad_client/tests/large_metadata.c
@@ -163,6 +163,7 @@
   meta.value_length = metadata_value_size;
 
   grpc_op op;
+  memset(&op, 0, sizeof(op));
   op.op = GRPC_OP_SEND_INITIAL_METADATA;
   op.data.send_initial_metadata.count = 1;
   op.data.send_initial_metadata.metadata = &meta;
diff --git a/test/core/bad_ssl/bad_ssl_test.c b/test/core/bad_ssl/bad_ssl_test.c
index c4ae212..bb06ab0 100644
--- a/test/core/bad_ssl/bad_ssl_test.c
+++ b/test/core/bad_ssl/bad_ssl_test.c
@@ -84,6 +84,7 @@
                                "/foo", "foo.test.google.fr:1234", deadline,
                                NULL);
 
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_SEND_INITIAL_METADATA;
   op->data.send_initial_metadata.count = 0;
diff --git a/test/core/channel/channel_args_test.c b/test/core/channel/channel_args_test.c
index c2fc050..8ef1bff 100644
--- a/test/core/channel/channel_args_test.c
+++ b/test/core/channel/channel_args_test.c
@@ -136,8 +136,10 @@
 
 int main(int argc, char **argv) {
   grpc_test_init(argc, argv);
+  grpc_init();
   test_create();
   test_set_compression_algorithm();
   test_compression_algorithm_states();
+  grpc_shutdown();
   return 0;
 }
diff --git a/test/core/channel/channel_stack_test.c b/test/core/channel/channel_stack_test.c
index 1a5594b..2d77bc5 100644
--- a/test/core/channel/channel_stack_test.c
+++ b/test/core/channel/channel_stack_test.c
@@ -63,7 +63,7 @@
                                  grpc_channel_element *elem) {}
 
 static void call_destroy_func(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
-                              void *ignored) {
+                              const grpc_call_stats *stats, void *ignored) {
   ++*(int *)(elem->channel_data);
 }
 
@@ -87,22 +87,23 @@
 }
 
 static void free_call(grpc_exec_ctx *exec_ctx, void *arg, bool success) {
-  grpc_call_stack_destroy(exec_ctx, arg, NULL);
+  grpc_call_stack_destroy(exec_ctx, arg, NULL, NULL);
   gpr_free(arg);
 }
 
 static void test_create_channel_stack(void) {
-  const grpc_channel_filter filter = {call_func,
-                                      channel_func,
-                                      sizeof(int),
-                                      call_init_func,
-                                      grpc_call_stack_ignore_set_pollset,
-                                      call_destroy_func,
-                                      sizeof(int),
-                                      channel_init_func,
-                                      channel_destroy_func,
-                                      get_peer,
-                                      "some_test_filter"};
+  const grpc_channel_filter filter = {
+      call_func,
+      channel_func,
+      sizeof(int),
+      call_init_func,
+      grpc_call_stack_ignore_set_pollset_or_pollset_set,
+      call_destroy_func,
+      sizeof(int),
+      channel_init_func,
+      channel_destroy_func,
+      get_peer,
+      "some_test_filter"};
   const grpc_channel_filter *filters = &filter;
   grpc_channel_stack *channel_stack;
   grpc_call_stack *call_stack;
@@ -123,7 +124,7 @@
 
   channel_stack = gpr_malloc(grpc_channel_stack_size(&filters, 1));
   grpc_channel_stack_init(&exec_ctx, 1, free_channel, channel_stack, &filters,
-                          1, &chan_args, "test", channel_stack);
+                          1, &chan_args, NULL, "test", channel_stack);
   GPR_ASSERT(channel_stack->count == 1);
   channel_elem = grpc_channel_stack_element(channel_stack, 0);
   channel_data = (int *)channel_elem->channel_data;
diff --git a/test/core/client_config/lb_policies_test.c b/test/core/client_config/lb_policies_test.c
index 2ec4612..1534360 100644
--- a/test/core/client_config/lb_policies_test.c
+++ b/test/core/client_config/lb_policies_test.c
@@ -275,6 +275,7 @@
     GPR_ASSERT(c);
     completed_client = 0;
 
+    memset(ops, 0, sizeof(ops));
     op = ops;
     op->op = GRPC_OP_SEND_INITIAL_METADATA;
     op->data.send_initial_metadata.count = 0;
@@ -327,6 +328,7 @@
     }
 
     if (s_idx >= 0) {
+      memset(ops, 0, sizeof(ops));
       op = ops;
       op->op = GRPC_OP_SEND_INITIAL_METADATA;
       op->data.send_initial_metadata.count = 0;
@@ -415,6 +417,7 @@
     kill_server(f, i);
   }
 
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_SEND_INITIAL_METADATA;
   op->data.send_initial_metadata.count = 0;
@@ -640,7 +643,7 @@
                                       const size_t num_iters) {
   size_t i;
   for (i = 0; i < num_iters; i++) {
-    gpr_log(GPR_ERROR, "FAILURE: Iter, expected, actual:%d (%d, %d)", i,
+    gpr_log(GPR_ERROR, "FAILURE: Iter (expected, actual): %d (%d, %d)", i,
             expected_connection_sequence[i % expected_seq_length],
             actual_connection_sequence[i]);
   }
@@ -664,8 +667,6 @@
     const int actual = actual_connection_sequence[i];
     const int expected = expected_connection_sequence[i % expected_seq_length];
     if (actual != expected) {
-      gpr_log(GPR_ERROR, "FAILURE: expected %d, actual %d at iter %d", expected,
-              actual, i);
       print_failed_expectations(expected_connection_sequence,
                                 actual_connection_sequence, expected_seq_length,
                                 num_iters);
@@ -692,24 +693,21 @@
   memcpy(expected_connection_sequence, actual_connection_sequence + 2,
          expected_seq_length * sizeof(int));
 
-  /* first three elements of the sequence should be [<1st>, -1] */
-  if (actual_connection_sequence[0] != expected_connection_sequence[0]) {
-    gpr_log(GPR_ERROR, "FAILURE: expected %d, actual %d at iter %d",
-            expected_connection_sequence[0], actual_connection_sequence[0], 0);
-    print_failed_expectations(expected_connection_sequence,
-                              actual_connection_sequence, expected_seq_length,
-                              1u);
-    abort();
-  }
-
+  /* first two elements of the sequence should be [0 (1st server), -1 (failure)]
+   */
+  GPR_ASSERT(actual_connection_sequence[0] == 0);
   GPR_ASSERT(actual_connection_sequence[1] == -1);
 
+  /* the next two element must be [3, 0], repeating from that point: the 3 is
+   * brought forth by servers 1 and 2 disappearing after the intial pick of 0 */
+  GPR_ASSERT(actual_connection_sequence[2] == 3);
+  GPR_ASSERT(actual_connection_sequence[3] == 0);
+
+  /* make sure that the expectation obliges */
   for (i = 2; i < num_iters; i++) {
     const int actual = actual_connection_sequence[i];
     const int expected = expected_connection_sequence[i % expected_seq_length];
     if (actual != expected) {
-      gpr_log(GPR_ERROR, "FAILURE: expected %d, actual %d at iter %d", expected,
-              actual, i);
       print_failed_expectations(expected_connection_sequence,
                                 actual_connection_sequence, expected_seq_length,
                                 num_iters);
@@ -757,8 +755,6 @@
     const int actual = actual_connection_sequence[i];
     const int expected = expected_connection_sequence[i % expected_seq_length];
     if (actual != expected) {
-      gpr_log(GPR_ERROR, "FAILURE: expected %d, actual %d at iter %d", expected,
-              actual, i);
       print_failed_expectations(expected_connection_sequence,
                                 actual_connection_sequence, expected_seq_length,
                                 num_iters);
@@ -856,8 +852,6 @@
     const int expected =
         expected_connection_sequence[j++ % expected_seq_length];
     if (actual != expected) {
-      gpr_log(GPR_ERROR, "FAILURE: expected %d, actual %d at iter %d", expected,
-              actual, i);
       print_failed_expectations(expected_connection_sequence,
                                 actual_connection_sequence, expected_seq_length,
                                 num_iters);
@@ -887,7 +881,8 @@
   GPR_ASSERT(grpc_lb_policy_create(&exec_ctx, NULL, NULL) == NULL);
 
   spec = test_spec_create(NUM_ITERS, NUM_SERVERS);
-  /* everything is fine, all servers stay up the whole time and life's peachy */
+  /* everything is fine, all servers stay up the whole time and life's peachy
+   */
   spec->verifier = verify_vanilla_round_robin;
   spec->description = "test_all_server_up";
   run_spec(spec);
diff --git a/test/core/client_config/set_initial_connect_string_test.c b/test/core/client_config/set_initial_connect_string_test.c
index 5390c4a..438b949 100644
--- a/test/core/client_config/set_initial_connect_string_test.c
+++ b/test/core/client_config/set_initial_connect_string_test.c
@@ -136,6 +136,7 @@
   state.call = grpc_channel_create_call(
       state.channel, NULL, GRPC_PROPAGATE_DEFAULTS, state.cq, "/Service/Method",
       "localhost", gpr_inf_future(GPR_CLOCK_REALTIME), NULL);
+  memset(&state.op, 0, sizeof(state.op));
   state.op.op = GRPC_OP_SEND_INITIAL_METADATA;
   state.op.data.send_initial_metadata.count = 0;
   state.op.flags = 0;
diff --git a/test/core/client_config/uri_fuzzer_test.c b/test/core/client_config/uri_fuzzer_test.c
index eb976fc..f297140 100644
--- a/test/core/client_config/uri_fuzzer_test.c
+++ b/test/core/client_config/uri_fuzzer_test.c
@@ -31,6 +31,7 @@
  *
  */
 
+#include <stdbool.h>
 #include <stdint.h>
 #include <string.h>
 
@@ -38,6 +39,9 @@
 
 #include "src/core/ext/client_config/uri_parser.h"
 
+bool squelch = true;
+bool leak_check = true;
+
 int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
   char *s = gpr_malloc(size + 1);
   memcpy(s, data, size);
diff --git a/test/core/end2end/cq_verifier.c b/test/core/end2end/cq_verifier.c
index 77afe58..8e9fa70 100644
--- a/test/core/end2end/cq_verifier.c
+++ b/test/core/end2end/cq_verifier.c
@@ -284,6 +284,6 @@
   return e;
 }
 
-void cq_expect_completion(cq_verifier *v, void *tag, int success) {
+void cq_expect_completion(cq_verifier *v, void *tag, bool success) {
   add(v, GRPC_OP_COMPLETE, tag)->success = success;
 }
diff --git a/test/core/end2end/cq_verifier.h b/test/core/end2end/cq_verifier.h
index b3e07c4..8c9a85c 100644
--- a/test/core/end2end/cq_verifier.h
+++ b/test/core/end2end/cq_verifier.h
@@ -34,6 +34,8 @@
 #ifndef GRPC_TEST_CORE_END2END_CQ_VERIFIER_H
 #define GRPC_TEST_CORE_END2END_CQ_VERIFIER_H
 
+#include <stdbool.h>
+
 #include <grpc/grpc.h>
 #include "test/core/util/test_config.h"
 
@@ -57,7 +59,7 @@
    Any functions taking ... expect a NULL terminated list of key/value pairs
    (each pair using two parameter slots) of metadata that MUST be present in
    the event. */
-void cq_expect_completion(cq_verifier *v, void *tag, int success);
+void cq_expect_completion(cq_verifier *v, void *tag, bool success);
 
 int byte_buffer_eq_string(grpc_byte_buffer *byte_buffer, const char *string);
 int contains_metadata(grpc_metadata_array *array, const char *key,
diff --git a/test/core/end2end/dualstack_socket_test.c b/test/core/end2end/dualstack_socket_test.c
index 202fb3b..46e060e 100644
--- a/test/core/end2end/dualstack_socket_test.c
+++ b/test/core/end2end/dualstack_socket_test.c
@@ -167,6 +167,7 @@
                                "/foo", "foo.test.google.fr", deadline, NULL);
   GPR_ASSERT(c);
 
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_SEND_INITIAL_METADATA;
   op->data.send_initial_metadata.count = 0;
@@ -201,6 +202,7 @@
     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 = 0;
diff --git a/test/core/end2end/fixtures/h2_fd.c b/test/core/end2end/fixtures/h2_fd.c
new file mode 100644
index 0000000..e938fe7
--- /dev/null
+++ b/test/core/end2end/fixtures/h2_fd.c
@@ -0,0 +1,128 @@
+/*
+ *
+ * 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 <fcntl.h>
+#include <string.h>
+
+#include <grpc/grpc.h>
+#include <grpc/grpc_posix.h>
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include "src/core/lib/iomgr/exec_ctx.h"
+#include "src/core/lib/iomgr/socket_utils_posix.h"
+#include "src/core/lib/iomgr/unix_sockets_posix.h"
+#include "test/core/util/test_config.h"
+
+typedef struct { int fd_pair[2]; } sp_fixture_data;
+
+static void create_sockets(int sv[2]) {
+  int flags;
+  grpc_create_socketpair_if_unix(sv);
+  flags = fcntl(sv[0], F_GETFL, 0);
+  GPR_ASSERT(fcntl(sv[0], F_SETFL, flags | O_NONBLOCK) == 0);
+  flags = fcntl(sv[1], F_GETFL, 0);
+  GPR_ASSERT(fcntl(sv[1], F_SETFL, flags | O_NONBLOCK) == 0);
+  GPR_ASSERT(grpc_set_socket_no_sigpipe_if_possible(sv[0]));
+  GPR_ASSERT(grpc_set_socket_no_sigpipe_if_possible(sv[1]));
+}
+
+static grpc_end2end_test_fixture chttp2_create_fixture_socketpair(
+    grpc_channel_args *client_args, grpc_channel_args *server_args) {
+  sp_fixture_data *fixture_data = gpr_malloc(sizeof(*fixture_data));
+
+  grpc_end2end_test_fixture f;
+  memset(&f, 0, sizeof(f));
+  f.fixture_data = fixture_data;
+  f.cq = grpc_completion_queue_create(NULL);
+
+  create_sockets(fixture_data->fd_pair);
+
+  return f;
+}
+
+static void chttp2_init_client_socketpair(grpc_end2end_test_fixture *f,
+                                          grpc_channel_args *client_args) {
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+  sp_fixture_data *sfd = f->fixture_data;
+
+  GPR_ASSERT(!f->client);
+  f->client = grpc_insecure_channel_create_from_fd(
+      "fixture_client", sfd->fd_pair[0], client_args);
+  GPR_ASSERT(f->client);
+
+  grpc_exec_ctx_finish(&exec_ctx);
+}
+
+static void chttp2_init_server_socketpair(grpc_end2end_test_fixture *f,
+                                          grpc_channel_args *server_args) {
+  grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+  sp_fixture_data *sfd = f->fixture_data;
+  GPR_ASSERT(!f->server);
+  f->server = grpc_server_create(server_args, NULL);
+  GPR_ASSERT(f->server);
+  grpc_server_register_completion_queue(f->server, f->cq, NULL);
+  grpc_server_start(f->server);
+
+  grpc_server_add_insecure_channel_from_fd(f->server, f->cq, sfd->fd_pair[1]);
+
+  grpc_exec_ctx_finish(&exec_ctx);
+}
+
+static void chttp2_tear_down_socketpair(grpc_end2end_test_fixture *f) {
+  gpr_free(f->fixture_data);
+}
+
+/* All test configurations */
+static grpc_end2end_test_config configs[] = {
+    {"chttp2/fd", 0, chttp2_create_fixture_socketpair,
+     chttp2_init_client_socketpair, chttp2_init_server_socketpair,
+     chttp2_tear_down_socketpair},
+};
+
+int main(int argc, char **argv) {
+  size_t i;
+
+  grpc_test_init(argc, argv);
+  grpc_end2end_tests_pre_init();
+  grpc_init();
+
+  for (i = 0; i < sizeof(configs) / sizeof(*configs); i++) {
+    grpc_end2end_tests(argc, argv, configs[i]);
+  }
+
+  grpc_shutdown();
+
+  return 0;
+}
diff --git a/test/core/end2end/fixtures/h2_loadreporting.c b/test/core/end2end/fixtures/h2_loadreporting.c
new file mode 100644
index 0000000..4ed02f9
--- /dev/null
+++ b/test/core/end2end/fixtures/h2_loadreporting.c
@@ -0,0 +1,184 @@
+/*
+ *
+ * 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 "test/core/end2end/end2end_tests.h"
+
+#include <string.h>
+
+#include <grpc/support/alloc.h>
+#include <grpc/support/host_port.h>
+#include <grpc/support/log.h>
+#include <grpc/support/sync.h>
+#include <grpc/support/thd.h>
+#include <grpc/support/useful.h>
+#include "src/core/ext/client_config/client_channel.h"
+#include "src/core/ext/load_reporting/load_reporting.h"
+#include "src/core/ext/transport/chttp2/transport/chttp2_transport.h"
+#include "src/core/lib/channel/channel_args.h"
+#include "src/core/lib/channel/connected_channel.h"
+#include "src/core/lib/channel/http_server_filter.h"
+#include "src/core/lib/surface/channel.h"
+#include "src/core/lib/surface/server.h"
+#include "test/core/util/port.h"
+#include "test/core/util/test_config.h"
+
+static grpc_load_reporting_config *g_client_lrc;
+static grpc_load_reporting_config *g_server_lrc;
+
+typedef struct fullstack_fixture_data {
+  char *localaddr;
+} fullstack_fixture_data;
+
+static grpc_end2end_test_fixture chttp2_create_fixture_fullstack(
+    grpc_channel_args *client_args, grpc_channel_args *server_args) {
+  grpc_end2end_test_fixture f;
+  int port = grpc_pick_unused_port_or_die();
+  fullstack_fixture_data *ffd = gpr_malloc(sizeof(fullstack_fixture_data));
+  memset(&f, 0, sizeof(f));
+
+  gpr_join_host_port(&ffd->localaddr, "localhost", port);
+
+  f.fixture_data = ffd;
+  f.cq = grpc_completion_queue_create(NULL);
+
+  return f;
+}
+
+typedef struct {
+  int64_t total_bytes;
+  bool fully_processed;
+  uint32_t initial_token;
+  uint32_t final_token;
+} aggregated_bw_stats;
+
+static void sample_fn(const grpc_load_reporting_call_data *call_data,
+                      void *user_data) {
+  GPR_ASSERT(user_data != NULL);
+  aggregated_bw_stats *custom_stats = (aggregated_bw_stats *)user_data;
+  if (call_data == NULL) {
+    /* initial invocation */
+    custom_stats->initial_token = 0xDEADBEEF;
+  } else {
+    /* final invocation */
+    custom_stats->total_bytes =
+        (int64_t)(call_data->stats->transport_stream_stats.outgoing.data_bytes +
+                  call_data->stats->transport_stream_stats.incoming.data_bytes);
+    custom_stats->final_token = 0xCAFED00D;
+    custom_stats->fully_processed = true;
+  }
+}
+
+void chttp2_init_client_fullstack(grpc_end2end_test_fixture *f,
+                                  grpc_channel_args *client_args) {
+  fullstack_fixture_data *ffd = f->fixture_data;
+  grpc_arg arg = grpc_load_reporting_config_create_arg(g_client_lrc);
+  client_args = grpc_channel_args_copy_and_add(client_args, &arg, 1);
+  f->client = grpc_insecure_channel_create(ffd->localaddr, client_args, NULL);
+  grpc_channel_args_destroy(client_args);
+  GPR_ASSERT(f->client);
+}
+
+void chttp2_init_server_fullstack(grpc_end2end_test_fixture *f,
+                                  grpc_channel_args *server_args) {
+  fullstack_fixture_data *ffd = f->fixture_data;
+  if (f->server) {
+    grpc_server_destroy(f->server);
+  }
+  grpc_arg arg = grpc_load_reporting_config_create_arg(g_server_lrc);
+  server_args = grpc_channel_args_copy_and_add(server_args, &arg, 1);
+  f->server = grpc_server_create(server_args, NULL);
+  grpc_channel_args_destroy(server_args);
+  grpc_server_register_completion_queue(f->server, f->cq, NULL);
+  GPR_ASSERT(grpc_server_add_insecure_http2_port(f->server, ffd->localaddr));
+  grpc_server_start(f->server);
+}
+
+void chttp2_tear_down_fullstack(grpc_end2end_test_fixture *f) {
+  fullstack_fixture_data *ffd = f->fixture_data;
+  gpr_free(ffd->localaddr);
+  gpr_free(ffd);
+}
+
+/* All test configurations */
+static grpc_end2end_test_config configs[] = {
+    {"chttp2/fullstack+loadreporting", FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION,
+     chttp2_create_fixture_fullstack, chttp2_init_client_fullstack,
+     chttp2_init_server_fullstack, chttp2_tear_down_fullstack},
+};
+
+int main(int argc, char **argv) {
+  size_t i;
+
+  aggregated_bw_stats *aggr_stats_client =
+      gpr_malloc(sizeof(aggregated_bw_stats));
+  aggr_stats_client->total_bytes = -1;
+  aggr_stats_client->fully_processed = false;
+  aggregated_bw_stats *aggr_stats_server =
+      gpr_malloc(sizeof(aggregated_bw_stats));
+  aggr_stats_server->total_bytes = -1;
+  aggr_stats_server->fully_processed = false;
+
+  g_client_lrc =
+      grpc_load_reporting_config_create(sample_fn, aggr_stats_client);
+  g_server_lrc =
+      grpc_load_reporting_config_create(sample_fn, aggr_stats_server);
+
+  grpc_test_init(argc, argv);
+  grpc_end2end_tests_pre_init();
+  grpc_init();
+
+  for (i = 0; i < sizeof(configs) / sizeof(*configs); i++) {
+    grpc_end2end_tests(argc, argv, configs[i]);
+  }
+
+  grpc_shutdown();
+
+  grpc_load_reporting_config_destroy(g_client_lrc);
+  grpc_load_reporting_config_destroy(g_server_lrc);
+
+  if (aggr_stats_client->fully_processed) {
+    GPR_ASSERT(aggr_stats_client->total_bytes >= 0);
+    GPR_ASSERT(aggr_stats_client->initial_token == 0xDEADBEEF);
+    GPR_ASSERT(aggr_stats_client->final_token == 0xCAFED00D);
+  }
+  if (aggr_stats_server->fully_processed) {
+    GPR_ASSERT(aggr_stats_server->total_bytes >= 0);
+    GPR_ASSERT(aggr_stats_server->initial_token == 0xDEADBEEF);
+    GPR_ASSERT(aggr_stats_server->final_token == 0xCAFED00D);
+  }
+
+  gpr_free(aggr_stats_client);
+  gpr_free(aggr_stats_server);
+
+  return 0;
+}
diff --git a/test/core/end2end/fixtures/h2_ssl_cert.c b/test/core/end2end/fixtures/h2_ssl_cert.c
index 0fa5251..b476bf5 100644
--- a/test/core/end2end/fixtures/h2_ssl_cert.c
+++ b/test/core/end2end/fixtures/h2_ssl_cert.c
@@ -321,6 +321,7 @@
                                NULL);
   GPR_ASSERT(c);
 
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_SEND_INITIAL_METADATA;
   op->data.send_initial_metadata.count = 0;
diff --git a/test/core/end2end/fixtures/proxy.c b/test/core/end2end/fixtures/proxy.c
index 7f10649..beed80d 100644
--- a/test/core/end2end/fixtures/proxy.c
+++ b/test/core/end2end/fixtures/proxy.c
@@ -170,6 +170,7 @@
   grpc_op op;
   grpc_call_error err;
 
+  memset(&op, 0, sizeof(op));
   if (!pc->proxy->shutdown) {
     op.op = GRPC_OP_SEND_INITIAL_METADATA;
     op.flags = 0;
@@ -329,6 +330,7 @@
 
   if (success) {
     grpc_op op;
+    memset(&op, 0, sizeof(op));
     proxy_call *pc = gpr_malloc(sizeof(*pc));
     memset(pc, 0, sizeof(*pc));
     pc->proxy = proxy;
diff --git a/test/core/end2end/fuzzers/api_fuzzer.c b/test/core/end2end/fuzzers/api_fuzzer.c
index e6cd88a..dd93c4a 100644
--- a/test/core/end2end/fuzzers/api_fuzzer.c
+++ b/test/core/end2end/fuzzers/api_fuzzer.c
@@ -50,7 +50,8 @@
 ////////////////////////////////////////////////////////////////////////////////
 // logging
 
-static const bool squelch = true;
+bool squelch = true;
+bool leak_check = true;
 
 static void dont_log(gpr_log_func_args *args) {}
 
@@ -674,7 +675,7 @@
         if (g_channel != NULL) {
           grpc_connectivity_state st =
               grpc_channel_check_connectivity_state(g_channel, 0);
-          if (st != GRPC_CHANNEL_FATAL_FAILURE) {
+          if (st != GRPC_CHANNEL_SHUTDOWN) {
             gpr_timespec deadline = gpr_time_add(
                 gpr_now(GPR_CLOCK_REALTIME),
                 gpr_time_from_micros(read_uint32(&inp), GPR_TIMESPAN));
@@ -739,6 +740,7 @@
           break;
         }
         grpc_op *ops = gpr_malloc(sizeof(grpc_op) * num_ops);
+        memset(ops, 0, sizeof(grpc_op) * num_ops);
         bool ok = true;
         size_t i;
         grpc_op *op;
diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/0e79b68aa8b9c336f0bbf9029928c53079711423 b/test/core/end2end/fuzzers/api_fuzzer_corpus/0e79b68aa8b9c336f0bbf9029928c53079711423
new file mode 100644
index 0000000..5b16d9d
--- /dev/null
+++ b/test/core/end2end/fuzzers/api_fuzzer_corpus/0e79b68aa8b9c336f0bbf9029928c53079711423
Binary files differ
diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/1560af88445d6c1e8b1300047f33056dce198e02 b/test/core/end2end/fuzzers/api_fuzzer_corpus/1560af88445d6c1e8b1300047f33056dce198e02
new file mode 100644
index 0000000..008dcac
--- /dev/null
+++ b/test/core/end2end/fuzzers/api_fuzzer_corpus/1560af88445d6c1e8b1300047f33056dce198e02
Binary files differ
diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/48caf755ddcc6c45d3416ba6ab44709f360eb82b b/test/core/end2end/fuzzers/api_fuzzer_corpus/48caf755ddcc6c45d3416ba6ab44709f360eb82b
new file mode 100644
index 0000000..f29e9a7
--- /dev/null
+++ b/test/core/end2end/fuzzers/api_fuzzer_corpus/48caf755ddcc6c45d3416ba6ab44709f360eb82b
Binary files differ
diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/7030cb2c62b289459e459bc54bd84c8d7e6f5a98 b/test/core/end2end/fuzzers/api_fuzzer_corpus/7030cb2c62b289459e459bc54bd84c8d7e6f5a98
new file mode 100644
index 0000000..035f23e
--- /dev/null
+++ b/test/core/end2end/fuzzers/api_fuzzer_corpus/7030cb2c62b289459e459bc54bd84c8d7e6f5a98
Binary files differ
diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/81f8c545d77d93e6cb8239e9e4a4d7f8f8beeee9 b/test/core/end2end/fuzzers/api_fuzzer_corpus/81f8c545d77d93e6cb8239e9e4a4d7f8f8beeee9
new file mode 100644
index 0000000..a16874c
--- /dev/null
+++ b/test/core/end2end/fuzzers/api_fuzzer_corpus/81f8c545d77d93e6cb8239e9e4a4d7f8f8beeee9
Binary files differ
diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/b7d02f4d12cd0b5442a04675e69f98fbdabc775a b/test/core/end2end/fuzzers/api_fuzzer_corpus/b7d02f4d12cd0b5442a04675e69f98fbdabc775a
new file mode 100644
index 0000000..6f1edf5
--- /dev/null
+++ b/test/core/end2end/fuzzers/api_fuzzer_corpus/b7d02f4d12cd0b5442a04675e69f98fbdabc775a
Binary files differ
diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/ce6a90cb7d395fea7aa54ee9f7061cc45f5494d7 b/test/core/end2end/fuzzers/api_fuzzer_corpus/ce6a90cb7d395fea7aa54ee9f7061cc45f5494d7
new file mode 100644
index 0000000..c5c9c27
--- /dev/null
+++ b/test/core/end2end/fuzzers/api_fuzzer_corpus/ce6a90cb7d395fea7aa54ee9f7061cc45f5494d7
Binary files differ
diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/crash-482e9bdce0e13df2a77eef75a1c07d38ee28f4ab b/test/core/end2end/fuzzers/api_fuzzer_corpus/crash-482e9bdce0e13df2a77eef75a1c07d38ee28f4ab
new file mode 100644
index 0000000..b83e382
--- /dev/null
+++ b/test/core/end2end/fuzzers/api_fuzzer_corpus/crash-482e9bdce0e13df2a77eef75a1c07d38ee28f4ab
Binary files differ
diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/e94428d78182060ff6309dd626cf6b3ebeed88d6 b/test/core/end2end/fuzzers/api_fuzzer_corpus/e94428d78182060ff6309dd626cf6b3ebeed88d6
new file mode 100644
index 0000000..570de0e
--- /dev/null
+++ b/test/core/end2end/fuzzers/api_fuzzer_corpus/e94428d78182060ff6309dd626cf6b3ebeed88d6
Binary files differ
diff --git a/test/core/end2end/fuzzers/client_fuzzer.c b/test/core/end2end/fuzzers/client_fuzzer.c
index afcf763..79b23d7 100644
--- a/test/core/end2end/fuzzers/client_fuzzer.c
+++ b/test/core/end2end/fuzzers/client_fuzzer.c
@@ -31,6 +31,8 @@
  *
  */
 
+#include <string.h>
+
 #include <grpc/grpc.h>
 #include <grpc/support/alloc.h>
 
@@ -39,7 +41,8 @@
 #include "test/core/util/memory_counters.h"
 #include "test/core/util/mock_endpoint.h"
 
-static const bool squelch = true;
+bool squelch = true;
+bool leak_check = true;
 
 static void discard_write(gpr_slice slice) {}
 
@@ -51,7 +54,7 @@
   grpc_test_only_set_metadata_hash_seed(0);
   struct grpc_memory_counters counters;
   if (squelch) gpr_set_log_function(dont_log);
-  grpc_memory_counters_init();
+  if (leak_check) grpc_memory_counters_init();
   grpc_init();
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
 
@@ -78,6 +81,7 @@
   size_t details_capacity = 0;
 
   grpc_op ops[6];
+  memset(ops, 0, sizeof(ops));
   grpc_op *op = ops;
   op->op = GRPC_OP_SEND_INITIAL_METADATA;
   op->data.send_initial_metadata.count = 0;
@@ -153,8 +157,10 @@
     grpc_byte_buffer_destroy(response_payload_recv);
   }
   grpc_shutdown();
-  counters = grpc_memory_counters_snapshot();
-  grpc_memory_counters_destroy();
-  GPR_ASSERT(counters.total_size_relative == 0);
+  if (leak_check) {
+    counters = grpc_memory_counters_snapshot();
+    grpc_memory_counters_destroy();
+    GPR_ASSERT(counters.total_size_relative == 0);
+  }
   return 0;
 }
diff --git a/test/core/end2end/fuzzers/hpack.dictionary b/test/core/end2end/fuzzers/hpack.dictionary
index b081368..097e9a8 100644
--- a/test/core/end2end/fuzzers/hpack.dictionary
+++ b/test/core/end2end/fuzzers/hpack.dictionary
@@ -63,6 +63,7 @@
 "\x13if-unmodified-since"
 "\x0Dlast-modified"
 "\x04link"
+"\x0Eload-reporting"
 "\x08location"
 "\x0Cmax-forwards"
 "\x07:method"
@@ -136,6 +137,7 @@
 "\x00\x13if-unmodified-since\x00"
 "\x00\x0Dlast-modified\x00"
 "\x00\x04link\x00"
+"\x00\x0Eload-reporting\x00"
 "\x00\x08location\x00"
 "\x00\x0Cmax-forwards\x00"
 "\x00\x07:method\x03GET"
diff --git a/test/core/end2end/fuzzers/server_fuzzer.c b/test/core/end2end/fuzzers/server_fuzzer.c
index 0a7d6d9..80f568a 100644
--- a/test/core/end2end/fuzzers/server_fuzzer.c
+++ b/test/core/end2end/fuzzers/server_fuzzer.c
@@ -38,7 +38,8 @@
 #include "test/core/util/memory_counters.h"
 #include "test/core/util/mock_endpoint.h"
 
-static const bool squelch = true;
+bool squelch = true;
+bool leak_check = true;
 
 static void discard_write(gpr_slice slice) {}
 
@@ -51,7 +52,7 @@
   grpc_test_only_set_metadata_hash_seed(0);
   struct grpc_memory_counters counters;
   if (squelch) gpr_set_log_function(dont_log);
-  grpc_memory_counters_init();
+  if (leak_check) grpc_memory_counters_init();
   grpc_init();
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
 
@@ -120,8 +121,10 @@
   grpc_server_destroy(server);
   grpc_completion_queue_destroy(cq);
   grpc_shutdown();
-  counters = grpc_memory_counters_snapshot();
-  grpc_memory_counters_destroy();
-  GPR_ASSERT(counters.total_size_relative == 0);
+  if (leak_check) {
+    counters = grpc_memory_counters_snapshot();
+    grpc_memory_counters_destroy();
+    GPR_ASSERT(counters.total_size_relative == 0);
+  }
   return 0;
 }
diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/05551028437699c8650f5d08eb5f95ee25adf436 b/test/core/end2end/fuzzers/server_fuzzer_corpus/05551028437699c8650f5d08eb5f95ee25adf436
new file mode 100644
index 0000000..c61aff8
--- /dev/null
+++ b/test/core/end2end/fuzzers/server_fuzzer_corpus/05551028437699c8650f5d08eb5f95ee25adf436
Binary files differ
diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/06285b50669cc16463db009ac821f99cf1ec2e24 b/test/core/end2end/fuzzers/server_fuzzer_corpus/06285b50669cc16463db009ac821f99cf1ec2e24
new file mode 100644
index 0000000..d480552
--- /dev/null
+++ b/test/core/end2end/fuzzers/server_fuzzer_corpus/06285b50669cc16463db009ac821f99cf1ec2e24
Binary files differ
diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/23c582f6e23c7bbc9ae7b039b3b4e2ccdea3d5d2 b/test/core/end2end/fuzzers/server_fuzzer_corpus/23c582f6e23c7bbc9ae7b039b3b4e2ccdea3d5d2
new file mode 100644
index 0000000..20b4cf8
--- /dev/null
+++ b/test/core/end2end/fuzzers/server_fuzzer_corpus/23c582f6e23c7bbc9ae7b039b3b4e2ccdea3d5d2
Binary files differ
diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/23f261e44d54a2736f6e288128d98db9e5015206 b/test/core/end2end/fuzzers/server_fuzzer_corpus/23f261e44d54a2736f6e288128d98db9e5015206
new file mode 100644
index 0000000..1452256
--- /dev/null
+++ b/test/core/end2end/fuzzers/server_fuzzer_corpus/23f261e44d54a2736f6e288128d98db9e5015206
Binary files differ
diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/395aea4fcfea081fc0d2733fff2d14405439fa72 b/test/core/end2end/fuzzers/server_fuzzer_corpus/395aea4fcfea081fc0d2733fff2d14405439fa72
new file mode 100644
index 0000000..c832262
--- /dev/null
+++ b/test/core/end2end/fuzzers/server_fuzzer_corpus/395aea4fcfea081fc0d2733fff2d14405439fa72
Binary files differ
diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/404e234751b01dd0b51f9e7610f787253b074528 b/test/core/end2end/fuzzers/server_fuzzer_corpus/404e234751b01dd0b51f9e7610f787253b074528
new file mode 100644
index 0000000..56a2f93
--- /dev/null
+++ b/test/core/end2end/fuzzers/server_fuzzer_corpus/404e234751b01dd0b51f9e7610f787253b074528
Binary files differ
diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/4123bd764c04385191342ea64918408140313714 b/test/core/end2end/fuzzers/server_fuzzer_corpus/4123bd764c04385191342ea64918408140313714
new file mode 100644
index 0000000..18d908f
--- /dev/null
+++ b/test/core/end2end/fuzzers/server_fuzzer_corpus/4123bd764c04385191342ea64918408140313714
Binary files differ
diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/4f96a5fba4d11401eb22d4b1e365fbbb2d684f24 b/test/core/end2end/fuzzers/server_fuzzer_corpus/4f96a5fba4d11401eb22d4b1e365fbbb2d684f24
new file mode 100644
index 0000000..cc5d498
--- /dev/null
+++ b/test/core/end2end/fuzzers/server_fuzzer_corpus/4f96a5fba4d11401eb22d4b1e365fbbb2d684f24
Binary files differ
diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/552199651d942e7220141a93ec33dd8256210a18 b/test/core/end2end/fuzzers/server_fuzzer_corpus/552199651d942e7220141a93ec33dd8256210a18
new file mode 100644
index 0000000..c8c54f4
--- /dev/null
+++ b/test/core/end2end/fuzzers/server_fuzzer_corpus/552199651d942e7220141a93ec33dd8256210a18
Binary files differ
diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/609706c57e848ea58d7ca14fe6cc253322f3e8ce b/test/core/end2end/fuzzers/server_fuzzer_corpus/609706c57e848ea58d7ca14fe6cc253322f3e8ce
new file mode 100644
index 0000000..1ac7cc9
--- /dev/null
+++ b/test/core/end2end/fuzzers/server_fuzzer_corpus/609706c57e848ea58d7ca14fe6cc253322f3e8ce
Binary files differ
diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/7a946bf3cd91b63001f2cf3f40c515c747f2ecde b/test/core/end2end/fuzzers/server_fuzzer_corpus/7a946bf3cd91b63001f2cf3f40c515c747f2ecde
new file mode 100644
index 0000000..8ef1b0a
--- /dev/null
+++ b/test/core/end2end/fuzzers/server_fuzzer_corpus/7a946bf3cd91b63001f2cf3f40c515c747f2ecde
Binary files differ
diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/7d25c28298fb4d0fe41209d0d14307e4aa67c59e b/test/core/end2end/fuzzers/server_fuzzer_corpus/7d25c28298fb4d0fe41209d0d14307e4aa67c59e
new file mode 100644
index 0000000..a323f7a
--- /dev/null
+++ b/test/core/end2end/fuzzers/server_fuzzer_corpus/7d25c28298fb4d0fe41209d0d14307e4aa67c59e
Binary files differ
diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/8138b18a9a743659befc2f2b23d23cb9c3086a09 b/test/core/end2end/fuzzers/server_fuzzer_corpus/8138b18a9a743659befc2f2b23d23cb9c3086a09
new file mode 100644
index 0000000..2bcef17
--- /dev/null
+++ b/test/core/end2end/fuzzers/server_fuzzer_corpus/8138b18a9a743659befc2f2b23d23cb9c3086a09
Binary files differ
diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/89cd90fb47bb9eb289e8126b26021ee00d572d95 b/test/core/end2end/fuzzers/server_fuzzer_corpus/89cd90fb47bb9eb289e8126b26021ee00d572d95
new file mode 100644
index 0000000..17b8d7d
--- /dev/null
+++ b/test/core/end2end/fuzzers/server_fuzzer_corpus/89cd90fb47bb9eb289e8126b26021ee00d572d95
Binary files differ
diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/925011abb99fd56bb0f425ae5e0d92e6d341f804 b/test/core/end2end/fuzzers/server_fuzzer_corpus/925011abb99fd56bb0f425ae5e0d92e6d341f804
new file mode 100644
index 0000000..948d5fa
--- /dev/null
+++ b/test/core/end2end/fuzzers/server_fuzzer_corpus/925011abb99fd56bb0f425ae5e0d92e6d341f804
Binary files differ
diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/99a1acc96512c1155f91afa378e2345726d307c3 b/test/core/end2end/fuzzers/server_fuzzer_corpus/99a1acc96512c1155f91afa378e2345726d307c3
new file mode 100644
index 0000000..a82790d
--- /dev/null
+++ b/test/core/end2end/fuzzers/server_fuzzer_corpus/99a1acc96512c1155f91afa378e2345726d307c3
Binary files differ
diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/crash-c1f66840627e3bfdedf2e4c225bc4de0c267ed37 b/test/core/end2end/fuzzers/server_fuzzer_corpus/crash-c1f66840627e3bfdedf2e4c225bc4de0c267ed37
new file mode 100644
index 0000000..a7fa57e
--- /dev/null
+++ b/test/core/end2end/fuzzers/server_fuzzer_corpus/crash-c1f66840627e3bfdedf2e4c225bc4de0c267ed37
Binary files differ
diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/crash-ccf36bef9318fe6d5e5e1560c5485cdc87d0a701 b/test/core/end2end/fuzzers/server_fuzzer_corpus/crash-ccf36bef9318fe6d5e5e1560c5485cdc87d0a701
new file mode 100644
index 0000000..8bc2de9
--- /dev/null
+++ b/test/core/end2end/fuzzers/server_fuzzer_corpus/crash-ccf36bef9318fe6d5e5e1560c5485cdc87d0a701
Binary files differ
diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/d6bed9cc3c10338a8c5f41064ff8bec0bbc267ce b/test/core/end2end/fuzzers/server_fuzzer_corpus/d6bed9cc3c10338a8c5f41064ff8bec0bbc267ce
new file mode 100644
index 0000000..2b3424a
--- /dev/null
+++ b/test/core/end2end/fuzzers/server_fuzzer_corpus/d6bed9cc3c10338a8c5f41064ff8bec0bbc267ce
Binary files differ
diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/dda9643679f8c8b796e64232a7d153e447d64991 b/test/core/end2end/fuzzers/server_fuzzer_corpus/dda9643679f8c8b796e64232a7d153e447d64991
new file mode 100644
index 0000000..b8ba07b
--- /dev/null
+++ b/test/core/end2end/fuzzers/server_fuzzer_corpus/dda9643679f8c8b796e64232a7d153e447d64991
Binary files differ
diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/e7b08e36420fa107f0aee652e62158af85a4ef15 b/test/core/end2end/fuzzers/server_fuzzer_corpus/e7b08e36420fa107f0aee652e62158af85a4ef15
new file mode 100644
index 0000000..523c785
--- /dev/null
+++ b/test/core/end2end/fuzzers/server_fuzzer_corpus/e7b08e36420fa107f0aee652e62158af85a4ef15
Binary files differ
diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/ec4949487fa84f0cead39521b51f837af9dc784a b/test/core/end2end/fuzzers/server_fuzzer_corpus/ec4949487fa84f0cead39521b51f837af9dc784a
new file mode 100644
index 0000000..e6ea532
--- /dev/null
+++ b/test/core/end2end/fuzzers/server_fuzzer_corpus/ec4949487fa84f0cead39521b51f837af9dc784a
Binary files differ
diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-0292270056246b7a4ccd2e7d0356665cef307ef2 b/test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-0292270056246b7a4ccd2e7d0356665cef307ef2
new file mode 100644
index 0000000..e3eab9e
--- /dev/null
+++ b/test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-0292270056246b7a4ccd2e7d0356665cef307ef2
Binary files differ
diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-098ec93ded3a20e6043d11e9cc6066351e257f8e b/test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-098ec93ded3a20e6043d11e9cc6066351e257f8e
new file mode 100644
index 0000000..b8fa2c0
--- /dev/null
+++ b/test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-098ec93ded3a20e6043d11e9cc6066351e257f8e
Binary files differ
diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-1dc659f500e7bee41a4fee4423ade8332c162cc0 b/test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-1dc659f500e7bee41a4fee4423ade8332c162cc0
new file mode 100644
index 0000000..54411c4
--- /dev/null
+++ b/test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-1dc659f500e7bee41a4fee4423ade8332c162cc0
Binary files differ
diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-350b5da741597222c98fe86768432507850317f5 b/test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-350b5da741597222c98fe86768432507850317f5
new file mode 100644
index 0000000..4364289
--- /dev/null
+++ b/test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-350b5da741597222c98fe86768432507850317f5
Binary files differ
diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-395aea4fcfea081fc0d2733fff2d14405439fa72 b/test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-395aea4fcfea081fc0d2733fff2d14405439fa72
new file mode 100644
index 0000000..c832262
--- /dev/null
+++ b/test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-395aea4fcfea081fc0d2733fff2d14405439fa72
Binary files differ
diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-45cf8ac5faa9c7b15baf9281e8d7e0b4e103f0e0 b/test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-45cf8ac5faa9c7b15baf9281e8d7e0b4e103f0e0
new file mode 100644
index 0000000..70b2eec
--- /dev/null
+++ b/test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-45cf8ac5faa9c7b15baf9281e8d7e0b4e103f0e0
Binary files differ
diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-60a9f77951c5059616764894e1963d83d478edfe b/test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-60a9f77951c5059616764894e1963d83d478edfe
new file mode 100644
index 0000000..0063c63
--- /dev/null
+++ b/test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-60a9f77951c5059616764894e1963d83d478edfe
Binary files differ
diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-97a338fa892093ed5013a76b96b35dd112df3342 b/test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-97a338fa892093ed5013a76b96b35dd112df3342
new file mode 100644
index 0000000..3a231db
--- /dev/null
+++ b/test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-97a338fa892093ed5013a76b96b35dd112df3342
Binary files differ
diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-a1b2cfcf0997acb13a32fc5c004f57d9e9bc4275 b/test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-a1b2cfcf0997acb13a32fc5c004f57d9e9bc4275
new file mode 100644
index 0000000..1a21346
--- /dev/null
+++ b/test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-a1b2cfcf0997acb13a32fc5c004f57d9e9bc4275
Binary files differ
diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-a1ed26e6f82ca0e81e3f415bd8b0b8b520d3927b b/test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-a1ed26e6f82ca0e81e3f415bd8b0b8b520d3927b
new file mode 100644
index 0000000..c00d51d
--- /dev/null
+++ b/test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-a1ed26e6f82ca0e81e3f415bd8b0b8b520d3927b
Binary files differ
diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-f412afea6b01aa53da919a41a65ffbf9885f2d65 b/test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-f412afea6b01aa53da919a41a65ffbf9885f2d65
new file mode 100644
index 0000000..171446c
--- /dev/null
+++ b/test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-f412afea6b01aa53da919a41a65ffbf9885f2d65
Binary files differ
diff --git a/test/core/end2end/gen_build_yaml.py b/test/core/end2end/gen_build_yaml.py
index 3e10ad5..3d3bec1 100755
--- a/test/core/end2end/gen_build_yaml.py
+++ b/test/core/end2end/gen_build_yaml.py
@@ -45,6 +45,8 @@
 socketpair_unsecure_fixture_options = default_unsecure_fixture_options._replace(fullstack=False, dns_resolver=False)
 default_secure_fixture_options = default_unsecure_fixture_options._replace(secure=True)
 uds_fixture_options = default_unsecure_fixture_options._replace(dns_resolver=False, platforms=['linux', 'mac', 'posix'])
+fd_unsecure_fixture_options = default_unsecure_fixture_options._replace(
+    dns_resolver=False, fullstack=False, platforms=['linux', 'mac', 'posix'])
 
 
 # maps fixture name to whether it requires the security library
@@ -52,10 +54,12 @@
     'h2_compress': default_unsecure_fixture_options,
     'h2_census': default_unsecure_fixture_options,
     'h2_fakesec': default_secure_fixture_options._replace(ci_mac=False),
+    'h2_fd': fd_unsecure_fixture_options,
     'h2_full': default_unsecure_fixture_options,
     'h2_full+pipe': default_unsecure_fixture_options._replace(
         platforms=['linux']),
     'h2_full+trace': default_unsecure_fixture_options._replace(tracing=True),
+    'h2_loadreporting': default_unsecure_fixture_options,
     'h2_oauth2': default_secure_fixture_options._replace(ci_mac=False),
     'h2_proxy': default_unsecure_fixture_options._replace(includes_proxy=True,
                                                           ci_mac=False),
@@ -72,7 +76,8 @@
 }
 
 TestOptions = collections.namedtuple(
-    'TestOptions', 'needs_fullstack needs_dns proxyable secure traceable cpu_cost')
+    'TestOptions',
+    'needs_fullstack needs_dns proxyable secure traceable cpu_cost')
 default_test_options = TestOptions(False, False, True, False, True, 1.0)
 connectivity_test_options = default_test_options._replace(needs_fullstack=True)
 
@@ -89,8 +94,10 @@
     'cancel_before_invoke': default_test_options._replace(cpu_cost=LOWCPU),
     'cancel_in_a_vacuum': default_test_options._replace(cpu_cost=LOWCPU),
     'cancel_with_status': default_test_options._replace(cpu_cost=LOWCPU),
-    'compressed_payload': default_test_options._replace(proxyable=False, cpu_cost=LOWCPU),
-    'connectivity': connectivity_test_options._replace(proxyable=False, cpu_cost=LOWCPU),
+    'compressed_payload': default_test_options._replace(proxyable=False,
+                                                        cpu_cost=LOWCPU),
+    'connectivity': connectivity_test_options._replace(proxyable=False,
+                                                       cpu_cost=LOWCPU),
     'default_host': default_test_options._replace(needs_fullstack=True,
                                                   needs_dns=True),
     'disappearing_server': connectivity_test_options,
@@ -116,7 +123,8 @@
     'server_finishes_request': default_test_options,
     'shutdown_finishes_calls': default_test_options,
     'shutdown_finishes_tags': default_test_options,
-    'simple_delayed_request': connectivity_test_options._replace(cpu_cost=LOWCPU),
+    'simple_delayed_request': connectivity_test_options._replace(
+        cpu_cost=LOWCPU),
     'simple_metadata': default_test_options,
     'simple_request': default_test_options,
     'trailing_metadata': default_test_options,
diff --git a/test/core/end2end/goaway_server_test.c b/test/core/end2end/goaway_server_test.c
index 5f8c264..3266793 100644
--- a/test/core/end2end/goaway_server_test.c
+++ b/test/core/end2end/goaway_server_test.c
@@ -132,6 +132,7 @@
       chan, NULL, GRPC_PROPAGATE_DEFAULTS, cq, "/foo", "127.0.0.1",
       GRPC_TIMEOUT_SECONDS_TO_DEADLINE(20), NULL);
   /* send initial metadata to probe connectivity */
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_SEND_INITIAL_METADATA;
   op->data.send_initial_metadata.count = 0;
@@ -142,6 +143,7 @@
                                                    (size_t)(op - ops),
                                                    tag(0x101), NULL));
   /* and receive status to probe termination */
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
   op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv1;
@@ -183,6 +185,7 @@
                                         tag(0x9999));
 
   /* listen for close on the server call to probe for finishing */
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
   op->data.recv_close_on_server.cancelled = &was_cancelled1;
@@ -205,6 +208,7 @@
       chan, NULL, GRPC_PROPAGATE_DEFAULTS, cq, "/foo", "127.0.0.1",
       GRPC_TIMEOUT_SECONDS_TO_DEADLINE(20), NULL);
   /* send initial metadata to probe connectivity */
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_SEND_INITIAL_METADATA;
   op->data.send_initial_metadata.count = 0;
@@ -215,6 +219,7 @@
                                                    (size_t)(op - ops),
                                                    tag(0x201), NULL));
   /* and receive status to probe termination */
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
   op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv2;
@@ -249,6 +254,7 @@
   cq_verify(cqv);
 
   /* listen for close on the server call to probe for finishing */
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
   op->data.recv_close_on_server.cancelled = &was_cancelled2;
diff --git a/test/core/end2end/invalid_call_argument_test.c b/test/core/end2end/invalid_call_argument_test.c
index cf42e92..3545660 100644
--- a/test/core/end2end/invalid_call_argument_test.c
+++ b/test/core/end2end/invalid_call_argument_test.c
@@ -30,11 +30,15 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  */
+
+#include <limits.h>
+#include <string.h>
+
 #include <grpc/grpc.h>
 #include <grpc/support/alloc.h>
 #include <grpc/support/host_port.h>
 #include <grpc/support/log.h>
-#include <limits.h>
+
 #include "test/core/end2end/cq_verifier.h"
 #include "test/core/util/port.h"
 #include "test/core/util/test_config.h"
@@ -74,6 +78,7 @@
   g_state.cqv = cq_verifier_create(g_state.cq);
   g_state.details = NULL;
   g_state.details_capacity = 0;
+  memset(g_state.ops, 0, sizeof(g_state.ops));
 
   if (is_client) {
     /* create a call, channel to a non existant server */
diff --git a/test/core/end2end/no_server_test.c b/test/core/end2end/no_server_test.c
index 7a5cd23..08af382 100644
--- a/test/core/end2end/no_server_test.c
+++ b/test/core/end2end/no_server_test.c
@@ -31,9 +31,12 @@
  *
  */
 
+#include <string.h>
+
 #include <grpc/grpc.h>
 #include <grpc/support/alloc.h>
 #include <grpc/support/log.h>
+
 #include "test/core/end2end/cq_verifier.h"
 #include "test/core/util/test_config.h"
 
@@ -65,6 +68,7 @@
   call = grpc_channel_create_call(chan, NULL, GRPC_PROPAGATE_DEFAULTS, cq,
                                   "/Foo", "nonexistant", deadline, NULL);
 
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_SEND_INITIAL_METADATA;
   op->data.send_initial_metadata.count = 0;
diff --git a/test/core/end2end/tests/bad_hostname.c b/test/core/end2end/tests/bad_hostname.c
index 3cb9b3d..c9663c2 100644
--- a/test/core/end2end/tests/bad_hostname.c
+++ b/test/core/end2end/tests/bad_hostname.c
@@ -123,6 +123,7 @@
   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 = 0;
diff --git a/test/core/end2end/tests/binary_metadata.c b/test/core/end2end/tests/binary_metadata.c
index 994c3bf..3dd2612 100644
--- a/test/core/end2end/tests/binary_metadata.c
+++ b/test/core/end2end/tests/binary_metadata.c
@@ -157,6 +157,7 @@
   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;
@@ -201,6 +202,7 @@
   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;
@@ -219,6 +221,7 @@
   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;
diff --git a/test/core/end2end/tests/call_creds.c b/test/core/end2end/tests/call_creds.c
index 5c6791f..694a0aa 100644
--- a/test/core/end2end/tests/call_creds.c
+++ b/test/core/end2end/tests/call_creds.c
@@ -193,6 +193,7 @@
   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 = 0;
@@ -248,6 +249,7 @@
   /* Cannot set creds on the server call object. */
   GPR_ASSERT(grpc_call_set_credentials(s, NULL) != GRPC_CALL_OK);
 
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_SEND_INITIAL_METADATA;
   op->data.send_initial_metadata.count = 0;
@@ -265,6 +267,7 @@
   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;
@@ -410,6 +413,7 @@
   grpc_metadata_array_init(&request_metadata_recv);
   grpc_call_details_init(&call_details);
 
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
   op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
diff --git a/test/core/end2end/tests/cancel_after_accept.c b/test/core/end2end/tests/cancel_after_accept.c
index fc2a64a..51c13da 100644
--- a/test/core/end2end/tests/cancel_after_accept.c
+++ b/test/core/end2end/tests/cancel_after_accept.c
@@ -136,6 +136,7 @@
   grpc_metadata_array_init(&request_metadata_recv);
   grpc_call_details_init(&call_details);
 
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
   op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
@@ -174,6 +175,7 @@
   cq_expect_completion(cqv, tag(2), 1);
   cq_verify(cqv);
 
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_RECV_MESSAGE;
   op->data.recv_message = &request_payload_recv;
diff --git a/test/core/end2end/tests/cancel_after_client_done.c b/test/core/end2end/tests/cancel_after_client_done.c
index 3bafa8c..2b5a409 100644
--- a/test/core/end2end/tests/cancel_after_client_done.c
+++ b/test/core/end2end/tests/cancel_after_client_done.c
@@ -136,6 +136,7 @@
   grpc_metadata_array_init(&request_metadata_recv);
   grpc_call_details_init(&call_details);
 
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
   op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
@@ -178,6 +179,7 @@
   cq_expect_completion(cqv, tag(2), 1);
   cq_verify(cqv);
 
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_RECV_MESSAGE;
   op->data.recv_message = &request_payload_recv;
diff --git a/test/core/end2end/tests/cancel_after_invoke.c b/test/core/end2end/tests/cancel_after_invoke.c
index fc2751a..85fbe9d 100644
--- a/test/core/end2end/tests/cancel_after_invoke.c
+++ b/test/core/end2end/tests/cancel_after_invoke.c
@@ -131,6 +131,7 @@
   grpc_metadata_array_init(&request_metadata_recv);
   grpc_call_details_init(&call_details);
 
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
   op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
diff --git a/test/core/end2end/tests/cancel_before_invoke.c b/test/core/end2end/tests/cancel_before_invoke.c
index 33005db..d99062c 100644
--- a/test/core/end2end/tests/cancel_before_invoke.c
+++ b/test/core/end2end/tests/cancel_before_invoke.c
@@ -131,6 +131,7 @@
   grpc_metadata_array_init(&request_metadata_recv);
   grpc_call_details_init(&call_details);
 
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
   op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
diff --git a/test/core/end2end/tests/cancel_with_status.c b/test/core/end2end/tests/cancel_with_status.c
index c3ee4a6..83629a9 100644
--- a/test/core/end2end/tests/cancel_with_status.c
+++ b/test/core/end2end/tests/cancel_with_status.c
@@ -122,6 +122,7 @@
   grpc_metadata_array_init(&initial_metadata_recv);
   grpc_metadata_array_init(&trailing_metadata_recv);
 
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
   op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
diff --git a/test/core/end2end/tests/compressed_payload.c b/test/core/end2end/tests/compressed_payload.c
index 589bc31..ec5c012 100644
--- a/test/core/end2end/tests/compressed_payload.c
+++ b/test/core/end2end/tests/compressed_payload.c
@@ -38,13 +38,15 @@
 
 #include <grpc/byte_buffer.h>
 #include <grpc/byte_buffer_reader.h>
+#include <grpc/compression.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 "src/core/lib/channel/channel_args.h"
-#include "src/core/lib/channel/compress_filter.h"
+#include "src/core/lib/surface/call.h"
 #include "src/core/lib/surface/call_test_only.h"
 #include "test/core/end2end/cq_verifier.h"
 
@@ -102,12 +104,12 @@
   grpc_completion_queue_destroy(f->cq);
 }
 
-static void request_with_payload_template(
+static void request_for_disabled_algorithm(
     grpc_end2end_test_config config, const char *test_name,
     uint32_t send_flags_bitmask,
-    grpc_compression_algorithm requested_compression_algorithm,
-    grpc_compression_algorithm expected_compression_algorithm,
-    grpc_metadata *client_metadata) {
+    grpc_compression_algorithm algorithm_to_disable,
+    grpc_compression_algorithm requested_client_compression_algorithm,
+    grpc_status_code expected_error, grpc_metadata *client_metadata) {
   grpc_call *c;
   grpc_call *s;
   gpr_slice request_payload_slice;
@@ -137,9 +139,11 @@
   request_payload = grpc_raw_byte_buffer_create(&request_payload_slice, 1);
 
   client_args = grpc_channel_args_set_compression_algorithm(
-      NULL, requested_compression_algorithm);
-  server_args = grpc_channel_args_set_compression_algorithm(
-      NULL, requested_compression_algorithm);
+      NULL, requested_client_compression_algorithm);
+  server_args =
+      grpc_channel_args_set_compression_algorithm(NULL, GRPC_COMPRESS_NONE);
+  server_args = grpc_channel_args_compression_algorithm_set_state(
+      &server_args, algorithm_to_disable, false);
 
   f = begin_test(config, test_name, client_args, server_args);
   cqv = cq_verifier_create(f.cq);
@@ -153,6 +157,7 @@
   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;
   if (client_metadata != NULL) {
@@ -193,18 +198,9 @@
       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_expect_completion(cqv, tag(101), true);
   cq_verify(cqv);
 
-  GPR_ASSERT(
-      GPR_BITCOUNT(grpc_call_test_only_get_encodings_accepted_by_peer(s)) == 3);
-  GPR_ASSERT(GPR_BITGET(grpc_call_test_only_get_encodings_accepted_by_peer(s),
-                        GRPC_COMPRESS_NONE) != 0);
-  GPR_ASSERT(GPR_BITGET(grpc_call_test_only_get_encodings_accepted_by_peer(s),
-                        GRPC_COMPRESS_DEFLATE) != 0);
-  GPR_ASSERT(GPR_BITGET(grpc_call_test_only_get_encodings_accepted_by_peer(s),
-                        GRPC_COMPRESS_GZIP) != 0);
-
   op = ops;
   op->op = GRPC_OP_SEND_INITIAL_METADATA;
   op->data.send_initial_metadata.count = 0;
@@ -219,8 +215,7 @@
   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);
+  cq_expect_completion(cqv, tag(102), false);
 
   op = ops;
   op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
@@ -228,31 +223,28 @@
   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_expect_completion(cqv, tag(103), true);
+  cq_expect_completion(cqv, tag(1), true);
   cq_verify(cqv);
 
-  GPR_ASSERT(status == GRPC_STATUS_OK);
-  GPR_ASSERT(0 == strcmp(details, "xyz"));
+  /* call was cancelled (closed) ... */
+  GPR_ASSERT(was_cancelled != 0);
+  /* with a certain error */
+  GPR_ASSERT(status == expected_error);
+
+  char *algo_name = NULL;
+  GPR_ASSERT(grpc_compression_algorithm_name(algorithm_to_disable, &algo_name));
+  char *expected_details = NULL;
+  gpr_asprintf(&expected_details, "Compression algorithm '%s' is disabled.",
+               algo_name);
+  /* and we expect a specific reason for it */
+  GPR_ASSERT(0 == strcmp(details, expected_details));
+  gpr_free(expected_details);
   GPR_ASSERT(0 == strcmp(call_details.method, "/foo"));
   GPR_ASSERT(0 == strcmp(call_details.host, "foo.test.google.fr"));
-  GPR_ASSERT(was_cancelled == 0);
-
-  GPR_ASSERT(request_payload_recv->type == GRPC_BB_RAW);
-  GPR_ASSERT(request_payload_recv->data.raw.compression ==
-             expected_compression_algorithm);
-
-  GPR_ASSERT(byte_buffer_eq_string(request_payload_recv, str));
 
   gpr_free(details);
   grpc_metadata_array_destroy(&initial_metadata_recv);
@@ -276,65 +268,340 @@
   config.tear_down_data(&f);
 }
 
+static void request_with_payload_template(
+    grpc_end2end_test_config config, const char *test_name,
+    uint32_t client_send_flags_bitmask,
+    grpc_compression_algorithm default_client_channel_compression_algorithm,
+    grpc_compression_algorithm default_server_channel_compression_algorithm,
+    grpc_compression_algorithm expected_algorithm_from_client,
+    grpc_compression_algorithm expected_algorithm_from_server,
+    grpc_metadata *client_init_metadata, bool set_server_level,
+    grpc_compression_level server_compression_level) {
+  grpc_call *c;
+  grpc_call *s;
+  gpr_slice request_payload_slice;
+  grpc_byte_buffer *request_payload;
+  gpr_timespec deadline = five_seconds_time();
+  grpc_channel_args *client_args;
+  grpc_channel_args *server_args;
+  grpc_end2end_test_fixture f;
+  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;
+  grpc_byte_buffer *response_payload_recv;
+  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;
+  cq_verifier *cqv;
+  char request_str[1024];
+  char response_str[1024];
+
+  memset(request_str, 'x', 1023);
+  request_str[1023] = '\0';
+
+  memset(response_str, 'y', 1023);
+  response_str[1023] = '\0';
+
+  request_payload_slice = gpr_slice_from_copied_string(request_str);
+  gpr_slice response_payload_slice = gpr_slice_from_copied_string(response_str);
+
+  client_args = grpc_channel_args_set_compression_algorithm(
+      NULL, default_client_channel_compression_algorithm);
+  server_args = grpc_channel_args_set_compression_algorithm(
+      NULL, default_server_channel_compression_algorithm);
+
+  f = begin_test(config, test_name, client_args, server_args);
+  cqv = cq_verifier_create(f.cq);
+
+  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;
+  if (client_init_metadata != NULL) {
+    op->data.send_initial_metadata.count = 1;
+    op->data.send_initial_metadata.metadata = client_init_metadata;
+  } else {
+    op->data.send_initial_metadata.count = 0;
+  }
+  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_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(100));
+  GPR_ASSERT(GRPC_CALL_OK == error);
+  cq_expect_completion(cqv, tag(100), true);
+  cq_verify(cqv);
+
+  GPR_ASSERT(GPR_BITCOUNT(grpc_call_test_only_get_encodings_accepted_by_peer(
+                 s)) == GRPC_COMPRESS_ALGORITHMS_COUNT);
+  GPR_ASSERT(GPR_BITGET(grpc_call_test_only_get_encodings_accepted_by_peer(s),
+                        GRPC_COMPRESS_NONE) != 0);
+  GPR_ASSERT(GPR_BITGET(grpc_call_test_only_get_encodings_accepted_by_peer(s),
+                        GRPC_COMPRESS_DEFLATE) != 0);
+  GPR_ASSERT(GPR_BITGET(grpc_call_test_only_get_encodings_accepted_by_peer(s),
+                        GRPC_COMPRESS_GZIP) != 0);
+
+  memset(ops, 0, sizeof(ops));
+  op = ops;
+  op->op = GRPC_OP_SEND_INITIAL_METADATA;
+  op->data.send_initial_metadata.count = 0;
+  if (set_server_level) {
+    op->data.send_initial_metadata.maybe_compression_level.is_set = true;
+    op->data.send_initial_metadata.maybe_compression_level.level =
+        server_compression_level;
+  }
+  op->flags = 0;
+  op->reserved = NULL;
+  op++;
+  op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
+  op->data.recv_close_on_server.cancelled = &was_cancelled;
+  op->flags = 0;
+  op->reserved = NULL;
+  op++;
+  error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(101), NULL);
+  GPR_ASSERT(GRPC_CALL_OK == error);
+
+  for (int i = 0; i < 2; i++) {
+    request_payload = grpc_raw_byte_buffer_create(&request_payload_slice, 1);
+    response_payload = grpc_raw_byte_buffer_create(&response_payload_slice, 1);
+
+    memset(ops, 0, sizeof(ops));
+    op = ops;
+    op->op = GRPC_OP_SEND_MESSAGE;
+    op->data.send_message = request_payload;
+    op->flags = client_send_flags_bitmask;
+    op->reserved = NULL;
+    op++;
+    op->op = GRPC_OP_RECV_MESSAGE;
+    op->data.recv_message = &response_payload_recv;
+    op->flags = 0;
+    op->reserved = NULL;
+    op++;
+    error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(2), NULL);
+    GPR_ASSERT(GRPC_CALL_OK == error);
+
+    memset(ops, 0, sizeof(ops));
+    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(102), NULL);
+    GPR_ASSERT(GRPC_CALL_OK == error);
+    cq_expect_completion(cqv, tag(102), 1);
+    cq_verify(cqv);
+
+    GPR_ASSERT(request_payload_recv->type == GRPC_BB_RAW);
+    GPR_ASSERT(byte_buffer_eq_string(request_payload_recv, request_str));
+    GPR_ASSERT(request_payload_recv->data.raw.compression ==
+               expected_algorithm_from_client);
+
+    memset(ops, 0, sizeof(ops));
+    op = ops;
+    op->op = GRPC_OP_SEND_MESSAGE;
+    op->data.send_message = response_payload;
+    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(2), 1);
+    cq_verify(cqv);
+
+    GPR_ASSERT(response_payload_recv->type == GRPC_BB_RAW);
+    GPR_ASSERT(byte_buffer_eq_string(response_payload_recv, response_str));
+    if (server_compression_level > GRPC_COMPRESS_LEVEL_NONE) {
+      const grpc_compression_algorithm algo_for_server_level =
+          grpc_call_compression_for_level(s, server_compression_level);
+      GPR_ASSERT(response_payload_recv->data.raw.compression ==
+                 algo_for_server_level);
+    } else {
+      GPR_ASSERT(response_payload_recv->data.raw.compression ==
+                 expected_algorithm_from_server);
+    }
+
+    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);
+  }
+
+  gpr_slice_unref(request_payload_slice);
+  gpr_slice_unref(response_payload_slice);
+
+  memset(ops, 0, sizeof(ops));
+  op = ops;
+  op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
+  op->flags = 0;
+  op->reserved = NULL;
+  op++;
+  error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(3), NULL);
+  GPR_ASSERT(GRPC_CALL_OK == error);
+
+  memset(ops, 0, sizeof(ops));
+  op = ops;
+  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(104), NULL);
+  GPR_ASSERT(GRPC_CALL_OK == error);
+
+  cq_expect_completion(cqv, tag(1), 1);
+  cq_expect_completion(cqv, tag(3), 1);
+  cq_expect_completion(cqv, tag(101), 1);
+  cq_expect_completion(cqv, tag(104), 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"));
+  GPR_ASSERT(was_cancelled == 0);
+
+  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_channel_args_destroy(client_args);
+  grpc_channel_args_destroy(server_args);
+
+  end_test(&f);
+  config.tear_down_data(&f);
+}
+
 static void test_invoke_request_with_exceptionally_uncompressed_payload(
     grpc_end2end_test_config config) {
   request_with_payload_template(
       config, "test_invoke_request_with_exceptionally_uncompressed_payload",
-      GRPC_WRITE_NO_COMPRESS, GRPC_COMPRESS_GZIP, GRPC_COMPRESS_NONE, NULL);
+      GRPC_WRITE_NO_COMPRESS, GRPC_COMPRESS_GZIP, GRPC_COMPRESS_GZIP,
+      GRPC_COMPRESS_NONE, GRPC_COMPRESS_GZIP, NULL, false,
+      /* ignored */ GRPC_COMPRESS_LEVEL_NONE);
 }
 
 static void test_invoke_request_with_uncompressed_payload(
     grpc_end2end_test_config config) {
   request_with_payload_template(
       config, "test_invoke_request_with_uncompressed_payload", 0,
-      GRPC_COMPRESS_NONE, GRPC_COMPRESS_NONE, NULL);
+      GRPC_COMPRESS_NONE, GRPC_COMPRESS_NONE, GRPC_COMPRESS_NONE,
+      GRPC_COMPRESS_NONE, NULL, false, /* ignored */ GRPC_COMPRESS_LEVEL_NONE);
 }
 
 static void test_invoke_request_with_compressed_payload(
     grpc_end2end_test_config config) {
   request_with_payload_template(
       config, "test_invoke_request_with_compressed_payload", 0,
-      GRPC_COMPRESS_GZIP, GRPC_COMPRESS_GZIP, NULL);
+      GRPC_COMPRESS_GZIP, GRPC_COMPRESS_GZIP, GRPC_COMPRESS_GZIP,
+      GRPC_COMPRESS_GZIP, NULL, false, /* ignored */ GRPC_COMPRESS_LEVEL_NONE);
+}
+
+static void test_invoke_request_with_server_level(
+    grpc_end2end_test_config config) {
+  request_with_payload_template(
+      config, "test_invoke_request_with_server_level", 0, GRPC_COMPRESS_NONE,
+      GRPC_COMPRESS_NONE, GRPC_COMPRESS_NONE, GRPC_COMPRESS_NONE /* ignored */,
+      NULL, true, GRPC_COMPRESS_LEVEL_HIGH);
 }
 
 static void test_invoke_request_with_compressed_payload_md_override(
     grpc_end2end_test_config config) {
   grpc_metadata gzip_compression_override;
-  grpc_metadata none_compression_override;
+  grpc_metadata identity_compression_override;
 
-  gzip_compression_override.key = GRPC_COMPRESS_REQUEST_ALGORITHM_KEY;
+  gzip_compression_override.key = GRPC_COMPRESSION_REQUEST_ALGORITHM_MD_KEY;
   gzip_compression_override.value = "gzip";
-  gzip_compression_override.value_length = 4;
+  gzip_compression_override.value_length =
+      strlen(gzip_compression_override.value);
   memset(&gzip_compression_override.internal_data, 0,
          sizeof(gzip_compression_override.internal_data));
 
-  none_compression_override.key = GRPC_COMPRESS_REQUEST_ALGORITHM_KEY;
-  none_compression_override.value = "identity";
-  none_compression_override.value_length = 4;
-  memset(&none_compression_override.internal_data, 0,
-         sizeof(none_compression_override.internal_data));
+  identity_compression_override.key = GRPC_COMPRESSION_REQUEST_ALGORITHM_MD_KEY;
+  identity_compression_override.value = "identity";
+  identity_compression_override.value_length =
+      strlen(identity_compression_override.value);
+  memset(&identity_compression_override.internal_data, 0,
+         sizeof(identity_compression_override.internal_data));
 
   /* Channel default NONE (aka IDENTITY), call override to GZIP */
   request_with_payload_template(
       config, "test_invoke_request_with_compressed_payload_md_override_1", 0,
-      GRPC_COMPRESS_NONE, GRPC_COMPRESS_GZIP, &gzip_compression_override);
+      GRPC_COMPRESS_NONE, GRPC_COMPRESS_NONE, GRPC_COMPRESS_GZIP,
+      GRPC_COMPRESS_NONE, &gzip_compression_override, false,
+      /*ignored*/ GRPC_COMPRESS_LEVEL_NONE);
 
   /* Channel default DEFLATE, call override to GZIP */
   request_with_payload_template(
       config, "test_invoke_request_with_compressed_payload_md_override_2", 0,
-      GRPC_COMPRESS_DEFLATE, GRPC_COMPRESS_GZIP, &gzip_compression_override);
+      GRPC_COMPRESS_DEFLATE, GRPC_COMPRESS_NONE, GRPC_COMPRESS_GZIP,
+      GRPC_COMPRESS_NONE, &gzip_compression_override, false,
+      /*ignored*/ GRPC_COMPRESS_LEVEL_NONE);
 
   /* Channel default DEFLATE, call override to NONE (aka IDENTITY) */
   request_with_payload_template(
       config, "test_invoke_request_with_compressed_payload_md_override_3", 0,
-      GRPC_COMPRESS_DEFLATE, GRPC_COMPRESS_NONE, &none_compression_override);
+      GRPC_COMPRESS_DEFLATE, GRPC_COMPRESS_NONE, GRPC_COMPRESS_NONE,
+      GRPC_COMPRESS_NONE, &identity_compression_override, false,
+      /*ignored*/ GRPC_COMPRESS_LEVEL_NONE);
+}
+
+static void test_invoke_request_with_disabled_algorithm(
+    grpc_end2end_test_config config) {
+  request_for_disabled_algorithm(
+      config, "test_invoke_request_with_disabled_algorithm", 0,
+      GRPC_COMPRESS_GZIP, GRPC_COMPRESS_GZIP, GRPC_STATUS_UNIMPLEMENTED, NULL);
 }
 
 void compressed_payload(grpc_end2end_test_config config) {
   test_invoke_request_with_exceptionally_uncompressed_payload(config);
   test_invoke_request_with_uncompressed_payload(config);
   test_invoke_request_with_compressed_payload(config);
+  test_invoke_request_with_server_level(config);
   test_invoke_request_with_compressed_payload_md_override(config);
+  test_invoke_request_with_disabled_algorithm(config);
 }
 
 void compressed_payload_pre_init(void) {}
diff --git a/test/core/end2end/tests/default_host.c b/test/core/end2end/tests/default_host.c
index 44384a7..728ee59 100644
--- a/test/core/end2end/tests/default_host.c
+++ b/test/core/end2end/tests/default_host.c
@@ -131,6 +131,7 @@
   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 = 0;
@@ -173,6 +174,7 @@
   gpr_log(GPR_DEBUG, "client_peer=%s", peer);
   gpr_free(peer);
 
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_SEND_INITIAL_METADATA;
   op->data.send_initial_metadata.count = 0;
diff --git a/test/core/end2end/tests/disappearing_server.c b/test/core/end2end/tests/disappearing_server.c
index 03d1ded..536fbd0 100644
--- a/test/core/end2end/tests/disappearing_server.c
+++ b/test/core/end2end/tests/disappearing_server.c
@@ -108,6 +108,7 @@
   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 = 0;
@@ -145,6 +146,7 @@
      - and still complete the request */
   grpc_server_shutdown_and_notify(f->server, f->cq, tag(1000));
 
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_SEND_INITIAL_METADATA;
   op->data.send_initial_metadata.count = 0;
diff --git a/test/core/end2end/tests/filter_causes_close.c b/test/core/end2end/tests/filter_causes_close.c
index 99049aa..e6edb21 100644
--- a/test/core/end2end/tests/filter_causes_close.c
+++ b/test/core/end2end/tests/filter_causes_close.c
@@ -134,6 +134,7 @@
   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 = 0;
@@ -233,6 +234,7 @@
                            grpc_call_element_args *args) {}
 
 static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
+                              const grpc_call_stats *stats,
                               void *and_free_memory) {}
 
 static void init_channel_elem(grpc_exec_ctx *exec_ctx,
@@ -247,7 +249,7 @@
     grpc_channel_next_op,
     sizeof(call_data),
     init_call_elem,
-    grpc_call_stack_ignore_set_pollset,
+    grpc_call_stack_ignore_set_pollset_or_pollset_set,
     destroy_call_elem,
     sizeof(channel_data),
     init_channel_elem,
diff --git a/test/core/end2end/tests/graceful_server_shutdown.c b/test/core/end2end/tests/graceful_server_shutdown.c
index 26198f3..f527b86 100644
--- a/test/core/end2end/tests/graceful_server_shutdown.c
+++ b/test/core/end2end/tests/graceful_server_shutdown.c
@@ -122,6 +122,7 @@
   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 = 0;
@@ -160,6 +161,7 @@
   grpc_server_shutdown_and_notify(f.server, f.cq, tag(0xdead));
   cq_verify_empty(cqv);
 
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_SEND_INITIAL_METADATA;
   op->data.send_initial_metadata.count = 0;
diff --git a/test/core/end2end/tests/high_initial_seqno.c b/test/core/end2end/tests/high_initial_seqno.c
index 374606d..50e3c9c 100644
--- a/test/core/end2end/tests/high_initial_seqno.c
+++ b/test/core/end2end/tests/high_initial_seqno.c
@@ -128,6 +128,7 @@
   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 = 0;
@@ -161,6 +162,7 @@
   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 = 0;
diff --git a/test/core/end2end/tests/hpack_size.c b/test/core/end2end/tests/hpack_size.c
index 07d5d38..ee889b7 100644
--- a/test/core/end2end/tests/hpack_size.c
+++ b/test/core/end2end/tests/hpack_size.c
@@ -323,6 +323,7 @@
   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 = GPR_ARRAY_SIZE(extra_metadata);
@@ -357,6 +358,7 @@
   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 = 0;
diff --git a/test/core/end2end/tests/idempotent_request.c b/test/core/end2end/tests/idempotent_request.c
index e53f3b2..dfedcfe 100644
--- a/test/core/end2end/tests/idempotent_request.c
+++ b/test/core/end2end/tests/idempotent_request.c
@@ -132,6 +132,7 @@
   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 = 0;
@@ -174,6 +175,7 @@
   gpr_log(GPR_DEBUG, "client_peer=%s", peer);
   gpr_free(peer);
 
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_SEND_INITIAL_METADATA;
   op->data.send_initial_metadata.count = 0;
diff --git a/test/core/end2end/tests/invoke_large_request.c b/test/core/end2end/tests/invoke_large_request.c
index 6410305..9c9ca95 100644
--- a/test/core/end2end/tests/invoke_large_request.c
+++ b/test/core/end2end/tests/invoke_large_request.c
@@ -138,6 +138,7 @@
   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 = 0;
@@ -181,6 +182,7 @@
   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 = 0;
@@ -198,6 +200,7 @@
   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;
diff --git a/test/core/end2end/tests/large_metadata.c b/test/core/end2end/tests/large_metadata.c
index ae1f68a..1f27896 100644
--- a/test/core/end2end/tests/large_metadata.c
+++ b/test/core/end2end/tests/large_metadata.c
@@ -142,6 +142,7 @@
   grpc_metadata_array_init(&request_metadata_recv);
   grpc_call_details_init(&call_details);
 
+  memset(ops, 0, sizeof(ops));
   // Client: send request.
   op = ops;
   op->op = GRPC_OP_SEND_INITIAL_METADATA;
@@ -183,6 +184,7 @@
   cq_expect_completion(cqv, tag(101), 1);
   cq_verify(cqv);
 
+  memset(ops, 0, sizeof(ops));
   // Server: send initial metadata and receive request.
   op = ops;
   op->op = GRPC_OP_SEND_INITIAL_METADATA;
@@ -201,6 +203,7 @@
   cq_expect_completion(cqv, tag(102), 1);
   cq_verify(cqv);
 
+  memset(ops, 0, sizeof(ops));
   // Server: receive close and send status.  This should trigger
   // completion of request on client.
   op = ops;
diff --git a/test/core/end2end/tests/max_concurrent_streams.c b/test/core/end2end/tests/max_concurrent_streams.c
index 1bb5307..41de74f 100644
--- a/test/core/end2end/tests/max_concurrent_streams.c
+++ b/test/core/end2end/tests/max_concurrent_streams.c
@@ -124,6 +124,7 @@
   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 = 0;
@@ -157,6 +158,7 @@
   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 = 0;
@@ -270,6 +272,7 @@
                                  f.server, &s1, &call_details,
                                  &request_metadata_recv, f.cq, f.cq, tag(101)));
 
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_SEND_INITIAL_METADATA;
   op->data.send_initial_metadata.count = 0;
@@ -283,6 +286,7 @@
   error = grpc_call_start_batch(c1, ops, (size_t)(op - ops), tag(301), NULL);
   GPR_ASSERT(GRPC_CALL_OK == error);
 
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
   op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv1;
@@ -300,6 +304,7 @@
   error = grpc_call_start_batch(c1, ops, (size_t)(op - ops), tag(302), NULL);
   GPR_ASSERT(GRPC_CALL_OK == error);
 
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_SEND_INITIAL_METADATA;
   op->data.send_initial_metadata.count = 0;
@@ -313,6 +318,7 @@
   error = grpc_call_start_batch(c2, ops, (size_t)(op - ops), tag(401), NULL);
   GPR_ASSERT(GRPC_CALL_OK == error);
 
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
   op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv2;
@@ -354,6 +360,7 @@
   }
   GPR_ASSERT(live_call == 300 || live_call == 400);
 
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_SEND_INITIAL_METADATA;
   op->data.send_initial_metadata.count = 0;
@@ -388,6 +395,7 @@
   cq_expect_completion(cqv, tag(201), 1);
   cq_verify(cqv);
 
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_SEND_INITIAL_METADATA;
   op->data.send_initial_metadata.count = 0;
diff --git a/test/core/end2end/tests/max_message_length.c b/test/core/end2end/tests/max_message_length.c
index 4f57278..08d326a 100644
--- a/test/core/end2end/tests/max_message_length.c
+++ b/test/core/end2end/tests/max_message_length.c
@@ -143,6 +143,7 @@
   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 = 0;
@@ -181,6 +182,7 @@
   cq_expect_completion(cqv, tag(101), 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;
diff --git a/test/core/end2end/tests/negative_deadline.c b/test/core/end2end/tests/negative_deadline.c
index 03e57a9..fd56c8b 100644
--- a/test/core/end2end/tests/negative_deadline.c
+++ b/test/core/end2end/tests/negative_deadline.c
@@ -122,6 +122,7 @@
   grpc_metadata_array_init(&initial_metadata_recv);
   grpc_metadata_array_init(&trailing_metadata_recv);
 
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
   op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
diff --git a/test/core/end2end/tests/payload.c b/test/core/end2end/tests/payload.c
index bdfb135..443d85e 100644
--- a/test/core/end2end/tests/payload.c
+++ b/test/core/end2end/tests/payload.c
@@ -131,6 +131,7 @@
   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 = 0;
@@ -174,6 +175,7 @@
   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 = 0;
@@ -191,6 +193,7 @@
   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;
diff --git a/test/core/end2end/tests/ping_pong_streaming.c b/test/core/end2end/tests/ping_pong_streaming.c
index 15e1c6e..1d2f794 100644
--- a/test/core/end2end/tests/ping_pong_streaming.c
+++ b/test/core/end2end/tests/ping_pong_streaming.c
@@ -135,6 +135,7 @@
   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 = 0;
@@ -164,6 +165,7 @@
   cq_expect_completion(cqv, tag(100), 1);
   cq_verify(cqv);
 
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_SEND_INITIAL_METADATA;
   op->data.send_initial_metadata.count = 0;
@@ -182,6 +184,7 @@
     request_payload = grpc_raw_byte_buffer_create(&request_payload_slice, 1);
     response_payload = grpc_raw_byte_buffer_create(&response_payload_slice, 1);
 
+    memset(ops, 0, sizeof(ops));
     op = ops;
     op->op = GRPC_OP_SEND_MESSAGE;
     op->data.send_message = request_payload;
@@ -196,6 +199,7 @@
     error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(2), NULL);
     GPR_ASSERT(GRPC_CALL_OK == error);
 
+    memset(ops, 0, sizeof(ops));
     op = ops;
     op->op = GRPC_OP_RECV_MESSAGE;
     op->data.recv_message = &request_payload_recv;
@@ -207,6 +211,7 @@
     cq_expect_completion(cqv, tag(102), 1);
     cq_verify(cqv);
 
+    memset(ops, 0, sizeof(ops));
     op = ops;
     op->op = GRPC_OP_SEND_MESSAGE;
     op->data.send_message = response_payload;
@@ -228,6 +233,7 @@
   gpr_slice_unref(request_payload_slice);
   gpr_slice_unref(response_payload_slice);
 
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
   op->flags = 0;
@@ -236,6 +242,7 @@
   error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(3), NULL);
   GPR_ASSERT(GRPC_CALL_OK == error);
 
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
   op->data.send_status_from_server.trailing_metadata_count = 0;
diff --git a/test/core/end2end/tests/registered_call.c b/test/core/end2end/tests/registered_call.c
index 3c4edba..ece6250 100644
--- a/test/core/end2end/tests/registered_call.c
+++ b/test/core/end2end/tests/registered_call.c
@@ -125,6 +125,7 @@
   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 = 0;
@@ -158,6 +159,7 @@
   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 = 0;
diff --git a/test/core/end2end/tests/request_with_flags.c b/test/core/end2end/tests/request_with_flags.c
index f5a8d4d..b5d398b 100644
--- a/test/core/end2end/tests/request_with_flags.c
+++ b/test/core/end2end/tests/request_with_flags.c
@@ -131,6 +131,7 @@
   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 = 0;
diff --git a/test/core/end2end/tests/request_with_payload.c b/test/core/end2end/tests/request_with_payload.c
index 7706404..d94267e 100644
--- a/test/core/end2end/tests/request_with_payload.c
+++ b/test/core/end2end/tests/request_with_payload.c
@@ -130,6 +130,7 @@
   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 = 0;
@@ -167,6 +168,7 @@
   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 = 0;
@@ -184,6 +186,7 @@
   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;
diff --git a/test/core/end2end/tests/server_finishes_request.c b/test/core/end2end/tests/server_finishes_request.c
index a4f5319..a723c6f 100644
--- a/test/core/end2end/tests/server_finishes_request.c
+++ b/test/core/end2end/tests/server_finishes_request.c
@@ -126,6 +126,7 @@
   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 = 0;
@@ -155,6 +156,7 @@
   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 = 0;
diff --git a/test/core/end2end/tests/shutdown_finishes_calls.c b/test/core/end2end/tests/shutdown_finishes_calls.c
index 80287cd..abb6b26 100644
--- a/test/core/end2end/tests/shutdown_finishes_calls.c
+++ b/test/core/end2end/tests/shutdown_finishes_calls.c
@@ -115,6 +115,7 @@
   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 = 0;
@@ -149,6 +150,7 @@
   cq_expect_completion(cqv, tag(101), 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;
diff --git a/test/core/end2end/tests/simple_delayed_request.c b/test/core/end2end/tests/simple_delayed_request.c
index 400b3a0..e1fcc03 100644
--- a/test/core/end2end/tests/simple_delayed_request.c
+++ b/test/core/end2end/tests/simple_delayed_request.c
@@ -117,6 +117,7 @@
   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 = 0;
@@ -152,6 +153,7 @@
   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 = 0;
diff --git a/test/core/end2end/tests/simple_metadata.c b/test/core/end2end/tests/simple_metadata.c
index 707b3c9..c9b1a03 100644
--- a/test/core/end2end/tests/simple_metadata.c
+++ b/test/core/end2end/tests/simple_metadata.c
@@ -141,6 +141,7 @@
   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;
@@ -185,6 +186,7 @@
   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;
@@ -203,6 +205,7 @@
   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;
diff --git a/test/core/end2end/tests/simple_request.c b/test/core/end2end/tests/simple_request.c
index 4210842..a8014e6 100644
--- a/test/core/end2end/tests/simple_request.c
+++ b/test/core/end2end/tests/simple_request.c
@@ -132,6 +132,7 @@
   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 = 0;
@@ -174,6 +175,7 @@
   gpr_log(GPR_DEBUG, "client_peer=%s", peer);
   gpr_free(peer);
 
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_SEND_INITIAL_METADATA;
   op->data.send_initial_metadata.count = 0;
diff --git a/test/core/end2end/tests/trailing_metadata.c b/test/core/end2end/tests/trailing_metadata.c
index 4dd8c12..41e0f00 100644
--- a/test/core/end2end/tests/trailing_metadata.c
+++ b/test/core/end2end/tests/trailing_metadata.c
@@ -144,6 +144,7 @@
   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;
@@ -188,6 +189,7 @@
   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;
@@ -206,6 +208,7 @@
   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;
diff --git a/test/core/fling/client.c b/test/core/fling/client.c
index 8156227..123f2b5 100644
--- a/test/core/fling/client.c
+++ b/test/core/fling/client.c
@@ -65,6 +65,7 @@
   grpc_metadata_array_init(&initial_metadata_recv);
   grpc_metadata_array_init(&trailing_metadata_recv);
 
+  memset(ops, 0, sizeof(ops));
   op = ops;
 
   op->op = GRPC_OP_SEND_INITIAL_METADATA;
diff --git a/test/core/http/fuzzer.c b/test/core/http/fuzzer.c
index 7e4f4eb..c3c634f 100644
--- a/test/core/http/fuzzer.c
+++ b/test/core/http/fuzzer.c
@@ -31,6 +31,7 @@
  *
  */
 
+#include <stdbool.h>
 #include <stdint.h>
 #include <string.h>
 
@@ -38,6 +39,9 @@
 
 #include "src/core/lib/http/parser.h"
 
+bool squelch = true;
+bool leak_check = true;
+
 int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
   grpc_http_parser parser;
   grpc_http_parser_init(&parser);
diff --git a/test/core/http/httpcli_test.c b/test/core/http/httpcli_test.c
index d3a68d0..6c27ea2 100644
--- a/test/core/http/httpcli_test.c
+++ b/test/core/http/httpcli_test.c
@@ -48,7 +48,7 @@
 static int g_done = 0;
 static grpc_httpcli_context g_context;
 static gpr_mu *g_mu;
-static grpc_pollset *g_pollset;
+static grpc_polling_entity g_pops;
 
 static gpr_timespec n_seconds_time(int seconds) {
   return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(seconds);
@@ -66,7 +66,7 @@
   GPR_ASSERT(0 == memcmp(expect, response->body, response->body_length));
   gpr_mu_lock(g_mu);
   g_done = 1;
-  grpc_pollset_kick(g_pollset, NULL);
+  grpc_pollset_kick(grpc_polling_entity_pollset(&g_pops), NULL);
   gpr_mu_unlock(g_mu);
 }
 
@@ -86,12 +86,12 @@
   req.http.path = "/get";
   req.handshaker = &grpc_httpcli_plaintext;
 
-  grpc_httpcli_get(&exec_ctx, &g_context, g_pollset, &req, n_seconds_time(15),
+  grpc_httpcli_get(&exec_ctx, &g_context, &g_pops, &req, n_seconds_time(15),
                    on_finish, (void *)42);
   gpr_mu_lock(g_mu);
   while (!g_done) {
     grpc_pollset_worker *worker = NULL;
-    grpc_pollset_work(&exec_ctx, g_pollset, &worker,
+    grpc_pollset_work(&exec_ctx, grpc_polling_entity_pollset(&g_pops), &worker,
                       gpr_now(GPR_CLOCK_MONOTONIC), n_seconds_time(20));
     gpr_mu_unlock(g_mu);
     grpc_exec_ctx_finish(&exec_ctx);
@@ -117,12 +117,12 @@
   req.http.path = "/post";
   req.handshaker = &grpc_httpcli_plaintext;
 
-  grpc_httpcli_post(&exec_ctx, &g_context, g_pollset, &req, "hello", 5,
+  grpc_httpcli_post(&exec_ctx, &g_context, &g_pops, &req, "hello", 5,
                     n_seconds_time(15), on_finish, (void *)42);
   gpr_mu_lock(g_mu);
   while (!g_done) {
     grpc_pollset_worker *worker = NULL;
-    grpc_pollset_work(&exec_ctx, g_pollset, &worker,
+    grpc_pollset_work(&exec_ctx, grpc_polling_entity_pollset(&g_pops), &worker,
                       gpr_now(GPR_CLOCK_MONOTONIC), n_seconds_time(20));
     gpr_mu_unlock(g_mu);
     grpc_exec_ctx_finish(&exec_ctx);
@@ -132,8 +132,8 @@
   gpr_free(host);
 }
 
-static void destroy_pollset(grpc_exec_ctx *exec_ctx, void *p, bool success) {
-  grpc_pollset_destroy(p);
+static void destroy_pops(grpc_exec_ctx *exec_ctx, void *p, bool success) {
+  grpc_pollset_destroy(grpc_polling_entity_pollset(p));
 }
 
 int main(int argc, char **argv) {
@@ -180,19 +180,21 @@
   grpc_test_init(argc, argv);
   grpc_init();
   grpc_httpcli_context_init(&g_context);
-  g_pollset = gpr_malloc(grpc_pollset_size());
-  grpc_pollset_init(g_pollset, &g_mu);
+  grpc_pollset *pollset = gpr_malloc(grpc_pollset_size());
+  grpc_pollset_init(pollset, &g_mu);
+  g_pops = grpc_polling_entity_create_from_pollset(pollset);
 
   test_get(port);
   test_post(port);
 
   grpc_httpcli_context_destroy(&g_context);
-  grpc_closure_init(&destroyed, destroy_pollset, g_pollset);
-  grpc_pollset_shutdown(&exec_ctx, g_pollset, &destroyed);
+  grpc_closure_init(&destroyed, destroy_pops, &g_pops);
+  grpc_pollset_shutdown(&exec_ctx, grpc_polling_entity_pollset(&g_pops),
+                        &destroyed);
   grpc_exec_ctx_finish(&exec_ctx);
   grpc_shutdown();
 
-  gpr_free(g_pollset);
+  gpr_free(grpc_polling_entity_pollset(&g_pops));
 
   gpr_subprocess_destroy(server);
 
diff --git a/test/core/http/httpscli_test.c b/test/core/http/httpscli_test.c
index d807336..1b0bc60 100644
--- a/test/core/http/httpscli_test.c
+++ b/test/core/http/httpscli_test.c
@@ -48,7 +48,7 @@
 static int g_done = 0;
 static grpc_httpcli_context g_context;
 static gpr_mu *g_mu;
-static grpc_pollset *g_pollset;
+static grpc_polling_entity g_pops;
 
 static gpr_timespec n_seconds_time(int seconds) {
   return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(seconds);
@@ -66,7 +66,7 @@
   GPR_ASSERT(0 == memcmp(expect, response->body, response->body_length));
   gpr_mu_lock(g_mu);
   g_done = 1;
-  grpc_pollset_kick(g_pollset, NULL);
+  grpc_pollset_kick(grpc_polling_entity_pollset(&g_pops), NULL);
   gpr_mu_unlock(g_mu);
 }
 
@@ -87,12 +87,12 @@
   req.http.path = "/get";
   req.handshaker = &grpc_httpcli_ssl;
 
-  grpc_httpcli_get(&exec_ctx, &g_context, g_pollset, &req, n_seconds_time(15),
+  grpc_httpcli_get(&exec_ctx, &g_context, &g_pops, &req, n_seconds_time(15),
                    on_finish, (void *)42);
   gpr_mu_lock(g_mu);
   while (!g_done) {
     grpc_pollset_worker *worker = NULL;
-    grpc_pollset_work(&exec_ctx, g_pollset, &worker,
+    grpc_pollset_work(&exec_ctx, grpc_polling_entity_pollset(&g_pops), &worker,
                       gpr_now(GPR_CLOCK_MONOTONIC), n_seconds_time(20));
     gpr_mu_unlock(g_mu);
     grpc_exec_ctx_finish(&exec_ctx);
@@ -119,12 +119,12 @@
   req.http.path = "/post";
   req.handshaker = &grpc_httpcli_ssl;
 
-  grpc_httpcli_post(&exec_ctx, &g_context, g_pollset, &req, "hello", 5,
+  grpc_httpcli_post(&exec_ctx, &g_context, &g_pops, &req, "hello", 5,
                     n_seconds_time(15), on_finish, (void *)42);
   gpr_mu_lock(g_mu);
   while (!g_done) {
     grpc_pollset_worker *worker = NULL;
-    grpc_pollset_work(&exec_ctx, g_pollset, &worker,
+    grpc_pollset_work(&exec_ctx, grpc_polling_entity_pollset(&g_pops), &worker,
                       gpr_now(GPR_CLOCK_MONOTONIC), n_seconds_time(20));
     gpr_mu_unlock(g_mu);
     grpc_exec_ctx_finish(&exec_ctx);
@@ -134,8 +134,8 @@
   gpr_free(host);
 }
 
-static void destroy_pollset(grpc_exec_ctx *exec_ctx, void *p, bool success) {
-  grpc_pollset_destroy(p);
+static void destroy_pops(grpc_exec_ctx *exec_ctx, void *p, bool success) {
+  grpc_pollset_destroy(grpc_polling_entity_pollset(p));
 }
 
 int main(int argc, char **argv) {
@@ -183,19 +183,21 @@
   grpc_test_init(argc, argv);
   grpc_init();
   grpc_httpcli_context_init(&g_context);
-  g_pollset = gpr_malloc(grpc_pollset_size());
-  grpc_pollset_init(g_pollset, &g_mu);
+  grpc_pollset *pollset = gpr_malloc(grpc_pollset_size());
+  grpc_pollset_init(pollset, &g_mu);
+  g_pops = grpc_polling_entity_create_from_pollset(pollset);
 
   test_get(port);
   test_post(port);
 
   grpc_httpcli_context_destroy(&g_context);
-  grpc_closure_init(&destroyed, destroy_pollset, g_pollset);
-  grpc_pollset_shutdown(&exec_ctx, g_pollset, &destroyed);
+  grpc_closure_init(&destroyed, destroy_pops, &g_pops);
+  grpc_pollset_shutdown(&exec_ctx, grpc_polling_entity_pollset(&g_pops),
+                        &destroyed);
   grpc_exec_ctx_finish(&exec_ctx);
   grpc_shutdown();
 
-  gpr_free(g_pollset);
+  gpr_free(grpc_polling_entity_pollset(&g_pops));
 
   gpr_subprocess_destroy(server);
 
diff --git a/test/core/iomgr/fd_posix_test.c b/test/core/iomgr/fd_posix_test.c
index f97f337..0630f1d 100644
--- a/test/core/iomgr/fd_posix_test.c
+++ b/test/core/iomgr/fd_posix_test.c
@@ -52,6 +52,7 @@
 
 #include "src/core/lib/iomgr/ev_posix.h"
 #include "src/core/lib/iomgr/iomgr.h"
+#include "src/core/lib/iomgr/socket_utils_posix.h"
 #include "test/core/util/test_config.h"
 
 static gpr_mu *g_mu;
@@ -68,17 +69,15 @@
                                struct sockaddr_in *sin) {
   int fd;
   int one = 1;
-  int buf_size = BUF_SIZE;
+  int buffer_size_bytes = BUF_SIZE;
   int flags;
 
   fd = socket(AF_INET, SOCK_STREAM, 0);
   setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
   /* Reset the size of socket send buffer to the minimal value to facilitate
      buffer filling up and triggering notify_on_write  */
-  GPR_ASSERT(
-      setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &buf_size, sizeof(buf_size)) != -1);
-  GPR_ASSERT(
-      setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &buf_size, sizeof(buf_size)) != -1);
+  GPR_ASSERT(grpc_set_socket_sndbuf(fd, buffer_size_bytes));
+  GPR_ASSERT(grpc_set_socket_rcvbuf(fd, buffer_size_bytes));
   /* Make fd non-blocking */
   flags = fcntl(fd, F_GETFL, 0);
   GPR_ASSERT(fcntl(fd, F_SETFL, flags | O_NONBLOCK) == 0);
diff --git a/test/core/json/fuzzer.c b/test/core/json/fuzzer.c
index e94b41c..26c5c25 100644
--- a/test/core/json/fuzzer.c
+++ b/test/core/json/fuzzer.c
@@ -31,6 +31,7 @@
  *
  */
 
+#include <stdbool.h>
 #include <stdint.h>
 #include <string.h>
 
@@ -40,6 +41,9 @@
 #include "src/core/lib/json/json.h"
 #include "test/core/util/memory_counters.h"
 
+bool squelch = true;
+bool leak_check = true;
+
 int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
   char *s;
   struct grpc_memory_counters counters;
diff --git a/test/core/nanopb/fuzzer_response.c b/test/core/nanopb/fuzzer_response.c
index b4e3860..21a5d7b 100644
--- a/test/core/nanopb/fuzzer_response.c
+++ b/test/core/nanopb/fuzzer_response.c
@@ -38,6 +38,9 @@
 
 #include "src/core/ext/lb_policy/grpclb/load_balancer_api.h"
 
+bool squelch = true;
+bool leak_check = true;
+
 int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
   gpr_slice slice = gpr_slice_from_copied_buffer((const char *)data, size);
   grpc_grpclb_response *response;
diff --git a/test/core/nanopb/fuzzer_serverlist.c b/test/core/nanopb/fuzzer_serverlist.c
index d4ec74f..df2044d 100644
--- a/test/core/nanopb/fuzzer_serverlist.c
+++ b/test/core/nanopb/fuzzer_serverlist.c
@@ -38,6 +38,9 @@
 
 #include "src/core/ext/lb_policy/grpclb/load_balancer_api.h"
 
+bool squelch = true;
+bool leak_check = true;
+
 int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
   gpr_slice slice = gpr_slice_from_copied_buffer((const char *)data, size);
   grpc_grpclb_serverlist *serverlist;
diff --git a/test/core/security/oauth2_utils.c b/test/core/security/oauth2_utils.c
index 80d21cc..cb27a1a 100644
--- a/test/core/security/oauth2_utils.c
+++ b/test/core/security/oauth2_utils.c
@@ -46,7 +46,7 @@
 
 typedef struct {
   gpr_mu *mu;
-  grpc_pollset *pollset;
+  grpc_polling_entity pops;
   int is_done;
   char *token;
 } oauth2_request;
@@ -70,7 +70,7 @@
   gpr_mu_lock(request->mu);
   request->is_done = 1;
   request->token = token;
-  grpc_pollset_kick(request->pollset, NULL);
+  grpc_pollset_kick(grpc_polling_entity_pollset(&request->pops), NULL);
   gpr_mu_unlock(request->mu);
 }
 
@@ -83,30 +83,30 @@
   grpc_closure do_nothing_closure;
   grpc_auth_metadata_context null_ctx = {"", "", NULL, NULL};
 
-  request.pollset = gpr_malloc(grpc_pollset_size());
-  grpc_pollset_init(request.pollset, &request.mu);
+  grpc_pollset *pollset = gpr_malloc(grpc_pollset_size());
+  grpc_pollset_init(pollset, &request.mu);
+  request.pops = grpc_polling_entity_create_from_pollset(pollset);
   request.is_done = 0;
 
   grpc_closure_init(&do_nothing_closure, do_nothing, NULL);
 
-  grpc_call_credentials_get_request_metadata(&exec_ctx, creds, request.pollset,
-                                             null_ctx, on_oauth2_response,
-                                             &request);
+  grpc_call_credentials_get_request_metadata(
+      &exec_ctx, creds, &request.pops, null_ctx, on_oauth2_response, &request);
 
   grpc_exec_ctx_finish(&exec_ctx);
 
   gpr_mu_lock(request.mu);
   while (!request.is_done) {
     grpc_pollset_worker *worker = NULL;
-    grpc_pollset_work(&exec_ctx, request.pollset, &worker,
-                      gpr_now(GPR_CLOCK_MONOTONIC),
+    grpc_pollset_work(&exec_ctx, grpc_polling_entity_pollset(&request.pops),
+                      &worker, gpr_now(GPR_CLOCK_MONOTONIC),
                       gpr_inf_future(GPR_CLOCK_MONOTONIC));
   }
   gpr_mu_unlock(request.mu);
 
-  grpc_pollset_shutdown(&exec_ctx, request.pollset, &do_nothing_closure);
+  grpc_pollset_shutdown(&exec_ctx, grpc_polling_entity_pollset(&request.pops),
+                        &do_nothing_closure);
   grpc_exec_ctx_finish(&exec_ctx);
-  grpc_pollset_destroy(request.pollset);
-  gpr_free(request.pollset);
+  gpr_free(grpc_polling_entity_pollset(&request.pops));
   return request.token;
 }
diff --git a/test/core/security/print_google_default_creds_token.c b/test/core/security/print_google_default_creds_token.c
index 1b7036c..07c8c58 100644
--- a/test/core/security/print_google_default_creds_token.c
+++ b/test/core/security/print_google_default_creds_token.c
@@ -48,7 +48,7 @@
 
 typedef struct {
   gpr_mu *mu;
-  grpc_pollset *pollset;
+  grpc_polling_entity pops;
   int is_done;
 } synchronizer;
 
@@ -67,7 +67,7 @@
   }
   gpr_mu_lock(sync->mu);
   sync->is_done = 1;
-  grpc_pollset_kick(sync->pollset, NULL);
+  grpc_pollset_kick(grpc_polling_entity_pollset(&sync->pops), NULL);
   gpr_mu_unlock(sync->mu);
 }
 
@@ -94,19 +94,20 @@
     goto end;
   }
 
-  sync.pollset = gpr_malloc(grpc_pollset_size());
-  grpc_pollset_init(sync.pollset, &sync.mu);
+  grpc_pollset *pollset = gpr_malloc(grpc_pollset_size());
+  grpc_pollset_init(pollset, &sync.mu);
+  sync.pops = grpc_polling_entity_create_from_pollset(pollset);
   sync.is_done = 0;
 
   grpc_call_credentials_get_request_metadata(
       &exec_ctx, ((grpc_composite_channel_credentials *)creds)->call_creds,
-      sync.pollset, context, on_metadata_response, &sync);
+      &sync.pops, context, on_metadata_response, &sync);
 
   gpr_mu_lock(sync.mu);
   while (!sync.is_done) {
     grpc_pollset_worker *worker = NULL;
-    grpc_pollset_work(&exec_ctx, sync.pollset, &worker,
-                      gpr_now(GPR_CLOCK_MONOTONIC),
+    grpc_pollset_work(&exec_ctx, grpc_polling_entity_pollset(&sync.pops),
+                      &worker, gpr_now(GPR_CLOCK_MONOTONIC),
                       gpr_inf_future(GPR_CLOCK_MONOTONIC));
     gpr_mu_unlock(sync.mu);
     grpc_exec_ctx_flush(&exec_ctx);
@@ -117,7 +118,7 @@
   grpc_exec_ctx_finish(&exec_ctx);
 
   grpc_channel_credentials_release(creds);
-  gpr_free(sync.pollset);
+  gpr_free(grpc_polling_entity_pollset(&sync.pops));
 
 end:
   gpr_cmdline_destroy(cl);
diff --git a/test/core/surface/lame_client_test.c b/test/core/surface/lame_client_test.c
index 12fa9de..edd5056 100644
--- a/test/core/surface/lame_client_test.c
+++ b/test/core/surface/lame_client_test.c
@@ -49,7 +49,7 @@
 
 void verify_connectivity(grpc_exec_ctx *exec_ctx, void *arg, bool success) {
   grpc_transport_op *op = arg;
-  GPR_ASSERT(GRPC_CHANNEL_FATAL_FAILURE == *op->connectivity_state);
+  GPR_ASSERT(GRPC_CHANNEL_SHUTDOWN == *op->connectivity_state);
   GPR_ASSERT(success);
 }
 
@@ -104,7 +104,7 @@
 
   test_transport_op(chan);
 
-  GPR_ASSERT(GRPC_CHANNEL_FATAL_FAILURE ==
+  GPR_ASSERT(GRPC_CHANNEL_SHUTDOWN ==
              grpc_channel_check_connectivity_state(chan, 0));
 
   cq = grpc_completion_queue_create(NULL);
@@ -115,6 +115,7 @@
   GPR_ASSERT(call);
   cqv = cq_verifier_create(cq);
 
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_SEND_INITIAL_METADATA;
   op->data.send_initial_metadata.count = 0;
@@ -133,6 +134,7 @@
   cq_expect_completion(cqv, tag(1), 0);
   cq_verify(cqv);
 
+  memset(ops, 0, sizeof(ops));
   op = ops;
   op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
   op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
diff --git a/test/core/surface/public_headers_must_be_c89.c b/test/core/surface/public_headers_must_be_c89.c
index fd6ff2c..3eeb55d 100644
--- a/test/core/surface/public_headers_must_be_c89.c
+++ b/test/core/surface/public_headers_must_be_c89.c
@@ -36,7 +36,6 @@
 #include <grpc/census.h>
 #include <grpc/compression.h>
 #include <grpc/grpc.h>
-#include <grpc/grpc_cronet.h>
 #include <grpc/grpc_security.h>
 #include <grpc/grpc_security_constants.h>
 #include <grpc/impl/codegen/alloc.h>
diff --git a/test/core/transport/chttp2/hpack_parser_fuzzer_test.c b/test/core/transport/chttp2/hpack_parser_fuzzer_test.c
index e41eda8..1e3d2d3 100644
--- a/test/core/transport/chttp2/hpack_parser_fuzzer_test.c
+++ b/test/core/transport/chttp2/hpack_parser_fuzzer_test.c
@@ -40,12 +40,15 @@
 
 #include "src/core/ext/transport/chttp2/transport/hpack_parser.h"
 
+bool squelch = true;
+bool leak_check = true;
+
 static void onhdr(void *ud, grpc_mdelem *md) { GRPC_MDELEM_UNREF(md); }
 static void dont_log(gpr_log_func_args *args) {}
 
 int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
   grpc_test_only_set_metadata_hash_seed(0);
-  gpr_set_log_function(dont_log);
+  if (squelch) gpr_set_log_function(dont_log);
   grpc_init();
   grpc_chttp2_hpack_parser parser;
   grpc_chttp2_hpack_parser_init(&parser);
diff --git a/test/core/transport/connectivity_state_test.c b/test/core/transport/connectivity_state_test.c
index 6bb7c3b..38dea01 100644
--- a/test/core/transport/connectivity_state_test.c
+++ b/test/core/transport/connectivity_state_test.c
@@ -66,9 +66,8 @@
   GPR_ASSERT(
       0 == strcmp(grpc_connectivity_state_name(GRPC_CHANNEL_TRANSIENT_FAILURE),
                   "TRANSIENT_FAILURE"));
-  GPR_ASSERT(0 ==
-             strcmp(grpc_connectivity_state_name(GRPC_CHANNEL_FATAL_FAILURE),
-                    "FATAL_FAILURE"));
+  GPR_ASSERT(0 == strcmp(grpc_connectivity_state_name(GRPC_CHANNEL_SHUTDOWN),
+                         "FATAL_FAILURE"));
 }
 
 static void test_check(void) {
@@ -119,26 +118,26 @@
   GPR_ASSERT(g_counter == 0);
   grpc_connectivity_state_destroy(&exec_ctx, &tracker);
   grpc_exec_ctx_finish(&exec_ctx);
-  GPR_ASSERT(state == GRPC_CHANNEL_FATAL_FAILURE);
+  GPR_ASSERT(state == GRPC_CHANNEL_SHUTDOWN);
   GPR_ASSERT(g_counter == 1);
 }
 
 static void test_subscribe_with_failure_then_destroy(void) {
   grpc_connectivity_state_tracker tracker;
   grpc_closure *closure = grpc_closure_create(must_fail, THE_ARG);
-  grpc_connectivity_state state = GRPC_CHANNEL_FATAL_FAILURE;
+  grpc_connectivity_state state = GRPC_CHANNEL_SHUTDOWN;
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
   gpr_log(GPR_DEBUG, "test_subscribe_with_failure_then_destroy");
   g_counter = 0;
-  grpc_connectivity_state_init(&tracker, GRPC_CHANNEL_FATAL_FAILURE, "xxx");
+  grpc_connectivity_state_init(&tracker, GRPC_CHANNEL_SHUTDOWN, "xxx");
   GPR_ASSERT(0 == grpc_connectivity_state_notify_on_state_change(
                       &exec_ctx, &tracker, &state, closure));
   grpc_exec_ctx_flush(&exec_ctx);
-  GPR_ASSERT(state == GRPC_CHANNEL_FATAL_FAILURE);
+  GPR_ASSERT(state == GRPC_CHANNEL_SHUTDOWN);
   GPR_ASSERT(g_counter == 0);
   grpc_connectivity_state_destroy(&exec_ctx, &tracker);
   grpc_exec_ctx_finish(&exec_ctx);
-  GPR_ASSERT(state == GRPC_CHANNEL_FATAL_FAILURE);
+  GPR_ASSERT(state == GRPC_CHANNEL_SHUTDOWN);
   GPR_ASSERT(g_counter == 1);
 }
 
diff --git a/test/core/util/one_corpus_entry_fuzzer.c b/test/core/util/one_corpus_entry_fuzzer.c
index 41f9558..be32a8a 100644
--- a/test/core/util/one_corpus_entry_fuzzer.c
+++ b/test/core/util/one_corpus_entry_fuzzer.c
@@ -31,13 +31,20 @@
  *
  */
 
+#include <stdbool.h>
+
 #include <grpc/support/log.h>
 #include "src/core/lib/support/load_file.h"
 
 extern int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size);
 
+extern bool squelch;
+extern bool leak_check;
+
 int main(int argc, char **argv) {
   int ok = 0;
+  squelch = false;
+  leak_check = false;
   gpr_slice buffer = gpr_load_file(argv[1], 0, &ok);
   GPR_ASSERT(ok);
   LLVMFuzzerTestOneInput(GPR_SLICE_START_PTR(buffer), GPR_SLICE_LENGTH(buffer));
diff --git a/test/core/util/port_server_client.c b/test/core/util/port_server_client.c
index 84e9054..f924d55 100644
--- a/test/core/util/port_server_client.c
+++ b/test/core/util/port_server_client.c
@@ -51,14 +51,15 @@
 
 typedef struct freereq {
   gpr_mu *mu;
-  grpc_pollset *pollset;
+  grpc_polling_entity pops;
   int done;
 } freereq;
 
-static void destroy_pollset_and_shutdown(grpc_exec_ctx *exec_ctx, void *p,
-                                         bool success) {
-  grpc_pollset_destroy(p);
-  gpr_free(p);
+static void destroy_pops_and_shutdown(grpc_exec_ctx *exec_ctx, void *p,
+                                      bool success) {
+  grpc_pollset *pollset = grpc_polling_entity_pollset(p);
+  grpc_pollset_destroy(pollset);
+  gpr_free(pollset);
   grpc_shutdown();
 }
 
@@ -67,7 +68,7 @@
   freereq *pr = arg;
   gpr_mu_lock(pr->mu);
   pr->done = 1;
-  grpc_pollset_kick(pr->pollset, NULL);
+  grpc_pollset_kick(grpc_polling_entity_pollset(&pr->pops), NULL);
   gpr_mu_unlock(pr->mu);
 }
 
@@ -84,23 +85,23 @@
   memset(&pr, 0, sizeof(pr));
   memset(&req, 0, sizeof(req));
 
-  pr.pollset = gpr_malloc(grpc_pollset_size());
-  grpc_pollset_init(pr.pollset, &pr.mu);
-  shutdown_closure =
-      grpc_closure_create(destroy_pollset_and_shutdown, pr.pollset);
+  grpc_pollset *pollset = gpr_malloc(grpc_pollset_size());
+  grpc_pollset_init(pollset, &pr.mu);
+  pr.pops = grpc_polling_entity_create_from_pollset(pollset);
+  shutdown_closure = grpc_closure_create(destroy_pops_and_shutdown, &pr.pops);
 
   req.host = server;
   gpr_asprintf(&path, "/drop/%d", port);
   req.http.path = path;
 
   grpc_httpcli_context_init(&context);
-  grpc_httpcli_get(&exec_ctx, &context, pr.pollset, &req,
+  grpc_httpcli_get(&exec_ctx, &context, &pr.pops, &req,
                    GRPC_TIMEOUT_SECONDS_TO_DEADLINE(10), freed_port_from_server,
                    &pr);
   gpr_mu_lock(pr.mu);
   while (!pr.done) {
     grpc_pollset_worker *worker = NULL;
-    grpc_pollset_work(&exec_ctx, pr.pollset, &worker,
+    grpc_pollset_work(&exec_ctx, grpc_polling_entity_pollset(&pr.pops), &worker,
                       gpr_now(GPR_CLOCK_MONOTONIC),
                       GRPC_TIMEOUT_SECONDS_TO_DEADLINE(1));
   }
@@ -108,14 +109,15 @@
 
   grpc_httpcli_context_destroy(&context);
   grpc_exec_ctx_finish(&exec_ctx);
-  grpc_pollset_shutdown(&exec_ctx, pr.pollset, shutdown_closure);
+  grpc_pollset_shutdown(&exec_ctx, grpc_polling_entity_pollset(&pr.pops),
+                        shutdown_closure);
   grpc_exec_ctx_finish(&exec_ctx);
   gpr_free(path);
 }
 
 typedef struct portreq {
   gpr_mu *mu;
-  grpc_pollset *pollset;
+  grpc_polling_entity pops;
   int port;
   int retries;
   char *server;
@@ -151,7 +153,7 @@
     pr->retries++;
     req.host = pr->server;
     req.http.path = "/get";
-    grpc_httpcli_get(exec_ctx, pr->ctx, pr->pollset, &req,
+    grpc_httpcli_get(exec_ctx, pr->ctx, &pr->pops, &req,
                      GRPC_TIMEOUT_SECONDS_TO_DEADLINE(10), got_port_from_server,
                      pr);
     return;
@@ -165,7 +167,7 @@
   GPR_ASSERT(port > 1024);
   gpr_mu_lock(pr->mu);
   pr->port = port;
-  grpc_pollset_kick(pr->pollset, NULL);
+  grpc_pollset_kick(grpc_polling_entity_pollset(&pr->pops), NULL);
   gpr_mu_unlock(pr->mu);
 }
 
@@ -180,10 +182,10 @@
 
   memset(&pr, 0, sizeof(pr));
   memset(&req, 0, sizeof(req));
-  pr.pollset = gpr_malloc(grpc_pollset_size());
-  grpc_pollset_init(pr.pollset, &pr.mu);
-  shutdown_closure =
-      grpc_closure_create(destroy_pollset_and_shutdown, pr.pollset);
+  grpc_pollset *pollset = gpr_malloc(grpc_pollset_size());
+  grpc_pollset_init(pollset, &pr.mu);
+  pr.pops = grpc_polling_entity_create_from_pollset(pollset);
+  shutdown_closure = grpc_closure_create(destroy_pops_and_shutdown, &pr.pops);
   pr.port = -1;
   pr.server = server;
   pr.ctx = &context;
@@ -192,21 +194,22 @@
   req.http.path = "/get";
 
   grpc_httpcli_context_init(&context);
-  grpc_httpcli_get(&exec_ctx, &context, pr.pollset, &req,
+  grpc_httpcli_get(&exec_ctx, &context, &pr.pops, &req,
                    GRPC_TIMEOUT_SECONDS_TO_DEADLINE(10), got_port_from_server,
                    &pr);
   grpc_exec_ctx_finish(&exec_ctx);
   gpr_mu_lock(pr.mu);
   while (pr.port == -1) {
     grpc_pollset_worker *worker = NULL;
-    grpc_pollset_work(&exec_ctx, pr.pollset, &worker,
+    grpc_pollset_work(&exec_ctx, grpc_polling_entity_pollset(&pr.pops), &worker,
                       gpr_now(GPR_CLOCK_MONOTONIC),
                       GRPC_TIMEOUT_SECONDS_TO_DEADLINE(1));
   }
   gpr_mu_unlock(pr.mu);
 
   grpc_httpcli_context_destroy(&context);
-  grpc_pollset_shutdown(&exec_ctx, pr.pollset, shutdown_closure);
+  grpc_pollset_shutdown(&exec_ctx, grpc_polling_entity_pollset(&pr.pops),
+                        shutdown_closure);
   grpc_exec_ctx_finish(&exec_ctx);
 
   return pr.port;
diff --git a/test/cpp/end2end/async_end2end_test.cc b/test/cpp/end2end/async_end2end_test.cc
index 45f5eb1..b839801 100644
--- a/test/cpp/end2end/async_end2end_test.cc
+++ b/test/cpp/end2end/async_end2end_test.cc
@@ -819,7 +819,7 @@
   EXPECT_TRUE(srv_ctx.IsCancelled());
 
   response_reader->Finish(&recv_response, &recv_status, tag(4));
-  Verifier(GetParam().disable_blocking).Expect(4, false).Verify(cq_.get());
+  Verifier(GetParam().disable_blocking).Expect(4, true).Verify(cq_.get());
 
   EXPECT_EQ(StatusCode::CANCELLED, recv_status.error_code());
 }
@@ -881,7 +881,7 @@
       stub->AsyncUnimplemented(&cli_ctx, send_request, cq_.get()));
 
   response_reader->Finish(&recv_response, &recv_status, tag(4));
-  Verifier(GetParam().disable_blocking).Expect(4, false).Verify(cq_.get());
+  Verifier(GetParam().disable_blocking).Expect(4, true).Verify(cq_.get());
 
   EXPECT_EQ(StatusCode::UNIMPLEMENTED, recv_status.error_code());
   EXPECT_EQ("", recv_status.error_message());
@@ -1026,9 +1026,7 @@
 
     // Client will see the cancellation
     cli_stream->Finish(&recv_status, tag(10));
-    // TODO(sreek): The expectation here should be true. This is a bug (github
-    // issue #4972)
-    Verifier(GetParam().disable_blocking).Expect(10, false).Verify(cq_.get());
+    Verifier(GetParam().disable_blocking).Expect(10, true).Verify(cq_.get());
     EXPECT_FALSE(recv_status.ok());
     EXPECT_EQ(::grpc::StatusCode::CANCELLED, recv_status.error_code());
   }
diff --git a/test/cpp/end2end/end2end_test.cc b/test/cpp/end2end/end2end_test.cc
index f52aa52..e3667cf 100644
--- a/test/cpp/end2end/end2end_test.cc
+++ b/test/cpp/end2end/end2end_test.cc
@@ -1014,6 +1014,16 @@
   SendRpc(stub_.get(), 1, false);
 }
 
+TEST_P(ProxyEnd2endTest, SimpleRpcWithEmptyMessages) {
+  ResetStub();
+  EchoRequest request;
+  EchoResponse response;
+
+  ClientContext context;
+  Status s = stub_->Echo(&context, request, &response);
+  EXPECT_TRUE(s.ok());
+}
+
 TEST_P(ProxyEnd2endTest, MultipleRpcs) {
   ResetStub();
   std::vector<std::thread*> threads;
diff --git a/test/cpp/end2end/generic_end2end_test.cc b/test/cpp/end2end/generic_end2end_test.cc
index d0cf6ae..57efa5f 100644
--- a/test/cpp/end2end/generic_end2end_test.cc
+++ b/test/cpp/end2end/generic_end2end_test.cc
@@ -38,7 +38,7 @@
 #include <grpc++/create_channel.h>
 #include <grpc++/generic/async_generic_service.h>
 #include <grpc++/generic/generic_stub.h>
-#include <grpc++/impl/proto_utils.h>
+#include <grpc++/impl/codegen/proto_utils.h>
 #include <grpc++/server.h>
 #include <grpc++/server_builder.h>
 #include <grpc++/server_context.h>
diff --git a/test/cpp/end2end/proto_server_reflection_test.cc b/test/cpp/end2end/proto_server_reflection_test.cc
new file mode 100644
index 0000000..f8fc39b
--- /dev/null
+++ b/test/cpp/end2end/proto_server_reflection_test.cc
@@ -0,0 +1,166 @@
+/*
+ *
+ * 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 <google/protobuf/descriptor.h>
+#include <grpc++/channel.h>
+#include <grpc++/client_context.h>
+#include <grpc++/create_channel.h>
+#include <grpc++/ext/proto_server_reflection_plugin.h>
+#include <grpc++/security/credentials.h>
+#include <grpc++/security/server_credentials.h>
+#include <grpc++/server.h>
+#include <grpc++/server_builder.h>
+#include <grpc++/server_context.h>
+#include <grpc/grpc.h>
+#include <gtest/gtest.h>
+
+#include "src/proto/grpc/testing/echo.grpc.pb.h"
+#include "test/core/util/port.h"
+#include "test/core/util/test_config.h"
+#include "test/cpp/end2end/test_service_impl.h"
+#include "test/cpp/util/proto_reflection_descriptor_database.h"
+
+namespace grpc {
+namespace testing {
+
+class ProtoServerReflectionTest : public ::testing::Test {
+ public:
+  ProtoServerReflectionTest() {}
+
+  void SetUp() GRPC_OVERRIDE {
+    port_ = grpc_pick_unused_port_or_die();
+    ref_desc_pool_ = google::protobuf::DescriptorPool::generated_pool();
+
+    ServerBuilder builder;
+    grpc::string server_address = "localhost:" + to_string(port_);
+    builder.AddListeningPort(server_address, InsecureServerCredentials());
+    server_ = builder.BuildAndStart();
+  }
+
+  void ResetStub() {
+    string target = "dns:localhost:" + to_string(port_);
+    std::shared_ptr<Channel> channel =
+        CreateChannel(target, InsecureChannelCredentials());
+    stub_ = grpc::testing::EchoTestService::NewStub(channel);
+    desc_db_.reset(new ProtoReflectionDescriptorDatabase(channel));
+    desc_pool_.reset(new google::protobuf::DescriptorPool(desc_db_.get()));
+  }
+
+  string to_string(const int number) {
+    std::stringstream strs;
+    strs << number;
+    return strs.str();
+  }
+
+  void CompareService(const grpc::string& service) {
+    const google::protobuf::ServiceDescriptor* service_desc =
+        desc_pool_->FindServiceByName(service);
+    const google::protobuf::ServiceDescriptor* ref_service_desc =
+        ref_desc_pool_->FindServiceByName(service);
+    EXPECT_TRUE(service_desc != nullptr);
+    EXPECT_TRUE(ref_service_desc != nullptr);
+    EXPECT_EQ(service_desc->DebugString(), ref_service_desc->DebugString());
+
+    const google::protobuf::FileDescriptor* file_desc = service_desc->file();
+    if (known_files_.find(file_desc->package() + "/" + file_desc->name()) !=
+        known_files_.end()) {
+      EXPECT_EQ(file_desc->DebugString(),
+                ref_service_desc->file()->DebugString());
+      known_files_.insert(file_desc->package() + "/" + file_desc->name());
+    }
+
+    for (int i = 0; i < service_desc->method_count(); ++i) {
+      CompareMethod(service_desc->method(i)->full_name());
+    }
+  }
+
+  void CompareMethod(const grpc::string& method) {
+    const google::protobuf::MethodDescriptor* method_desc =
+        desc_pool_->FindMethodByName(method);
+    const google::protobuf::MethodDescriptor* ref_method_desc =
+        ref_desc_pool_->FindMethodByName(method);
+    EXPECT_TRUE(method_desc != nullptr);
+    EXPECT_TRUE(ref_method_desc != nullptr);
+    EXPECT_EQ(method_desc->DebugString(), ref_method_desc->DebugString());
+
+    CompareType(method_desc->input_type()->full_name());
+    CompareType(method_desc->output_type()->full_name());
+  }
+
+  void CompareType(const grpc::string& type) {
+    if (known_types_.find(type) != known_types_.end()) {
+      return;
+    }
+
+    const google::protobuf::Descriptor* desc =
+        desc_pool_->FindMessageTypeByName(type);
+    const google::protobuf::Descriptor* ref_desc =
+        ref_desc_pool_->FindMessageTypeByName(type);
+    EXPECT_TRUE(desc != nullptr);
+    EXPECT_TRUE(ref_desc != nullptr);
+    EXPECT_EQ(desc->DebugString(), ref_desc->DebugString());
+  }
+
+ protected:
+  std::unique_ptr<Server> server_;
+  std::unique_ptr<grpc::testing::EchoTestService::Stub> stub_;
+  std::unique_ptr<ProtoReflectionDescriptorDatabase> desc_db_;
+  std::unique_ptr<google::protobuf::DescriptorPool> desc_pool_;
+  std::unordered_set<string> known_files_;
+  std::unordered_set<string> known_types_;
+  const google::protobuf::DescriptorPool* ref_desc_pool_;
+  int port_;
+  reflection::ProtoServerReflectionPlugin plugin_;
+};
+
+TEST_F(ProtoServerReflectionTest, CheckResponseWithLocalDescriptorPool) {
+  ResetStub();
+
+  std::vector<std::string> services;
+  desc_db_->GetServices(&services);
+  // The service list has at least one service (reflection servcie).
+  EXPECT_TRUE(services.size() > 0);
+
+  for (auto it = services.begin(); it != services.end(); ++it) {
+    CompareService(*it);
+  }
+}
+
+}  // namespace testing
+}  // namespace grpc
+
+int main(int argc, char** argv) {
+  grpc_test_init(argc, argv);
+  ::testing::InitGoogleTest(&argc, argv);
+  return RUN_ALL_TESTS();
+}
diff --git a/test/cpp/end2end/server_builder_plugin_test.cc b/test/cpp/end2end/server_builder_plugin_test.cc
index 8a74621..1c10950 100644
--- a/test/cpp/end2end/server_builder_plugin_test.cc
+++ b/test/cpp/end2end/server_builder_plugin_test.cc
@@ -61,6 +61,7 @@
     init_server_is_called_ = false;
     finish_is_called_ = false;
     change_arguments_is_called_ = false;
+    register_service_ = false;
   }
 
   grpc::string name() GRPC_OVERRIDE { return PLUGIN_NAME; }
diff --git a/test/cpp/interop/interop_client.cc b/test/cpp/interop/interop_client.cc
index 189e4a8..a0479e8 100644
--- a/test/cpp/interop/interop_client.cc
+++ b/test/cpp/interop/interop_client.cc
@@ -55,8 +55,6 @@
 namespace grpc {
 namespace testing {
 
-static const char* kRandomFile = "test/cpp/interop/rnd.dat";
-
 namespace {
 // The same value is defined by the Java client.
 const std::vector<int> request_stream_sizes = {27182, 8, 1828, 45904};
@@ -67,30 +65,26 @@
 const int kLargeRequestSize = 271828;
 const int kLargeResponseSize = 314159;
 
-CompressionType GetInteropCompressionTypeFromCompressionAlgorithm(
-    grpc_compression_algorithm algorithm) {
-  switch (algorithm) {
-    case GRPC_COMPRESS_NONE:
-      return CompressionType::NONE;
-    case GRPC_COMPRESS_GZIP:
-      return CompressionType::GZIP;
-    case GRPC_COMPRESS_DEFLATE:
-      return CompressionType::DEFLATE;
-    default:
-      GPR_ASSERT(false);
-  }
-}
-
 void NoopChecks(const InteropClientContextInspector& inspector,
                 const SimpleRequest* request, const SimpleResponse* response) {}
 
 void CompressionChecks(const InteropClientContextInspector& inspector,
                        const SimpleRequest* request,
                        const SimpleResponse* response) {
-  GPR_ASSERT(request->response_compression() ==
-             GetInteropCompressionTypeFromCompressionAlgorithm(
-                 inspector.GetCallCompressionAlgorithm()));
-  if (request->response_compression() == NONE) {
+  const grpc_compression_algorithm received_compression =
+      inspector.GetCallCompressionAlgorithm();
+  if (request->request_compressed_response() &&
+      received_compression == GRPC_COMPRESS_NONE) {
+    if (request->request_compressed_response() &&
+        received_compression == GRPC_COMPRESS_NONE) {
+      // Requested some compression, got NONE. This is an error.
+      gpr_log(GPR_ERROR,
+              "Failure: Requested compression but got uncompressed response "
+              "from server.");
+      abort();
+    }
+  }
+  if (!request->request_compressed_response()) {
     GPR_ASSERT(!(inspector.GetMessageFlags() & GRPC_WRITE_INTERNAL_COMPRESS));
   } else if (request->response_type() == PayloadType::COMPRESSABLE) {
     // requested compression and compressable response => results should always
@@ -211,20 +205,22 @@
   custom_checks_fn(inspector, request, response);
 
   // Payload related checks.
-  if (request->response_type() != PayloadType::RANDOM) {
-    GPR_ASSERT(response->payload().type() == request->response_type());
-  }
+  GPR_ASSERT(response->payload().type() == request->response_type());
   switch (response->payload().type()) {
     case PayloadType::COMPRESSABLE:
       GPR_ASSERT(response->payload().body() ==
                  grpc::string(kLargeResponseSize, '\0'));
       break;
     case PayloadType::UNCOMPRESSABLE: {
-      std::ifstream rnd_file(kRandomFile);
-      GPR_ASSERT(rnd_file.good());
-      for (int i = 0; i < kLargeResponseSize; i++) {
-        GPR_ASSERT(response->payload().body()[i] == (char)rnd_file.get());
-      }
+      // We don't really check anything: We can't assert that the payload is
+      // uncompressed because it's the server's prerogative to decide on that,
+      // and different implementations decide differently (ie, Java always
+      // compresses when requested to do so, whereas C core throws away the
+      // compressed payload if the output is larger than the input).
+      // In addition, we don't compare the actual random bytes received because
+      // asserting that data is sent/received properly isn't the purpose of this
+      // test. Moreover, different implementations are also free to use
+      // different sets of random bytes.
     } break;
     default:
       GPR_ASSERT(false);
@@ -341,13 +337,13 @@
 }
 
 bool InteropClient::DoLargeCompressedUnary() {
-  const CompressionType compression_types[] = {NONE, GZIP, DEFLATE};
-  const PayloadType payload_types[] = {COMPRESSABLE, UNCOMPRESSABLE, RANDOM};
+  const bool request_compression[] = {false, true};
+  const PayloadType payload_types[] = {COMPRESSABLE, UNCOMPRESSABLE};
   for (size_t i = 0; i < GPR_ARRAY_SIZE(payload_types); i++) {
-    for (size_t j = 0; j < GPR_ARRAY_SIZE(compression_types); j++) {
+    for (size_t j = 0; j < GPR_ARRAY_SIZE(request_compression); j++) {
       char* log_suffix;
       gpr_asprintf(&log_suffix, "(compression=%s; payload=%s)",
-                   CompressionType_Name(compression_types[j]).c_str(),
+                   request_compression[j] ? "true" : "false",
                    PayloadType_Name(payload_types[i]).c_str());
 
       gpr_log(GPR_DEBUG, "Sending a large compressed unary rpc %s.",
@@ -355,7 +351,7 @@
       SimpleRequest request;
       SimpleResponse response;
       request.set_response_type(payload_types[i]);
-      request.set_response_compression(compression_types[j]);
+      request.set_request_compressed_response(request_compression[j]);
 
       if (!PerformLargeUnary(&request, &response, CompressionChecks)) {
         gpr_log(GPR_ERROR, "Large compressed unary failed %s", log_suffix);
@@ -452,23 +448,23 @@
 }
 
 bool InteropClient::DoResponseCompressedStreaming() {
-  const CompressionType compression_types[] = {NONE, GZIP, DEFLATE};
-  const PayloadType payload_types[] = {COMPRESSABLE, UNCOMPRESSABLE, RANDOM};
+  const bool request_compression[] = {false, true};
+  const PayloadType payload_types[] = {COMPRESSABLE, UNCOMPRESSABLE};
   for (size_t i = 0; i < GPR_ARRAY_SIZE(payload_types); i++) {
-    for (size_t j = 0; j < GPR_ARRAY_SIZE(compression_types); j++) {
+    for (size_t j = 0; j < GPR_ARRAY_SIZE(request_compression); j++) {
       ClientContext context;
       InteropClientContextInspector inspector(context);
       StreamingOutputCallRequest request;
 
       char* log_suffix;
       gpr_asprintf(&log_suffix, "(compression=%s; payload=%s)",
-                   CompressionType_Name(compression_types[j]).c_str(),
+                   request_compression[j] ? "true" : "false",
                    PayloadType_Name(payload_types[i]).c_str());
 
       gpr_log(GPR_DEBUG, "Receiving response streaming rpc %s.", log_suffix);
 
       request.set_response_type(payload_types[i]);
-      request.set_response_compression(compression_types[j]);
+      request.set_request_compressed_response(request_compression[j]);
 
       for (size_t k = 0; k < response_stream_sizes.size(); ++k) {
         ResponseParameters* response_parameter =
@@ -483,37 +479,32 @@
       size_t k = 0;
       while (stream->Read(&response)) {
         // Payload related checks.
-        if (request.response_type() != PayloadType::RANDOM) {
-          GPR_ASSERT(response.payload().type() == request.response_type());
-        }
+        GPR_ASSERT(response.payload().type() == request.response_type());
         switch (response.payload().type()) {
           case PayloadType::COMPRESSABLE:
             GPR_ASSERT(response.payload().body() ==
                        grpc::string(response_stream_sizes[k], '\0'));
             break;
-          case PayloadType::UNCOMPRESSABLE: {
-            std::ifstream rnd_file(kRandomFile);
-            GPR_ASSERT(rnd_file.good());
-            for (int n = 0; n < response_stream_sizes[k]; n++) {
-              GPR_ASSERT(response.payload().body()[n] == (char)rnd_file.get());
-            }
-          } break;
+          case PayloadType::UNCOMPRESSABLE:
+            break;
           default:
             GPR_ASSERT(false);
         }
 
         // Compression related checks.
-        GPR_ASSERT(request.response_compression() ==
-                   GetInteropCompressionTypeFromCompressionAlgorithm(
-                       inspector.GetCallCompressionAlgorithm()));
-        if (request.response_compression() == NONE) {
+        if (request.request_compressed_response()) {
+          GPR_ASSERT(inspector.GetCallCompressionAlgorithm() >
+                     GRPC_COMPRESS_NONE);
+          if (request.response_type() == PayloadType::COMPRESSABLE) {
+            // requested compression and compressable response => results should
+            // always be compressed.
+            GPR_ASSERT(inspector.GetMessageFlags() &
+                       GRPC_WRITE_INTERNAL_COMPRESS);
+          }
+        } else {
+          // requested *no* compression.
           GPR_ASSERT(
               !(inspector.GetMessageFlags() & GRPC_WRITE_INTERNAL_COMPRESS));
-        } else if (request.response_type() == PayloadType::COMPRESSABLE) {
-          // requested compression and compressable response => results should
-          // always be compressed.
-          GPR_ASSERT(inspector.GetMessageFlags() &
-                     GRPC_WRITE_INTERNAL_COMPRESS);
         }
 
         ++k;
diff --git a/test/cpp/interop/server_main.cc b/test/cpp/interop/server_main.cc
index 889874f..bbedda1 100644
--- a/test/cpp/interop/server_main.cc
+++ b/test/cpp/interop/server_main.cc
@@ -110,14 +110,7 @@
   }
 }
 
-bool SetPayload(PayloadType type, int size, Payload* payload) {
-  PayloadType response_type;
-  if (type == PayloadType::RANDOM) {
-    response_type =
-        rand() & 0x1 ? PayloadType::COMPRESSABLE : PayloadType::UNCOMPRESSABLE;
-  } else {
-    response_type = type;
-  }
+bool SetPayload(PayloadType response_type, int size, Payload* payload) {
   payload->set_type(response_type);
   switch (response_type) {
     case PayloadType::COMPRESSABLE: {
@@ -141,18 +134,9 @@
 template <typename RequestType>
 void SetResponseCompression(ServerContext* context,
                             const RequestType& request) {
-  switch (request.response_compression()) {
-    case grpc::testing::NONE:
-      context->set_compression_algorithm(GRPC_COMPRESS_NONE);
-      break;
-    case grpc::testing::GZIP:
-      context->set_compression_algorithm(GRPC_COMPRESS_GZIP);
-      break;
-    case grpc::testing::DEFLATE:
-      context->set_compression_algorithm(GRPC_COMPRESS_DEFLATE);
-      break;
-    default:
-      abort();
+  if (request.request_compressed_response()) {
+    // Any level would do, let's go for HIGH because we are overachievers.
+    context->set_compression_level(GRPC_COMPRESS_LEVEL_HIGH);
   }
 }
 
diff --git a/test/cpp/qps/client_async.cc b/test/cpp/qps/client_async.cc
index c32160a..6ad4c32 100644
--- a/test/cpp/qps/client_async.cc
+++ b/test/cpp/qps/client_async.cc
@@ -42,7 +42,6 @@
 #include <thread>
 #include <vector>
 
-#include <gflags/gflags.h>
 #include <grpc++/alarm.h>
 #include <grpc++/channel.h>
 #include <grpc++/client_context.h>
diff --git a/test/cpp/qps/client_sync.cc b/test/cpp/qps/client_sync.cc
index fb161f7..c88e95b 100644
--- a/test/cpp/qps/client_sync.cc
+++ b/test/cpp/qps/client_sync.cc
@@ -40,7 +40,6 @@
 #include <thread>
 #include <vector>
 
-#include <gflags/gflags.h>
 #include <grpc++/channel.h>
 #include <grpc++/client_context.h>
 #include <grpc++/server.h>
diff --git a/test/cpp/qps/driver.cc b/test/cpp/qps/driver.cc
index 04b2b45..57d8c22 100644
--- a/test/cpp/qps/driver.cc
+++ b/test/cpp/qps/driver.cc
@@ -43,7 +43,6 @@
 #include <grpc/support/alloc.h>
 #include <grpc/support/host_port.h>
 #include <grpc/support/log.h>
-#include <gtest/gtest.h>
 
 #include "src/core/lib/support/env.h"
 #include "src/proto/grpc/testing/services.grpc.pb.h"
diff --git a/test/cpp/qps/parse_json.cc b/test/cpp/qps/parse_json.cc
index df7a62f..be80428 100644
--- a/test/cpp/qps/parse_json.cc
+++ b/test/cpp/qps/parse_json.cc
@@ -31,8 +31,6 @@
  *
  */
 
-#include <grpc++/support/config_protobuf.h>
-
 #include "test/cpp/qps/parse_json.h"
 
 #include <string>
@@ -63,5 +61,20 @@
   GPR_ASSERT(msg->ParseFromString(binary));
 }
 
+grpc::string SerializeJson(const GRPC_CUSTOM_MESSAGE& msg,
+                           const grpc::string& type) {
+  std::unique_ptr<google::protobuf::util::TypeResolver> type_resolver(
+      google::protobuf::util::NewTypeResolverForDescriptorPool(
+          "type.googleapis.com",
+          google::protobuf::DescriptorPool::generated_pool()));
+  grpc::string binary;
+  grpc::string json_string;
+  msg.SerializeToString(&binary);
+  auto status =
+      BinaryToJsonString(type_resolver.get(), type, binary, &json_string);
+  GPR_ASSERT(status.ok());
+  return json_string;
+}
+
 }  // testing
 }  // grpc
diff --git a/test/cpp/qps/parse_json.h b/test/cpp/qps/parse_json.h
index 4b8ca79..ce1821f 100644
--- a/test/cpp/qps/parse_json.h
+++ b/test/cpp/qps/parse_json.h
@@ -34,8 +34,8 @@
 #ifndef TEST_QPS_PARSE_JSON_H
 #define TEST_QPS_PARSE_JSON_H
 
+#include <grpc++/impl/codegen/config_protobuf.h>
 #include <grpc++/support/config.h>
-#include <grpc++/support/config_protobuf.h>
 
 namespace grpc {
 namespace testing {
@@ -43,6 +43,9 @@
 void ParseJson(const grpc::string& json, const grpc::string& type,
                GRPC_CUSTOM_MESSAGE* msg);
 
+grpc::string SerializeJson(const GRPC_CUSTOM_MESSAGE& msg,
+                           const grpc::string& type);
+
 }  // testing
 }  // grpc
 
diff --git a/test/cpp/qps/perf_db_client.cc b/test/cpp/qps/perf_db_client.cc
deleted file mode 100644
index 98efd8c..0000000
--- a/test/cpp/qps/perf_db_client.cc
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- *
- * Copyright 2015, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#include "test/cpp/qps/perf_db_client.h"
-
-namespace grpc {
-namespace testing {
-
-// sets the client and server config information
-void PerfDbClient::setConfigs(const ClientConfig& client_config,
-                              const ServerConfig& server_config) {
-  client_config_ = client_config;
-  server_config_ = server_config;
-}
-
-// sets the QPS
-void PerfDbClient::setQps(double qps) { qps_ = qps; }
-
-// sets the QPS per core
-void PerfDbClient::setQpsPerCore(double qps_per_core) {
-  qps_per_core_ = qps_per_core;
-}
-
-// sets the 50th, 90th, 95th, 99th and 99.9th percentile latency
-void PerfDbClient::setLatencies(double perc_lat_50, double perc_lat_90,
-                                double perc_lat_95, double perc_lat_99,
-                                double perc_lat_99_point_9) {
-  perc_lat_50_ = perc_lat_50;
-  perc_lat_90_ = perc_lat_90;
-  perc_lat_95_ = perc_lat_95;
-  perc_lat_99_ = perc_lat_99;
-  perc_lat_99_point_9_ = perc_lat_99_point_9;
-}
-
-// sets the server and client, user and system times
-void PerfDbClient::setTimes(double server_system_time, double server_user_time,
-                            double client_system_time,
-                            double client_user_time) {
-  server_system_time_ = server_system_time;
-  server_user_time_ = server_user_time;
-  client_system_time_ = client_system_time;
-  client_user_time_ = client_user_time;
-}
-
-// sends the data to the performance database server
-bool PerfDbClient::sendData(std::string hashed_id, std::string test_name,
-                            std::string sys_info, std::string tag) {
-  // Data record request object
-  SingleUserRecordRequest single_user_record_request;
-
-  // setting access token, name of the test and the system information
-  single_user_record_request.set_hashed_id(hashed_id);
-  single_user_record_request.set_test_name(test_name);
-  single_user_record_request.set_sys_info(sys_info);
-  single_user_record_request.set_tag(tag);
-
-  // setting configs
-  *(single_user_record_request.mutable_client_config()) = client_config_;
-  *(single_user_record_request.mutable_server_config()) = server_config_;
-
-  Metrics* metrics = single_user_record_request.mutable_metrics();
-
-  // setting metrcs in data record request
-  if (qps_ != DBL_MIN) {
-    metrics->set_qps(qps_);
-  }
-  if (qps_per_core_ != DBL_MIN) {
-    metrics->set_qps_per_core(qps_per_core_);
-  }
-  if (perc_lat_50_ != DBL_MIN) {
-    metrics->set_perc_lat_50(perc_lat_50_);
-  }
-  if (perc_lat_90_ != DBL_MIN) {
-    metrics->set_perc_lat_90(perc_lat_90_);
-  }
-  if (perc_lat_95_ != DBL_MIN) {
-    metrics->set_perc_lat_95(perc_lat_95_);
-  }
-  if (perc_lat_99_ != DBL_MIN) {
-    metrics->set_perc_lat_99(perc_lat_99_);
-  }
-  if (perc_lat_99_point_9_ != DBL_MIN) {
-    metrics->set_perc_lat_99_point_9(perc_lat_99_point_9_);
-  }
-  if (server_system_time_ != DBL_MIN) {
-    metrics->set_server_system_time(server_system_time_);
-  }
-  if (server_user_time_ != DBL_MIN) {
-    metrics->set_server_user_time(server_user_time_);
-  }
-  if (client_system_time_ != DBL_MIN) {
-    metrics->set_client_system_time(client_system_time_);
-  }
-  if (client_user_time_ != DBL_MIN) {
-    metrics->set_client_user_time(client_user_time_);
-  }
-
-  SingleUserRecordReply single_user_record_reply;
-  ClientContext context;
-
-  Status status = stub_->RecordSingleClientData(
-      &context, single_user_record_request, &single_user_record_reply);
-  if (status.ok()) {
-    return true;  // data sent to database successfully
-  } else {
-    return false;  // error in data sending
-  }
-}
-}  // testing
-}  // grpc
diff --git a/test/cpp/qps/perf_db_client.h b/test/cpp/qps/perf_db_client.h
deleted file mode 100644
index b74c70d..0000000
--- a/test/cpp/qps/perf_db_client.h
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- *
- * Copyright 2015, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#include <cfloat>
-#include <iostream>
-#include <memory>
-#include <string>
-
-#include <grpc++/channel.h>
-#include <grpc++/client_context.h>
-#include <grpc++/create_channel.h>
-#include <grpc++/security/credentials.h>
-#include <grpc++/support/channel_arguments.h>
-#include <grpc/grpc.h>
-#include "src/proto/grpc/testing/perf_db.grpc.pb.h"
-
-namespace grpc {
-namespace testing {
-
-// Manages data sending to performance database server
-class PerfDbClient {
- public:
-  PerfDbClient() {
-    qps_ = DBL_MIN;
-    qps_per_core_ = DBL_MIN;
-    perc_lat_50_ = DBL_MIN;
-    perc_lat_90_ = DBL_MIN;
-    perc_lat_95_ = DBL_MIN;
-    perc_lat_99_ = DBL_MIN;
-    perc_lat_99_point_9_ = DBL_MIN;
-    server_system_time_ = DBL_MIN;
-    server_user_time_ = DBL_MIN;
-    client_system_time_ = DBL_MIN;
-    client_user_time_ = DBL_MIN;
-  }
-
-  void init(std::shared_ptr<Channel> channel) {
-    stub_ = PerfDbTransfer::NewStub(channel);
-  }
-
-  ~PerfDbClient() {}
-
-  // sets the client and server config information
-  void setConfigs(const ClientConfig& client_config,
-                  const ServerConfig& server_config);
-
-  // sets the qps
-  void setQps(double qps);
-
-  // sets the qps per core
-  void setQpsPerCore(double qps_per_core);
-
-  // sets the 50th, 90th, 95th, 99th and 99.9th percentile latency
-  void setLatencies(double perc_lat_50, double perc_lat_90, double perc_lat_95,
-                    double perc_lat_99, double perc_lat_99_point_9);
-
-  // sets the server and client, user and system times
-  void setTimes(double server_system_time, double server_user_time,
-                double client_system_time, double client_user_time);
-
-  // sends the data to the performance database server
-  bool sendData(std::string hashed_id, std::string test_name,
-                std::string sys_info, std::string tag);
-
- private:
-  std::unique_ptr<PerfDbTransfer::Stub> stub_;
-  ClientConfig client_config_;
-  ServerConfig server_config_;
-  double qps_;
-  double qps_per_core_;
-  double perc_lat_50_;
-  double perc_lat_90_;
-  double perc_lat_95_;
-  double perc_lat_99_;
-  double perc_lat_99_point_9_;
-  double server_system_time_;
-  double server_user_time_;
-  double client_system_time_;
-  double client_user_time_;
-};
-
-}  // namespace testing
-}  // namespace grpc
diff --git a/test/cpp/qps/qps_json_driver.cc b/test/cpp/qps/qps_json_driver.cc
index d7642f0..f5d739f 100644
--- a/test/cpp/qps/qps_json_driver.cc
+++ b/test/cpp/qps/qps_json_driver.cc
@@ -34,7 +34,7 @@
 #include <memory>
 #include <set>
 
-#include <grpc++/support/config_protobuf.h>
+#include <grpc++/impl/codegen/config_protobuf.h>
 
 #include <gflags/gflags.h>
 #include <grpc/support/log.h>
diff --git a/test/cpp/qps/report.cc b/test/cpp/qps/report.cc
index 3ae4139..2ec7d86 100644
--- a/test/cpp/qps/report.cc
+++ b/test/cpp/qps/report.cc
@@ -35,11 +35,9 @@
 
 #include <fstream>
 
-#include <google/protobuf/util/json_util.h>
-#include <google/protobuf/util/type_resolver_util.h>
-
 #include <grpc/support/log.h>
 #include "test/cpp/qps/driver.h"
+#include "test/cpp/qps/parse_json.h"
 #include "test/cpp/qps/stats.h"
 
 namespace grpc {
@@ -104,18 +102,8 @@
 }
 
 void JsonReporter::ReportQPS(const ScenarioResult& result) {
-  std::unique_ptr<google::protobuf::util::TypeResolver> type_resolver(
-      google::protobuf::util::NewTypeResolverForDescriptorPool(
-          "type.googleapis.com",
-          google::protobuf::DescriptorPool::generated_pool()));
-  grpc::string binary;
-  grpc::string json_string;
-  result.SerializeToString(&binary);
-  auto status = BinaryToJsonString(
-      type_resolver.get(), "type.googleapis.com/grpc.testing.ScenarioResult",
-      binary, &json_string);
-  GPR_ASSERT(status.ok());
-
+  grpc::string json_string =
+      SerializeJson(result, "type.googleapis.com/grpc.testing.ScenarioResult");
   std::ofstream output_file(report_file_);
   output_file << json_string;
   output_file.close();
diff --git a/test/cpp/qps/report.h b/test/cpp/qps/report.h
index 8f04d84..39cf498 100644
--- a/test/cpp/qps/report.h
+++ b/test/cpp/qps/report.h
@@ -41,7 +41,6 @@
 #include <grpc++/support/config.h>
 
 #include "test/cpp/qps/driver.h"
-#include "test/cpp/qps/perf_db_client.h"
 
 namespace grpc {
 namespace testing {
diff --git a/test/cpp/qps/server_async.cc b/test/cpp/qps/server_async.cc
index 1eddb1d..c9954d0 100644
--- a/test/cpp/qps/server_async.cc
+++ b/test/cpp/qps/server_async.cc
@@ -37,7 +37,6 @@
 #include <mutex>
 #include <thread>
 
-#include <gflags/gflags.h>
 #include <grpc++/generic/async_generic_service.h>
 #include <grpc++/security/server_credentials.h>
 #include <grpc++/server.h>
@@ -48,7 +47,6 @@
 #include <grpc/support/alloc.h>
 #include <grpc/support/host_port.h>
 #include <grpc/support/log.h>
-#include <gtest/gtest.h>
 
 #include "src/proto/grpc/testing/services.grpc.pb.h"
 #include "test/core/util/test_config.h"
diff --git a/test/cpp/qps/server_sync.cc b/test/cpp/qps/server_sync.cc
index 9e64f47..c774985 100644
--- a/test/cpp/qps/server_sync.cc
+++ b/test/cpp/qps/server_sync.cc
@@ -33,7 +33,6 @@
 
 #include <thread>
 
-#include <gflags/gflags.h>
 #include <grpc++/security/server_credentials.h>
 #include <grpc++/server.h>
 #include <grpc++/server_builder.h>
diff --git a/test/cpp/util/byte_buffer_proto_helper.h b/test/cpp/util/byte_buffer_proto_helper.h
index 42cea59..007723c 100644
--- a/test/cpp/util/byte_buffer_proto_helper.h
+++ b/test/cpp/util/byte_buffer_proto_helper.h
@@ -36,8 +36,8 @@
 
 #include <memory>
 
+#include <grpc++/impl/codegen/config_protobuf.h>
 #include <grpc++/support/byte_buffer.h>
-#include <grpc++/support/config_protobuf.h>
 
 namespace grpc {
 namespace testing {
diff --git a/test/cpp/util/cli_call.cc b/test/cpp/util/cli_call.cc
index 99fad7f..98b9d93 100644
--- a/test/cpp/util/cli_call.cc
+++ b/test/cpp/util/cli_call.cc
@@ -86,7 +86,6 @@
   cq.Next(&got_tag, &ok);
   if (!ok) {
     std::cout << "Failed to read response." << std::endl;
-    return Status(StatusCode::INTERNAL, "Failed to read response");
   }
   grpc::Status status;
   call->Finish(&status, tag(5));
@@ -103,6 +102,7 @@
                        slices[i].size());
     }
   }
+
   *server_initial_metadata = ctx.GetServerInitialMetadata();
   *server_trailing_metadata = ctx.GetServerTrailingMetadata();
   return status;
diff --git a/test/cpp/util/grpc_cli.cc b/test/cpp/util/grpc_cli.cc
index 68cf411..c52e48b 100644
--- a/test/cpp/util/grpc_cli.cc
+++ b/test/cpp/util/grpc_cli.cc
@@ -32,32 +32,33 @@
  */
 
 /*
-  A command line tool to talk to any grpc server.
+  A command line tool to talk to a grpc server.
   Example of talking to grpc interop server:
-  1. Prepare request binary file:
-    a. create a text file input.txt, containing the following:
-        response_size: 10
-        payload: {
-          body: "hello world"
-        }
-    b. under grpc/ run
-        protoc --proto_path=src/proto/grpc/testing/ \
-        --encode=grpc.testing.SimpleRequest
-  src/proto/grpc/testing/messages.proto \
-        < input.txt > input.bin
-  2. Start a server
-    make interop_server && bins/opt/interop_server --port=50051
-  3. Run the tool
-    make grpc_cli && bins/opt/grpc_cli call localhost:50051 \
-    /grpc.testing.TestService/UnaryCall --enable_ssl=false \
-    --input_binary_file=input.bin --output_binary_file=output.bin
-  4. Decode response
-    protoc --proto_path=src/proto/grpc/testing/ \
-    --decode=grpc.testing.SimpleResponse src/proto/grpc/testing/messages.proto \
-    < output.bin > output.txt
-  5. Now the text form of response should be in output.txt
-  Optionally, metadata can be passed to server via flag --metadata, e.g.
-    --metadata="MyHeaderKey1:Value1:MyHeaderKey2:Value2"
+  grpc_cli call localhost:50051 UnaryCall src/proto/grpc/testing/test.proto \
+    "response_size:10"  --enable_ssl=false
+
+  Options:
+    1. --proto_path, if your proto file is not under current working directory,
+       use this flag to provide a search root. It should work similar to the
+       counterpart in protoc.
+    2. --metadata specifies metadata to be sent to the server, such as:
+       --metadata="MyHeaderKey1:Value1:MyHeaderKey2:Value2"
+    3. --enable_ssl, whether to use tls.
+    4. --use_auth, if set to true, attach a GoogleDefaultCredentials to the call
+    3. --input_binary_file, a file containing the serialized request. The file
+       can be generated by calling something like:
+       protoc --proto_path=src/proto/grpc/testing/ \
+         --encode=grpc.testing.SimpleRequest \
+         src/proto/grpc/testing/messages.proto \
+         < input.txt > input.bin
+       If this is used and no proto file is provided in the argument list, the
+       method string has to be exact in the form of /package.service/method.
+    4. --output_binary_file, a file to write binary format response into, it can
+       be later decoded using protoc:
+       protoc --proto_path=src/proto/grpc/testing/ \
+       --decode=grpc.testing.SimpleResponse \
+       src/proto/grpc/testing/messages.proto \
+       < output.bin > output.txt
 */
 
 #include <fstream>
@@ -72,6 +73,7 @@
 #include <grpc/grpc.h>
 
 #include "test/cpp/util/cli_call.h"
+#include "test/cpp/util/proto_file_parser.h"
 #include "test/cpp/util/string_ref_helper.h"
 #include "test/cpp/util/test_config.h"
 
@@ -79,10 +81,11 @@
 DEFINE_bool(use_auth, false, "Whether to create default google credentials.");
 DEFINE_string(input_binary_file, "",
               "Path to input file containing serialized request.");
-DEFINE_string(output_binary_file, "output.bin",
+DEFINE_string(output_binary_file, "",
               "Path to output file to write serialized response.");
 DEFINE_string(metadata, "",
               "Metadata to send to server, in the form of key1:val1:key2:val2");
+DEFINE_string(proto_path, ".", "Path to look for the proto file.");
 
 void ParseMetadataFlag(
     std::multimap<grpc::string, grpc::string>* client_metadata) {
@@ -126,29 +129,52 @@
 int main(int argc, char** argv) {
   grpc::testing::InitTest(&argc, &argv, true);
 
-  if (argc < 4 || grpc::string(argv[1]) != "call") {
-    std::cout << "Usage: grpc_cli call server_host:port full_method_string\n"
-              << "Example: grpc_cli call service.googleapis.com "
-              << "/grpc.testing.TestService/UnaryCall "
-              << "--input_binary_file=input.bin --output_binary_file=output.bin"
-              << std::endl;
+  if (argc < 4 || argc == 5 || grpc::string(argv[1]) != "call") {
+    std::cout << "Usage: grpc_cli call server_host:port method_name "
+              << "[proto file] [text format request] [<options>]" << std::endl;
   }
-  grpc::string server_address(argv[2]);
-  // TODO(yangg) basic check of method string
-  grpc::string method(argv[3]);
 
-  if (FLAGS_input_binary_file.empty()) {
-    std::cout << "Missing --input_binary_file for serialized request."
-              << std::endl;
+  grpc::string file_name;
+  grpc::string request_text;
+  grpc::string server_address(argv[2]);
+  grpc::string method_name(argv[3]);
+  std::unique_ptr<grpc::testing::ProtoFileParser> parser;
+  grpc::string serialized_request_proto;
+
+  if (argc == 6) {
+    file_name = argv[4];
+    // TODO(yangg) read from stdin as well?
+    request_text = argv[5];
+  }
+
+  if (request_text.empty() && FLAGS_input_binary_file.empty()) {
+    std::cout << "Missing input. Use text format input or "
+              << "--input_binary_file for serialized request" << std::endl;
     return 1;
+  } else if (!request_text.empty()) {
+    parser.reset(new grpc::testing::ProtoFileParser(FLAGS_proto_path, file_name,
+                                                    method_name));
+    method_name = parser->GetFullMethodName();
+    if (parser->HasError()) {
+      return 1;
+    }
+  }
+
+  if (parser) {
+    serialized_request_proto =
+        parser->GetSerializedProto(request_text, true /* is_request */);
+    if (parser->HasError()) {
+      return 1;
+    }
+  } else if (!FLAGS_input_binary_file.empty()) {
+    std::ifstream input_file(FLAGS_input_binary_file,
+                             std::ios::in | std::ios::binary);
+    std::stringstream input_stream;
+    input_stream << input_file.rdbuf();
+    serialized_request_proto = input_stream.str();
   }
   std::cout << "connecting to " << server_address << std::endl;
 
-  std::ifstream input_file(FLAGS_input_binary_file,
-                           std::ios::in | std::ios::binary);
-  std::stringstream input_stream;
-  input_stream << input_file.rdbuf();
-
   std::shared_ptr<grpc::ChannelCredentials> creds;
   if (!FLAGS_enable_ssl) {
     creds = grpc::InsecureChannelCredentials();
@@ -162,25 +188,34 @@
   std::shared_ptr<grpc::Channel> channel =
       grpc::CreateChannel(server_address, creds);
 
-  grpc::string response;
+  grpc::string serialized_response_proto;
   std::multimap<grpc::string, grpc::string> client_metadata;
   std::multimap<grpc::string_ref, grpc::string_ref> server_initial_metadata,
       server_trailing_metadata;
   ParseMetadataFlag(&client_metadata);
   PrintMetadata(client_metadata, "Sending client initial metadata:");
   grpc::Status s = grpc::testing::CliCall::Call(
-      channel, method, input_stream.str(), &response, client_metadata,
-      &server_initial_metadata, &server_trailing_metadata);
+      channel, method_name, serialized_request_proto,
+      &serialized_response_proto, client_metadata, &server_initial_metadata,
+      &server_trailing_metadata);
   PrintMetadata(server_initial_metadata,
                 "Received initial metadata from server:");
   PrintMetadata(server_trailing_metadata,
                 "Received trailing metadata from server:");
   if (s.ok()) {
     std::cout << "Rpc succeeded with OK status" << std::endl;
-    if (!response.empty()) {
+    if (parser) {
+      grpc::string response_text = parser->GetTextFormat(
+          serialized_response_proto, false /* is_request */);
+      if (parser->HasError()) {
+        return 1;
+      }
+      std::cout << "Response: \n " << response_text << std::endl;
+    }
+    if (!FLAGS_output_binary_file.empty()) {
       std::ofstream output_file(FLAGS_output_binary_file,
                                 std::ios::trunc | std::ios::binary);
-      output_file << response;
+      output_file << serialized_response_proto;
     }
   } else {
     std::cout << "Rpc failed with status code " << s.error_code()
diff --git a/test/cpp/util/proto_file_parser.cc b/test/cpp/util/proto_file_parser.cc
new file mode 100644
index 0000000..25aec32
--- /dev/null
+++ b/test/cpp/util/proto_file_parser.cc
@@ -0,0 +1,178 @@
+/*
+ *
+ * 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 "test/cpp/util/proto_file_parser.h"
+
+#include <algorithm>
+#include <iostream>
+#include <sstream>
+
+#include <google/protobuf/text_format.h>
+#include <grpc++/support/config.h>
+
+namespace grpc {
+namespace testing {
+namespace {
+
+// Match the user input method string to the full_name from method descriptor.
+bool MethodNameMatch(const grpc::string& full_name, const grpc::string& input) {
+  grpc::string clean_input = input;
+  std::replace(clean_input.begin(), clean_input.end(), '/', '.');
+  if (clean_input.size() > full_name.size()) {
+    return false;
+  }
+  return full_name.compare(full_name.size() - clean_input.size(),
+                           clean_input.size(), clean_input) == 0;
+}
+}  // namespace
+
+class ErrorPrinter
+    : public google::protobuf::compiler::MultiFileErrorCollector {
+ public:
+  explicit ErrorPrinter(ProtoFileParser* parser) : parser_(parser) {}
+
+  void AddError(const grpc::string& filename, int line, int column,
+                const grpc::string& message) GRPC_OVERRIDE {
+    std::ostringstream oss;
+    oss << "error " << filename << " " << line << " " << column << " "
+        << message << "\n";
+    parser_->LogError(oss.str());
+  }
+
+  void AddWarning(const grpc::string& filename, int line, int column,
+                  const grpc::string& message) GRPC_OVERRIDE {
+    std::cout << "warning " << filename << " " << line << " " << column << " "
+              << message << std::endl;
+  }
+
+ private:
+  ProtoFileParser* parser_;  // not owned
+};
+
+ProtoFileParser::ProtoFileParser(const grpc::string& proto_path,
+                                 const grpc::string& file_name,
+                                 const grpc::string& method)
+    : has_error_(false) {
+  source_tree_.MapPath("", proto_path);
+  error_printer_.reset(new ErrorPrinter(this));
+  importer_.reset(new google::protobuf::compiler::Importer(
+      &source_tree_, error_printer_.get()));
+  const auto* file_desc = importer_->Import(file_name);
+  if (!file_desc) {
+    LogError("");
+    return;
+  }
+  dynamic_factory_.reset(
+      new google::protobuf::DynamicMessageFactory(importer_->pool()));
+
+  const google::protobuf::MethodDescriptor* method_descriptor = nullptr;
+  for (int i = 0; !method_descriptor && i < file_desc->service_count(); i++) {
+    const auto* service_desc = file_desc->service(i);
+    for (int j = 0; j < service_desc->method_count(); j++) {
+      const auto* method_desc = service_desc->method(j);
+      if (MethodNameMatch(method_desc->full_name(), method)) {
+        if (method_descriptor) {
+          std::ostringstream error_stream("Ambiguous method names: ");
+          error_stream << method_descriptor->full_name() << " ";
+          error_stream << method_desc->full_name();
+          LogError(error_stream.str());
+        }
+        method_descriptor = method_desc;
+      }
+    }
+  }
+  if (!method_descriptor) {
+    LogError("Method name not found");
+  }
+  if (has_error_) {
+    return;
+  }
+  full_method_name_ = method_descriptor->full_name();
+  size_t last_dot = full_method_name_.find_last_of('.');
+  if (last_dot != grpc::string::npos) {
+    full_method_name_[last_dot] = '/';
+  }
+  full_method_name_.insert(full_method_name_.begin(), '/');
+
+  request_prototype_.reset(
+      dynamic_factory_->GetPrototype(method_descriptor->input_type())->New());
+  response_prototype_.reset(
+      dynamic_factory_->GetPrototype(method_descriptor->output_type())->New());
+}
+
+ProtoFileParser::~ProtoFileParser() {}
+
+grpc::string ProtoFileParser::GetSerializedProto(
+    const grpc::string& text_format_proto, bool is_request) {
+  grpc::string serialized;
+  grpc::protobuf::Message* msg =
+      is_request ? request_prototype_.get() : response_prototype_.get();
+  bool ok =
+      google::protobuf::TextFormat::ParseFromString(text_format_proto, msg);
+  if (!ok) {
+    LogError("Failed to parse text format to proto.");
+    return "";
+  }
+  ok = request_prototype_->SerializeToString(&serialized);
+  if (!ok) {
+    LogError("Failed to serialize proto.");
+    return "";
+  }
+  return serialized;
+}
+
+grpc::string ProtoFileParser::GetTextFormat(
+    const grpc::string& serialized_proto, bool is_request) {
+  grpc::protobuf::Message* msg =
+      is_request ? request_prototype_.get() : response_prototype_.get();
+  if (!msg->ParseFromString(serialized_proto)) {
+    LogError("Failed to deserialize proto.");
+    return "";
+  }
+  grpc::string text_format;
+  if (!google::protobuf::TextFormat::PrintToString(*msg, &text_format)) {
+    LogError("Failed to print proto message to text format");
+    return "";
+  }
+  return text_format;
+}
+
+void ProtoFileParser::LogError(const grpc::string& error_msg) {
+  if (!error_msg.empty()) {
+    std::cout << error_msg << std::endl;
+  }
+  has_error_ = true;
+}
+
+}  // namespace testing
+}  // namespace grpc
diff --git a/test/cpp/util/proto_file_parser.h b/test/cpp/util/proto_file_parser.h
new file mode 100644
index 0000000..46cdd66
--- /dev/null
+++ b/test/cpp/util/proto_file_parser.h
@@ -0,0 +1,85 @@
+/*
+ *
+ * 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_TEST_CPP_UTIL_PROTO_FILE_PARSER_H
+#define GRPC_TEST_CPP_UTIL_PROTO_FILE_PARSER_H
+
+#include <memory>
+
+#include <google/protobuf/compiler/importer.h>
+#include <google/protobuf/dynamic_message.h>
+
+#include "src/compiler/config.h"
+
+namespace grpc {
+namespace testing {
+class ErrorPrinter;
+
+// Find method and associated request/response types.
+class ProtoFileParser {
+ public:
+  // The given proto file_name will be searched in a source tree rooted from
+  // proto_path. The method could be a partial string such as Service.Method or
+  // even just Method. It will log an error if there is ambiguity.
+  ProtoFileParser(const grpc::string& proto_path, const grpc::string& file_name,
+                  const grpc::string& method);
+  ~ProtoFileParser();
+
+  grpc::string GetFullMethodName() const { return full_method_name_; }
+
+  grpc::string GetSerializedProto(const grpc::string& text_format_proto,
+                                  bool is_request);
+
+  grpc::string GetTextFormat(const grpc::string& serialized_proto,
+                             bool is_request);
+
+  bool HasError() const { return has_error_; }
+
+  void LogError(const grpc::string& error_msg);
+
+ private:
+  bool has_error_;
+  grpc::string request_text_;
+  grpc::string full_method_name_;
+  google::protobuf::compiler::DiskSourceTree source_tree_;
+  std::unique_ptr<ErrorPrinter> error_printer_;
+  std::unique_ptr<google::protobuf::compiler::Importer> importer_;
+  std::unique_ptr<google::protobuf::DynamicMessageFactory> dynamic_factory_;
+  std::unique_ptr<grpc::protobuf::Message> request_prototype_;
+  std::unique_ptr<grpc::protobuf::Message> response_prototype_;
+};
+
+}  // namespace testing
+}  // namespace grpc
+
+#endif  // GRPC_TEST_CPP_UTIL_PROTO_FILE_PARSER_H
diff --git a/test/cpp/util/proto_reflection_descriptor_database.cc b/test/cpp/util/proto_reflection_descriptor_database.cc
new file mode 100644
index 0000000..6907d97
--- /dev/null
+++ b/test/cpp/util/proto_reflection_descriptor_database.cc
@@ -0,0 +1,316 @@
+/*
+ *
+ * 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 "test/cpp/util/proto_reflection_descriptor_database.h"
+
+#include <vector>
+
+#include <grpc/support/log.h>
+
+using grpc::reflection::v1alpha::ServerReflection;
+using grpc::reflection::v1alpha::ServerReflectionRequest;
+using grpc::reflection::v1alpha::ServerReflectionResponse;
+using grpc::reflection::v1alpha::ListServiceResponse;
+using grpc::reflection::v1alpha::ErrorResponse;
+
+namespace grpc {
+
+ProtoReflectionDescriptorDatabase::ProtoReflectionDescriptorDatabase(
+    std::unique_ptr<ServerReflection::Stub> stub)
+    : stub_(std::move(stub)) {}
+
+ProtoReflectionDescriptorDatabase::ProtoReflectionDescriptorDatabase(
+    std::shared_ptr<grpc::Channel> channel)
+    : stub_(ServerReflection::NewStub(channel)) {}
+
+ProtoReflectionDescriptorDatabase::~ProtoReflectionDescriptorDatabase() {}
+
+bool ProtoReflectionDescriptorDatabase::FindFileByName(
+    const string& filename, google::protobuf::FileDescriptorProto* output) {
+  if (cached_db_.FindFileByName(filename, output)) {
+    return true;
+  }
+
+  if (known_files_.find(filename) != known_files_.end()) {
+    return false;
+  }
+
+  ServerReflectionRequest request;
+  request.set_file_by_filename(filename);
+  ServerReflectionResponse response;
+
+  DoOneRequest(request, response);
+
+  if (response.message_response_case() ==
+      ServerReflectionResponse::MessageResponseCase::kFileDescriptorResponse) {
+    AddFileFromResponse(response.file_descriptor_response());
+  } else if (response.message_response_case() ==
+             ServerReflectionResponse::MessageResponseCase::kErrorResponse) {
+    const ErrorResponse error = response.error_response();
+    if (error.error_code() == StatusCode::NOT_FOUND) {
+      gpr_log(GPR_INFO, "NOT_FOUND from server for FindFileByName(%s)",
+              filename.c_str());
+    } else {
+      gpr_log(GPR_INFO,
+              "Error on FindFileByName(%s)\n\tError code: %d\n"
+              "\tError Message: %s",
+              filename.c_str(), error.error_code(),
+              error.error_message().c_str());
+    }
+  } else {
+    gpr_log(
+        GPR_INFO,
+        "Error on FindFileByName(%s) response type\n"
+        "\tExpecting: %d\n\tReceived: %d",
+        filename.c_str(),
+        ServerReflectionResponse::MessageResponseCase::kFileDescriptorResponse,
+        response.message_response_case());
+  }
+
+  return cached_db_.FindFileByName(filename, output);
+}
+
+bool ProtoReflectionDescriptorDatabase::FindFileContainingSymbol(
+    const string& symbol_name, google::protobuf::FileDescriptorProto* output) {
+  if (cached_db_.FindFileContainingSymbol(symbol_name, output)) {
+    return true;
+  }
+
+  if (missing_symbols_.find(symbol_name) != missing_symbols_.end()) {
+    return false;
+  }
+
+  ServerReflectionRequest request;
+  request.set_file_containing_symbol(symbol_name);
+  ServerReflectionResponse response;
+
+  DoOneRequest(request, response);
+
+  if (response.message_response_case() ==
+      ServerReflectionResponse::MessageResponseCase::kFileDescriptorResponse) {
+    AddFileFromResponse(response.file_descriptor_response());
+  } else if (response.message_response_case() ==
+             ServerReflectionResponse::MessageResponseCase::kErrorResponse) {
+    const ErrorResponse error = response.error_response();
+    if (error.error_code() == StatusCode::NOT_FOUND) {
+      missing_symbols_.insert(symbol_name);
+      gpr_log(GPR_INFO,
+              "NOT_FOUND from server for FindFileContainingSymbol(%s)",
+              symbol_name.c_str());
+    } else {
+      gpr_log(GPR_INFO,
+              "Error on FindFileContainingSymbol(%s)\n"
+              "\tError code: %d\n\tError Message: %s",
+              symbol_name.c_str(), error.error_code(),
+              error.error_message().c_str());
+    }
+  } else {
+    gpr_log(
+        GPR_INFO,
+        "Error on FindFileContainingSymbol(%s) response type\n"
+        "\tExpecting: %d\n\tReceived: %d",
+        symbol_name.c_str(),
+        ServerReflectionResponse::MessageResponseCase::kFileDescriptorResponse,
+        response.message_response_case());
+  }
+  return cached_db_.FindFileContainingSymbol(symbol_name, output);
+}
+
+bool ProtoReflectionDescriptorDatabase::FindFileContainingExtension(
+    const string& containing_type, int field_number,
+    google::protobuf::FileDescriptorProto* output) {
+  if (cached_db_.FindFileContainingExtension(containing_type, field_number,
+                                             output)) {
+    return true;
+  }
+
+  if (missing_extensions_.find(containing_type) != missing_extensions_.end() &&
+      missing_extensions_[containing_type].find(field_number) !=
+          missing_extensions_[containing_type].end()) {
+    gpr_log(GPR_INFO, "nested map.");
+    return false;
+  }
+
+  ServerReflectionRequest request;
+  request.mutable_file_containing_extension()->set_containing_type(
+      containing_type);
+  request.mutable_file_containing_extension()->set_extension_number(
+      field_number);
+  ServerReflectionResponse response;
+
+  DoOneRequest(request, response);
+
+  if (response.message_response_case() ==
+      ServerReflectionResponse::MessageResponseCase::kFileDescriptorResponse) {
+    AddFileFromResponse(response.file_descriptor_response());
+  } else if (response.message_response_case() ==
+             ServerReflectionResponse::MessageResponseCase::kErrorResponse) {
+    const ErrorResponse error = response.error_response();
+    if (error.error_code() == StatusCode::NOT_FOUND) {
+      if (missing_extensions_.find(containing_type) ==
+          missing_extensions_.end()) {
+        missing_extensions_[containing_type] = {};
+      }
+      missing_extensions_[containing_type].insert(field_number);
+      gpr_log(GPR_INFO,
+              "NOT_FOUND from server for FindFileContainingExtension(%s, %d)",
+              containing_type.c_str(), field_number);
+    } else {
+      gpr_log(GPR_INFO,
+              "Error on FindFileContainingExtension(%s, %d)\n"
+              "\tError code: %d\n\tError Message: %s",
+              containing_type.c_str(), field_number, error.error_code(),
+              error.error_message().c_str());
+    }
+  } else {
+    gpr_log(
+        GPR_INFO,
+        "Error on FindFileContainingExtension(%s, %d) response type\n"
+        "\tExpecting: %d\n\tReceived: %d",
+        containing_type.c_str(), field_number,
+        ServerReflectionResponse::MessageResponseCase::kFileDescriptorResponse,
+        response.message_response_case());
+  }
+
+  return cached_db_.FindFileContainingExtension(containing_type, field_number,
+                                                output);
+}
+
+bool ProtoReflectionDescriptorDatabase::FindAllExtensionNumbers(
+    const string& extendee_type, std::vector<int>* output) {
+  if (cached_extension_numbers_.find(extendee_type) !=
+      cached_extension_numbers_.end()) {
+    *output = cached_extension_numbers_[extendee_type];
+    return true;
+  }
+
+  ServerReflectionRequest request;
+  request.set_all_extension_numbers_of_type(extendee_type);
+  ServerReflectionResponse response;
+
+  DoOneRequest(request, response);
+
+  if (response.message_response_case() ==
+      ServerReflectionResponse::MessageResponseCase::
+          kAllExtensionNumbersResponse) {
+    auto number = response.all_extension_numbers_response().extension_number();
+    *output = std::vector<int>(number.begin(), number.end());
+    cached_extension_numbers_[extendee_type] = *output;
+    return true;
+  } else if (response.message_response_case() ==
+             ServerReflectionResponse::MessageResponseCase::kErrorResponse) {
+    const ErrorResponse error = response.error_response();
+    if (error.error_code() == StatusCode::NOT_FOUND) {
+      gpr_log(GPR_INFO, "NOT_FOUND from server for FindAllExtensionNumbers(%s)",
+              extendee_type.c_str());
+    } else {
+      gpr_log(GPR_INFO,
+              "Error on FindAllExtensionNumbersExtension(%s)\n"
+              "\tError code: %d\n\tError Message: %s",
+              extendee_type.c_str(), error.error_code(),
+              error.error_message().c_str());
+    }
+  }
+  return false;
+}
+
+bool ProtoReflectionDescriptorDatabase::GetServices(
+    std::vector<std::string>* output) {
+  ServerReflectionRequest request;
+  request.set_list_services("");
+  ServerReflectionResponse response;
+
+  DoOneRequest(request, response);
+
+  if (response.message_response_case() ==
+      ServerReflectionResponse::MessageResponseCase::kListServicesResponse) {
+    const ListServiceResponse ls_response = response.list_services_response();
+    for (int i = 0; i < ls_response.service_size(); ++i) {
+      (*output).push_back(ls_response.service(i).name());
+    }
+    return true;
+  } else if (response.message_response_case() ==
+             ServerReflectionResponse::MessageResponseCase::kErrorResponse) {
+    const ErrorResponse error = response.error_response();
+    gpr_log(GPR_INFO,
+            "Error on GetServices()\n\tError code: %d\n"
+            "\tError Message: %s",
+            error.error_code(), error.error_message().c_str());
+  } else {
+    gpr_log(
+        GPR_INFO,
+        "Error on GetServices() response type\n\tExpecting: %d\n\tReceived: %d",
+        ServerReflectionResponse::MessageResponseCase::kListServicesResponse,
+        response.message_response_case());
+  }
+  return false;
+}
+
+const google::protobuf::FileDescriptorProto
+ProtoReflectionDescriptorDatabase::ParseFileDescriptorProtoResponse(
+    const std::string& byte_fd_proto) {
+  google::protobuf::FileDescriptorProto file_desc_proto;
+  file_desc_proto.ParseFromString(byte_fd_proto);
+  return file_desc_proto;
+}
+
+void ProtoReflectionDescriptorDatabase::AddFileFromResponse(
+    const grpc::reflection::v1alpha::FileDescriptorResponse& response) {
+  for (int i = 0; i < response.file_descriptor_proto_size(); ++i) {
+    const google::protobuf::FileDescriptorProto file_proto =
+        ParseFileDescriptorProtoResponse(response.file_descriptor_proto(i));
+    if (known_files_.find(file_proto.name()) == known_files_.end()) {
+      known_files_.insert(file_proto.name());
+      cached_db_.Add(file_proto);
+    }
+  }
+}
+
+const std::shared_ptr<ProtoReflectionDescriptorDatabase::ClientStream>
+ProtoReflectionDescriptorDatabase::GetStream() {
+  if (stream_ == nullptr) {
+    stream_ = stub_->ServerReflectionInfo(&ctx_);
+  }
+  return stream_;
+}
+
+void ProtoReflectionDescriptorDatabase::DoOneRequest(
+    const ServerReflectionRequest& request,
+    ServerReflectionResponse& response) {
+  stream_mutex_.lock();
+  GetStream()->Write(request);
+  GetStream()->Read(&response);
+  stream_mutex_.unlock();
+}
+
+}  // namespace grpc
diff --git a/test/cpp/util/proto_reflection_descriptor_database.h b/test/cpp/util/proto_reflection_descriptor_database.h
new file mode 100644
index 0000000..99c0067
--- /dev/null
+++ b/test/cpp/util/proto_reflection_descriptor_database.h
@@ -0,0 +1,131 @@
+/*
+ *
+ * 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_TEST_CPP_PROTO_SERVER_REFLECTION_DATABSE_H
+#define GRPC_TEST_CPP_PROTO_SERVER_REFLECTION_DATABSE_H
+
+#include <mutex>
+#include <unordered_map>
+#include <unordered_set>
+#include <vector>
+
+#include <google/protobuf/descriptor.h>
+#include <google/protobuf/descriptor.pb.h>
+#include <google/protobuf/descriptor_database.h>
+#include <grpc++/ext/reflection.grpc.pb.h>
+#include <grpc++/grpc++.h>
+
+namespace grpc {
+
+// ProtoReflectionDescriptorDatabase takes a stub of ServerReflection and
+// provides the methods defined by DescriptorDatabase interfaces. It can be used
+// to feed a DescriptorPool instance.
+class ProtoReflectionDescriptorDatabase
+    : public google::protobuf::DescriptorDatabase {
+ public:
+  explicit ProtoReflectionDescriptorDatabase(
+      std::unique_ptr<reflection::v1alpha::ServerReflection::Stub> stub);
+
+  explicit ProtoReflectionDescriptorDatabase(
+      std::shared_ptr<grpc::Channel> channel);
+
+  virtual ~ProtoReflectionDescriptorDatabase();
+
+  // The following four methods implement DescriptorDatabase interfaces.
+  //
+  // Find a file by file name.  Fills in in *output and returns true if found.
+  // Otherwise, returns false, leaving the contents of *output undefined.
+  bool FindFileByName(const string& filename,
+                      google::protobuf::FileDescriptorProto* output)
+      GRPC_OVERRIDE;
+
+  // Find the file that declares the given fully-qualified symbol name.
+  // If found, fills in *output and returns true, otherwise returns false
+  // and leaves *output undefined.
+  bool FindFileContainingSymbol(const string& symbol_name,
+                                google::protobuf::FileDescriptorProto* output)
+      GRPC_OVERRIDE;
+
+  // Find the file which defines an extension extending the given message type
+  // with the given field number.  If found, fills in *output and returns true,
+  // otherwise returns false and leaves *output undefined.  containing_type
+  // must be a fully-qualified type name.
+  bool FindFileContainingExtension(
+      const string& containing_type, int field_number,
+      google::protobuf::FileDescriptorProto* output) GRPC_OVERRIDE;
+
+  // Finds the tag numbers used by all known extensions of
+  // extendee_type, and appends them to output in an undefined
+  // order. This method is best-effort: it's not guaranteed that the
+  // database will find all extensions, and it's not guaranteed that
+  // FindFileContainingExtension will return true on all of the found
+  // numbers. Returns true if the search was successful, otherwise
+  // returns false and leaves output unchanged.
+  bool FindAllExtensionNumbers(const string& extendee_type,
+                               std::vector<int>* output) GRPC_OVERRIDE;
+
+  // Provide a list of full names of registered services
+  bool GetServices(std::vector<std::string>* output);
+
+ private:
+  typedef ClientReaderWriter<
+      grpc::reflection::v1alpha::ServerReflectionRequest,
+      grpc::reflection::v1alpha::ServerReflectionResponse>
+      ClientStream;
+
+  const google::protobuf::FileDescriptorProto ParseFileDescriptorProtoResponse(
+      const std::string& byte_fd_proto);
+
+  void AddFileFromResponse(
+      const grpc::reflection::v1alpha::FileDescriptorResponse& response);
+
+  const std::shared_ptr<ClientStream> GetStream();
+
+  void DoOneRequest(
+      const grpc::reflection::v1alpha::ServerReflectionRequest& request,
+      grpc::reflection::v1alpha::ServerReflectionResponse& response);
+
+  std::shared_ptr<ClientStream> stream_;
+  grpc::ClientContext ctx_;
+  std::unique_ptr<grpc::reflection::v1alpha::ServerReflection::Stub> stub_;
+  std::unordered_set<string> known_files_;
+  std::unordered_set<string> missing_symbols_;
+  std::unordered_map<string, std::unordered_set<int>> missing_extensions_;
+  std::unordered_map<string, std::vector<int>> cached_extension_numbers_;
+  std::mutex stream_mutex_;
+
+  google::protobuf::SimpleDescriptorDatabase cached_db_;
+};
+
+}  // namespace grpc
+
+#endif  // GRPC_TEST_CPP_METRICS_SERVER_H
diff --git a/tools/codegen/core/gen_nano_proto.sh b/tools/codegen/core/gen_nano_proto.sh
index b216a20..c880fc2 100755
--- a/tools/codegen/core/gen_nano_proto.sh
+++ b/tools/codegen/core/gen_nano_proto.sh
@@ -136,6 +136,13 @@
 sed -i "s:$PROTO_BASENAME.pb.h:${GRPC_OUTPUT_DIR}/$PROTO_BASENAME.pb.h:g" \
   "$OUTPUT_DIR/$PROTO_BASENAME.pb.c"
 
+# Fix up the include guards such that they pass the check_include_guards.py
+# test. Assumes that the generated files are being placed in gRPC src dir.
+readonly INCLUDE_GUARD_BASE=`echo $GRPC_OUTPUT_DIR | tr [a-z/] [A-Z_] | sed s:^.*SRC_::`
+readonly UC_PROTO_BASENAME=`echo $PROTO_BASENAME | tr [a-z] [A-Z]`
+sed -i "s:PB_${UC_PROTO_BASENAME}_PB_H_INCLUDED:GRPC_${INCLUDE_GUARD_BASE}_${UC_PROTO_BASENAME}_PB_H:g" \
+  "$OUTPUT_DIR/$PROTO_BASENAME.pb.h"
+
 # prepend copyright
 TMPFILE=$(mktemp)
 cat $COPYRIGHT_FILE "$OUTPUT_DIR/$PROTO_BASENAME.pb.c" > $TMPFILE
diff --git a/tools/codegen/core/gen_static_metadata.py b/tools/codegen/core/gen_static_metadata.py
index b38555e..faa8386 100755
--- a/tools/codegen/core/gen_static_metadata.py
+++ b/tools/codegen/core/gen_static_metadata.py
@@ -108,6 +108,7 @@
     ('if-range', ''),
     ('if-unmodified-since', ''),
     ('last-modified', ''),
+    ('load-reporting', ''),
     ('link', ''),
     ('location', ''),
     ('max-forwards', ''),
diff --git a/tools/codegen/extensions/gen_reflection_proto.sh b/tools/codegen/extensions/gen_reflection_proto.sh
new file mode 100755
index 0000000..45a1a9f
--- /dev/null
+++ b/tools/codegen/extensions/gen_reflection_proto.sh
@@ -0,0 +1,73 @@
+#!/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.
+
+PROTO_DIR="src/proto/grpc/reflection/v1alpha"
+PROTO_FILE="reflection"
+HEADER_DIR="include/grpc++/ext"
+SRC_DIR="src/cpp/ext"
+INCLUDE_DIR="grpc++/ext"
+TMP_DIR="tmp"
+GRPC_PLUGIN="bins/opt/grpc_cpp_plugin"
+PROTOC=third_party/protobuf/src/protoc
+
+set -e
+
+TMP_DIR=${TMP_DIR}_${PROTO_FILE}
+
+cd $(dirname $0)/../../..
+
+[ ! -d $HEADER_DIR ] && mkdir -p $HEADER_DIR || :
+[ ! -d $SRC_DIR ] && mkdir -p $SRC_DIR || :
+[ ! -d $TMP_DIR ] && mkdir -p $TMP_DIR || :
+
+$PROTOC -I$PROTO_DIR --cpp_out=$TMP_DIR ${PROTO_DIR}/${PROTO_FILE}.proto
+$PROTOC -I$PROTO_DIR --grpc_out=$TMP_DIR --plugin=protoc-gen-grpc=${GRPC_PLUGIN} ${PROTO_DIR}/${PROTO_FILE}.proto
+
+sed -i "s/\"${PROTO_FILE}.pb.h\"/<${INCLUDE_DIR/\//\\\/}\/${PROTO_FILE}.pb.h>/g" ${TMP_DIR}/${PROTO_FILE}.pb.cc
+sed -i "s/\"${PROTO_FILE}.pb.h\"/<${INCLUDE_DIR/\//\\\/}\/${PROTO_FILE}.pb.h>/g" ${TMP_DIR}/${PROTO_FILE}.grpc.pb.h
+sed -i "s/\"${PROTO_FILE}.pb.h\"/<${INCLUDE_DIR/\//\\\/}\/${PROTO_FILE}.pb.h>/g" ${TMP_DIR}/${PROTO_FILE}.grpc.pb.cc
+sed -i "s/\"${PROTO_FILE}.grpc.pb.h\"/<${INCLUDE_DIR/\//\\\/}\/${PROTO_FILE}.grpc.pb.h>/g" ${TMP_DIR}/${PROTO_FILE}.grpc.pb.cc
+
+/bin/cp LICENSE ${TMP_DIR}/TMP_LICENSE
+sed -i -e "s/./ &/" -e "s/.*/ \*&/" ${TMP_DIR}/TMP_LICENSE
+sed -i -r "\$a\ *\n *\/\n\n"  ${TMP_DIR}/TMP_LICENSE
+
+sed -i -e "1s/^/ *\n/" -e "1s/^/\/*\n/" ${TMP_DIR}/*.pb.h
+sed -i -e "1s/^/ *\n/" -e "1s/^/\/*\n/" ${TMP_DIR}/*.pb.cc
+
+sed -i "2r ${TMP_DIR}/TMP_LICENSE" ${TMP_DIR}/*.pb.h
+sed -i "2r ${TMP_DIR}/TMP_LICENSE" ${TMP_DIR}/*.pb.cc
+
+/bin/mv ${TMP_DIR}/${PROTO_FILE}.pb.h ${HEADER_DIR}
+/bin/mv ${TMP_DIR}/${PROTO_FILE}.grpc.pb.h ${HEADER_DIR}
+/bin/mv ${TMP_DIR}/${PROTO_FILE}.pb.cc ${SRC_DIR}
+/bin/mv ${TMP_DIR}/${PROTO_FILE}.grpc.pb.cc ${SRC_DIR}
+/bin/rm -r $TMP_DIR
diff --git a/src/python/grpcio/grpc/_adapter/_implementations.py b/tools/distrib/check_generated_pb_files.sh
old mode 100644
new mode 100755
similarity index 74%
copy from src/python/grpcio/grpc/_adapter/_implementations.py
copy to tools/distrib/check_generated_pb_files.sh
index b85f228..5570678
--- a/src/python/grpcio/grpc/_adapter/_implementations.py
+++ b/tools/distrib/check_generated_pb_files.sh
@@ -1,4 +1,5 @@
-# Copyright 2015, Google Inc.
+#!/bin/bash
+# Copyright 2016, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
@@ -27,22 +28,13 @@
 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-import collections
+set -ex
 
-from grpc.beta import interfaces
+# change to root directory
+cd $(dirname $0)/../..
 
-class AuthMetadataContext(collections.namedtuple(
-    'AuthMetadataContext', [
-        'service_url',
-        'method_name'
-    ]), interfaces.GRPCAuthMetadataContext):
-  pass
+# build grpc_check_generated_pb_files docker image
+docker build -t grpc_check_generated_pb_files tools/dockerfile/grpc_check_generated_pb_files
 
-
-class AuthMetadataPluginCallback(interfaces.GRPCAuthMetadataContext):
-
-  def __init__(self, callback):
-    self._callback = callback
-
-  def __call__(self, metadata, error):
-    self._callback(metadata, error)
+# run check_pb_files against the checked out codebase
+docker run -e TEST=$TEST --rm=true -v ${HOST_GIT_ROOT:-`pwd`}:/var/local/jenkins/grpc -t grpc_check_generated_pb_files /var/local/jenkins/grpc/tools/dockerfile/grpc_check_generated_pb_files/check_pb_files.sh
diff --git a/tools/distrib/check_include_guards.py b/tools/distrib/check_include_guards.py
index ef770b3..56b2924 100755
--- a/tools/distrib/check_include_guards.py
+++ b/tools/distrib/check_include_guards.py
@@ -172,6 +172,8 @@
 
 KNOWN_BAD = set([
     'src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h',
+    'include/grpc++/ext/reflection.grpc.pb.h',
+    'include/grpc++/ext/reflection.pb.h',
 ])
 
 
diff --git a/tools/distrib/python/check_grpcio_tools.py b/tools/distrib/python/check_grpcio_tools.py
index baf2ff4..80c6327 100755
--- a/tools/distrib/python/check_grpcio_tools.py
+++ b/tools/distrib/python/check_grpcio_tools.py
@@ -37,7 +37,7 @@
 
 Have you called tools/distrib/python/make_grpcio_tools.py since upgrading protobuf?"""
 
-check_protoc_lib_deps_content = make.get_deps(make.BAZEL_DEPS_PROTOC_LIB_QUERY)
+check_protoc_lib_deps_content = make.get_deps()
 
 with open(make.GRPC_PYTHON_PROTOC_LIB_DEPS, 'r') as protoc_lib_deps_file:
   if protoc_lib_deps_file.read() != check_protoc_lib_deps_content:
diff --git a/tools/distrib/python/grpcio_tools/README.rst b/tools/distrib/python/grpcio_tools/README.rst
index 10d2fe8..e9f1374 100644
--- a/tools/distrib/python/grpcio_tools/README.rst
+++ b/tools/distrib/python/grpcio_tools/README.rst
@@ -126,3 +126,13 @@
   GCC 6.0), this is probably a bug where GCC chokes on constant expressions
   when the :code:`-fwrapv` flag is specified. You should consider setting your
   environment with :code:`CFLAGS=-fno-wrapv` or using clang (:code:`CC=clang`).
+
+Usage
+-----
+
+Given protobuf include directories :code:`$INCLUDE`, an output directory
+:code:`$OUTPUT`, and proto files :code:`$PROTO_FILES`, invoke as:
+
+::
+
+  $ python -m grpc.tools.protoc -I$INCLUDE --python_out=$OUTPUT --grpc_python_out=$OUTPUT $PROTO_FILES
diff --git a/tools/distrib/python/grpcio_tools/grpc/tools/protoc.py b/tools/distrib/python/grpcio_tools/grpc/tools/protoc.py
index b4dd0ec..1c69e78 100644
--- a/tools/distrib/python/grpcio_tools/grpc/tools/protoc.py
+++ b/tools/distrib/python/grpcio_tools/grpc/tools/protoc.py
@@ -29,10 +29,13 @@
 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
+import pkg_resources
 import sys
 
 from grpc.tools import protoc_compiler
 
 
 if __name__ == '__main__':
-  protoc_compiler.run_main(sys.argv)
+  proto_include = pkg_resources.resource_filename('grpc.tools', '_proto')
+  protoc_compiler.run_main(
+      sys.argv + ['-I{}'.format(proto_include)])
diff --git a/tools/distrib/python/grpcio_tools/protoc_lib_deps.py b/tools/distrib/python/grpcio_tools/protoc_lib_deps.py
index 135ac5c..cd4effa 100644
--- a/tools/distrib/python/grpcio_tools/protoc_lib_deps.py
+++ b/tools/distrib/python/grpcio_tools/protoc_lib_deps.py
@@ -30,3 +30,7 @@
 
 # AUTO-GENERATED BY make_grpcio_tools.py!
 CC_FILES=['google/protobuf/compiler/zip_writer.cc', 'google/protobuf/compiler/subprocess.cc', 'google/protobuf/compiler/ruby/ruby_generator.cc', 'google/protobuf/compiler/python/python_generator.cc', 'google/protobuf/compiler/plugin.pb.cc', 'google/protobuf/compiler/plugin.cc', 'google/protobuf/compiler/objectivec/objectivec_primitive_field.cc', 'google/protobuf/compiler/objectivec/objectivec_oneof.cc', 'google/protobuf/compiler/objectivec/objectivec_message_field.cc', 'google/protobuf/compiler/objectivec/objectivec_message.cc', 'google/protobuf/compiler/objectivec/objectivec_map_field.cc', 'google/protobuf/compiler/objectivec/objectivec_helpers.cc', 'google/protobuf/compiler/objectivec/objectivec_generator.cc', 'google/protobuf/compiler/objectivec/objectivec_file.cc', 'google/protobuf/compiler/objectivec/objectivec_field.cc', 'google/protobuf/compiler/objectivec/objectivec_extension.cc', 'google/protobuf/compiler/objectivec/objectivec_enum_field.cc', 'google/protobuf/compiler/objectivec/objectivec_enum.cc', 'google/protobuf/compiler/js/js_generator.cc', 'google/protobuf/compiler/javanano/javanano_primitive_field.cc', 'google/protobuf/compiler/javanano/javanano_message_field.cc', 'google/protobuf/compiler/javanano/javanano_message.cc', 'google/protobuf/compiler/javanano/javanano_map_field.cc', 'google/protobuf/compiler/javanano/javanano_helpers.cc', 'google/protobuf/compiler/javanano/javanano_generator.cc', 'google/protobuf/compiler/javanano/javanano_file.cc', 'google/protobuf/compiler/javanano/javanano_field.cc', 'google/protobuf/compiler/javanano/javanano_extension.cc', 'google/protobuf/compiler/javanano/javanano_enum_field.cc', 'google/protobuf/compiler/javanano/javanano_enum.cc', 'google/protobuf/compiler/java/java_string_field_lite.cc', 'google/protobuf/compiler/java/java_string_field.cc', 'google/protobuf/compiler/java/java_shared_code_generator.cc', 'google/protobuf/compiler/java/java_service.cc', 'google/protobuf/compiler/java/java_primitive_field_lite.cc', 'google/protobuf/compiler/java/java_primitive_field.cc', 'google/protobuf/compiler/java/java_name_resolver.cc', 'google/protobuf/compiler/java/java_message_lite.cc', 'google/protobuf/compiler/java/java_message_field_lite.cc', 'google/protobuf/compiler/java/java_message_field.cc', 'google/protobuf/compiler/java/java_message_builder_lite.cc', 'google/protobuf/compiler/java/java_message_builder.cc', 'google/protobuf/compiler/java/java_message.cc', 'google/protobuf/compiler/java/java_map_field_lite.cc', 'google/protobuf/compiler/java/java_map_field.cc', 'google/protobuf/compiler/java/java_lazy_message_field_lite.cc', 'google/protobuf/compiler/java/java_lazy_message_field.cc', 'google/protobuf/compiler/java/java_helpers.cc', 'google/protobuf/compiler/java/java_generator_factory.cc', 'google/protobuf/compiler/java/java_generator.cc', 'google/protobuf/compiler/java/java_file.cc', 'google/protobuf/compiler/java/java_field.cc', 'google/protobuf/compiler/java/java_extension_lite.cc', 'google/protobuf/compiler/java/java_extension.cc', 'google/protobuf/compiler/java/java_enum_lite.cc', 'google/protobuf/compiler/java/java_enum_field_lite.cc', 'google/protobuf/compiler/java/java_enum_field.cc', 'google/protobuf/compiler/java/java_enum.cc', 'google/protobuf/compiler/java/java_doc_comment.cc', 'google/protobuf/compiler/java/java_context.cc', 'google/protobuf/compiler/csharp/csharp_wrapper_field.cc', 'google/protobuf/compiler/csharp/csharp_source_generator_base.cc', 'google/protobuf/compiler/csharp/csharp_repeated_primitive_field.cc', 'google/protobuf/compiler/csharp/csharp_repeated_message_field.cc', 'google/protobuf/compiler/csharp/csharp_repeated_enum_field.cc', 'google/protobuf/compiler/csharp/csharp_reflection_class.cc', 'google/protobuf/compiler/csharp/csharp_primitive_field.cc', 'google/protobuf/compiler/csharp/csharp_message_field.cc', 'google/protobuf/compiler/csharp/csharp_message.cc', 'google/protobuf/compiler/csharp/csharp_map_field.cc', 'google/protobuf/compiler/csharp/csharp_helpers.cc', 'google/protobuf/compiler/csharp/csharp_generator.cc', 'google/protobuf/compiler/csharp/csharp_field_base.cc', 'google/protobuf/compiler/csharp/csharp_enum_field.cc', 'google/protobuf/compiler/csharp/csharp_enum.cc', 'google/protobuf/compiler/csharp/csharp_doc_comment.cc', 'google/protobuf/compiler/cpp/cpp_string_field.cc', 'google/protobuf/compiler/cpp/cpp_service.cc', 'google/protobuf/compiler/cpp/cpp_primitive_field.cc', 'google/protobuf/compiler/cpp/cpp_message_field.cc', 'google/protobuf/compiler/cpp/cpp_message.cc', 'google/protobuf/compiler/cpp/cpp_map_field.cc', 'google/protobuf/compiler/cpp/cpp_helpers.cc', 'google/protobuf/compiler/cpp/cpp_generator.cc', 'google/protobuf/compiler/cpp/cpp_file.cc', 'google/protobuf/compiler/cpp/cpp_field.cc', 'google/protobuf/compiler/cpp/cpp_extension.cc', 'google/protobuf/compiler/cpp/cpp_enum_field.cc', 'google/protobuf/compiler/cpp/cpp_enum.cc', 'google/protobuf/compiler/command_line_interface.cc', 'google/protobuf/compiler/code_generator.cc', 'google/protobuf/wrappers.pb.cc', 'google/protobuf/wire_format.cc', 'google/protobuf/util/type_resolver_util.cc', 'google/protobuf/util/time_util.cc', 'google/protobuf/util/message_differencer.cc', 'google/protobuf/util/json_util.cc', 'google/protobuf/util/internal/utility.cc', 'google/protobuf/util/internal/type_info_test_helper.cc', 'google/protobuf/util/internal/type_info.cc', 'google/protobuf/util/internal/protostream_objectwriter.cc', 'google/protobuf/util/internal/protostream_objectsource.cc', 'google/protobuf/util/internal/proto_writer.cc', 'google/protobuf/util/internal/object_writer.cc', 'google/protobuf/util/internal/json_stream_parser.cc', 'google/protobuf/util/internal/json_objectwriter.cc', 'google/protobuf/util/internal/json_escaping.cc', 'google/protobuf/util/internal/field_mask_utility.cc', 'google/protobuf/util/internal/error_listener.cc', 'google/protobuf/util/internal/default_value_objectwriter.cc', 'google/protobuf/util/internal/datapiece.cc', 'google/protobuf/util/field_mask_util.cc', 'google/protobuf/util/field_comparator.cc', 'google/protobuf/unknown_field_set.cc', 'google/protobuf/type.pb.cc', 'google/protobuf/timestamp.pb.cc', 'google/protobuf/text_format.cc', 'google/protobuf/stubs/substitute.cc', 'google/protobuf/stubs/mathlimits.cc', 'google/protobuf/struct.pb.cc', 'google/protobuf/source_context.pb.cc', 'google/protobuf/service.cc', 'google/protobuf/reflection_ops.cc', 'google/protobuf/message.cc', 'google/protobuf/map_field.cc', 'google/protobuf/io/zero_copy_stream_impl.cc', 'google/protobuf/io/tokenizer.cc', 'google/protobuf/io/strtod.cc', 'google/protobuf/io/printer.cc', 'google/protobuf/io/gzip_stream.cc', 'google/protobuf/generated_message_reflection.cc', 'google/protobuf/field_mask.pb.cc', 'google/protobuf/extension_set_heavy.cc', 'google/protobuf/empty.pb.cc', 'google/protobuf/dynamic_message.cc', 'google/protobuf/duration.pb.cc', 'google/protobuf/descriptor_database.cc', 'google/protobuf/descriptor.pb.cc', 'google/protobuf/descriptor.cc', 'google/protobuf/compiler/parser.cc', 'google/protobuf/compiler/importer.cc', 'google/protobuf/api.pb.cc', 'google/protobuf/any.pb.cc', 'google/protobuf/any.cc', 'google/protobuf/wire_format_lite.cc', 'google/protobuf/stubs/time.cc', 'google/protobuf/stubs/strutil.cc', 'google/protobuf/stubs/structurally_valid.cc', 'google/protobuf/stubs/stringprintf.cc', 'google/protobuf/stubs/stringpiece.cc', 'google/protobuf/stubs/statusor.cc', 'google/protobuf/stubs/status.cc', 'google/protobuf/stubs/once.cc', 'google/protobuf/stubs/int128.cc', 'google/protobuf/stubs/common.cc', 'google/protobuf/stubs/bytestream.cc', 'google/protobuf/stubs/atomicops_internals_x86_msvc.cc', 'google/protobuf/stubs/atomicops_internals_x86_gcc.cc', 'google/protobuf/repeated_field.cc', 'google/protobuf/message_lite.cc', 'google/protobuf/io/zero_copy_stream_impl_lite.cc', 'google/protobuf/io/zero_copy_stream.cc', 'google/protobuf/io/coded_stream.cc', 'google/protobuf/generated_message_util.cc', 'google/protobuf/extension_set.cc', 'google/protobuf/arenastring.cc', 'google/protobuf/arena.cc']
+PROTO_FILES=['google/protobuf/wrappers.proto', 'google/protobuf/type.proto', 'google/protobuf/timestamp.proto', 'google/protobuf/struct.proto', 'google/protobuf/source_context.proto', 'google/protobuf/field_mask.proto', 'google/protobuf/empty.proto', 'google/protobuf/duration.proto', 'google/protobuf/descriptor.proto', 'google/protobuf/compiler/plugin.proto', 'google/protobuf/api.proto', 'google/protobuf/any.proto']
+
+CC_INCLUDE='third_party/protobuf/src'
+PROTO_INCLUDE='third_party/protobuf/src'
diff --git a/tools/distrib/python/grpcio_tools/setup.py b/tools/distrib/python/grpcio_tools/setup.py
index 576f7ae..fbe69f4 100644
--- a/tools/distrib/python/grpcio_tools/setup.py
+++ b/tools/distrib/python/grpcio_tools/setup.py
@@ -28,9 +28,11 @@
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 from distutils import extension
+import errno
 import os
 import os.path
 import shlex
+import shutil
 import sys
 
 import setuptools
@@ -47,18 +49,41 @@
 # ourselves in w.r.t. the multitude of operating systems this ought to build on.
 # By default we assume a GCC-like compiler.
 EXTRA_COMPILE_ARGS = shlex.split(os.environ.get('GRPC_PYTHON_CFLAGS',
-                                                '-frtti -std=c++11'))
+                                                '-fno-wrapv -frtti -std=c++11'))
 EXTRA_LINK_ARGS = shlex.split(os.environ.get('GRPC_PYTHON_LDFLAGS',
                                              '-lpthread'))
 
+GRPC_PYTHON_TOOLS_PACKAGE = 'grpc.tools'
+GRPC_PYTHON_PROTO_RESOURCES_NAME = '_proto'
+
 import protoc_lib_deps
 import grpc_version
 
+def package_data():
+  tools_path = GRPC_PYTHON_TOOLS_PACKAGE.replace('.', os.path.sep)
+  proto_resources_path = os.path.join(tools_path,
+                                      GRPC_PYTHON_PROTO_RESOURCES_NAME)
+  proto_files = []
+  for proto_file in protoc_lib_deps.PROTO_FILES:
+    source = os.path.join(protoc_lib_deps.PROTO_INCLUDE, proto_file)
+    target = os.path.join(proto_resources_path, proto_file)
+    relative_target = os.path.join(GRPC_PYTHON_PROTO_RESOURCES_NAME, proto_file)
+    try:
+      os.makedirs(os.path.dirname(target))
+    except OSError as error:
+      if error.errno == errno.EEXIST:
+        pass
+      else:
+        raise
+    shutil.copy(source, target)
+    proto_files.append(relative_target)
+  return {GRPC_PYTHON_TOOLS_PACKAGE: proto_files}
+
 def protoc_ext_module():
   plugin_sources = [
       'grpc/tools/main.cc',
       'grpc_root/src/compiler/python_generator.cc'] + [
-      os.path.join('third_party/protobuf/src', cc_file)
+      os.path.join(protoc_lib_deps.CC_INCLUDE, cc_file)
       for cc_file in protoc_lib_deps.CC_FILES]
   plugin_ext = extension.Extension(
       name='grpc.tools.protoc_compiler',
@@ -67,7 +92,7 @@
           '.',
           'grpc_root',
           'grpc_root/include',
-          'third_party/protobuf/src',
+          protoc_lib_deps.CC_INCLUDE,
       ],
       language='c++',
       define_macros=[('HAVE_PTHREAD', 1)],
@@ -88,9 +113,10 @@
       protoc_ext_module(),
   ]),
   packages=setuptools.find_packages('.'),
-  # TODO(atash): Figure out why auditwheel doesn't like namespace packages.
-  #namespace_packages=['grpc'],
+  namespace_packages=['grpc'],
   install_requires=[
     'protobuf>=3.0.0a3',
+    'grpcio>=0.14.0',
   ],
+  package_data=package_data(),
 )
diff --git a/tools/distrib/python/make_grpcio_tools.py b/tools/distrib/python/make_grpcio_tools.py
index 50fbdbb..fd9b38b 100755
--- a/tools/distrib/python/make_grpcio_tools.py
+++ b/tools/distrib/python/make_grpcio_tools.py
@@ -67,11 +67,16 @@
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 # AUTO-GENERATED BY make_grpcio_tools.py!
-CC_FILES={}
+CC_FILES={cc_files}
+PROTO_FILES={proto_files}
+
+CC_INCLUDE={cc_include}
+PROTO_INCLUDE={proto_include}
 """
 
 # Bazel query result prefix for expected source files in protobuf.
 PROTOBUF_CC_PREFIX = '//:src/'
+PROTOBUF_PROTO_PREFIX = '//:src/'
 
 GRPC_ROOT = os.path.abspath(
     os.path.join(os.path.dirname(os.path.abspath(__file__)),
@@ -79,7 +84,8 @@
 
 GRPC_PYTHON_ROOT = os.path.join(GRPC_ROOT, 'tools/distrib/python/grpcio_tools')
 
-GRPC_PROTOBUF = os.path.join(GRPC_ROOT, 'third_party/protobuf/src')
+GRPC_PYTHON_PROTOBUF_RELATIVE_ROOT = 'third_party/protobuf/src'
+GRPC_PROTOBUF = os.path.join(GRPC_ROOT, GRPC_PYTHON_PROTOBUF_RELATIVE_ROOT)
 GRPC_PROTOC_PLUGINS = os.path.join(GRPC_ROOT, 'src/compiler')
 GRPC_PYTHON_PROTOBUF = os.path.join(GRPC_PYTHON_ROOT,
                                     'third_party/protobuf/src')
@@ -93,18 +99,29 @@
 
 BAZEL_DEPS = os.path.join(GRPC_ROOT, 'tools/distrib/python/bazel_deps.sh')
 BAZEL_DEPS_PROTOC_LIB_QUERY = '//:protoc_lib'
+BAZEL_DEPS_COMMON_PROTOS_QUERY = '//:well_known_protos'
 
 
-def get_deps(query):
+def bazel_query(query):
+  output = subprocess.check_output([BAZEL_DEPS, query])
+  return output.splitlines()
+
+def get_deps():
   """Write the result of the bazel query `query` against protobuf to
      `out_file`."""
-  output = subprocess.check_output([BAZEL_DEPS, query])
-  output = output.splitlines()
+  cc_files_output = bazel_query(BAZEL_DEPS_PROTOC_LIB_QUERY)
   cc_files = [
-      name for name in output
+      name[len(PROTOBUF_CC_PREFIX):] for name in cc_files_output
       if name.endswith('.cc') and name.startswith(PROTOBUF_CC_PREFIX)]
-  cc_files = [cc_file[len(PROTOBUF_CC_PREFIX):] for cc_file in cc_files]
-  deps_file_content = DEPS_FILE_CONTENT.format(cc_files)
+  proto_files_output = bazel_query(BAZEL_DEPS_COMMON_PROTOS_QUERY)
+  proto_files = [
+      name[len(PROTOBUF_PROTO_PREFIX):] for name in proto_files_output
+      if name.endswith('.proto') and name.startswith(PROTOBUF_PROTO_PREFIX)]
+  deps_file_content = DEPS_FILE_CONTENT.format(
+      cc_files=cc_files,
+      proto_files=proto_files,
+      cc_include=repr(GRPC_PYTHON_PROTOBUF_RELATIVE_ROOT),
+      proto_include=repr(GRPC_PYTHON_PROTOBUF_RELATIVE_ROOT))
   return deps_file_content
 
 
@@ -123,7 +140,7 @@
   shutil.copytree(GRPC_INCLUDE, GRPC_PYTHON_INCLUDE)
 
   try:
-    protoc_lib_deps_content = get_deps(BAZEL_DEPS_PROTOC_LIB_QUERY)
+    protoc_lib_deps_content = get_deps()
   except Exception as error:
     # We allow this script to succeed even if we couldn't get the dependencies,
     # as then we can assume that even without a successful bazel run the
diff --git a/tools/dockerfile/grpc_artifact_python_manylinux_x64/Dockerfile b/tools/dockerfile/grpc_artifact_python_manylinux_x64/Dockerfile
index 3e31a2b..1d4e8e1 100644
--- a/tools/dockerfile/grpc_artifact_python_manylinux_x64/Dockerfile
+++ b/tools/dockerfile/grpc_artifact_python_manylinux_x64/Dockerfile
@@ -41,3 +41,10 @@
 RUN /opt/python/cp34-cp34m/bin/pip install cython
 RUN /opt/python/cp35-cp35m/bin/pip install cython
 
+####################################################
+# Install auditwheel with fix for namespace packages
+RUN git clone https://github.com/pypa/auditwheel /usr/local/src/auditwheel
+RUN cd /usr/local/src/auditwheel && git checkout bf071b38c9fe78b025ea05c78b1cb61d7cb09939
+RUN /opt/python/cp35-cp35m/bin/pip install /usr/local/src/auditwheel
+RUN rm /usr/local/bin/auditwheel
+RUN cd /usr/local/bin && ln -s /opt/python/cp35-cp35m/bin/auditwheel
diff --git a/tools/dockerfile/grpc_artifact_python_manylinux_x86/Dockerfile b/tools/dockerfile/grpc_artifact_python_manylinux_x86/Dockerfile
index 5fe62c2..8104996 100644
--- a/tools/dockerfile/grpc_artifact_python_manylinux_x86/Dockerfile
+++ b/tools/dockerfile/grpc_artifact_python_manylinux_x86/Dockerfile
@@ -41,3 +41,10 @@
 RUN /opt/python/cp34-cp34m/bin/pip install cython
 RUN /opt/python/cp35-cp35m/bin/pip install cython
 
+####################################################
+# Install auditwheel with fix for namespace packages
+RUN git clone https://github.com/pypa/auditwheel /usr/local/src/auditwheel
+RUN cd /usr/local/src/auditwheel && git checkout bf071b38c9fe78b025ea05c78b1cb61d7cb09939
+RUN /opt/python/cp35-cp35m/bin/pip install /usr/local/src/auditwheel
+RUN rm /usr/local/bin/auditwheel
+RUN cd /usr/local/bin && ln -s /opt/python/cp35-cp35m/bin/auditwheel
diff --git a/src/python/grpcio/grpc/_adapter/_implementations.py b/tools/dockerfile/grpc_check_generated_pb_files/Dockerfile
similarity index 62%
copy from src/python/grpcio/grpc/_adapter/_implementations.py
copy to tools/dockerfile/grpc_check_generated_pb_files/Dockerfile
index b85f228..7658991 100644
--- a/src/python/grpcio/grpc/_adapter/_implementations.py
+++ b/tools/dockerfile/grpc_check_generated_pb_files/Dockerfile
@@ -27,22 +27,52 @@
 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-import collections
+FROM debian:jessie
 
-from grpc.beta import interfaces
+# 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
 
-class AuthMetadataContext(collections.namedtuple(
-    'AuthMetadataContext', [
-        'service_url',
-        'method_name'
-    ]), interfaces.GRPCAuthMetadataContext):
-  pass
+#================
+# Build profiling
+RUN apt-get update && apt-get install -y time && apt-get clean
 
+#=================
+# C++ dependencies
+RUN apt-get update && apt-get -y install libgflags-dev libgtest-dev libc++-dev clang && apt-get clean
 
-class AuthMetadataPluginCallback(interfaces.GRPCAuthMetadataContext):
+#======================
+# Zookeeper dependencies
+# TODO(jtattermusch): is zookeeper still needed?
+RUN apt-get install -y libzookeeper-mt-dev
 
-  def __init__(self, callback):
-    self._callback = callback
+RUN mkdir /var/local/jenkins
 
-  def __call__(self, metadata, error):
-    self._callback(metadata, error)
+# Define the default command.
+CMD ["bash"]
diff --git a/src/python/grpcio/grpc/_adapter/_implementations.py b/tools/dockerfile/grpc_check_generated_pb_files/check_pb_files.sh
old mode 100644
new mode 100755
similarity index 77%
rename from src/python/grpcio/grpc/_adapter/_implementations.py
rename to tools/dockerfile/grpc_check_generated_pb_files/check_pb_files.sh
index b85f228..62e4175
--- a/src/python/grpcio/grpc/_adapter/_implementations.py
+++ b/tools/dockerfile/grpc_check_generated_pb_files/check_pb_files.sh
@@ -1,3 +1,4 @@
+#!/bin/bash
 # Copyright 2015, Google Inc.
 # All rights reserved.
 #
@@ -27,22 +28,19 @@
 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-import collections
+set -e
 
-from grpc.beta import interfaces
+mkdir -p /var/local/git
+git clone --recursive /var/local/jenkins/grpc /var/local/git/grpc
 
-class AuthMetadataContext(collections.namedtuple(
-    'AuthMetadataContext', [
-        'service_url',
-        'method_name'
-    ]), interfaces.GRPCAuthMetadataContext):
-  pass
+cd /var/local/git/grpc
 
+# build grpc cpp plugin for generating grpc pb files
+make grpc_cpp_plugin
 
-class AuthMetadataPluginCallback(interfaces.GRPCAuthMetadataContext):
+# generate pb files
+tools/codegen/extensions/gen_reflection_proto.sh
 
-  def __init__(self, callback):
-    self._callback = callback
-
-  def __call__(self, metadata, error):
-    self._callback(metadata, error)
+# check if the pb files in the checked out codebase are identical with the newly
+# generated ones
+git diff --exit-code
diff --git a/tools/dockerfile/grpc_clang_format/clang_format_all_the_things.sh b/tools/dockerfile/grpc_clang_format/clang_format_all_the_things.sh
index 6f41559..eab7611 100755
--- a/tools/dockerfile/grpc_clang_format/clang_format_all_the_things.sh
+++ b/tools/dockerfile/grpc_clang_format/clang_format_all_the_things.sh
@@ -44,7 +44,7 @@
 do
   for glob in $GLOB
   do
-    files="$files `find /local-code/$dir -name $glob -and -not -name *.generated.* -and -not -name *.pb.h -and -not -name *.pb.c`"
+    files="$files `find /local-code/$dir -name $glob -and -not -name *.generated.* -and -not -name *.pb.h -and -not -name *.pb.c -and -not -name *.pb.cc`"
   done
 done
 
diff --git a/tools/dockerfile/test/cxx_ubuntu1604_x64/Dockerfile b/tools/dockerfile/test/cxx_ubuntu1604_x64/Dockerfile
index 02d3c0d..d356433 100644
--- a/tools/dockerfile/test/cxx_ubuntu1604_x64/Dockerfile
+++ b/tools/dockerfile/test/cxx_ubuntu1604_x64/Dockerfile
@@ -82,5 +82,11 @@
 
 RUN mkdir /var/local/jenkins
 
+
+# The clang-3.6 symlink for the default clang version was added
+# to Ubuntu 16.04 recently, so make sure it's installed.
+# Also install clang3.7.
+RUN apt-get update && apt-get -y install clang-3.6 clang-3.7 && apt-get clean
+
 # Define the default command.
 CMD ["bash"]
diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++
index 798d68b..7f9d2df 100644
--- a/tools/doxygen/Doxyfile.c++
+++ b/tools/doxygen/Doxyfile.c++
@@ -765,14 +765,15 @@
 include/grpc++/client_context.h \
 include/grpc++/completion_queue.h \
 include/grpc++/create_channel.h \
+include/grpc++/create_channel_posix.h \
 include/grpc++/generic/async_generic_service.h \
 include/grpc++/generic/generic_stub.h \
 include/grpc++/grpc++.h \
 include/grpc++/impl/call.h \
 include/grpc++/impl/client_unary_call.h \
+include/grpc++/impl/codegen/core_codegen.h \
 include/grpc++/impl/grpc_library.h \
 include/grpc++/impl/method_handler_impl.h \
-include/grpc++/impl/proto_utils.h \
 include/grpc++/impl/rpc_method.h \
 include/grpc++/impl/rpc_service_method.h \
 include/grpc++/impl/serialization_traits.h \
@@ -793,10 +794,12 @@
 include/grpc++/server.h \
 include/grpc++/server_builder.h \
 include/grpc++/server_context.h \
+include/grpc++/server_posix.h \
 include/grpc++/support/async_stream.h \
 include/grpc++/support/async_unary_call.h \
 include/grpc++/support/byte_buffer.h \
 include/grpc++/support/channel_arguments.h \
+include/grpc++/support/config.h \
 include/grpc++/support/slice.h \
 include/grpc++/support/status.h \
 include/grpc++/support/status_code_enum.h \
@@ -813,11 +816,11 @@
 include/grpc++/impl/codegen/client_unary_call.h \
 include/grpc++/impl/codegen/completion_queue.h \
 include/grpc++/impl/codegen/completion_queue_tag.h \
+include/grpc++/impl/codegen/config.h \
 include/grpc++/impl/codegen/core_codegen_interface.h \
 include/grpc++/impl/codegen/create_auth_context.h \
 include/grpc++/impl/codegen/grpc_library.h \
 include/grpc++/impl/codegen/method_handler_impl.h \
-include/grpc++/impl/codegen/proto_utils.h \
 include/grpc++/impl/codegen/rpc_method.h \
 include/grpc++/impl/codegen/rpc_service_method.h \
 include/grpc++/impl/codegen/security/auth_context.h \
@@ -845,7 +848,7 @@
 include/grpc/impl/codegen/atm.h \
 include/grpc/impl/codegen/atm_gcc_atomic.h \
 include/grpc/impl/codegen/atm_gcc_sync.h \
-include/grpc/impl/codegen/atm_win32.h \
+include/grpc/impl/codegen/atm_windows.h \
 include/grpc/impl/codegen/log.h \
 include/grpc/impl/codegen/port_platform.h \
 include/grpc/impl/codegen/slice.h \
@@ -853,12 +856,8 @@
 include/grpc/impl/codegen/sync.h \
 include/grpc/impl/codegen/sync_generic.h \
 include/grpc/impl/codegen/sync_posix.h \
-include/grpc/impl/codegen/sync_win32.h \
-include/grpc/impl/codegen/time.h \
-include/grpc++/impl/codegen/config.h \
-include/grpc++/impl/codegen/config_protobuf.h \
-include/grpc++/support/config.h \
-include/grpc++/support/config_protobuf.h
+include/grpc/impl/codegen/sync_windows.h \
+include/grpc/impl/codegen/time.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.c++.internal b/tools/doxygen/Doxyfile.c++.internal
index ce1d6ac..dcf1a4c 100644
--- a/tools/doxygen/Doxyfile.c++.internal
+++ b/tools/doxygen/Doxyfile.c++.internal
@@ -765,14 +765,15 @@
 include/grpc++/client_context.h \
 include/grpc++/completion_queue.h \
 include/grpc++/create_channel.h \
+include/grpc++/create_channel_posix.h \
 include/grpc++/generic/async_generic_service.h \
 include/grpc++/generic/generic_stub.h \
 include/grpc++/grpc++.h \
 include/grpc++/impl/call.h \
 include/grpc++/impl/client_unary_call.h \
+include/grpc++/impl/codegen/core_codegen.h \
 include/grpc++/impl/grpc_library.h \
 include/grpc++/impl/method_handler_impl.h \
-include/grpc++/impl/proto_utils.h \
 include/grpc++/impl/rpc_method.h \
 include/grpc++/impl/rpc_service_method.h \
 include/grpc++/impl/serialization_traits.h \
@@ -793,10 +794,12 @@
 include/grpc++/server.h \
 include/grpc++/server_builder.h \
 include/grpc++/server_context.h \
+include/grpc++/server_posix.h \
 include/grpc++/support/async_stream.h \
 include/grpc++/support/async_unary_call.h \
 include/grpc++/support/byte_buffer.h \
 include/grpc++/support/channel_arguments.h \
+include/grpc++/support/config.h \
 include/grpc++/support/slice.h \
 include/grpc++/support/status.h \
 include/grpc++/support/status_code_enum.h \
@@ -813,11 +816,11 @@
 include/grpc++/impl/codegen/client_unary_call.h \
 include/grpc++/impl/codegen/completion_queue.h \
 include/grpc++/impl/codegen/completion_queue_tag.h \
+include/grpc++/impl/codegen/config.h \
 include/grpc++/impl/codegen/core_codegen_interface.h \
 include/grpc++/impl/codegen/create_auth_context.h \
 include/grpc++/impl/codegen/grpc_library.h \
 include/grpc++/impl/codegen/method_handler_impl.h \
-include/grpc++/impl/codegen/proto_utils.h \
 include/grpc++/impl/codegen/rpc_method.h \
 include/grpc++/impl/codegen/rpc_service_method.h \
 include/grpc++/impl/codegen/security/auth_context.h \
@@ -845,7 +848,7 @@
 include/grpc/impl/codegen/atm.h \
 include/grpc/impl/codegen/atm_gcc_atomic.h \
 include/grpc/impl/codegen/atm_gcc_sync.h \
-include/grpc/impl/codegen/atm_win32.h \
+include/grpc/impl/codegen/atm_windows.h \
 include/grpc/impl/codegen/log.h \
 include/grpc/impl/codegen/port_platform.h \
 include/grpc/impl/codegen/slice.h \
@@ -853,14 +856,10 @@
 include/grpc/impl/codegen/sync.h \
 include/grpc/impl/codegen/sync_generic.h \
 include/grpc/impl/codegen/sync_posix.h \
-include/grpc/impl/codegen/sync_win32.h \
+include/grpc/impl/codegen/sync_windows.h \
 include/grpc/impl/codegen/time.h \
-include/grpc++/impl/codegen/config.h \
-include/grpc++/impl/codegen/config_protobuf.h \
-include/grpc++/support/config.h \
-include/grpc++/support/config_protobuf.h \
+include/grpc++/impl/codegen/core_codegen.h \
 src/cpp/client/secure_credentials.h \
-src/cpp/common/core_codegen.h \
 src/cpp/common/secure_auth_context.h \
 src/cpp/server/secure_server_credentials.h \
 src/cpp/client/create_channel_internal.h \
@@ -876,6 +875,7 @@
 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/generic_stub.cc \
 src/cpp/client/insecure_credentials.cc \
@@ -891,6 +891,7 @@
 src/cpp/server/server_builder.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/status.cc \
diff --git a/tools/doxygen/Doxyfile.c++.internal.orig b/tools/doxygen/Doxyfile.c++.internal.orig
new file mode 100644
index 0000000..c214b3d
--- /dev/null
+++ b/tools/doxygen/Doxyfile.c++.internal.orig
@@ -0,0 +1,2505 @@
+
+
+# Doxyfile 1.8.9.1
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project.
+#
+# All text after a double hash (##) is considered a comment and is placed in
+# front of the TAG it is preceding.
+#
+# All text after a single hash (#) is considered a comment and will be ignored.
+# The format is:
+# TAG = value [value, ...]
+# For lists, items can also be appended using:
+# TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (\" \").
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# This tag specifies the encoding used for all characters in the config file
+# that follow. The default is UTF-8 which is also the encoding used for all text
+# before the first occurrence of this tag. Doxygen uses libiconv (or the iconv
+# built into libc) for the transcoding. See http://www.gnu.org/software/libiconv
+# for the list of possible encodings.
+# The default value is: UTF-8.
+
+DOXYFILE_ENCODING      = UTF-8
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by
+# double-quotes, unless you are using Doxywizard) that should identify the
+# project for which the documentation is generated. This name is used in the
+# title of most generated pages and in a few other places.
+# The default value is: My Project.
+
+PROJECT_NAME           = "GRPC C++"
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number. This
+# could be handy for archiving the generated documentation or if some version
+# control system is used.
+
+PROJECT_NUMBER         = 0.15.0-dev
+
+# Using the PROJECT_BRIEF tag one can provide an optional one line description
+# for a project that appears at the top of each page and should give viewer a
+# quick idea about the purpose of the project. Keep the description short.
+
+PROJECT_BRIEF          =
+
+# With the PROJECT_LOGO tag one can specify a logo or an icon that is included
+# in the documentation. The maximum height of the logo should not exceed 55
+# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy
+# the logo to the output directory.
+
+PROJECT_LOGO           =
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path
+# into which the generated documentation will be written. If a relative path is
+# entered, it will be relative to the location where doxygen was started. If
+# left blank the current directory will be used.
+
+OUTPUT_DIRECTORY       = doc/ref/c++.internal
+
+# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub-
+# directories (in 2 levels) under the output directory of each output format and
+# will distribute the generated files over these directories. Enabling this
+# option can be useful when feeding doxygen a huge amount of source files, where
+# putting all generated files in the same directory would otherwise causes
+# performance problems for the file system.
+# The default value is: NO.
+
+CREATE_SUBDIRS         = NO
+
+# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII
+# characters to appear in the names of generated files. If set to NO, non-ASCII
+# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode
+# U+3044.
+# The default value is: NO.
+
+ALLOW_UNICODE_NAMES    = NO
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all
+# documentation generated by doxygen is written. Doxygen will use this
+# information to generate all constant output in the proper language.
+# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese,
+# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States),
+# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian,
+# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages),
+# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian,
+# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian,
+# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish,
+# Ukrainian and Vietnamese.
+# The default value is: English.
+
+OUTPUT_LANGUAGE        = English
+
+# If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member
+# descriptions after the members that are listed in the file and class
+# documentation (similar to Javadoc). Set to NO to disable this.
+# The default value is: YES.
+
+BRIEF_MEMBER_DESC      = YES
+
+# If the REPEAT_BRIEF tag is set to YES, doxygen will prepend the brief
+# description of a member or function before the detailed description
+#
+# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
+# brief descriptions will be completely suppressed.
+# The default value is: YES.
+
+REPEAT_BRIEF           = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator that is
+# used to form the text in various listings. Each string in this list, if found
+# as the leading text of the brief description, will be stripped from the text
+# and the result, after processing the whole list, is used as the annotated
+# text. Otherwise, the brief description is used as-is. If left blank, the
+# following values are used ($name is automatically replaced with the name of
+# the entity):The $name class, The $name widget, The $name file, is, provides,
+# specifies, contains, represents, a, an and the.
+
+ABBREVIATE_BRIEF       =
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
+# doxygen will generate a detailed section even if there is only a brief
+# description.
+# The default value is: NO.
+
+ALWAYS_DETAILED_SEC    = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
+# inherited members of a class in the documentation of that class as if those
+# members were ordinary class members. Constructors, destructors and assignment
+# operators of the base classes will not be shown.
+# The default value is: NO.
+
+INLINE_INHERITED_MEMB  = NO
+
+# If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path
+# before files name in the file list and in the header files. If set to NO the
+# shortest path that makes the file name unique will be used
+# The default value is: YES.
+
+FULL_PATH_NAMES        = YES
+
+# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path.
+# Stripping is only done if one of the specified strings matches the left-hand
+# part of the path. The tag can be used to show relative paths in the file list.
+# If left blank the directory from which doxygen is run is used as the path to
+# strip.
+#
+# Note that you can specify absolute paths here, but also relative paths, which
+# will be relative from the directory where doxygen is started.
+# This tag requires that the tag FULL_PATH_NAMES is set to YES.
+
+STRIP_FROM_PATH        =
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the
+# path mentioned in the documentation of a class, which tells the reader which
+# header file to include in order to use a class. If left blank only the name of
+# the header file containing the class definition is used. Otherwise one should
+# specify the list of include paths that are normally passed to the compiler
+# using the -I flag.
+
+STRIP_FROM_INC_PATH    =
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but
+# less readable) file names. This can be useful is your file systems doesn't
+# support long names like on DOS, Mac, or CD-ROM.
+# The default value is: NO.
+
+SHORT_NAMES            = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the
+# first line (until the first dot) of a Javadoc-style comment as the brief
+# description. If set to NO, the Javadoc-style will behave just like regular Qt-
+# style comments (thus requiring an explicit @brief command for a brief
+# description.)
+# The default value is: NO.
+
+JAVADOC_AUTOBRIEF      = YES
+
+# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first
+# line (until the first dot) of a Qt-style comment as the brief description. If
+# set to NO, the Qt-style will behave just like regular Qt-style comments (thus
+# requiring an explicit \brief command for a brief description.)
+# The default value is: NO.
+
+QT_AUTOBRIEF           = NO
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a
+# multi-line C++ special comment block (i.e. a block of //! or /// comments) as
+# a brief description. This used to be the default behavior. The new default is
+# to treat a multi-line C++ comment block as a detailed description. Set this
+# tag to YES if you prefer the old behavior instead.
+#
+# Note that setting this tag to YES also means that rational rose comments are
+# not recognized any more.
+# The default value is: NO.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the
+# documentation from any documented member that it re-implements.
+# The default value is: YES.
+
+INHERIT_DOCS           = YES
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES then doxygen will produce a new
+# page for each member. If set to NO, the documentation of a member will be part
+# of the file/class/namespace that contains it.
+# The default value is: NO.
+
+SEPARATE_MEMBER_PAGES  = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen
+# uses this value to replace tabs by spaces in code fragments.
+# Minimum value: 1, maximum value: 16, default value: 4.
+
+TAB_SIZE               = 2
+
+# This tag can be used to specify a number of aliases that act as commands in
+# the documentation. An alias has the form:
+# name=value
+# For example adding
+# "sideeffect=@par Side Effects:\n"
+# will allow you to put the command \sideeffect (or @sideeffect) in the
+# documentation, which will result in a user-defined paragraph with heading
+# "Side Effects:". You can put \n's in the value part of an alias to insert
+# newlines.
+
+ALIASES                =
+
+# This tag can be used to specify a number of word-keyword mappings (TCL only).
+# A mapping has the form "name=value". For example adding "class=itcl::class"
+# will allow you to use the command class in the itcl::class meaning.
+
+TCL_SUBST              =
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources
+# only. Doxygen will then generate output that is more tailored for C. For
+# instance, some of the names that are used will be different. The list of all
+# members will be omitted, etc.
+# The default value is: NO.
+
+OPTIMIZE_OUTPUT_FOR_C  = YES
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or
+# Python sources only. Doxygen will then generate output that is more tailored
+# for that language. For instance, namespaces will be presented as packages,
+# qualified scopes will look different, etc.
+# The default value is: NO.
+
+OPTIMIZE_OUTPUT_JAVA   = NO
+
+# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran
+# sources. Doxygen will then generate output that is tailored for Fortran.
+# The default value is: NO.
+
+OPTIMIZE_FOR_FORTRAN   = NO
+
+# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL
+# sources. Doxygen will then generate output that is tailored for VHDL.
+# The default value is: NO.
+
+OPTIMIZE_OUTPUT_VHDL   = NO
+
+# Doxygen selects the parser to use depending on the extension of the files it
+# parses. With this tag you can assign which parser to use for a given
+# extension. Doxygen has a built-in mapping, but you can override or extend it
+# using this tag. The format is ext=language, where ext is a file extension, and
+# language is one of the parsers supported by doxygen: IDL, Java, Javascript,
+# C#, C, C++, D, PHP, Objective-C, Python, Fortran (fixed format Fortran:
+# FortranFixed, free formatted Fortran: FortranFree, unknown formatted Fortran:
+# Fortran. In the later case the parser tries to guess whether the code is fixed
+# or free formatted code, this is the default for Fortran type files), VHDL. For
+# instance to make doxygen treat .inc files as Fortran files (default is PHP),
+# and .f files as C (default is Fortran), use: inc=Fortran f=C.
+#
+# Note: For files without extension you can use no_extension as a placeholder.
+#
+# Note that for custom extensions you also need to set FILE_PATTERNS otherwise
+# the files are not read by doxygen.
+
+EXTENSION_MAPPING      =
+
+# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments
+# according to the Markdown format, which allows for more readable
+# documentation. See http://daringfireball.net/projects/markdown/ for details.
+# The output of markdown processing is further processed by doxygen, so you can
+# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in
+# case of backward compatibilities issues.
+# The default value is: YES.
+
+MARKDOWN_SUPPORT       = YES
+
+# When enabled doxygen tries to link words that correspond to documented
+# classes, or namespaces to their corresponding documentation. Such a link can
+# be prevented in individual cases by putting a % sign in front of the word or
+# globally by setting AUTOLINK_SUPPORT to NO.
+# The default value is: YES.
+
+AUTOLINK_SUPPORT       = YES
+
+# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want
+# to include (a tag file for) the STL sources as input, then you should set this
+# tag to YES in order to let doxygen match functions declarations and
+# definitions whose arguments contain STL classes (e.g. func(std::string);
+# versus func(std::string) {}). This also make the inheritance and collaboration
+# diagrams that involve STL classes more complete and accurate.
+# The default value is: NO.
+
+BUILTIN_STL_SUPPORT    = NO
+
+# If you use Microsoft's C++/CLI language, you should set this option to YES to
+# enable parsing support.
+# The default value is: NO.
+
+CPP_CLI_SUPPORT        = NO
+
+# Set the SIP_SUPPORT tag to YES if your project consists of sip (see:
+# http://www.riverbankcomputing.co.uk/software/sip/intro) sources only. Doxygen
+# will parse them like normal C++ but will assume all classes use public instead
+# of private inheritance when no explicit protection keyword is present.
+# The default value is: NO.
+
+SIP_SUPPORT            = NO
+
+# For Microsoft's IDL there are propget and propput attributes to indicate
+# getter and setter methods for a property. Setting this option to YES will make
+# doxygen to replace the get and set methods by a property in the documentation.
+# This will only work if the methods are indeed getting or setting a simple
+# type. If this is not the case, or you want to show the methods anyway, you
+# should set this option to NO.
+# The default value is: YES.
+
+IDL_PROPERTY_SUPPORT   = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
+# tag is set to YES then doxygen will reuse the documentation of the first
+# member in the group (if any) for the other members of the group. By default
+# all members of a group must be documented explicitly.
+# The default value is: NO.
+
+DISTRIBUTE_GROUP_DOC   = NO
+
+# Set the SUBGROUPING tag to YES to allow class member groups of the same type
+# (for instance a group of public functions) to be put as a subgroup of that
+# type (e.g. under the Public Functions section). Set it to NO to prevent
+# subgrouping. Alternatively, this can be done per class using the
+# \nosubgrouping command.
+# The default value is: YES.
+
+SUBGROUPING            = YES
+
+# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions
+# are shown inside the group in which they are included (e.g. using \ingroup)
+# instead of on a separate page (for HTML and Man pages) or section (for LaTeX
+# and RTF).
+#
+# Note that this feature does not work in combination with
+# SEPARATE_MEMBER_PAGES.
+# The default value is: NO.
+
+INLINE_GROUPED_CLASSES = NO
+
+# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions
+# with only public data fields or simple typedef fields will be shown inline in
+# the documentation of the scope in which they are defined (i.e. file,
+# namespace, or group documentation), provided this scope is documented. If set
+# to NO, structs, classes, and unions are shown on a separate page (for HTML and
+# Man pages) or section (for LaTeX and RTF).
+# The default value is: NO.
+
+INLINE_SIMPLE_STRUCTS  = NO
+
+# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or
+# enum is documented as struct, union, or enum with the name of the typedef. So
+# typedef struct TypeS {} TypeT, will appear in the documentation as a struct
+# with name TypeT. When disabled the typedef will appear as a member of a file,
+# namespace, or class. And the struct will be named TypeS. This can typically be
+# useful for C code in case the coding convention dictates that all compound
+# types are typedef'ed and only the typedef is referenced, never the tag name.
+# The default value is: NO.
+
+TYPEDEF_HIDES_STRUCT   = NO
+
+# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This
+# cache is used to resolve symbols given their name and scope. Since this can be
+# an expensive process and often the same symbol appears multiple times in the
+# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small
+# doxygen will become slower. If the cache is too large, memory is wasted. The
+# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range
+# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536
+# symbols. At the end of a run doxygen will report the cache usage and suggest
+# the optimal cache size from a speed point of view.
+# Minimum value: 0, maximum value: 9, default value: 0.
+
+LOOKUP_CACHE_SIZE      = 0
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in
+# documentation are documented, even if no documentation was available. Private
+# class members and static file members will be hidden unless the
+# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES.
+# Note: This will also disable the warnings about undocumented members that are
+# normally produced when WARNINGS is set to YES.
+# The default value is: NO.
+
+EXTRACT_ALL            = YES
+
+# If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will
+# be included in the documentation.
+# The default value is: NO.
+
+EXTRACT_PRIVATE        = NO
+
+# If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal
+# scope will be included in the documentation.
+# The default value is: NO.
+
+EXTRACT_PACKAGE        = NO
+
+# If the EXTRACT_STATIC tag is set to YES, all static members of a file will be
+# included in the documentation.
+# The default value is: NO.
+
+EXTRACT_STATIC         = NO
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined
+# locally in source files will be included in the documentation. If set to NO,
+# only classes defined in header files are included. Does not have any effect
+# for Java sources.
+# The default value is: YES.
+
+EXTRACT_LOCAL_CLASSES  = YES
+
+# This flag is only useful for Objective-C code. If set to YES, local methods,
+# which are defined in the implementation section but not in the interface are
+# included in the documentation. If set to NO, only methods in the interface are
+# included.
+# The default value is: NO.
+
+EXTRACT_LOCAL_METHODS  = NO
+
+# If this flag is set to YES, the members of anonymous namespaces will be
+# extracted and appear in the documentation as a namespace called
+# 'anonymous_namespace{file}', where file will be replaced with the base name of
+# the file that contains the anonymous namespace. By default anonymous namespace
+# are hidden.
+# The default value is: NO.
+
+EXTRACT_ANON_NSPACES   = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all
+# undocumented members inside documented classes or files. If set to NO these
+# members will be included in the various overviews, but no documentation
+# section is generated. This option has no effect if EXTRACT_ALL is enabled.
+# The default value is: NO.
+
+HIDE_UNDOC_MEMBERS     = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all
+# undocumented classes that are normally visible in the class hierarchy. If set
+# to NO, these classes will be included in the various overviews. This option
+# has no effect if EXTRACT_ALL is enabled.
+# The default value is: NO.
+
+HIDE_UNDOC_CLASSES     = NO
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend
+# (class|struct|union) declarations. If set to NO, these declarations will be
+# included in the documentation.
+# The default value is: NO.
+
+HIDE_FRIEND_COMPOUNDS  = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any
+# documentation blocks found inside the body of a function. If set to NO, these
+# blocks will be appended to the function's detailed documentation block.
+# The default value is: NO.
+
+HIDE_IN_BODY_DOCS      = NO
+
+# The INTERNAL_DOCS tag determines if documentation that is typed after a
+# \internal command is included. If the tag is set to NO then the documentation
+# will be excluded. Set it to YES to include the internal documentation.
+# The default value is: NO.
+
+INTERNAL_DOCS          = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file
+# names in lower-case letters. If set to YES, upper-case letters are also
+# allowed. This is useful if you have classes or files whose names only differ
+# in case and if your file system supports case sensitive file names. Windows
+# and Mac users are advised to set this option to NO.
+# The default value is: system dependent.
+
+CASE_SENSE_NAMES       = NO
+
+# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with
+# their full class and namespace scopes in the documentation. If set to YES, the
+# scope will be hidden.
+# The default value is: NO.
+
+HIDE_SCOPE_NAMES       = NO
+
+# If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will
+# append additional text to a page's title, such as Class Reference. If set to
+# YES the compound reference will be hidden.
+# The default value is: NO.
+
+HIDE_COMPOUND_REFERENCE= NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of
+# the files that are included by a file in the documentation of that file.
+# The default value is: YES.
+
+SHOW_INCLUDE_FILES     = YES
+
+# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each
+# grouped member an include statement to the documentation, telling the reader
+# which file to include in order to use the member.
+# The default value is: NO.
+
+SHOW_GROUPED_MEMB_INC  = NO
+
+# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include
+# files with double quotes in the documentation rather than with sharp brackets.
+# The default value is: NO.
+
+FORCE_LOCAL_INCLUDES   = NO
+
+# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the
+# documentation for inline members.
+# The default value is: YES.
+
+INLINE_INFO            = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the
+# (detailed) documentation of file and class members alphabetically by member
+# name. If set to NO, the members will appear in declaration order.
+# The default value is: YES.
+
+SORT_MEMBER_DOCS       = YES
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief
+# descriptions of file, namespace and class members alphabetically by member
+# name. If set to NO, the members will appear in declaration order. Note that
+# this will also influence the order of the classes in the class list.
+# The default value is: NO.
+
+SORT_BRIEF_DOCS        = NO
+
+# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the
+# (brief and detailed) documentation of class members so that constructors and
+# destructors are listed first. If set to NO the constructors will appear in the
+# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS.
+# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief
+# member documentation.
+# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting
+# detailed member documentation.
+# The default value is: NO.
+
+SORT_MEMBERS_CTORS_1ST = NO
+
+# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy
+# of group names into alphabetical order. If set to NO the group names will
+# appear in their defined order.
+# The default value is: NO.
+
+SORT_GROUP_NAMES       = NO
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by
+# fully-qualified names, including namespaces. If set to NO, the class list will
+# be sorted only by class name, not including the namespace part.
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
+# Note: This option applies only to the class list, not to the alphabetical
+# list.
+# The default value is: NO.
+
+SORT_BY_SCOPE_NAME     = NO
+
+# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper
+# type resolution of all parameters of a function it will reject a match between
+# the prototype and the implementation of a member function even if there is
+# only one candidate or it is obvious which candidate to choose by doing a
+# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still
+# accept a match between prototype and implementation in such cases.
+# The default value is: NO.
+
+STRICT_PROTO_MATCHING  = NO
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo
+# list. This list is created by putting \todo commands in the documentation.
+# The default value is: YES.
+
+GENERATE_TODOLIST      = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or disable (NO) the test
+# list. This list is created by putting \test commands in the documentation.
+# The default value is: YES.
+
+GENERATE_TESTLIST      = YES
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or disable (NO) the bug
+# list. This list is created by putting \bug commands in the documentation.
+# The default value is: YES.
+
+GENERATE_BUGLIST       = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or disable (NO)
+# the deprecated list. This list is created by putting \deprecated commands in
+# the documentation.
+# The default value is: YES.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional documentation
+# sections, marked by \if <section_label> ... \endif and \cond <section_label>
+# ... \endcond blocks.
+
+ENABLED_SECTIONS       =
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the
+# initial value of a variable or macro / define can have for it to appear in the
+# documentation. If the initializer consists of more lines than specified here
+# it will be hidden. Use a value of 0 to hide initializers completely. The
+# appearance of the value of individual variables and macros / defines can be
+# controlled using \showinitializer or \hideinitializer command in the
+# documentation regardless of this setting.
+# Minimum value: 0, maximum value: 10000, default value: 30.
+
+MAX_INITIALIZER_LINES  = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at
+# the bottom of the documentation of classes and structs. If set to YES, the
+# list will mention the files that were used to generate the documentation.
+# The default value is: YES.
+
+SHOW_USED_FILES        = YES
+
+# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This
+# will remove the Files entry from the Quick Index and from the Folder Tree View
+# (if specified).
+# The default value is: YES.
+
+SHOW_FILES             = YES
+
+# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces
+# page. This will remove the Namespaces entry from the Quick Index and from the
+# Folder Tree View (if specified).
+# The default value is: YES.
+
+SHOW_NAMESPACES        = YES
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that
+# doxygen should invoke to get the current version for each file (typically from
+# the version control system). Doxygen will invoke the program by executing (via
+# popen()) the command command input-file, where command is the value of the
+# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided
+# by doxygen. Whatever the program writes to standard output is used as the file
+# version. For an example see the documentation.
+
+FILE_VERSION_FILTER    =
+
+# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed
+# by doxygen. The layout file controls the global structure of the generated
+# output files in an output format independent way. To create the layout file
+# that represents doxygen's defaults, run doxygen with the -l option. You can
+# optionally specify a file name after the option, if omitted DoxygenLayout.xml
+# will be used as the name of the layout file.
+#
+# Note that if you run doxygen from a directory containing a file called
+# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE
+# tag is left empty.
+
+LAYOUT_FILE            =
+
+# The CITE_BIB_FILES tag can be used to specify one or more bib files containing
+# the reference definitions. This must be a list of .bib files. The .bib
+# extension is automatically appended if omitted. This requires the bibtex tool
+# to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info.
+# For LaTeX the style of the bibliography can be controlled using
+# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the
+# search path. See also \cite for info how to create references.
+
+CITE_BIB_FILES         =
+
+#---------------------------------------------------------------------------
+# Configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated to
+# standard output by doxygen. If QUIET is set to YES this implies that the
+# messages are off.
+# The default value is: NO.
+
+QUIET                  = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are
+# generated to standard error (stderr) by doxygen. If WARNINGS is set to YES
+# this implies that the warnings are on.
+#
+# Tip: Turn warnings on while writing the documentation.
+# The default value is: YES.
+
+WARNINGS               = YES
+
+# If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate
+# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag
+# will automatically be disabled.
+# The default value is: YES.
+
+WARN_IF_UNDOCUMENTED   = YES
+
+# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for
+# potential errors in the documentation, such as not documenting some parameters
+# in a documented function, or documenting parameters that don't exist or using
+# markup commands wrongly.
+# The default value is: YES.
+
+WARN_IF_DOC_ERROR      = YES
+
+# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that
+# are documented, but have no documentation for their parameters or return
+# value. If set to NO, doxygen will only warn about wrong or incomplete
+# parameter documentation, but not about the absence of documentation.
+# The default value is: NO.
+
+WARN_NO_PARAMDOC       = NO
+
+# The WARN_FORMAT tag determines the format of the warning messages that doxygen
+# can produce. The string should contain the $file, $line, and $text tags, which
+# will be replaced by the file and line number from which the warning originated
+# and the warning text. Optionally the format may contain $version, which will
+# be replaced by the version of the file (if it could be obtained via
+# FILE_VERSION_FILTER)
+# The default value is: $file:$line: $text.
+
+WARN_FORMAT            = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning and error
+# messages should be written. If left blank the output is written to standard
+# error (stderr).
+
+WARN_LOGFILE           =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag is used to specify the files and/or directories that contain
+# documented source files. You may enter file names like myfile.cpp or
+# directories like /usr/src/myproject. Separate the files or directories with
+# spaces.
+# Note: If this tag is empty the current directory is searched.
+
+INPUT                  = include/grpc++/alarm.h \
+include/grpc++/channel.h \
+include/grpc++/client_context.h \
+include/grpc++/completion_queue.h \
+include/grpc++/create_channel.h \
+include/grpc++/generic/async_generic_service.h \
+include/grpc++/generic/generic_stub.h \
+include/grpc++/grpc++.h \
+include/grpc++/impl/call.h \
+include/grpc++/impl/client_unary_call.h \
+include/grpc++/impl/codegen/core_codegen.h \
+include/grpc++/impl/grpc_library.h \
+include/grpc++/impl/method_handler_impl.h \
+include/grpc++/impl/rpc_method.h \
+include/grpc++/impl/rpc_service_method.h \
+include/grpc++/impl/serialization_traits.h \
+include/grpc++/impl/server_builder_option.h \
+include/grpc++/impl/server_builder_plugin.h \
+include/grpc++/impl/server_initializer.h \
+include/grpc++/impl/service_type.h \
+include/grpc++/impl/sync.h \
+include/grpc++/impl/sync_cxx11.h \
+include/grpc++/impl/sync_no_cxx11.h \
+include/grpc++/impl/thd.h \
+include/grpc++/impl/thd_cxx11.h \
+include/grpc++/impl/thd_no_cxx11.h \
+include/grpc++/security/auth_context.h \
+include/grpc++/security/auth_metadata_processor.h \
+include/grpc++/security/credentials.h \
+include/grpc++/security/server_credentials.h \
+include/grpc++/server.h \
+include/grpc++/server_builder.h \
+include/grpc++/server_context.h \
+include/grpc++/support/async_stream.h \
+include/grpc++/support/async_unary_call.h \
+include/grpc++/support/byte_buffer.h \
+include/grpc++/support/channel_arguments.h \
+include/grpc++/support/config.h \
+include/grpc++/support/slice.h \
+include/grpc++/support/status.h \
+include/grpc++/support/status_code_enum.h \
+include/grpc++/support/string_ref.h \
+include/grpc++/support/stub_options.h \
+include/grpc++/support/sync_stream.h \
+include/grpc++/support/time.h \
+include/grpc++/impl/codegen/async_stream.h \
+include/grpc++/impl/codegen/async_unary_call.h \
+include/grpc++/impl/codegen/call.h \
+include/grpc++/impl/codegen/call_hook.h \
+include/grpc++/impl/codegen/channel_interface.h \
+include/grpc++/impl/codegen/client_context.h \
+include/grpc++/impl/codegen/client_unary_call.h \
+include/grpc++/impl/codegen/completion_queue.h \
+include/grpc++/impl/codegen/completion_queue_tag.h \
+include/grpc++/impl/codegen/config.h \
+include/grpc++/impl/codegen/core_codegen_interface.h \
+include/grpc++/impl/codegen/create_auth_context.h \
+include/grpc++/impl/codegen/grpc_library.h \
+include/grpc++/impl/codegen/method_handler_impl.h \
+include/grpc++/impl/codegen/rpc_method.h \
+include/grpc++/impl/codegen/rpc_service_method.h \
+include/grpc++/impl/codegen/security/auth_context.h \
+include/grpc++/impl/codegen/serialization_traits.h \
+include/grpc++/impl/codegen/server_context.h \
+include/grpc++/impl/codegen/server_interface.h \
+include/grpc++/impl/codegen/service_type.h \
+include/grpc++/impl/codegen/status.h \
+include/grpc++/impl/codegen/status_code_enum.h \
+include/grpc++/impl/codegen/string_ref.h \
+include/grpc++/impl/codegen/stub_options.h \
+include/grpc++/impl/codegen/sync.h \
+include/grpc++/impl/codegen/sync_cxx11.h \
+include/grpc++/impl/codegen/sync_no_cxx11.h \
+include/grpc++/impl/codegen/sync_stream.h \
+include/grpc++/impl/codegen/time.h \
+include/grpc/impl/codegen/byte_buffer.h \
+include/grpc/impl/codegen/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/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 \
+<<<<<<< HEAD
+include/grpc++/impl/codegen/config.h \
+include/grpc++/impl/codegen/config_protobuf.h \
+include/grpc++/support/config.h \
+include/grpc++/support/config_protobuf.h \
+include/grpc++/impl/codegen/core_codegen.h \
+=======
+>>>>>>> d30d4e279c4a63effaa6e912fc00bd4ad96054c7
+src/cpp/client/secure_credentials.h \
+src/cpp/common/secure_auth_context.h \
+src/cpp/server/secure_server_credentials.h \
+src/cpp/client/create_channel_internal.h \
+src/cpp/server/dynamic_thread_pool.h \
+src/cpp/server/thread_pool_interface.h \
+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/secure_server_credentials.cc \
+src/cpp/client/channel.cc \
+src/cpp/client/client_context.cc \
+src/cpp/client/create_channel.cc \
+src/cpp/client/create_channel_internal.cc \
+src/cpp/client/credentials.cc \
+src/cpp/client/generic_stub.cc \
+src/cpp/client/insecure_credentials.cc \
+src/cpp/common/channel_arguments.cc \
+src/cpp/common/completion_queue.cc \
+src/cpp/common/core_codegen.cc \
+src/cpp/common/rpc_method.cc \
+src/cpp/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_context.cc \
+src/cpp/server/server_credentials.cc \
+src/cpp/util/byte_buffer.cc \
+src/cpp/util/slice.cc \
+src/cpp/util/status.cc \
+src/cpp/util/string_ref.cc \
+src/cpp/util/time.cc \
+src/cpp/codegen/codegen_init.cc
+
+# This tag can be used to specify the character encoding of the source files
+# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
+# libiconv (or the iconv built into libc) for the transcoding. See the libiconv
+# documentation (see: http://www.gnu.org/software/libiconv) for the list of
+# possible encodings.
+# The default value is: UTF-8.
+
+INPUT_ENCODING         = UTF-8
+
+# If the value of the INPUT tag contains directories, you can use the
+# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and
+# *.h) to filter out the source-files in the directories. If left blank the
+# following patterns are tested:*.c, *.cc, *.cxx, *.cpp, *.c++, *.java, *.ii,
+# *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, *.hh, *.hxx, *.hpp,
+# *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, *.m, *.markdown,
+# *.md, *.mm, *.dox, *.py, *.f90, *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf,
+# *.qsf, *.as and *.js.
+
+FILE_PATTERNS          =
+
+# The RECURSIVE tag can be used to specify whether or not subdirectories should
+# be searched for input files as well.
+# The default value is: NO.
+
+RECURSIVE              = NO
+
+# The EXCLUDE tag can be used to specify files and/or directories that should be
+# excluded from the INPUT source files. This way you can easily exclude a
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+#
+# Note that relative paths are relative to the directory from which doxygen is
+# run.
+
+EXCLUDE                =
+
+# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
+# directories that are symbolic links (a Unix file system feature) are excluded
+# from the input.
+# The default value is: NO.
+
+EXCLUDE_SYMLINKS       = NO
+
+# If the value of the INPUT tag contains directories, you can use the
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
+# certain files from those directories.
+#
+# Note that the wildcards are matched against the file with absolute path, so to
+# exclude all test directories for example use the pattern */test/*
+
+EXCLUDE_PATTERNS       =
+
+# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
+# (namespaces, classes, functions, etc.) that should be excluded from the
+# output. The symbol name can be a fully qualified name, a word, or if the
+# wildcard * is used, a substring. Examples: ANamespace, AClass,
+# AClass::ANamespace, ANamespace::*Test
+#
+# Note that the wildcards are matched against the file with absolute path, so to
+# exclude all test directories use the pattern */test/*
+
+EXCLUDE_SYMBOLS        =
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or directories
+# that contain example code fragments that are included (see the \include
+# command).
+
+EXAMPLE_PATH           =
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and
+# *.h) to filter out the source-files in the directories. If left blank all
+# files are included.
+
+EXAMPLE_PATTERNS       =
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
+# searched for input files to be used with the \include or \dontinclude commands
+# irrespective of the value of the RECURSIVE tag.
+# The default value is: NO.
+
+EXAMPLE_RECURSIVE      = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or directories
+# that contain images that are to be included in the documentation (see the
+# \image command).
+
+IMAGE_PATH             =
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should
+# invoke to filter for each input file. Doxygen will invoke the filter program
+# by executing (via popen()) the command:
+#
+# <filter> <input-file>
+#
+# where <filter> is the value of the INPUT_FILTER tag, and <input-file> is the
+# name of an input file. Doxygen will then use the output that the filter
+# program writes to standard output. If FILTER_PATTERNS is specified, this tag
+# will be ignored.
+#
+# Note that the filter must not add or remove lines; it is applied before the
+# code is scanned, but not when the output code is generated. If lines are added
+# or removed, the anchors will not be placed correctly.
+
+INPUT_FILTER           =
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
+# basis. Doxygen will compare the file name with each pattern and apply the
+# filter if there is a match. The filters are a list of the form: pattern=filter
+# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how
+# filters are used. If the FILTER_PATTERNS tag is empty or if none of the
+# patterns match the file name, INPUT_FILTER is applied.
+
+FILTER_PATTERNS        =
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
+# INPUT_FILTER) will also be used to filter the input files that are used for
+# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES).
+# The default value is: NO.
+
+FILTER_SOURCE_FILES    = NO
+
+# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file
+# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and
+# it is also possible to disable source filtering for a specific pattern using
+# *.ext= (so without naming a filter).
+# This tag requires that the tag FILTER_SOURCE_FILES is set to YES.
+
+FILTER_SOURCE_PATTERNS =
+
+# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that
+# is part of the input, its contents will be placed on the main page
+# (index.html). This can be useful if you have a project on for instance GitHub
+# and want to reuse the introduction page also for the doxygen output.
+
+USE_MDFILE_AS_MAINPAGE =
+
+#---------------------------------------------------------------------------
+# Configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will be
+# generated. Documented entities will be cross-referenced with these sources.
+#
+# Note: To get rid of all source code in the generated output, make sure that
+# also VERBATIM_HEADERS is set to NO.
+# The default value is: NO.
+
+SOURCE_BROWSER         = NO
+
+# Setting the INLINE_SOURCES tag to YES will include the body of functions,
+# classes and enums directly into the documentation.
+# The default value is: NO.
+
+INLINE_SOURCES         = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any
+# special comment blocks from generated source code fragments. Normal C, C++ and
+# Fortran comments will always remain visible.
+# The default value is: YES.
+
+STRIP_CODE_COMMENTS    = YES
+
+# If the REFERENCED_BY_RELATION tag is set to YES then for each documented
+# function all documented functions referencing it will be listed.
+# The default value is: NO.
+
+REFERENCED_BY_RELATION = NO
+
+# If the REFERENCES_RELATION tag is set to YES then for each documented function
+# all documented entities called/used by that function will be listed.
+# The default value is: NO.
+
+REFERENCES_RELATION    = NO
+
+# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set
+# to YES then the hyperlinks from functions in REFERENCES_RELATION and
+# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will
+# link to the documentation.
+# The default value is: YES.
+
+REFERENCES_LINK_SOURCE = YES
+
+# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the
+# source code will show a tooltip with additional information such as prototype,
+# brief description and links to the definition and documentation. Since this
+# will make the HTML file larger and loading of large files a bit slower, you
+# can opt to disable this feature.
+# The default value is: YES.
+# This tag requires that the tag SOURCE_BROWSER is set to YES.
+
+SOURCE_TOOLTIPS        = YES
+
+# If the USE_HTAGS tag is set to YES then the references to source code will
+# point to the HTML generated by the htags(1) tool instead of doxygen built-in
+# source browser. The htags tool is part of GNU's global source tagging system
+# (see http://www.gnu.org/software/global/global.html). You will need version
+# 4.8.6 or higher.
+#
+# To use it do the following:
+# - Install the latest version of global
+# - Enable SOURCE_BROWSER and USE_HTAGS in the config file
+# - Make sure the INPUT points to the root of the source tree
+# - Run doxygen as normal
+#
+# Doxygen will invoke htags (and that will in turn invoke gtags), so these
+# tools must be available from the command line (i.e. in the search path).
+#
+# The result: instead of the source browser generated by doxygen, the links to
+# source code will now point to the output of htags.
+# The default value is: NO.
+# This tag requires that the tag SOURCE_BROWSER is set to YES.
+
+USE_HTAGS              = NO
+
+# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a
+# verbatim copy of the header file for each class for which an include is
+# specified. Set to NO to disable this.
+# See also: Section \class.
+# The default value is: YES.
+
+VERBATIM_HEADERS       = YES
+
+#---------------------------------------------------------------------------
+# Configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all
+# compounds will be generated. Enable this if the project contains a lot of
+# classes, structs, unions or interfaces.
+# The default value is: YES.
+
+ALPHABETICAL_INDEX     = YES
+
+# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in
+# which the alphabetical index list will be split.
+# Minimum value: 1, maximum value: 20, default value: 5.
+# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
+
+COLS_IN_ALPHA_INDEX    = 5
+
+# In case all classes in a project start with a common prefix, all classes will
+# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag
+# can be used to specify a prefix (or a list of prefixes) that should be ignored
+# while generating the index headers.
+# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
+
+IGNORE_PREFIX          =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output
+# The default value is: YES.
+
+GENERATE_HTML          = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: html.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_OUTPUT            = html
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each
+# generated HTML page (for example: .htm, .php, .asp).
+# The default value is: .html.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_FILE_EXTENSION    = .html
+
+# The HTML_HEADER tag can be used to specify a user-defined HTML header file for
+# each generated HTML page. If the tag is left blank doxygen will generate a
+# standard header.
+#
+# To get valid HTML the header file that includes any scripts and style sheets
+# that doxygen needs, which is dependent on the configuration options used (e.g.
+# the setting GENERATE_TREEVIEW). It is highly recommended to start with a
+# default header using
+# doxygen -w html new_header.html new_footer.html new_stylesheet.css
+# YourConfigFile
+# and then modify the file new_header.html. See also section "Doxygen usage"
+# for information on how to generate the default header that doxygen normally
+# uses.
+# Note: The header is subject to change so you typically have to regenerate the
+# default header when upgrading to a newer version of doxygen. For a description
+# of the possible markers and block names see the documentation.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_HEADER            =
+
+# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each
+# generated HTML page. If the tag is left blank doxygen will generate a standard
+# footer. See HTML_HEADER for more information on how to generate a default
+# footer and what special commands can be used inside the footer. See also
+# section "Doxygen usage" for information on how to generate the default footer
+# that doxygen normally uses.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_FOOTER            =
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style
+# sheet that is used by each HTML page. It can be used to fine-tune the look of
+# the HTML output. If left blank doxygen will generate a default style sheet.
+# See also section "Doxygen usage" for information on how to generate the style
+# sheet that doxygen normally uses.
+# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as
+# it is more robust and this tag (HTML_STYLESHEET) will in the future become
+# obsolete.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_STYLESHEET        =
+
+# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined
+# cascading style sheets that are included after the standard style sheets
+# created by doxygen. Using this option one can overrule certain style aspects.
+# This is preferred over using HTML_STYLESHEET since it does not replace the
+# standard style sheet and is therefore more robust against future updates.
+# Doxygen will copy the style sheet files to the output directory.
+# Note: The order of the extra style sheet files is of importance (e.g. the last
+# style sheet in the list overrules the setting of the previous ones in the
+# list). For an example see the documentation.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_EXTRA_STYLESHEET  =
+
+# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or
+# other source files which should be copied to the HTML output directory. Note
+# that these files will be copied to the base HTML output directory. Use the
+# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these
+# files. In the HTML_STYLESHEET file, use the file name only. Also note that the
+# files will be copied as-is; there are no commands or markers available.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_EXTRA_FILES       =
+
+# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen
+# will adjust the colors in the style sheet and background images according to
+# this color. Hue is specified as an angle on a colorwheel, see
+# http://en.wikipedia.org/wiki/Hue for more information. For instance the value
+# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300
+# purple, and 360 is red again.
+# Minimum value: 0, maximum value: 359, default value: 220.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_COLORSTYLE_HUE    = 220
+
+# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors
+# in the HTML output. For a value of 0 the output will use grayscales only. A
+# value of 255 will produce the most vivid colors.
+# Minimum value: 0, maximum value: 255, default value: 100.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_COLORSTYLE_SAT    = 100
+
+# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the
+# luminance component of the colors in the HTML output. Values below 100
+# gradually make the output lighter, whereas values above 100 make the output
+# darker. The value divided by 100 is the actual gamma applied, so 80 represents
+# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not
+# change the gamma.
+# Minimum value: 40, maximum value: 240, default value: 80.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_COLORSTYLE_GAMMA  = 80
+
+# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML
+# page will contain the date and time when the page was generated. Setting this
+# to NO can help when comparing the output of multiple runs.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_TIMESTAMP         = YES
+
+# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
+# documentation will contain sections that can be hidden and shown after the
+# page has loaded.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_DYNAMIC_SECTIONS  = NO
+
+# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries
+# shown in the various tree structured indices initially; the user can expand
+# and collapse entries dynamically later on. Doxygen will expand the tree to
+# such a level that at most the specified number of entries are visible (unless
+# a fully collapsed tree already exceeds this amount). So setting the number of
+# entries 1 will produce a full collapsed tree by default. 0 is a special value
+# representing an infinite number of entries and will result in a full expanded
+# tree by default.
+# Minimum value: 0, maximum value: 9999, default value: 100.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_INDEX_NUM_ENTRIES = 100
+
+# If the GENERATE_DOCSET tag is set to YES, additional index files will be
+# generated that can be used as input for Apple's Xcode 3 integrated development
+# environment (see: http://developer.apple.com/tools/xcode/), introduced with
+# OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a
+# Makefile in the HTML output directory. Running make will produce the docset in
+# that directory and running make install will install the docset in
+# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at
+# startup. See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html
+# for more information.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_DOCSET        = NO
+
+# This tag determines the name of the docset feed. A documentation feed provides
+# an umbrella under which multiple documentation sets from a single provider
+# (such as a company or product suite) can be grouped.
+# The default value is: Doxygen generated docs.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_FEEDNAME        = "Doxygen generated docs"
+
+# This tag specifies a string that should uniquely identify the documentation
+# set bundle. This should be a reverse domain-name style string, e.g.
+# com.mycompany.MyDocSet. Doxygen will append .docset to the name.
+# The default value is: org.doxygen.Project.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_BUNDLE_ID       = org.doxygen.Project
+
+# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify
+# the documentation publisher. This should be a reverse domain-name style
+# string, e.g. com.mycompany.MyDocSet.documentation.
+# The default value is: org.doxygen.Publisher.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_PUBLISHER_ID    = org.doxygen.Publisher
+
+# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher.
+# The default value is: Publisher.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_PUBLISHER_NAME  = Publisher
+
+# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three
+# additional HTML index files: index.hhp, index.hhc, and index.hhk. The
+# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop
+# (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on
+# Windows.
+#
+# The HTML Help Workshop contains a compiler that can convert all HTML output
+# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML
+# files are now used as the Windows 98 help format, and will replace the old
+# Windows help format (.hlp) on all Windows platforms in the future. Compressed
+# HTML files also contain an index, a table of contents, and you can search for
+# words in the documentation. The HTML workshop also contains a viewer for
+# compressed HTML files.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_HTMLHELP      = NO
+
+# The CHM_FILE tag can be used to specify the file name of the resulting .chm
+# file. You can add a path in front of the file if the result should not be
+# written to the html output directory.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+CHM_FILE               =
+
+# The HHC_LOCATION tag can be used to specify the location (absolute path
+# including file name) of the HTML help compiler (hhc.exe). If non-empty,
+# doxygen will try to run the HTML help compiler on the generated index.hhp.
+# The file has to be specified with full path.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+HHC_LOCATION           =
+
+# The GENERATE_CHI flag controls if a separate .chi index file is generated
+# (YES) or that it should be included in the master .chm file (NO).
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+GENERATE_CHI           = NO
+
+# The CHM_INDEX_ENCODING is used to encode HtmlHelp index (hhk), content (hhc)
+# and project file content.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+CHM_INDEX_ENCODING     =
+
+# The BINARY_TOC flag controls whether a binary table of contents is generated
+# (YES) or a normal table of contents (NO) in the .chm file. Furthermore it
+# enables the Previous and Next buttons.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+BINARY_TOC             = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members to
+# the table of contents of the HTML help documentation and to the tree view.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+TOC_EXPAND             = NO
+
+# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and
+# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that
+# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help
+# (.qch) of the generated HTML documentation.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_QHP           = NO
+
+# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify
+# the file name of the resulting .qch file. The path specified is relative to
+# the HTML output folder.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QCH_FILE               =
+
+# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help
+# Project output. For more information please see Qt Help Project / Namespace
+# (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#namespace).
+# The default value is: org.doxygen.Project.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_NAMESPACE          = org.doxygen.Project
+
+# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt
+# Help Project output. For more information please see Qt Help Project / Virtual
+# Folders (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#virtual-
+# folders).
+# The default value is: doc.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_VIRTUAL_FOLDER     = doc
+
+# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom
+# filter to add. For more information please see Qt Help Project / Custom
+# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-
+# filters).
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_CUST_FILTER_NAME   =
+
+# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the
+# custom filter to add. For more information please see Qt Help Project / Custom
+# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-
+# filters).
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_CUST_FILTER_ATTRS  =
+
+# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this
+# project's filter section matches. Qt Help Project / Filter Attributes (see:
+# http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes).
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_SECT_FILTER_ATTRS  =
+
+# The QHG_LOCATION tag can be used to specify the location of Qt's
+# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the
+# generated .qhp file.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHG_LOCATION           =
+
+# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be
+# generated, together with the HTML files, they form an Eclipse help plugin. To
+# install this plugin and make it available under the help contents menu in
+# Eclipse, the contents of the directory containing the HTML and XML files needs
+# to be copied into the plugins directory of eclipse. The name of the directory
+# within the plugins directory should be the same as the ECLIPSE_DOC_ID value.
+# After copying Eclipse needs to be restarted before the help appears.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_ECLIPSEHELP   = NO
+
+# A unique identifier for the Eclipse help plugin. When installing the plugin
+# the directory name containing the HTML and XML files should also have this
+# name. Each documentation set should have its own identifier.
+# The default value is: org.doxygen.Project.
+# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES.
+
+ECLIPSE_DOC_ID         = org.doxygen.Project
+
+# If you want full control over the layout of the generated HTML pages it might
+# be necessary to disable the index and replace it with your own. The
+# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top
+# of each HTML page. A value of NO enables the index and the value YES disables
+# it. Since the tabs in the index contain the same information as the navigation
+# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+DISABLE_INDEX          = NO
+
+# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
+# structure should be generated to display hierarchical information. If the tag
+# value is set to YES, a side panel will be generated containing a tree-like
+# index structure (just like the one that is generated for HTML Help). For this
+# to work a browser that supports JavaScript, DHTML, CSS and frames is required
+# (i.e. any modern browser). Windows users are probably better off using the
+# HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can
+# further fine-tune the look of the index. As an example, the default style
+# sheet generated by doxygen has an example that shows how to put an image at
+# the root of the tree instead of the PROJECT_NAME. Since the tree basically has
+# the same information as the tab index, you could consider setting
+# DISABLE_INDEX to YES when enabling this option.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_TREEVIEW      = NO
+
+# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that
+# doxygen will group on one line in the generated HTML documentation.
+#
+# Note that a value of 0 will completely suppress the enum values from appearing
+# in the overview section.
+# Minimum value: 0, maximum value: 20, default value: 4.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+ENUM_VALUES_PER_LINE   = 4
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used
+# to set the initial width (in pixels) of the frame in which the tree is shown.
+# Minimum value: 0, maximum value: 1500, default value: 250.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+TREEVIEW_WIDTH         = 250
+
+# If the EXT_LINKS_IN_WINDOW option is set to YES, doxygen will open links to
+# external symbols imported via tag files in a separate window.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+EXT_LINKS_IN_WINDOW    = NO
+
+# Use this tag to change the font size of LaTeX formulas included as images in
+# the HTML documentation. When you change the font size after a successful
+# doxygen run you need to manually remove any form_*.png images from the HTML
+# output directory to force them to be regenerated.
+# Minimum value: 8, maximum value: 50, default value: 10.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+FORMULA_FONTSIZE       = 10
+
+# Use the FORMULA_TRANPARENT tag to determine whether or not the images
+# generated for formulas are transparent PNGs. Transparent PNGs are not
+# supported properly for IE 6.0, but are supported on all modern browsers.
+#
+# Note that when changing this option you need to delete any form_*.png files in
+# the HTML output directory before the changes have effect.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+FORMULA_TRANSPARENT    = YES
+
+# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see
+# http://www.mathjax.org) which uses client side Javascript for the rendering
+# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX
+# installed or if you want to formulas look prettier in the HTML output. When
+# enabled you may also need to install MathJax separately and configure the path
+# to it using the MATHJAX_RELPATH option.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+USE_MATHJAX            = NO
+
+# When MathJax is enabled you can set the default output format to be used for
+# the MathJax output. See the MathJax site (see:
+# http://docs.mathjax.org/en/latest/output.html) for more details.
+# Possible values are: HTML-CSS (which is slower, but has the best
+# compatibility), NativeMML (i.e. MathML) and SVG.
+# The default value is: HTML-CSS.
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_FORMAT         = HTML-CSS
+
+# When MathJax is enabled you need to specify the location relative to the HTML
+# output directory using the MATHJAX_RELPATH option. The destination directory
+# should contain the MathJax.js script. For instance, if the mathjax directory
+# is located at the same level as the HTML output directory, then
+# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax
+# Content Delivery Network so you can quickly see the result without installing
+# MathJax. However, it is strongly recommended to install a local copy of
+# MathJax from http://www.mathjax.org before deployment.
+# The default value is: http://cdn.mathjax.org/mathjax/latest.
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_RELPATH        = http://cdn.mathjax.org/mathjax/latest
+
+# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax
+# extension names that should be enabled during MathJax rendering. For example
+# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_EXTENSIONS     =
+
+# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces
+# of code that will be used on startup of the MathJax code. See the MathJax site
+# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an
+# example see the documentation.
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_CODEFILE       =
+
+# When the SEARCHENGINE tag is enabled doxygen will generate a search box for
+# the HTML output. The underlying search engine uses javascript and DHTML and
+# should work on any modern browser. Note that when using HTML help
+# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET)
+# there is already a search function so this one should typically be disabled.
+# For large projects the javascript based search engine can be slow, then
+# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to
+# search using the keyboard; to jump to the search box use <access key> + S
+# (what the <access key> is depends on the OS and browser, but it is typically
+# <CTRL>, <ALT>/<option>, or both). Inside the search box use the <cursor down
+# key> to jump into the search results window, the results can be navigated
+# using the <cursor keys>. Press <Enter> to select an item or <escape> to cancel
+# the search. The filter options can be selected when the cursor is inside the
+# search box by pressing <Shift>+<cursor down>. Also here use the <cursor keys>
+# to select a filter and <Enter> or <escape> to activate or cancel the filter
+# option.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+SEARCHENGINE           = YES
+
+# When the SERVER_BASED_SEARCH tag is enabled the search engine will be
+# implemented using a web server instead of a web client using Javascript. There
+# are two flavors of web server based searching depending on the EXTERNAL_SEARCH
+# setting. When disabled, doxygen will generate a PHP script for searching and
+# an index file used by the script. When EXTERNAL_SEARCH is enabled the indexing
+# and searching needs to be provided by external tools. See the section
+# "External Indexing and Searching" for details.
+# The default value is: NO.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+SERVER_BASED_SEARCH    = NO
+
+# When EXTERNAL_SEARCH tag is enabled doxygen will no longer generate the PHP
+# script for searching. Instead the search results are written to an XML file
+# which needs to be processed by an external indexer. Doxygen will invoke an
+# external search engine pointed to by the SEARCHENGINE_URL option to obtain the
+# search results.
+#
+# Doxygen ships with an example indexer (doxyindexer) and search engine
+# (doxysearch.cgi) which are based on the open source search engine library
+# Xapian (see: http://xapian.org/).
+#
+# See the section "External Indexing and Searching" for details.
+# The default value is: NO.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+EXTERNAL_SEARCH        = NO
+
+# The SEARCHENGINE_URL should point to a search engine hosted by a web server
+# which will return the search results when EXTERNAL_SEARCH is enabled.
+#
+# Doxygen ships with an example indexer (doxyindexer) and search engine
+# (doxysearch.cgi) which are based on the open source search engine library
+# Xapian (see: http://xapian.org/). See the section "External Indexing and
+# Searching" for details.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+SEARCHENGINE_URL       =
+
+# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed
+# search data is written to a file for indexing by an external tool. With the
+# SEARCHDATA_FILE tag the name of this file can be specified.
+# The default file is: searchdata.xml.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+SEARCHDATA_FILE        = searchdata.xml
+
+# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the
+# EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is
+# useful in combination with EXTRA_SEARCH_MAPPINGS to search through multiple
+# projects and redirect the results back to the right project.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+EXTERNAL_SEARCH_ID     =
+
+# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen
+# projects other than the one defined by this configuration file, but that are
+# all added to the same external search index. Each project needs to have a
+# unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id of
+# to a relative location where the documentation can be found. The format is:
+# EXTRA_SEARCH_MAPPINGS = tagname1=loc1 tagname2=loc2 ...
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+EXTRA_SEARCH_MAPPINGS  =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES, doxygen will generate LaTeX output.
+# The default value is: YES.
+
+GENERATE_LATEX         = NO
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: latex.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_OUTPUT           = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
+# invoked.
+#
+# Note that when enabling USE_PDFLATEX this option is only used for generating
+# bitmaps for formulas in the HTML output, but not in the Makefile that is
+# written to the output directory.
+# The default file is: latex.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_CMD_NAME         = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to generate
+# index for LaTeX.
+# The default file is: makeindex.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+MAKEINDEX_CMD_NAME     = makeindex
+
+# If the COMPACT_LATEX tag is set to YES, doxygen generates more compact LaTeX
+# documents. This may be useful for small projects and may help to save some
+# trees in general.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+COMPACT_LATEX          = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used by the
+# printer.
+# Possible values are: a4 (210 x 297 mm), letter (8.5 x 11 inches), legal (8.5 x
+# 14 inches) and executive (7.25 x 10.5 inches).
+# The default value is: a4.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+PAPER_TYPE             = a4
+
+# The EXTRA_PACKAGES tag can be used to specify one or more LaTeX package names
+# that should be included in the LaTeX output. To get the times font for
+# instance you can specify
+# EXTRA_PACKAGES=times
+# If left blank no extra packages will be included.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+EXTRA_PACKAGES         =
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for the
+# generated LaTeX document. The header should contain everything until the first
+# chapter. If it is left blank doxygen will generate a standard header. See
+# section "Doxygen usage" for information on how to let doxygen write the
+# default header to a separate file.
+#
+# Note: Only use a user-defined header if you know what you are doing! The
+# following commands have a special meaning inside the header: $title,
+# $datetime, $date, $doxygenversion, $projectname, $projectnumber,
+# $projectbrief, $projectlogo. Doxygen will replace $title with the empty
+# string, for the replacement values of the other commands the user is referred
+# to HTML_HEADER.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_HEADER           =
+
+# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for the
+# generated LaTeX document. The footer should contain everything after the last
+# chapter. If it is left blank doxygen will generate a standard footer. See
+# LATEX_HEADER for more information on how to generate a default footer and what
+# special commands can be used inside the footer.
+#
+# Note: Only use a user-defined footer if you know what you are doing!
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_FOOTER           =
+
+# The LATEX_EXTRA_STYLESHEET tag can be used to specify additional user-defined
+# LaTeX style sheets that are included after the standard style sheets created
+# by doxygen. Using this option one can overrule certain style aspects. Doxygen
+# will copy the style sheet files to the output directory.
+# Note: The order of the extra style sheet files is of importance (e.g. the last
+# style sheet in the list overrules the setting of the previous ones in the
+# list).
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_EXTRA_STYLESHEET =
+
+# The LATEX_EXTRA_FILES tag can be used to specify one or more extra images or
+# other source files which should be copied to the LATEX_OUTPUT output
+# directory. Note that the files will be copied as-is; there are no commands or
+# markers available.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_EXTRA_FILES      =
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated is
+# prepared for conversion to PDF (using ps2pdf or pdflatex). The PDF file will
+# contain links (just like the HTML output) instead of page references. This
+# makes the output suitable for online browsing using a PDF viewer.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+PDF_HYPERLINKS         = YES
+
+# If the USE_PDFLATEX tag is set to YES, doxygen will use pdflatex to generate
+# the PDF file directly from the LaTeX files. Set this option to YES, to get a
+# higher quality PDF documentation.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+USE_PDFLATEX           = YES
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \batchmode
+# command to the generated LaTeX files. This will instruct LaTeX to keep running
+# if errors occur, instead of asking the user for help. This option is also used
+# when generating formulas in HTML.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_BATCHMODE        = NO
+
+# If the LATEX_HIDE_INDICES tag is set to YES then doxygen will not include the
+# index chapters (such as File Index, Compound Index, etc.) in the output.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_HIDE_INDICES     = NO
+
+# If the LATEX_SOURCE_CODE tag is set to YES then doxygen will include source
+# code with syntax highlighting in the LaTeX output.
+#
+# Note that which sources are shown also depends on other settings such as
+# SOURCE_BROWSER.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_SOURCE_CODE      = NO
+
+# The LATEX_BIB_STYLE tag can be used to specify the style to use for the
+# bibliography, e.g. plainnat, or ieeetr. See
+# http://en.wikipedia.org/wiki/BibTeX and \cite for more info.
+# The default value is: plain.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_BIB_STYLE        = plain
+
+#---------------------------------------------------------------------------
+# Configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES, doxygen will generate RTF output. The
+# RTF output is optimized for Word 97 and may not look too pretty with other RTF
+# readers/editors.
+# The default value is: NO.
+
+GENERATE_RTF           = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: rtf.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_OUTPUT             = rtf
+
+# If the COMPACT_RTF tag is set to YES, doxygen generates more compact RTF
+# documents. This may be useful for small projects and may help to save some
+# trees in general.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+COMPACT_RTF            = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated will
+# contain hyperlink fields. The RTF file will contain links (just like the HTML
+# output) instead of page references. This makes the output suitable for online
+# browsing using Word or some other Word compatible readers that support those
+# fields.
+#
+# Note: WordPad (write) and others do not support links.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_HYPERLINKS         = NO
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's config
+# file, i.e. a series of assignments. You only have to provide replacements,
+# missing definitions are set to their default value.
+#
+# See also section "Doxygen usage" for information on how to generate the
+# default style sheet that doxygen normally uses.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_STYLESHEET_FILE    =
+
+# Set optional variables used in the generation of an RTF document. Syntax is
+# similar to doxygen's config file. A template extensions file can be generated
+# using doxygen -e rtf extensionFile.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_EXTENSIONS_FILE    =
+
+# If the RTF_SOURCE_CODE tag is set to YES then doxygen will include source code
+# with syntax highlighting in the RTF output.
+#
+# Note that which sources are shown also depends on other settings such as
+# SOURCE_BROWSER.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_SOURCE_CODE        = NO
+
+#---------------------------------------------------------------------------
+# Configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES, doxygen will generate man pages for
+# classes and files.
+# The default value is: NO.
+
+GENERATE_MAN           = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it. A directory man3 will be created inside the directory specified by
+# MAN_OUTPUT.
+# The default directory is: man.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_OUTPUT             = man
+
+# The MAN_EXTENSION tag determines the extension that is added to the generated
+# man pages. In case the manual section does not start with a number, the number
+# 3 is prepended. The dot (.) at the beginning of the MAN_EXTENSION tag is
+# optional.
+# The default value is: .3.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_EXTENSION          = .3
+
+# The MAN_SUBDIR tag determines the name of the directory created within
+# MAN_OUTPUT in which the man pages are placed. If defaults to man followed by
+# MAN_EXTENSION with the initial . removed.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_SUBDIR             =
+
+# If the MAN_LINKS tag is set to YES and doxygen generates man output, then it
+# will generate one additional man file for each entity documented in the real
+# man page(s). These additional files only source the real man page, but without
+# them the man command would be unable to find the correct page.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_LINKS              = NO
+
+#---------------------------------------------------------------------------
+# Configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES, doxygen will generate an XML file that
+# captures the structure of the code including all documentation.
+# The default value is: NO.
+
+GENERATE_XML           = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: xml.
+# This tag requires that the tag GENERATE_XML is set to YES.
+
+XML_OUTPUT             = xml
+
+# If the XML_PROGRAMLISTING tag is set to YES, doxygen will dump the program
+# listings (including syntax highlighting and cross-referencing information) to
+# the XML output. Note that enabling this will significantly increase the size
+# of the XML output.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_XML is set to YES.
+
+XML_PROGRAMLISTING     = YES
+
+#---------------------------------------------------------------------------
+# Configuration options related to the DOCBOOK output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_DOCBOOK tag is set to YES, doxygen will generate Docbook files
+# that can be used to generate PDF.
+# The default value is: NO.
+
+GENERATE_DOCBOOK       = NO
+
+# The DOCBOOK_OUTPUT tag is used to specify where the Docbook pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be put in
+# front of it.
+# The default directory is: docbook.
+# This tag requires that the tag GENERATE_DOCBOOK is set to YES.
+
+DOCBOOK_OUTPUT         = docbook
+
+# If the DOCBOOK_PROGRAMLISTING tag is set to YES, doxygen will include the
+# program listings (including syntax highlighting and cross-referencing
+# information) to the DOCBOOK output. Note that enabling this will significantly
+# increase the size of the DOCBOOK output.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_DOCBOOK is set to YES.
+
+DOCBOOK_PROGRAMLISTING = NO
+
+#---------------------------------------------------------------------------
+# Configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES, doxygen will generate an
+# AutoGen Definitions (see http://autogen.sf.net) file that captures the
+# structure of the code including all documentation. Note that this feature is
+# still experimental and incomplete at the moment.
+# The default value is: NO.
+
+GENERATE_AUTOGEN_DEF   = NO
+
+#---------------------------------------------------------------------------
+# Configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES, doxygen will generate a Perl module
+# file that captures the structure of the code including all documentation.
+#
+# Note that this feature is still experimental and incomplete at the moment.
+# The default value is: NO.
+
+GENERATE_PERLMOD       = NO
+
+# If the PERLMOD_LATEX tag is set to YES, doxygen will generate the necessary
+# Makefile rules, Perl scripts and LaTeX code to be able to generate PDF and DVI
+# output from the Perl module output.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_PERLMOD is set to YES.
+
+PERLMOD_LATEX          = NO
+
+# If the PERLMOD_PRETTY tag is set to YES, the Perl module output will be nicely
+# formatted so it can be parsed by a human reader. This is useful if you want to
+# understand what is going on. On the other hand, if this tag is set to NO, the
+# size of the Perl module output will be much smaller and Perl will parse it
+# just the same.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_PERLMOD is set to YES.
+
+PERLMOD_PRETTY         = YES
+
+# The names of the make variables in the generated doxyrules.make file are
+# prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. This is useful
+# so different doxyrules.make files included by the same Makefile don't
+# overwrite each other's variables.
+# This tag requires that the tag GENERATE_PERLMOD is set to YES.
+
+PERLMOD_MAKEVAR_PREFIX =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES, doxygen will evaluate all
+# C-preprocessor directives found in the sources and include files.
+# The default value is: YES.
+
+ENABLE_PREPROCESSING   = YES
+
+# If the MACRO_EXPANSION tag is set to YES, doxygen will expand all macro names
+# in the source code. If set to NO, only conditional compilation will be
+# performed. Macro expansion can be done in a controlled way by setting
+# EXPAND_ONLY_PREDEF to YES.
+# The default value is: NO.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+MACRO_EXPANSION        = YES
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES then
+# the macro expansion is limited to the macros specified with the PREDEFINED and
+# EXPAND_AS_DEFINED tags.
+# The default value is: NO.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+EXPAND_ONLY_PREDEF     = NO
+
+# If the SEARCH_INCLUDES tag is set to YES, the include files in the
+# INCLUDE_PATH will be searched if a #include is found.
+# The default value is: YES.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+SEARCH_INCLUDES        = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that
+# contain include files that are not input files but should be processed by the
+# preprocessor.
+# This tag requires that the tag SEARCH_INCLUDES is set to YES.
+
+INCLUDE_PATH           =
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
+# patterns (like *.h and *.hpp) to filter out the header-files in the
+# directories. If left blank, the patterns specified with FILE_PATTERNS will be
+# used.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+INCLUDE_FILE_PATTERNS  =
+
+# The PREDEFINED tag can be used to specify one or more macro names that are
+# defined before the preprocessor is started (similar to the -D option of e.g.
+# gcc). The argument of the tag is a list of macros of the form: name or
+# name=definition (no spaces). If the definition and the "=" are omitted, "=1"
+# is assumed. To prevent a macro definition from being undefined via #undef or
+# recursively expanded use the := operator instead of the = operator.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+PREDEFINED             = GRPC_FINAL= GRPC_OVERIDE=
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
+# tag can be used to specify a list of macro names that should be expanded. The
+# macro definition that is found in the sources will be used. Use the PREDEFINED
+# tag if you want to use a different macro definition that overrules the
+# definition found in the source code.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+EXPAND_AS_DEFINED      =
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will
+# remove all references to function-like macros that are alone on a line, have
+# an all uppercase name, and do not end with a semicolon. Such function macros
+# are typically used for boiler-plate code, and will confuse the parser if not
+# removed.
+# The default value is: YES.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+SKIP_FUNCTION_MACROS   = YES
+
+#---------------------------------------------------------------------------
+# Configuration options related to external references
+#---------------------------------------------------------------------------
+
+# The TAGFILES tag can be used to specify one or more tag files. For each tag
+# file the location of the external documentation should be added. The format of
+# a tag file without this location is as follows:
+# TAGFILES = file1 file2 ...
+# Adding location for the tag files is done as follows:
+# TAGFILES = file1=loc1 "file2 = loc2" ...
+# where loc1 and loc2 can be relative or absolute paths or URLs. See the
+# section "Linking to external documentation" for more information about the use
+# of tag files.
+# Note: Each tag file must have a unique name (where the name does NOT include
+# the path). If a tag file is not located in the directory in which doxygen is
+# run, you must also specify the path to the tagfile here.
+
+TAGFILES               =
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create a
+# tag file that is based on the input files it reads. See section "Linking to
+# external documentation" for more information about the usage of tag files.
+
+GENERATE_TAGFILE       =
+
+# If the ALLEXTERNALS tag is set to YES, all external class will be listed in
+# the class index. If set to NO, only the inherited external classes will be
+# listed.
+# The default value is: NO.
+
+ALLEXTERNALS           = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES, all external groups will be listed
+# in the modules index. If set to NO, only the current project's groups will be
+# listed.
+# The default value is: YES.
+
+EXTERNAL_GROUPS        = YES
+
+# If the EXTERNAL_PAGES tag is set to YES, all external pages will be listed in
+# the related pages index. If set to NO, only the current project's pages will
+# be listed.
+# The default value is: YES.
+
+EXTERNAL_PAGES         = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script
+# interpreter (i.e. the result of 'which perl').
+# The default file (with absolute path) is: /usr/bin/perl.
+
+PERL_PATH              = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES, doxygen will generate a class diagram
+# (in HTML and LaTeX) for classes with base or super classes. Setting the tag to
+# NO turns the diagrams off. Note that this option also works with HAVE_DOT
+# disabled, but it is recommended to install and use dot, since it yields more
+# powerful graphs.
+# The default value is: YES.
+
+CLASS_DIAGRAMS         = YES
+
+# You can define message sequence charts within doxygen comments using the \msc
+# command. Doxygen will then run the mscgen tool (see:
+# http://www.mcternan.me.uk/mscgen/)) to produce the chart and insert it in the
+# documentation. The MSCGEN_PATH tag allows you to specify the directory where
+# the mscgen tool resides. If left empty the tool is assumed to be found in the
+# default search path.
+
+MSCGEN_PATH            =
+
+# You can include diagrams made with dia in doxygen documentation. Doxygen will
+# then run dia to produce the diagram and insert it in the documentation. The
+# DIA_PATH tag allows you to specify the directory where the dia binary resides.
+# If left empty dia is assumed to be found in the default search path.
+
+DIA_PATH               =
+
+# If set to YES the inheritance and collaboration graphs will hide inheritance
+# and usage relations if the target is undocumented or is not a class.
+# The default value is: YES.
+
+HIDE_UNDOC_RELATIONS   = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
+# available from the path. This tool is part of Graphviz (see:
+# http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent
+# Bell Labs. The other options in this section have no effect if this option is
+# set to NO
+# The default value is: NO.
+
+HAVE_DOT               = YES
+
+# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is allowed
+# to run in parallel. When set to 0 doxygen will base this on the number of
+# processors available in the system. You can set it explicitly to a value
+# larger than 0 to get control over the balance between CPU load and processing
+# speed.
+# Minimum value: 0, maximum value: 32, default value: 0.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_NUM_THREADS        = 0
+
+# When you want a differently looking font in the dot files that doxygen
+# generates you can specify the font name using DOT_FONTNAME. You need to make
+# sure dot is able to find the font, which can be done by putting it in a
+# standard location or by setting the DOTFONTPATH environment variable or by
+# setting DOT_FONTPATH to the directory containing the font.
+# The default value is: Helvetica.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_FONTNAME           = Helvetica
+
+# The DOT_FONTSIZE tag can be used to set the size (in points) of the font of
+# dot graphs.
+# Minimum value: 4, maximum value: 24, default value: 10.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_FONTSIZE           = 10
+
+# By default doxygen will tell dot to use the default font as specified with
+# DOT_FONTNAME. If you specify a different font using DOT_FONTNAME you can set
+# the path where dot can find it using this tag.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_FONTPATH           =
+
+# If the CLASS_GRAPH tag is set to YES then doxygen will generate a graph for
+# each documented class showing the direct and indirect inheritance relations.
+# Setting this tag to YES will force the CLASS_DIAGRAMS tag to NO.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+CLASS_GRAPH            = NO
+
+# If the COLLABORATION_GRAPH tag is set to YES then doxygen will generate a
+# graph for each documented class showing the direct and indirect implementation
+# dependencies (inheritance, containment, and class references variables) of the
+# class with other documented classes.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+COLLABORATION_GRAPH    = NO
+
+# If the GROUP_GRAPHS tag is set to YES then doxygen will generate a graph for
+# groups, showing the direct groups dependencies.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+GROUP_GRAPHS           = NO
+
+# If the UML_LOOK tag is set to YES, doxygen will generate inheritance and
+# collaboration diagrams in a style similar to the OMG's Unified Modeling
+# Language.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+UML_LOOK               = NO
+
+# If the UML_LOOK tag is enabled, the fields and methods are shown inside the
+# class node. If there are many fields or methods and many nodes the graph may
+# become too big to be useful. The UML_LIMIT_NUM_FIELDS threshold limits the
+# number of items for each type to make the size more manageable. Set this to 0
+# for no limit. Note that the threshold may be exceeded by 50% before the limit
+# is enforced. So when you set the threshold to 10, up to 15 fields may appear,
+# but if the number exceeds 15, the total amount of fields shown is limited to
+# 10.
+# Minimum value: 0, maximum value: 100, default value: 10.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+UML_LIMIT_NUM_FIELDS   = 10
+
+# If the TEMPLATE_RELATIONS tag is set to YES then the inheritance and
+# collaboration graphs will show the relations between templates and their
+# instances.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+TEMPLATE_RELATIONS     = NO
+
+# If the INCLUDE_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are set to
+# YES then doxygen will generate a graph for each documented file showing the
+# direct and indirect include dependencies of the file with other documented
+# files.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+INCLUDE_GRAPH          = NO
+
+# If the INCLUDED_BY_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are
+# set to YES then doxygen will generate a graph for each documented file showing
+# the direct and indirect include dependencies of the file with other documented
+# files.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+INCLUDED_BY_GRAPH      = NO
+
+# If the CALL_GRAPH tag is set to YES then doxygen will generate a call
+# dependency graph for every global function or class method.
+#
+# Note that enabling this option will significantly increase the time of a run.
+# So in most cases it will be better to enable call graphs for selected
+# functions only using the \callgraph command.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+CALL_GRAPH             = NO
+
+# If the CALLER_GRAPH tag is set to YES then doxygen will generate a caller
+# dependency graph for every global function or class method.
+#
+# Note that enabling this option will significantly increase the time of a run.
+# So in most cases it will be better to enable caller graphs for selected
+# functions only using the \callergraph command.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+CALLER_GRAPH           = NO
+
+# If the GRAPHICAL_HIERARCHY tag is set to YES then doxygen will graphical
+# hierarchy of all classes instead of a textual one.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+GRAPHICAL_HIERARCHY    = NO
+
+# If the DIRECTORY_GRAPH tag is set to YES then doxygen will show the
+# dependencies a directory has on other directories in a graphical way. The
+# dependency relations are determined by the #include relations between the
+# files in the directories.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DIRECTORY_GRAPH        = NO
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
+# generated by dot.
+# Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order
+# to make the SVG files visible in IE 9+ (other browsers do not have this
+# requirement).
+# Possible values are: png, jpg, gif and svg.
+# The default value is: png.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_IMAGE_FORMAT       = png
+
+# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to
+# enable generation of interactive SVG images that allow zooming and panning.
+#
+# Note that this requires a modern browser other than Internet Explorer. Tested
+# and working are Firefox, Chrome, Safari, and Opera.
+# Note: For IE 9+ you need to set HTML_FILE_EXTENSION to xhtml in order to make
+# the SVG files visible. Older versions of IE do not have SVG support.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+INTERACTIVE_SVG        = NO
+
+# The DOT_PATH tag can be used to specify the path where the dot tool can be
+# found. If left blank, it is assumed the dot tool can be found in the path.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_PATH               =
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that
+# contain dot files that are included in the documentation (see the \dotfile
+# command).
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOTFILE_DIRS           =
+
+# The MSCFILE_DIRS tag can be used to specify one or more directories that
+# contain msc files that are included in the documentation (see the \mscfile
+# command).
+
+MSCFILE_DIRS           =
+
+# The DIAFILE_DIRS tag can be used to specify one or more directories that
+# contain dia files that are included in the documentation (see the \diafile
+# command).
+
+DIAFILE_DIRS           =
+
+# When using plantuml, the PLANTUML_JAR_PATH tag should be used to specify the
+# path where java can find the plantuml.jar file. If left blank, it is assumed
+# PlantUML is not used or called during a preprocessing step. Doxygen will
+# generate a warning when it encounters a \startuml command in this case and
+# will not generate output for the diagram.
+
+PLANTUML_JAR_PATH      =
+
+# When using plantuml, the specified paths are searched for files specified by
+# the !include statement in a plantuml block.
+
+PLANTUML_INCLUDE_PATH  =
+
+# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of nodes
+# that will be shown in the graph. If the number of nodes in a graph becomes
+# larger than this value, doxygen will truncate the graph, which is visualized
+# by representing a node as a red box. Note that doxygen if the number of direct
+# children of the root node in a graph is already larger than
+# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note that
+# the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
+# Minimum value: 0, maximum value: 10000, default value: 50.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_GRAPH_MAX_NODES    = 50
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the graphs
+# generated by dot. A depth value of 3 means that only nodes reachable from the
+# root by following a path via at most 3 edges will be shown. Nodes that lay
+# further from the root node will be omitted. Note that setting this option to 1
+# or 2 may greatly reduce the computation time needed for large code bases. Also
+# note that the size of a graph can be further restricted by
+# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
+# Minimum value: 0, maximum value: 1000, default value: 0.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+MAX_DOT_GRAPH_DEPTH    = 0
+
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
+# background. This is disabled by default, because dot on Windows does not seem
+# to support this out of the box.
+#
+# Warning: Depending on the platform used, enabling this option may lead to
+# badly anti-aliased labels on the edges of a graph (i.e. they become hard to
+# read).
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_TRANSPARENT        = NO
+
+# Set the DOT_MULTI_TARGETS tag to YES to allow dot to generate multiple output
+# files in one run (i.e. multiple -o and -T options on the command line). This
+# makes dot run faster, but since only newer versions of dot (>1.8.10) support
+# this, this feature is disabled by default.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_MULTI_TARGETS      = NO
+
+# If the GENERATE_LEGEND tag is set to YES doxygen will generate a legend page
+# explaining the meaning of the various boxes and arrows in the dot generated
+# graphs.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+GENERATE_LEGEND        = YES
+
+# If the DOT_CLEANUP tag is set to YES, doxygen will remove the intermediate dot
+# files that are used to generate the various graphs.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_CLEANUP            = YES
+
diff --git a/tools/doxygen/Doxyfile.core b/tools/doxygen/Doxyfile.core
index aabca41..72102b2 100644
--- a/tools/doxygen/Doxyfile.core
+++ b/tools/doxygen/Doxyfile.core
@@ -764,6 +764,7 @@
 include/grpc/byte_buffer_reader.h \
 include/grpc/compression.h \
 include/grpc/grpc.h \
+include/grpc/grpc_posix.h \
 include/grpc/status.h \
 include/grpc/impl/codegen/byte_buffer.h \
 include/grpc/impl/codegen/byte_buffer_reader.h \
@@ -776,7 +777,7 @@
 include/grpc/impl/codegen/atm.h \
 include/grpc/impl/codegen/atm_gcc_atomic.h \
 include/grpc/impl/codegen/atm_gcc_sync.h \
-include/grpc/impl/codegen/atm_win32.h \
+include/grpc/impl/codegen/atm_windows.h \
 include/grpc/impl/codegen/log.h \
 include/grpc/impl/codegen/port_platform.h \
 include/grpc/impl/codegen/slice.h \
@@ -784,9 +785,8 @@
 include/grpc/impl/codegen/sync.h \
 include/grpc/impl/codegen/sync_generic.h \
 include/grpc/impl/codegen/sync_posix.h \
-include/grpc/impl/codegen/sync_win32.h \
+include/grpc/impl/codegen/sync_windows.h \
 include/grpc/impl/codegen/time.h \
-include/grpc/grpc_cronet.h \
 include/grpc/grpc_security.h \
 include/grpc/grpc_security_constants.h \
 include/grpc/census.h \
@@ -794,14 +794,14 @@
 include/grpc/support/atm.h \
 include/grpc/support/atm_gcc_atomic.h \
 include/grpc/support/atm_gcc_sync.h \
-include/grpc/support/atm_win32.h \
+include/grpc/support/atm_windows.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_win32.h \
+include/grpc/support/log_windows.h \
 include/grpc/support/port_platform.h \
 include/grpc/support/slice.h \
 include/grpc/support/slice_buffer.h \
@@ -810,7 +810,7 @@
 include/grpc/support/sync.h \
 include/grpc/support/sync_generic.h \
 include/grpc/support/sync_posix.h \
-include/grpc/support/sync_win32.h \
+include/grpc/support/sync_windows.h \
 include/grpc/support/thd.h \
 include/grpc/support/time.h \
 include/grpc/support/tls.h \
@@ -822,7 +822,7 @@
 include/grpc/impl/codegen/atm.h \
 include/grpc/impl/codegen/atm_gcc_atomic.h \
 include/grpc/impl/codegen/atm_gcc_sync.h \
-include/grpc/impl/codegen/atm_win32.h \
+include/grpc/impl/codegen/atm_windows.h \
 include/grpc/impl/codegen/log.h \
 include/grpc/impl/codegen/port_platform.h \
 include/grpc/impl/codegen/slice.h \
@@ -830,7 +830,7 @@
 include/grpc/impl/codegen/sync.h \
 include/grpc/impl/codegen/sync_generic.h \
 include/grpc/impl/codegen/sync_posix.h \
-include/grpc/impl/codegen/sync_win32.h \
+include/grpc/impl/codegen/sync_windows.h \
 include/grpc/impl/codegen/time.h
 
 # This tag can be used to specify the character encoding of the source files
diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal
index c3fd59b..10c8cbd 100644
--- a/tools/doxygen/Doxyfile.core.internal
+++ b/tools/doxygen/Doxyfile.core.internal
@@ -764,6 +764,7 @@
 include/grpc/byte_buffer_reader.h \
 include/grpc/compression.h \
 include/grpc/grpc.h \
+include/grpc/grpc_posix.h \
 include/grpc/status.h \
 include/grpc/impl/codegen/byte_buffer.h \
 include/grpc/impl/codegen/byte_buffer_reader.h \
@@ -776,7 +777,7 @@
 include/grpc/impl/codegen/atm.h \
 include/grpc/impl/codegen/atm_gcc_atomic.h \
 include/grpc/impl/codegen/atm_gcc_sync.h \
-include/grpc/impl/codegen/atm_win32.h \
+include/grpc/impl/codegen/atm_windows.h \
 include/grpc/impl/codegen/log.h \
 include/grpc/impl/codegen/port_platform.h \
 include/grpc/impl/codegen/slice.h \
@@ -784,9 +785,8 @@
 include/grpc/impl/codegen/sync.h \
 include/grpc/impl/codegen/sync_generic.h \
 include/grpc/impl/codegen/sync_posix.h \
-include/grpc/impl/codegen/sync_win32.h \
+include/grpc/impl/codegen/sync_windows.h \
 include/grpc/impl/codegen/time.h \
-include/grpc/grpc_cronet.h \
 include/grpc/grpc_security.h \
 include/grpc/grpc_security_constants.h \
 include/grpc/census.h \
@@ -807,6 +807,7 @@
 src/core/lib/iomgr/closure.h \
 src/core/lib/iomgr/endpoint.h \
 src/core/lib/iomgr/endpoint_pair.h \
+src/core/lib/iomgr/ev_poll_and_epoll_posix.h \
 src/core/lib/iomgr/ev_poll_posix.h \
 src/core/lib/iomgr/ev_posix.h \
 src/core/lib/iomgr/exec_ctx.h \
@@ -815,6 +816,7 @@
 src/core/lib/iomgr/iomgr.h \
 src/core/lib/iomgr/iomgr_internal.h \
 src/core/lib/iomgr/iomgr_posix.h \
+src/core/lib/iomgr/polling_entity.h \
 src/core/lib/iomgr/pollset.h \
 src/core/lib/iomgr/pollset_set.h \
 src/core/lib/iomgr/pollset_set_windows.h \
@@ -823,7 +825,7 @@
 src/core/lib/iomgr/sockaddr.h \
 src/core/lib/iomgr/sockaddr_posix.h \
 src/core/lib/iomgr/sockaddr_utils.h \
-src/core/lib/iomgr/sockaddr_win32.h \
+src/core/lib/iomgr/sockaddr_windows.h \
 src/core/lib/iomgr/socket_utils_posix.h \
 src/core/lib/iomgr/socket_windows.h \
 src/core/lib/iomgr/tcp_client.h \
@@ -923,16 +925,18 @@
 src/core/ext/client_config/subchannel_call_holder.h \
 src/core/ext/client_config/subchannel_index.h \
 src/core/ext/client_config/uri_parser.h \
-third_party/objective_c/Cronet/cronet_c_for_grpc.h \
 src/core/ext/lb_policy/grpclb/load_balancer_api.h \
 src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.h \
 third_party/nanopb/pb.h \
 third_party/nanopb/pb_common.h \
 third_party/nanopb/pb_decode.h \
 third_party/nanopb/pb_encode.h \
+src/core/ext/load_reporting/load_reporting.h \
+src/core/ext/load_reporting/load_reporting_filter.h \
 src/core/ext/census/aggregation.h \
 src/core/ext/census/census_interface.h \
 src/core/ext/census/census_rpc_stats.h \
+src/core/ext/census/gen/census.pb.h \
 src/core/ext/census/grpc_filter.h \
 src/core/ext/census/mlog.h \
 src/core/ext/census/rpc_metric_id.h \
@@ -944,7 +948,7 @@
 src/core/lib/channel/connected_channel.c \
 src/core/lib/channel/http_client_filter.c \
 src/core/lib/channel/http_server_filter.c \
-src/core/lib/compression/compression_algorithm.c \
+src/core/lib/compression/compression.c \
 src/core/lib/compression/message_compress.c \
 src/core/lib/debug/trace.c \
 src/core/lib/http/format_request.c \
@@ -954,6 +958,7 @@
 src/core/lib/iomgr/endpoint.c \
 src/core/lib/iomgr/endpoint_pair_posix.c \
 src/core/lib/iomgr/endpoint_pair_windows.c \
+src/core/lib/iomgr/ev_poll_and_epoll_posix.c \
 src/core/lib/iomgr/ev_poll_posix.c \
 src/core/lib/iomgr/ev_posix.c \
 src/core/lib/iomgr/exec_ctx.c \
@@ -962,6 +967,7 @@
 src/core/lib/iomgr/iomgr.c \
 src/core/lib/iomgr/iomgr_posix.c \
 src/core/lib/iomgr/iomgr_windows.c \
+src/core/lib/iomgr/polling_entity.c \
 src/core/lib/iomgr/pollset_set_windows.c \
 src/core/lib/iomgr/pollset_windows.c \
 src/core/lib/iomgr/resolve_address_posix.c \
@@ -1048,7 +1054,7 @@
 src/core/lib/security/credentials/credentials_metadata.c \
 src/core/lib/security/credentials/fake/fake_credentials.c \
 src/core/lib/security/credentials/google_default/credentials_posix.c \
-src/core/lib/security/credentials/google_default/credentials_win32.c \
+src/core/lib/security/credentials/google_default/credentials_windows.c \
 src/core/lib/security/credentials/google_default/google_default_credentials.c \
 src/core/lib/security/credentials/iam/iam_credentials.c \
 src/core/lib/security/credentials/jwt/json_token.c \
@@ -1089,10 +1095,9 @@
 src/core/ext/client_config/subchannel_index.c \
 src/core/ext/client_config/uri_parser.c \
 src/core/ext/transport/chttp2/server/insecure/server_chttp2.c \
+src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.c \
 src/core/ext/transport/chttp2/client/insecure/channel_create.c \
-src/core/ext/transport/cronet/client/secure/cronet_channel_create.c \
-src/core/ext/transport/cronet/transport/cronet_api_dummy.c \
-src/core/ext/transport/cronet/transport/cronet_transport.c \
+src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c \
 src/core/ext/lb_policy/grpclb/load_balancer_api.c \
 src/core/ext/lb_policy/grpclb/proto/grpc/lb/v1/load_balancer.pb.c \
 third_party/nanopb/pb_common.c \
@@ -1102,7 +1107,10 @@
 src/core/ext/lb_policy/round_robin/round_robin.c \
 src/core/ext/resolver/dns/native/dns_resolver.c \
 src/core/ext/resolver/sockaddr/sockaddr_resolver.c \
+src/core/ext/load_reporting/load_reporting.c \
+src/core/ext/load_reporting/load_reporting_filter.c \
 src/core/ext/census/context.c \
+src/core/ext/census/gen/census.pb.c \
 src/core/ext/census/grpc_context.c \
 src/core/ext/census/grpc_filter.c \
 src/core/ext/census/grpc_plugin.c \
@@ -1116,14 +1124,14 @@
 include/grpc/support/atm.h \
 include/grpc/support/atm_gcc_atomic.h \
 include/grpc/support/atm_gcc_sync.h \
-include/grpc/support/atm_win32.h \
+include/grpc/support/atm_windows.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_win32.h \
+include/grpc/support/log_windows.h \
 include/grpc/support/port_platform.h \
 include/grpc/support/slice.h \
 include/grpc/support/slice_buffer.h \
@@ -1132,7 +1140,7 @@
 include/grpc/support/sync.h \
 include/grpc/support/sync_generic.h \
 include/grpc/support/sync_posix.h \
-include/grpc/support/sync_win32.h \
+include/grpc/support/sync_windows.h \
 include/grpc/support/thd.h \
 include/grpc/support/time.h \
 include/grpc/support/tls.h \
@@ -1144,7 +1152,7 @@
 include/grpc/impl/codegen/atm.h \
 include/grpc/impl/codegen/atm_gcc_atomic.h \
 include/grpc/impl/codegen/atm_gcc_sync.h \
-include/grpc/impl/codegen/atm_win32.h \
+include/grpc/impl/codegen/atm_windows.h \
 include/grpc/impl/codegen/log.h \
 include/grpc/impl/codegen/port_platform.h \
 include/grpc/impl/codegen/slice.h \
@@ -1152,7 +1160,7 @@
 include/grpc/impl/codegen/sync.h \
 include/grpc/impl/codegen/sync_generic.h \
 include/grpc/impl/codegen/sync_posix.h \
-include/grpc/impl/codegen/sync_win32.h \
+include/grpc/impl/codegen/sync_windows.h \
 include/grpc/impl/codegen/time.h \
 src/core/lib/profiling/timers.h \
 src/core/lib/support/backoff.h \
@@ -1162,7 +1170,7 @@
 src/core/lib/support/murmur_hash.h \
 src/core/lib/support/stack_lockfree.h \
 src/core/lib/support/string.h \
-src/core/lib/support/string_win32.h \
+src/core/lib/support/string_windows.h \
 src/core/lib/support/thd_internal.h \
 src/core/lib/support/time_precise.h \
 src/core/lib/support/tmpfile.h \
@@ -1178,7 +1186,7 @@
 src/core/lib/support/cpu_windows.c \
 src/core/lib/support/env_linux.c \
 src/core/lib/support/env_posix.c \
-src/core/lib/support/env_win32.c \
+src/core/lib/support/env_windows.c \
 src/core/lib/support/histogram.c \
 src/core/lib/support/host_port.c \
 src/core/lib/support/load_file.c \
@@ -1186,31 +1194,31 @@
 src/core/lib/support/log_android.c \
 src/core/lib/support/log_linux.c \
 src/core/lib/support/log_posix.c \
-src/core/lib/support/log_win32.c \
+src/core/lib/support/log_windows.c \
 src/core/lib/support/murmur_hash.c \
 src/core/lib/support/slice.c \
 src/core/lib/support/slice_buffer.c \
 src/core/lib/support/stack_lockfree.c \
 src/core/lib/support/string.c \
 src/core/lib/support/string_posix.c \
-src/core/lib/support/string_util_win32.c \
-src/core/lib/support/string_win32.c \
+src/core/lib/support/string_util_windows.c \
+src/core/lib/support/string_windows.c \
 src/core/lib/support/subprocess_posix.c \
 src/core/lib/support/subprocess_windows.c \
 src/core/lib/support/sync.c \
 src/core/lib/support/sync_posix.c \
-src/core/lib/support/sync_win32.c \
+src/core/lib/support/sync_windows.c \
 src/core/lib/support/thd.c \
 src/core/lib/support/thd_posix.c \
-src/core/lib/support/thd_win32.c \
+src/core/lib/support/thd_windows.c \
 src/core/lib/support/time.c \
 src/core/lib/support/time_posix.c \
 src/core/lib/support/time_precise.c \
-src/core/lib/support/time_win32.c \
+src/core/lib/support/time_windows.c \
 src/core/lib/support/tls_pthread.c \
 src/core/lib/support/tmpfile_msys.c \
 src/core/lib/support/tmpfile_posix.c \
-src/core/lib/support/tmpfile_win32.c \
+src/core/lib/support/tmpfile_windows.c \
 src/core/lib/support/wrap_memcpy.c
 
 # This tag can be used to specify the character encoding of the source files
diff --git a/tools/gce/linux_performance_worker_init.sh b/tools/gce/linux_performance_worker_init.sh
index dc47842..9b8d1d1 100755
--- a/tools/gce/linux_performance_worker_init.sh
+++ b/tools/gce/linux_performance_worker_init.sh
@@ -69,6 +69,10 @@
   python-pip \
   python-setuptools \
   python-yaml \
+  python3-dev \
+  python3-pip \
+  python3-setuptools \
+  python3-yaml \
   telnet \
   unzip \
   wget \
diff --git a/tools/jenkins/run_full_performance.sh b/tools/jenkins/run_full_performance.sh
index bb1f79f..3feda86 100755
--- a/tools/jenkins/run_full_performance.sh
+++ b/tools/jenkins/run_full_performance.sh
@@ -40,7 +40,7 @@
     --netperf \
     --category all \
     --bq_result_table performance_test.performance_experiment \
-    --remote_worker_host grpc-performance-server-8core grpc-performance-client-8core \
+    --remote_worker_host grpc-performance-server-8core grpc-performance-client-8core grpc-performance-client2-8core \
     || EXIT_CODE=1
 
 # scalability with 32cores (and upload to a different BQ table)
@@ -49,7 +49,7 @@
     --netperf \
     --category scalable \
     --bq_result_table performance_test.performance_experiment_32core \
-    --remote_worker_host grpc-performance-server-32core grpc-performance-client-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_python.sh b/tools/run_tests/build_artifact_python.sh
index 4320f97..55f8eb6 100755
--- a/tools/run_tests/build_artifact_python.sh
+++ b/tools/run_tests/build_artifact_python.sh
@@ -59,12 +59,14 @@
 ${SETARCH_CMD} ${PYTHON} setup.py  \
     bdist_wheel
 
+# Build gRPC tools package distribution
+${PYTHON} tools/distrib/python/make_grpcio_tools.py
+
 # Build gRPC tools package source distribution
 ${SETARCH_CMD} ${PYTHON} tools/distrib/python/grpcio_tools/setup.py  \
     sdist
 
 # Build gRPC tools package binary distribution
-${PYTHON} tools/distrib/python/make_grpcio_tools.py
 CFLAGS="$CFLAGS -fno-wrapv" ${SETARCH_CMD} \
   ${PYTHON} tools/distrib/python/grpcio_tools/setup.py bdist_wheel
 
diff --git a/tools/run_tests/build_python.sh b/tools/run_tests/build_python.sh
index 4cc6881..b1c90df 100755
--- a/tools/run_tests/build_python.sh
+++ b/tools/run_tests/build_python.sh
@@ -34,6 +34,7 @@
 cd $(dirname $0)/../..
 
 TOX_PYTHON_ENV="$1"
+PY_VERSION="${TOX_PYTHON_ENV: -2}"
 
 ROOT=`pwd`
 export LD_LIBRARY_PATH=$ROOT/libs/$CONFIG
@@ -51,11 +52,25 @@
 
 tox -e ${TOX_PYTHON_ENV} --notest
 
+# We force the .so naming convention in PEP 3149 for side by side installation support
+# Note this is the default in Python3, but explicitly disabled for Darwin, so we only
+# use this hack for our testing environment.
+if [ "$PY_VERSION" -gt "27" ]
+then
+  mv $ROOT/src/python/grpcio/grpc/_cython/cygrpc.so $ROOT/src/python/grpcio/grpc/_cython/cygrpc.so.backup || true
+fi
+
 $ROOT/.tox/${TOX_PYTHON_ENV}/bin/python $ROOT/setup.py build
 $ROOT/.tox/${TOX_PYTHON_ENV}/bin/python $ROOT/setup.py build_py
 $ROOT/.tox/${TOX_PYTHON_ENV}/bin/python $ROOT/setup.py build_ext --inplace
 $ROOT/.tox/${TOX_PYTHON_ENV}/bin/python $ROOT/setup.py gather --test
 
+if [ "$PY_VERSION" -gt "27" ]
+then
+  mv $ROOT/src/python/grpcio/grpc/_cython/cygrpc.so $ROOT/src/python/grpcio/grpc/_cython/cygrpc.cpython-${PY_VERSION}m.so || true
+  mv $ROOT/src/python/grpcio/grpc/_cython/cygrpc.so.backup $ROOT/src/python/grpcio/grpc/_cython/cygrpc.so || true
+fi
+
 # Build the health checker
 $ROOT/.tox/${TOX_PYTHON_ENV}/bin/python $ROOT/src/python/grpcio_health_checking/setup.py build
 $ROOT/.tox/${TOX_PYTHON_ENV}/bin/python $ROOT/src/python/grpcio_health_checking/setup.py build_py
diff --git a/tools/run_tests/performance/scenario_config.py b/tools/run_tests/performance/scenario_config.py
index b55d728..2d5130e 100644
--- a/tools/run_tests/performance/scenario_config.py
+++ b/tools/run_tests/performance/scenario_config.py
@@ -395,8 +395,8 @@
     #    categories=[SMOKETEST])
 
     yield _ping_pong_scenario(
-        'python_protobuf_async_streaming_ping_pong', rpc_type='STREAMING',
-        client_type='ASYNC_CLIENT', server_type='SYNC_SERVER')
+        'python_protobuf_sync_streaming_ping_pong', rpc_type='STREAMING',
+        client_type='SYNC_CLIENT', server_type='SYNC_SERVER')
 
     yield _ping_pong_scenario(
         'python_protobuf_async_unary_ping_pong', rpc_type='UNARY',
@@ -413,9 +413,9 @@
         unconstrained_client='sync')
 
     yield _ping_pong_scenario(
-        'python_protobuf_async_streaming_qps_unconstrained', rpc_type='STREAMING',
-        client_type='ASYNC_CLIENT', server_type='SYNC_SERVER',
-        unconstrained_client='async')
+        'python_protobuf_sync_streaming_qps_unconstrained', rpc_type='STREAMING',
+        client_type='SYNC_CLIENT', server_type='SYNC_SERVER',
+        unconstrained_client='sync')
 
     yield _ping_pong_scenario(
         'python_to_cpp_protobuf_sync_unary_ping_pong', rpc_type='UNARY',
diff --git a/tools/run_tests/run_interop_tests.py b/tools/run_tests/run_interop_tests.py
index edbdf05..5aaefb1 100755
--- a/tools/run_tests/run_interop_tests.py
+++ b/tools/run_tests/run_interop_tests.py
@@ -317,8 +317,7 @@
             'PYTHONPATH': '{}/src/python/gens'.format(DOCKER_WORKDIR_ROOT)}
 
   def unimplemented_test_cases(self):
-    return _SKIP_ADVANCED + _SKIP_COMPRESSION + ['jwt_token_creds',
-                                                 'per_rpc_creds']
+    return _SKIP_ADVANCED + _SKIP_COMPRESSION
 
   def unimplemented_test_cases_server(self):
     return _SKIP_ADVANCED + _SKIP_COMPRESSION
diff --git a/tools/run_tests/run_python.sh b/tools/run_tests/run_python.sh
index 7a3ce6b..8059059 100755
--- a/tools/run_tests/run_python.sh
+++ b/tools/run_tests/run_python.sh
@@ -55,3 +55,4 @@
 mkdir -p $ROOT/reports
 rm -rf $ROOT/reports/python-coverage
 (mv -T $ROOT/htmlcov $ROOT/reports/python-coverage) || true
+
diff --git a/tools/run_tests/run_tests.py b/tools/run_tests/run_tests.py
index 0538dce..3080d19 100755
--- a/tools/run_tests/run_tests.py
+++ b/tools/run_tests/run_tests.py
@@ -157,7 +157,7 @@
       'windows': ['all'],
       'mac': ['all'],
       'posix': ['all'],
-      'linux': ['poll'],
+      'linux': ['poll', 'legacy']
     }
     for target in binaries:
       polling_strategies = (POLLING_STRATEGIES[self.platform]
@@ -246,29 +246,40 @@
   def makefile_name(self):
     return 'Makefile'
 
-  def _clang_make_options(self):
-    return ['CC=clang', 'CXX=clang++', 'LD=clang', 'LDXX=clang++']
+  def _clang_make_options(self, version_suffix=''):
+    return ['CC=clang%s' % version_suffix,
+            'CXX=clang++%s' % version_suffix,
+            'LD=clang%s' % version_suffix,
+            'LDXX=clang++%s' % version_suffix]
 
-  def _gcc44_make_options(self):
-    return ['CC=gcc-4.4', 'CXX=g++-4.4', 'LD=gcc-4.4', 'LDXX=g++-4.4']
+  def _gcc_make_options(self, version_suffix):
+    return ['CC=gcc%s' % version_suffix,
+            'CXX=g++%s' % version_suffix,
+            'LD=gcc%s' % version_suffix,
+            'LDXX=g++%s' % version_suffix]
 
   def _compiler_options(self, use_docker, compiler):
     """Returns docker distro and make options to use for given compiler."""
-    if _is_use_docker_child():
-      return ("already_under_docker", [])
-    if not use_docker:
+    if not use_docker and not _is_use_docker_child():
       _check_compiler(compiler, ['default'])
 
     if compiler == 'gcc4.9' or compiler == 'default':
       return ('jessie', [])
     elif compiler == 'gcc4.4':
-      return ('wheezy', self._gcc44_make_options())
+      return ('wheezy', self._gcc_make_options(version_suffix='-4.4'))
+    elif compiler == 'gcc4.6':
+      return ('wheezy', self._gcc_make_options(version_suffix='-4.6'))
     elif compiler == 'gcc5.3':
       return ('ubuntu1604', [])
     elif compiler == 'clang3.4':
+      # on ubuntu1404, clang-3.4 alias doesn't exist, just use 'clang'
       return ('ubuntu1404', self._clang_make_options())
+    elif compiler == 'clang3.5':
+      return ('jessie', self._clang_make_options(version_suffix='-3.5'))
     elif compiler == 'clang3.6':
-      return ('ubuntu1604', self._clang_make_options())
+      return ('ubuntu1604', self._clang_make_options(version_suffix='-3.6'))
+    elif compiler == 'clang3.7':
+      return ('ubuntu1604', self._clang_make_options(version_suffix='-3.7'))
     else:
       raise Exception('Compiler %s not supported.' % compiler)
 
@@ -376,7 +387,7 @@
   def configure(self, config, args):
     self.config = config
     self.args = args
-    self._tox_env = self._get_tox_env(self.args.compiler)
+    self._tox_envs = self._get_tox_envs(self.args.compiler)
 
   def test_specs(self):
     # load list of known test suites
@@ -388,19 +399,21 @@
       os.path.abspath('src/python/grpcio_health_checking'))
     if self.config.build_config != 'gcov':
       return [self.config.job_spec(
-          ['tools/run_tests/run_python.sh', self._tox_env],
+          ['tools/run_tests/run_python.sh', tox_env],
           None,
           environ=dict(environment.items() +
                        [('GRPC_PYTHON_TESTRUNNER_FILTER', suite_name)]),
-          shortname='py.test.%s' % suite_name,
+          shortname='%s.test.%s' % (tox_env, suite_name),
           timeout_seconds=5*60)
-          for suite_name in tests_json]
+          for suite_name in tests_json
+          for tox_env in self._tox_envs]
     else:
-      return [self.config.job_spec(['tools/run_tests/run_python.sh'],
+      return [self.config.job_spec(['tools/run_tests/run_python.sh', tox_env],
                                    None,
                                    environ=environment,
-                                   shortname='py.test.coverage',
-                                   timeout_seconds=15*60)]
+                                   shortname='%s.test.coverage' % tox_env,
+                                   timeout_seconds=15*60)
+                                   for tox_env in self._tox_envs]
 
 
   def pre_build_steps(self):
@@ -413,7 +426,8 @@
     return []
 
   def build_steps(self):
-    return [['tools/run_tests/build_python.sh', self._tox_env]]
+    return [['tools/run_tests/build_python.sh', tox_env] 
+            for tox_env in self._tox_envs]
 
   def post_tests_steps(self):
     return []
@@ -424,12 +438,14 @@
   def dockerfile_dir(self):
     return 'tools/dockerfile/test/python_jessie_%s' % _docker_arch_suffix(self.args.arch)
 
-  def _get_tox_env(self, compiler):
+  def _get_tox_envs(self, compiler):
     """Returns name of tox environment based on selected compiler."""
-    if compiler == 'python2.7' or compiler == 'default':
-      return 'py27'
+    if compiler == 'default':
+      return ('py27', 'py34')
+    elif compiler == 'python2.7':
+      return ('py27',)
     elif compiler == 'python3.4':
-      return 'py34'
+      return ('py34',)
     else:
       raise Exception('Compiler %s not supported.' % compiler)
 
@@ -818,8 +834,8 @@
                   help='Selects architecture to target. For some platforms "default" is the only supported choice.')
 argp.add_argument('--compiler',
                   choices=['default',
-                           'gcc4.4', 'gcc4.9', 'gcc5.3',
-                           'clang3.4', 'clang3.6',
+                           'gcc4.4', 'gcc4.6', 'gcc4.9', 'gcc5.3',
+                           'clang3.4', 'clang3.5', 'clang3.6', 'clang3.7',
                            'vs2010', 'vs2013', 'vs2015',
                            'python2.7', 'python3.4',
                            'node0.12', 'node4', 'node5'],
diff --git a/tools/run_tests/sanity/sanity_tests.yaml b/tools/run_tests/sanity/sanity_tests.yaml
index c5945c6..e699c51 100644
--- a/tools/run_tests/sanity/sanity_tests.yaml
+++ b/tools/run_tests/sanity/sanity_tests.yaml
@@ -11,3 +11,4 @@
 - script: tools/distrib/check_nanopb_output.sh
 - script: tools/distrib/check_include_guards.py
 - script: tools/distrib/python/check_grpcio_tools.py
+- script: tools/distrib/check_generated_pb_files.sh
diff --git a/tools/run_tests/sources_and_headers.json b/tools/run_tests/sources_and_headers.json
index 24d23fe..4cd5a81 100644
--- a/tools/run_tests/sources_and_headers.json
+++ b/tools/run_tests/sources_and_headers.json
@@ -1851,6 +1851,7 @@
       "grpc", 
       "grpc++", 
       "grpc++_test_util", 
+      "grpc_cli_libs", 
       "grpc_test_util"
     ], 
     "headers": [], 
@@ -1903,7 +1904,7 @@
       "gpr", 
       "grpc", 
       "grpc++", 
-      "grpc++_codegen"
+      "grpc++_codegen_base"
     ], 
     "headers": [
       "src/proto/grpc/testing/control.grpc.pb.h", 
@@ -1912,8 +1913,6 @@
       "src/proto/grpc/testing/messages.pb.h", 
       "src/proto/grpc/testing/payloads.grpc.pb.h", 
       "src/proto/grpc/testing/payloads.pb.h", 
-      "src/proto/grpc/testing/perf_db.grpc.pb.h", 
-      "src/proto/grpc/testing/perf_db.pb.h", 
       "src/proto/grpc/testing/services.grpc.pb.h", 
       "src/proto/grpc/testing/services.pb.h", 
       "src/proto/grpc/testing/stats.grpc.pb.h", 
@@ -1929,7 +1928,8 @@
   }, 
   {
     "deps": [
-      "grpc++_codegen"
+      "grpc++_codegen_base", 
+      "grpc++_codegen_base_src"
     ], 
     "headers": [
       "src/proto/grpc/testing/control.grpc.pb.h", 
@@ -1938,8 +1938,6 @@
       "src/proto/grpc/testing/messages.pb.h", 
       "src/proto/grpc/testing/payloads.grpc.pb.h", 
       "src/proto/grpc/testing/payloads.pb.h", 
-      "src/proto/grpc/testing/perf_db.grpc.pb.h", 
-      "src/proto/grpc/testing/perf_db.pb.h", 
       "src/proto/grpc/testing/services.grpc.pb.h", 
       "src/proto/grpc/testing/services.pb.h", 
       "src/proto/grpc/testing/stats.grpc.pb.h", 
@@ -2094,6 +2092,7 @@
       "grpc++", 
       "grpc++_test_config", 
       "grpc++_test_util", 
+      "grpc_cli_libs", 
       "grpc_test_util"
     ], 
     "headers": [], 
@@ -2338,6 +2337,29 @@
       "gpr_test_util", 
       "grpc", 
       "grpc++", 
+      "grpc++_reflection", 
+      "grpc++_test_util", 
+      "grpc_test_util"
+    ], 
+    "headers": [
+      "test/cpp/util/proto_reflection_descriptor_database.h"
+    ], 
+    "language": "c++", 
+    "name": "proto_server_reflection_test", 
+    "src": [
+      "test/cpp/end2end/proto_server_reflection_test.cc", 
+      "test/cpp/util/proto_reflection_descriptor_database.cc", 
+      "test/cpp/util/proto_reflection_descriptor_database.h"
+    ], 
+    "third_party": false, 
+    "type": "target"
+  }, 
+  {
+    "deps": [
+      "gpr", 
+      "gpr_test_util", 
+      "grpc", 
+      "grpc++", 
       "grpc++_test_util", 
       "grpc_test_util", 
       "qps"
@@ -2362,14 +2384,10 @@
       "grpc_test_util", 
       "qps"
     ], 
-    "headers": [
-      "test/cpp/qps/parse_json.h"
-    ], 
+    "headers": [], 
     "language": "c++", 
     "name": "qps_json_driver", 
     "src": [
-      "test/cpp/qps/parse_json.cc", 
-      "test/cpp/qps/parse_json.h", 
       "test/cpp/qps/qps_json_driver.cc"
     ], 
     "third_party": false, 
@@ -3502,6 +3520,23 @@
     ], 
     "headers": [], 
     "language": "c", 
+    "name": "h2_fd_test", 
+    "src": [
+      "test/core/end2end/fixtures/h2_fd.c"
+    ], 
+    "third_party": false, 
+    "type": "target"
+  }, 
+  {
+    "deps": [
+      "end2end_tests", 
+      "gpr", 
+      "gpr_test_util", 
+      "grpc", 
+      "grpc_test_util"
+    ], 
+    "headers": [], 
+    "language": "c", 
     "name": "h2_full_test", 
     "src": [
       "test/core/end2end/fixtures/h2_full.c"
@@ -3553,6 +3588,23 @@
     ], 
     "headers": [], 
     "language": "c", 
+    "name": "h2_loadreporting_test", 
+    "src": [
+      "test/core/end2end/fixtures/h2_loadreporting.c"
+    ], 
+    "third_party": false, 
+    "type": "target"
+  }, 
+  {
+    "deps": [
+      "end2end_tests", 
+      "gpr", 
+      "gpr_test_util", 
+      "grpc", 
+      "grpc_test_util"
+    ], 
+    "headers": [], 
+    "language": "c", 
     "name": "h2_oauth2_test", 
     "src": [
       "test/core/end2end/fixtures/h2_oauth2.c"
@@ -3740,6 +3792,23 @@
     ], 
     "headers": [], 
     "language": "c", 
+    "name": "h2_fd_nosec_test", 
+    "src": [
+      "test/core/end2end/fixtures/h2_fd.c"
+    ], 
+    "third_party": false, 
+    "type": "target"
+  }, 
+  {
+    "deps": [
+      "end2end_nosec_tests", 
+      "gpr", 
+      "gpr_test_util", 
+      "grpc_test_util_unsecure", 
+      "grpc_unsecure"
+    ], 
+    "headers": [], 
+    "language": "c", 
     "name": "h2_full_nosec_test", 
     "src": [
       "test/core/end2end/fixtures/h2_full.c"
@@ -3791,6 +3860,23 @@
     ], 
     "headers": [], 
     "language": "c", 
+    "name": "h2_loadreporting_nosec_test", 
+    "src": [
+      "test/core/end2end/fixtures/h2_loadreporting.c"
+    ], 
+    "third_party": false, 
+    "type": "target"
+  }, 
+  {
+    "deps": [
+      "end2end_nosec_tests", 
+      "gpr", 
+      "gpr_test_util", 
+      "grpc_test_util_unsecure", 
+      "grpc_unsecure"
+    ], 
+    "headers": [], 
+    "language": "c", 
     "name": "h2_proxy_nosec_test", 
     "src": [
       "test/core/end2end/fixtures/h2_proxy.c"
@@ -4054,14 +4140,14 @@
       "grpc_lb_policy_grpclb", 
       "grpc_lb_policy_pick_first", 
       "grpc_lb_policy_round_robin", 
+      "grpc_load_reporting", 
       "grpc_resolver_dns_native", 
       "grpc_resolver_sockaddr", 
       "grpc_secure", 
       "grpc_transport_chttp2_client_insecure", 
       "grpc_transport_chttp2_client_secure", 
       "grpc_transport_chttp2_server_insecure", 
-      "grpc_transport_chttp2_server_secure", 
-      "grpc_transport_cronet_client_secure"
+      "grpc_transport_chttp2_server_secure"
     ], 
     "headers": [], 
     "language": "c", 
@@ -4075,6 +4161,22 @@
   {
     "deps": [
       "gpr", 
+      "grpc_base", 
+      "grpc_transport_chttp2_client_secure", 
+      "grpc_transport_cronet_client_secure"
+    ], 
+    "headers": [], 
+    "language": "c", 
+    "name": "grpc_cronet", 
+    "src": [
+      "src/core/lib/surface/init.c"
+    ], 
+    "third_party": false, 
+    "type": "lib"
+  }, 
+  {
+    "deps": [
+      "gpr", 
       "grpc"
     ], 
     "headers": [], 
@@ -4132,6 +4234,7 @@
       "grpc_lb_policy_grpclb", 
       "grpc_lb_policy_pick_first", 
       "grpc_lb_policy_round_robin", 
+      "grpc_load_reporting", 
       "grpc_resolver_dns_native", 
       "grpc_resolver_sockaddr", 
       "grpc_transport_chttp2_client_insecure", 
@@ -4207,21 +4310,22 @@
     "deps": [
       "grpc", 
       "grpc++_base", 
-      "grpc++_codegen"
+      "grpc++_codegen_base", 
+      "grpc++_codegen_base_src"
     ], 
     "headers": [
+      "include/grpc++/impl/codegen/core_codegen.h", 
       "src/cpp/client/secure_credentials.h", 
-      "src/cpp/common/core_codegen.h", 
       "src/cpp/common/secure_auth_context.h", 
       "src/cpp/server/secure_server_credentials.h"
     ], 
     "language": "c++", 
     "name": "grpc++", 
     "src": [
+      "include/grpc++/impl/codegen/core_codegen.h", 
       "src/cpp/client/secure_credentials.cc", 
       "src/cpp/client/secure_credentials.h", 
       "src/cpp/common/auth_property_iterator.cc", 
-      "src/cpp/common/core_codegen.h", 
       "src/cpp/common/secure_auth_context.cc", 
       "src/cpp/common/secure_auth_context.h", 
       "src/cpp/common/secure_channel_arguments.cc", 
@@ -4233,6 +4337,32 @@
     "type": "lib"
   }, 
   {
+    "deps": [
+      "grpc++", 
+      "grpc++_codegen_proto"
+    ], 
+    "headers": [
+      "include/grpc++/ext/proto_server_reflection_plugin.h", 
+      "include/grpc++/ext/reflection.grpc.pb.h", 
+      "include/grpc++/ext/reflection.pb.h", 
+      "src/cpp/ext/proto_server_reflection.h"
+    ], 
+    "language": "c++", 
+    "name": "grpc++_reflection", 
+    "src": [
+      "include/grpc++/ext/proto_server_reflection_plugin.h", 
+      "include/grpc++/ext/reflection.grpc.pb.h", 
+      "include/grpc++/ext/reflection.pb.h", 
+      "src/cpp/ext/proto_server_reflection.cc", 
+      "src/cpp/ext/proto_server_reflection.h", 
+      "src/cpp/ext/proto_server_reflection_plugin.cc", 
+      "src/cpp/ext/reflection.grpc.pb.cc", 
+      "src/cpp/ext/reflection.pb.cc"
+    ], 
+    "third_party": false, 
+    "type": "lib"
+  }, 
+  {
     "deps": [], 
     "headers": [
       "test/cpp/util/test_config.h"
@@ -4249,6 +4379,10 @@
   {
     "deps": [
       "grpc++", 
+      "grpc++_codegen_base", 
+      "grpc++_codegen_base_src", 
+      "grpc++_codegen_proto", 
+      "grpc++_config_proto", 
       "grpc_test_util"
     ], 
     "headers": [
@@ -4260,7 +4394,6 @@
       "src/proto/grpc/testing/echo_messages.pb.h", 
       "test/cpp/end2end/test_service_impl.h", 
       "test/cpp/util/byte_buffer_proto_helper.h", 
-      "test/cpp/util/cli_call.h", 
       "test/cpp/util/create_test_channel.h", 
       "test/cpp/util/string_ref_helper.h", 
       "test/cpp/util/subprocess.h", 
@@ -4273,8 +4406,6 @@
       "test/cpp/end2end/test_service_impl.h", 
       "test/cpp/util/byte_buffer_proto_helper.cc", 
       "test/cpp/util/byte_buffer_proto_helper.h", 
-      "test/cpp/util/cli_call.cc", 
-      "test/cpp/util/cli_call.h", 
       "test/cpp/util/create_test_channel.cc", 
       "test/cpp/util/create_test_channel.h", 
       "test/cpp/util/string_ref_helper.cc", 
@@ -4292,7 +4423,8 @@
       "gpr", 
       "grpc", 
       "grpc++_base", 
-      "grpc++_codegen", 
+      "grpc++_codegen_base", 
+      "grpc++_codegen_base_src", 
       "grpc_unsecure"
     ], 
     "headers": [], 
@@ -4306,7 +4438,27 @@
   }, 
   {
     "deps": [
-      "grpc++_config"
+      "grpc++", 
+      "grpc_plugin_support"
+    ], 
+    "headers": [
+      "test/cpp/util/cli_call.h", 
+      "test/cpp/util/proto_file_parser.h"
+    ], 
+    "language": "c++", 
+    "name": "grpc_cli_libs", 
+    "src": [
+      "test/cpp/util/cli_call.cc", 
+      "test/cpp/util/cli_call.h", 
+      "test/cpp/util/proto_file_parser.cc", 
+      "test/cpp/util/proto_file_parser.h"
+    ], 
+    "third_party": false, 
+    "type": "lib"
+  }, 
+  {
+    "deps": [
+      "grpc++_config_proto"
     ], 
     "headers": [
       "src/compiler/config.h", 
@@ -4464,8 +4616,6 @@
       "src/proto/grpc/testing/messages.pb.h", 
       "src/proto/grpc/testing/payloads.grpc.pb.h", 
       "src/proto/grpc/testing/payloads.pb.h", 
-      "src/proto/grpc/testing/perf_db.grpc.pb.h", 
-      "src/proto/grpc/testing/perf_db.pb.h", 
       "src/proto/grpc/testing/services.grpc.pb.h", 
       "src/proto/grpc/testing/services.pb.h", 
       "src/proto/grpc/testing/stats.grpc.pb.h", 
@@ -4475,7 +4625,7 @@
       "test/cpp/qps/histogram.h", 
       "test/cpp/qps/interarrival.h", 
       "test/cpp/qps/limit_cores.h", 
-      "test/cpp/qps/perf_db_client.h", 
+      "test/cpp/qps/parse_json.h", 
       "test/cpp/qps/qps_worker.h", 
       "test/cpp/qps/report.h", 
       "test/cpp/qps/server.h", 
@@ -4495,8 +4645,8 @@
       "test/cpp/qps/interarrival.h", 
       "test/cpp/qps/limit_cores.cc", 
       "test/cpp/qps/limit_cores.h", 
-      "test/cpp/qps/perf_db_client.cc", 
-      "test/cpp/qps/perf_db_client.h", 
+      "test/cpp/qps/parse_json.cc", 
+      "test/cpp/qps/parse_json.h", 
       "test/cpp/qps/qps_worker.cc", 
       "test/cpp/qps/qps_worker.h", 
       "test/cpp/qps/report.cc", 
@@ -5290,13 +5440,15 @@
   {
     "deps": [
       "gpr", 
-      "grpc_base"
+      "grpc_base", 
+      "nanopb"
     ], 
     "headers": [
       "include/grpc/census.h", 
       "src/core/ext/census/aggregation.h", 
       "src/core/ext/census/census_interface.h", 
       "src/core/ext/census/census_rpc_stats.h", 
+      "src/core/ext/census/gen/census.pb.h", 
       "src/core/ext/census/grpc_filter.h", 
       "src/core/ext/census/mlog.h", 
       "src/core/ext/census/rpc_metric_id.h"
@@ -5309,6 +5461,8 @@
       "src/core/ext/census/census_interface.h", 
       "src/core/ext/census/census_rpc_stats.h", 
       "src/core/ext/census/context.c", 
+      "src/core/ext/census/gen/census.pb.c", 
+      "src/core/ext/census/gen/census.pb.h", 
       "src/core/ext/census/grpc_context.c", 
       "src/core/ext/census/grpc_filter.c", 
       "src/core/ext/census/grpc_filter.h", 
@@ -5333,14 +5487,14 @@
       "include/grpc/support/atm.h", 
       "include/grpc/support/atm_gcc_atomic.h", 
       "include/grpc/support/atm_gcc_sync.h", 
-      "include/grpc/support/atm_win32.h", 
+      "include/grpc/support/atm_windows.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_win32.h", 
+      "include/grpc/support/log_windows.h", 
       "include/grpc/support/port_platform.h", 
       "include/grpc/support/slice.h", 
       "include/grpc/support/slice_buffer.h", 
@@ -5349,7 +5503,7 @@
       "include/grpc/support/sync.h", 
       "include/grpc/support/sync_generic.h", 
       "include/grpc/support/sync_posix.h", 
-      "include/grpc/support/sync_win32.h", 
+      "include/grpc/support/sync_windows.h", 
       "include/grpc/support/thd.h", 
       "include/grpc/support/time.h", 
       "include/grpc/support/tls.h", 
@@ -5365,7 +5519,7 @@
       "src/core/lib/support/murmur_hash.h", 
       "src/core/lib/support/stack_lockfree.h", 
       "src/core/lib/support/string.h", 
-      "src/core/lib/support/string_win32.h", 
+      "src/core/lib/support/string_windows.h", 
       "src/core/lib/support/thd_internal.h", 
       "src/core/lib/support/time_precise.h", 
       "src/core/lib/support/tmpfile.h"
@@ -5377,14 +5531,14 @@
       "include/grpc/support/atm.h", 
       "include/grpc/support/atm_gcc_atomic.h", 
       "include/grpc/support/atm_gcc_sync.h", 
-      "include/grpc/support/atm_win32.h", 
+      "include/grpc/support/atm_windows.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_win32.h", 
+      "include/grpc/support/log_windows.h", 
       "include/grpc/support/port_platform.h", 
       "include/grpc/support/slice.h", 
       "include/grpc/support/slice_buffer.h", 
@@ -5393,7 +5547,7 @@
       "include/grpc/support/sync.h", 
       "include/grpc/support/sync_generic.h", 
       "include/grpc/support/sync_posix.h", 
-      "include/grpc/support/sync_win32.h", 
+      "include/grpc/support/sync_windows.h", 
       "include/grpc/support/thd.h", 
       "include/grpc/support/time.h", 
       "include/grpc/support/tls.h", 
@@ -5417,7 +5571,7 @@
       "src/core/lib/support/env.h", 
       "src/core/lib/support/env_linux.c", 
       "src/core/lib/support/env_posix.c", 
-      "src/core/lib/support/env_win32.c", 
+      "src/core/lib/support/env_windows.c", 
       "src/core/lib/support/histogram.c", 
       "src/core/lib/support/host_port.c", 
       "src/core/lib/support/load_file.c", 
@@ -5426,7 +5580,7 @@
       "src/core/lib/support/log_android.c", 
       "src/core/lib/support/log_linux.c", 
       "src/core/lib/support/log_posix.c", 
-      "src/core/lib/support/log_win32.c", 
+      "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/slice.c", 
@@ -5436,28 +5590,28 @@
       "src/core/lib/support/string.c", 
       "src/core/lib/support/string.h", 
       "src/core/lib/support/string_posix.c", 
-      "src/core/lib/support/string_util_win32.c", 
-      "src/core/lib/support/string_win32.c", 
-      "src/core/lib/support/string_win32.h", 
+      "src/core/lib/support/string_util_windows.c", 
+      "src/core/lib/support/string_windows.c", 
+      "src/core/lib/support/string_windows.h", 
       "src/core/lib/support/subprocess_posix.c", 
       "src/core/lib/support/subprocess_windows.c", 
       "src/core/lib/support/sync.c", 
       "src/core/lib/support/sync_posix.c", 
-      "src/core/lib/support/sync_win32.c", 
+      "src/core/lib/support/sync_windows.c", 
       "src/core/lib/support/thd.c", 
       "src/core/lib/support/thd_internal.h", 
       "src/core/lib/support/thd_posix.c", 
-      "src/core/lib/support/thd_win32.c", 
+      "src/core/lib/support/thd_windows.c", 
       "src/core/lib/support/time.c", 
       "src/core/lib/support/time_posix.c", 
       "src/core/lib/support/time_precise.c", 
       "src/core/lib/support/time_precise.h", 
-      "src/core/lib/support/time_win32.c", 
+      "src/core/lib/support/time_windows.c", 
       "src/core/lib/support/tls_pthread.c", 
       "src/core/lib/support/tmpfile.h", 
       "src/core/lib/support/tmpfile_msys.c", 
       "src/core/lib/support/tmpfile_posix.c", 
-      "src/core/lib/support/tmpfile_win32.c", 
+      "src/core/lib/support/tmpfile_windows.c", 
       "src/core/lib/support/wrap_memcpy.c"
     ], 
     "third_party": false, 
@@ -5470,7 +5624,7 @@
       "include/grpc/impl/codegen/atm.h", 
       "include/grpc/impl/codegen/atm_gcc_atomic.h", 
       "include/grpc/impl/codegen/atm_gcc_sync.h", 
-      "include/grpc/impl/codegen/atm_win32.h", 
+      "include/grpc/impl/codegen/atm_windows.h", 
       "include/grpc/impl/codegen/log.h", 
       "include/grpc/impl/codegen/port_platform.h", 
       "include/grpc/impl/codegen/slice.h", 
@@ -5478,7 +5632,7 @@
       "include/grpc/impl/codegen/sync.h", 
       "include/grpc/impl/codegen/sync_generic.h", 
       "include/grpc/impl/codegen/sync_posix.h", 
-      "include/grpc/impl/codegen/sync_win32.h", 
+      "include/grpc/impl/codegen/sync_windows.h", 
       "include/grpc/impl/codegen/time.h"
     ], 
     "language": "c", 
@@ -5488,7 +5642,7 @@
       "include/grpc/impl/codegen/atm.h", 
       "include/grpc/impl/codegen/atm_gcc_atomic.h", 
       "include/grpc/impl/codegen/atm_gcc_sync.h", 
-      "include/grpc/impl/codegen/atm_win32.h", 
+      "include/grpc/impl/codegen/atm_windows.h", 
       "include/grpc/impl/codegen/log.h", 
       "include/grpc/impl/codegen/port_platform.h", 
       "include/grpc/impl/codegen/slice.h", 
@@ -5496,7 +5650,7 @@
       "include/grpc/impl/codegen/sync.h", 
       "include/grpc/impl/codegen/sync_generic.h", 
       "include/grpc/impl/codegen/sync_posix.h", 
-      "include/grpc/impl/codegen/sync_win32.h", 
+      "include/grpc/impl/codegen/sync_windows.h", 
       "include/grpc/impl/codegen/time.h"
     ], 
     "third_party": false, 
@@ -5504,6 +5658,19 @@
   }, 
   {
     "deps": [
+      "grpc++_codegen_base"
+    ], 
+    "headers": [], 
+    "language": "c", 
+    "name": "grpc++_codegen_base_src", 
+    "src": [
+      "src/cpp/codegen/codegen_init.cc"
+    ], 
+    "third_party": false, 
+    "type": "filegroup"
+  }, 
+  {
+    "deps": [
       "gpr", 
       "grpc_codegen"
     ], 
@@ -5512,6 +5679,7 @@
       "include/grpc/byte_buffer_reader.h", 
       "include/grpc/compression.h", 
       "include/grpc/grpc.h", 
+      "include/grpc/grpc_posix.h", 
       "include/grpc/status.h", 
       "src/core/lib/channel/channel_args.h", 
       "src/core/lib/channel/channel_stack.h", 
@@ -5530,6 +5698,7 @@
       "src/core/lib/iomgr/closure.h", 
       "src/core/lib/iomgr/endpoint.h", 
       "src/core/lib/iomgr/endpoint_pair.h", 
+      "src/core/lib/iomgr/ev_poll_and_epoll_posix.h", 
       "src/core/lib/iomgr/ev_poll_posix.h", 
       "src/core/lib/iomgr/ev_posix.h", 
       "src/core/lib/iomgr/exec_ctx.h", 
@@ -5538,6 +5707,7 @@
       "src/core/lib/iomgr/iomgr.h", 
       "src/core/lib/iomgr/iomgr_internal.h", 
       "src/core/lib/iomgr/iomgr_posix.h", 
+      "src/core/lib/iomgr/polling_entity.h", 
       "src/core/lib/iomgr/pollset.h", 
       "src/core/lib/iomgr/pollset_set.h", 
       "src/core/lib/iomgr/pollset_set_windows.h", 
@@ -5546,7 +5716,7 @@
       "src/core/lib/iomgr/sockaddr.h", 
       "src/core/lib/iomgr/sockaddr_posix.h", 
       "src/core/lib/iomgr/sockaddr_utils.h", 
-      "src/core/lib/iomgr/sockaddr_win32.h", 
+      "src/core/lib/iomgr/sockaddr_windows.h", 
       "src/core/lib/iomgr/socket_utils_posix.h", 
       "src/core/lib/iomgr/socket_windows.h", 
       "src/core/lib/iomgr/tcp_client.h", 
@@ -5594,6 +5764,7 @@
       "include/grpc/byte_buffer_reader.h", 
       "include/grpc/compression.h", 
       "include/grpc/grpc.h", 
+      "include/grpc/grpc_posix.h", 
       "include/grpc/status.h", 
       "src/core/lib/channel/channel_args.c", 
       "src/core/lib/channel/channel_args.h", 
@@ -5611,7 +5782,7 @@
       "src/core/lib/channel/http_server_filter.c", 
       "src/core/lib/channel/http_server_filter.h", 
       "src/core/lib/compression/algorithm_metadata.h", 
-      "src/core/lib/compression/compression_algorithm.c", 
+      "src/core/lib/compression/compression.c", 
       "src/core/lib/compression/message_compress.c", 
       "src/core/lib/compression/message_compress.h", 
       "src/core/lib/debug/trace.c", 
@@ -5629,6 +5800,8 @@
       "src/core/lib/iomgr/endpoint_pair.h", 
       "src/core/lib/iomgr/endpoint_pair_posix.c", 
       "src/core/lib/iomgr/endpoint_pair_windows.c", 
+      "src/core/lib/iomgr/ev_poll_and_epoll_posix.c", 
+      "src/core/lib/iomgr/ev_poll_and_epoll_posix.h", 
       "src/core/lib/iomgr/ev_poll_posix.c", 
       "src/core/lib/iomgr/ev_poll_posix.h", 
       "src/core/lib/iomgr/ev_posix.c", 
@@ -5645,6 +5818,8 @@
       "src/core/lib/iomgr/iomgr_posix.c", 
       "src/core/lib/iomgr/iomgr_posix.h", 
       "src/core/lib/iomgr/iomgr_windows.c", 
+      "src/core/lib/iomgr/polling_entity.c", 
+      "src/core/lib/iomgr/polling_entity.h", 
       "src/core/lib/iomgr/pollset.h", 
       "src/core/lib/iomgr/pollset_set.h", 
       "src/core/lib/iomgr/pollset_set_windows.c", 
@@ -5658,7 +5833,7 @@
       "src/core/lib/iomgr/sockaddr_posix.h", 
       "src/core/lib/iomgr/sockaddr_utils.c", 
       "src/core/lib/iomgr/sockaddr_utils.h", 
-      "src/core/lib/iomgr/sockaddr_win32.h", 
+      "src/core/lib/iomgr/sockaddr_windows.h", 
       "src/core/lib/iomgr/socket_utils_common_posix.c", 
       "src/core/lib/iomgr/socket_utils_linux.c", 
       "src/core/lib/iomgr/socket_utils_posix.c", 
@@ -5900,6 +6075,26 @@
   {
     "deps": [
       "gpr", 
+      "grpc_base"
+    ], 
+    "headers": [
+      "src/core/ext/load_reporting/load_reporting.h", 
+      "src/core/ext/load_reporting/load_reporting_filter.h"
+    ], 
+    "language": "c", 
+    "name": "grpc_load_reporting", 
+    "src": [
+      "src/core/ext/load_reporting/load_reporting.c", 
+      "src/core/ext/load_reporting/load_reporting.h", 
+      "src/core/ext/load_reporting/load_reporting_filter.c", 
+      "src/core/ext/load_reporting/load_reporting_filter.h"
+    ], 
+    "third_party": false, 
+    "type": "filegroup"
+  }, 
+  {
+    "deps": [
+      "gpr", 
       "grpc_base", 
       "grpc_client_config"
     ], 
@@ -5935,7 +6130,6 @@
       "tsi"
     ], 
     "headers": [
-      "include/grpc/grpc_cronet.h", 
       "include/grpc/grpc_security.h", 
       "include/grpc/grpc_security_constants.h", 
       "src/core/lib/security/context/security_context.h", 
@@ -5960,7 +6154,6 @@
     "language": "c", 
     "name": "grpc_secure", 
     "src": [
-      "include/grpc/grpc_cronet.h", 
       "include/grpc/grpc_security.h", 
       "include/grpc/grpc_security_constants.h", 
       "src/core/lib/http/httpcli_security_connector.c", 
@@ -5974,7 +6167,7 @@
       "src/core/lib/security/credentials/fake/fake_credentials.c", 
       "src/core/lib/security/credentials/fake/fake_credentials.h", 
       "src/core/lib/security/credentials/google_default/credentials_posix.c", 
-      "src/core/lib/security/credentials/google_default/credentials_win32.c", 
+      "src/core/lib/security/credentials/google_default/credentials_windows.c", 
       "src/core/lib/security/credentials/google_default/google_default_credentials.c", 
       "src/core/lib/security/credentials/google_default/google_default_credentials.h", 
       "src/core/lib/security/credentials/iam/iam_credentials.c", 
@@ -6160,7 +6353,8 @@
     "language": "c", 
     "name": "grpc_transport_chttp2_client_insecure", 
     "src": [
-      "src/core/ext/transport/chttp2/client/insecure/channel_create.c"
+      "src/core/ext/transport/chttp2/client/insecure/channel_create.c", 
+      "src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c"
     ], 
     "third_party": false, 
     "type": "filegroup"
@@ -6192,7 +6386,8 @@
     "language": "c", 
     "name": "grpc_transport_chttp2_server_insecure", 
     "src": [
-      "src/core/ext/transport/chttp2/server/insecure/server_chttp2.c"
+      "src/core/ext/transport/chttp2/server/insecure/server_chttp2.c", 
+      "src/core/ext/transport/chttp2/server/insecure/server_chttp2_posix.c"
     ], 
     "third_party": false, 
     "type": "filegroup"
@@ -6219,11 +6414,17 @@
       "grpc_transport_chttp2"
     ], 
     "headers": [
+      "include/grpc/grpc_cronet.h", 
+      "include/grpc/grpc_security.h", 
+      "include/grpc/grpc_security_constants.h", 
       "third_party/objective_c/Cronet/cronet_c_for_grpc.h"
     ], 
     "language": "c", 
     "name": "grpc_transport_cronet_client_secure", 
     "src": [
+      "include/grpc/grpc_cronet.h", 
+      "include/grpc/grpc_security.h", 
+      "include/grpc/grpc_security_constants.h", 
       "src/core/ext/transport/cronet/client/secure/cronet_channel_create.c", 
       "src/core/ext/transport/cronet/transport/cronet_api_dummy.c", 
       "src/core/ext/transport/cronet/transport/cronet_transport.c"
@@ -6274,8 +6475,7 @@
   {
     "deps": [
       "grpc", 
-      "grpc++_codegen", 
-      "grpc++_config"
+      "grpc++_codegen_base"
     ], 
     "headers": [
       "include/grpc++/alarm.h", 
@@ -6283,14 +6483,15 @@
       "include/grpc++/client_context.h", 
       "include/grpc++/completion_queue.h", 
       "include/grpc++/create_channel.h", 
+      "include/grpc++/create_channel_posix.h", 
       "include/grpc++/generic/async_generic_service.h", 
       "include/grpc++/generic/generic_stub.h", 
       "include/grpc++/grpc++.h", 
       "include/grpc++/impl/call.h", 
       "include/grpc++/impl/client_unary_call.h", 
+      "include/grpc++/impl/codegen/core_codegen.h", 
       "include/grpc++/impl/grpc_library.h", 
       "include/grpc++/impl/method_handler_impl.h", 
-      "include/grpc++/impl/proto_utils.h", 
       "include/grpc++/impl/rpc_method.h", 
       "include/grpc++/impl/rpc_service_method.h", 
       "include/grpc++/impl/serialization_traits.h", 
@@ -6311,10 +6512,12 @@
       "include/grpc++/server.h", 
       "include/grpc++/server_builder.h", 
       "include/grpc++/server_context.h", 
+      "include/grpc++/server_posix.h", 
       "include/grpc++/support/async_stream.h", 
       "include/grpc++/support/async_unary_call.h", 
       "include/grpc++/support/byte_buffer.h", 
       "include/grpc++/support/channel_arguments.h", 
+      "include/grpc++/support/config.h", 
       "include/grpc++/support/slice.h", 
       "include/grpc++/support/status.h", 
       "include/grpc++/support/status_code_enum.h", 
@@ -6323,7 +6526,6 @@
       "include/grpc++/support/sync_stream.h", 
       "include/grpc++/support/time.h", 
       "src/cpp/client/create_channel_internal.h", 
-      "src/cpp/common/core_codegen.h", 
       "src/cpp/server/dynamic_thread_pool.h", 
       "src/cpp/server/thread_pool_interface.h"
     ], 
@@ -6335,14 +6537,15 @@
       "include/grpc++/client_context.h", 
       "include/grpc++/completion_queue.h", 
       "include/grpc++/create_channel.h", 
+      "include/grpc++/create_channel_posix.h", 
       "include/grpc++/generic/async_generic_service.h", 
       "include/grpc++/generic/generic_stub.h", 
       "include/grpc++/grpc++.h", 
       "include/grpc++/impl/call.h", 
       "include/grpc++/impl/client_unary_call.h", 
+      "include/grpc++/impl/codegen/core_codegen.h", 
       "include/grpc++/impl/grpc_library.h", 
       "include/grpc++/impl/method_handler_impl.h", 
-      "include/grpc++/impl/proto_utils.h", 
       "include/grpc++/impl/rpc_method.h", 
       "include/grpc++/impl/rpc_service_method.h", 
       "include/grpc++/impl/serialization_traits.h", 
@@ -6363,10 +6566,12 @@
       "include/grpc++/server.h", 
       "include/grpc++/server_builder.h", 
       "include/grpc++/server_context.h", 
+      "include/grpc++/server_posix.h", 
       "include/grpc++/support/async_stream.h", 
       "include/grpc++/support/async_unary_call.h", 
       "include/grpc++/support/byte_buffer.h", 
       "include/grpc++/support/channel_arguments.h", 
+      "include/grpc++/support/config.h", 
       "include/grpc++/support/slice.h", 
       "include/grpc++/support/status.h", 
       "include/grpc++/support/status_code_enum.h", 
@@ -6379,13 +6584,13 @@
       "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/generic_stub.cc", 
       "src/cpp/client/insecure_credentials.cc", 
       "src/cpp/common/channel_arguments.cc", 
       "src/cpp/common/completion_queue.cc", 
       "src/cpp/common/core_codegen.cc", 
-      "src/cpp/common/core_codegen.h", 
       "src/cpp/common/rpc_method.cc", 
       "src/cpp/server/async_generic_service.cc", 
       "src/cpp/server/create_default_thread_pool.cc", 
@@ -6396,6 +6601,7 @@
       "src/cpp/server/server_builder.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", 
@@ -6408,7 +6614,6 @@
   }, 
   {
     "deps": [
-      "grpc++_config_codegen", 
       "grpc_codegen"
     ], 
     "headers": [
@@ -6421,11 +6626,11 @@
       "include/grpc++/impl/codegen/client_unary_call.h", 
       "include/grpc++/impl/codegen/completion_queue.h", 
       "include/grpc++/impl/codegen/completion_queue_tag.h", 
+      "include/grpc++/impl/codegen/config.h", 
       "include/grpc++/impl/codegen/core_codegen_interface.h", 
       "include/grpc++/impl/codegen/create_auth_context.h", 
       "include/grpc++/impl/codegen/grpc_library.h", 
       "include/grpc++/impl/codegen/method_handler_impl.h", 
-      "include/grpc++/impl/codegen/proto_utils.h", 
       "include/grpc++/impl/codegen/rpc_method.h", 
       "include/grpc++/impl/codegen/rpc_service_method.h", 
       "include/grpc++/impl/codegen/security/auth_context.h", 
@@ -6444,7 +6649,7 @@
       "include/grpc++/impl/codegen/time.h"
     ], 
     "language": "c++", 
-    "name": "grpc++_codegen", 
+    "name": "grpc++_codegen_base", 
     "src": [
       "include/grpc++/impl/codegen/async_stream.h", 
       "include/grpc++/impl/codegen/async_unary_call.h", 
@@ -6455,11 +6660,11 @@
       "include/grpc++/impl/codegen/client_unary_call.h", 
       "include/grpc++/impl/codegen/completion_queue.h", 
       "include/grpc++/impl/codegen/completion_queue_tag.h", 
+      "include/grpc++/impl/codegen/config.h", 
       "include/grpc++/impl/codegen/core_codegen_interface.h", 
       "include/grpc++/impl/codegen/create_auth_context.h", 
       "include/grpc++/impl/codegen/grpc_library.h", 
       "include/grpc++/impl/codegen/method_handler_impl.h", 
-      "include/grpc++/impl/codegen/proto_utils.h", 
       "include/grpc++/impl/codegen/rpc_method.h", 
       "include/grpc++/impl/codegen/rpc_service_method.h", 
       "include/grpc++/impl/codegen/security/auth_context.h", 
@@ -6475,25 +6680,23 @@
       "include/grpc++/impl/codegen/sync_cxx11.h", 
       "include/grpc++/impl/codegen/sync_no_cxx11.h", 
       "include/grpc++/impl/codegen/sync_stream.h", 
-      "include/grpc++/impl/codegen/time.h", 
-      "src/cpp/codegen/codegen_init.cc"
+      "include/grpc++/impl/codegen/time.h"
     ], 
     "third_party": false, 
     "type": "filegroup"
   }, 
   {
     "deps": [
-      "grpc++_config_codegen"
+      "grpc++_codegen_base", 
+      "grpc++_config_proto"
     ], 
     "headers": [
-      "include/grpc++/support/config.h", 
-      "include/grpc++/support/config_protobuf.h"
+      "include/grpc++/impl/codegen/proto_utils.h"
     ], 
     "language": "c++", 
-    "name": "grpc++_config", 
+    "name": "grpc++_codegen_proto", 
     "src": [
-      "include/grpc++/support/config.h", 
-      "include/grpc++/support/config_protobuf.h"
+      "include/grpc++/impl/codegen/proto_utils.h"
     ], 
     "third_party": false, 
     "type": "filegroup"
@@ -6501,13 +6704,11 @@
   {
     "deps": [], 
     "headers": [
-      "include/grpc++/impl/codegen/config.h", 
       "include/grpc++/impl/codegen/config_protobuf.h"
     ], 
     "language": "c++", 
-    "name": "grpc++_config_codegen", 
+    "name": "grpc++_config_proto", 
     "src": [
-      "include/grpc++/impl/codegen/config.h", 
       "include/grpc++/impl/codegen/config_protobuf.h"
     ], 
     "third_party": false, 
diff --git a/tools/run_tests/tests.json b/tools/run_tests/tests.json
index 850f947..2304ce7 100644
--- a/tools/run_tests/tests.json
+++ b/tools/run_tests/tests.json
@@ -2318,6 +2318,27 @@
     "ci_platforms": [
       "linux", 
       "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "gtest": true, 
+    "language": "c++", 
+    "name": "proto_server_reflection_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ]
+  }, 
+  {
+    "args": [], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
       "posix"
     ], 
     "cpu_cost": 0.5, 
@@ -6784,6 +6805,666 @@
       "bad_hostname"
     ], 
     "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_fd_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "binary_metadata"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_fd_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "call_creds"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_fd_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "cancel_after_accept"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_fd_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "cancel_after_client_done"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_fd_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "cancel_after_invoke"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_fd_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "cancel_before_invoke"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_fd_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "cancel_in_a_vacuum"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_fd_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "cancel_with_status"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_fd_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "compressed_payload"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_fd_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "empty_batch"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_fd_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "filter_causes_close"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_fd_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "graceful_server_shutdown"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_fd_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "high_initial_seqno"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_fd_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "hpack_size"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_fd_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "idempotent_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": [
+      "invoke_large_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": [
+      "large_metadata"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_fd_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "max_concurrent_streams"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_fd_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "max_message_length"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_fd_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "negative_deadline"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_fd_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "no_op"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_fd_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "payload"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_fd_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "ping_pong_streaming"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_fd_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "registered_call"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_fd_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "request_with_flags"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_fd_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "request_with_payload"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_fd_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "server_finishes_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": [
+      "shutdown_finishes_calls"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_fd_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "shutdown_finishes_tags"
+    ], 
+    "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": [
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_fd_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "simple_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": [
+      "trailing_metadata"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_fd_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "bad_hostname"
+    ], 
+    "ci_platforms": [
       "windows", 
       "linux", 
       "mac", 
@@ -9044,6 +9725,842 @@
     "ci_platforms": [
       "windows", 
       "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_loadreporting_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "binary_metadata"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_loadreporting_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "call_creds"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_loadreporting_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "cancel_after_accept"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_loadreporting_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "cancel_after_client_done"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_loadreporting_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "cancel_after_invoke"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_loadreporting_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "cancel_before_invoke"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_loadreporting_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "cancel_in_a_vacuum"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_loadreporting_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "cancel_with_status"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_loadreporting_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "compressed_payload"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_loadreporting_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "connectivity"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_loadreporting_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "default_host"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_loadreporting_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "disappearing_server"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_loadreporting_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "empty_batch"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_loadreporting_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "filter_causes_close"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_loadreporting_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "graceful_server_shutdown"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_loadreporting_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "high_initial_seqno"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_loadreporting_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "hpack_size"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_loadreporting_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "idempotent_request"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_loadreporting_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "invoke_large_request"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_loadreporting_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "large_metadata"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_loadreporting_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "max_concurrent_streams"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_loadreporting_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "max_message_length"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_loadreporting_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "negative_deadline"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_loadreporting_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "no_op"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_loadreporting_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "payload"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_loadreporting_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "ping"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_loadreporting_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "ping_pong_streaming"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_loadreporting_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "registered_call"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_loadreporting_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "request_with_flags"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_loadreporting_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "request_with_payload"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_loadreporting_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "server_finishes_request"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_loadreporting_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "shutdown_finishes_calls"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_loadreporting_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "shutdown_finishes_tags"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_loadreporting_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "simple_delayed_request"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_loadreporting_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "simple_metadata"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_loadreporting_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "simple_request"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_loadreporting_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "trailing_metadata"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_loadreporting_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "bad_hostname"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
       "posix"
     ], 
     "cpu_cost": 1.0, 
@@ -17282,6 +18799,646 @@
       "bad_hostname"
     ], 
     "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": [
+      "binary_metadata"
+    ], 
+    "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": [
+      "cancel_after_accept"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_fd_nosec_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "cancel_after_client_done"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_fd_nosec_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "cancel_after_invoke"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_fd_nosec_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "cancel_before_invoke"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_fd_nosec_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "cancel_in_a_vacuum"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_fd_nosec_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "cancel_with_status"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_fd_nosec_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "compressed_payload"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_fd_nosec_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "empty_batch"
+    ], 
+    "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": [
+      "filter_causes_close"
+    ], 
+    "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": [
+      "graceful_server_shutdown"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_fd_nosec_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "high_initial_seqno"
+    ], 
+    "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": [
+      "hpack_size"
+    ], 
+    "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": [
+      "idempotent_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": [
+      "invoke_large_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": [
+      "large_metadata"
+    ], 
+    "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": [
+      "max_concurrent_streams"
+    ], 
+    "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": [
+      "max_message_length"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_fd_nosec_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "negative_deadline"
+    ], 
+    "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": [
+      "no_op"
+    ], 
+    "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": [
+      "payload"
+    ], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_fd_nosec_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "ping_pong_streaming"
+    ], 
+    "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": [
+      "registered_call"
+    ], 
+    "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": [
+      "request_with_flags"
+    ], 
+    "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": [
+      "request_with_payload"
+    ], 
+    "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": [
+      "server_finishes_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": [
+      "shutdown_finishes_calls"
+    ], 
+    "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": [
+      "shutdown_finishes_tags"
+    ], 
+    "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": [
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_fd_nosec_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "simple_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": [
+      "trailing_metadata"
+    ], 
+    "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": [
+      "bad_hostname"
+    ], 
+    "ci_platforms": [
       "windows", 
       "linux", 
       "mac", 
@@ -19482,6 +21639,820 @@
     "ci_platforms": [
       "windows", 
       "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_loadreporting_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "binary_metadata"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_loadreporting_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "cancel_after_accept"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_loadreporting_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "cancel_after_client_done"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_loadreporting_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "cancel_after_invoke"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_loadreporting_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "cancel_before_invoke"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_loadreporting_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "cancel_in_a_vacuum"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_loadreporting_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "cancel_with_status"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_loadreporting_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "compressed_payload"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_loadreporting_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "connectivity"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_loadreporting_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "default_host"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_loadreporting_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "disappearing_server"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_loadreporting_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "empty_batch"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_loadreporting_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "filter_causes_close"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_loadreporting_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "graceful_server_shutdown"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_loadreporting_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "high_initial_seqno"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_loadreporting_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "hpack_size"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_loadreporting_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "idempotent_request"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_loadreporting_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "invoke_large_request"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_loadreporting_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "large_metadata"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_loadreporting_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "max_concurrent_streams"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_loadreporting_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "max_message_length"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_loadreporting_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "negative_deadline"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_loadreporting_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "no_op"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_loadreporting_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "payload"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_loadreporting_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "ping"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_loadreporting_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "ping_pong_streaming"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_loadreporting_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "registered_call"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_loadreporting_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "request_with_flags"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_loadreporting_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "request_with_payload"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_loadreporting_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "server_finishes_request"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_loadreporting_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "shutdown_finishes_calls"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_loadreporting_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "shutdown_finishes_tags"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_loadreporting_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "simple_delayed_request"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_loadreporting_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "simple_metadata"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_loadreporting_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "simple_request"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_loadreporting_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "trailing_metadata"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "h2_loadreporting_nosec_test", 
+    "platforms": [
+      "windows", 
+      "linux", 
+      "mac", 
+      "posix"
+    ]
+  }, 
+  {
+    "args": [
+      "bad_hostname"
+    ], 
+    "ci_platforms": [
+      "windows", 
+      "linux", 
       "posix"
     ], 
     "cpu_cost": 1.0, 
@@ -24547,6 +27518,23 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/api_fuzzer_corpus/0e79b68aa8b9c336f0bbf9029928c53079711423"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "api_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/api_fuzzer_corpus/0ea509d249ae28faba8980aacb972c7ea28d3fd5"
     ], 
     "ci_platforms": [
@@ -25006,6 +27994,23 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/api_fuzzer_corpus/1560af88445d6c1e8b1300047f33056dce198e02"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "api_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/api_fuzzer_corpus/157586c7c0ba8fd0dc9bfc2426229a7da934cec2"
     ], 
     "ci_platforms": [
@@ -28967,6 +31972,23 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/api_fuzzer_corpus/48caf755ddcc6c45d3416ba6ab44709f360eb82b"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "api_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/api_fuzzer_corpus/48f56289592da153b3c50bcc26ad6d4d3a7e443b"
     ], 
     "ci_platforms": [
@@ -31789,6 +34811,23 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/api_fuzzer_corpus/7030cb2c62b289459e459bc54bd84c8d7e6f5a98"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "api_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/api_fuzzer_corpus/705c87b99197c87eb2ed148f8b3fdc60f8616f15"
     ], 
     "ci_platforms": [
@@ -33115,6 +36154,23 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/api_fuzzer_corpus/81f8c545d77d93e6cb8239e9e4a4d7f8f8beeee9"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "api_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/api_fuzzer_corpus/820d5ba2e9d91563dae39a1b02833fbef1e6d8f1"
     ], 
     "ci_platforms": [
@@ -36736,6 +39792,23 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/api_fuzzer_corpus/b7d02f4d12cd0b5442a04675e69f98fbdabc775a"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "api_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/api_fuzzer_corpus/b7f282fbd77193d822df9c8156370398e1fd099c"
     ], 
     "ci_platforms": [
@@ -38606,6 +41679,23 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/api_fuzzer_corpus/ce6a90cb7d395fea7aa54ee9f7061cc45f5494d7"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "api_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/api_fuzzer_corpus/ceecce905981d8291a79fe32f89e8be688dfee7e"
     ], 
     "ci_platforms": [
@@ -38776,6 +41866,23 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/api_fuzzer_corpus/crash-482e9bdce0e13df2a77eef75a1c07d38ee28f4ab"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "api_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/api_fuzzer_corpus/crash-4ae4941b4c3f857966a0e3c05f789a0a5ae15bbf"
     ], 
     "ci_platforms": [
@@ -41173,6 +44280,23 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/api_fuzzer_corpus/e94428d78182060ff6309dd626cf6b3ebeed88d6"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "api_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/api_fuzzer_corpus/ea2cf809383d8725bec1b44ab774f04b3e6d5ae5"
     ], 
     "ci_platforms": [
@@ -69682,6 +72806,23 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/server_fuzzer_corpus/05551028437699c8650f5d08eb5f95ee25adf436"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "server_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/server_fuzzer_corpus/05c3a0390d0f52d241728926fa901599a47e4606"
     ], 
     "ci_platforms": [
@@ -69716,6 +72857,23 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/server_fuzzer_corpus/06285b50669cc16463db009ac821f99cf1ec2e24"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "server_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/server_fuzzer_corpus/06bd2f82fefb9943787d63ea359f9b77072380c2"
     ], 
     "ci_platforms": [
@@ -70515,6 +73673,40 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/server_fuzzer_corpus/23c582f6e23c7bbc9ae7b039b3b4e2ccdea3d5d2"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "server_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
+      "test/core/end2end/fuzzers/server_fuzzer_corpus/23f261e44d54a2736f6e288128d98db9e5015206"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "server_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/server_fuzzer_corpus/2463aea879c5ab49f8409d0e5c062c7e086b034b"
     ], 
     "ci_platforms": [
@@ -71127,6 +74319,23 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/server_fuzzer_corpus/395aea4fcfea081fc0d2733fff2d14405439fa72"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "server_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/server_fuzzer_corpus/39ea47bb.bin"
     ], 
     "ci_platforms": [
@@ -71314,6 +74523,23 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/server_fuzzer_corpus/404e234751b01dd0b51f9e7610f787253b074528"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "server_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/server_fuzzer_corpus/407607d2.bin"
     ], 
     "ci_platforms": [
@@ -71348,6 +74574,23 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/server_fuzzer_corpus/4123bd764c04385191342ea64918408140313714"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "server_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/server_fuzzer_corpus/418f392319c44d06a018ce4c62569d527829177a"
     ], 
     "ci_platforms": [
@@ -71705,6 +74948,23 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/server_fuzzer_corpus/4f96a5fba4d11401eb22d4b1e365fbbb2d684f24"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "server_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/server_fuzzer_corpus/4f97bd97ab5dc6b4c0f62f8459be8a9593dc83b3"
     ], 
     "ci_platforms": [
@@ -71943,6 +75203,23 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/server_fuzzer_corpus/552199651d942e7220141a93ec33dd8256210a18"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "server_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/server_fuzzer_corpus/55af20415ead0ddd417f37fa91a4c767b749ee34"
     ], 
     "ci_platforms": [
@@ -72232,6 +75509,23 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/server_fuzzer_corpus/609706c57e848ea58d7ca14fe6cc253322f3e8ce"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "server_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/server_fuzzer_corpus/61e798bdd49b339983fea4ccfe18efe44afbd69b"
     ], 
     "ci_platforms": [
@@ -72708,6 +76002,23 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/server_fuzzer_corpus/7a946bf3cd91b63001f2cf3f40c515c747f2ecde"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "server_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/server_fuzzer_corpus/7b453adcb9c4bf31dbc448ff32c2bc90ebcbdf0f"
     ], 
     "ci_platforms": [
@@ -72725,6 +76036,23 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/server_fuzzer_corpus/7d25c28298fb4d0fe41209d0d14307e4aa67c59e"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "server_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/server_fuzzer_corpus/7ddfac7d7845b424bf670070781ca6ff8586c63b"
     ], 
     "ci_platforms": [
@@ -72776,6 +76104,23 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/server_fuzzer_corpus/8138b18a9a743659befc2f2b23d23cb9c3086a09"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "server_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/server_fuzzer_corpus/8164d3c4af043c47cfd6966873bccd2353d072bf"
     ], 
     "ci_platforms": [
@@ -72980,6 +76325,23 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/server_fuzzer_corpus/89cd90fb47bb9eb289e8126b26021ee00d572d95"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "server_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/server_fuzzer_corpus/8b186384.bin"
     ], 
     "ci_platforms": [
@@ -73184,6 +76546,23 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/server_fuzzer_corpus/925011abb99fd56bb0f425ae5e0d92e6d341f804"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "server_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/server_fuzzer_corpus/93beeba2.bin"
     ], 
     "ci_platforms": [
@@ -73337,6 +76716,23 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/server_fuzzer_corpus/99a1acc96512c1155f91afa378e2345726d307c3"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "server_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/server_fuzzer_corpus/9a176b6f7e0dc5f681a1788d8954f76fabd08cad"
     ], 
     "ci_platforms": [
@@ -74595,6 +77991,40 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/server_fuzzer_corpus/crash-c1f66840627e3bfdedf2e4c225bc4de0c267ed37"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "server_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
+      "test/core/end2end/fuzzers/server_fuzzer_corpus/crash-ccf36bef9318fe6d5e5e1560c5485cdc87d0a701"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "server_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/server_fuzzer_corpus/crash-dae0f07934a527989f23f06e630710ff6ca8c809"
     ], 
     "ci_platforms": [
@@ -74697,6 +78127,23 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/server_fuzzer_corpus/d6bed9cc3c10338a8c5f41064ff8bec0bbc267ce"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "server_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/server_fuzzer_corpus/d8a1d141a9e3876b71c7decbe6e3affccf6de397"
     ], 
     "ci_platforms": [
@@ -74850,6 +78297,23 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/server_fuzzer_corpus/dda9643679f8c8b796e64232a7d153e447d64991"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "server_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/server_fuzzer_corpus/df5d3cf5f05eab65ef9d385e263780ae73c42b19"
     ], 
     "ci_platforms": [
@@ -74952,6 +78416,23 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/server_fuzzer_corpus/e7b08e36420fa107f0aee652e62158af85a4ef15"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "server_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/server_fuzzer_corpus/e96ad9c17795e52edc810a08d4fc61fe8790002a"
     ], 
     "ci_platforms": [
@@ -75037,6 +78518,23 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/server_fuzzer_corpus/ec4949487fa84f0cead39521b51f837af9dc784a"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "server_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/server_fuzzer_corpus/ed8da77f.bin"
     ], 
     "ci_platforms": [
@@ -75530,6 +79028,23 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-0292270056246b7a4ccd2e7d0356665cef307ef2"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "server_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-082763e16153cb6b8f3f5308cd060e822f475e5a"
     ], 
     "ci_platforms": [
@@ -75547,6 +79062,23 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-098ec93ded3a20e6043d11e9cc6066351e257f8e"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "server_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-0aa52e00ddd54f8e129430852c2da95650c354b0"
     ], 
     "ci_platforms": [
@@ -75649,6 +79181,57 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-1dc659f500e7bee41a4fee4423ade8332c162cc0"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "server_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
+      "test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-350b5da741597222c98fe86768432507850317f5"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "server_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
+      "test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-395aea4fcfea081fc0d2733fff2d14405439fa72"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "server_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-3991c873ba814d0cd03a67d25fff0c8fe8713aca"
     ], 
     "ci_platforms": [
@@ -75683,6 +79266,23 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-45cf8ac5faa9c7b15baf9281e8d7e0b4e103f0e0"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "server_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-4c6da955e4c101b81a62b2f8e934d94a62ae534b"
     ], 
     "ci_platforms": [
@@ -75734,6 +79334,23 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-60a9f77951c5059616764894e1963d83d478edfe"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "server_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-63ebf780ee6c2003eba622686a4bf94c503ad96e"
     ], 
     "ci_platforms": [
@@ -75887,6 +79504,23 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-97a338fa892093ed5013a76b96b35dd112df3342"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "server_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-9a176b6f7e0dc5f681a1788d8954f76fabd08cad"
     ], 
     "ci_platforms": [
@@ -75921,6 +79555,40 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-a1b2cfcf0997acb13a32fc5c004f57d9e9bc4275"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "server_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
+      "test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-a1ed26e6f82ca0e81e3f415bd8b0b8b520d3927b"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "server_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-a61a28cf78149518466b87e5463ec5c771dc504e"
     ], 
     "ci_platforms": [
@@ -76193,6 +79861,23 @@
   }, 
   {
     "args": [
+      "test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-f412afea6b01aa53da919a41a65ffbf9885f2d65"
+    ], 
+    "ci_platforms": [
+      "linux"
+    ], 
+    "cpu_cost": 0.1, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "language": "c", 
+    "name": "server_fuzzer_one_entry", 
+    "platforms": [
+      "linux"
+    ], 
+    "uses_polling": false
+  }, 
+  {
+    "args": [
       "test/core/end2end/fuzzers/server_fuzzer_corpus/slow-unit-f67be653815f6c2c10eea55c8009e1167ac9c20b"
     ], 
     "ci_platforms": [
diff --git a/vsprojects/buildtests_c.sln b/vsprojects/buildtests_c.sln
index be8b5d4..ca43dad 100644
--- a/vsprojects/buildtests_c.sln
+++ b/vsprojects/buildtests_c.sln
@@ -3,121 +3,6 @@
 # Visual Studio 2013
 VisualStudioVersion = 12.0.21005.1
 MinimumVisualStudioVersion = 10.0.40219.1
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gpr", "vcxproj\.\gpr\gpr.vcxproj", "{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}"
-	ProjectSection(myProperties) = preProject
-        	lib = "True"
-	EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gpr_test_util", "vcxproj\.\gpr_test_util\gpr_test_util.vcxproj", "{EAB0A629-17A9-44DB-B5FF-E91A721FE037}"
-	ProjectSection(myProperties) = preProject
-        	lib = "True"
-	EndProjectSection
-	ProjectSection(ProjectDependencies) = postProject
-		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
-	EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "grpc", "vcxproj\.\grpc\grpc.vcxproj", "{29D16885-7228-4C31-81ED-5F9187C7F2A9}"
-	ProjectSection(myProperties) = preProject
-        	lib = "True"
-	EndProjectSection
-	ProjectSection(ProjectDependencies) = postProject
-		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
-	EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "grpc_dll", "vcxproj\.\grpc_dll\grpc_dll.vcxproj", "{A2F6CBBA-A553-41B3-A7DE-F26DECCC27F0}"
-	ProjectSection(myProperties) = preProject
-        	lib = "True"
-	EndProjectSection
-	ProjectSection(ProjectDependencies) = postProject
-		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
-		{29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9}
-	EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "grpc_test_util", "vcxproj\.\grpc_test_util\grpc_test_util.vcxproj", "{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}"
-	ProjectSection(myProperties) = preProject
-        	lib = "True"
-	EndProjectSection
-	ProjectSection(ProjectDependencies) = postProject
-		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
-		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
-		{29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9}
-	EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "grpc_test_util_unsecure", "vcxproj\.\grpc_test_util_unsecure\grpc_test_util_unsecure.vcxproj", "{0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF}"
-	ProjectSection(myProperties) = preProject
-        	lib = "True"
-	EndProjectSection
-	ProjectSection(ProjectDependencies) = postProject
-		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
-		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
-		{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5} = {46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}
-		{29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9}
-	EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "grpc_unsecure", "vcxproj\.\grpc_unsecure\grpc_unsecure.vcxproj", "{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}"
-	ProjectSection(myProperties) = preProject
-        	lib = "True"
-	EndProjectSection
-	ProjectSection(ProjectDependencies) = postProject
-		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
-	EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "reconnect_server", "vcxproj\.\reconnect_server\reconnect_server.vcxproj", "{929C90AE-483F-AC80-EF93-226199F9E428}"
-	ProjectSection(myProperties) = preProject
-        	lib = "True"
-	EndProjectSection
-	ProjectSection(ProjectDependencies) = postProject
-		{E3110C46-A148-FF65-08FD-3324829BE7FE} = {E3110C46-A148-FF65-08FD-3324829BE7FE}
-		{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B} = {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}
-		{29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9}
-		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
-		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
-	EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_tcp_server", "vcxproj\.\test_tcp_server\test_tcp_server.vcxproj", "{E3110C46-A148-FF65-08FD-3324829BE7FE}"
-	ProjectSection(myProperties) = preProject
-        	lib = "True"
-	EndProjectSection
-	ProjectSection(ProjectDependencies) = postProject
-		{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B} = {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}
-		{29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9}
-		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
-		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
-	EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bad_client_test", "vcxproj\test/bad_client\bad_client_test\bad_client_test.vcxproj", "{BA67B418-B699-E41A-9CC4-0279C49481A5}"
-	ProjectSection(myProperties) = preProject
-        	lib = "True"
-	EndProjectSection
-	ProjectSection(ProjectDependencies) = postProject
-		{0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF} = {0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF}
-		{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5} = {46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}
-		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
-		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
-	EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "end2end_tests", "vcxproj\test/end2end/tests\end2end_tests\end2end_tests.vcxproj", "{1F1F9084-2A93-B80E-364F-5754894AFAB4}"
-	ProjectSection(myProperties) = preProject
-        	lib = "True"
-	EndProjectSection
-	ProjectSection(ProjectDependencies) = postProject
-		{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B} = {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}
-		{29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9}
-		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
-		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
-	EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "end2end_nosec_tests", "vcxproj\test/end2end/tests\end2end_nosec_tests\end2end_nosec_tests.vcxproj", "{47C2CB41-4E9F-58B6-F606-F6FAED5D00ED}"
-	ProjectSection(myProperties) = preProject
-        	lib = "True"
-	EndProjectSection
-	ProjectSection(ProjectDependencies) = postProject
-		{0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF} = {0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF}
-		{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5} = {46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}
-		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
-		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
-	EndProjectSection
-EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "alarm_test", "vcxproj\test\alarm_test\alarm_test.vcxproj", "{AFD362D7-0E2A-E700-1F27-9D90F76166DF}"
 	ProjectSection(myProperties) = preProject
         	lib = "False"
@@ -160,6 +45,29 @@
 		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
 	EndProjectSection
 EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bad_client_test", "vcxproj\test/bad_client\bad_client_test\bad_client_test.vcxproj", "{BA67B418-B699-E41A-9CC4-0279C49481A5}"
+	ProjectSection(myProperties) = preProject
+        	lib = "True"
+	EndProjectSection
+	ProjectSection(ProjectDependencies) = postProject
+		{0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF} = {0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF}
+		{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5} = {46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}
+		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
+		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "badreq_bad_client_test", "vcxproj\test\badreq_bad_client_test\badreq_bad_client_test.vcxproj", "{8A811C28-E04E-A444-E4C1-7588DF5B90AE}"
+	ProjectSection(myProperties) = preProject
+        	lib = "False"
+	EndProjectSection
+	ProjectSection(ProjectDependencies) = postProject
+		{BA67B418-B699-E41A-9CC4-0279C49481A5} = {BA67B418-B699-E41A-9CC4-0279C49481A5}
+		{0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF} = {0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF}
+		{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5} = {46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}
+		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
+		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
+	EndProjectSection
+EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bin_encoder_test", "vcxproj\test\bin_encoder_test\bin_encoder_test.vcxproj", "{D5C70922-D68E-0E9D-9988-995E0F9A79AE}"
 	ProjectSection(myProperties) = preProject
         	lib = "False"
@@ -257,6 +165,18 @@
 		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
 	EndProjectSection
 EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "connection_prefix_bad_client_test", "vcxproj\test\connection_prefix_bad_client_test\connection_prefix_bad_client_test.vcxproj", "{AF9D0EB2-2A53-B815-3A63-E82C7F91DB29}"
+	ProjectSection(myProperties) = preProject
+        	lib = "False"
+	EndProjectSection
+	ProjectSection(ProjectDependencies) = postProject
+		{BA67B418-B699-E41A-9CC4-0279C49481A5} = {BA67B418-B699-E41A-9CC4-0279C49481A5}
+		{0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF} = {0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF}
+		{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5} = {46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}
+		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
+		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
+	EndProjectSection
+EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dns_resolver_connectivity_test", "vcxproj\test\dns_resolver_connectivity_test\dns_resolver_connectivity_test.vcxproj", "{F7B6FE68-E847-D7CA-4062-E737E542BCC3}"
 	ProjectSection(myProperties) = preProject
         	lib = "False"
@@ -279,6 +199,28 @@
 		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
 	EndProjectSection
 EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "end2end_nosec_tests", "vcxproj\test/end2end/tests\end2end_nosec_tests\end2end_nosec_tests.vcxproj", "{47C2CB41-4E9F-58B6-F606-F6FAED5D00ED}"
+	ProjectSection(myProperties) = preProject
+        	lib = "True"
+	EndProjectSection
+	ProjectSection(ProjectDependencies) = postProject
+		{0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF} = {0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF}
+		{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5} = {46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}
+		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
+		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "end2end_tests", "vcxproj\test/end2end/tests\end2end_tests\end2end_tests.vcxproj", "{1F1F9084-2A93-B80E-364F-5754894AFAB4}"
+	ProjectSection(myProperties) = preProject
+        	lib = "True"
+	EndProjectSection
+	ProjectSection(ProjectDependencies) = postProject
+		{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B} = {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}
+		{29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9}
+		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
+		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
+	EndProjectSection
+EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "endpoint_pair_test", "vcxproj\test\endpoint_pair_test\endpoint_pair_test.vcxproj", "{37166D50-3AAA-1156-19F6-5901DFA55172}"
 	ProjectSection(myProperties) = preProject
         	lib = "False"
@@ -326,6 +268,11 @@
         	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"
+	EndProjectSection
+EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gpr_avl_test", "vcxproj\test\gpr_avl_test\gpr_avl_test.vcxproj", "{144D8CFF-2737-A18A-DCFD-01603533D63F}"
 	ProjectSection(myProperties) = preProject
         	lib = "False"
@@ -452,6 +399,14 @@
 		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
 	EndProjectSection
 EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gpr_test_util", "vcxproj\.\gpr_test_util\gpr_test_util.vcxproj", "{EAB0A629-17A9-44DB-B5FF-E91A721FE037}"
+	ProjectSection(myProperties) = preProject
+        	lib = "True"
+	EndProjectSection
+	ProjectSection(ProjectDependencies) = postProject
+		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
+	EndProjectSection
+EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gpr_thd_test", "vcxproj\test\gpr_thd_test\gpr_thd_test.vcxproj", "{459B2FAC-5FC8-1F47-8053-66D46EA39A49}"
 	ProjectSection(myProperties) = preProject
         	lib = "False"
@@ -488,6 +443,14 @@
 		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
 	EndProjectSection
 EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "grpc", "vcxproj\.\grpc\grpc.vcxproj", "{29D16885-7228-4C31-81ED-5F9187C7F2A9}"
+	ProjectSection(myProperties) = preProject
+        	lib = "True"
+	EndProjectSection
+	ProjectSection(ProjectDependencies) = postProject
+		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
+	EndProjectSection
+EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "grpc_auth_context_test", "vcxproj\test\grpc_auth_context_test\grpc_auth_context_test.vcxproj", "{C65A4336-92D6-D6A0-EB86-E3AA425222D0}"
 	ProjectSection(myProperties) = preProject
         	lib = "False"
@@ -631,6 +594,35 @@
 		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
 	EndProjectSection
 EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "grpc_test_util", "vcxproj\.\grpc_test_util\grpc_test_util.vcxproj", "{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}"
+	ProjectSection(myProperties) = preProject
+        	lib = "True"
+	EndProjectSection
+	ProjectSection(ProjectDependencies) = postProject
+		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
+		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
+		{29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "grpc_test_util_unsecure", "vcxproj\.\grpc_test_util_unsecure\grpc_test_util_unsecure.vcxproj", "{0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF}"
+	ProjectSection(myProperties) = preProject
+        	lib = "True"
+	EndProjectSection
+	ProjectSection(ProjectDependencies) = postProject
+		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
+		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
+		{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5} = {46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}
+		{29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "grpc_unsecure", "vcxproj\.\grpc_unsecure\grpc_unsecure.vcxproj", "{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}"
+	ProjectSection(myProperties) = preProject
+        	lib = "True"
+	EndProjectSection
+	ProjectSection(ProjectDependencies) = postProject
+		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
+	EndProjectSection
+EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "grpc_verify_jwt", "vcxproj\.\grpc_verify_jwt\grpc_verify_jwt.vcxproj", "{02FAC25F-5FF6-34A0-00AE-B82BFBA851A9}"
 	ProjectSection(myProperties) = preProject
         	lib = "False"
@@ -642,6 +634,306 @@
 		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
 	EndProjectSection
 EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "h2_census_nosec_test", "vcxproj\test/end2end/fixtures\h2_census_nosec_test\h2_census_nosec_test.vcxproj", "{A8039D43-910E-4248-2A22-74366E8C4DCD}"
+	ProjectSection(myProperties) = preProject
+        	lib = "False"
+	EndProjectSection
+	ProjectSection(ProjectDependencies) = postProject
+		{47C2CB41-4E9F-58B6-F606-F6FAED5D00ED} = {47C2CB41-4E9F-58B6-F606-F6FAED5D00ED}
+		{0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF} = {0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF}
+		{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5} = {46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}
+		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
+		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "h2_census_test", "vcxproj\test/end2end/fixtures\h2_census_test\h2_census_test.vcxproj", "{9E4180B0-81ED-7305-333F-653CE9AB819B}"
+	ProjectSection(myProperties) = preProject
+        	lib = "False"
+	EndProjectSection
+	ProjectSection(ProjectDependencies) = postProject
+		{1F1F9084-2A93-B80E-364F-5754894AFAB4} = {1F1F9084-2A93-B80E-364F-5754894AFAB4}
+		{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B} = {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}
+		{29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9}
+		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
+		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "h2_compress_nosec_test", "vcxproj\test/end2end/fixtures\h2_compress_nosec_test\h2_compress_nosec_test.vcxproj", "{42826C1F-DCF0-918E-D247-0376DC1EFD50}"
+	ProjectSection(myProperties) = preProject
+        	lib = "False"
+	EndProjectSection
+	ProjectSection(ProjectDependencies) = postProject
+		{47C2CB41-4E9F-58B6-F606-F6FAED5D00ED} = {47C2CB41-4E9F-58B6-F606-F6FAED5D00ED}
+		{0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF} = {0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF}
+		{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5} = {46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}
+		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
+		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "h2_compress_test", "vcxproj\test/end2end/fixtures\h2_compress_test\h2_compress_test.vcxproj", "{C7E516E9-B80F-4BC1-A617-095FC6E14BC9}"
+	ProjectSection(myProperties) = preProject
+        	lib = "False"
+	EndProjectSection
+	ProjectSection(ProjectDependencies) = postProject
+		{1F1F9084-2A93-B80E-364F-5754894AFAB4} = {1F1F9084-2A93-B80E-364F-5754894AFAB4}
+		{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B} = {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}
+		{29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9}
+		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
+		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "h2_fakesec_test", "vcxproj\test/end2end/fixtures\h2_fakesec_test\h2_fakesec_test.vcxproj", "{0E980562-3AA0-91B1-C590-85C9A899BE44}"
+	ProjectSection(myProperties) = preProject
+        	lib = "False"
+	EndProjectSection
+	ProjectSection(ProjectDependencies) = postProject
+		{1F1F9084-2A93-B80E-364F-5754894AFAB4} = {1F1F9084-2A93-B80E-364F-5754894AFAB4}
+		{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B} = {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}
+		{29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9}
+		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
+		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "h2_full+trace_nosec_test", "vcxproj\test/end2end/fixtures\h2_full+trace_nosec_test\h2_full+trace_nosec_test.vcxproj", "{DFD51943-4906-8051-7D66-6A7D50E0D87E}"
+	ProjectSection(myProperties) = preProject
+        	lib = "False"
+	EndProjectSection
+	ProjectSection(ProjectDependencies) = postProject
+		{47C2CB41-4E9F-58B6-F606-F6FAED5D00ED} = {47C2CB41-4E9F-58B6-F606-F6FAED5D00ED}
+		{0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF} = {0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF}
+		{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5} = {46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}
+		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
+		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "h2_full+trace_test", "vcxproj\test/end2end/fixtures\h2_full+trace_test\h2_full+trace_test.vcxproj", "{16C713C6-062E-F71F-A44C-52DC35494B27}"
+	ProjectSection(myProperties) = preProject
+        	lib = "False"
+	EndProjectSection
+	ProjectSection(ProjectDependencies) = postProject
+		{1F1F9084-2A93-B80E-364F-5754894AFAB4} = {1F1F9084-2A93-B80E-364F-5754894AFAB4}
+		{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B} = {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}
+		{29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9}
+		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
+		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "h2_full_nosec_test", "vcxproj\test/end2end/fixtures\h2_full_nosec_test\h2_full_nosec_test.vcxproj", "{345EA50E-BCD4-DAC7-E1C8-DDA6291B75E2}"
+	ProjectSection(myProperties) = preProject
+        	lib = "False"
+	EndProjectSection
+	ProjectSection(ProjectDependencies) = postProject
+		{47C2CB41-4E9F-58B6-F606-F6FAED5D00ED} = {47C2CB41-4E9F-58B6-F606-F6FAED5D00ED}
+		{0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF} = {0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF}
+		{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5} = {46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}
+		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
+		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "h2_full_test", "vcxproj\test/end2end/fixtures\h2_full_test\h2_full_test.vcxproj", "{EEBEFA75-C625-C823-FE96-9AD64887B57D}"
+	ProjectSection(myProperties) = preProject
+        	lib = "False"
+	EndProjectSection
+	ProjectSection(ProjectDependencies) = postProject
+		{1F1F9084-2A93-B80E-364F-5754894AFAB4} = {1F1F9084-2A93-B80E-364F-5754894AFAB4}
+		{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B} = {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}
+		{29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9}
+		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
+		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "h2_loadreporting_nosec_test", "vcxproj\test/end2end/fixtures\h2_loadreporting_nosec_test\h2_loadreporting_nosec_test.vcxproj", "{679EA55C-7399-53E8-79F0-82FBDB3DDE07}"
+	ProjectSection(myProperties) = preProject
+        	lib = "False"
+	EndProjectSection
+	ProjectSection(ProjectDependencies) = postProject
+		{47C2CB41-4E9F-58B6-F606-F6FAED5D00ED} = {47C2CB41-4E9F-58B6-F606-F6FAED5D00ED}
+		{0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF} = {0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF}
+		{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5} = {46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}
+		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
+		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "h2_loadreporting_test", "vcxproj\test/end2end/fixtures\h2_loadreporting_test\h2_loadreporting_test.vcxproj", "{B107130E-EA33-C114-9CB6-78A18C929F64}"
+	ProjectSection(myProperties) = preProject
+        	lib = "False"
+	EndProjectSection
+	ProjectSection(ProjectDependencies) = postProject
+		{1F1F9084-2A93-B80E-364F-5754894AFAB4} = {1F1F9084-2A93-B80E-364F-5754894AFAB4}
+		{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B} = {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}
+		{29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9}
+		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
+		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "h2_oauth2_test", "vcxproj\test/end2end/fixtures\h2_oauth2_test\h2_oauth2_test.vcxproj", "{0F761FF3-342A-C429-711F-F76181BAA52D}"
+	ProjectSection(myProperties) = preProject
+        	lib = "False"
+	EndProjectSection
+	ProjectSection(ProjectDependencies) = postProject
+		{1F1F9084-2A93-B80E-364F-5754894AFAB4} = {1F1F9084-2A93-B80E-364F-5754894AFAB4}
+		{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B} = {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}
+		{29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9}
+		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
+		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "h2_proxy_nosec_test", "vcxproj\test/end2end/fixtures\h2_proxy_nosec_test\h2_proxy_nosec_test.vcxproj", "{6EC72045-98CB-8A8D-9788-BC94209E23C8}"
+	ProjectSection(myProperties) = preProject
+        	lib = "False"
+	EndProjectSection
+	ProjectSection(ProjectDependencies) = postProject
+		{47C2CB41-4E9F-58B6-F606-F6FAED5D00ED} = {47C2CB41-4E9F-58B6-F606-F6FAED5D00ED}
+		{0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF} = {0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF}
+		{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5} = {46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}
+		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
+		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "h2_proxy_test", "vcxproj\test/end2end/fixtures\h2_proxy_test\h2_proxy_test.vcxproj", "{5753B14F-0C69-2E56-6264-5541B2DCDF67}"
+	ProjectSection(myProperties) = preProject
+        	lib = "False"
+	EndProjectSection
+	ProjectSection(ProjectDependencies) = postProject
+		{1F1F9084-2A93-B80E-364F-5754894AFAB4} = {1F1F9084-2A93-B80E-364F-5754894AFAB4}
+		{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B} = {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}
+		{29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9}
+		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
+		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "h2_sockpair+trace_nosec_test", "vcxproj\test/end2end/fixtures\h2_sockpair+trace_nosec_test\h2_sockpair+trace_nosec_test.vcxproj", "{962380E0-1C06-8917-8F7F-1A02E0E93BE7}"
+	ProjectSection(myProperties) = preProject
+        	lib = "False"
+	EndProjectSection
+	ProjectSection(ProjectDependencies) = postProject
+		{47C2CB41-4E9F-58B6-F606-F6FAED5D00ED} = {47C2CB41-4E9F-58B6-F606-F6FAED5D00ED}
+		{0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF} = {0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF}
+		{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5} = {46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}
+		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
+		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "h2_sockpair+trace_test", "vcxproj\test/end2end/fixtures\h2_sockpair+trace_test\h2_sockpair+trace_test.vcxproj", "{82878169-5A89-FD1E-31A6-E9F07BB92418}"
+	ProjectSection(myProperties) = preProject
+        	lib = "False"
+	EndProjectSection
+	ProjectSection(ProjectDependencies) = postProject
+		{1F1F9084-2A93-B80E-364F-5754894AFAB4} = {1F1F9084-2A93-B80E-364F-5754894AFAB4}
+		{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B} = {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}
+		{29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9}
+		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
+		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "h2_sockpair_1byte_nosec_test", "vcxproj\test/end2end/fixtures\h2_sockpair_1byte_nosec_test\h2_sockpair_1byte_nosec_test.vcxproj", "{485E6713-487D-F274-BDE7-5D29300C93FE}"
+	ProjectSection(myProperties) = preProject
+        	lib = "False"
+	EndProjectSection
+	ProjectSection(ProjectDependencies) = postProject
+		{47C2CB41-4E9F-58B6-F606-F6FAED5D00ED} = {47C2CB41-4E9F-58B6-F606-F6FAED5D00ED}
+		{0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF} = {0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF}
+		{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5} = {46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}
+		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
+		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "h2_sockpair_1byte_test", "vcxproj\test/end2end/fixtures\h2_sockpair_1byte_test\h2_sockpair_1byte_test.vcxproj", "{03A65361-E139-5344-1868-8E8FC269C6E6}"
+	ProjectSection(myProperties) = preProject
+        	lib = "False"
+	EndProjectSection
+	ProjectSection(ProjectDependencies) = postProject
+		{1F1F9084-2A93-B80E-364F-5754894AFAB4} = {1F1F9084-2A93-B80E-364F-5754894AFAB4}
+		{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B} = {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}
+		{29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9}
+		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
+		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "h2_sockpair_nosec_test", "vcxproj\test/end2end/fixtures\h2_sockpair_nosec_test\h2_sockpair_nosec_test.vcxproj", "{B3F26242-A43D-4F77-A84C-0F478741A061}"
+	ProjectSection(myProperties) = preProject
+        	lib = "False"
+	EndProjectSection
+	ProjectSection(ProjectDependencies) = postProject
+		{47C2CB41-4E9F-58B6-F606-F6FAED5D00ED} = {47C2CB41-4E9F-58B6-F606-F6FAED5D00ED}
+		{0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF} = {0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF}
+		{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5} = {46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}
+		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
+		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "h2_sockpair_test", "vcxproj\test/end2end/fixtures\h2_sockpair_test\h2_sockpair_test.vcxproj", "{67458AF8-A122-7740-F195-C2E74A106FAB}"
+	ProjectSection(myProperties) = preProject
+        	lib = "False"
+	EndProjectSection
+	ProjectSection(ProjectDependencies) = postProject
+		{1F1F9084-2A93-B80E-364F-5754894AFAB4} = {1F1F9084-2A93-B80E-364F-5754894AFAB4}
+		{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B} = {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}
+		{29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9}
+		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
+		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "h2_ssl_cert_test", "vcxproj\test/end2end/fixtures\h2_ssl_cert_test\h2_ssl_cert_test.vcxproj", "{B3B7D225-3C04-72F9-4C2C-1C3F3136FE58}"
+	ProjectSection(myProperties) = preProject
+        	lib = "False"
+	EndProjectSection
+	ProjectSection(ProjectDependencies) = postProject
+		{1F1F9084-2A93-B80E-364F-5754894AFAB4} = {1F1F9084-2A93-B80E-364F-5754894AFAB4}
+		{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B} = {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}
+		{29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9}
+		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
+		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "h2_ssl_proxy_test", "vcxproj\test/end2end/fixtures\h2_ssl_proxy_test\h2_ssl_proxy_test.vcxproj", "{A9092608-E45E-AC96-6533-A6E7DD98211D}"
+	ProjectSection(myProperties) = preProject
+        	lib = "False"
+	EndProjectSection
+	ProjectSection(ProjectDependencies) = postProject
+		{1F1F9084-2A93-B80E-364F-5754894AFAB4} = {1F1F9084-2A93-B80E-364F-5754894AFAB4}
+		{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B} = {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}
+		{29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9}
+		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
+		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "h2_ssl_test", "vcxproj\test/end2end/fixtures\h2_ssl_test\h2_ssl_test.vcxproj", "{EA78D290-4098-FF04-C647-013F6B81E4E7}"
+	ProjectSection(myProperties) = preProject
+        	lib = "False"
+	EndProjectSection
+	ProjectSection(ProjectDependencies) = postProject
+		{1F1F9084-2A93-B80E-364F-5754894AFAB4} = {1F1F9084-2A93-B80E-364F-5754894AFAB4}
+		{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B} = {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}
+		{29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9}
+		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
+		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "head_of_line_blocking_bad_client_test", "vcxproj\test\head_of_line_blocking_bad_client_test\head_of_line_blocking_bad_client_test.vcxproj", "{23DF0572-DBF1-08DA-8EAD-8508354C90A4}"
+	ProjectSection(myProperties) = preProject
+        	lib = "False"
+	EndProjectSection
+	ProjectSection(ProjectDependencies) = postProject
+		{BA67B418-B699-E41A-9CC4-0279C49481A5} = {BA67B418-B699-E41A-9CC4-0279C49481A5}
+		{0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF} = {0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF}
+		{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5} = {46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}
+		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
+		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "headers_bad_client_test", "vcxproj\test\headers_bad_client_test\headers_bad_client_test.vcxproj", "{7819A11E-607E-F0C0-FC47-C704CF7D818C}"
+	ProjectSection(myProperties) = preProject
+        	lib = "False"
+	EndProjectSection
+	ProjectSection(ProjectDependencies) = postProject
+		{BA67B418-B699-E41A-9CC4-0279C49481A5} = {BA67B418-B699-E41A-9CC4-0279C49481A5}
+		{0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF} = {0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF}
+		{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5} = {46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}
+		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
+		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
+	EndProjectSection
+EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "hpack_parser_test", "vcxproj\test\hpack_parser_test\hpack_parser_test.vcxproj", "{4CAEC7C3-5354-D474-FB3D-ABED6AD2E1DA}"
 	ProjectSection(myProperties) = preProject
         	lib = "False"
@@ -697,6 +989,18 @@
 		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
 	EndProjectSection
 EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "initial_settings_frame_bad_client_test", "vcxproj\test\initial_settings_frame_bad_client_test\initial_settings_frame_bad_client_test.vcxproj", "{6756895E-05BF-8CC7-58F2-868DF0C0300C}"
+	ProjectSection(myProperties) = preProject
+        	lib = "False"
+	EndProjectSection
+	ProjectSection(ProjectDependencies) = postProject
+		{BA67B418-B699-E41A-9CC4-0279C49481A5} = {BA67B418-B699-E41A-9CC4-0279C49481A5}
+		{0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF} = {0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF}
+		{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5} = {46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}
+		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
+		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
+	EndProjectSection
+EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "internal_api_canary_iomgr_test", "vcxproj\test\internal_api_canary_iomgr_test\internal_api_canary_iomgr_test.vcxproj", "{28AE726B-1BFB-202B-48D2-41AF9D09B9EA}"
 	ProjectSection(myProperties) = preProject
         	lib = "False"
@@ -794,6 +1098,18 @@
 		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
 	EndProjectSection
 EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "large_metadata_bad_client_test", "vcxproj\test\large_metadata_bad_client_test\large_metadata_bad_client_test.vcxproj", "{B706A9EC-7982-0DBC-495D-07B165F6CF56}"
+	ProjectSection(myProperties) = preProject
+        	lib = "False"
+	EndProjectSection
+	ProjectSection(ProjectDependencies) = postProject
+		{BA67B418-B699-E41A-9CC4-0279C49481A5} = {BA67B418-B699-E41A-9CC4-0279C49481A5}
+		{0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF} = {0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF}
+		{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5} = {46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}
+		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
+		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
+	EndProjectSection
+EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lb_policies_test", "vcxproj\test\lb_policies_test\lb_policies_test.vcxproj", "{62D58A08-3B5E-D6A8-ABBB-77995AA0A8C6}"
 	ProjectSection(myProperties) = preProject
         	lib = "False"
@@ -902,6 +1218,18 @@
 		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
 	EndProjectSection
 EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "server_registered_method_bad_client_test", "vcxproj\test\server_registered_method_bad_client_test\server_registered_method_bad_client_test.vcxproj", "{B4E7CD82-988A-BD3A-29F8-8590D3A8BC28}"
+	ProjectSection(myProperties) = preProject
+        	lib = "False"
+	EndProjectSection
+	ProjectSection(ProjectDependencies) = postProject
+		{BA67B418-B699-E41A-9CC4-0279C49481A5} = {BA67B418-B699-E41A-9CC4-0279C49481A5}
+		{0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF} = {0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF}
+		{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5} = {46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}
+		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
+		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
+	EndProjectSection
+EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "server_test", "vcxproj\test\server_test\server_test.vcxproj", "{E765AC67-E4E5-C350-59A1-C6CA2BD9F64B}"
 	ProjectSection(myProperties) = preProject
         	lib = "False"
@@ -925,6 +1253,18 @@
 		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
 	EndProjectSection
 EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "simple_request_bad_client_test", "vcxproj\test\simple_request_bad_client_test\simple_request_bad_client_test.vcxproj", "{63422647-93FA-46BB-4827-95473D9D503C}"
+	ProjectSection(myProperties) = preProject
+        	lib = "False"
+	EndProjectSection
+	ProjectSection(ProjectDependencies) = postProject
+		{BA67B418-B699-E41A-9CC4-0279C49481A5} = {BA67B418-B699-E41A-9CC4-0279C49481A5}
+		{0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF} = {0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF}
+		{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5} = {46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}
+		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
+		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
+	EndProjectSection
+EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sockaddr_resolver_test", "vcxproj\test\sockaddr_resolver_test\sockaddr_resolver_test.vcxproj", "{9889A80C-F1D7-99C9-FE7E-657724BEDC62}"
 	ProjectSection(myProperties) = preProject
         	lib = "False"
@@ -947,6 +1287,17 @@
 		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
 	EndProjectSection
 EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test_tcp_server", "vcxproj\.\test_tcp_server\test_tcp_server.vcxproj", "{E3110C46-A148-FF65-08FD-3324829BE7FE}"
+	ProjectSection(myProperties) = preProject
+        	lib = "True"
+	EndProjectSection
+	ProjectSection(ProjectDependencies) = postProject
+		{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B} = {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}
+		{29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9}
+		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
+		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
+	EndProjectSection
+EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "time_averaged_stats_test", "vcxproj\test\time_averaged_stats_test\time_averaged_stats_test.vcxproj", "{D1EB2A9B-8508-62D7-8FC4-11A11B1CBFD3}"
 	ProjectSection(myProperties) = preProject
         	lib = "False"
@@ -1024,113 +1375,6 @@
 		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
 	EndProjectSection
 EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "uri_parser_test", "vcxproj\test\uri_parser_test\uri_parser_test.vcxproj", "{E35C24A0-8725-E773-FE78-CC0C67071EF7}"
-	ProjectSection(myProperties) = preProject
-        	lib = "False"
-	EndProjectSection
-	ProjectSection(ProjectDependencies) = postProject
-		{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B} = {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}
-		{29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9}
-		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
-		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
-	EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "badreq_bad_client_test", "vcxproj\test\badreq_bad_client_test\badreq_bad_client_test.vcxproj", "{8A811C28-E04E-A444-E4C1-7588DF5B90AE}"
-	ProjectSection(myProperties) = preProject
-        	lib = "False"
-	EndProjectSection
-	ProjectSection(ProjectDependencies) = postProject
-		{BA67B418-B699-E41A-9CC4-0279C49481A5} = {BA67B418-B699-E41A-9CC4-0279C49481A5}
-		{0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF} = {0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF}
-		{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5} = {46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}
-		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
-		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
-	EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "connection_prefix_bad_client_test", "vcxproj\test\connection_prefix_bad_client_test\connection_prefix_bad_client_test.vcxproj", "{AF9D0EB2-2A53-B815-3A63-E82C7F91DB29}"
-	ProjectSection(myProperties) = preProject
-        	lib = "False"
-	EndProjectSection
-	ProjectSection(ProjectDependencies) = postProject
-		{BA67B418-B699-E41A-9CC4-0279C49481A5} = {BA67B418-B699-E41A-9CC4-0279C49481A5}
-		{0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF} = {0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF}
-		{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5} = {46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}
-		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
-		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
-	EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "head_of_line_blocking_bad_client_test", "vcxproj\test\head_of_line_blocking_bad_client_test\head_of_line_blocking_bad_client_test.vcxproj", "{23DF0572-DBF1-08DA-8EAD-8508354C90A4}"
-	ProjectSection(myProperties) = preProject
-        	lib = "False"
-	EndProjectSection
-	ProjectSection(ProjectDependencies) = postProject
-		{BA67B418-B699-E41A-9CC4-0279C49481A5} = {BA67B418-B699-E41A-9CC4-0279C49481A5}
-		{0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF} = {0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF}
-		{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5} = {46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}
-		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
-		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
-	EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "headers_bad_client_test", "vcxproj\test\headers_bad_client_test\headers_bad_client_test.vcxproj", "{7819A11E-607E-F0C0-FC47-C704CF7D818C}"
-	ProjectSection(myProperties) = preProject
-        	lib = "False"
-	EndProjectSection
-	ProjectSection(ProjectDependencies) = postProject
-		{BA67B418-B699-E41A-9CC4-0279C49481A5} = {BA67B418-B699-E41A-9CC4-0279C49481A5}
-		{0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF} = {0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF}
-		{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5} = {46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}
-		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
-		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
-	EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "initial_settings_frame_bad_client_test", "vcxproj\test\initial_settings_frame_bad_client_test\initial_settings_frame_bad_client_test.vcxproj", "{6756895E-05BF-8CC7-58F2-868DF0C0300C}"
-	ProjectSection(myProperties) = preProject
-        	lib = "False"
-	EndProjectSection
-	ProjectSection(ProjectDependencies) = postProject
-		{BA67B418-B699-E41A-9CC4-0279C49481A5} = {BA67B418-B699-E41A-9CC4-0279C49481A5}
-		{0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF} = {0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF}
-		{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5} = {46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}
-		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
-		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
-	EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "large_metadata_bad_client_test", "vcxproj\test\large_metadata_bad_client_test\large_metadata_bad_client_test.vcxproj", "{B706A9EC-7982-0DBC-495D-07B165F6CF56}"
-	ProjectSection(myProperties) = preProject
-        	lib = "False"
-	EndProjectSection
-	ProjectSection(ProjectDependencies) = postProject
-		{BA67B418-B699-E41A-9CC4-0279C49481A5} = {BA67B418-B699-E41A-9CC4-0279C49481A5}
-		{0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF} = {0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF}
-		{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5} = {46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}
-		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
-		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
-	EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "server_registered_method_bad_client_test", "vcxproj\test\server_registered_method_bad_client_test\server_registered_method_bad_client_test.vcxproj", "{B4E7CD82-988A-BD3A-29F8-8590D3A8BC28}"
-	ProjectSection(myProperties) = preProject
-        	lib = "False"
-	EndProjectSection
-	ProjectSection(ProjectDependencies) = postProject
-		{BA67B418-B699-E41A-9CC4-0279C49481A5} = {BA67B418-B699-E41A-9CC4-0279C49481A5}
-		{0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF} = {0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF}
-		{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5} = {46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}
-		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
-		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
-	EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "simple_request_bad_client_test", "vcxproj\test\simple_request_bad_client_test\simple_request_bad_client_test.vcxproj", "{63422647-93FA-46BB-4827-95473D9D503C}"
-	ProjectSection(myProperties) = preProject
-        	lib = "False"
-	EndProjectSection
-	ProjectSection(ProjectDependencies) = postProject
-		{BA67B418-B699-E41A-9CC4-0279C49481A5} = {BA67B418-B699-E41A-9CC4-0279C49481A5}
-		{0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF} = {0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF}
-		{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5} = {46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}
-		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
-		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
-	EndProjectSection
-EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "unknown_frame_bad_client_test", "vcxproj\test\unknown_frame_bad_client_test\unknown_frame_bad_client_test.vcxproj", "{9E0A2239-20D5-DB2D-CA0D-69F24E3416E7}"
 	ProjectSection(myProperties) = preProject
         	lib = "False"
@@ -1143,6 +1387,17 @@
 		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
 	EndProjectSection
 EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "uri_parser_test", "vcxproj\test\uri_parser_test\uri_parser_test.vcxproj", "{E35C24A0-8725-E773-FE78-CC0C67071EF7}"
+	ProjectSection(myProperties) = preProject
+        	lib = "False"
+	EndProjectSection
+	ProjectSection(ProjectDependencies) = postProject
+		{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B} = {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}
+		{29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9}
+		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
+		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
+	EndProjectSection
+EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "window_overflow_bad_client_test", "vcxproj\test\window_overflow_bad_client_test\window_overflow_bad_client_test.vcxproj", "{658D7F7F-9628-6545-743C-D949301DC5DC}"
 	ProjectSection(myProperties) = preProject
         	lib = "False"
@@ -1155,258 +1410,6 @@
 		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
 	EndProjectSection
 EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "h2_census_test", "vcxproj\test/end2end/fixtures\h2_census_test\h2_census_test.vcxproj", "{9E4180B0-81ED-7305-333F-653CE9AB819B}"
-	ProjectSection(myProperties) = preProject
-        	lib = "False"
-	EndProjectSection
-	ProjectSection(ProjectDependencies) = postProject
-		{1F1F9084-2A93-B80E-364F-5754894AFAB4} = {1F1F9084-2A93-B80E-364F-5754894AFAB4}
-		{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B} = {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}
-		{29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9}
-		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
-		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
-	EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "h2_compress_test", "vcxproj\test/end2end/fixtures\h2_compress_test\h2_compress_test.vcxproj", "{C7E516E9-B80F-4BC1-A617-095FC6E14BC9}"
-	ProjectSection(myProperties) = preProject
-        	lib = "False"
-	EndProjectSection
-	ProjectSection(ProjectDependencies) = postProject
-		{1F1F9084-2A93-B80E-364F-5754894AFAB4} = {1F1F9084-2A93-B80E-364F-5754894AFAB4}
-		{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B} = {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}
-		{29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9}
-		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
-		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
-	EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "h2_fakesec_test", "vcxproj\test/end2end/fixtures\h2_fakesec_test\h2_fakesec_test.vcxproj", "{0E980562-3AA0-91B1-C590-85C9A899BE44}"
-	ProjectSection(myProperties) = preProject
-        	lib = "False"
-	EndProjectSection
-	ProjectSection(ProjectDependencies) = postProject
-		{1F1F9084-2A93-B80E-364F-5754894AFAB4} = {1F1F9084-2A93-B80E-364F-5754894AFAB4}
-		{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B} = {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}
-		{29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9}
-		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
-		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
-	EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "h2_full_test", "vcxproj\test/end2end/fixtures\h2_full_test\h2_full_test.vcxproj", "{EEBEFA75-C625-C823-FE96-9AD64887B57D}"
-	ProjectSection(myProperties) = preProject
-        	lib = "False"
-	EndProjectSection
-	ProjectSection(ProjectDependencies) = postProject
-		{1F1F9084-2A93-B80E-364F-5754894AFAB4} = {1F1F9084-2A93-B80E-364F-5754894AFAB4}
-		{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B} = {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}
-		{29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9}
-		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
-		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
-	EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "h2_full+trace_test", "vcxproj\test/end2end/fixtures\h2_full+trace_test\h2_full+trace_test.vcxproj", "{16C713C6-062E-F71F-A44C-52DC35494B27}"
-	ProjectSection(myProperties) = preProject
-        	lib = "False"
-	EndProjectSection
-	ProjectSection(ProjectDependencies) = postProject
-		{1F1F9084-2A93-B80E-364F-5754894AFAB4} = {1F1F9084-2A93-B80E-364F-5754894AFAB4}
-		{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B} = {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}
-		{29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9}
-		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
-		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
-	EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "h2_oauth2_test", "vcxproj\test/end2end/fixtures\h2_oauth2_test\h2_oauth2_test.vcxproj", "{0F761FF3-342A-C429-711F-F76181BAA52D}"
-	ProjectSection(myProperties) = preProject
-        	lib = "False"
-	EndProjectSection
-	ProjectSection(ProjectDependencies) = postProject
-		{1F1F9084-2A93-B80E-364F-5754894AFAB4} = {1F1F9084-2A93-B80E-364F-5754894AFAB4}
-		{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B} = {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}
-		{29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9}
-		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
-		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
-	EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "h2_proxy_test", "vcxproj\test/end2end/fixtures\h2_proxy_test\h2_proxy_test.vcxproj", "{5753B14F-0C69-2E56-6264-5541B2DCDF67}"
-	ProjectSection(myProperties) = preProject
-        	lib = "False"
-	EndProjectSection
-	ProjectSection(ProjectDependencies) = postProject
-		{1F1F9084-2A93-B80E-364F-5754894AFAB4} = {1F1F9084-2A93-B80E-364F-5754894AFAB4}
-		{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B} = {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}
-		{29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9}
-		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
-		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
-	EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "h2_sockpair_test", "vcxproj\test/end2end/fixtures\h2_sockpair_test\h2_sockpair_test.vcxproj", "{67458AF8-A122-7740-F195-C2E74A106FAB}"
-	ProjectSection(myProperties) = preProject
-        	lib = "False"
-	EndProjectSection
-	ProjectSection(ProjectDependencies) = postProject
-		{1F1F9084-2A93-B80E-364F-5754894AFAB4} = {1F1F9084-2A93-B80E-364F-5754894AFAB4}
-		{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B} = {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}
-		{29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9}
-		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
-		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
-	EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "h2_sockpair+trace_test", "vcxproj\test/end2end/fixtures\h2_sockpair+trace_test\h2_sockpair+trace_test.vcxproj", "{82878169-5A89-FD1E-31A6-E9F07BB92418}"
-	ProjectSection(myProperties) = preProject
-        	lib = "False"
-	EndProjectSection
-	ProjectSection(ProjectDependencies) = postProject
-		{1F1F9084-2A93-B80E-364F-5754894AFAB4} = {1F1F9084-2A93-B80E-364F-5754894AFAB4}
-		{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B} = {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}
-		{29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9}
-		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
-		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
-	EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "h2_sockpair_1byte_test", "vcxproj\test/end2end/fixtures\h2_sockpair_1byte_test\h2_sockpair_1byte_test.vcxproj", "{03A65361-E139-5344-1868-8E8FC269C6E6}"
-	ProjectSection(myProperties) = preProject
-        	lib = "False"
-	EndProjectSection
-	ProjectSection(ProjectDependencies) = postProject
-		{1F1F9084-2A93-B80E-364F-5754894AFAB4} = {1F1F9084-2A93-B80E-364F-5754894AFAB4}
-		{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B} = {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}
-		{29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9}
-		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
-		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
-	EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "h2_ssl_test", "vcxproj\test/end2end/fixtures\h2_ssl_test\h2_ssl_test.vcxproj", "{EA78D290-4098-FF04-C647-013F6B81E4E7}"
-	ProjectSection(myProperties) = preProject
-        	lib = "False"
-	EndProjectSection
-	ProjectSection(ProjectDependencies) = postProject
-		{1F1F9084-2A93-B80E-364F-5754894AFAB4} = {1F1F9084-2A93-B80E-364F-5754894AFAB4}
-		{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B} = {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}
-		{29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9}
-		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
-		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
-	EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "h2_ssl_cert_test", "vcxproj\test/end2end/fixtures\h2_ssl_cert_test\h2_ssl_cert_test.vcxproj", "{B3B7D225-3C04-72F9-4C2C-1C3F3136FE58}"
-	ProjectSection(myProperties) = preProject
-        	lib = "False"
-	EndProjectSection
-	ProjectSection(ProjectDependencies) = postProject
-		{1F1F9084-2A93-B80E-364F-5754894AFAB4} = {1F1F9084-2A93-B80E-364F-5754894AFAB4}
-		{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B} = {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}
-		{29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9}
-		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
-		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
-	EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "h2_ssl_proxy_test", "vcxproj\test/end2end/fixtures\h2_ssl_proxy_test\h2_ssl_proxy_test.vcxproj", "{A9092608-E45E-AC96-6533-A6E7DD98211D}"
-	ProjectSection(myProperties) = preProject
-        	lib = "False"
-	EndProjectSection
-	ProjectSection(ProjectDependencies) = postProject
-		{1F1F9084-2A93-B80E-364F-5754894AFAB4} = {1F1F9084-2A93-B80E-364F-5754894AFAB4}
-		{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B} = {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}
-		{29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9}
-		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
-		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
-	EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "h2_census_nosec_test", "vcxproj\test/end2end/fixtures\h2_census_nosec_test\h2_census_nosec_test.vcxproj", "{A8039D43-910E-4248-2A22-74366E8C4DCD}"
-	ProjectSection(myProperties) = preProject
-        	lib = "False"
-	EndProjectSection
-	ProjectSection(ProjectDependencies) = postProject
-		{47C2CB41-4E9F-58B6-F606-F6FAED5D00ED} = {47C2CB41-4E9F-58B6-F606-F6FAED5D00ED}
-		{0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF} = {0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF}
-		{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5} = {46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}
-		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
-		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
-	EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "h2_compress_nosec_test", "vcxproj\test/end2end/fixtures\h2_compress_nosec_test\h2_compress_nosec_test.vcxproj", "{42826C1F-DCF0-918E-D247-0376DC1EFD50}"
-	ProjectSection(myProperties) = preProject
-        	lib = "False"
-	EndProjectSection
-	ProjectSection(ProjectDependencies) = postProject
-		{47C2CB41-4E9F-58B6-F606-F6FAED5D00ED} = {47C2CB41-4E9F-58B6-F606-F6FAED5D00ED}
-		{0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF} = {0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF}
-		{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5} = {46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}
-		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
-		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
-	EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "h2_full_nosec_test", "vcxproj\test/end2end/fixtures\h2_full_nosec_test\h2_full_nosec_test.vcxproj", "{345EA50E-BCD4-DAC7-E1C8-DDA6291B75E2}"
-	ProjectSection(myProperties) = preProject
-        	lib = "False"
-	EndProjectSection
-	ProjectSection(ProjectDependencies) = postProject
-		{47C2CB41-4E9F-58B6-F606-F6FAED5D00ED} = {47C2CB41-4E9F-58B6-F606-F6FAED5D00ED}
-		{0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF} = {0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF}
-		{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5} = {46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}
-		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
-		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
-	EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "h2_full+trace_nosec_test", "vcxproj\test/end2end/fixtures\h2_full+trace_nosec_test\h2_full+trace_nosec_test.vcxproj", "{DFD51943-4906-8051-7D66-6A7D50E0D87E}"
-	ProjectSection(myProperties) = preProject
-        	lib = "False"
-	EndProjectSection
-	ProjectSection(ProjectDependencies) = postProject
-		{47C2CB41-4E9F-58B6-F606-F6FAED5D00ED} = {47C2CB41-4E9F-58B6-F606-F6FAED5D00ED}
-		{0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF} = {0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF}
-		{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5} = {46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}
-		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
-		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
-	EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "h2_proxy_nosec_test", "vcxproj\test/end2end/fixtures\h2_proxy_nosec_test\h2_proxy_nosec_test.vcxproj", "{6EC72045-98CB-8A8D-9788-BC94209E23C8}"
-	ProjectSection(myProperties) = preProject
-        	lib = "False"
-	EndProjectSection
-	ProjectSection(ProjectDependencies) = postProject
-		{47C2CB41-4E9F-58B6-F606-F6FAED5D00ED} = {47C2CB41-4E9F-58B6-F606-F6FAED5D00ED}
-		{0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF} = {0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF}
-		{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5} = {46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}
-		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
-		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
-	EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "h2_sockpair_nosec_test", "vcxproj\test/end2end/fixtures\h2_sockpair_nosec_test\h2_sockpair_nosec_test.vcxproj", "{B3F26242-A43D-4F77-A84C-0F478741A061}"
-	ProjectSection(myProperties) = preProject
-        	lib = "False"
-	EndProjectSection
-	ProjectSection(ProjectDependencies) = postProject
-		{47C2CB41-4E9F-58B6-F606-F6FAED5D00ED} = {47C2CB41-4E9F-58B6-F606-F6FAED5D00ED}
-		{0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF} = {0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF}
-		{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5} = {46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}
-		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
-		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
-	EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "h2_sockpair+trace_nosec_test", "vcxproj\test/end2end/fixtures\h2_sockpair+trace_nosec_test\h2_sockpair+trace_nosec_test.vcxproj", "{962380E0-1C06-8917-8F7F-1A02E0E93BE7}"
-	ProjectSection(myProperties) = preProject
-        	lib = "False"
-	EndProjectSection
-	ProjectSection(ProjectDependencies) = postProject
-		{47C2CB41-4E9F-58B6-F606-F6FAED5D00ED} = {47C2CB41-4E9F-58B6-F606-F6FAED5D00ED}
-		{0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF} = {0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF}
-		{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5} = {46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}
-		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
-		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
-	EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "h2_sockpair_1byte_nosec_test", "vcxproj\test/end2end/fixtures\h2_sockpair_1byte_nosec_test\h2_sockpair_1byte_nosec_test.vcxproj", "{485E6713-487D-F274-BDE7-5D29300C93FE}"
-	ProjectSection(myProperties) = preProject
-        	lib = "False"
-	EndProjectSection
-	ProjectSection(ProjectDependencies) = postProject
-		{47C2CB41-4E9F-58B6-F606-F6FAED5D00ED} = {47C2CB41-4E9F-58B6-F606-F6FAED5D00ED}
-		{0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF} = {0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF}
-		{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5} = {46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}
-		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
-		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
-	EndProjectSection
-EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|Win32 = Debug|Win32
@@ -1419,198 +1422,6 @@
 		Release-DLL|x64 = Release-DLL|x64
 	EndGlobalSection
 	GlobalSection(ProjectConfigurationPlatforms) = postSolution
-		{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
-		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}.Release|x64.ActiveCfg = Release|x64
-		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}.Debug|Win32.Build.0 = Debug|Win32
-		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}.Debug|x64.Build.0 = Debug|x64
-		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}.Release|Win32.Build.0 = Release|Win32
-		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}.Release|x64.Build.0 = Release|x64
-		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
-		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}.Debug-DLL|Win32.Build.0 = Debug|Win32
-		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}.Debug-DLL|x64.ActiveCfg = Debug|x64
-		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}.Debug-DLL|x64.Build.0 = Debug|x64
-		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}.Release-DLL|Win32.ActiveCfg = Release|Win32
-		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}.Release-DLL|Win32.Build.0 = Release|Win32
-		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}.Release-DLL|x64.ActiveCfg = Release|x64
-		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}.Release-DLL|x64.Build.0 = Release|x64
-		{EAB0A629-17A9-44DB-B5FF-E91A721FE037}.Debug|Win32.ActiveCfg = Debug|Win32
-		{EAB0A629-17A9-44DB-B5FF-E91A721FE037}.Debug|x64.ActiveCfg = Debug|x64
-		{EAB0A629-17A9-44DB-B5FF-E91A721FE037}.Release|Win32.ActiveCfg = Release|Win32
-		{EAB0A629-17A9-44DB-B5FF-E91A721FE037}.Release|x64.ActiveCfg = Release|x64
-		{EAB0A629-17A9-44DB-B5FF-E91A721FE037}.Debug|Win32.Build.0 = Debug|Win32
-		{EAB0A629-17A9-44DB-B5FF-E91A721FE037}.Debug|x64.Build.0 = Debug|x64
-		{EAB0A629-17A9-44DB-B5FF-E91A721FE037}.Release|Win32.Build.0 = Release|Win32
-		{EAB0A629-17A9-44DB-B5FF-E91A721FE037}.Release|x64.Build.0 = Release|x64
-		{EAB0A629-17A9-44DB-B5FF-E91A721FE037}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
-		{EAB0A629-17A9-44DB-B5FF-E91A721FE037}.Debug-DLL|Win32.Build.0 = Debug|Win32
-		{EAB0A629-17A9-44DB-B5FF-E91A721FE037}.Debug-DLL|x64.ActiveCfg = Debug|x64
-		{EAB0A629-17A9-44DB-B5FF-E91A721FE037}.Debug-DLL|x64.Build.0 = Debug|x64
-		{EAB0A629-17A9-44DB-B5FF-E91A721FE037}.Release-DLL|Win32.ActiveCfg = Release|Win32
-		{EAB0A629-17A9-44DB-B5FF-E91A721FE037}.Release-DLL|Win32.Build.0 = Release|Win32
-		{EAB0A629-17A9-44DB-B5FF-E91A721FE037}.Release-DLL|x64.ActiveCfg = Release|x64
-		{EAB0A629-17A9-44DB-B5FF-E91A721FE037}.Release-DLL|x64.Build.0 = Release|x64
-		{29D16885-7228-4C31-81ED-5F9187C7F2A9}.Debug|Win32.ActiveCfg = Debug|Win32
-		{29D16885-7228-4C31-81ED-5F9187C7F2A9}.Debug|x64.ActiveCfg = Debug|x64
-		{29D16885-7228-4C31-81ED-5F9187C7F2A9}.Release|Win32.ActiveCfg = Release|Win32
-		{29D16885-7228-4C31-81ED-5F9187C7F2A9}.Release|x64.ActiveCfg = Release|x64
-		{29D16885-7228-4C31-81ED-5F9187C7F2A9}.Debug|Win32.Build.0 = Debug|Win32
-		{29D16885-7228-4C31-81ED-5F9187C7F2A9}.Debug|x64.Build.0 = Debug|x64
-		{29D16885-7228-4C31-81ED-5F9187C7F2A9}.Release|Win32.Build.0 = Release|Win32
-		{29D16885-7228-4C31-81ED-5F9187C7F2A9}.Release|x64.Build.0 = Release|x64
-		{29D16885-7228-4C31-81ED-5F9187C7F2A9}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32
-		{29D16885-7228-4C31-81ED-5F9187C7F2A9}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32
-		{29D16885-7228-4C31-81ED-5F9187C7F2A9}.Debug-DLL|x64.ActiveCfg = Debug-DLL|x64
-		{29D16885-7228-4C31-81ED-5F9187C7F2A9}.Debug-DLL|x64.Build.0 = Debug-DLL|x64
-		{29D16885-7228-4C31-81ED-5F9187C7F2A9}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32
-		{29D16885-7228-4C31-81ED-5F9187C7F2A9}.Release-DLL|Win32.Build.0 = Release-DLL|Win32
-		{29D16885-7228-4C31-81ED-5F9187C7F2A9}.Release-DLL|x64.ActiveCfg = Release-DLL|x64
-		{29D16885-7228-4C31-81ED-5F9187C7F2A9}.Release-DLL|x64.Build.0 = Release-DLL|x64
-		{A2F6CBBA-A553-41B3-A7DE-F26DECCC27F0}.Debug|Win32.ActiveCfg = Debug|Win32
-		{A2F6CBBA-A553-41B3-A7DE-F26DECCC27F0}.Debug|x64.ActiveCfg = Debug|x64
-		{A2F6CBBA-A553-41B3-A7DE-F26DECCC27F0}.Release|Win32.ActiveCfg = Release|Win32
-		{A2F6CBBA-A553-41B3-A7DE-F26DECCC27F0}.Release|x64.ActiveCfg = Release|x64
-		{A2F6CBBA-A553-41B3-A7DE-F26DECCC27F0}.Debug|Win32.Build.0 = Debug|Win32
-		{A2F6CBBA-A553-41B3-A7DE-F26DECCC27F0}.Debug|x64.Build.0 = Debug|x64
-		{A2F6CBBA-A553-41B3-A7DE-F26DECCC27F0}.Release|Win32.Build.0 = Release|Win32
-		{A2F6CBBA-A553-41B3-A7DE-F26DECCC27F0}.Release|x64.Build.0 = Release|x64
-		{A2F6CBBA-A553-41B3-A7DE-F26DECCC27F0}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
-		{A2F6CBBA-A553-41B3-A7DE-F26DECCC27F0}.Debug-DLL|Win32.Build.0 = Debug|Win32
-		{A2F6CBBA-A553-41B3-A7DE-F26DECCC27F0}.Debug-DLL|x64.ActiveCfg = Debug|x64
-		{A2F6CBBA-A553-41B3-A7DE-F26DECCC27F0}.Debug-DLL|x64.Build.0 = Debug|x64
-		{A2F6CBBA-A553-41B3-A7DE-F26DECCC27F0}.Release-DLL|Win32.ActiveCfg = Release|Win32
-		{A2F6CBBA-A553-41B3-A7DE-F26DECCC27F0}.Release-DLL|Win32.Build.0 = Release|Win32
-		{A2F6CBBA-A553-41B3-A7DE-F26DECCC27F0}.Release-DLL|x64.ActiveCfg = Release|x64
-		{A2F6CBBA-A553-41B3-A7DE-F26DECCC27F0}.Release-DLL|x64.Build.0 = Release|x64
-		{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}.Debug|Win32.ActiveCfg = Debug|Win32
-		{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}.Debug|x64.ActiveCfg = Debug|x64
-		{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}.Release|Win32.ActiveCfg = Release|Win32
-		{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}.Release|x64.ActiveCfg = Release|x64
-		{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}.Debug|Win32.Build.0 = Debug|Win32
-		{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}.Debug|x64.Build.0 = Debug|x64
-		{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}.Release|Win32.Build.0 = Release|Win32
-		{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}.Release|x64.Build.0 = Release|x64
-		{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
-		{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}.Debug-DLL|Win32.Build.0 = Debug|Win32
-		{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}.Debug-DLL|x64.ActiveCfg = Debug|x64
-		{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}.Debug-DLL|x64.Build.0 = Debug|x64
-		{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}.Release-DLL|Win32.ActiveCfg = Release|Win32
-		{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}.Release-DLL|Win32.Build.0 = Release|Win32
-		{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}.Release-DLL|x64.ActiveCfg = Release|x64
-		{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}.Release-DLL|x64.Build.0 = Release|x64
-		{0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF}.Debug|Win32.ActiveCfg = Debug|Win32
-		{0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF}.Debug|x64.ActiveCfg = Debug|x64
-		{0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF}.Release|Win32.ActiveCfg = Release|Win32
-		{0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF}.Release|x64.ActiveCfg = Release|x64
-		{0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF}.Debug|Win32.Build.0 = Debug|Win32
-		{0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF}.Debug|x64.Build.0 = Debug|x64
-		{0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF}.Release|Win32.Build.0 = Release|Win32
-		{0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF}.Release|x64.Build.0 = Release|x64
-		{0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
-		{0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF}.Debug-DLL|Win32.Build.0 = Debug|Win32
-		{0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF}.Debug-DLL|x64.ActiveCfg = Debug|x64
-		{0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF}.Debug-DLL|x64.Build.0 = Debug|x64
-		{0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF}.Release-DLL|Win32.ActiveCfg = Release|Win32
-		{0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF}.Release-DLL|Win32.Build.0 = Release|Win32
-		{0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF}.Release-DLL|x64.ActiveCfg = Release|x64
-		{0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF}.Release-DLL|x64.Build.0 = Release|x64
-		{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}.Debug|Win32.ActiveCfg = Debug|Win32
-		{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}.Debug|x64.ActiveCfg = Debug|x64
-		{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}.Release|Win32.ActiveCfg = Release|Win32
-		{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}.Release|x64.ActiveCfg = Release|x64
-		{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}.Debug|Win32.Build.0 = Debug|Win32
-		{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}.Debug|x64.Build.0 = Debug|x64
-		{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}.Release|Win32.Build.0 = Release|Win32
-		{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}.Release|x64.Build.0 = Release|x64
-		{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32
-		{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32
-		{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}.Debug-DLL|x64.ActiveCfg = Debug-DLL|x64
-		{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}.Debug-DLL|x64.Build.0 = Debug-DLL|x64
-		{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32
-		{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}.Release-DLL|Win32.Build.0 = Release-DLL|Win32
-		{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}.Release-DLL|x64.ActiveCfg = Release-DLL|x64
-		{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}.Release-DLL|x64.Build.0 = Release-DLL|x64
-		{929C90AE-483F-AC80-EF93-226199F9E428}.Debug|Win32.ActiveCfg = Debug|Win32
-		{929C90AE-483F-AC80-EF93-226199F9E428}.Debug|x64.ActiveCfg = Debug|x64
-		{929C90AE-483F-AC80-EF93-226199F9E428}.Release|Win32.ActiveCfg = Release|Win32
-		{929C90AE-483F-AC80-EF93-226199F9E428}.Release|x64.ActiveCfg = Release|x64
-		{929C90AE-483F-AC80-EF93-226199F9E428}.Debug|Win32.Build.0 = Debug|Win32
-		{929C90AE-483F-AC80-EF93-226199F9E428}.Debug|x64.Build.0 = Debug|x64
-		{929C90AE-483F-AC80-EF93-226199F9E428}.Release|Win32.Build.0 = Release|Win32
-		{929C90AE-483F-AC80-EF93-226199F9E428}.Release|x64.Build.0 = Release|x64
-		{929C90AE-483F-AC80-EF93-226199F9E428}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
-		{929C90AE-483F-AC80-EF93-226199F9E428}.Debug-DLL|Win32.Build.0 = Debug|Win32
-		{929C90AE-483F-AC80-EF93-226199F9E428}.Debug-DLL|x64.ActiveCfg = Debug|x64
-		{929C90AE-483F-AC80-EF93-226199F9E428}.Debug-DLL|x64.Build.0 = Debug|x64
-		{929C90AE-483F-AC80-EF93-226199F9E428}.Release-DLL|Win32.ActiveCfg = Release|Win32
-		{929C90AE-483F-AC80-EF93-226199F9E428}.Release-DLL|Win32.Build.0 = Release|Win32
-		{929C90AE-483F-AC80-EF93-226199F9E428}.Release-DLL|x64.ActiveCfg = Release|x64
-		{929C90AE-483F-AC80-EF93-226199F9E428}.Release-DLL|x64.Build.0 = Release|x64
-		{E3110C46-A148-FF65-08FD-3324829BE7FE}.Debug|Win32.ActiveCfg = Debug|Win32
-		{E3110C46-A148-FF65-08FD-3324829BE7FE}.Debug|x64.ActiveCfg = Debug|x64
-		{E3110C46-A148-FF65-08FD-3324829BE7FE}.Release|Win32.ActiveCfg = Release|Win32
-		{E3110C46-A148-FF65-08FD-3324829BE7FE}.Release|x64.ActiveCfg = Release|x64
-		{E3110C46-A148-FF65-08FD-3324829BE7FE}.Debug|Win32.Build.0 = Debug|Win32
-		{E3110C46-A148-FF65-08FD-3324829BE7FE}.Debug|x64.Build.0 = Debug|x64
-		{E3110C46-A148-FF65-08FD-3324829BE7FE}.Release|Win32.Build.0 = Release|Win32
-		{E3110C46-A148-FF65-08FD-3324829BE7FE}.Release|x64.Build.0 = Release|x64
-		{E3110C46-A148-FF65-08FD-3324829BE7FE}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
-		{E3110C46-A148-FF65-08FD-3324829BE7FE}.Debug-DLL|Win32.Build.0 = Debug|Win32
-		{E3110C46-A148-FF65-08FD-3324829BE7FE}.Debug-DLL|x64.ActiveCfg = Debug|x64
-		{E3110C46-A148-FF65-08FD-3324829BE7FE}.Debug-DLL|x64.Build.0 = Debug|x64
-		{E3110C46-A148-FF65-08FD-3324829BE7FE}.Release-DLL|Win32.ActiveCfg = Release|Win32
-		{E3110C46-A148-FF65-08FD-3324829BE7FE}.Release-DLL|Win32.Build.0 = Release|Win32
-		{E3110C46-A148-FF65-08FD-3324829BE7FE}.Release-DLL|x64.ActiveCfg = Release|x64
-		{E3110C46-A148-FF65-08FD-3324829BE7FE}.Release-DLL|x64.Build.0 = Release|x64
-		{BA67B418-B699-E41A-9CC4-0279C49481A5}.Debug|Win32.ActiveCfg = Debug|Win32
-		{BA67B418-B699-E41A-9CC4-0279C49481A5}.Debug|x64.ActiveCfg = Debug|x64
-		{BA67B418-B699-E41A-9CC4-0279C49481A5}.Release|Win32.ActiveCfg = Release|Win32
-		{BA67B418-B699-E41A-9CC4-0279C49481A5}.Release|x64.ActiveCfg = Release|x64
-		{BA67B418-B699-E41A-9CC4-0279C49481A5}.Debug|Win32.Build.0 = Debug|Win32
-		{BA67B418-B699-E41A-9CC4-0279C49481A5}.Debug|x64.Build.0 = Debug|x64
-		{BA67B418-B699-E41A-9CC4-0279C49481A5}.Release|Win32.Build.0 = Release|Win32
-		{BA67B418-B699-E41A-9CC4-0279C49481A5}.Release|x64.Build.0 = Release|x64
-		{BA67B418-B699-E41A-9CC4-0279C49481A5}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
-		{BA67B418-B699-E41A-9CC4-0279C49481A5}.Debug-DLL|Win32.Build.0 = Debug|Win32
-		{BA67B418-B699-E41A-9CC4-0279C49481A5}.Debug-DLL|x64.ActiveCfg = Debug|x64
-		{BA67B418-B699-E41A-9CC4-0279C49481A5}.Debug-DLL|x64.Build.0 = Debug|x64
-		{BA67B418-B699-E41A-9CC4-0279C49481A5}.Release-DLL|Win32.ActiveCfg = Release|Win32
-		{BA67B418-B699-E41A-9CC4-0279C49481A5}.Release-DLL|Win32.Build.0 = Release|Win32
-		{BA67B418-B699-E41A-9CC4-0279C49481A5}.Release-DLL|x64.ActiveCfg = Release|x64
-		{BA67B418-B699-E41A-9CC4-0279C49481A5}.Release-DLL|x64.Build.0 = Release|x64
-		{1F1F9084-2A93-B80E-364F-5754894AFAB4}.Debug|Win32.ActiveCfg = Debug|Win32
-		{1F1F9084-2A93-B80E-364F-5754894AFAB4}.Debug|x64.ActiveCfg = Debug|x64
-		{1F1F9084-2A93-B80E-364F-5754894AFAB4}.Release|Win32.ActiveCfg = Release|Win32
-		{1F1F9084-2A93-B80E-364F-5754894AFAB4}.Release|x64.ActiveCfg = Release|x64
-		{1F1F9084-2A93-B80E-364F-5754894AFAB4}.Debug|Win32.Build.0 = Debug|Win32
-		{1F1F9084-2A93-B80E-364F-5754894AFAB4}.Debug|x64.Build.0 = Debug|x64
-		{1F1F9084-2A93-B80E-364F-5754894AFAB4}.Release|Win32.Build.0 = Release|Win32
-		{1F1F9084-2A93-B80E-364F-5754894AFAB4}.Release|x64.Build.0 = Release|x64
-		{1F1F9084-2A93-B80E-364F-5754894AFAB4}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
-		{1F1F9084-2A93-B80E-364F-5754894AFAB4}.Debug-DLL|Win32.Build.0 = Debug|Win32
-		{1F1F9084-2A93-B80E-364F-5754894AFAB4}.Debug-DLL|x64.ActiveCfg = Debug|x64
-		{1F1F9084-2A93-B80E-364F-5754894AFAB4}.Debug-DLL|x64.Build.0 = Debug|x64
-		{1F1F9084-2A93-B80E-364F-5754894AFAB4}.Release-DLL|Win32.ActiveCfg = Release|Win32
-		{1F1F9084-2A93-B80E-364F-5754894AFAB4}.Release-DLL|Win32.Build.0 = Release|Win32
-		{1F1F9084-2A93-B80E-364F-5754894AFAB4}.Release-DLL|x64.ActiveCfg = Release|x64
-		{1F1F9084-2A93-B80E-364F-5754894AFAB4}.Release-DLL|x64.Build.0 = Release|x64
-		{47C2CB41-4E9F-58B6-F606-F6FAED5D00ED}.Debug|Win32.ActiveCfg = Debug|Win32
-		{47C2CB41-4E9F-58B6-F606-F6FAED5D00ED}.Debug|x64.ActiveCfg = Debug|x64
-		{47C2CB41-4E9F-58B6-F606-F6FAED5D00ED}.Release|Win32.ActiveCfg = Release|Win32
-		{47C2CB41-4E9F-58B6-F606-F6FAED5D00ED}.Release|x64.ActiveCfg = Release|x64
-		{47C2CB41-4E9F-58B6-F606-F6FAED5D00ED}.Debug|Win32.Build.0 = Debug|Win32
-		{47C2CB41-4E9F-58B6-F606-F6FAED5D00ED}.Debug|x64.Build.0 = Debug|x64
-		{47C2CB41-4E9F-58B6-F606-F6FAED5D00ED}.Release|Win32.Build.0 = Release|Win32
-		{47C2CB41-4E9F-58B6-F606-F6FAED5D00ED}.Release|x64.Build.0 = Release|x64
-		{47C2CB41-4E9F-58B6-F606-F6FAED5D00ED}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
-		{47C2CB41-4E9F-58B6-F606-F6FAED5D00ED}.Debug-DLL|Win32.Build.0 = Debug|Win32
-		{47C2CB41-4E9F-58B6-F606-F6FAED5D00ED}.Debug-DLL|x64.ActiveCfg = Debug|x64
-		{47C2CB41-4E9F-58B6-F606-F6FAED5D00ED}.Debug-DLL|x64.Build.0 = Debug|x64
-		{47C2CB41-4E9F-58B6-F606-F6FAED5D00ED}.Release-DLL|Win32.ActiveCfg = Release|Win32
-		{47C2CB41-4E9F-58B6-F606-F6FAED5D00ED}.Release-DLL|Win32.Build.0 = Release|Win32
-		{47C2CB41-4E9F-58B6-F606-F6FAED5D00ED}.Release-DLL|x64.ActiveCfg = Release|x64
-		{47C2CB41-4E9F-58B6-F606-F6FAED5D00ED}.Release-DLL|x64.Build.0 = Release|x64
 		{AFD362D7-0E2A-E700-1F27-9D90F76166DF}.Debug|Win32.ActiveCfg = Debug|Win32
 		{AFD362D7-0E2A-E700-1F27-9D90F76166DF}.Debug|x64.ActiveCfg = Debug|x64
 		{AFD362D7-0E2A-E700-1F27-9D90F76166DF}.Release|Win32.ActiveCfg = Release|Win32
@@ -1675,6 +1486,38 @@
 		{5BAAE7EA-A972-DD80-F190-29B9E3110BB3}.Release-DLL|Win32.Build.0 = Release|Win32
 		{5BAAE7EA-A972-DD80-F190-29B9E3110BB3}.Release-DLL|x64.ActiveCfg = Release|x64
 		{5BAAE7EA-A972-DD80-F190-29B9E3110BB3}.Release-DLL|x64.Build.0 = Release|x64
+		{BA67B418-B699-E41A-9CC4-0279C49481A5}.Debug|Win32.ActiveCfg = Debug|Win32
+		{BA67B418-B699-E41A-9CC4-0279C49481A5}.Debug|x64.ActiveCfg = Debug|x64
+		{BA67B418-B699-E41A-9CC4-0279C49481A5}.Release|Win32.ActiveCfg = Release|Win32
+		{BA67B418-B699-E41A-9CC4-0279C49481A5}.Release|x64.ActiveCfg = Release|x64
+		{BA67B418-B699-E41A-9CC4-0279C49481A5}.Debug|Win32.Build.0 = Debug|Win32
+		{BA67B418-B699-E41A-9CC4-0279C49481A5}.Debug|x64.Build.0 = Debug|x64
+		{BA67B418-B699-E41A-9CC4-0279C49481A5}.Release|Win32.Build.0 = Release|Win32
+		{BA67B418-B699-E41A-9CC4-0279C49481A5}.Release|x64.Build.0 = Release|x64
+		{BA67B418-B699-E41A-9CC4-0279C49481A5}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
+		{BA67B418-B699-E41A-9CC4-0279C49481A5}.Debug-DLL|Win32.Build.0 = Debug|Win32
+		{BA67B418-B699-E41A-9CC4-0279C49481A5}.Debug-DLL|x64.ActiveCfg = Debug|x64
+		{BA67B418-B699-E41A-9CC4-0279C49481A5}.Debug-DLL|x64.Build.0 = Debug|x64
+		{BA67B418-B699-E41A-9CC4-0279C49481A5}.Release-DLL|Win32.ActiveCfg = Release|Win32
+		{BA67B418-B699-E41A-9CC4-0279C49481A5}.Release-DLL|Win32.Build.0 = Release|Win32
+		{BA67B418-B699-E41A-9CC4-0279C49481A5}.Release-DLL|x64.ActiveCfg = Release|x64
+		{BA67B418-B699-E41A-9CC4-0279C49481A5}.Release-DLL|x64.Build.0 = Release|x64
+		{8A811C28-E04E-A444-E4C1-7588DF5B90AE}.Debug|Win32.ActiveCfg = Debug|Win32
+		{8A811C28-E04E-A444-E4C1-7588DF5B90AE}.Debug|x64.ActiveCfg = Debug|x64
+		{8A811C28-E04E-A444-E4C1-7588DF5B90AE}.Release|Win32.ActiveCfg = Release|Win32
+		{8A811C28-E04E-A444-E4C1-7588DF5B90AE}.Release|x64.ActiveCfg = Release|x64
+		{8A811C28-E04E-A444-E4C1-7588DF5B90AE}.Debug|Win32.Build.0 = Debug|Win32
+		{8A811C28-E04E-A444-E4C1-7588DF5B90AE}.Debug|x64.Build.0 = Debug|x64
+		{8A811C28-E04E-A444-E4C1-7588DF5B90AE}.Release|Win32.Build.0 = Release|Win32
+		{8A811C28-E04E-A444-E4C1-7588DF5B90AE}.Release|x64.Build.0 = Release|x64
+		{8A811C28-E04E-A444-E4C1-7588DF5B90AE}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
+		{8A811C28-E04E-A444-E4C1-7588DF5B90AE}.Debug-DLL|Win32.Build.0 = Debug|Win32
+		{8A811C28-E04E-A444-E4C1-7588DF5B90AE}.Debug-DLL|x64.ActiveCfg = Debug|x64
+		{8A811C28-E04E-A444-E4C1-7588DF5B90AE}.Debug-DLL|x64.Build.0 = Debug|x64
+		{8A811C28-E04E-A444-E4C1-7588DF5B90AE}.Release-DLL|Win32.ActiveCfg = Release|Win32
+		{8A811C28-E04E-A444-E4C1-7588DF5B90AE}.Release-DLL|Win32.Build.0 = Release|Win32
+		{8A811C28-E04E-A444-E4C1-7588DF5B90AE}.Release-DLL|x64.ActiveCfg = Release|x64
+		{8A811C28-E04E-A444-E4C1-7588DF5B90AE}.Release-DLL|x64.Build.0 = Release|x64
 		{D5C70922-D68E-0E9D-9988-995E0F9A79AE}.Debug|Win32.ActiveCfg = Debug|Win32
 		{D5C70922-D68E-0E9D-9988-995E0F9A79AE}.Debug|x64.ActiveCfg = Debug|x64
 		{D5C70922-D68E-0E9D-9988-995E0F9A79AE}.Release|Win32.ActiveCfg = Release|Win32
@@ -1819,6 +1662,22 @@
 		{391B366C-D916-45AA-3FE5-67363A46193B}.Release-DLL|Win32.Build.0 = Release|Win32
 		{391B366C-D916-45AA-3FE5-67363A46193B}.Release-DLL|x64.ActiveCfg = Release|x64
 		{391B366C-D916-45AA-3FE5-67363A46193B}.Release-DLL|x64.Build.0 = Release|x64
+		{AF9D0EB2-2A53-B815-3A63-E82C7F91DB29}.Debug|Win32.ActiveCfg = Debug|Win32
+		{AF9D0EB2-2A53-B815-3A63-E82C7F91DB29}.Debug|x64.ActiveCfg = Debug|x64
+		{AF9D0EB2-2A53-B815-3A63-E82C7F91DB29}.Release|Win32.ActiveCfg = Release|Win32
+		{AF9D0EB2-2A53-B815-3A63-E82C7F91DB29}.Release|x64.ActiveCfg = Release|x64
+		{AF9D0EB2-2A53-B815-3A63-E82C7F91DB29}.Debug|Win32.Build.0 = Debug|Win32
+		{AF9D0EB2-2A53-B815-3A63-E82C7F91DB29}.Debug|x64.Build.0 = Debug|x64
+		{AF9D0EB2-2A53-B815-3A63-E82C7F91DB29}.Release|Win32.Build.0 = Release|Win32
+		{AF9D0EB2-2A53-B815-3A63-E82C7F91DB29}.Release|x64.Build.0 = Release|x64
+		{AF9D0EB2-2A53-B815-3A63-E82C7F91DB29}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
+		{AF9D0EB2-2A53-B815-3A63-E82C7F91DB29}.Debug-DLL|Win32.Build.0 = Debug|Win32
+		{AF9D0EB2-2A53-B815-3A63-E82C7F91DB29}.Debug-DLL|x64.ActiveCfg = Debug|x64
+		{AF9D0EB2-2A53-B815-3A63-E82C7F91DB29}.Debug-DLL|x64.Build.0 = Debug|x64
+		{AF9D0EB2-2A53-B815-3A63-E82C7F91DB29}.Release-DLL|Win32.ActiveCfg = Release|Win32
+		{AF9D0EB2-2A53-B815-3A63-E82C7F91DB29}.Release-DLL|Win32.Build.0 = Release|Win32
+		{AF9D0EB2-2A53-B815-3A63-E82C7F91DB29}.Release-DLL|x64.ActiveCfg = Release|x64
+		{AF9D0EB2-2A53-B815-3A63-E82C7F91DB29}.Release-DLL|x64.Build.0 = Release|x64
 		{F7B6FE68-E847-D7CA-4062-E737E542BCC3}.Debug|Win32.ActiveCfg = Debug|Win32
 		{F7B6FE68-E847-D7CA-4062-E737E542BCC3}.Debug|x64.ActiveCfg = Debug|x64
 		{F7B6FE68-E847-D7CA-4062-E737E542BCC3}.Release|Win32.ActiveCfg = Release|Win32
@@ -1851,6 +1710,38 @@
 		{D06E10DC-272A-5203-7066-2698A247DF26}.Release-DLL|Win32.Build.0 = Release|Win32
 		{D06E10DC-272A-5203-7066-2698A247DF26}.Release-DLL|x64.ActiveCfg = Release|x64
 		{D06E10DC-272A-5203-7066-2698A247DF26}.Release-DLL|x64.Build.0 = Release|x64
+		{47C2CB41-4E9F-58B6-F606-F6FAED5D00ED}.Debug|Win32.ActiveCfg = Debug|Win32
+		{47C2CB41-4E9F-58B6-F606-F6FAED5D00ED}.Debug|x64.ActiveCfg = Debug|x64
+		{47C2CB41-4E9F-58B6-F606-F6FAED5D00ED}.Release|Win32.ActiveCfg = Release|Win32
+		{47C2CB41-4E9F-58B6-F606-F6FAED5D00ED}.Release|x64.ActiveCfg = Release|x64
+		{47C2CB41-4E9F-58B6-F606-F6FAED5D00ED}.Debug|Win32.Build.0 = Debug|Win32
+		{47C2CB41-4E9F-58B6-F606-F6FAED5D00ED}.Debug|x64.Build.0 = Debug|x64
+		{47C2CB41-4E9F-58B6-F606-F6FAED5D00ED}.Release|Win32.Build.0 = Release|Win32
+		{47C2CB41-4E9F-58B6-F606-F6FAED5D00ED}.Release|x64.Build.0 = Release|x64
+		{47C2CB41-4E9F-58B6-F606-F6FAED5D00ED}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
+		{47C2CB41-4E9F-58B6-F606-F6FAED5D00ED}.Debug-DLL|Win32.Build.0 = Debug|Win32
+		{47C2CB41-4E9F-58B6-F606-F6FAED5D00ED}.Debug-DLL|x64.ActiveCfg = Debug|x64
+		{47C2CB41-4E9F-58B6-F606-F6FAED5D00ED}.Debug-DLL|x64.Build.0 = Debug|x64
+		{47C2CB41-4E9F-58B6-F606-F6FAED5D00ED}.Release-DLL|Win32.ActiveCfg = Release|Win32
+		{47C2CB41-4E9F-58B6-F606-F6FAED5D00ED}.Release-DLL|Win32.Build.0 = Release|Win32
+		{47C2CB41-4E9F-58B6-F606-F6FAED5D00ED}.Release-DLL|x64.ActiveCfg = Release|x64
+		{47C2CB41-4E9F-58B6-F606-F6FAED5D00ED}.Release-DLL|x64.Build.0 = Release|x64
+		{1F1F9084-2A93-B80E-364F-5754894AFAB4}.Debug|Win32.ActiveCfg = Debug|Win32
+		{1F1F9084-2A93-B80E-364F-5754894AFAB4}.Debug|x64.ActiveCfg = Debug|x64
+		{1F1F9084-2A93-B80E-364F-5754894AFAB4}.Release|Win32.ActiveCfg = Release|Win32
+		{1F1F9084-2A93-B80E-364F-5754894AFAB4}.Release|x64.ActiveCfg = Release|x64
+		{1F1F9084-2A93-B80E-364F-5754894AFAB4}.Debug|Win32.Build.0 = Debug|Win32
+		{1F1F9084-2A93-B80E-364F-5754894AFAB4}.Debug|x64.Build.0 = Debug|x64
+		{1F1F9084-2A93-B80E-364F-5754894AFAB4}.Release|Win32.Build.0 = Release|Win32
+		{1F1F9084-2A93-B80E-364F-5754894AFAB4}.Release|x64.Build.0 = Release|x64
+		{1F1F9084-2A93-B80E-364F-5754894AFAB4}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
+		{1F1F9084-2A93-B80E-364F-5754894AFAB4}.Debug-DLL|Win32.Build.0 = Debug|Win32
+		{1F1F9084-2A93-B80E-364F-5754894AFAB4}.Debug-DLL|x64.ActiveCfg = Debug|x64
+		{1F1F9084-2A93-B80E-364F-5754894AFAB4}.Debug-DLL|x64.Build.0 = Debug|x64
+		{1F1F9084-2A93-B80E-364F-5754894AFAB4}.Release-DLL|Win32.ActiveCfg = Release|Win32
+		{1F1F9084-2A93-B80E-364F-5754894AFAB4}.Release-DLL|Win32.Build.0 = Release|Win32
+		{1F1F9084-2A93-B80E-364F-5754894AFAB4}.Release-DLL|x64.ActiveCfg = Release|x64
+		{1F1F9084-2A93-B80E-364F-5754894AFAB4}.Release-DLL|x64.Build.0 = Release|x64
 		{37166D50-3AAA-1156-19F6-5901DFA55172}.Debug|Win32.ActiveCfg = Debug|Win32
 		{37166D50-3AAA-1156-19F6-5901DFA55172}.Debug|x64.ActiveCfg = Debug|x64
 		{37166D50-3AAA-1156-19F6-5901DFA55172}.Release|Win32.ActiveCfg = Release|Win32
@@ -1931,6 +1822,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
+		{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
+		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}.Release|x64.ActiveCfg = Release|x64
+		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}.Debug|Win32.Build.0 = Debug|Win32
+		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}.Debug|x64.Build.0 = Debug|x64
+		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}.Release|Win32.Build.0 = Release|Win32
+		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}.Release|x64.Build.0 = Release|x64
+		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
+		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}.Debug-DLL|Win32.Build.0 = Debug|Win32
+		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}.Debug-DLL|x64.ActiveCfg = Debug|x64
+		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}.Debug-DLL|x64.Build.0 = Debug|x64
+		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}.Release-DLL|Win32.ActiveCfg = Release|Win32
+		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}.Release-DLL|Win32.Build.0 = Release|Win32
+		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}.Release-DLL|x64.ActiveCfg = Release|x64
+		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}.Release-DLL|x64.Build.0 = Release|x64
 		{144D8CFF-2737-A18A-DCFD-01603533D63F}.Debug|Win32.ActiveCfg = Debug|Win32
 		{144D8CFF-2737-A18A-DCFD-01603533D63F}.Debug|x64.ActiveCfg = Debug|x64
 		{144D8CFF-2737-A18A-DCFD-01603533D63F}.Release|Win32.ActiveCfg = Release|Win32
@@ -2155,6 +2062,22 @@
 		{98B2F932-5D6D-9FF0-516F-43FD7E0E4F1A}.Release-DLL|Win32.Build.0 = Release|Win32
 		{98B2F932-5D6D-9FF0-516F-43FD7E0E4F1A}.Release-DLL|x64.ActiveCfg = Release|x64
 		{98B2F932-5D6D-9FF0-516F-43FD7E0E4F1A}.Release-DLL|x64.Build.0 = Release|x64
+		{EAB0A629-17A9-44DB-B5FF-E91A721FE037}.Debug|Win32.ActiveCfg = Debug|Win32
+		{EAB0A629-17A9-44DB-B5FF-E91A721FE037}.Debug|x64.ActiveCfg = Debug|x64
+		{EAB0A629-17A9-44DB-B5FF-E91A721FE037}.Release|Win32.ActiveCfg = Release|Win32
+		{EAB0A629-17A9-44DB-B5FF-E91A721FE037}.Release|x64.ActiveCfg = Release|x64
+		{EAB0A629-17A9-44DB-B5FF-E91A721FE037}.Debug|Win32.Build.0 = Debug|Win32
+		{EAB0A629-17A9-44DB-B5FF-E91A721FE037}.Debug|x64.Build.0 = Debug|x64
+		{EAB0A629-17A9-44DB-B5FF-E91A721FE037}.Release|Win32.Build.0 = Release|Win32
+		{EAB0A629-17A9-44DB-B5FF-E91A721FE037}.Release|x64.Build.0 = Release|x64
+		{EAB0A629-17A9-44DB-B5FF-E91A721FE037}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
+		{EAB0A629-17A9-44DB-B5FF-E91A721FE037}.Debug-DLL|Win32.Build.0 = Debug|Win32
+		{EAB0A629-17A9-44DB-B5FF-E91A721FE037}.Debug-DLL|x64.ActiveCfg = Debug|x64
+		{EAB0A629-17A9-44DB-B5FF-E91A721FE037}.Debug-DLL|x64.Build.0 = Debug|x64
+		{EAB0A629-17A9-44DB-B5FF-E91A721FE037}.Release-DLL|Win32.ActiveCfg = Release|Win32
+		{EAB0A629-17A9-44DB-B5FF-E91A721FE037}.Release-DLL|Win32.Build.0 = Release|Win32
+		{EAB0A629-17A9-44DB-B5FF-E91A721FE037}.Release-DLL|x64.ActiveCfg = Release|x64
+		{EAB0A629-17A9-44DB-B5FF-E91A721FE037}.Release-DLL|x64.Build.0 = Release|x64
 		{459B2FAC-5FC8-1F47-8053-66D46EA39A49}.Debug|Win32.ActiveCfg = Debug|Win32
 		{459B2FAC-5FC8-1F47-8053-66D46EA39A49}.Debug|x64.ActiveCfg = Debug|x64
 		{459B2FAC-5FC8-1F47-8053-66D46EA39A49}.Release|Win32.ActiveCfg = Release|Win32
@@ -2219,6 +2142,22 @@
 		{40B790A8-BB01-9F12-5309-C0BEA97C75BC}.Release-DLL|Win32.Build.0 = Release|Win32
 		{40B790A8-BB01-9F12-5309-C0BEA97C75BC}.Release-DLL|x64.ActiveCfg = Release|x64
 		{40B790A8-BB01-9F12-5309-C0BEA97C75BC}.Release-DLL|x64.Build.0 = Release|x64
+		{29D16885-7228-4C31-81ED-5F9187C7F2A9}.Debug|Win32.ActiveCfg = Debug|Win32
+		{29D16885-7228-4C31-81ED-5F9187C7F2A9}.Debug|x64.ActiveCfg = Debug|x64
+		{29D16885-7228-4C31-81ED-5F9187C7F2A9}.Release|Win32.ActiveCfg = Release|Win32
+		{29D16885-7228-4C31-81ED-5F9187C7F2A9}.Release|x64.ActiveCfg = Release|x64
+		{29D16885-7228-4C31-81ED-5F9187C7F2A9}.Debug|Win32.Build.0 = Debug|Win32
+		{29D16885-7228-4C31-81ED-5F9187C7F2A9}.Debug|x64.Build.0 = Debug|x64
+		{29D16885-7228-4C31-81ED-5F9187C7F2A9}.Release|Win32.Build.0 = Release|Win32
+		{29D16885-7228-4C31-81ED-5F9187C7F2A9}.Release|x64.Build.0 = Release|x64
+		{29D16885-7228-4C31-81ED-5F9187C7F2A9}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32
+		{29D16885-7228-4C31-81ED-5F9187C7F2A9}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32
+		{29D16885-7228-4C31-81ED-5F9187C7F2A9}.Debug-DLL|x64.ActiveCfg = Debug-DLL|x64
+		{29D16885-7228-4C31-81ED-5F9187C7F2A9}.Debug-DLL|x64.Build.0 = Debug-DLL|x64
+		{29D16885-7228-4C31-81ED-5F9187C7F2A9}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32
+		{29D16885-7228-4C31-81ED-5F9187C7F2A9}.Release-DLL|Win32.Build.0 = Release-DLL|Win32
+		{29D16885-7228-4C31-81ED-5F9187C7F2A9}.Release-DLL|x64.ActiveCfg = Release-DLL|x64
+		{29D16885-7228-4C31-81ED-5F9187C7F2A9}.Release-DLL|x64.Build.0 = Release-DLL|x64
 		{C65A4336-92D6-D6A0-EB86-E3AA425222D0}.Debug|Win32.ActiveCfg = Debug|Win32
 		{C65A4336-92D6-D6A0-EB86-E3AA425222D0}.Debug|x64.ActiveCfg = Debug|x64
 		{C65A4336-92D6-D6A0-EB86-E3AA425222D0}.Release|Win32.ActiveCfg = Release|Win32
@@ -2427,6 +2366,54 @@
 		{74DCFC52-3C79-66BC-3DB0-B6A90D81BB68}.Release-DLL|Win32.Build.0 = Release|Win32
 		{74DCFC52-3C79-66BC-3DB0-B6A90D81BB68}.Release-DLL|x64.ActiveCfg = Release|x64
 		{74DCFC52-3C79-66BC-3DB0-B6A90D81BB68}.Release-DLL|x64.Build.0 = Release|x64
+		{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}.Debug|Win32.ActiveCfg = Debug|Win32
+		{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}.Debug|x64.ActiveCfg = Debug|x64
+		{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}.Release|Win32.ActiveCfg = Release|Win32
+		{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}.Release|x64.ActiveCfg = Release|x64
+		{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}.Debug|Win32.Build.0 = Debug|Win32
+		{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}.Debug|x64.Build.0 = Debug|x64
+		{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}.Release|Win32.Build.0 = Release|Win32
+		{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}.Release|x64.Build.0 = Release|x64
+		{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
+		{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}.Debug-DLL|Win32.Build.0 = Debug|Win32
+		{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}.Debug-DLL|x64.ActiveCfg = Debug|x64
+		{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}.Debug-DLL|x64.Build.0 = Debug|x64
+		{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}.Release-DLL|Win32.ActiveCfg = Release|Win32
+		{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}.Release-DLL|Win32.Build.0 = Release|Win32
+		{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}.Release-DLL|x64.ActiveCfg = Release|x64
+		{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}.Release-DLL|x64.Build.0 = Release|x64
+		{0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF}.Debug|Win32.ActiveCfg = Debug|Win32
+		{0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF}.Debug|x64.ActiveCfg = Debug|x64
+		{0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF}.Release|Win32.ActiveCfg = Release|Win32
+		{0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF}.Release|x64.ActiveCfg = Release|x64
+		{0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF}.Debug|Win32.Build.0 = Debug|Win32
+		{0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF}.Debug|x64.Build.0 = Debug|x64
+		{0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF}.Release|Win32.Build.0 = Release|Win32
+		{0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF}.Release|x64.Build.0 = Release|x64
+		{0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
+		{0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF}.Debug-DLL|Win32.Build.0 = Debug|Win32
+		{0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF}.Debug-DLL|x64.ActiveCfg = Debug|x64
+		{0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF}.Debug-DLL|x64.Build.0 = Debug|x64
+		{0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF}.Release-DLL|Win32.ActiveCfg = Release|Win32
+		{0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF}.Release-DLL|Win32.Build.0 = Release|Win32
+		{0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF}.Release-DLL|x64.ActiveCfg = Release|x64
+		{0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF}.Release-DLL|x64.Build.0 = Release|x64
+		{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}.Debug|Win32.ActiveCfg = Debug|Win32
+		{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}.Debug|x64.ActiveCfg = Debug|x64
+		{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}.Release|Win32.ActiveCfg = Release|Win32
+		{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}.Release|x64.ActiveCfg = Release|x64
+		{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}.Debug|Win32.Build.0 = Debug|Win32
+		{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}.Debug|x64.Build.0 = Debug|x64
+		{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}.Release|Win32.Build.0 = Release|Win32
+		{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}.Release|x64.Build.0 = Release|x64
+		{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32
+		{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32
+		{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}.Debug-DLL|x64.ActiveCfg = Debug-DLL|x64
+		{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}.Debug-DLL|x64.Build.0 = Debug-DLL|x64
+		{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32
+		{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}.Release-DLL|Win32.Build.0 = Release-DLL|Win32
+		{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}.Release-DLL|x64.ActiveCfg = Release-DLL|x64
+		{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}.Release-DLL|x64.Build.0 = Release-DLL|x64
 		{02FAC25F-5FF6-34A0-00AE-B82BFBA851A9}.Debug|Win32.ActiveCfg = Debug|Win32
 		{02FAC25F-5FF6-34A0-00AE-B82BFBA851A9}.Debug|x64.ActiveCfg = Debug|x64
 		{02FAC25F-5FF6-34A0-00AE-B82BFBA851A9}.Release|Win32.ActiveCfg = Release|Win32
@@ -2443,6 +2430,406 @@
 		{02FAC25F-5FF6-34A0-00AE-B82BFBA851A9}.Release-DLL|Win32.Build.0 = Release|Win32
 		{02FAC25F-5FF6-34A0-00AE-B82BFBA851A9}.Release-DLL|x64.ActiveCfg = Release|x64
 		{02FAC25F-5FF6-34A0-00AE-B82BFBA851A9}.Release-DLL|x64.Build.0 = Release|x64
+		{A8039D43-910E-4248-2A22-74366E8C4DCD}.Debug|Win32.ActiveCfg = Debug|Win32
+		{A8039D43-910E-4248-2A22-74366E8C4DCD}.Debug|x64.ActiveCfg = Debug|x64
+		{A8039D43-910E-4248-2A22-74366E8C4DCD}.Release|Win32.ActiveCfg = Release|Win32
+		{A8039D43-910E-4248-2A22-74366E8C4DCD}.Release|x64.ActiveCfg = Release|x64
+		{A8039D43-910E-4248-2A22-74366E8C4DCD}.Debug|Win32.Build.0 = Debug|Win32
+		{A8039D43-910E-4248-2A22-74366E8C4DCD}.Debug|x64.Build.0 = Debug|x64
+		{A8039D43-910E-4248-2A22-74366E8C4DCD}.Release|Win32.Build.0 = Release|Win32
+		{A8039D43-910E-4248-2A22-74366E8C4DCD}.Release|x64.Build.0 = Release|x64
+		{A8039D43-910E-4248-2A22-74366E8C4DCD}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
+		{A8039D43-910E-4248-2A22-74366E8C4DCD}.Debug-DLL|Win32.Build.0 = Debug|Win32
+		{A8039D43-910E-4248-2A22-74366E8C4DCD}.Debug-DLL|x64.ActiveCfg = Debug|x64
+		{A8039D43-910E-4248-2A22-74366E8C4DCD}.Debug-DLL|x64.Build.0 = Debug|x64
+		{A8039D43-910E-4248-2A22-74366E8C4DCD}.Release-DLL|Win32.ActiveCfg = Release|Win32
+		{A8039D43-910E-4248-2A22-74366E8C4DCD}.Release-DLL|Win32.Build.0 = Release|Win32
+		{A8039D43-910E-4248-2A22-74366E8C4DCD}.Release-DLL|x64.ActiveCfg = Release|x64
+		{A8039D43-910E-4248-2A22-74366E8C4DCD}.Release-DLL|x64.Build.0 = Release|x64
+		{9E4180B0-81ED-7305-333F-653CE9AB819B}.Debug|Win32.ActiveCfg = Debug|Win32
+		{9E4180B0-81ED-7305-333F-653CE9AB819B}.Debug|x64.ActiveCfg = Debug|x64
+		{9E4180B0-81ED-7305-333F-653CE9AB819B}.Release|Win32.ActiveCfg = Release|Win32
+		{9E4180B0-81ED-7305-333F-653CE9AB819B}.Release|x64.ActiveCfg = Release|x64
+		{9E4180B0-81ED-7305-333F-653CE9AB819B}.Debug|Win32.Build.0 = Debug|Win32
+		{9E4180B0-81ED-7305-333F-653CE9AB819B}.Debug|x64.Build.0 = Debug|x64
+		{9E4180B0-81ED-7305-333F-653CE9AB819B}.Release|Win32.Build.0 = Release|Win32
+		{9E4180B0-81ED-7305-333F-653CE9AB819B}.Release|x64.Build.0 = Release|x64
+		{9E4180B0-81ED-7305-333F-653CE9AB819B}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
+		{9E4180B0-81ED-7305-333F-653CE9AB819B}.Debug-DLL|Win32.Build.0 = Debug|Win32
+		{9E4180B0-81ED-7305-333F-653CE9AB819B}.Debug-DLL|x64.ActiveCfg = Debug|x64
+		{9E4180B0-81ED-7305-333F-653CE9AB819B}.Debug-DLL|x64.Build.0 = Debug|x64
+		{9E4180B0-81ED-7305-333F-653CE9AB819B}.Release-DLL|Win32.ActiveCfg = Release|Win32
+		{9E4180B0-81ED-7305-333F-653CE9AB819B}.Release-DLL|Win32.Build.0 = Release|Win32
+		{9E4180B0-81ED-7305-333F-653CE9AB819B}.Release-DLL|x64.ActiveCfg = Release|x64
+		{9E4180B0-81ED-7305-333F-653CE9AB819B}.Release-DLL|x64.Build.0 = Release|x64
+		{42826C1F-DCF0-918E-D247-0376DC1EFD50}.Debug|Win32.ActiveCfg = Debug|Win32
+		{42826C1F-DCF0-918E-D247-0376DC1EFD50}.Debug|x64.ActiveCfg = Debug|x64
+		{42826C1F-DCF0-918E-D247-0376DC1EFD50}.Release|Win32.ActiveCfg = Release|Win32
+		{42826C1F-DCF0-918E-D247-0376DC1EFD50}.Release|x64.ActiveCfg = Release|x64
+		{42826C1F-DCF0-918E-D247-0376DC1EFD50}.Debug|Win32.Build.0 = Debug|Win32
+		{42826C1F-DCF0-918E-D247-0376DC1EFD50}.Debug|x64.Build.0 = Debug|x64
+		{42826C1F-DCF0-918E-D247-0376DC1EFD50}.Release|Win32.Build.0 = Release|Win32
+		{42826C1F-DCF0-918E-D247-0376DC1EFD50}.Release|x64.Build.0 = Release|x64
+		{42826C1F-DCF0-918E-D247-0376DC1EFD50}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
+		{42826C1F-DCF0-918E-D247-0376DC1EFD50}.Debug-DLL|Win32.Build.0 = Debug|Win32
+		{42826C1F-DCF0-918E-D247-0376DC1EFD50}.Debug-DLL|x64.ActiveCfg = Debug|x64
+		{42826C1F-DCF0-918E-D247-0376DC1EFD50}.Debug-DLL|x64.Build.0 = Debug|x64
+		{42826C1F-DCF0-918E-D247-0376DC1EFD50}.Release-DLL|Win32.ActiveCfg = Release|Win32
+		{42826C1F-DCF0-918E-D247-0376DC1EFD50}.Release-DLL|Win32.Build.0 = Release|Win32
+		{42826C1F-DCF0-918E-D247-0376DC1EFD50}.Release-DLL|x64.ActiveCfg = Release|x64
+		{42826C1F-DCF0-918E-D247-0376DC1EFD50}.Release-DLL|x64.Build.0 = Release|x64
+		{C7E516E9-B80F-4BC1-A617-095FC6E14BC9}.Debug|Win32.ActiveCfg = Debug|Win32
+		{C7E516E9-B80F-4BC1-A617-095FC6E14BC9}.Debug|x64.ActiveCfg = Debug|x64
+		{C7E516E9-B80F-4BC1-A617-095FC6E14BC9}.Release|Win32.ActiveCfg = Release|Win32
+		{C7E516E9-B80F-4BC1-A617-095FC6E14BC9}.Release|x64.ActiveCfg = Release|x64
+		{C7E516E9-B80F-4BC1-A617-095FC6E14BC9}.Debug|Win32.Build.0 = Debug|Win32
+		{C7E516E9-B80F-4BC1-A617-095FC6E14BC9}.Debug|x64.Build.0 = Debug|x64
+		{C7E516E9-B80F-4BC1-A617-095FC6E14BC9}.Release|Win32.Build.0 = Release|Win32
+		{C7E516E9-B80F-4BC1-A617-095FC6E14BC9}.Release|x64.Build.0 = Release|x64
+		{C7E516E9-B80F-4BC1-A617-095FC6E14BC9}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
+		{C7E516E9-B80F-4BC1-A617-095FC6E14BC9}.Debug-DLL|Win32.Build.0 = Debug|Win32
+		{C7E516E9-B80F-4BC1-A617-095FC6E14BC9}.Debug-DLL|x64.ActiveCfg = Debug|x64
+		{C7E516E9-B80F-4BC1-A617-095FC6E14BC9}.Debug-DLL|x64.Build.0 = Debug|x64
+		{C7E516E9-B80F-4BC1-A617-095FC6E14BC9}.Release-DLL|Win32.ActiveCfg = Release|Win32
+		{C7E516E9-B80F-4BC1-A617-095FC6E14BC9}.Release-DLL|Win32.Build.0 = Release|Win32
+		{C7E516E9-B80F-4BC1-A617-095FC6E14BC9}.Release-DLL|x64.ActiveCfg = Release|x64
+		{C7E516E9-B80F-4BC1-A617-095FC6E14BC9}.Release-DLL|x64.Build.0 = Release|x64
+		{0E980562-3AA0-91B1-C590-85C9A899BE44}.Debug|Win32.ActiveCfg = Debug|Win32
+		{0E980562-3AA0-91B1-C590-85C9A899BE44}.Debug|x64.ActiveCfg = Debug|x64
+		{0E980562-3AA0-91B1-C590-85C9A899BE44}.Release|Win32.ActiveCfg = Release|Win32
+		{0E980562-3AA0-91B1-C590-85C9A899BE44}.Release|x64.ActiveCfg = Release|x64
+		{0E980562-3AA0-91B1-C590-85C9A899BE44}.Debug|Win32.Build.0 = Debug|Win32
+		{0E980562-3AA0-91B1-C590-85C9A899BE44}.Debug|x64.Build.0 = Debug|x64
+		{0E980562-3AA0-91B1-C590-85C9A899BE44}.Release|Win32.Build.0 = Release|Win32
+		{0E980562-3AA0-91B1-C590-85C9A899BE44}.Release|x64.Build.0 = Release|x64
+		{0E980562-3AA0-91B1-C590-85C9A899BE44}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
+		{0E980562-3AA0-91B1-C590-85C9A899BE44}.Debug-DLL|Win32.Build.0 = Debug|Win32
+		{0E980562-3AA0-91B1-C590-85C9A899BE44}.Debug-DLL|x64.ActiveCfg = Debug|x64
+		{0E980562-3AA0-91B1-C590-85C9A899BE44}.Debug-DLL|x64.Build.0 = Debug|x64
+		{0E980562-3AA0-91B1-C590-85C9A899BE44}.Release-DLL|Win32.ActiveCfg = Release|Win32
+		{0E980562-3AA0-91B1-C590-85C9A899BE44}.Release-DLL|Win32.Build.0 = Release|Win32
+		{0E980562-3AA0-91B1-C590-85C9A899BE44}.Release-DLL|x64.ActiveCfg = Release|x64
+		{0E980562-3AA0-91B1-C590-85C9A899BE44}.Release-DLL|x64.Build.0 = Release|x64
+		{DFD51943-4906-8051-7D66-6A7D50E0D87E}.Debug|Win32.ActiveCfg = Debug|Win32
+		{DFD51943-4906-8051-7D66-6A7D50E0D87E}.Debug|x64.ActiveCfg = Debug|x64
+		{DFD51943-4906-8051-7D66-6A7D50E0D87E}.Release|Win32.ActiveCfg = Release|Win32
+		{DFD51943-4906-8051-7D66-6A7D50E0D87E}.Release|x64.ActiveCfg = Release|x64
+		{DFD51943-4906-8051-7D66-6A7D50E0D87E}.Debug|Win32.Build.0 = Debug|Win32
+		{DFD51943-4906-8051-7D66-6A7D50E0D87E}.Debug|x64.Build.0 = Debug|x64
+		{DFD51943-4906-8051-7D66-6A7D50E0D87E}.Release|Win32.Build.0 = Release|Win32
+		{DFD51943-4906-8051-7D66-6A7D50E0D87E}.Release|x64.Build.0 = Release|x64
+		{DFD51943-4906-8051-7D66-6A7D50E0D87E}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
+		{DFD51943-4906-8051-7D66-6A7D50E0D87E}.Debug-DLL|Win32.Build.0 = Debug|Win32
+		{DFD51943-4906-8051-7D66-6A7D50E0D87E}.Debug-DLL|x64.ActiveCfg = Debug|x64
+		{DFD51943-4906-8051-7D66-6A7D50E0D87E}.Debug-DLL|x64.Build.0 = Debug|x64
+		{DFD51943-4906-8051-7D66-6A7D50E0D87E}.Release-DLL|Win32.ActiveCfg = Release|Win32
+		{DFD51943-4906-8051-7D66-6A7D50E0D87E}.Release-DLL|Win32.Build.0 = Release|Win32
+		{DFD51943-4906-8051-7D66-6A7D50E0D87E}.Release-DLL|x64.ActiveCfg = Release|x64
+		{DFD51943-4906-8051-7D66-6A7D50E0D87E}.Release-DLL|x64.Build.0 = Release|x64
+		{16C713C6-062E-F71F-A44C-52DC35494B27}.Debug|Win32.ActiveCfg = Debug|Win32
+		{16C713C6-062E-F71F-A44C-52DC35494B27}.Debug|x64.ActiveCfg = Debug|x64
+		{16C713C6-062E-F71F-A44C-52DC35494B27}.Release|Win32.ActiveCfg = Release|Win32
+		{16C713C6-062E-F71F-A44C-52DC35494B27}.Release|x64.ActiveCfg = Release|x64
+		{16C713C6-062E-F71F-A44C-52DC35494B27}.Debug|Win32.Build.0 = Debug|Win32
+		{16C713C6-062E-F71F-A44C-52DC35494B27}.Debug|x64.Build.0 = Debug|x64
+		{16C713C6-062E-F71F-A44C-52DC35494B27}.Release|Win32.Build.0 = Release|Win32
+		{16C713C6-062E-F71F-A44C-52DC35494B27}.Release|x64.Build.0 = Release|x64
+		{16C713C6-062E-F71F-A44C-52DC35494B27}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
+		{16C713C6-062E-F71F-A44C-52DC35494B27}.Debug-DLL|Win32.Build.0 = Debug|Win32
+		{16C713C6-062E-F71F-A44C-52DC35494B27}.Debug-DLL|x64.ActiveCfg = Debug|x64
+		{16C713C6-062E-F71F-A44C-52DC35494B27}.Debug-DLL|x64.Build.0 = Debug|x64
+		{16C713C6-062E-F71F-A44C-52DC35494B27}.Release-DLL|Win32.ActiveCfg = Release|Win32
+		{16C713C6-062E-F71F-A44C-52DC35494B27}.Release-DLL|Win32.Build.0 = Release|Win32
+		{16C713C6-062E-F71F-A44C-52DC35494B27}.Release-DLL|x64.ActiveCfg = Release|x64
+		{16C713C6-062E-F71F-A44C-52DC35494B27}.Release-DLL|x64.Build.0 = Release|x64
+		{345EA50E-BCD4-DAC7-E1C8-DDA6291B75E2}.Debug|Win32.ActiveCfg = Debug|Win32
+		{345EA50E-BCD4-DAC7-E1C8-DDA6291B75E2}.Debug|x64.ActiveCfg = Debug|x64
+		{345EA50E-BCD4-DAC7-E1C8-DDA6291B75E2}.Release|Win32.ActiveCfg = Release|Win32
+		{345EA50E-BCD4-DAC7-E1C8-DDA6291B75E2}.Release|x64.ActiveCfg = Release|x64
+		{345EA50E-BCD4-DAC7-E1C8-DDA6291B75E2}.Debug|Win32.Build.0 = Debug|Win32
+		{345EA50E-BCD4-DAC7-E1C8-DDA6291B75E2}.Debug|x64.Build.0 = Debug|x64
+		{345EA50E-BCD4-DAC7-E1C8-DDA6291B75E2}.Release|Win32.Build.0 = Release|Win32
+		{345EA50E-BCD4-DAC7-E1C8-DDA6291B75E2}.Release|x64.Build.0 = Release|x64
+		{345EA50E-BCD4-DAC7-E1C8-DDA6291B75E2}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
+		{345EA50E-BCD4-DAC7-E1C8-DDA6291B75E2}.Debug-DLL|Win32.Build.0 = Debug|Win32
+		{345EA50E-BCD4-DAC7-E1C8-DDA6291B75E2}.Debug-DLL|x64.ActiveCfg = Debug|x64
+		{345EA50E-BCD4-DAC7-E1C8-DDA6291B75E2}.Debug-DLL|x64.Build.0 = Debug|x64
+		{345EA50E-BCD4-DAC7-E1C8-DDA6291B75E2}.Release-DLL|Win32.ActiveCfg = Release|Win32
+		{345EA50E-BCD4-DAC7-E1C8-DDA6291B75E2}.Release-DLL|Win32.Build.0 = Release|Win32
+		{345EA50E-BCD4-DAC7-E1C8-DDA6291B75E2}.Release-DLL|x64.ActiveCfg = Release|x64
+		{345EA50E-BCD4-DAC7-E1C8-DDA6291B75E2}.Release-DLL|x64.Build.0 = Release|x64
+		{EEBEFA75-C625-C823-FE96-9AD64887B57D}.Debug|Win32.ActiveCfg = Debug|Win32
+		{EEBEFA75-C625-C823-FE96-9AD64887B57D}.Debug|x64.ActiveCfg = Debug|x64
+		{EEBEFA75-C625-C823-FE96-9AD64887B57D}.Release|Win32.ActiveCfg = Release|Win32
+		{EEBEFA75-C625-C823-FE96-9AD64887B57D}.Release|x64.ActiveCfg = Release|x64
+		{EEBEFA75-C625-C823-FE96-9AD64887B57D}.Debug|Win32.Build.0 = Debug|Win32
+		{EEBEFA75-C625-C823-FE96-9AD64887B57D}.Debug|x64.Build.0 = Debug|x64
+		{EEBEFA75-C625-C823-FE96-9AD64887B57D}.Release|Win32.Build.0 = Release|Win32
+		{EEBEFA75-C625-C823-FE96-9AD64887B57D}.Release|x64.Build.0 = Release|x64
+		{EEBEFA75-C625-C823-FE96-9AD64887B57D}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
+		{EEBEFA75-C625-C823-FE96-9AD64887B57D}.Debug-DLL|Win32.Build.0 = Debug|Win32
+		{EEBEFA75-C625-C823-FE96-9AD64887B57D}.Debug-DLL|x64.ActiveCfg = Debug|x64
+		{EEBEFA75-C625-C823-FE96-9AD64887B57D}.Debug-DLL|x64.Build.0 = Debug|x64
+		{EEBEFA75-C625-C823-FE96-9AD64887B57D}.Release-DLL|Win32.ActiveCfg = Release|Win32
+		{EEBEFA75-C625-C823-FE96-9AD64887B57D}.Release-DLL|Win32.Build.0 = Release|Win32
+		{EEBEFA75-C625-C823-FE96-9AD64887B57D}.Release-DLL|x64.ActiveCfg = Release|x64
+		{EEBEFA75-C625-C823-FE96-9AD64887B57D}.Release-DLL|x64.Build.0 = Release|x64
+		{679EA55C-7399-53E8-79F0-82FBDB3DDE07}.Debug|Win32.ActiveCfg = Debug|Win32
+		{679EA55C-7399-53E8-79F0-82FBDB3DDE07}.Debug|x64.ActiveCfg = Debug|x64
+		{679EA55C-7399-53E8-79F0-82FBDB3DDE07}.Release|Win32.ActiveCfg = Release|Win32
+		{679EA55C-7399-53E8-79F0-82FBDB3DDE07}.Release|x64.ActiveCfg = Release|x64
+		{679EA55C-7399-53E8-79F0-82FBDB3DDE07}.Debug|Win32.Build.0 = Debug|Win32
+		{679EA55C-7399-53E8-79F0-82FBDB3DDE07}.Debug|x64.Build.0 = Debug|x64
+		{679EA55C-7399-53E8-79F0-82FBDB3DDE07}.Release|Win32.Build.0 = Release|Win32
+		{679EA55C-7399-53E8-79F0-82FBDB3DDE07}.Release|x64.Build.0 = Release|x64
+		{679EA55C-7399-53E8-79F0-82FBDB3DDE07}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
+		{679EA55C-7399-53E8-79F0-82FBDB3DDE07}.Debug-DLL|Win32.Build.0 = Debug|Win32
+		{679EA55C-7399-53E8-79F0-82FBDB3DDE07}.Debug-DLL|x64.ActiveCfg = Debug|x64
+		{679EA55C-7399-53E8-79F0-82FBDB3DDE07}.Debug-DLL|x64.Build.0 = Debug|x64
+		{679EA55C-7399-53E8-79F0-82FBDB3DDE07}.Release-DLL|Win32.ActiveCfg = Release|Win32
+		{679EA55C-7399-53E8-79F0-82FBDB3DDE07}.Release-DLL|Win32.Build.0 = Release|Win32
+		{679EA55C-7399-53E8-79F0-82FBDB3DDE07}.Release-DLL|x64.ActiveCfg = Release|x64
+		{679EA55C-7399-53E8-79F0-82FBDB3DDE07}.Release-DLL|x64.Build.0 = Release|x64
+		{B107130E-EA33-C114-9CB6-78A18C929F64}.Debug|Win32.ActiveCfg = Debug|Win32
+		{B107130E-EA33-C114-9CB6-78A18C929F64}.Debug|x64.ActiveCfg = Debug|x64
+		{B107130E-EA33-C114-9CB6-78A18C929F64}.Release|Win32.ActiveCfg = Release|Win32
+		{B107130E-EA33-C114-9CB6-78A18C929F64}.Release|x64.ActiveCfg = Release|x64
+		{B107130E-EA33-C114-9CB6-78A18C929F64}.Debug|Win32.Build.0 = Debug|Win32
+		{B107130E-EA33-C114-9CB6-78A18C929F64}.Debug|x64.Build.0 = Debug|x64
+		{B107130E-EA33-C114-9CB6-78A18C929F64}.Release|Win32.Build.0 = Release|Win32
+		{B107130E-EA33-C114-9CB6-78A18C929F64}.Release|x64.Build.0 = Release|x64
+		{B107130E-EA33-C114-9CB6-78A18C929F64}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
+		{B107130E-EA33-C114-9CB6-78A18C929F64}.Debug-DLL|Win32.Build.0 = Debug|Win32
+		{B107130E-EA33-C114-9CB6-78A18C929F64}.Debug-DLL|x64.ActiveCfg = Debug|x64
+		{B107130E-EA33-C114-9CB6-78A18C929F64}.Debug-DLL|x64.Build.0 = Debug|x64
+		{B107130E-EA33-C114-9CB6-78A18C929F64}.Release-DLL|Win32.ActiveCfg = Release|Win32
+		{B107130E-EA33-C114-9CB6-78A18C929F64}.Release-DLL|Win32.Build.0 = Release|Win32
+		{B107130E-EA33-C114-9CB6-78A18C929F64}.Release-DLL|x64.ActiveCfg = Release|x64
+		{B107130E-EA33-C114-9CB6-78A18C929F64}.Release-DLL|x64.Build.0 = Release|x64
+		{0F761FF3-342A-C429-711F-F76181BAA52D}.Debug|Win32.ActiveCfg = Debug|Win32
+		{0F761FF3-342A-C429-711F-F76181BAA52D}.Debug|x64.ActiveCfg = Debug|x64
+		{0F761FF3-342A-C429-711F-F76181BAA52D}.Release|Win32.ActiveCfg = Release|Win32
+		{0F761FF3-342A-C429-711F-F76181BAA52D}.Release|x64.ActiveCfg = Release|x64
+		{0F761FF3-342A-C429-711F-F76181BAA52D}.Debug|Win32.Build.0 = Debug|Win32
+		{0F761FF3-342A-C429-711F-F76181BAA52D}.Debug|x64.Build.0 = Debug|x64
+		{0F761FF3-342A-C429-711F-F76181BAA52D}.Release|Win32.Build.0 = Release|Win32
+		{0F761FF3-342A-C429-711F-F76181BAA52D}.Release|x64.Build.0 = Release|x64
+		{0F761FF3-342A-C429-711F-F76181BAA52D}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
+		{0F761FF3-342A-C429-711F-F76181BAA52D}.Debug-DLL|Win32.Build.0 = Debug|Win32
+		{0F761FF3-342A-C429-711F-F76181BAA52D}.Debug-DLL|x64.ActiveCfg = Debug|x64
+		{0F761FF3-342A-C429-711F-F76181BAA52D}.Debug-DLL|x64.Build.0 = Debug|x64
+		{0F761FF3-342A-C429-711F-F76181BAA52D}.Release-DLL|Win32.ActiveCfg = Release|Win32
+		{0F761FF3-342A-C429-711F-F76181BAA52D}.Release-DLL|Win32.Build.0 = Release|Win32
+		{0F761FF3-342A-C429-711F-F76181BAA52D}.Release-DLL|x64.ActiveCfg = Release|x64
+		{0F761FF3-342A-C429-711F-F76181BAA52D}.Release-DLL|x64.Build.0 = Release|x64
+		{6EC72045-98CB-8A8D-9788-BC94209E23C8}.Debug|Win32.ActiveCfg = Debug|Win32
+		{6EC72045-98CB-8A8D-9788-BC94209E23C8}.Debug|x64.ActiveCfg = Debug|x64
+		{6EC72045-98CB-8A8D-9788-BC94209E23C8}.Release|Win32.ActiveCfg = Release|Win32
+		{6EC72045-98CB-8A8D-9788-BC94209E23C8}.Release|x64.ActiveCfg = Release|x64
+		{6EC72045-98CB-8A8D-9788-BC94209E23C8}.Debug|Win32.Build.0 = Debug|Win32
+		{6EC72045-98CB-8A8D-9788-BC94209E23C8}.Debug|x64.Build.0 = Debug|x64
+		{6EC72045-98CB-8A8D-9788-BC94209E23C8}.Release|Win32.Build.0 = Release|Win32
+		{6EC72045-98CB-8A8D-9788-BC94209E23C8}.Release|x64.Build.0 = Release|x64
+		{6EC72045-98CB-8A8D-9788-BC94209E23C8}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
+		{6EC72045-98CB-8A8D-9788-BC94209E23C8}.Debug-DLL|Win32.Build.0 = Debug|Win32
+		{6EC72045-98CB-8A8D-9788-BC94209E23C8}.Debug-DLL|x64.ActiveCfg = Debug|x64
+		{6EC72045-98CB-8A8D-9788-BC94209E23C8}.Debug-DLL|x64.Build.0 = Debug|x64
+		{6EC72045-98CB-8A8D-9788-BC94209E23C8}.Release-DLL|Win32.ActiveCfg = Release|Win32
+		{6EC72045-98CB-8A8D-9788-BC94209E23C8}.Release-DLL|Win32.Build.0 = Release|Win32
+		{6EC72045-98CB-8A8D-9788-BC94209E23C8}.Release-DLL|x64.ActiveCfg = Release|x64
+		{6EC72045-98CB-8A8D-9788-BC94209E23C8}.Release-DLL|x64.Build.0 = Release|x64
+		{5753B14F-0C69-2E56-6264-5541B2DCDF67}.Debug|Win32.ActiveCfg = Debug|Win32
+		{5753B14F-0C69-2E56-6264-5541B2DCDF67}.Debug|x64.ActiveCfg = Debug|x64
+		{5753B14F-0C69-2E56-6264-5541B2DCDF67}.Release|Win32.ActiveCfg = Release|Win32
+		{5753B14F-0C69-2E56-6264-5541B2DCDF67}.Release|x64.ActiveCfg = Release|x64
+		{5753B14F-0C69-2E56-6264-5541B2DCDF67}.Debug|Win32.Build.0 = Debug|Win32
+		{5753B14F-0C69-2E56-6264-5541B2DCDF67}.Debug|x64.Build.0 = Debug|x64
+		{5753B14F-0C69-2E56-6264-5541B2DCDF67}.Release|Win32.Build.0 = Release|Win32
+		{5753B14F-0C69-2E56-6264-5541B2DCDF67}.Release|x64.Build.0 = Release|x64
+		{5753B14F-0C69-2E56-6264-5541B2DCDF67}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
+		{5753B14F-0C69-2E56-6264-5541B2DCDF67}.Debug-DLL|Win32.Build.0 = Debug|Win32
+		{5753B14F-0C69-2E56-6264-5541B2DCDF67}.Debug-DLL|x64.ActiveCfg = Debug|x64
+		{5753B14F-0C69-2E56-6264-5541B2DCDF67}.Debug-DLL|x64.Build.0 = Debug|x64
+		{5753B14F-0C69-2E56-6264-5541B2DCDF67}.Release-DLL|Win32.ActiveCfg = Release|Win32
+		{5753B14F-0C69-2E56-6264-5541B2DCDF67}.Release-DLL|Win32.Build.0 = Release|Win32
+		{5753B14F-0C69-2E56-6264-5541B2DCDF67}.Release-DLL|x64.ActiveCfg = Release|x64
+		{5753B14F-0C69-2E56-6264-5541B2DCDF67}.Release-DLL|x64.Build.0 = Release|x64
+		{962380E0-1C06-8917-8F7F-1A02E0E93BE7}.Debug|Win32.ActiveCfg = Debug|Win32
+		{962380E0-1C06-8917-8F7F-1A02E0E93BE7}.Debug|x64.ActiveCfg = Debug|x64
+		{962380E0-1C06-8917-8F7F-1A02E0E93BE7}.Release|Win32.ActiveCfg = Release|Win32
+		{962380E0-1C06-8917-8F7F-1A02E0E93BE7}.Release|x64.ActiveCfg = Release|x64
+		{962380E0-1C06-8917-8F7F-1A02E0E93BE7}.Debug|Win32.Build.0 = Debug|Win32
+		{962380E0-1C06-8917-8F7F-1A02E0E93BE7}.Debug|x64.Build.0 = Debug|x64
+		{962380E0-1C06-8917-8F7F-1A02E0E93BE7}.Release|Win32.Build.0 = Release|Win32
+		{962380E0-1C06-8917-8F7F-1A02E0E93BE7}.Release|x64.Build.0 = Release|x64
+		{962380E0-1C06-8917-8F7F-1A02E0E93BE7}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
+		{962380E0-1C06-8917-8F7F-1A02E0E93BE7}.Debug-DLL|Win32.Build.0 = Debug|Win32
+		{962380E0-1C06-8917-8F7F-1A02E0E93BE7}.Debug-DLL|x64.ActiveCfg = Debug|x64
+		{962380E0-1C06-8917-8F7F-1A02E0E93BE7}.Debug-DLL|x64.Build.0 = Debug|x64
+		{962380E0-1C06-8917-8F7F-1A02E0E93BE7}.Release-DLL|Win32.ActiveCfg = Release|Win32
+		{962380E0-1C06-8917-8F7F-1A02E0E93BE7}.Release-DLL|Win32.Build.0 = Release|Win32
+		{962380E0-1C06-8917-8F7F-1A02E0E93BE7}.Release-DLL|x64.ActiveCfg = Release|x64
+		{962380E0-1C06-8917-8F7F-1A02E0E93BE7}.Release-DLL|x64.Build.0 = Release|x64
+		{82878169-5A89-FD1E-31A6-E9F07BB92418}.Debug|Win32.ActiveCfg = Debug|Win32
+		{82878169-5A89-FD1E-31A6-E9F07BB92418}.Debug|x64.ActiveCfg = Debug|x64
+		{82878169-5A89-FD1E-31A6-E9F07BB92418}.Release|Win32.ActiveCfg = Release|Win32
+		{82878169-5A89-FD1E-31A6-E9F07BB92418}.Release|x64.ActiveCfg = Release|x64
+		{82878169-5A89-FD1E-31A6-E9F07BB92418}.Debug|Win32.Build.0 = Debug|Win32
+		{82878169-5A89-FD1E-31A6-E9F07BB92418}.Debug|x64.Build.0 = Debug|x64
+		{82878169-5A89-FD1E-31A6-E9F07BB92418}.Release|Win32.Build.0 = Release|Win32
+		{82878169-5A89-FD1E-31A6-E9F07BB92418}.Release|x64.Build.0 = Release|x64
+		{82878169-5A89-FD1E-31A6-E9F07BB92418}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
+		{82878169-5A89-FD1E-31A6-E9F07BB92418}.Debug-DLL|Win32.Build.0 = Debug|Win32
+		{82878169-5A89-FD1E-31A6-E9F07BB92418}.Debug-DLL|x64.ActiveCfg = Debug|x64
+		{82878169-5A89-FD1E-31A6-E9F07BB92418}.Debug-DLL|x64.Build.0 = Debug|x64
+		{82878169-5A89-FD1E-31A6-E9F07BB92418}.Release-DLL|Win32.ActiveCfg = Release|Win32
+		{82878169-5A89-FD1E-31A6-E9F07BB92418}.Release-DLL|Win32.Build.0 = Release|Win32
+		{82878169-5A89-FD1E-31A6-E9F07BB92418}.Release-DLL|x64.ActiveCfg = Release|x64
+		{82878169-5A89-FD1E-31A6-E9F07BB92418}.Release-DLL|x64.Build.0 = Release|x64
+		{485E6713-487D-F274-BDE7-5D29300C93FE}.Debug|Win32.ActiveCfg = Debug|Win32
+		{485E6713-487D-F274-BDE7-5D29300C93FE}.Debug|x64.ActiveCfg = Debug|x64
+		{485E6713-487D-F274-BDE7-5D29300C93FE}.Release|Win32.ActiveCfg = Release|Win32
+		{485E6713-487D-F274-BDE7-5D29300C93FE}.Release|x64.ActiveCfg = Release|x64
+		{485E6713-487D-F274-BDE7-5D29300C93FE}.Debug|Win32.Build.0 = Debug|Win32
+		{485E6713-487D-F274-BDE7-5D29300C93FE}.Debug|x64.Build.0 = Debug|x64
+		{485E6713-487D-F274-BDE7-5D29300C93FE}.Release|Win32.Build.0 = Release|Win32
+		{485E6713-487D-F274-BDE7-5D29300C93FE}.Release|x64.Build.0 = Release|x64
+		{485E6713-487D-F274-BDE7-5D29300C93FE}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
+		{485E6713-487D-F274-BDE7-5D29300C93FE}.Debug-DLL|Win32.Build.0 = Debug|Win32
+		{485E6713-487D-F274-BDE7-5D29300C93FE}.Debug-DLL|x64.ActiveCfg = Debug|x64
+		{485E6713-487D-F274-BDE7-5D29300C93FE}.Debug-DLL|x64.Build.0 = Debug|x64
+		{485E6713-487D-F274-BDE7-5D29300C93FE}.Release-DLL|Win32.ActiveCfg = Release|Win32
+		{485E6713-487D-F274-BDE7-5D29300C93FE}.Release-DLL|Win32.Build.0 = Release|Win32
+		{485E6713-487D-F274-BDE7-5D29300C93FE}.Release-DLL|x64.ActiveCfg = Release|x64
+		{485E6713-487D-F274-BDE7-5D29300C93FE}.Release-DLL|x64.Build.0 = Release|x64
+		{03A65361-E139-5344-1868-8E8FC269C6E6}.Debug|Win32.ActiveCfg = Debug|Win32
+		{03A65361-E139-5344-1868-8E8FC269C6E6}.Debug|x64.ActiveCfg = Debug|x64
+		{03A65361-E139-5344-1868-8E8FC269C6E6}.Release|Win32.ActiveCfg = Release|Win32
+		{03A65361-E139-5344-1868-8E8FC269C6E6}.Release|x64.ActiveCfg = Release|x64
+		{03A65361-E139-5344-1868-8E8FC269C6E6}.Debug|Win32.Build.0 = Debug|Win32
+		{03A65361-E139-5344-1868-8E8FC269C6E6}.Debug|x64.Build.0 = Debug|x64
+		{03A65361-E139-5344-1868-8E8FC269C6E6}.Release|Win32.Build.0 = Release|Win32
+		{03A65361-E139-5344-1868-8E8FC269C6E6}.Release|x64.Build.0 = Release|x64
+		{03A65361-E139-5344-1868-8E8FC269C6E6}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
+		{03A65361-E139-5344-1868-8E8FC269C6E6}.Debug-DLL|Win32.Build.0 = Debug|Win32
+		{03A65361-E139-5344-1868-8E8FC269C6E6}.Debug-DLL|x64.ActiveCfg = Debug|x64
+		{03A65361-E139-5344-1868-8E8FC269C6E6}.Debug-DLL|x64.Build.0 = Debug|x64
+		{03A65361-E139-5344-1868-8E8FC269C6E6}.Release-DLL|Win32.ActiveCfg = Release|Win32
+		{03A65361-E139-5344-1868-8E8FC269C6E6}.Release-DLL|Win32.Build.0 = Release|Win32
+		{03A65361-E139-5344-1868-8E8FC269C6E6}.Release-DLL|x64.ActiveCfg = Release|x64
+		{03A65361-E139-5344-1868-8E8FC269C6E6}.Release-DLL|x64.Build.0 = Release|x64
+		{B3F26242-A43D-4F77-A84C-0F478741A061}.Debug|Win32.ActiveCfg = Debug|Win32
+		{B3F26242-A43D-4F77-A84C-0F478741A061}.Debug|x64.ActiveCfg = Debug|x64
+		{B3F26242-A43D-4F77-A84C-0F478741A061}.Release|Win32.ActiveCfg = Release|Win32
+		{B3F26242-A43D-4F77-A84C-0F478741A061}.Release|x64.ActiveCfg = Release|x64
+		{B3F26242-A43D-4F77-A84C-0F478741A061}.Debug|Win32.Build.0 = Debug|Win32
+		{B3F26242-A43D-4F77-A84C-0F478741A061}.Debug|x64.Build.0 = Debug|x64
+		{B3F26242-A43D-4F77-A84C-0F478741A061}.Release|Win32.Build.0 = Release|Win32
+		{B3F26242-A43D-4F77-A84C-0F478741A061}.Release|x64.Build.0 = Release|x64
+		{B3F26242-A43D-4F77-A84C-0F478741A061}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
+		{B3F26242-A43D-4F77-A84C-0F478741A061}.Debug-DLL|Win32.Build.0 = Debug|Win32
+		{B3F26242-A43D-4F77-A84C-0F478741A061}.Debug-DLL|x64.ActiveCfg = Debug|x64
+		{B3F26242-A43D-4F77-A84C-0F478741A061}.Debug-DLL|x64.Build.0 = Debug|x64
+		{B3F26242-A43D-4F77-A84C-0F478741A061}.Release-DLL|Win32.ActiveCfg = Release|Win32
+		{B3F26242-A43D-4F77-A84C-0F478741A061}.Release-DLL|Win32.Build.0 = Release|Win32
+		{B3F26242-A43D-4F77-A84C-0F478741A061}.Release-DLL|x64.ActiveCfg = Release|x64
+		{B3F26242-A43D-4F77-A84C-0F478741A061}.Release-DLL|x64.Build.0 = Release|x64
+		{67458AF8-A122-7740-F195-C2E74A106FAB}.Debug|Win32.ActiveCfg = Debug|Win32
+		{67458AF8-A122-7740-F195-C2E74A106FAB}.Debug|x64.ActiveCfg = Debug|x64
+		{67458AF8-A122-7740-F195-C2E74A106FAB}.Release|Win32.ActiveCfg = Release|Win32
+		{67458AF8-A122-7740-F195-C2E74A106FAB}.Release|x64.ActiveCfg = Release|x64
+		{67458AF8-A122-7740-F195-C2E74A106FAB}.Debug|Win32.Build.0 = Debug|Win32
+		{67458AF8-A122-7740-F195-C2E74A106FAB}.Debug|x64.Build.0 = Debug|x64
+		{67458AF8-A122-7740-F195-C2E74A106FAB}.Release|Win32.Build.0 = Release|Win32
+		{67458AF8-A122-7740-F195-C2E74A106FAB}.Release|x64.Build.0 = Release|x64
+		{67458AF8-A122-7740-F195-C2E74A106FAB}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
+		{67458AF8-A122-7740-F195-C2E74A106FAB}.Debug-DLL|Win32.Build.0 = Debug|Win32
+		{67458AF8-A122-7740-F195-C2E74A106FAB}.Debug-DLL|x64.ActiveCfg = Debug|x64
+		{67458AF8-A122-7740-F195-C2E74A106FAB}.Debug-DLL|x64.Build.0 = Debug|x64
+		{67458AF8-A122-7740-F195-C2E74A106FAB}.Release-DLL|Win32.ActiveCfg = Release|Win32
+		{67458AF8-A122-7740-F195-C2E74A106FAB}.Release-DLL|Win32.Build.0 = Release|Win32
+		{67458AF8-A122-7740-F195-C2E74A106FAB}.Release-DLL|x64.ActiveCfg = Release|x64
+		{67458AF8-A122-7740-F195-C2E74A106FAB}.Release-DLL|x64.Build.0 = Release|x64
+		{B3B7D225-3C04-72F9-4C2C-1C3F3136FE58}.Debug|Win32.ActiveCfg = Debug|Win32
+		{B3B7D225-3C04-72F9-4C2C-1C3F3136FE58}.Debug|x64.ActiveCfg = Debug|x64
+		{B3B7D225-3C04-72F9-4C2C-1C3F3136FE58}.Release|Win32.ActiveCfg = Release|Win32
+		{B3B7D225-3C04-72F9-4C2C-1C3F3136FE58}.Release|x64.ActiveCfg = Release|x64
+		{B3B7D225-3C04-72F9-4C2C-1C3F3136FE58}.Debug|Win32.Build.0 = Debug|Win32
+		{B3B7D225-3C04-72F9-4C2C-1C3F3136FE58}.Debug|x64.Build.0 = Debug|x64
+		{B3B7D225-3C04-72F9-4C2C-1C3F3136FE58}.Release|Win32.Build.0 = Release|Win32
+		{B3B7D225-3C04-72F9-4C2C-1C3F3136FE58}.Release|x64.Build.0 = Release|x64
+		{B3B7D225-3C04-72F9-4C2C-1C3F3136FE58}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
+		{B3B7D225-3C04-72F9-4C2C-1C3F3136FE58}.Debug-DLL|Win32.Build.0 = Debug|Win32
+		{B3B7D225-3C04-72F9-4C2C-1C3F3136FE58}.Debug-DLL|x64.ActiveCfg = Debug|x64
+		{B3B7D225-3C04-72F9-4C2C-1C3F3136FE58}.Debug-DLL|x64.Build.0 = Debug|x64
+		{B3B7D225-3C04-72F9-4C2C-1C3F3136FE58}.Release-DLL|Win32.ActiveCfg = Release|Win32
+		{B3B7D225-3C04-72F9-4C2C-1C3F3136FE58}.Release-DLL|Win32.Build.0 = Release|Win32
+		{B3B7D225-3C04-72F9-4C2C-1C3F3136FE58}.Release-DLL|x64.ActiveCfg = Release|x64
+		{B3B7D225-3C04-72F9-4C2C-1C3F3136FE58}.Release-DLL|x64.Build.0 = Release|x64
+		{A9092608-E45E-AC96-6533-A6E7DD98211D}.Debug|Win32.ActiveCfg = Debug|Win32
+		{A9092608-E45E-AC96-6533-A6E7DD98211D}.Debug|x64.ActiveCfg = Debug|x64
+		{A9092608-E45E-AC96-6533-A6E7DD98211D}.Release|Win32.ActiveCfg = Release|Win32
+		{A9092608-E45E-AC96-6533-A6E7DD98211D}.Release|x64.ActiveCfg = Release|x64
+		{A9092608-E45E-AC96-6533-A6E7DD98211D}.Debug|Win32.Build.0 = Debug|Win32
+		{A9092608-E45E-AC96-6533-A6E7DD98211D}.Debug|x64.Build.0 = Debug|x64
+		{A9092608-E45E-AC96-6533-A6E7DD98211D}.Release|Win32.Build.0 = Release|Win32
+		{A9092608-E45E-AC96-6533-A6E7DD98211D}.Release|x64.Build.0 = Release|x64
+		{A9092608-E45E-AC96-6533-A6E7DD98211D}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
+		{A9092608-E45E-AC96-6533-A6E7DD98211D}.Debug-DLL|Win32.Build.0 = Debug|Win32
+		{A9092608-E45E-AC96-6533-A6E7DD98211D}.Debug-DLL|x64.ActiveCfg = Debug|x64
+		{A9092608-E45E-AC96-6533-A6E7DD98211D}.Debug-DLL|x64.Build.0 = Debug|x64
+		{A9092608-E45E-AC96-6533-A6E7DD98211D}.Release-DLL|Win32.ActiveCfg = Release|Win32
+		{A9092608-E45E-AC96-6533-A6E7DD98211D}.Release-DLL|Win32.Build.0 = Release|Win32
+		{A9092608-E45E-AC96-6533-A6E7DD98211D}.Release-DLL|x64.ActiveCfg = Release|x64
+		{A9092608-E45E-AC96-6533-A6E7DD98211D}.Release-DLL|x64.Build.0 = Release|x64
+		{EA78D290-4098-FF04-C647-013F6B81E4E7}.Debug|Win32.ActiveCfg = Debug|Win32
+		{EA78D290-4098-FF04-C647-013F6B81E4E7}.Debug|x64.ActiveCfg = Debug|x64
+		{EA78D290-4098-FF04-C647-013F6B81E4E7}.Release|Win32.ActiveCfg = Release|Win32
+		{EA78D290-4098-FF04-C647-013F6B81E4E7}.Release|x64.ActiveCfg = Release|x64
+		{EA78D290-4098-FF04-C647-013F6B81E4E7}.Debug|Win32.Build.0 = Debug|Win32
+		{EA78D290-4098-FF04-C647-013F6B81E4E7}.Debug|x64.Build.0 = Debug|x64
+		{EA78D290-4098-FF04-C647-013F6B81E4E7}.Release|Win32.Build.0 = Release|Win32
+		{EA78D290-4098-FF04-C647-013F6B81E4E7}.Release|x64.Build.0 = Release|x64
+		{EA78D290-4098-FF04-C647-013F6B81E4E7}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
+		{EA78D290-4098-FF04-C647-013F6B81E4E7}.Debug-DLL|Win32.Build.0 = Debug|Win32
+		{EA78D290-4098-FF04-C647-013F6B81E4E7}.Debug-DLL|x64.ActiveCfg = Debug|x64
+		{EA78D290-4098-FF04-C647-013F6B81E4E7}.Debug-DLL|x64.Build.0 = Debug|x64
+		{EA78D290-4098-FF04-C647-013F6B81E4E7}.Release-DLL|Win32.ActiveCfg = Release|Win32
+		{EA78D290-4098-FF04-C647-013F6B81E4E7}.Release-DLL|Win32.Build.0 = Release|Win32
+		{EA78D290-4098-FF04-C647-013F6B81E4E7}.Release-DLL|x64.ActiveCfg = Release|x64
+		{EA78D290-4098-FF04-C647-013F6B81E4E7}.Release-DLL|x64.Build.0 = Release|x64
+		{23DF0572-DBF1-08DA-8EAD-8508354C90A4}.Debug|Win32.ActiveCfg = Debug|Win32
+		{23DF0572-DBF1-08DA-8EAD-8508354C90A4}.Debug|x64.ActiveCfg = Debug|x64
+		{23DF0572-DBF1-08DA-8EAD-8508354C90A4}.Release|Win32.ActiveCfg = Release|Win32
+		{23DF0572-DBF1-08DA-8EAD-8508354C90A4}.Release|x64.ActiveCfg = Release|x64
+		{23DF0572-DBF1-08DA-8EAD-8508354C90A4}.Debug|Win32.Build.0 = Debug|Win32
+		{23DF0572-DBF1-08DA-8EAD-8508354C90A4}.Debug|x64.Build.0 = Debug|x64
+		{23DF0572-DBF1-08DA-8EAD-8508354C90A4}.Release|Win32.Build.0 = Release|Win32
+		{23DF0572-DBF1-08DA-8EAD-8508354C90A4}.Release|x64.Build.0 = Release|x64
+		{23DF0572-DBF1-08DA-8EAD-8508354C90A4}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
+		{23DF0572-DBF1-08DA-8EAD-8508354C90A4}.Debug-DLL|Win32.Build.0 = Debug|Win32
+		{23DF0572-DBF1-08DA-8EAD-8508354C90A4}.Debug-DLL|x64.ActiveCfg = Debug|x64
+		{23DF0572-DBF1-08DA-8EAD-8508354C90A4}.Debug-DLL|x64.Build.0 = Debug|x64
+		{23DF0572-DBF1-08DA-8EAD-8508354C90A4}.Release-DLL|Win32.ActiveCfg = Release|Win32
+		{23DF0572-DBF1-08DA-8EAD-8508354C90A4}.Release-DLL|Win32.Build.0 = Release|Win32
+		{23DF0572-DBF1-08DA-8EAD-8508354C90A4}.Release-DLL|x64.ActiveCfg = Release|x64
+		{23DF0572-DBF1-08DA-8EAD-8508354C90A4}.Release-DLL|x64.Build.0 = Release|x64
+		{7819A11E-607E-F0C0-FC47-C704CF7D818C}.Debug|Win32.ActiveCfg = Debug|Win32
+		{7819A11E-607E-F0C0-FC47-C704CF7D818C}.Debug|x64.ActiveCfg = Debug|x64
+		{7819A11E-607E-F0C0-FC47-C704CF7D818C}.Release|Win32.ActiveCfg = Release|Win32
+		{7819A11E-607E-F0C0-FC47-C704CF7D818C}.Release|x64.ActiveCfg = Release|x64
+		{7819A11E-607E-F0C0-FC47-C704CF7D818C}.Debug|Win32.Build.0 = Debug|Win32
+		{7819A11E-607E-F0C0-FC47-C704CF7D818C}.Debug|x64.Build.0 = Debug|x64
+		{7819A11E-607E-F0C0-FC47-C704CF7D818C}.Release|Win32.Build.0 = Release|Win32
+		{7819A11E-607E-F0C0-FC47-C704CF7D818C}.Release|x64.Build.0 = Release|x64
+		{7819A11E-607E-F0C0-FC47-C704CF7D818C}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
+		{7819A11E-607E-F0C0-FC47-C704CF7D818C}.Debug-DLL|Win32.Build.0 = Debug|Win32
+		{7819A11E-607E-F0C0-FC47-C704CF7D818C}.Debug-DLL|x64.ActiveCfg = Debug|x64
+		{7819A11E-607E-F0C0-FC47-C704CF7D818C}.Debug-DLL|x64.Build.0 = Debug|x64
+		{7819A11E-607E-F0C0-FC47-C704CF7D818C}.Release-DLL|Win32.ActiveCfg = Release|Win32
+		{7819A11E-607E-F0C0-FC47-C704CF7D818C}.Release-DLL|Win32.Build.0 = Release|Win32
+		{7819A11E-607E-F0C0-FC47-C704CF7D818C}.Release-DLL|x64.ActiveCfg = Release|x64
+		{7819A11E-607E-F0C0-FC47-C704CF7D818C}.Release-DLL|x64.Build.0 = Release|x64
 		{4CAEC7C3-5354-D474-FB3D-ABED6AD2E1DA}.Debug|Win32.ActiveCfg = Debug|Win32
 		{4CAEC7C3-5354-D474-FB3D-ABED6AD2E1DA}.Debug|x64.ActiveCfg = Debug|x64
 		{4CAEC7C3-5354-D474-FB3D-ABED6AD2E1DA}.Release|Win32.ActiveCfg = Release|Win32
@@ -2523,6 +2910,22 @@
 		{117CA7AD-C42B-9217-6C95-42A801777BC5}.Release-DLL|Win32.Build.0 = Release|Win32
 		{117CA7AD-C42B-9217-6C95-42A801777BC5}.Release-DLL|x64.ActiveCfg = Release|x64
 		{117CA7AD-C42B-9217-6C95-42A801777BC5}.Release-DLL|x64.Build.0 = Release|x64
+		{6756895E-05BF-8CC7-58F2-868DF0C0300C}.Debug|Win32.ActiveCfg = Debug|Win32
+		{6756895E-05BF-8CC7-58F2-868DF0C0300C}.Debug|x64.ActiveCfg = Debug|x64
+		{6756895E-05BF-8CC7-58F2-868DF0C0300C}.Release|Win32.ActiveCfg = Release|Win32
+		{6756895E-05BF-8CC7-58F2-868DF0C0300C}.Release|x64.ActiveCfg = Release|x64
+		{6756895E-05BF-8CC7-58F2-868DF0C0300C}.Debug|Win32.Build.0 = Debug|Win32
+		{6756895E-05BF-8CC7-58F2-868DF0C0300C}.Debug|x64.Build.0 = Debug|x64
+		{6756895E-05BF-8CC7-58F2-868DF0C0300C}.Release|Win32.Build.0 = Release|Win32
+		{6756895E-05BF-8CC7-58F2-868DF0C0300C}.Release|x64.Build.0 = Release|x64
+		{6756895E-05BF-8CC7-58F2-868DF0C0300C}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
+		{6756895E-05BF-8CC7-58F2-868DF0C0300C}.Debug-DLL|Win32.Build.0 = Debug|Win32
+		{6756895E-05BF-8CC7-58F2-868DF0C0300C}.Debug-DLL|x64.ActiveCfg = Debug|x64
+		{6756895E-05BF-8CC7-58F2-868DF0C0300C}.Debug-DLL|x64.Build.0 = Debug|x64
+		{6756895E-05BF-8CC7-58F2-868DF0C0300C}.Release-DLL|Win32.ActiveCfg = Release|Win32
+		{6756895E-05BF-8CC7-58F2-868DF0C0300C}.Release-DLL|Win32.Build.0 = Release|Win32
+		{6756895E-05BF-8CC7-58F2-868DF0C0300C}.Release-DLL|x64.ActiveCfg = Release|x64
+		{6756895E-05BF-8CC7-58F2-868DF0C0300C}.Release-DLL|x64.Build.0 = Release|x64
 		{28AE726B-1BFB-202B-48D2-41AF9D09B9EA}.Debug|Win32.ActiveCfg = Debug|Win32
 		{28AE726B-1BFB-202B-48D2-41AF9D09B9EA}.Debug|x64.ActiveCfg = Debug|x64
 		{28AE726B-1BFB-202B-48D2-41AF9D09B9EA}.Release|Win32.ActiveCfg = Release|Win32
@@ -2667,6 +3070,22 @@
 		{6E60B394-E17D-658A-6648-A2E6E183226F}.Release-DLL|Win32.Build.0 = Release|Win32
 		{6E60B394-E17D-658A-6648-A2E6E183226F}.Release-DLL|x64.ActiveCfg = Release|x64
 		{6E60B394-E17D-658A-6648-A2E6E183226F}.Release-DLL|x64.Build.0 = Release|x64
+		{B706A9EC-7982-0DBC-495D-07B165F6CF56}.Debug|Win32.ActiveCfg = Debug|Win32
+		{B706A9EC-7982-0DBC-495D-07B165F6CF56}.Debug|x64.ActiveCfg = Debug|x64
+		{B706A9EC-7982-0DBC-495D-07B165F6CF56}.Release|Win32.ActiveCfg = Release|Win32
+		{B706A9EC-7982-0DBC-495D-07B165F6CF56}.Release|x64.ActiveCfg = Release|x64
+		{B706A9EC-7982-0DBC-495D-07B165F6CF56}.Debug|Win32.Build.0 = Debug|Win32
+		{B706A9EC-7982-0DBC-495D-07B165F6CF56}.Debug|x64.Build.0 = Debug|x64
+		{B706A9EC-7982-0DBC-495D-07B165F6CF56}.Release|Win32.Build.0 = Release|Win32
+		{B706A9EC-7982-0DBC-495D-07B165F6CF56}.Release|x64.Build.0 = Release|x64
+		{B706A9EC-7982-0DBC-495D-07B165F6CF56}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
+		{B706A9EC-7982-0DBC-495D-07B165F6CF56}.Debug-DLL|Win32.Build.0 = Debug|Win32
+		{B706A9EC-7982-0DBC-495D-07B165F6CF56}.Debug-DLL|x64.ActiveCfg = Debug|x64
+		{B706A9EC-7982-0DBC-495D-07B165F6CF56}.Debug-DLL|x64.Build.0 = Debug|x64
+		{B706A9EC-7982-0DBC-495D-07B165F6CF56}.Release-DLL|Win32.ActiveCfg = Release|Win32
+		{B706A9EC-7982-0DBC-495D-07B165F6CF56}.Release-DLL|Win32.Build.0 = Release|Win32
+		{B706A9EC-7982-0DBC-495D-07B165F6CF56}.Release-DLL|x64.ActiveCfg = Release|x64
+		{B706A9EC-7982-0DBC-495D-07B165F6CF56}.Release-DLL|x64.Build.0 = Release|x64
 		{62D58A08-3B5E-D6A8-ABBB-77995AA0A8C6}.Debug|Win32.ActiveCfg = Debug|Win32
 		{62D58A08-3B5E-D6A8-ABBB-77995AA0A8C6}.Debug|x64.ActiveCfg = Debug|x64
 		{62D58A08-3B5E-D6A8-ABBB-77995AA0A8C6}.Release|Win32.ActiveCfg = Release|Win32
@@ -2827,6 +3246,22 @@
 		{BF9F909B-8266-6AAC-A81B-05F8210AA8CA}.Release-DLL|Win32.Build.0 = Release|Win32
 		{BF9F909B-8266-6AAC-A81B-05F8210AA8CA}.Release-DLL|x64.ActiveCfg = Release|x64
 		{BF9F909B-8266-6AAC-A81B-05F8210AA8CA}.Release-DLL|x64.Build.0 = Release|x64
+		{B4E7CD82-988A-BD3A-29F8-8590D3A8BC28}.Debug|Win32.ActiveCfg = Debug|Win32
+		{B4E7CD82-988A-BD3A-29F8-8590D3A8BC28}.Debug|x64.ActiveCfg = Debug|x64
+		{B4E7CD82-988A-BD3A-29F8-8590D3A8BC28}.Release|Win32.ActiveCfg = Release|Win32
+		{B4E7CD82-988A-BD3A-29F8-8590D3A8BC28}.Release|x64.ActiveCfg = Release|x64
+		{B4E7CD82-988A-BD3A-29F8-8590D3A8BC28}.Debug|Win32.Build.0 = Debug|Win32
+		{B4E7CD82-988A-BD3A-29F8-8590D3A8BC28}.Debug|x64.Build.0 = Debug|x64
+		{B4E7CD82-988A-BD3A-29F8-8590D3A8BC28}.Release|Win32.Build.0 = Release|Win32
+		{B4E7CD82-988A-BD3A-29F8-8590D3A8BC28}.Release|x64.Build.0 = Release|x64
+		{B4E7CD82-988A-BD3A-29F8-8590D3A8BC28}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
+		{B4E7CD82-988A-BD3A-29F8-8590D3A8BC28}.Debug-DLL|Win32.Build.0 = Debug|Win32
+		{B4E7CD82-988A-BD3A-29F8-8590D3A8BC28}.Debug-DLL|x64.ActiveCfg = Debug|x64
+		{B4E7CD82-988A-BD3A-29F8-8590D3A8BC28}.Debug-DLL|x64.Build.0 = Debug|x64
+		{B4E7CD82-988A-BD3A-29F8-8590D3A8BC28}.Release-DLL|Win32.ActiveCfg = Release|Win32
+		{B4E7CD82-988A-BD3A-29F8-8590D3A8BC28}.Release-DLL|Win32.Build.0 = Release|Win32
+		{B4E7CD82-988A-BD3A-29F8-8590D3A8BC28}.Release-DLL|x64.ActiveCfg = Release|x64
+		{B4E7CD82-988A-BD3A-29F8-8590D3A8BC28}.Release-DLL|x64.Build.0 = Release|x64
 		{E765AC67-E4E5-C350-59A1-C6CA2BD9F64B}.Debug|Win32.ActiveCfg = Debug|Win32
 		{E765AC67-E4E5-C350-59A1-C6CA2BD9F64B}.Debug|x64.ActiveCfg = Debug|x64
 		{E765AC67-E4E5-C350-59A1-C6CA2BD9F64B}.Release|Win32.ActiveCfg = Release|Win32
@@ -2859,6 +3294,22 @@
 		{4A48E5A5-2E69-ED6D-063C-C297180A54D0}.Release-DLL|Win32.Build.0 = Release|Win32
 		{4A48E5A5-2E69-ED6D-063C-C297180A54D0}.Release-DLL|x64.ActiveCfg = Release|x64
 		{4A48E5A5-2E69-ED6D-063C-C297180A54D0}.Release-DLL|x64.Build.0 = Release|x64
+		{63422647-93FA-46BB-4827-95473D9D503C}.Debug|Win32.ActiveCfg = Debug|Win32
+		{63422647-93FA-46BB-4827-95473D9D503C}.Debug|x64.ActiveCfg = Debug|x64
+		{63422647-93FA-46BB-4827-95473D9D503C}.Release|Win32.ActiveCfg = Release|Win32
+		{63422647-93FA-46BB-4827-95473D9D503C}.Release|x64.ActiveCfg = Release|x64
+		{63422647-93FA-46BB-4827-95473D9D503C}.Debug|Win32.Build.0 = Debug|Win32
+		{63422647-93FA-46BB-4827-95473D9D503C}.Debug|x64.Build.0 = Debug|x64
+		{63422647-93FA-46BB-4827-95473D9D503C}.Release|Win32.Build.0 = Release|Win32
+		{63422647-93FA-46BB-4827-95473D9D503C}.Release|x64.Build.0 = Release|x64
+		{63422647-93FA-46BB-4827-95473D9D503C}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
+		{63422647-93FA-46BB-4827-95473D9D503C}.Debug-DLL|Win32.Build.0 = Debug|Win32
+		{63422647-93FA-46BB-4827-95473D9D503C}.Debug-DLL|x64.ActiveCfg = Debug|x64
+		{63422647-93FA-46BB-4827-95473D9D503C}.Debug-DLL|x64.Build.0 = Debug|x64
+		{63422647-93FA-46BB-4827-95473D9D503C}.Release-DLL|Win32.ActiveCfg = Release|Win32
+		{63422647-93FA-46BB-4827-95473D9D503C}.Release-DLL|Win32.Build.0 = Release|Win32
+		{63422647-93FA-46BB-4827-95473D9D503C}.Release-DLL|x64.ActiveCfg = Release|x64
+		{63422647-93FA-46BB-4827-95473D9D503C}.Release-DLL|x64.Build.0 = Release|x64
 		{9889A80C-F1D7-99C9-FE7E-657724BEDC62}.Debug|Win32.ActiveCfg = Debug|Win32
 		{9889A80C-F1D7-99C9-FE7E-657724BEDC62}.Debug|x64.ActiveCfg = Debug|x64
 		{9889A80C-F1D7-99C9-FE7E-657724BEDC62}.Release|Win32.ActiveCfg = Release|Win32
@@ -2891,6 +3342,22 @@
 		{529771F0-10B0-9B1A-1E7E-8A8E01870348}.Release-DLL|Win32.Build.0 = Release|Win32
 		{529771F0-10B0-9B1A-1E7E-8A8E01870348}.Release-DLL|x64.ActiveCfg = Release|x64
 		{529771F0-10B0-9B1A-1E7E-8A8E01870348}.Release-DLL|x64.Build.0 = Release|x64
+		{E3110C46-A148-FF65-08FD-3324829BE7FE}.Debug|Win32.ActiveCfg = Debug|Win32
+		{E3110C46-A148-FF65-08FD-3324829BE7FE}.Debug|x64.ActiveCfg = Debug|x64
+		{E3110C46-A148-FF65-08FD-3324829BE7FE}.Release|Win32.ActiveCfg = Release|Win32
+		{E3110C46-A148-FF65-08FD-3324829BE7FE}.Release|x64.ActiveCfg = Release|x64
+		{E3110C46-A148-FF65-08FD-3324829BE7FE}.Debug|Win32.Build.0 = Debug|Win32
+		{E3110C46-A148-FF65-08FD-3324829BE7FE}.Debug|x64.Build.0 = Debug|x64
+		{E3110C46-A148-FF65-08FD-3324829BE7FE}.Release|Win32.Build.0 = Release|Win32
+		{E3110C46-A148-FF65-08FD-3324829BE7FE}.Release|x64.Build.0 = Release|x64
+		{E3110C46-A148-FF65-08FD-3324829BE7FE}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
+		{E3110C46-A148-FF65-08FD-3324829BE7FE}.Debug-DLL|Win32.Build.0 = Debug|Win32
+		{E3110C46-A148-FF65-08FD-3324829BE7FE}.Debug-DLL|x64.ActiveCfg = Debug|x64
+		{E3110C46-A148-FF65-08FD-3324829BE7FE}.Debug-DLL|x64.Build.0 = Debug|x64
+		{E3110C46-A148-FF65-08FD-3324829BE7FE}.Release-DLL|Win32.ActiveCfg = Release|Win32
+		{E3110C46-A148-FF65-08FD-3324829BE7FE}.Release-DLL|Win32.Build.0 = Release|Win32
+		{E3110C46-A148-FF65-08FD-3324829BE7FE}.Release-DLL|x64.ActiveCfg = Release|x64
+		{E3110C46-A148-FF65-08FD-3324829BE7FE}.Release-DLL|x64.Build.0 = Release|x64
 		{D1EB2A9B-8508-62D7-8FC4-11A11B1CBFD3}.Debug|Win32.ActiveCfg = Debug|Win32
 		{D1EB2A9B-8508-62D7-8FC4-11A11B1CBFD3}.Debug|x64.ActiveCfg = Debug|x64
 		{D1EB2A9B-8508-62D7-8FC4-11A11B1CBFD3}.Release|Win32.ActiveCfg = Release|Win32
@@ -3003,150 +3470,6 @@
 		{89A119C5-0F62-33B8-5D08-1FAA29DA7DEB}.Release-DLL|Win32.Build.0 = Release|Win32
 		{89A119C5-0F62-33B8-5D08-1FAA29DA7DEB}.Release-DLL|x64.ActiveCfg = Release|x64
 		{89A119C5-0F62-33B8-5D08-1FAA29DA7DEB}.Release-DLL|x64.Build.0 = Release|x64
-		{E35C24A0-8725-E773-FE78-CC0C67071EF7}.Debug|Win32.ActiveCfg = Debug|Win32
-		{E35C24A0-8725-E773-FE78-CC0C67071EF7}.Debug|x64.ActiveCfg = Debug|x64
-		{E35C24A0-8725-E773-FE78-CC0C67071EF7}.Release|Win32.ActiveCfg = Release|Win32
-		{E35C24A0-8725-E773-FE78-CC0C67071EF7}.Release|x64.ActiveCfg = Release|x64
-		{E35C24A0-8725-E773-FE78-CC0C67071EF7}.Debug|Win32.Build.0 = Debug|Win32
-		{E35C24A0-8725-E773-FE78-CC0C67071EF7}.Debug|x64.Build.0 = Debug|x64
-		{E35C24A0-8725-E773-FE78-CC0C67071EF7}.Release|Win32.Build.0 = Release|Win32
-		{E35C24A0-8725-E773-FE78-CC0C67071EF7}.Release|x64.Build.0 = Release|x64
-		{E35C24A0-8725-E773-FE78-CC0C67071EF7}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
-		{E35C24A0-8725-E773-FE78-CC0C67071EF7}.Debug-DLL|Win32.Build.0 = Debug|Win32
-		{E35C24A0-8725-E773-FE78-CC0C67071EF7}.Debug-DLL|x64.ActiveCfg = Debug|x64
-		{E35C24A0-8725-E773-FE78-CC0C67071EF7}.Debug-DLL|x64.Build.0 = Debug|x64
-		{E35C24A0-8725-E773-FE78-CC0C67071EF7}.Release-DLL|Win32.ActiveCfg = Release|Win32
-		{E35C24A0-8725-E773-FE78-CC0C67071EF7}.Release-DLL|Win32.Build.0 = Release|Win32
-		{E35C24A0-8725-E773-FE78-CC0C67071EF7}.Release-DLL|x64.ActiveCfg = Release|x64
-		{E35C24A0-8725-E773-FE78-CC0C67071EF7}.Release-DLL|x64.Build.0 = Release|x64
-		{8A811C28-E04E-A444-E4C1-7588DF5B90AE}.Debug|Win32.ActiveCfg = Debug|Win32
-		{8A811C28-E04E-A444-E4C1-7588DF5B90AE}.Debug|x64.ActiveCfg = Debug|x64
-		{8A811C28-E04E-A444-E4C1-7588DF5B90AE}.Release|Win32.ActiveCfg = Release|Win32
-		{8A811C28-E04E-A444-E4C1-7588DF5B90AE}.Release|x64.ActiveCfg = Release|x64
-		{8A811C28-E04E-A444-E4C1-7588DF5B90AE}.Debug|Win32.Build.0 = Debug|Win32
-		{8A811C28-E04E-A444-E4C1-7588DF5B90AE}.Debug|x64.Build.0 = Debug|x64
-		{8A811C28-E04E-A444-E4C1-7588DF5B90AE}.Release|Win32.Build.0 = Release|Win32
-		{8A811C28-E04E-A444-E4C1-7588DF5B90AE}.Release|x64.Build.0 = Release|x64
-		{8A811C28-E04E-A444-E4C1-7588DF5B90AE}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
-		{8A811C28-E04E-A444-E4C1-7588DF5B90AE}.Debug-DLL|Win32.Build.0 = Debug|Win32
-		{8A811C28-E04E-A444-E4C1-7588DF5B90AE}.Debug-DLL|x64.ActiveCfg = Debug|x64
-		{8A811C28-E04E-A444-E4C1-7588DF5B90AE}.Debug-DLL|x64.Build.0 = Debug|x64
-		{8A811C28-E04E-A444-E4C1-7588DF5B90AE}.Release-DLL|Win32.ActiveCfg = Release|Win32
-		{8A811C28-E04E-A444-E4C1-7588DF5B90AE}.Release-DLL|Win32.Build.0 = Release|Win32
-		{8A811C28-E04E-A444-E4C1-7588DF5B90AE}.Release-DLL|x64.ActiveCfg = Release|x64
-		{8A811C28-E04E-A444-E4C1-7588DF5B90AE}.Release-DLL|x64.Build.0 = Release|x64
-		{AF9D0EB2-2A53-B815-3A63-E82C7F91DB29}.Debug|Win32.ActiveCfg = Debug|Win32
-		{AF9D0EB2-2A53-B815-3A63-E82C7F91DB29}.Debug|x64.ActiveCfg = Debug|x64
-		{AF9D0EB2-2A53-B815-3A63-E82C7F91DB29}.Release|Win32.ActiveCfg = Release|Win32
-		{AF9D0EB2-2A53-B815-3A63-E82C7F91DB29}.Release|x64.ActiveCfg = Release|x64
-		{AF9D0EB2-2A53-B815-3A63-E82C7F91DB29}.Debug|Win32.Build.0 = Debug|Win32
-		{AF9D0EB2-2A53-B815-3A63-E82C7F91DB29}.Debug|x64.Build.0 = Debug|x64
-		{AF9D0EB2-2A53-B815-3A63-E82C7F91DB29}.Release|Win32.Build.0 = Release|Win32
-		{AF9D0EB2-2A53-B815-3A63-E82C7F91DB29}.Release|x64.Build.0 = Release|x64
-		{AF9D0EB2-2A53-B815-3A63-E82C7F91DB29}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
-		{AF9D0EB2-2A53-B815-3A63-E82C7F91DB29}.Debug-DLL|Win32.Build.0 = Debug|Win32
-		{AF9D0EB2-2A53-B815-3A63-E82C7F91DB29}.Debug-DLL|x64.ActiveCfg = Debug|x64
-		{AF9D0EB2-2A53-B815-3A63-E82C7F91DB29}.Debug-DLL|x64.Build.0 = Debug|x64
-		{AF9D0EB2-2A53-B815-3A63-E82C7F91DB29}.Release-DLL|Win32.ActiveCfg = Release|Win32
-		{AF9D0EB2-2A53-B815-3A63-E82C7F91DB29}.Release-DLL|Win32.Build.0 = Release|Win32
-		{AF9D0EB2-2A53-B815-3A63-E82C7F91DB29}.Release-DLL|x64.ActiveCfg = Release|x64
-		{AF9D0EB2-2A53-B815-3A63-E82C7F91DB29}.Release-DLL|x64.Build.0 = Release|x64
-		{23DF0572-DBF1-08DA-8EAD-8508354C90A4}.Debug|Win32.ActiveCfg = Debug|Win32
-		{23DF0572-DBF1-08DA-8EAD-8508354C90A4}.Debug|x64.ActiveCfg = Debug|x64
-		{23DF0572-DBF1-08DA-8EAD-8508354C90A4}.Release|Win32.ActiveCfg = Release|Win32
-		{23DF0572-DBF1-08DA-8EAD-8508354C90A4}.Release|x64.ActiveCfg = Release|x64
-		{23DF0572-DBF1-08DA-8EAD-8508354C90A4}.Debug|Win32.Build.0 = Debug|Win32
-		{23DF0572-DBF1-08DA-8EAD-8508354C90A4}.Debug|x64.Build.0 = Debug|x64
-		{23DF0572-DBF1-08DA-8EAD-8508354C90A4}.Release|Win32.Build.0 = Release|Win32
-		{23DF0572-DBF1-08DA-8EAD-8508354C90A4}.Release|x64.Build.0 = Release|x64
-		{23DF0572-DBF1-08DA-8EAD-8508354C90A4}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
-		{23DF0572-DBF1-08DA-8EAD-8508354C90A4}.Debug-DLL|Win32.Build.0 = Debug|Win32
-		{23DF0572-DBF1-08DA-8EAD-8508354C90A4}.Debug-DLL|x64.ActiveCfg = Debug|x64
-		{23DF0572-DBF1-08DA-8EAD-8508354C90A4}.Debug-DLL|x64.Build.0 = Debug|x64
-		{23DF0572-DBF1-08DA-8EAD-8508354C90A4}.Release-DLL|Win32.ActiveCfg = Release|Win32
-		{23DF0572-DBF1-08DA-8EAD-8508354C90A4}.Release-DLL|Win32.Build.0 = Release|Win32
-		{23DF0572-DBF1-08DA-8EAD-8508354C90A4}.Release-DLL|x64.ActiveCfg = Release|x64
-		{23DF0572-DBF1-08DA-8EAD-8508354C90A4}.Release-DLL|x64.Build.0 = Release|x64
-		{7819A11E-607E-F0C0-FC47-C704CF7D818C}.Debug|Win32.ActiveCfg = Debug|Win32
-		{7819A11E-607E-F0C0-FC47-C704CF7D818C}.Debug|x64.ActiveCfg = Debug|x64
-		{7819A11E-607E-F0C0-FC47-C704CF7D818C}.Release|Win32.ActiveCfg = Release|Win32
-		{7819A11E-607E-F0C0-FC47-C704CF7D818C}.Release|x64.ActiveCfg = Release|x64
-		{7819A11E-607E-F0C0-FC47-C704CF7D818C}.Debug|Win32.Build.0 = Debug|Win32
-		{7819A11E-607E-F0C0-FC47-C704CF7D818C}.Debug|x64.Build.0 = Debug|x64
-		{7819A11E-607E-F0C0-FC47-C704CF7D818C}.Release|Win32.Build.0 = Release|Win32
-		{7819A11E-607E-F0C0-FC47-C704CF7D818C}.Release|x64.Build.0 = Release|x64
-		{7819A11E-607E-F0C0-FC47-C704CF7D818C}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
-		{7819A11E-607E-F0C0-FC47-C704CF7D818C}.Debug-DLL|Win32.Build.0 = Debug|Win32
-		{7819A11E-607E-F0C0-FC47-C704CF7D818C}.Debug-DLL|x64.ActiveCfg = Debug|x64
-		{7819A11E-607E-F0C0-FC47-C704CF7D818C}.Debug-DLL|x64.Build.0 = Debug|x64
-		{7819A11E-607E-F0C0-FC47-C704CF7D818C}.Release-DLL|Win32.ActiveCfg = Release|Win32
-		{7819A11E-607E-F0C0-FC47-C704CF7D818C}.Release-DLL|Win32.Build.0 = Release|Win32
-		{7819A11E-607E-F0C0-FC47-C704CF7D818C}.Release-DLL|x64.ActiveCfg = Release|x64
-		{7819A11E-607E-F0C0-FC47-C704CF7D818C}.Release-DLL|x64.Build.0 = Release|x64
-		{6756895E-05BF-8CC7-58F2-868DF0C0300C}.Debug|Win32.ActiveCfg = Debug|Win32
-		{6756895E-05BF-8CC7-58F2-868DF0C0300C}.Debug|x64.ActiveCfg = Debug|x64
-		{6756895E-05BF-8CC7-58F2-868DF0C0300C}.Release|Win32.ActiveCfg = Release|Win32
-		{6756895E-05BF-8CC7-58F2-868DF0C0300C}.Release|x64.ActiveCfg = Release|x64
-		{6756895E-05BF-8CC7-58F2-868DF0C0300C}.Debug|Win32.Build.0 = Debug|Win32
-		{6756895E-05BF-8CC7-58F2-868DF0C0300C}.Debug|x64.Build.0 = Debug|x64
-		{6756895E-05BF-8CC7-58F2-868DF0C0300C}.Release|Win32.Build.0 = Release|Win32
-		{6756895E-05BF-8CC7-58F2-868DF0C0300C}.Release|x64.Build.0 = Release|x64
-		{6756895E-05BF-8CC7-58F2-868DF0C0300C}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
-		{6756895E-05BF-8CC7-58F2-868DF0C0300C}.Debug-DLL|Win32.Build.0 = Debug|Win32
-		{6756895E-05BF-8CC7-58F2-868DF0C0300C}.Debug-DLL|x64.ActiveCfg = Debug|x64
-		{6756895E-05BF-8CC7-58F2-868DF0C0300C}.Debug-DLL|x64.Build.0 = Debug|x64
-		{6756895E-05BF-8CC7-58F2-868DF0C0300C}.Release-DLL|Win32.ActiveCfg = Release|Win32
-		{6756895E-05BF-8CC7-58F2-868DF0C0300C}.Release-DLL|Win32.Build.0 = Release|Win32
-		{6756895E-05BF-8CC7-58F2-868DF0C0300C}.Release-DLL|x64.ActiveCfg = Release|x64
-		{6756895E-05BF-8CC7-58F2-868DF0C0300C}.Release-DLL|x64.Build.0 = Release|x64
-		{B706A9EC-7982-0DBC-495D-07B165F6CF56}.Debug|Win32.ActiveCfg = Debug|Win32
-		{B706A9EC-7982-0DBC-495D-07B165F6CF56}.Debug|x64.ActiveCfg = Debug|x64
-		{B706A9EC-7982-0DBC-495D-07B165F6CF56}.Release|Win32.ActiveCfg = Release|Win32
-		{B706A9EC-7982-0DBC-495D-07B165F6CF56}.Release|x64.ActiveCfg = Release|x64
-		{B706A9EC-7982-0DBC-495D-07B165F6CF56}.Debug|Win32.Build.0 = Debug|Win32
-		{B706A9EC-7982-0DBC-495D-07B165F6CF56}.Debug|x64.Build.0 = Debug|x64
-		{B706A9EC-7982-0DBC-495D-07B165F6CF56}.Release|Win32.Build.0 = Release|Win32
-		{B706A9EC-7982-0DBC-495D-07B165F6CF56}.Release|x64.Build.0 = Release|x64
-		{B706A9EC-7982-0DBC-495D-07B165F6CF56}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
-		{B706A9EC-7982-0DBC-495D-07B165F6CF56}.Debug-DLL|Win32.Build.0 = Debug|Win32
-		{B706A9EC-7982-0DBC-495D-07B165F6CF56}.Debug-DLL|x64.ActiveCfg = Debug|x64
-		{B706A9EC-7982-0DBC-495D-07B165F6CF56}.Debug-DLL|x64.Build.0 = Debug|x64
-		{B706A9EC-7982-0DBC-495D-07B165F6CF56}.Release-DLL|Win32.ActiveCfg = Release|Win32
-		{B706A9EC-7982-0DBC-495D-07B165F6CF56}.Release-DLL|Win32.Build.0 = Release|Win32
-		{B706A9EC-7982-0DBC-495D-07B165F6CF56}.Release-DLL|x64.ActiveCfg = Release|x64
-		{B706A9EC-7982-0DBC-495D-07B165F6CF56}.Release-DLL|x64.Build.0 = Release|x64
-		{B4E7CD82-988A-BD3A-29F8-8590D3A8BC28}.Debug|Win32.ActiveCfg = Debug|Win32
-		{B4E7CD82-988A-BD3A-29F8-8590D3A8BC28}.Debug|x64.ActiveCfg = Debug|x64
-		{B4E7CD82-988A-BD3A-29F8-8590D3A8BC28}.Release|Win32.ActiveCfg = Release|Win32
-		{B4E7CD82-988A-BD3A-29F8-8590D3A8BC28}.Release|x64.ActiveCfg = Release|x64
-		{B4E7CD82-988A-BD3A-29F8-8590D3A8BC28}.Debug|Win32.Build.0 = Debug|Win32
-		{B4E7CD82-988A-BD3A-29F8-8590D3A8BC28}.Debug|x64.Build.0 = Debug|x64
-		{B4E7CD82-988A-BD3A-29F8-8590D3A8BC28}.Release|Win32.Build.0 = Release|Win32
-		{B4E7CD82-988A-BD3A-29F8-8590D3A8BC28}.Release|x64.Build.0 = Release|x64
-		{B4E7CD82-988A-BD3A-29F8-8590D3A8BC28}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
-		{B4E7CD82-988A-BD3A-29F8-8590D3A8BC28}.Debug-DLL|Win32.Build.0 = Debug|Win32
-		{B4E7CD82-988A-BD3A-29F8-8590D3A8BC28}.Debug-DLL|x64.ActiveCfg = Debug|x64
-		{B4E7CD82-988A-BD3A-29F8-8590D3A8BC28}.Debug-DLL|x64.Build.0 = Debug|x64
-		{B4E7CD82-988A-BD3A-29F8-8590D3A8BC28}.Release-DLL|Win32.ActiveCfg = Release|Win32
-		{B4E7CD82-988A-BD3A-29F8-8590D3A8BC28}.Release-DLL|Win32.Build.0 = Release|Win32
-		{B4E7CD82-988A-BD3A-29F8-8590D3A8BC28}.Release-DLL|x64.ActiveCfg = Release|x64
-		{B4E7CD82-988A-BD3A-29F8-8590D3A8BC28}.Release-DLL|x64.Build.0 = Release|x64
-		{63422647-93FA-46BB-4827-95473D9D503C}.Debug|Win32.ActiveCfg = Debug|Win32
-		{63422647-93FA-46BB-4827-95473D9D503C}.Debug|x64.ActiveCfg = Debug|x64
-		{63422647-93FA-46BB-4827-95473D9D503C}.Release|Win32.ActiveCfg = Release|Win32
-		{63422647-93FA-46BB-4827-95473D9D503C}.Release|x64.ActiveCfg = Release|x64
-		{63422647-93FA-46BB-4827-95473D9D503C}.Debug|Win32.Build.0 = Debug|Win32
-		{63422647-93FA-46BB-4827-95473D9D503C}.Debug|x64.Build.0 = Debug|x64
-		{63422647-93FA-46BB-4827-95473D9D503C}.Release|Win32.Build.0 = Release|Win32
-		{63422647-93FA-46BB-4827-95473D9D503C}.Release|x64.Build.0 = Release|x64
-		{63422647-93FA-46BB-4827-95473D9D503C}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
-		{63422647-93FA-46BB-4827-95473D9D503C}.Debug-DLL|Win32.Build.0 = Debug|Win32
-		{63422647-93FA-46BB-4827-95473D9D503C}.Debug-DLL|x64.ActiveCfg = Debug|x64
-		{63422647-93FA-46BB-4827-95473D9D503C}.Debug-DLL|x64.Build.0 = Debug|x64
-		{63422647-93FA-46BB-4827-95473D9D503C}.Release-DLL|Win32.ActiveCfg = Release|Win32
-		{63422647-93FA-46BB-4827-95473D9D503C}.Release-DLL|Win32.Build.0 = Release|Win32
-		{63422647-93FA-46BB-4827-95473D9D503C}.Release-DLL|x64.ActiveCfg = Release|x64
-		{63422647-93FA-46BB-4827-95473D9D503C}.Release-DLL|x64.Build.0 = Release|x64
 		{9E0A2239-20D5-DB2D-CA0D-69F24E3416E7}.Debug|Win32.ActiveCfg = Debug|Win32
 		{9E0A2239-20D5-DB2D-CA0D-69F24E3416E7}.Debug|x64.ActiveCfg = Debug|x64
 		{9E0A2239-20D5-DB2D-CA0D-69F24E3416E7}.Release|Win32.ActiveCfg = Release|Win32
@@ -3163,6 +3486,22 @@
 		{9E0A2239-20D5-DB2D-CA0D-69F24E3416E7}.Release-DLL|Win32.Build.0 = Release|Win32
 		{9E0A2239-20D5-DB2D-CA0D-69F24E3416E7}.Release-DLL|x64.ActiveCfg = Release|x64
 		{9E0A2239-20D5-DB2D-CA0D-69F24E3416E7}.Release-DLL|x64.Build.0 = Release|x64
+		{E35C24A0-8725-E773-FE78-CC0C67071EF7}.Debug|Win32.ActiveCfg = Debug|Win32
+		{E35C24A0-8725-E773-FE78-CC0C67071EF7}.Debug|x64.ActiveCfg = Debug|x64
+		{E35C24A0-8725-E773-FE78-CC0C67071EF7}.Release|Win32.ActiveCfg = Release|Win32
+		{E35C24A0-8725-E773-FE78-CC0C67071EF7}.Release|x64.ActiveCfg = Release|x64
+		{E35C24A0-8725-E773-FE78-CC0C67071EF7}.Debug|Win32.Build.0 = Debug|Win32
+		{E35C24A0-8725-E773-FE78-CC0C67071EF7}.Debug|x64.Build.0 = Debug|x64
+		{E35C24A0-8725-E773-FE78-CC0C67071EF7}.Release|Win32.Build.0 = Release|Win32
+		{E35C24A0-8725-E773-FE78-CC0C67071EF7}.Release|x64.Build.0 = Release|x64
+		{E35C24A0-8725-E773-FE78-CC0C67071EF7}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
+		{E35C24A0-8725-E773-FE78-CC0C67071EF7}.Debug-DLL|Win32.Build.0 = Debug|Win32
+		{E35C24A0-8725-E773-FE78-CC0C67071EF7}.Debug-DLL|x64.ActiveCfg = Debug|x64
+		{E35C24A0-8725-E773-FE78-CC0C67071EF7}.Debug-DLL|x64.Build.0 = Debug|x64
+		{E35C24A0-8725-E773-FE78-CC0C67071EF7}.Release-DLL|Win32.ActiveCfg = Release|Win32
+		{E35C24A0-8725-E773-FE78-CC0C67071EF7}.Release-DLL|Win32.Build.0 = Release|Win32
+		{E35C24A0-8725-E773-FE78-CC0C67071EF7}.Release-DLL|x64.ActiveCfg = Release|x64
+		{E35C24A0-8725-E773-FE78-CC0C67071EF7}.Release-DLL|x64.Build.0 = Release|x64
 		{658D7F7F-9628-6545-743C-D949301DC5DC}.Debug|Win32.ActiveCfg = Debug|Win32
 		{658D7F7F-9628-6545-743C-D949301DC5DC}.Debug|x64.ActiveCfg = Debug|x64
 		{658D7F7F-9628-6545-743C-D949301DC5DC}.Release|Win32.ActiveCfg = Release|Win32
@@ -3179,342 +3518,6 @@
 		{658D7F7F-9628-6545-743C-D949301DC5DC}.Release-DLL|Win32.Build.0 = Release|Win32
 		{658D7F7F-9628-6545-743C-D949301DC5DC}.Release-DLL|x64.ActiveCfg = Release|x64
 		{658D7F7F-9628-6545-743C-D949301DC5DC}.Release-DLL|x64.Build.0 = Release|x64
-		{9E4180B0-81ED-7305-333F-653CE9AB819B}.Debug|Win32.ActiveCfg = Debug|Win32
-		{9E4180B0-81ED-7305-333F-653CE9AB819B}.Debug|x64.ActiveCfg = Debug|x64
-		{9E4180B0-81ED-7305-333F-653CE9AB819B}.Release|Win32.ActiveCfg = Release|Win32
-		{9E4180B0-81ED-7305-333F-653CE9AB819B}.Release|x64.ActiveCfg = Release|x64
-		{9E4180B0-81ED-7305-333F-653CE9AB819B}.Debug|Win32.Build.0 = Debug|Win32
-		{9E4180B0-81ED-7305-333F-653CE9AB819B}.Debug|x64.Build.0 = Debug|x64
-		{9E4180B0-81ED-7305-333F-653CE9AB819B}.Release|Win32.Build.0 = Release|Win32
-		{9E4180B0-81ED-7305-333F-653CE9AB819B}.Release|x64.Build.0 = Release|x64
-		{9E4180B0-81ED-7305-333F-653CE9AB819B}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
-		{9E4180B0-81ED-7305-333F-653CE9AB819B}.Debug-DLL|Win32.Build.0 = Debug|Win32
-		{9E4180B0-81ED-7305-333F-653CE9AB819B}.Debug-DLL|x64.ActiveCfg = Debug|x64
-		{9E4180B0-81ED-7305-333F-653CE9AB819B}.Debug-DLL|x64.Build.0 = Debug|x64
-		{9E4180B0-81ED-7305-333F-653CE9AB819B}.Release-DLL|Win32.ActiveCfg = Release|Win32
-		{9E4180B0-81ED-7305-333F-653CE9AB819B}.Release-DLL|Win32.Build.0 = Release|Win32
-		{9E4180B0-81ED-7305-333F-653CE9AB819B}.Release-DLL|x64.ActiveCfg = Release|x64
-		{9E4180B0-81ED-7305-333F-653CE9AB819B}.Release-DLL|x64.Build.0 = Release|x64
-		{C7E516E9-B80F-4BC1-A617-095FC6E14BC9}.Debug|Win32.ActiveCfg = Debug|Win32
-		{C7E516E9-B80F-4BC1-A617-095FC6E14BC9}.Debug|x64.ActiveCfg = Debug|x64
-		{C7E516E9-B80F-4BC1-A617-095FC6E14BC9}.Release|Win32.ActiveCfg = Release|Win32
-		{C7E516E9-B80F-4BC1-A617-095FC6E14BC9}.Release|x64.ActiveCfg = Release|x64
-		{C7E516E9-B80F-4BC1-A617-095FC6E14BC9}.Debug|Win32.Build.0 = Debug|Win32
-		{C7E516E9-B80F-4BC1-A617-095FC6E14BC9}.Debug|x64.Build.0 = Debug|x64
-		{C7E516E9-B80F-4BC1-A617-095FC6E14BC9}.Release|Win32.Build.0 = Release|Win32
-		{C7E516E9-B80F-4BC1-A617-095FC6E14BC9}.Release|x64.Build.0 = Release|x64
-		{C7E516E9-B80F-4BC1-A617-095FC6E14BC9}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
-		{C7E516E9-B80F-4BC1-A617-095FC6E14BC9}.Debug-DLL|Win32.Build.0 = Debug|Win32
-		{C7E516E9-B80F-4BC1-A617-095FC6E14BC9}.Debug-DLL|x64.ActiveCfg = Debug|x64
-		{C7E516E9-B80F-4BC1-A617-095FC6E14BC9}.Debug-DLL|x64.Build.0 = Debug|x64
-		{C7E516E9-B80F-4BC1-A617-095FC6E14BC9}.Release-DLL|Win32.ActiveCfg = Release|Win32
-		{C7E516E9-B80F-4BC1-A617-095FC6E14BC9}.Release-DLL|Win32.Build.0 = Release|Win32
-		{C7E516E9-B80F-4BC1-A617-095FC6E14BC9}.Release-DLL|x64.ActiveCfg = Release|x64
-		{C7E516E9-B80F-4BC1-A617-095FC6E14BC9}.Release-DLL|x64.Build.0 = Release|x64
-		{0E980562-3AA0-91B1-C590-85C9A899BE44}.Debug|Win32.ActiveCfg = Debug|Win32
-		{0E980562-3AA0-91B1-C590-85C9A899BE44}.Debug|x64.ActiveCfg = Debug|x64
-		{0E980562-3AA0-91B1-C590-85C9A899BE44}.Release|Win32.ActiveCfg = Release|Win32
-		{0E980562-3AA0-91B1-C590-85C9A899BE44}.Release|x64.ActiveCfg = Release|x64
-		{0E980562-3AA0-91B1-C590-85C9A899BE44}.Debug|Win32.Build.0 = Debug|Win32
-		{0E980562-3AA0-91B1-C590-85C9A899BE44}.Debug|x64.Build.0 = Debug|x64
-		{0E980562-3AA0-91B1-C590-85C9A899BE44}.Release|Win32.Build.0 = Release|Win32
-		{0E980562-3AA0-91B1-C590-85C9A899BE44}.Release|x64.Build.0 = Release|x64
-		{0E980562-3AA0-91B1-C590-85C9A899BE44}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
-		{0E980562-3AA0-91B1-C590-85C9A899BE44}.Debug-DLL|Win32.Build.0 = Debug|Win32
-		{0E980562-3AA0-91B1-C590-85C9A899BE44}.Debug-DLL|x64.ActiveCfg = Debug|x64
-		{0E980562-3AA0-91B1-C590-85C9A899BE44}.Debug-DLL|x64.Build.0 = Debug|x64
-		{0E980562-3AA0-91B1-C590-85C9A899BE44}.Release-DLL|Win32.ActiveCfg = Release|Win32
-		{0E980562-3AA0-91B1-C590-85C9A899BE44}.Release-DLL|Win32.Build.0 = Release|Win32
-		{0E980562-3AA0-91B1-C590-85C9A899BE44}.Release-DLL|x64.ActiveCfg = Release|x64
-		{0E980562-3AA0-91B1-C590-85C9A899BE44}.Release-DLL|x64.Build.0 = Release|x64
-		{EEBEFA75-C625-C823-FE96-9AD64887B57D}.Debug|Win32.ActiveCfg = Debug|Win32
-		{EEBEFA75-C625-C823-FE96-9AD64887B57D}.Debug|x64.ActiveCfg = Debug|x64
-		{EEBEFA75-C625-C823-FE96-9AD64887B57D}.Release|Win32.ActiveCfg = Release|Win32
-		{EEBEFA75-C625-C823-FE96-9AD64887B57D}.Release|x64.ActiveCfg = Release|x64
-		{EEBEFA75-C625-C823-FE96-9AD64887B57D}.Debug|Win32.Build.0 = Debug|Win32
-		{EEBEFA75-C625-C823-FE96-9AD64887B57D}.Debug|x64.Build.0 = Debug|x64
-		{EEBEFA75-C625-C823-FE96-9AD64887B57D}.Release|Win32.Build.0 = Release|Win32
-		{EEBEFA75-C625-C823-FE96-9AD64887B57D}.Release|x64.Build.0 = Release|x64
-		{EEBEFA75-C625-C823-FE96-9AD64887B57D}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
-		{EEBEFA75-C625-C823-FE96-9AD64887B57D}.Debug-DLL|Win32.Build.0 = Debug|Win32
-		{EEBEFA75-C625-C823-FE96-9AD64887B57D}.Debug-DLL|x64.ActiveCfg = Debug|x64
-		{EEBEFA75-C625-C823-FE96-9AD64887B57D}.Debug-DLL|x64.Build.0 = Debug|x64
-		{EEBEFA75-C625-C823-FE96-9AD64887B57D}.Release-DLL|Win32.ActiveCfg = Release|Win32
-		{EEBEFA75-C625-C823-FE96-9AD64887B57D}.Release-DLL|Win32.Build.0 = Release|Win32
-		{EEBEFA75-C625-C823-FE96-9AD64887B57D}.Release-DLL|x64.ActiveCfg = Release|x64
-		{EEBEFA75-C625-C823-FE96-9AD64887B57D}.Release-DLL|x64.Build.0 = Release|x64
-		{16C713C6-062E-F71F-A44C-52DC35494B27}.Debug|Win32.ActiveCfg = Debug|Win32
-		{16C713C6-062E-F71F-A44C-52DC35494B27}.Debug|x64.ActiveCfg = Debug|x64
-		{16C713C6-062E-F71F-A44C-52DC35494B27}.Release|Win32.ActiveCfg = Release|Win32
-		{16C713C6-062E-F71F-A44C-52DC35494B27}.Release|x64.ActiveCfg = Release|x64
-		{16C713C6-062E-F71F-A44C-52DC35494B27}.Debug|Win32.Build.0 = Debug|Win32
-		{16C713C6-062E-F71F-A44C-52DC35494B27}.Debug|x64.Build.0 = Debug|x64
-		{16C713C6-062E-F71F-A44C-52DC35494B27}.Release|Win32.Build.0 = Release|Win32
-		{16C713C6-062E-F71F-A44C-52DC35494B27}.Release|x64.Build.0 = Release|x64
-		{16C713C6-062E-F71F-A44C-52DC35494B27}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
-		{16C713C6-062E-F71F-A44C-52DC35494B27}.Debug-DLL|Win32.Build.0 = Debug|Win32
-		{16C713C6-062E-F71F-A44C-52DC35494B27}.Debug-DLL|x64.ActiveCfg = Debug|x64
-		{16C713C6-062E-F71F-A44C-52DC35494B27}.Debug-DLL|x64.Build.0 = Debug|x64
-		{16C713C6-062E-F71F-A44C-52DC35494B27}.Release-DLL|Win32.ActiveCfg = Release|Win32
-		{16C713C6-062E-F71F-A44C-52DC35494B27}.Release-DLL|Win32.Build.0 = Release|Win32
-		{16C713C6-062E-F71F-A44C-52DC35494B27}.Release-DLL|x64.ActiveCfg = Release|x64
-		{16C713C6-062E-F71F-A44C-52DC35494B27}.Release-DLL|x64.Build.0 = Release|x64
-		{0F761FF3-342A-C429-711F-F76181BAA52D}.Debug|Win32.ActiveCfg = Debug|Win32
-		{0F761FF3-342A-C429-711F-F76181BAA52D}.Debug|x64.ActiveCfg = Debug|x64
-		{0F761FF3-342A-C429-711F-F76181BAA52D}.Release|Win32.ActiveCfg = Release|Win32
-		{0F761FF3-342A-C429-711F-F76181BAA52D}.Release|x64.ActiveCfg = Release|x64
-		{0F761FF3-342A-C429-711F-F76181BAA52D}.Debug|Win32.Build.0 = Debug|Win32
-		{0F761FF3-342A-C429-711F-F76181BAA52D}.Debug|x64.Build.0 = Debug|x64
-		{0F761FF3-342A-C429-711F-F76181BAA52D}.Release|Win32.Build.0 = Release|Win32
-		{0F761FF3-342A-C429-711F-F76181BAA52D}.Release|x64.Build.0 = Release|x64
-		{0F761FF3-342A-C429-711F-F76181BAA52D}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
-		{0F761FF3-342A-C429-711F-F76181BAA52D}.Debug-DLL|Win32.Build.0 = Debug|Win32
-		{0F761FF3-342A-C429-711F-F76181BAA52D}.Debug-DLL|x64.ActiveCfg = Debug|x64
-		{0F761FF3-342A-C429-711F-F76181BAA52D}.Debug-DLL|x64.Build.0 = Debug|x64
-		{0F761FF3-342A-C429-711F-F76181BAA52D}.Release-DLL|Win32.ActiveCfg = Release|Win32
-		{0F761FF3-342A-C429-711F-F76181BAA52D}.Release-DLL|Win32.Build.0 = Release|Win32
-		{0F761FF3-342A-C429-711F-F76181BAA52D}.Release-DLL|x64.ActiveCfg = Release|x64
-		{0F761FF3-342A-C429-711F-F76181BAA52D}.Release-DLL|x64.Build.0 = Release|x64
-		{5753B14F-0C69-2E56-6264-5541B2DCDF67}.Debug|Win32.ActiveCfg = Debug|Win32
-		{5753B14F-0C69-2E56-6264-5541B2DCDF67}.Debug|x64.ActiveCfg = Debug|x64
-		{5753B14F-0C69-2E56-6264-5541B2DCDF67}.Release|Win32.ActiveCfg = Release|Win32
-		{5753B14F-0C69-2E56-6264-5541B2DCDF67}.Release|x64.ActiveCfg = Release|x64
-		{5753B14F-0C69-2E56-6264-5541B2DCDF67}.Debug|Win32.Build.0 = Debug|Win32
-		{5753B14F-0C69-2E56-6264-5541B2DCDF67}.Debug|x64.Build.0 = Debug|x64
-		{5753B14F-0C69-2E56-6264-5541B2DCDF67}.Release|Win32.Build.0 = Release|Win32
-		{5753B14F-0C69-2E56-6264-5541B2DCDF67}.Release|x64.Build.0 = Release|x64
-		{5753B14F-0C69-2E56-6264-5541B2DCDF67}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
-		{5753B14F-0C69-2E56-6264-5541B2DCDF67}.Debug-DLL|Win32.Build.0 = Debug|Win32
-		{5753B14F-0C69-2E56-6264-5541B2DCDF67}.Debug-DLL|x64.ActiveCfg = Debug|x64
-		{5753B14F-0C69-2E56-6264-5541B2DCDF67}.Debug-DLL|x64.Build.0 = Debug|x64
-		{5753B14F-0C69-2E56-6264-5541B2DCDF67}.Release-DLL|Win32.ActiveCfg = Release|Win32
-		{5753B14F-0C69-2E56-6264-5541B2DCDF67}.Release-DLL|Win32.Build.0 = Release|Win32
-		{5753B14F-0C69-2E56-6264-5541B2DCDF67}.Release-DLL|x64.ActiveCfg = Release|x64
-		{5753B14F-0C69-2E56-6264-5541B2DCDF67}.Release-DLL|x64.Build.0 = Release|x64
-		{67458AF8-A122-7740-F195-C2E74A106FAB}.Debug|Win32.ActiveCfg = Debug|Win32
-		{67458AF8-A122-7740-F195-C2E74A106FAB}.Debug|x64.ActiveCfg = Debug|x64
-		{67458AF8-A122-7740-F195-C2E74A106FAB}.Release|Win32.ActiveCfg = Release|Win32
-		{67458AF8-A122-7740-F195-C2E74A106FAB}.Release|x64.ActiveCfg = Release|x64
-		{67458AF8-A122-7740-F195-C2E74A106FAB}.Debug|Win32.Build.0 = Debug|Win32
-		{67458AF8-A122-7740-F195-C2E74A106FAB}.Debug|x64.Build.0 = Debug|x64
-		{67458AF8-A122-7740-F195-C2E74A106FAB}.Release|Win32.Build.0 = Release|Win32
-		{67458AF8-A122-7740-F195-C2E74A106FAB}.Release|x64.Build.0 = Release|x64
-		{67458AF8-A122-7740-F195-C2E74A106FAB}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
-		{67458AF8-A122-7740-F195-C2E74A106FAB}.Debug-DLL|Win32.Build.0 = Debug|Win32
-		{67458AF8-A122-7740-F195-C2E74A106FAB}.Debug-DLL|x64.ActiveCfg = Debug|x64
-		{67458AF8-A122-7740-F195-C2E74A106FAB}.Debug-DLL|x64.Build.0 = Debug|x64
-		{67458AF8-A122-7740-F195-C2E74A106FAB}.Release-DLL|Win32.ActiveCfg = Release|Win32
-		{67458AF8-A122-7740-F195-C2E74A106FAB}.Release-DLL|Win32.Build.0 = Release|Win32
-		{67458AF8-A122-7740-F195-C2E74A106FAB}.Release-DLL|x64.ActiveCfg = Release|x64
-		{67458AF8-A122-7740-F195-C2E74A106FAB}.Release-DLL|x64.Build.0 = Release|x64
-		{82878169-5A89-FD1E-31A6-E9F07BB92418}.Debug|Win32.ActiveCfg = Debug|Win32
-		{82878169-5A89-FD1E-31A6-E9F07BB92418}.Debug|x64.ActiveCfg = Debug|x64
-		{82878169-5A89-FD1E-31A6-E9F07BB92418}.Release|Win32.ActiveCfg = Release|Win32
-		{82878169-5A89-FD1E-31A6-E9F07BB92418}.Release|x64.ActiveCfg = Release|x64
-		{82878169-5A89-FD1E-31A6-E9F07BB92418}.Debug|Win32.Build.0 = Debug|Win32
-		{82878169-5A89-FD1E-31A6-E9F07BB92418}.Debug|x64.Build.0 = Debug|x64
-		{82878169-5A89-FD1E-31A6-E9F07BB92418}.Release|Win32.Build.0 = Release|Win32
-		{82878169-5A89-FD1E-31A6-E9F07BB92418}.Release|x64.Build.0 = Release|x64
-		{82878169-5A89-FD1E-31A6-E9F07BB92418}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
-		{82878169-5A89-FD1E-31A6-E9F07BB92418}.Debug-DLL|Win32.Build.0 = Debug|Win32
-		{82878169-5A89-FD1E-31A6-E9F07BB92418}.Debug-DLL|x64.ActiveCfg = Debug|x64
-		{82878169-5A89-FD1E-31A6-E9F07BB92418}.Debug-DLL|x64.Build.0 = Debug|x64
-		{82878169-5A89-FD1E-31A6-E9F07BB92418}.Release-DLL|Win32.ActiveCfg = Release|Win32
-		{82878169-5A89-FD1E-31A6-E9F07BB92418}.Release-DLL|Win32.Build.0 = Release|Win32
-		{82878169-5A89-FD1E-31A6-E9F07BB92418}.Release-DLL|x64.ActiveCfg = Release|x64
-		{82878169-5A89-FD1E-31A6-E9F07BB92418}.Release-DLL|x64.Build.0 = Release|x64
-		{03A65361-E139-5344-1868-8E8FC269C6E6}.Debug|Win32.ActiveCfg = Debug|Win32
-		{03A65361-E139-5344-1868-8E8FC269C6E6}.Debug|x64.ActiveCfg = Debug|x64
-		{03A65361-E139-5344-1868-8E8FC269C6E6}.Release|Win32.ActiveCfg = Release|Win32
-		{03A65361-E139-5344-1868-8E8FC269C6E6}.Release|x64.ActiveCfg = Release|x64
-		{03A65361-E139-5344-1868-8E8FC269C6E6}.Debug|Win32.Build.0 = Debug|Win32
-		{03A65361-E139-5344-1868-8E8FC269C6E6}.Debug|x64.Build.0 = Debug|x64
-		{03A65361-E139-5344-1868-8E8FC269C6E6}.Release|Win32.Build.0 = Release|Win32
-		{03A65361-E139-5344-1868-8E8FC269C6E6}.Release|x64.Build.0 = Release|x64
-		{03A65361-E139-5344-1868-8E8FC269C6E6}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
-		{03A65361-E139-5344-1868-8E8FC269C6E6}.Debug-DLL|Win32.Build.0 = Debug|Win32
-		{03A65361-E139-5344-1868-8E8FC269C6E6}.Debug-DLL|x64.ActiveCfg = Debug|x64
-		{03A65361-E139-5344-1868-8E8FC269C6E6}.Debug-DLL|x64.Build.0 = Debug|x64
-		{03A65361-E139-5344-1868-8E8FC269C6E6}.Release-DLL|Win32.ActiveCfg = Release|Win32
-		{03A65361-E139-5344-1868-8E8FC269C6E6}.Release-DLL|Win32.Build.0 = Release|Win32
-		{03A65361-E139-5344-1868-8E8FC269C6E6}.Release-DLL|x64.ActiveCfg = Release|x64
-		{03A65361-E139-5344-1868-8E8FC269C6E6}.Release-DLL|x64.Build.0 = Release|x64
-		{EA78D290-4098-FF04-C647-013F6B81E4E7}.Debug|Win32.ActiveCfg = Debug|Win32
-		{EA78D290-4098-FF04-C647-013F6B81E4E7}.Debug|x64.ActiveCfg = Debug|x64
-		{EA78D290-4098-FF04-C647-013F6B81E4E7}.Release|Win32.ActiveCfg = Release|Win32
-		{EA78D290-4098-FF04-C647-013F6B81E4E7}.Release|x64.ActiveCfg = Release|x64
-		{EA78D290-4098-FF04-C647-013F6B81E4E7}.Debug|Win32.Build.0 = Debug|Win32
-		{EA78D290-4098-FF04-C647-013F6B81E4E7}.Debug|x64.Build.0 = Debug|x64
-		{EA78D290-4098-FF04-C647-013F6B81E4E7}.Release|Win32.Build.0 = Release|Win32
-		{EA78D290-4098-FF04-C647-013F6B81E4E7}.Release|x64.Build.0 = Release|x64
-		{EA78D290-4098-FF04-C647-013F6B81E4E7}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
-		{EA78D290-4098-FF04-C647-013F6B81E4E7}.Debug-DLL|Win32.Build.0 = Debug|Win32
-		{EA78D290-4098-FF04-C647-013F6B81E4E7}.Debug-DLL|x64.ActiveCfg = Debug|x64
-		{EA78D290-4098-FF04-C647-013F6B81E4E7}.Debug-DLL|x64.Build.0 = Debug|x64
-		{EA78D290-4098-FF04-C647-013F6B81E4E7}.Release-DLL|Win32.ActiveCfg = Release|Win32
-		{EA78D290-4098-FF04-C647-013F6B81E4E7}.Release-DLL|Win32.Build.0 = Release|Win32
-		{EA78D290-4098-FF04-C647-013F6B81E4E7}.Release-DLL|x64.ActiveCfg = Release|x64
-		{EA78D290-4098-FF04-C647-013F6B81E4E7}.Release-DLL|x64.Build.0 = Release|x64
-		{B3B7D225-3C04-72F9-4C2C-1C3F3136FE58}.Debug|Win32.ActiveCfg = Debug|Win32
-		{B3B7D225-3C04-72F9-4C2C-1C3F3136FE58}.Debug|x64.ActiveCfg = Debug|x64
-		{B3B7D225-3C04-72F9-4C2C-1C3F3136FE58}.Release|Win32.ActiveCfg = Release|Win32
-		{B3B7D225-3C04-72F9-4C2C-1C3F3136FE58}.Release|x64.ActiveCfg = Release|x64
-		{B3B7D225-3C04-72F9-4C2C-1C3F3136FE58}.Debug|Win32.Build.0 = Debug|Win32
-		{B3B7D225-3C04-72F9-4C2C-1C3F3136FE58}.Debug|x64.Build.0 = Debug|x64
-		{B3B7D225-3C04-72F9-4C2C-1C3F3136FE58}.Release|Win32.Build.0 = Release|Win32
-		{B3B7D225-3C04-72F9-4C2C-1C3F3136FE58}.Release|x64.Build.0 = Release|x64
-		{B3B7D225-3C04-72F9-4C2C-1C3F3136FE58}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
-		{B3B7D225-3C04-72F9-4C2C-1C3F3136FE58}.Debug-DLL|Win32.Build.0 = Debug|Win32
-		{B3B7D225-3C04-72F9-4C2C-1C3F3136FE58}.Debug-DLL|x64.ActiveCfg = Debug|x64
-		{B3B7D225-3C04-72F9-4C2C-1C3F3136FE58}.Debug-DLL|x64.Build.0 = Debug|x64
-		{B3B7D225-3C04-72F9-4C2C-1C3F3136FE58}.Release-DLL|Win32.ActiveCfg = Release|Win32
-		{B3B7D225-3C04-72F9-4C2C-1C3F3136FE58}.Release-DLL|Win32.Build.0 = Release|Win32
-		{B3B7D225-3C04-72F9-4C2C-1C3F3136FE58}.Release-DLL|x64.ActiveCfg = Release|x64
-		{B3B7D225-3C04-72F9-4C2C-1C3F3136FE58}.Release-DLL|x64.Build.0 = Release|x64
-		{A9092608-E45E-AC96-6533-A6E7DD98211D}.Debug|Win32.ActiveCfg = Debug|Win32
-		{A9092608-E45E-AC96-6533-A6E7DD98211D}.Debug|x64.ActiveCfg = Debug|x64
-		{A9092608-E45E-AC96-6533-A6E7DD98211D}.Release|Win32.ActiveCfg = Release|Win32
-		{A9092608-E45E-AC96-6533-A6E7DD98211D}.Release|x64.ActiveCfg = Release|x64
-		{A9092608-E45E-AC96-6533-A6E7DD98211D}.Debug|Win32.Build.0 = Debug|Win32
-		{A9092608-E45E-AC96-6533-A6E7DD98211D}.Debug|x64.Build.0 = Debug|x64
-		{A9092608-E45E-AC96-6533-A6E7DD98211D}.Release|Win32.Build.0 = Release|Win32
-		{A9092608-E45E-AC96-6533-A6E7DD98211D}.Release|x64.Build.0 = Release|x64
-		{A9092608-E45E-AC96-6533-A6E7DD98211D}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
-		{A9092608-E45E-AC96-6533-A6E7DD98211D}.Debug-DLL|Win32.Build.0 = Debug|Win32
-		{A9092608-E45E-AC96-6533-A6E7DD98211D}.Debug-DLL|x64.ActiveCfg = Debug|x64
-		{A9092608-E45E-AC96-6533-A6E7DD98211D}.Debug-DLL|x64.Build.0 = Debug|x64
-		{A9092608-E45E-AC96-6533-A6E7DD98211D}.Release-DLL|Win32.ActiveCfg = Release|Win32
-		{A9092608-E45E-AC96-6533-A6E7DD98211D}.Release-DLL|Win32.Build.0 = Release|Win32
-		{A9092608-E45E-AC96-6533-A6E7DD98211D}.Release-DLL|x64.ActiveCfg = Release|x64
-		{A9092608-E45E-AC96-6533-A6E7DD98211D}.Release-DLL|x64.Build.0 = Release|x64
-		{A8039D43-910E-4248-2A22-74366E8C4DCD}.Debug|Win32.ActiveCfg = Debug|Win32
-		{A8039D43-910E-4248-2A22-74366E8C4DCD}.Debug|x64.ActiveCfg = Debug|x64
-		{A8039D43-910E-4248-2A22-74366E8C4DCD}.Release|Win32.ActiveCfg = Release|Win32
-		{A8039D43-910E-4248-2A22-74366E8C4DCD}.Release|x64.ActiveCfg = Release|x64
-		{A8039D43-910E-4248-2A22-74366E8C4DCD}.Debug|Win32.Build.0 = Debug|Win32
-		{A8039D43-910E-4248-2A22-74366E8C4DCD}.Debug|x64.Build.0 = Debug|x64
-		{A8039D43-910E-4248-2A22-74366E8C4DCD}.Release|Win32.Build.0 = Release|Win32
-		{A8039D43-910E-4248-2A22-74366E8C4DCD}.Release|x64.Build.0 = Release|x64
-		{A8039D43-910E-4248-2A22-74366E8C4DCD}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
-		{A8039D43-910E-4248-2A22-74366E8C4DCD}.Debug-DLL|Win32.Build.0 = Debug|Win32
-		{A8039D43-910E-4248-2A22-74366E8C4DCD}.Debug-DLL|x64.ActiveCfg = Debug|x64
-		{A8039D43-910E-4248-2A22-74366E8C4DCD}.Debug-DLL|x64.Build.0 = Debug|x64
-		{A8039D43-910E-4248-2A22-74366E8C4DCD}.Release-DLL|Win32.ActiveCfg = Release|Win32
-		{A8039D43-910E-4248-2A22-74366E8C4DCD}.Release-DLL|Win32.Build.0 = Release|Win32
-		{A8039D43-910E-4248-2A22-74366E8C4DCD}.Release-DLL|x64.ActiveCfg = Release|x64
-		{A8039D43-910E-4248-2A22-74366E8C4DCD}.Release-DLL|x64.Build.0 = Release|x64
-		{42826C1F-DCF0-918E-D247-0376DC1EFD50}.Debug|Win32.ActiveCfg = Debug|Win32
-		{42826C1F-DCF0-918E-D247-0376DC1EFD50}.Debug|x64.ActiveCfg = Debug|x64
-		{42826C1F-DCF0-918E-D247-0376DC1EFD50}.Release|Win32.ActiveCfg = Release|Win32
-		{42826C1F-DCF0-918E-D247-0376DC1EFD50}.Release|x64.ActiveCfg = Release|x64
-		{42826C1F-DCF0-918E-D247-0376DC1EFD50}.Debug|Win32.Build.0 = Debug|Win32
-		{42826C1F-DCF0-918E-D247-0376DC1EFD50}.Debug|x64.Build.0 = Debug|x64
-		{42826C1F-DCF0-918E-D247-0376DC1EFD50}.Release|Win32.Build.0 = Release|Win32
-		{42826C1F-DCF0-918E-D247-0376DC1EFD50}.Release|x64.Build.0 = Release|x64
-		{42826C1F-DCF0-918E-D247-0376DC1EFD50}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
-		{42826C1F-DCF0-918E-D247-0376DC1EFD50}.Debug-DLL|Win32.Build.0 = Debug|Win32
-		{42826C1F-DCF0-918E-D247-0376DC1EFD50}.Debug-DLL|x64.ActiveCfg = Debug|x64
-		{42826C1F-DCF0-918E-D247-0376DC1EFD50}.Debug-DLL|x64.Build.0 = Debug|x64
-		{42826C1F-DCF0-918E-D247-0376DC1EFD50}.Release-DLL|Win32.ActiveCfg = Release|Win32
-		{42826C1F-DCF0-918E-D247-0376DC1EFD50}.Release-DLL|Win32.Build.0 = Release|Win32
-		{42826C1F-DCF0-918E-D247-0376DC1EFD50}.Release-DLL|x64.ActiveCfg = Release|x64
-		{42826C1F-DCF0-918E-D247-0376DC1EFD50}.Release-DLL|x64.Build.0 = Release|x64
-		{345EA50E-BCD4-DAC7-E1C8-DDA6291B75E2}.Debug|Win32.ActiveCfg = Debug|Win32
-		{345EA50E-BCD4-DAC7-E1C8-DDA6291B75E2}.Debug|x64.ActiveCfg = Debug|x64
-		{345EA50E-BCD4-DAC7-E1C8-DDA6291B75E2}.Release|Win32.ActiveCfg = Release|Win32
-		{345EA50E-BCD4-DAC7-E1C8-DDA6291B75E2}.Release|x64.ActiveCfg = Release|x64
-		{345EA50E-BCD4-DAC7-E1C8-DDA6291B75E2}.Debug|Win32.Build.0 = Debug|Win32
-		{345EA50E-BCD4-DAC7-E1C8-DDA6291B75E2}.Debug|x64.Build.0 = Debug|x64
-		{345EA50E-BCD4-DAC7-E1C8-DDA6291B75E2}.Release|Win32.Build.0 = Release|Win32
-		{345EA50E-BCD4-DAC7-E1C8-DDA6291B75E2}.Release|x64.Build.0 = Release|x64
-		{345EA50E-BCD4-DAC7-E1C8-DDA6291B75E2}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
-		{345EA50E-BCD4-DAC7-E1C8-DDA6291B75E2}.Debug-DLL|Win32.Build.0 = Debug|Win32
-		{345EA50E-BCD4-DAC7-E1C8-DDA6291B75E2}.Debug-DLL|x64.ActiveCfg = Debug|x64
-		{345EA50E-BCD4-DAC7-E1C8-DDA6291B75E2}.Debug-DLL|x64.Build.0 = Debug|x64
-		{345EA50E-BCD4-DAC7-E1C8-DDA6291B75E2}.Release-DLL|Win32.ActiveCfg = Release|Win32
-		{345EA50E-BCD4-DAC7-E1C8-DDA6291B75E2}.Release-DLL|Win32.Build.0 = Release|Win32
-		{345EA50E-BCD4-DAC7-E1C8-DDA6291B75E2}.Release-DLL|x64.ActiveCfg = Release|x64
-		{345EA50E-BCD4-DAC7-E1C8-DDA6291B75E2}.Release-DLL|x64.Build.0 = Release|x64
-		{DFD51943-4906-8051-7D66-6A7D50E0D87E}.Debug|Win32.ActiveCfg = Debug|Win32
-		{DFD51943-4906-8051-7D66-6A7D50E0D87E}.Debug|x64.ActiveCfg = Debug|x64
-		{DFD51943-4906-8051-7D66-6A7D50E0D87E}.Release|Win32.ActiveCfg = Release|Win32
-		{DFD51943-4906-8051-7D66-6A7D50E0D87E}.Release|x64.ActiveCfg = Release|x64
-		{DFD51943-4906-8051-7D66-6A7D50E0D87E}.Debug|Win32.Build.0 = Debug|Win32
-		{DFD51943-4906-8051-7D66-6A7D50E0D87E}.Debug|x64.Build.0 = Debug|x64
-		{DFD51943-4906-8051-7D66-6A7D50E0D87E}.Release|Win32.Build.0 = Release|Win32
-		{DFD51943-4906-8051-7D66-6A7D50E0D87E}.Release|x64.Build.0 = Release|x64
-		{DFD51943-4906-8051-7D66-6A7D50E0D87E}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
-		{DFD51943-4906-8051-7D66-6A7D50E0D87E}.Debug-DLL|Win32.Build.0 = Debug|Win32
-		{DFD51943-4906-8051-7D66-6A7D50E0D87E}.Debug-DLL|x64.ActiveCfg = Debug|x64
-		{DFD51943-4906-8051-7D66-6A7D50E0D87E}.Debug-DLL|x64.Build.0 = Debug|x64
-		{DFD51943-4906-8051-7D66-6A7D50E0D87E}.Release-DLL|Win32.ActiveCfg = Release|Win32
-		{DFD51943-4906-8051-7D66-6A7D50E0D87E}.Release-DLL|Win32.Build.0 = Release|Win32
-		{DFD51943-4906-8051-7D66-6A7D50E0D87E}.Release-DLL|x64.ActiveCfg = Release|x64
-		{DFD51943-4906-8051-7D66-6A7D50E0D87E}.Release-DLL|x64.Build.0 = Release|x64
-		{6EC72045-98CB-8A8D-9788-BC94209E23C8}.Debug|Win32.ActiveCfg = Debug|Win32
-		{6EC72045-98CB-8A8D-9788-BC94209E23C8}.Debug|x64.ActiveCfg = Debug|x64
-		{6EC72045-98CB-8A8D-9788-BC94209E23C8}.Release|Win32.ActiveCfg = Release|Win32
-		{6EC72045-98CB-8A8D-9788-BC94209E23C8}.Release|x64.ActiveCfg = Release|x64
-		{6EC72045-98CB-8A8D-9788-BC94209E23C8}.Debug|Win32.Build.0 = Debug|Win32
-		{6EC72045-98CB-8A8D-9788-BC94209E23C8}.Debug|x64.Build.0 = Debug|x64
-		{6EC72045-98CB-8A8D-9788-BC94209E23C8}.Release|Win32.Build.0 = Release|Win32
-		{6EC72045-98CB-8A8D-9788-BC94209E23C8}.Release|x64.Build.0 = Release|x64
-		{6EC72045-98CB-8A8D-9788-BC94209E23C8}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
-		{6EC72045-98CB-8A8D-9788-BC94209E23C8}.Debug-DLL|Win32.Build.0 = Debug|Win32
-		{6EC72045-98CB-8A8D-9788-BC94209E23C8}.Debug-DLL|x64.ActiveCfg = Debug|x64
-		{6EC72045-98CB-8A8D-9788-BC94209E23C8}.Debug-DLL|x64.Build.0 = Debug|x64
-		{6EC72045-98CB-8A8D-9788-BC94209E23C8}.Release-DLL|Win32.ActiveCfg = Release|Win32
-		{6EC72045-98CB-8A8D-9788-BC94209E23C8}.Release-DLL|Win32.Build.0 = Release|Win32
-		{6EC72045-98CB-8A8D-9788-BC94209E23C8}.Release-DLL|x64.ActiveCfg = Release|x64
-		{6EC72045-98CB-8A8D-9788-BC94209E23C8}.Release-DLL|x64.Build.0 = Release|x64
-		{B3F26242-A43D-4F77-A84C-0F478741A061}.Debug|Win32.ActiveCfg = Debug|Win32
-		{B3F26242-A43D-4F77-A84C-0F478741A061}.Debug|x64.ActiveCfg = Debug|x64
-		{B3F26242-A43D-4F77-A84C-0F478741A061}.Release|Win32.ActiveCfg = Release|Win32
-		{B3F26242-A43D-4F77-A84C-0F478741A061}.Release|x64.ActiveCfg = Release|x64
-		{B3F26242-A43D-4F77-A84C-0F478741A061}.Debug|Win32.Build.0 = Debug|Win32
-		{B3F26242-A43D-4F77-A84C-0F478741A061}.Debug|x64.Build.0 = Debug|x64
-		{B3F26242-A43D-4F77-A84C-0F478741A061}.Release|Win32.Build.0 = Release|Win32
-		{B3F26242-A43D-4F77-A84C-0F478741A061}.Release|x64.Build.0 = Release|x64
-		{B3F26242-A43D-4F77-A84C-0F478741A061}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
-		{B3F26242-A43D-4F77-A84C-0F478741A061}.Debug-DLL|Win32.Build.0 = Debug|Win32
-		{B3F26242-A43D-4F77-A84C-0F478741A061}.Debug-DLL|x64.ActiveCfg = Debug|x64
-		{B3F26242-A43D-4F77-A84C-0F478741A061}.Debug-DLL|x64.Build.0 = Debug|x64
-		{B3F26242-A43D-4F77-A84C-0F478741A061}.Release-DLL|Win32.ActiveCfg = Release|Win32
-		{B3F26242-A43D-4F77-A84C-0F478741A061}.Release-DLL|Win32.Build.0 = Release|Win32
-		{B3F26242-A43D-4F77-A84C-0F478741A061}.Release-DLL|x64.ActiveCfg = Release|x64
-		{B3F26242-A43D-4F77-A84C-0F478741A061}.Release-DLL|x64.Build.0 = Release|x64
-		{962380E0-1C06-8917-8F7F-1A02E0E93BE7}.Debug|Win32.ActiveCfg = Debug|Win32
-		{962380E0-1C06-8917-8F7F-1A02E0E93BE7}.Debug|x64.ActiveCfg = Debug|x64
-		{962380E0-1C06-8917-8F7F-1A02E0E93BE7}.Release|Win32.ActiveCfg = Release|Win32
-		{962380E0-1C06-8917-8F7F-1A02E0E93BE7}.Release|x64.ActiveCfg = Release|x64
-		{962380E0-1C06-8917-8F7F-1A02E0E93BE7}.Debug|Win32.Build.0 = Debug|Win32
-		{962380E0-1C06-8917-8F7F-1A02E0E93BE7}.Debug|x64.Build.0 = Debug|x64
-		{962380E0-1C06-8917-8F7F-1A02E0E93BE7}.Release|Win32.Build.0 = Release|Win32
-		{962380E0-1C06-8917-8F7F-1A02E0E93BE7}.Release|x64.Build.0 = Release|x64
-		{962380E0-1C06-8917-8F7F-1A02E0E93BE7}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
-		{962380E0-1C06-8917-8F7F-1A02E0E93BE7}.Debug-DLL|Win32.Build.0 = Debug|Win32
-		{962380E0-1C06-8917-8F7F-1A02E0E93BE7}.Debug-DLL|x64.ActiveCfg = Debug|x64
-		{962380E0-1C06-8917-8F7F-1A02E0E93BE7}.Debug-DLL|x64.Build.0 = Debug|x64
-		{962380E0-1C06-8917-8F7F-1A02E0E93BE7}.Release-DLL|Win32.ActiveCfg = Release|Win32
-		{962380E0-1C06-8917-8F7F-1A02E0E93BE7}.Release-DLL|Win32.Build.0 = Release|Win32
-		{962380E0-1C06-8917-8F7F-1A02E0E93BE7}.Release-DLL|x64.ActiveCfg = Release|x64
-		{962380E0-1C06-8917-8F7F-1A02E0E93BE7}.Release-DLL|x64.Build.0 = Release|x64
-		{485E6713-487D-F274-BDE7-5D29300C93FE}.Debug|Win32.ActiveCfg = Debug|Win32
-		{485E6713-487D-F274-BDE7-5D29300C93FE}.Debug|x64.ActiveCfg = Debug|x64
-		{485E6713-487D-F274-BDE7-5D29300C93FE}.Release|Win32.ActiveCfg = Release|Win32
-		{485E6713-487D-F274-BDE7-5D29300C93FE}.Release|x64.ActiveCfg = Release|x64
-		{485E6713-487D-F274-BDE7-5D29300C93FE}.Debug|Win32.Build.0 = Debug|Win32
-		{485E6713-487D-F274-BDE7-5D29300C93FE}.Debug|x64.Build.0 = Debug|x64
-		{485E6713-487D-F274-BDE7-5D29300C93FE}.Release|Win32.Build.0 = Release|Win32
-		{485E6713-487D-F274-BDE7-5D29300C93FE}.Release|x64.Build.0 = Release|x64
-		{485E6713-487D-F274-BDE7-5D29300C93FE}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
-		{485E6713-487D-F274-BDE7-5D29300C93FE}.Debug-DLL|Win32.Build.0 = Debug|Win32
-		{485E6713-487D-F274-BDE7-5D29300C93FE}.Debug-DLL|x64.ActiveCfg = Debug|x64
-		{485E6713-487D-F274-BDE7-5D29300C93FE}.Debug-DLL|x64.Build.0 = Debug|x64
-		{485E6713-487D-F274-BDE7-5D29300C93FE}.Release-DLL|Win32.ActiveCfg = Release|Win32
-		{485E6713-487D-F274-BDE7-5D29300C93FE}.Release-DLL|Win32.Build.0 = Release|Win32
-		{485E6713-487D-F274-BDE7-5D29300C93FE}.Release-DLL|x64.ActiveCfg = Release|x64
-		{485E6713-487D-F274-BDE7-5D29300C93FE}.Release-DLL|x64.Build.0 = Release|x64
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE
diff --git a/vsprojects/coapp/openssl/libeay32.vcxproj b/vsprojects/coapp/openssl/libeay32.vcxproj
index ea63162..46ddbde 100644
--- a/vsprojects/coapp/openssl/libeay32.vcxproj
+++ b/vsprojects/coapp/openssl/libeay32.vcxproj
@@ -609,7 +609,7 @@
     <ClCompile Include="$(OpenSslPath)\crypto\dso\dso_err.c" />
     <ClCompile Include="$(OpenSslPath)\crypto\dso\dso_dlfcn.c" />
     <ClCompile Include="$(OpenSslPath)\crypto\dso\dso_lib.c" />
-    <ClCompile Include="$(OpenSslPath)\crypto\dso\dso_win32.c" />
+    <ClCompile Include="$(OpenSslPath)\crypto\dso\dso_windows.c" />
     <ClCompile Include="$(OpenSslPath)\crypto\stack\stack.c" />
     <ClCompile Include="$(OpenSslPath)\crypto\md4\md4_dgst.c" />
     <ClCompile Include="$(OpenSslPath)\crypto\md4\md4_one.c" />
diff --git a/vsprojects/grpc.sln b/vsprojects/grpc.sln
index 029c9ed..a43daaf 100644
--- a/vsprojects/grpc.sln
+++ b/vsprojects/grpc.sln
@@ -3,6 +3,25 @@
 # Visual Studio 2013
 VisualStudioVersion = 12.0.21005.1
 MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "boringssl", "vcxproj\.\boringssl\boringssl.vcxproj", "{9FD9A3EF-C4A3-8390-D8F4-6F86C22A58CE}"
+	ProjectSection(myProperties) = preProject
+        	lib = "True"
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gen_hpack_tables", "vcxproj\.\gen_hpack_tables\gen_hpack_tables.vcxproj", "{FCDEA4C7-7F26-05DB-D08F-A08F499026E6}"
+	ProjectSection(myProperties) = preProject
+        	lib = "False"
+	EndProjectSection
+	ProjectSection(ProjectDependencies) = postProject
+		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
+		{29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gen_legal_metadata_characters", "vcxproj\.\gen_legal_metadata_characters\gen_legal_metadata_characters.vcxproj", "{A635DE99-B131-CA00-2D3B-8691D60B76C2}"
+	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"
@@ -24,6 +43,43 @@
 		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
 	EndProjectSection
 EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "grpc++", "vcxproj\.\grpc++\grpc++.vcxproj", "{C187A093-A0FE-489D-A40A-6E33DE0F9FEB}"
+	ProjectSection(myProperties) = preProject
+        	lib = "True"
+	EndProjectSection
+	ProjectSection(ProjectDependencies) = postProject
+		{29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "grpc++_reflection", "vcxproj\.\grpc++_reflection\grpc++_reflection.vcxproj", "{5F575402-3F89-5D1A-6910-9DB8BF5D2BAB}"
+	ProjectSection(myProperties) = preProject
+        	lib = "True"
+	EndProjectSection
+	ProjectSection(ProjectDependencies) = postProject
+		{C187A093-A0FE-489D-A40A-6E33DE0F9FEB} = {C187A093-A0FE-489D-A40A-6E33DE0F9FEB}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "grpc++_unsecure", "vcxproj\.\grpc++_unsecure\grpc++_unsecure.vcxproj", "{6EE56155-DF7C-4F6E-BFC4-F6F776BEB211}"
+	ProjectSection(myProperties) = preProject
+        	lib = "True"
+	EndProjectSection
+	ProjectSection(ProjectDependencies) = postProject
+		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
+		{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5} = {46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}
+		{29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "grpc_create_jwt", "vcxproj\.\grpc_create_jwt\grpc_create_jwt.vcxproj", "{77971F8D-F583-3E77-0E3C-6C1FB6B1749C}"
+	ProjectSection(myProperties) = preProject
+        	lib = "False"
+	EndProjectSection
+	ProjectSection(ProjectDependencies) = postProject
+		{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B} = {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}
+		{29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9}
+		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
+		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
+	EndProjectSection
+EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "grpc_dll", "vcxproj\.\grpc_dll\grpc_dll.vcxproj", "{A2F6CBBA-A553-41B3-A7DE-F26DECCC27F0}"
 	ProjectSection(myProperties) = preProject
         	lib = "True"
@@ -33,6 +89,28 @@
 		{29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9}
 	EndProjectSection
 EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "grpc_fetch_oauth2", "vcxproj\.\grpc_fetch_oauth2\grpc_fetch_oauth2.vcxproj", "{43722E98-54EC-5058-3DAC-327F45964971}"
+	ProjectSection(myProperties) = preProject
+        	lib = "False"
+	EndProjectSection
+	ProjectSection(ProjectDependencies) = postProject
+		{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B} = {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}
+		{29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9}
+		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
+		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "grpc_print_google_default_creds_token", "vcxproj\.\grpc_print_google_default_creds_token\grpc_print_google_default_creds_token.vcxproj", "{C002965C-8457-CCE5-B1BA-E748FF9A11B6}"
+	ProjectSection(myProperties) = preProject
+        	lib = "False"
+	EndProjectSection
+	ProjectSection(ProjectDependencies) = postProject
+		{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B} = {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}
+		{29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9}
+		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
+		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
+	EndProjectSection
+EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "grpc_test_util", "vcxproj\.\grpc_test_util\grpc_test_util.vcxproj", "{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}"
 	ProjectSection(myProperties) = preProject
         	lib = "True"
@@ -62,6 +140,17 @@
 		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
 	EndProjectSection
 EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "grpc_verify_jwt", "vcxproj\.\grpc_verify_jwt\grpc_verify_jwt.vcxproj", "{02FAC25F-5FF6-34A0-00AE-B82BFBA851A9}"
+	ProjectSection(myProperties) = preProject
+        	lib = "False"
+	EndProjectSection
+	ProjectSection(ProjectDependencies) = postProject
+		{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B} = {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}
+		{29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9}
+		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
+		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
+	EndProjectSection
+EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "reconnect_server", "vcxproj\.\reconnect_server\reconnect_server.vcxproj", "{929C90AE-483F-AC80-EF93-226199F9E428}"
 	ProjectSection(myProperties) = preProject
         	lib = "True"
@@ -85,92 +174,11 @@
 		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
 	EndProjectSection
 EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "grpc++", "vcxproj\.\grpc++\grpc++.vcxproj", "{C187A093-A0FE-489D-A40A-6E33DE0F9FEB}"
-	ProjectSection(myProperties) = preProject
-        	lib = "True"
-	EndProjectSection
-	ProjectSection(ProjectDependencies) = postProject
-		{29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9}
-	EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "grpc++_unsecure", "vcxproj\.\grpc++_unsecure\grpc++_unsecure.vcxproj", "{6EE56155-DF7C-4F6E-BFC4-F6F776BEB211}"
-	ProjectSection(myProperties) = preProject
-        	lib = "True"
-	EndProjectSection
-	ProjectSection(ProjectDependencies) = postProject
-		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
-		{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5} = {46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}
-		{29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9}
-	EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "boringssl", "vcxproj\.\boringssl\boringssl.vcxproj", "{9FD9A3EF-C4A3-8390-D8F4-6F86C22A58CE}"
-	ProjectSection(myProperties) = preProject
-        	lib = "True"
-	EndProjectSection
-EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "z", "vcxproj\.\z\z.vcxproj", "{FBADE9E3-6A3F-36D3-D676-C1B808451DD7}"
 	ProjectSection(myProperties) = preProject
         	lib = "True"
 	EndProjectSection
 EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gen_hpack_tables", "vcxproj\.\gen_hpack_tables\gen_hpack_tables.vcxproj", "{FCDEA4C7-7F26-05DB-D08F-A08F499026E6}"
-	ProjectSection(myProperties) = preProject
-        	lib = "False"
-	EndProjectSection
-	ProjectSection(ProjectDependencies) = postProject
-		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
-		{29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9}
-	EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gen_legal_metadata_characters", "vcxproj\.\gen_legal_metadata_characters\gen_legal_metadata_characters.vcxproj", "{A635DE99-B131-CA00-2D3B-8691D60B76C2}"
-	ProjectSection(myProperties) = preProject
-        	lib = "False"
-	EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "grpc_create_jwt", "vcxproj\.\grpc_create_jwt\grpc_create_jwt.vcxproj", "{77971F8D-F583-3E77-0E3C-6C1FB6B1749C}"
-	ProjectSection(myProperties) = preProject
-        	lib = "False"
-	EndProjectSection
-	ProjectSection(ProjectDependencies) = postProject
-		{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B} = {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}
-		{29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9}
-		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
-		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
-	EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "grpc_fetch_oauth2", "vcxproj\.\grpc_fetch_oauth2\grpc_fetch_oauth2.vcxproj", "{43722E98-54EC-5058-3DAC-327F45964971}"
-	ProjectSection(myProperties) = preProject
-        	lib = "False"
-	EndProjectSection
-	ProjectSection(ProjectDependencies) = postProject
-		{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B} = {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}
-		{29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9}
-		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
-		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
-	EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "grpc_print_google_default_creds_token", "vcxproj\.\grpc_print_google_default_creds_token\grpc_print_google_default_creds_token.vcxproj", "{C002965C-8457-CCE5-B1BA-E748FF9A11B6}"
-	ProjectSection(myProperties) = preProject
-        	lib = "False"
-	EndProjectSection
-	ProjectSection(ProjectDependencies) = postProject
-		{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B} = {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}
-		{29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9}
-		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
-		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
-	EndProjectSection
-EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "grpc_verify_jwt", "vcxproj\.\grpc_verify_jwt\grpc_verify_jwt.vcxproj", "{02FAC25F-5FF6-34A0-00AE-B82BFBA851A9}"
-	ProjectSection(myProperties) = preProject
-        	lib = "False"
-	EndProjectSection
-	ProjectSection(ProjectDependencies) = postProject
-		{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B} = {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}
-		{29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9}
-		{EAB0A629-17A9-44DB-B5FF-E91A721FE037} = {EAB0A629-17A9-44DB-B5FF-E91A721FE037}
-		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
-	EndProjectSection
-EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|Win32 = Debug|Win32
@@ -183,6 +191,54 @@
 		Release-DLL|x64 = Release-DLL|x64
 	EndGlobalSection
 	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{9FD9A3EF-C4A3-8390-D8F4-6F86C22A58CE}.Debug|Win32.ActiveCfg = Debug|Win32
+		{9FD9A3EF-C4A3-8390-D8F4-6F86C22A58CE}.Debug|x64.ActiveCfg = Debug|x64
+		{9FD9A3EF-C4A3-8390-D8F4-6F86C22A58CE}.Release|Win32.ActiveCfg = Release|Win32
+		{9FD9A3EF-C4A3-8390-D8F4-6F86C22A58CE}.Release|x64.ActiveCfg = Release|x64
+		{9FD9A3EF-C4A3-8390-D8F4-6F86C22A58CE}.Debug|Win32.Build.0 = Debug|Win32
+		{9FD9A3EF-C4A3-8390-D8F4-6F86C22A58CE}.Debug|x64.Build.0 = Debug|x64
+		{9FD9A3EF-C4A3-8390-D8F4-6F86C22A58CE}.Release|Win32.Build.0 = Release|Win32
+		{9FD9A3EF-C4A3-8390-D8F4-6F86C22A58CE}.Release|x64.Build.0 = Release|x64
+		{9FD9A3EF-C4A3-8390-D8F4-6F86C22A58CE}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
+		{9FD9A3EF-C4A3-8390-D8F4-6F86C22A58CE}.Debug-DLL|Win32.Build.0 = Debug|Win32
+		{9FD9A3EF-C4A3-8390-D8F4-6F86C22A58CE}.Debug-DLL|x64.ActiveCfg = Debug|x64
+		{9FD9A3EF-C4A3-8390-D8F4-6F86C22A58CE}.Debug-DLL|x64.Build.0 = Debug|x64
+		{9FD9A3EF-C4A3-8390-D8F4-6F86C22A58CE}.Release-DLL|Win32.ActiveCfg = Release|Win32
+		{9FD9A3EF-C4A3-8390-D8F4-6F86C22A58CE}.Release-DLL|Win32.Build.0 = Release|Win32
+		{9FD9A3EF-C4A3-8390-D8F4-6F86C22A58CE}.Release-DLL|x64.ActiveCfg = Release|x64
+		{9FD9A3EF-C4A3-8390-D8F4-6F86C22A58CE}.Release-DLL|x64.Build.0 = Release|x64
+		{FCDEA4C7-7F26-05DB-D08F-A08F499026E6}.Debug|Win32.ActiveCfg = Debug|Win32
+		{FCDEA4C7-7F26-05DB-D08F-A08F499026E6}.Debug|x64.ActiveCfg = Debug|x64
+		{FCDEA4C7-7F26-05DB-D08F-A08F499026E6}.Release|Win32.ActiveCfg = Release|Win32
+		{FCDEA4C7-7F26-05DB-D08F-A08F499026E6}.Release|x64.ActiveCfg = Release|x64
+		{FCDEA4C7-7F26-05DB-D08F-A08F499026E6}.Debug|Win32.Build.0 = Debug|Win32
+		{FCDEA4C7-7F26-05DB-D08F-A08F499026E6}.Debug|x64.Build.0 = Debug|x64
+		{FCDEA4C7-7F26-05DB-D08F-A08F499026E6}.Release|Win32.Build.0 = Release|Win32
+		{FCDEA4C7-7F26-05DB-D08F-A08F499026E6}.Release|x64.Build.0 = Release|x64
+		{FCDEA4C7-7F26-05DB-D08F-A08F499026E6}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
+		{FCDEA4C7-7F26-05DB-D08F-A08F499026E6}.Debug-DLL|Win32.Build.0 = Debug|Win32
+		{FCDEA4C7-7F26-05DB-D08F-A08F499026E6}.Debug-DLL|x64.ActiveCfg = Debug|x64
+		{FCDEA4C7-7F26-05DB-D08F-A08F499026E6}.Debug-DLL|x64.Build.0 = Debug|x64
+		{FCDEA4C7-7F26-05DB-D08F-A08F499026E6}.Release-DLL|Win32.ActiveCfg = Release|Win32
+		{FCDEA4C7-7F26-05DB-D08F-A08F499026E6}.Release-DLL|Win32.Build.0 = Release|Win32
+		{FCDEA4C7-7F26-05DB-D08F-A08F499026E6}.Release-DLL|x64.ActiveCfg = Release|x64
+		{FCDEA4C7-7F26-05DB-D08F-A08F499026E6}.Release-DLL|x64.Build.0 = Release|x64
+		{A635DE99-B131-CA00-2D3B-8691D60B76C2}.Debug|Win32.ActiveCfg = Debug|Win32
+		{A635DE99-B131-CA00-2D3B-8691D60B76C2}.Debug|x64.ActiveCfg = Debug|x64
+		{A635DE99-B131-CA00-2D3B-8691D60B76C2}.Release|Win32.ActiveCfg = Release|Win32
+		{A635DE99-B131-CA00-2D3B-8691D60B76C2}.Release|x64.ActiveCfg = Release|x64
+		{A635DE99-B131-CA00-2D3B-8691D60B76C2}.Debug|Win32.Build.0 = Debug|Win32
+		{A635DE99-B131-CA00-2D3B-8691D60B76C2}.Debug|x64.Build.0 = Debug|x64
+		{A635DE99-B131-CA00-2D3B-8691D60B76C2}.Release|Win32.Build.0 = Release|Win32
+		{A635DE99-B131-CA00-2D3B-8691D60B76C2}.Release|x64.Build.0 = Release|x64
+		{A635DE99-B131-CA00-2D3B-8691D60B76C2}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
+		{A635DE99-B131-CA00-2D3B-8691D60B76C2}.Debug-DLL|Win32.Build.0 = Debug|Win32
+		{A635DE99-B131-CA00-2D3B-8691D60B76C2}.Debug-DLL|x64.ActiveCfg = Debug|x64
+		{A635DE99-B131-CA00-2D3B-8691D60B76C2}.Debug-DLL|x64.Build.0 = Debug|x64
+		{A635DE99-B131-CA00-2D3B-8691D60B76C2}.Release-DLL|Win32.ActiveCfg = Release|Win32
+		{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
 		{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
@@ -231,6 +287,70 @@
 		{29D16885-7228-4C31-81ED-5F9187C7F2A9}.Release-DLL|Win32.Build.0 = Release-DLL|Win32
 		{29D16885-7228-4C31-81ED-5F9187C7F2A9}.Release-DLL|x64.ActiveCfg = Release-DLL|x64
 		{29D16885-7228-4C31-81ED-5F9187C7F2A9}.Release-DLL|x64.Build.0 = Release-DLL|x64
+		{C187A093-A0FE-489D-A40A-6E33DE0F9FEB}.Debug|Win32.ActiveCfg = Debug|Win32
+		{C187A093-A0FE-489D-A40A-6E33DE0F9FEB}.Debug|x64.ActiveCfg = Debug|x64
+		{C187A093-A0FE-489D-A40A-6E33DE0F9FEB}.Release|Win32.ActiveCfg = Release|Win32
+		{C187A093-A0FE-489D-A40A-6E33DE0F9FEB}.Release|x64.ActiveCfg = Release|x64
+		{C187A093-A0FE-489D-A40A-6E33DE0F9FEB}.Debug|Win32.Build.0 = Debug|Win32
+		{C187A093-A0FE-489D-A40A-6E33DE0F9FEB}.Debug|x64.Build.0 = Debug|x64
+		{C187A093-A0FE-489D-A40A-6E33DE0F9FEB}.Release|Win32.Build.0 = Release|Win32
+		{C187A093-A0FE-489D-A40A-6E33DE0F9FEB}.Release|x64.Build.0 = Release|x64
+		{C187A093-A0FE-489D-A40A-6E33DE0F9FEB}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32
+		{C187A093-A0FE-489D-A40A-6E33DE0F9FEB}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32
+		{C187A093-A0FE-489D-A40A-6E33DE0F9FEB}.Debug-DLL|x64.ActiveCfg = Debug-DLL|x64
+		{C187A093-A0FE-489D-A40A-6E33DE0F9FEB}.Debug-DLL|x64.Build.0 = Debug-DLL|x64
+		{C187A093-A0FE-489D-A40A-6E33DE0F9FEB}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32
+		{C187A093-A0FE-489D-A40A-6E33DE0F9FEB}.Release-DLL|Win32.Build.0 = Release-DLL|Win32
+		{C187A093-A0FE-489D-A40A-6E33DE0F9FEB}.Release-DLL|x64.ActiveCfg = Release-DLL|x64
+		{C187A093-A0FE-489D-A40A-6E33DE0F9FEB}.Release-DLL|x64.Build.0 = Release-DLL|x64
+		{5F575402-3F89-5D1A-6910-9DB8BF5D2BAB}.Debug|Win32.ActiveCfg = Debug|Win32
+		{5F575402-3F89-5D1A-6910-9DB8BF5D2BAB}.Debug|x64.ActiveCfg = Debug|x64
+		{5F575402-3F89-5D1A-6910-9DB8BF5D2BAB}.Release|Win32.ActiveCfg = Release|Win32
+		{5F575402-3F89-5D1A-6910-9DB8BF5D2BAB}.Release|x64.ActiveCfg = Release|x64
+		{5F575402-3F89-5D1A-6910-9DB8BF5D2BAB}.Debug|Win32.Build.0 = Debug|Win32
+		{5F575402-3F89-5D1A-6910-9DB8BF5D2BAB}.Debug|x64.Build.0 = Debug|x64
+		{5F575402-3F89-5D1A-6910-9DB8BF5D2BAB}.Release|Win32.Build.0 = Release|Win32
+		{5F575402-3F89-5D1A-6910-9DB8BF5D2BAB}.Release|x64.Build.0 = Release|x64
+		{5F575402-3F89-5D1A-6910-9DB8BF5D2BAB}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
+		{5F575402-3F89-5D1A-6910-9DB8BF5D2BAB}.Debug-DLL|Win32.Build.0 = Debug|Win32
+		{5F575402-3F89-5D1A-6910-9DB8BF5D2BAB}.Debug-DLL|x64.ActiveCfg = Debug|x64
+		{5F575402-3F89-5D1A-6910-9DB8BF5D2BAB}.Debug-DLL|x64.Build.0 = Debug|x64
+		{5F575402-3F89-5D1A-6910-9DB8BF5D2BAB}.Release-DLL|Win32.ActiveCfg = Release|Win32
+		{5F575402-3F89-5D1A-6910-9DB8BF5D2BAB}.Release-DLL|Win32.Build.0 = Release|Win32
+		{5F575402-3F89-5D1A-6910-9DB8BF5D2BAB}.Release-DLL|x64.ActiveCfg = Release|x64
+		{5F575402-3F89-5D1A-6910-9DB8BF5D2BAB}.Release-DLL|x64.Build.0 = Release|x64
+		{6EE56155-DF7C-4F6E-BFC4-F6F776BEB211}.Debug|Win32.ActiveCfg = Debug|Win32
+		{6EE56155-DF7C-4F6E-BFC4-F6F776BEB211}.Debug|x64.ActiveCfg = Debug|x64
+		{6EE56155-DF7C-4F6E-BFC4-F6F776BEB211}.Release|Win32.ActiveCfg = Release|Win32
+		{6EE56155-DF7C-4F6E-BFC4-F6F776BEB211}.Release|x64.ActiveCfg = Release|x64
+		{6EE56155-DF7C-4F6E-BFC4-F6F776BEB211}.Debug|Win32.Build.0 = Debug|Win32
+		{6EE56155-DF7C-4F6E-BFC4-F6F776BEB211}.Debug|x64.Build.0 = Debug|x64
+		{6EE56155-DF7C-4F6E-BFC4-F6F776BEB211}.Release|Win32.Build.0 = Release|Win32
+		{6EE56155-DF7C-4F6E-BFC4-F6F776BEB211}.Release|x64.Build.0 = Release|x64
+		{6EE56155-DF7C-4F6E-BFC4-F6F776BEB211}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32
+		{6EE56155-DF7C-4F6E-BFC4-F6F776BEB211}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32
+		{6EE56155-DF7C-4F6E-BFC4-F6F776BEB211}.Debug-DLL|x64.ActiveCfg = Debug-DLL|x64
+		{6EE56155-DF7C-4F6E-BFC4-F6F776BEB211}.Debug-DLL|x64.Build.0 = Debug-DLL|x64
+		{6EE56155-DF7C-4F6E-BFC4-F6F776BEB211}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32
+		{6EE56155-DF7C-4F6E-BFC4-F6F776BEB211}.Release-DLL|Win32.Build.0 = Release-DLL|Win32
+		{6EE56155-DF7C-4F6E-BFC4-F6F776BEB211}.Release-DLL|x64.ActiveCfg = Release-DLL|x64
+		{6EE56155-DF7C-4F6E-BFC4-F6F776BEB211}.Release-DLL|x64.Build.0 = Release-DLL|x64
+		{77971F8D-F583-3E77-0E3C-6C1FB6B1749C}.Debug|Win32.ActiveCfg = Debug|Win32
+		{77971F8D-F583-3E77-0E3C-6C1FB6B1749C}.Debug|x64.ActiveCfg = Debug|x64
+		{77971F8D-F583-3E77-0E3C-6C1FB6B1749C}.Release|Win32.ActiveCfg = Release|Win32
+		{77971F8D-F583-3E77-0E3C-6C1FB6B1749C}.Release|x64.ActiveCfg = Release|x64
+		{77971F8D-F583-3E77-0E3C-6C1FB6B1749C}.Debug|Win32.Build.0 = Debug|Win32
+		{77971F8D-F583-3E77-0E3C-6C1FB6B1749C}.Debug|x64.Build.0 = Debug|x64
+		{77971F8D-F583-3E77-0E3C-6C1FB6B1749C}.Release|Win32.Build.0 = Release|Win32
+		{77971F8D-F583-3E77-0E3C-6C1FB6B1749C}.Release|x64.Build.0 = Release|x64
+		{77971F8D-F583-3E77-0E3C-6C1FB6B1749C}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
+		{77971F8D-F583-3E77-0E3C-6C1FB6B1749C}.Debug-DLL|Win32.Build.0 = Debug|Win32
+		{77971F8D-F583-3E77-0E3C-6C1FB6B1749C}.Debug-DLL|x64.ActiveCfg = Debug|x64
+		{77971F8D-F583-3E77-0E3C-6C1FB6B1749C}.Debug-DLL|x64.Build.0 = Debug|x64
+		{77971F8D-F583-3E77-0E3C-6C1FB6B1749C}.Release-DLL|Win32.ActiveCfg = Release|Win32
+		{77971F8D-F583-3E77-0E3C-6C1FB6B1749C}.Release-DLL|Win32.Build.0 = Release|Win32
+		{77971F8D-F583-3E77-0E3C-6C1FB6B1749C}.Release-DLL|x64.ActiveCfg = Release|x64
+		{77971F8D-F583-3E77-0E3C-6C1FB6B1749C}.Release-DLL|x64.Build.0 = Release|x64
 		{A2F6CBBA-A553-41B3-A7DE-F26DECCC27F0}.Debug|Win32.ActiveCfg = Debug|Win32
 		{A2F6CBBA-A553-41B3-A7DE-F26DECCC27F0}.Debug|x64.ActiveCfg = Debug|x64
 		{A2F6CBBA-A553-41B3-A7DE-F26DECCC27F0}.Release|Win32.ActiveCfg = Release|Win32
@@ -247,6 +367,38 @@
 		{A2F6CBBA-A553-41B3-A7DE-F26DECCC27F0}.Release-DLL|Win32.Build.0 = Release|Win32
 		{A2F6CBBA-A553-41B3-A7DE-F26DECCC27F0}.Release-DLL|x64.ActiveCfg = Release|x64
 		{A2F6CBBA-A553-41B3-A7DE-F26DECCC27F0}.Release-DLL|x64.Build.0 = Release|x64
+		{43722E98-54EC-5058-3DAC-327F45964971}.Debug|Win32.ActiveCfg = Debug|Win32
+		{43722E98-54EC-5058-3DAC-327F45964971}.Debug|x64.ActiveCfg = Debug|x64
+		{43722E98-54EC-5058-3DAC-327F45964971}.Release|Win32.ActiveCfg = Release|Win32
+		{43722E98-54EC-5058-3DAC-327F45964971}.Release|x64.ActiveCfg = Release|x64
+		{43722E98-54EC-5058-3DAC-327F45964971}.Debug|Win32.Build.0 = Debug|Win32
+		{43722E98-54EC-5058-3DAC-327F45964971}.Debug|x64.Build.0 = Debug|x64
+		{43722E98-54EC-5058-3DAC-327F45964971}.Release|Win32.Build.0 = Release|Win32
+		{43722E98-54EC-5058-3DAC-327F45964971}.Release|x64.Build.0 = Release|x64
+		{43722E98-54EC-5058-3DAC-327F45964971}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
+		{43722E98-54EC-5058-3DAC-327F45964971}.Debug-DLL|Win32.Build.0 = Debug|Win32
+		{43722E98-54EC-5058-3DAC-327F45964971}.Debug-DLL|x64.ActiveCfg = Debug|x64
+		{43722E98-54EC-5058-3DAC-327F45964971}.Debug-DLL|x64.Build.0 = Debug|x64
+		{43722E98-54EC-5058-3DAC-327F45964971}.Release-DLL|Win32.ActiveCfg = Release|Win32
+		{43722E98-54EC-5058-3DAC-327F45964971}.Release-DLL|Win32.Build.0 = Release|Win32
+		{43722E98-54EC-5058-3DAC-327F45964971}.Release-DLL|x64.ActiveCfg = Release|x64
+		{43722E98-54EC-5058-3DAC-327F45964971}.Release-DLL|x64.Build.0 = Release|x64
+		{C002965C-8457-CCE5-B1BA-E748FF9A11B6}.Debug|Win32.ActiveCfg = Debug|Win32
+		{C002965C-8457-CCE5-B1BA-E748FF9A11B6}.Debug|x64.ActiveCfg = Debug|x64
+		{C002965C-8457-CCE5-B1BA-E748FF9A11B6}.Release|Win32.ActiveCfg = Release|Win32
+		{C002965C-8457-CCE5-B1BA-E748FF9A11B6}.Release|x64.ActiveCfg = Release|x64
+		{C002965C-8457-CCE5-B1BA-E748FF9A11B6}.Debug|Win32.Build.0 = Debug|Win32
+		{C002965C-8457-CCE5-B1BA-E748FF9A11B6}.Debug|x64.Build.0 = Debug|x64
+		{C002965C-8457-CCE5-B1BA-E748FF9A11B6}.Release|Win32.Build.0 = Release|Win32
+		{C002965C-8457-CCE5-B1BA-E748FF9A11B6}.Release|x64.Build.0 = Release|x64
+		{C002965C-8457-CCE5-B1BA-E748FF9A11B6}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
+		{C002965C-8457-CCE5-B1BA-E748FF9A11B6}.Debug-DLL|Win32.Build.0 = Debug|Win32
+		{C002965C-8457-CCE5-B1BA-E748FF9A11B6}.Debug-DLL|x64.ActiveCfg = Debug|x64
+		{C002965C-8457-CCE5-B1BA-E748FF9A11B6}.Debug-DLL|x64.Build.0 = Debug|x64
+		{C002965C-8457-CCE5-B1BA-E748FF9A11B6}.Release-DLL|Win32.ActiveCfg = Release|Win32
+		{C002965C-8457-CCE5-B1BA-E748FF9A11B6}.Release-DLL|Win32.Build.0 = Release|Win32
+		{C002965C-8457-CCE5-B1BA-E748FF9A11B6}.Release-DLL|x64.ActiveCfg = Release|x64
+		{C002965C-8457-CCE5-B1BA-E748FF9A11B6}.Release-DLL|x64.Build.0 = Release|x64
 		{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}.Debug|Win32.ActiveCfg = Debug|Win32
 		{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}.Debug|x64.ActiveCfg = Debug|x64
 		{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}.Release|Win32.ActiveCfg = Release|Win32
@@ -295,6 +447,22 @@
 		{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}.Release-DLL|Win32.Build.0 = Release-DLL|Win32
 		{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}.Release-DLL|x64.ActiveCfg = Release-DLL|x64
 		{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}.Release-DLL|x64.Build.0 = Release-DLL|x64
+		{02FAC25F-5FF6-34A0-00AE-B82BFBA851A9}.Debug|Win32.ActiveCfg = Debug|Win32
+		{02FAC25F-5FF6-34A0-00AE-B82BFBA851A9}.Debug|x64.ActiveCfg = Debug|x64
+		{02FAC25F-5FF6-34A0-00AE-B82BFBA851A9}.Release|Win32.ActiveCfg = Release|Win32
+		{02FAC25F-5FF6-34A0-00AE-B82BFBA851A9}.Release|x64.ActiveCfg = Release|x64
+		{02FAC25F-5FF6-34A0-00AE-B82BFBA851A9}.Debug|Win32.Build.0 = Debug|Win32
+		{02FAC25F-5FF6-34A0-00AE-B82BFBA851A9}.Debug|x64.Build.0 = Debug|x64
+		{02FAC25F-5FF6-34A0-00AE-B82BFBA851A9}.Release|Win32.Build.0 = Release|Win32
+		{02FAC25F-5FF6-34A0-00AE-B82BFBA851A9}.Release|x64.Build.0 = Release|x64
+		{02FAC25F-5FF6-34A0-00AE-B82BFBA851A9}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
+		{02FAC25F-5FF6-34A0-00AE-B82BFBA851A9}.Debug-DLL|Win32.Build.0 = Debug|Win32
+		{02FAC25F-5FF6-34A0-00AE-B82BFBA851A9}.Debug-DLL|x64.ActiveCfg = Debug|x64
+		{02FAC25F-5FF6-34A0-00AE-B82BFBA851A9}.Debug-DLL|x64.Build.0 = Debug|x64
+		{02FAC25F-5FF6-34A0-00AE-B82BFBA851A9}.Release-DLL|Win32.ActiveCfg = Release|Win32
+		{02FAC25F-5FF6-34A0-00AE-B82BFBA851A9}.Release-DLL|Win32.Build.0 = Release|Win32
+		{02FAC25F-5FF6-34A0-00AE-B82BFBA851A9}.Release-DLL|x64.ActiveCfg = Release|x64
+		{02FAC25F-5FF6-34A0-00AE-B82BFBA851A9}.Release-DLL|x64.Build.0 = Release|x64
 		{929C90AE-483F-AC80-EF93-226199F9E428}.Debug|Win32.ActiveCfg = Debug|Win32
 		{929C90AE-483F-AC80-EF93-226199F9E428}.Debug|x64.ActiveCfg = Debug|x64
 		{929C90AE-483F-AC80-EF93-226199F9E428}.Release|Win32.ActiveCfg = Release|Win32
@@ -327,54 +495,6 @@
 		{E3110C46-A148-FF65-08FD-3324829BE7FE}.Release-DLL|Win32.Build.0 = Release|Win32
 		{E3110C46-A148-FF65-08FD-3324829BE7FE}.Release-DLL|x64.ActiveCfg = Release|x64
 		{E3110C46-A148-FF65-08FD-3324829BE7FE}.Release-DLL|x64.Build.0 = Release|x64
-		{C187A093-A0FE-489D-A40A-6E33DE0F9FEB}.Debug|Win32.ActiveCfg = Debug|Win32
-		{C187A093-A0FE-489D-A40A-6E33DE0F9FEB}.Debug|x64.ActiveCfg = Debug|x64
-		{C187A093-A0FE-489D-A40A-6E33DE0F9FEB}.Release|Win32.ActiveCfg = Release|Win32
-		{C187A093-A0FE-489D-A40A-6E33DE0F9FEB}.Release|x64.ActiveCfg = Release|x64
-		{C187A093-A0FE-489D-A40A-6E33DE0F9FEB}.Debug|Win32.Build.0 = Debug|Win32
-		{C187A093-A0FE-489D-A40A-6E33DE0F9FEB}.Debug|x64.Build.0 = Debug|x64
-		{C187A093-A0FE-489D-A40A-6E33DE0F9FEB}.Release|Win32.Build.0 = Release|Win32
-		{C187A093-A0FE-489D-A40A-6E33DE0F9FEB}.Release|x64.Build.0 = Release|x64
-		{C187A093-A0FE-489D-A40A-6E33DE0F9FEB}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32
-		{C187A093-A0FE-489D-A40A-6E33DE0F9FEB}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32
-		{C187A093-A0FE-489D-A40A-6E33DE0F9FEB}.Debug-DLL|x64.ActiveCfg = Debug-DLL|x64
-		{C187A093-A0FE-489D-A40A-6E33DE0F9FEB}.Debug-DLL|x64.Build.0 = Debug-DLL|x64
-		{C187A093-A0FE-489D-A40A-6E33DE0F9FEB}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32
-		{C187A093-A0FE-489D-A40A-6E33DE0F9FEB}.Release-DLL|Win32.Build.0 = Release-DLL|Win32
-		{C187A093-A0FE-489D-A40A-6E33DE0F9FEB}.Release-DLL|x64.ActiveCfg = Release-DLL|x64
-		{C187A093-A0FE-489D-A40A-6E33DE0F9FEB}.Release-DLL|x64.Build.0 = Release-DLL|x64
-		{6EE56155-DF7C-4F6E-BFC4-F6F776BEB211}.Debug|Win32.ActiveCfg = Debug|Win32
-		{6EE56155-DF7C-4F6E-BFC4-F6F776BEB211}.Debug|x64.ActiveCfg = Debug|x64
-		{6EE56155-DF7C-4F6E-BFC4-F6F776BEB211}.Release|Win32.ActiveCfg = Release|Win32
-		{6EE56155-DF7C-4F6E-BFC4-F6F776BEB211}.Release|x64.ActiveCfg = Release|x64
-		{6EE56155-DF7C-4F6E-BFC4-F6F776BEB211}.Debug|Win32.Build.0 = Debug|Win32
-		{6EE56155-DF7C-4F6E-BFC4-F6F776BEB211}.Debug|x64.Build.0 = Debug|x64
-		{6EE56155-DF7C-4F6E-BFC4-F6F776BEB211}.Release|Win32.Build.0 = Release|Win32
-		{6EE56155-DF7C-4F6E-BFC4-F6F776BEB211}.Release|x64.Build.0 = Release|x64
-		{6EE56155-DF7C-4F6E-BFC4-F6F776BEB211}.Debug-DLL|Win32.ActiveCfg = Debug-DLL|Win32
-		{6EE56155-DF7C-4F6E-BFC4-F6F776BEB211}.Debug-DLL|Win32.Build.0 = Debug-DLL|Win32
-		{6EE56155-DF7C-4F6E-BFC4-F6F776BEB211}.Debug-DLL|x64.ActiveCfg = Debug-DLL|x64
-		{6EE56155-DF7C-4F6E-BFC4-F6F776BEB211}.Debug-DLL|x64.Build.0 = Debug-DLL|x64
-		{6EE56155-DF7C-4F6E-BFC4-F6F776BEB211}.Release-DLL|Win32.ActiveCfg = Release-DLL|Win32
-		{6EE56155-DF7C-4F6E-BFC4-F6F776BEB211}.Release-DLL|Win32.Build.0 = Release-DLL|Win32
-		{6EE56155-DF7C-4F6E-BFC4-F6F776BEB211}.Release-DLL|x64.ActiveCfg = Release-DLL|x64
-		{6EE56155-DF7C-4F6E-BFC4-F6F776BEB211}.Release-DLL|x64.Build.0 = Release-DLL|x64
-		{9FD9A3EF-C4A3-8390-D8F4-6F86C22A58CE}.Debug|Win32.ActiveCfg = Debug|Win32
-		{9FD9A3EF-C4A3-8390-D8F4-6F86C22A58CE}.Debug|x64.ActiveCfg = Debug|x64
-		{9FD9A3EF-C4A3-8390-D8F4-6F86C22A58CE}.Release|Win32.ActiveCfg = Release|Win32
-		{9FD9A3EF-C4A3-8390-D8F4-6F86C22A58CE}.Release|x64.ActiveCfg = Release|x64
-		{9FD9A3EF-C4A3-8390-D8F4-6F86C22A58CE}.Debug|Win32.Build.0 = Debug|Win32
-		{9FD9A3EF-C4A3-8390-D8F4-6F86C22A58CE}.Debug|x64.Build.0 = Debug|x64
-		{9FD9A3EF-C4A3-8390-D8F4-6F86C22A58CE}.Release|Win32.Build.0 = Release|Win32
-		{9FD9A3EF-C4A3-8390-D8F4-6F86C22A58CE}.Release|x64.Build.0 = Release|x64
-		{9FD9A3EF-C4A3-8390-D8F4-6F86C22A58CE}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
-		{9FD9A3EF-C4A3-8390-D8F4-6F86C22A58CE}.Debug-DLL|Win32.Build.0 = Debug|Win32
-		{9FD9A3EF-C4A3-8390-D8F4-6F86C22A58CE}.Debug-DLL|x64.ActiveCfg = Debug|x64
-		{9FD9A3EF-C4A3-8390-D8F4-6F86C22A58CE}.Debug-DLL|x64.Build.0 = Debug|x64
-		{9FD9A3EF-C4A3-8390-D8F4-6F86C22A58CE}.Release-DLL|Win32.ActiveCfg = Release|Win32
-		{9FD9A3EF-C4A3-8390-D8F4-6F86C22A58CE}.Release-DLL|Win32.Build.0 = Release|Win32
-		{9FD9A3EF-C4A3-8390-D8F4-6F86C22A58CE}.Release-DLL|x64.ActiveCfg = Release|x64
-		{9FD9A3EF-C4A3-8390-D8F4-6F86C22A58CE}.Release-DLL|x64.Build.0 = Release|x64
 		{FBADE9E3-6A3F-36D3-D676-C1B808451DD7}.Debug|Win32.ActiveCfg = Debug|Win32
 		{FBADE9E3-6A3F-36D3-D676-C1B808451DD7}.Debug|x64.ActiveCfg = Debug|x64
 		{FBADE9E3-6A3F-36D3-D676-C1B808451DD7}.Release|Win32.ActiveCfg = Release|Win32
@@ -391,102 +511,6 @@
 		{FBADE9E3-6A3F-36D3-D676-C1B808451DD7}.Release-DLL|Win32.Build.0 = Release|Win32
 		{FBADE9E3-6A3F-36D3-D676-C1B808451DD7}.Release-DLL|x64.ActiveCfg = Release|x64
 		{FBADE9E3-6A3F-36D3-D676-C1B808451DD7}.Release-DLL|x64.Build.0 = Release|x64
-		{FCDEA4C7-7F26-05DB-D08F-A08F499026E6}.Debug|Win32.ActiveCfg = Debug|Win32
-		{FCDEA4C7-7F26-05DB-D08F-A08F499026E6}.Debug|x64.ActiveCfg = Debug|x64
-		{FCDEA4C7-7F26-05DB-D08F-A08F499026E6}.Release|Win32.ActiveCfg = Release|Win32
-		{FCDEA4C7-7F26-05DB-D08F-A08F499026E6}.Release|x64.ActiveCfg = Release|x64
-		{FCDEA4C7-7F26-05DB-D08F-A08F499026E6}.Debug|Win32.Build.0 = Debug|Win32
-		{FCDEA4C7-7F26-05DB-D08F-A08F499026E6}.Debug|x64.Build.0 = Debug|x64
-		{FCDEA4C7-7F26-05DB-D08F-A08F499026E6}.Release|Win32.Build.0 = Release|Win32
-		{FCDEA4C7-7F26-05DB-D08F-A08F499026E6}.Release|x64.Build.0 = Release|x64
-		{FCDEA4C7-7F26-05DB-D08F-A08F499026E6}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
-		{FCDEA4C7-7F26-05DB-D08F-A08F499026E6}.Debug-DLL|Win32.Build.0 = Debug|Win32
-		{FCDEA4C7-7F26-05DB-D08F-A08F499026E6}.Debug-DLL|x64.ActiveCfg = Debug|x64
-		{FCDEA4C7-7F26-05DB-D08F-A08F499026E6}.Debug-DLL|x64.Build.0 = Debug|x64
-		{FCDEA4C7-7F26-05DB-D08F-A08F499026E6}.Release-DLL|Win32.ActiveCfg = Release|Win32
-		{FCDEA4C7-7F26-05DB-D08F-A08F499026E6}.Release-DLL|Win32.Build.0 = Release|Win32
-		{FCDEA4C7-7F26-05DB-D08F-A08F499026E6}.Release-DLL|x64.ActiveCfg = Release|x64
-		{FCDEA4C7-7F26-05DB-D08F-A08F499026E6}.Release-DLL|x64.Build.0 = Release|x64
-		{A635DE99-B131-CA00-2D3B-8691D60B76C2}.Debug|Win32.ActiveCfg = Debug|Win32
-		{A635DE99-B131-CA00-2D3B-8691D60B76C2}.Debug|x64.ActiveCfg = Debug|x64
-		{A635DE99-B131-CA00-2D3B-8691D60B76C2}.Release|Win32.ActiveCfg = Release|Win32
-		{A635DE99-B131-CA00-2D3B-8691D60B76C2}.Release|x64.ActiveCfg = Release|x64
-		{A635DE99-B131-CA00-2D3B-8691D60B76C2}.Debug|Win32.Build.0 = Debug|Win32
-		{A635DE99-B131-CA00-2D3B-8691D60B76C2}.Debug|x64.Build.0 = Debug|x64
-		{A635DE99-B131-CA00-2D3B-8691D60B76C2}.Release|Win32.Build.0 = Release|Win32
-		{A635DE99-B131-CA00-2D3B-8691D60B76C2}.Release|x64.Build.0 = Release|x64
-		{A635DE99-B131-CA00-2D3B-8691D60B76C2}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
-		{A635DE99-B131-CA00-2D3B-8691D60B76C2}.Debug-DLL|Win32.Build.0 = Debug|Win32
-		{A635DE99-B131-CA00-2D3B-8691D60B76C2}.Debug-DLL|x64.ActiveCfg = Debug|x64
-		{A635DE99-B131-CA00-2D3B-8691D60B76C2}.Debug-DLL|x64.Build.0 = Debug|x64
-		{A635DE99-B131-CA00-2D3B-8691D60B76C2}.Release-DLL|Win32.ActiveCfg = Release|Win32
-		{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
-		{77971F8D-F583-3E77-0E3C-6C1FB6B1749C}.Debug|Win32.ActiveCfg = Debug|Win32
-		{77971F8D-F583-3E77-0E3C-6C1FB6B1749C}.Debug|x64.ActiveCfg = Debug|x64
-		{77971F8D-F583-3E77-0E3C-6C1FB6B1749C}.Release|Win32.ActiveCfg = Release|Win32
-		{77971F8D-F583-3E77-0E3C-6C1FB6B1749C}.Release|x64.ActiveCfg = Release|x64
-		{77971F8D-F583-3E77-0E3C-6C1FB6B1749C}.Debug|Win32.Build.0 = Debug|Win32
-		{77971F8D-F583-3E77-0E3C-6C1FB6B1749C}.Debug|x64.Build.0 = Debug|x64
-		{77971F8D-F583-3E77-0E3C-6C1FB6B1749C}.Release|Win32.Build.0 = Release|Win32
-		{77971F8D-F583-3E77-0E3C-6C1FB6B1749C}.Release|x64.Build.0 = Release|x64
-		{77971F8D-F583-3E77-0E3C-6C1FB6B1749C}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
-		{77971F8D-F583-3E77-0E3C-6C1FB6B1749C}.Debug-DLL|Win32.Build.0 = Debug|Win32
-		{77971F8D-F583-3E77-0E3C-6C1FB6B1749C}.Debug-DLL|x64.ActiveCfg = Debug|x64
-		{77971F8D-F583-3E77-0E3C-6C1FB6B1749C}.Debug-DLL|x64.Build.0 = Debug|x64
-		{77971F8D-F583-3E77-0E3C-6C1FB6B1749C}.Release-DLL|Win32.ActiveCfg = Release|Win32
-		{77971F8D-F583-3E77-0E3C-6C1FB6B1749C}.Release-DLL|Win32.Build.0 = Release|Win32
-		{77971F8D-F583-3E77-0E3C-6C1FB6B1749C}.Release-DLL|x64.ActiveCfg = Release|x64
-		{77971F8D-F583-3E77-0E3C-6C1FB6B1749C}.Release-DLL|x64.Build.0 = Release|x64
-		{43722E98-54EC-5058-3DAC-327F45964971}.Debug|Win32.ActiveCfg = Debug|Win32
-		{43722E98-54EC-5058-3DAC-327F45964971}.Debug|x64.ActiveCfg = Debug|x64
-		{43722E98-54EC-5058-3DAC-327F45964971}.Release|Win32.ActiveCfg = Release|Win32
-		{43722E98-54EC-5058-3DAC-327F45964971}.Release|x64.ActiveCfg = Release|x64
-		{43722E98-54EC-5058-3DAC-327F45964971}.Debug|Win32.Build.0 = Debug|Win32
-		{43722E98-54EC-5058-3DAC-327F45964971}.Debug|x64.Build.0 = Debug|x64
-		{43722E98-54EC-5058-3DAC-327F45964971}.Release|Win32.Build.0 = Release|Win32
-		{43722E98-54EC-5058-3DAC-327F45964971}.Release|x64.Build.0 = Release|x64
-		{43722E98-54EC-5058-3DAC-327F45964971}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
-		{43722E98-54EC-5058-3DAC-327F45964971}.Debug-DLL|Win32.Build.0 = Debug|Win32
-		{43722E98-54EC-5058-3DAC-327F45964971}.Debug-DLL|x64.ActiveCfg = Debug|x64
-		{43722E98-54EC-5058-3DAC-327F45964971}.Debug-DLL|x64.Build.0 = Debug|x64
-		{43722E98-54EC-5058-3DAC-327F45964971}.Release-DLL|Win32.ActiveCfg = Release|Win32
-		{43722E98-54EC-5058-3DAC-327F45964971}.Release-DLL|Win32.Build.0 = Release|Win32
-		{43722E98-54EC-5058-3DAC-327F45964971}.Release-DLL|x64.ActiveCfg = Release|x64
-		{43722E98-54EC-5058-3DAC-327F45964971}.Release-DLL|x64.Build.0 = Release|x64
-		{C002965C-8457-CCE5-B1BA-E748FF9A11B6}.Debug|Win32.ActiveCfg = Debug|Win32
-		{C002965C-8457-CCE5-B1BA-E748FF9A11B6}.Debug|x64.ActiveCfg = Debug|x64
-		{C002965C-8457-CCE5-B1BA-E748FF9A11B6}.Release|Win32.ActiveCfg = Release|Win32
-		{C002965C-8457-CCE5-B1BA-E748FF9A11B6}.Release|x64.ActiveCfg = Release|x64
-		{C002965C-8457-CCE5-B1BA-E748FF9A11B6}.Debug|Win32.Build.0 = Debug|Win32
-		{C002965C-8457-CCE5-B1BA-E748FF9A11B6}.Debug|x64.Build.0 = Debug|x64
-		{C002965C-8457-CCE5-B1BA-E748FF9A11B6}.Release|Win32.Build.0 = Release|Win32
-		{C002965C-8457-CCE5-B1BA-E748FF9A11B6}.Release|x64.Build.0 = Release|x64
-		{C002965C-8457-CCE5-B1BA-E748FF9A11B6}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
-		{C002965C-8457-CCE5-B1BA-E748FF9A11B6}.Debug-DLL|Win32.Build.0 = Debug|Win32
-		{C002965C-8457-CCE5-B1BA-E748FF9A11B6}.Debug-DLL|x64.ActiveCfg = Debug|x64
-		{C002965C-8457-CCE5-B1BA-E748FF9A11B6}.Debug-DLL|x64.Build.0 = Debug|x64
-		{C002965C-8457-CCE5-B1BA-E748FF9A11B6}.Release-DLL|Win32.ActiveCfg = Release|Win32
-		{C002965C-8457-CCE5-B1BA-E748FF9A11B6}.Release-DLL|Win32.Build.0 = Release|Win32
-		{C002965C-8457-CCE5-B1BA-E748FF9A11B6}.Release-DLL|x64.ActiveCfg = Release|x64
-		{C002965C-8457-CCE5-B1BA-E748FF9A11B6}.Release-DLL|x64.Build.0 = Release|x64
-		{02FAC25F-5FF6-34A0-00AE-B82BFBA851A9}.Debug|Win32.ActiveCfg = Debug|Win32
-		{02FAC25F-5FF6-34A0-00AE-B82BFBA851A9}.Debug|x64.ActiveCfg = Debug|x64
-		{02FAC25F-5FF6-34A0-00AE-B82BFBA851A9}.Release|Win32.ActiveCfg = Release|Win32
-		{02FAC25F-5FF6-34A0-00AE-B82BFBA851A9}.Release|x64.ActiveCfg = Release|x64
-		{02FAC25F-5FF6-34A0-00AE-B82BFBA851A9}.Debug|Win32.Build.0 = Debug|Win32
-		{02FAC25F-5FF6-34A0-00AE-B82BFBA851A9}.Debug|x64.Build.0 = Debug|x64
-		{02FAC25F-5FF6-34A0-00AE-B82BFBA851A9}.Release|Win32.Build.0 = Release|Win32
-		{02FAC25F-5FF6-34A0-00AE-B82BFBA851A9}.Release|x64.Build.0 = Release|x64
-		{02FAC25F-5FF6-34A0-00AE-B82BFBA851A9}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
-		{02FAC25F-5FF6-34A0-00AE-B82BFBA851A9}.Debug-DLL|Win32.Build.0 = Debug|Win32
-		{02FAC25F-5FF6-34A0-00AE-B82BFBA851A9}.Debug-DLL|x64.ActiveCfg = Debug|x64
-		{02FAC25F-5FF6-34A0-00AE-B82BFBA851A9}.Debug-DLL|x64.Build.0 = Debug|x64
-		{02FAC25F-5FF6-34A0-00AE-B82BFBA851A9}.Release-DLL|Win32.ActiveCfg = Release|Win32
-		{02FAC25F-5FF6-34A0-00AE-B82BFBA851A9}.Release-DLL|Win32.Build.0 = Release|Win32
-		{02FAC25F-5FF6-34A0-00AE-B82BFBA851A9}.Release-DLL|x64.ActiveCfg = Release|x64
-		{02FAC25F-5FF6-34A0-00AE-B82BFBA851A9}.Release-DLL|x64.Build.0 = Release|x64
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE
diff --git a/vsprojects/grpc_csharp_ext.sln b/vsprojects/grpc_csharp_ext.sln
index 11d2204..ad8ae8a 100644
--- a/vsprojects/grpc_csharp_ext.sln
+++ b/vsprojects/grpc_csharp_ext.sln
@@ -16,14 +16,6 @@
 		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
 	EndProjectSection
 EndProject
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "grpc_unsecure", "vcxproj\.\grpc_unsecure\grpc_unsecure.vcxproj", "{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}"
-	ProjectSection(myProperties) = preProject
-        	lib = "True"
-	EndProjectSection
-	ProjectSection(ProjectDependencies) = postProject
-		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
-	EndProjectSection
-EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "grpc_csharp_ext", "vcxproj\.\grpc_csharp_ext\grpc_csharp_ext.vcxproj", "{D64C6D63-4458-4A88-AB38-35678384A7E4}"
 	ProjectSection(myProperties) = preProject
         	lib = "True"
@@ -57,14 +49,6 @@
 		{29D16885-7228-4C31-81ED-5F9187C7F2A9}.Release|Win32.Build.0 = Release-DLL|Win32
 		{29D16885-7228-4C31-81ED-5F9187C7F2A9}.Release|x64.ActiveCfg = Release-DLL|x64
 		{29D16885-7228-4C31-81ED-5F9187C7F2A9}.Release|x64.Build.0 = Release-DLL|x64
-		{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}.Debug|Win32.ActiveCfg = Debug-DLL|Win32
-		{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}.Debug|Win32.Build.0 = Debug-DLL|Win32
-		{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}.Debug|x64.ActiveCfg = Debug-DLL|x64
-		{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}.Debug|x64.Build.0 = Debug-DLL|x64
-		{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}.Release|Win32.ActiveCfg = Release-DLL|Win32
-		{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}.Release|Win32.Build.0 = Release-DLL|Win32
-		{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}.Release|x64.ActiveCfg = Release-DLL|x64
-		{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}.Release|x64.Build.0 = Release-DLL|x64
 		{D64C6D63-4458-4A88-AB38-35678384A7E4}.Debug|Win32.ActiveCfg = Debug|Win32
 		{D64C6D63-4458-4A88-AB38-35678384A7E4}.Debug|Win32.Build.0 = Debug|Win32
 		{D64C6D63-4458-4A88-AB38-35678384A7E4}.Debug|x64.ActiveCfg = Debug|x64
diff --git a/vsprojects/grpc_protoc_plugins.sln b/vsprojects/grpc_protoc_plugins.sln
index ace295d..2e55720 100644
--- a/vsprojects/grpc_protoc_plugins.sln
+++ b/vsprojects/grpc_protoc_plugins.sln
@@ -3,11 +3,6 @@
 # Visual Studio 2013
 VisualStudioVersion = 12.0.21005.1
 MinimumVisualStudioVersion = 10.0.40219.1
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "grpc_plugin_support", "vcxproj\.\grpc_plugin_support\grpc_plugin_support.vcxproj", "{B6E81D84-2ACB-41B8-8781-493A944C7817}"
-	ProjectSection(myProperties) = preProject
-        	lib = "True"
-	EndProjectSection
-EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "grpc_cpp_plugin", "vcxproj\.\grpc_cpp_plugin\grpc_cpp_plugin.vcxproj", "{7E51A25F-AC59-488F-906C-C60FAAE706AA}"
 	ProjectSection(myProperties) = preProject
         	lib = "False"
@@ -40,6 +35,11 @@
 		{B6E81D84-2ACB-41B8-8781-493A944C7817} = {B6E81D84-2ACB-41B8-8781-493A944C7817}
 	EndProjectSection
 EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "grpc_plugin_support", "vcxproj\.\grpc_plugin_support\grpc_plugin_support.vcxproj", "{B6E81D84-2ACB-41B8-8781-493A944C7817}"
+	ProjectSection(myProperties) = preProject
+        	lib = "True"
+	EndProjectSection
+EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "grpc_python_plugin", "vcxproj\.\grpc_python_plugin\grpc_python_plugin.vcxproj", "{DF52D501-A6CF-4E6F-BA38-6EBE2E8DAFB2}"
 	ProjectSection(myProperties) = preProject
         	lib = "False"
@@ -64,14 +64,6 @@
 		Release|x64 = Release|x64
 	EndGlobalSection
 	GlobalSection(ProjectConfigurationPlatforms) = postSolution
-		{B6E81D84-2ACB-41B8-8781-493A944C7817}.Debug|Win32.ActiveCfg = Debug|Win32
-		{B6E81D84-2ACB-41B8-8781-493A944C7817}.Debug|x64.ActiveCfg = Debug|x64
-		{B6E81D84-2ACB-41B8-8781-493A944C7817}.Release|Win32.ActiveCfg = Release|Win32
-		{B6E81D84-2ACB-41B8-8781-493A944C7817}.Release|x64.ActiveCfg = Release|x64
-		{B6E81D84-2ACB-41B8-8781-493A944C7817}.Debug|Win32.Build.0 = Debug|Win32
-		{B6E81D84-2ACB-41B8-8781-493A944C7817}.Debug|x64.Build.0 = Debug|x64
-		{B6E81D84-2ACB-41B8-8781-493A944C7817}.Release|Win32.Build.0 = Release|Win32
-		{B6E81D84-2ACB-41B8-8781-493A944C7817}.Release|x64.Build.0 = Release|x64
 		{7E51A25F-AC59-488F-906C-C60FAAE706AA}.Debug|Win32.ActiveCfg = Debug|Win32
 		{7E51A25F-AC59-488F-906C-C60FAAE706AA}.Debug|x64.ActiveCfg = Debug|x64
 		{7E51A25F-AC59-488F-906C-C60FAAE706AA}.Release|Win32.ActiveCfg = Release|Win32
@@ -104,6 +96,14 @@
 		{19564640-CEE6-4921-ABA5-676ED79A36F6}.Debug|x64.Build.0 = Debug|x64
 		{19564640-CEE6-4921-ABA5-676ED79A36F6}.Release|Win32.Build.0 = Release|Win32
 		{19564640-CEE6-4921-ABA5-676ED79A36F6}.Release|x64.Build.0 = Release|x64
+		{B6E81D84-2ACB-41B8-8781-493A944C7817}.Debug|Win32.ActiveCfg = Debug|Win32
+		{B6E81D84-2ACB-41B8-8781-493A944C7817}.Debug|x64.ActiveCfg = Debug|x64
+		{B6E81D84-2ACB-41B8-8781-493A944C7817}.Release|Win32.ActiveCfg = Release|Win32
+		{B6E81D84-2ACB-41B8-8781-493A944C7817}.Release|x64.ActiveCfg = Release|x64
+		{B6E81D84-2ACB-41B8-8781-493A944C7817}.Debug|Win32.Build.0 = Debug|Win32
+		{B6E81D84-2ACB-41B8-8781-493A944C7817}.Debug|x64.Build.0 = Debug|x64
+		{B6E81D84-2ACB-41B8-8781-493A944C7817}.Release|Win32.Build.0 = Release|Win32
+		{B6E81D84-2ACB-41B8-8781-493A944C7817}.Release|x64.Build.0 = Release|x64
 		{DF52D501-A6CF-4E6F-BA38-6EBE2E8DAFB2}.Debug|Win32.ActiveCfg = Debug|Win32
 		{DF52D501-A6CF-4E6F-BA38-6EBE2E8DAFB2}.Debug|x64.ActiveCfg = Debug|x64
 		{DF52D501-A6CF-4E6F-BA38-6EBE2E8DAFB2}.Release|Win32.ActiveCfg = Release|Win32
diff --git a/vsprojects/vcxproj/gpr/gpr.vcxproj b/vsprojects/vcxproj/gpr/gpr.vcxproj
index 26195bb..2e403c2 100644
--- a/vsprojects/vcxproj/gpr/gpr.vcxproj
+++ b/vsprojects/vcxproj/gpr/gpr.vcxproj
@@ -151,14 +151,14 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\support\atm.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\support\atm_gcc_atomic.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\support\atm_gcc_sync.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\support\atm_win32.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\support\atm_windows.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\support\avl.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\support\cmdline.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\support\cpu.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\support\histogram.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\support\host_port.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\support\log.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\support\log_win32.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\support\log_windows.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\support\port_platform.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\support\slice.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\support\slice_buffer.h" />
@@ -167,7 +167,7 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\support\sync.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\support\sync_generic.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\support\sync_posix.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\support\sync_win32.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\support\sync_windows.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\support\thd.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\support\time.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\support\tls.h" />
@@ -179,7 +179,7 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_atomic.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_sync.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_win32.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_windows.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\log.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\port_platform.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\slice.h" />
@@ -187,7 +187,7 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_generic.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_posix.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_win32.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_windows.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\time.h" />
   </ItemGroup>
   <ItemGroup>
@@ -199,7 +199,7 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\support\murmur_hash.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_win32.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\support\string_windows.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\support\thd_internal.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\support\time_precise.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\support\tmpfile.h" />
@@ -229,7 +229,7 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\support\env_posix.c">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\lib\support\env_win32.c">
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\support\env_windows.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\support\histogram.c">
     </ClCompile>
@@ -245,7 +245,7 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\support\log_posix.c">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\lib\support\log_win32.c">
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\support\log_windows.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\support\murmur_hash.c">
     </ClCompile>
@@ -259,9 +259,9 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\support\string_posix.c">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\lib\support\string_util_win32.c">
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\support\string_util_windows.c">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\lib\support\string_win32.c">
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\support\string_windows.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\support\subprocess_posix.c">
     </ClCompile>
@@ -271,13 +271,13 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\support\sync_posix.c">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\lib\support\sync_win32.c">
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\support\sync_windows.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\support\thd.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\support\thd_posix.c">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\lib\support\thd_win32.c">
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\support\thd_windows.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\support\time.c">
     </ClCompile>
@@ -285,7 +285,7 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\support\time_precise.c">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\lib\support\time_win32.c">
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\support\time_windows.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\support\tls_pthread.c">
     </ClCompile>
@@ -293,7 +293,7 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\support\tmpfile_posix.c">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\lib\support\tmpfile_win32.c">
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\support\tmpfile_windows.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\support\wrap_memcpy.c">
     </ClCompile>
diff --git a/vsprojects/vcxproj/gpr/gpr.vcxproj.filters b/vsprojects/vcxproj/gpr/gpr.vcxproj.filters
index be15391..c952a78 100644
--- a/vsprojects/vcxproj/gpr/gpr.vcxproj.filters
+++ b/vsprojects/vcxproj/gpr/gpr.vcxproj.filters
@@ -37,7 +37,7 @@
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\support\env_posix.c">
       <Filter>src\core\lib\support</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\lib\support\env_win32.c">
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\support\env_windows.c">
       <Filter>src\core\lib\support</Filter>
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\support\histogram.c">
@@ -61,7 +61,7 @@
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\support\log_posix.c">
       <Filter>src\core\lib\support</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\lib\support\log_win32.c">
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\support\log_windows.c">
       <Filter>src\core\lib\support</Filter>
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\support\murmur_hash.c">
@@ -82,10 +82,10 @@
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\support\string_posix.c">
       <Filter>src\core\lib\support</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\lib\support\string_util_win32.c">
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\support\string_util_windows.c">
       <Filter>src\core\lib\support</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\lib\support\string_win32.c">
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\support\string_windows.c">
       <Filter>src\core\lib\support</Filter>
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\support\subprocess_posix.c">
@@ -100,7 +100,7 @@
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\support\sync_posix.c">
       <Filter>src\core\lib\support</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\lib\support\sync_win32.c">
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\support\sync_windows.c">
       <Filter>src\core\lib\support</Filter>
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\support\thd.c">
@@ -109,7 +109,7 @@
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\support\thd_posix.c">
       <Filter>src\core\lib\support</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\lib\support\thd_win32.c">
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\support\thd_windows.c">
       <Filter>src\core\lib\support</Filter>
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\support\time.c">
@@ -121,7 +121,7 @@
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\support\time_precise.c">
       <Filter>src\core\lib\support</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\lib\support\time_win32.c">
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\support\time_windows.c">
       <Filter>src\core\lib\support</Filter>
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\support\tls_pthread.c">
@@ -133,7 +133,7 @@
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\support\tmpfile_posix.c">
       <Filter>src\core\lib\support</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\lib\support\tmpfile_win32.c">
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\support\tmpfile_windows.c">
       <Filter>src\core\lib\support</Filter>
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\support\wrap_memcpy.c">
@@ -153,7 +153,7 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\support\atm_gcc_sync.h">
       <Filter>include\grpc\support</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\support\atm_win32.h">
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\support\atm_windows.h">
       <Filter>include\grpc\support</Filter>
     </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\include\grpc\support\avl.h">
@@ -174,7 +174,7 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\support\log.h">
       <Filter>include\grpc\support</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\support\log_win32.h">
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\support\log_windows.h">
       <Filter>include\grpc\support</Filter>
     </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\include\grpc\support\port_platform.h">
@@ -201,7 +201,7 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\support\sync_posix.h">
       <Filter>include\grpc\support</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\support\sync_win32.h">
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\support\sync_windows.h">
       <Filter>include\grpc\support</Filter>
     </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\include\grpc\support\thd.h">
@@ -237,7 +237,7 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_sync.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_win32.h">
+    <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">
@@ -261,7 +261,7 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_posix.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_win32.h">
+    <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">
@@ -293,7 +293,7 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\support\string.h">
       <Filter>src\core\lib\support</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\src\core\lib\support\string_win32.h">
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\support\string_windows.h">
       <Filter>src\core\lib\support</Filter>
     </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\support\thd_internal.h">
diff --git a/vsprojects/vcxproj/grpc++/grpc++.vcxproj b/vsprojects/vcxproj/grpc++/grpc++.vcxproj
index 65de5e9..cb9e41e 100644
--- a/vsprojects/vcxproj/grpc++/grpc++.vcxproj
+++ b/vsprojects/vcxproj/grpc++/grpc++.vcxproj
@@ -263,14 +263,15 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\client_context.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\completion_queue.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\create_channel.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\create_channel_posix.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\generic\async_generic_service.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\generic\generic_stub.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\grpc++.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\call.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\client_unary_call.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\core_codegen.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\grpc_library.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\method_handler_impl.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\proto_utils.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\rpc_method.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\rpc_service_method.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\serialization_traits.h" />
@@ -291,10 +292,12 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\server.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\server_builder.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\server_context.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\server_posix.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\support\async_stream.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\support\async_unary_call.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\support\byte_buffer.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\support\channel_arguments.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\support\config.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\support\slice.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\support\status.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\support\status_code_enum.h" />
@@ -311,11 +314,11 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\client_unary_call.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\completion_queue.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\completion_queue_tag.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\config.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\core_codegen_interface.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\create_auth_context.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\grpc_library.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\method_handler_impl.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\proto_utils.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\rpc_method.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\rpc_service_method.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\security\auth_context.h" />
@@ -343,7 +346,7 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_atomic.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_sync.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_win32.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_windows.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\log.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\port_platform.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\slice.h" />
@@ -351,16 +354,12 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_generic.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_posix.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_win32.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_windows.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\time.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\config.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\config_protobuf.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\support\config.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\support\config_protobuf.h" />
   </ItemGroup>
   <ItemGroup>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\core_codegen.h" />
     <ClInclude Include="$(SolutionDir)\..\src\cpp\client\secure_credentials.h" />
-    <ClInclude Include="$(SolutionDir)\..\src\cpp\common\core_codegen.h" />
     <ClInclude Include="$(SolutionDir)\..\src\cpp\common\secure_auth_context.h" />
     <ClInclude Include="$(SolutionDir)\..\src\cpp\server\secure_server_credentials.h" />
     <ClInclude Include="$(SolutionDir)\..\src\cpp\client\create_channel_internal.h" />
@@ -388,6 +387,8 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\client\create_channel_internal.cc">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\cpp\client\create_channel_posix.cc">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\client\credentials.cc">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\client\generic_stub.cc">
@@ -418,6 +419,8 @@
     </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>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\util\slice.cc">
diff --git a/vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters b/vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters
index ce50bd9..a905118 100644
--- a/vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters
@@ -31,6 +31,9 @@
     <ClCompile Include="$(SolutionDir)\..\src\cpp\client\create_channel_internal.cc">
       <Filter>src\cpp\client</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\cpp\client\create_channel_posix.cc">
+      <Filter>src\cpp\client</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\client\credentials.cc">
       <Filter>src\cpp\client</Filter>
     </ClCompile>
@@ -76,6 +79,9 @@
     <ClCompile Include="$(SolutionDir)\..\src\cpp\server\server_credentials.cc">
       <Filter>src\cpp\server</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\cpp\server\server_posix.cc">
+      <Filter>src\cpp\server</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\util\byte_buffer.cc">
       <Filter>src\cpp\util</Filter>
     </ClCompile>
@@ -111,6 +117,9 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\create_channel.h">
       <Filter>include\grpc++</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\create_channel_posix.h">
+      <Filter>include\grpc++</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\generic\async_generic_service.h">
       <Filter>include\grpc++\generic</Filter>
     </ClInclude>
@@ -126,15 +135,15 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\client_unary_call.h">
       <Filter>include\grpc++\impl</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\core_codegen.h">
+      <Filter>include\grpc++\impl\codegen</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\grpc_library.h">
       <Filter>include\grpc++\impl</Filter>
     </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\method_handler_impl.h">
       <Filter>include\grpc++\impl</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\proto_utils.h">
-      <Filter>include\grpc++\impl</Filter>
-    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\rpc_method.h">
       <Filter>include\grpc++\impl</Filter>
     </ClInclude>
@@ -195,6 +204,9 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\server_context.h">
       <Filter>include\grpc++</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\server_posix.h">
+      <Filter>include\grpc++</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\support\async_stream.h">
       <Filter>include\grpc++\support</Filter>
     </ClInclude>
@@ -207,6 +219,9 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\support\channel_arguments.h">
       <Filter>include\grpc++\support</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\support\config.h">
+      <Filter>include\grpc++\support</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\support\slice.h">
       <Filter>include\grpc++\support</Filter>
     </ClInclude>
@@ -255,6 +270,9 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\completion_queue_tag.h">
       <Filter>include\grpc++\impl\codegen</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\config.h">
+      <Filter>include\grpc++\impl\codegen</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\core_codegen_interface.h">
       <Filter>include\grpc++\impl\codegen</Filter>
     </ClInclude>
@@ -267,9 +285,6 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\method_handler_impl.h">
       <Filter>include\grpc++\impl\codegen</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\proto_utils.h">
-      <Filter>include\grpc++\impl\codegen</Filter>
-    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\rpc_method.h">
       <Filter>include\grpc++\impl\codegen</Filter>
     </ClInclude>
@@ -351,7 +366,7 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_sync.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_win32.h">
+    <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">
@@ -375,32 +390,20 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_posix.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_win32.h">
+    <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.h">
-      <Filter>include\grpc++\impl\codegen</Filter>
-    </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\config_protobuf.h">
-      <Filter>include\grpc++\impl\codegen</Filter>
-    </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\support\config.h">
-      <Filter>include\grpc++\support</Filter>
-    </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\support\config_protobuf.h">
-      <Filter>include\grpc++\support</Filter>
-    </ClInclude>
   </ItemGroup>
   <ItemGroup>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\core_codegen.h">
+      <Filter>include\grpc++\impl\codegen</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\cpp\client\secure_credentials.h">
       <Filter>src\cpp\client</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\src\cpp\common\core_codegen.h">
-      <Filter>src\cpp\common</Filter>
-    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\cpp\common\secure_auth_context.h">
       <Filter>src\cpp\common</Filter>
     </ClInclude>
diff --git a/vsprojects/vcxproj/grpc++_reflection/grpc++_reflection.vcxproj b/vsprojects/vcxproj/grpc++_reflection/grpc++_reflection.vcxproj
new file mode 100644
index 0000000..7c3e63b
--- /dev/null
+++ b/vsprojects/vcxproj/grpc++_reflection/grpc++_reflection.vcxproj
@@ -0,0 +1,234 @@
+<?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>{5F575402-3F89-5D1A-6910-9DB8BF5D2BAB}</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>grpc++_reflection</TargetName>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)'=='Release'">
+    <TargetName>grpc++_reflection</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>Windows</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>Windows</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>Windows</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>Windows</SubSystem>
+      <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
+      <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+    </Link>
+  </ItemDefinitionGroup>
+
+  <ItemGroup>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\ext\proto_server_reflection_plugin.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\ext\reflection.grpc.pb.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\ext\reflection.pb.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\proto_utils.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\async_stream.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\async_unary_call.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\call.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\call_hook.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\channel_interface.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\client_context.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\client_unary_call.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\completion_queue.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\completion_queue_tag.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\config.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\core_codegen_interface.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\create_auth_context.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\grpc_library.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\method_handler_impl.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\rpc_method.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\rpc_service_method.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\security\auth_context.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\serialization_traits.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\server_context.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\server_interface.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\service_type.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\status.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\status_code_enum.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\string_ref.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\stub_options.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\sync.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\sync_cxx11.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\sync_no_cxx11.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\sync_stream.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\time.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\byte_buffer.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\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\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>
+    <ClInclude Include="$(SolutionDir)\..\src\cpp\ext\proto_server_reflection.h" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="$(SolutionDir)\..\src\cpp\ext\proto_server_reflection.cc">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\cpp\ext\proto_server_reflection_plugin.cc">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\cpp\ext\reflection.grpc.pb.cc">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\cpp\ext\reflection.pb.cc">
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc++\grpc++.vcxproj">
+      <Project>{C187A093-A0FE-489D-A40A-6E33DE0F9FEB}</Project>
+    </ProjectReference>
+  </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/grpc++_reflection/grpc++_reflection.vcxproj.filters b/vsprojects/vcxproj/grpc++_reflection/grpc++_reflection.vcxproj.filters
new file mode 100644
index 0000000..d9cd49c
--- /dev/null
+++ b/vsprojects/vcxproj/grpc++_reflection/grpc++_reflection.vcxproj.filters
@@ -0,0 +1,232 @@
+<?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\ext\proto_server_reflection.cc">
+      <Filter>src\cpp\ext</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\cpp\ext\proto_server_reflection_plugin.cc">
+      <Filter>src\cpp\ext</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\cpp\ext\reflection.grpc.pb.cc">
+      <Filter>src\cpp\ext</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\cpp\ext\reflection.pb.cc">
+      <Filter>src\cpp\ext</Filter>
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\ext\proto_server_reflection_plugin.h">
+      <Filter>include\grpc++\ext</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\ext\reflection.grpc.pb.h">
+      <Filter>include\grpc++\ext</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\ext\reflection.pb.h">
+      <Filter>include\grpc++\ext</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\proto_utils.h">
+      <Filter>include\grpc++\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\async_stream.h">
+      <Filter>include\grpc++\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\async_unary_call.h">
+      <Filter>include\grpc++\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\call.h">
+      <Filter>include\grpc++\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\call_hook.h">
+      <Filter>include\grpc++\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\channel_interface.h">
+      <Filter>include\grpc++\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\client_context.h">
+      <Filter>include\grpc++\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\client_unary_call.h">
+      <Filter>include\grpc++\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\completion_queue.h">
+      <Filter>include\grpc++\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\completion_queue_tag.h">
+      <Filter>include\grpc++\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\config.h">
+      <Filter>include\grpc++\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\core_codegen_interface.h">
+      <Filter>include\grpc++\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\create_auth_context.h">
+      <Filter>include\grpc++\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\grpc_library.h">
+      <Filter>include\grpc++\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\method_handler_impl.h">
+      <Filter>include\grpc++\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\rpc_method.h">
+      <Filter>include\grpc++\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\rpc_service_method.h">
+      <Filter>include\grpc++\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\security\auth_context.h">
+      <Filter>include\grpc++\impl\codegen\security</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\serialization_traits.h">
+      <Filter>include\grpc++\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\server_context.h">
+      <Filter>include\grpc++\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\server_interface.h">
+      <Filter>include\grpc++\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\service_type.h">
+      <Filter>include\grpc++\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\status.h">
+      <Filter>include\grpc++\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\status_code_enum.h">
+      <Filter>include\grpc++\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\string_ref.h">
+      <Filter>include\grpc++\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\stub_options.h">
+      <Filter>include\grpc++\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\sync.h">
+      <Filter>include\grpc++\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\sync_cxx11.h">
+      <Filter>include\grpc++\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\sync_no_cxx11.h">
+      <Filter>include\grpc++\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\sync_stream.h">
+      <Filter>include\grpc++\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\time.h">
+      <Filter>include\grpc++\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\byte_buffer.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\byte_buffer_reader.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\compression_types.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\connectivity_state.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\grpc_types.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\propagation_bits.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\status.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\alloc.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_atomic.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_sync.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_windows.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\log.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\port_platform.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\slice.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\slice_buffer.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_generic.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_posix.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_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>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="$(SolutionDir)\..\src\cpp\ext\proto_server_reflection.h">
+      <Filter>src\cpp\ext</Filter>
+    </ClInclude>
+  </ItemGroup>
+
+  <ItemGroup>
+    <Filter Include="include">
+      <UniqueIdentifier>{e9441021-f78a-ec84-7efd-1883975feddb}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="include\grpc">
+      <UniqueIdentifier>{3b19b259-3bf4-c0fa-8e20-ed79acd63ac3}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="include\grpc++">
+      <UniqueIdentifier>{c66e66b4-a64e-79bf-40e8-1a1bac124a3d}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="include\grpc++\ext">
+      <UniqueIdentifier>{8d96203b-d3ce-2164-74a6-06e0ff2b09af}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="include\grpc++\impl">
+      <UniqueIdentifier>{4e57d72c-762f-20b1-bdb9-bc7088ca6fda}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="include\grpc++\impl\codegen">
+      <UniqueIdentifier>{0f0f3943-7a9d-2b03-7eb1-2fbad4199428}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="include\grpc++\impl\codegen\security">
+      <UniqueIdentifier>{e1b8bc6d-2cd2-1283-868a-dfd64c3dbab8}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="include\grpc\impl">
+      <UniqueIdentifier>{7bccc379-84fb-c1aa-19aa-a0cc09ac59ac}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="include\grpc\impl\codegen">
+      <UniqueIdentifier>{a1f1904b-e820-dd3c-b4b0-14a6e0ff9d19}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src">
+      <UniqueIdentifier>{5ec5476e-3d72-e3f9-4f05-3f7c31c13651}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\cpp">
+      <UniqueIdentifier>{a642ac8e-cec2-35d3-9a8a-78313d03b440}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\cpp\ext">
+      <UniqueIdentifier>{d0204618-0f6a-dbc6-cf41-ffc04e76075a}</UniqueIdentifier>
+    </Filter>
+  </ItemGroup>
+</Project>
+
diff --git a/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj b/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj
index 33860af..d0fca9b 100644
--- a/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj
+++ b/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj
@@ -147,9 +147,63 @@
   </ItemDefinitionGroup>
 
   <ItemGroup>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\async_stream.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\async_unary_call.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\call.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\call_hook.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\channel_interface.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\client_context.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\client_unary_call.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\completion_queue.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\completion_queue_tag.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\config.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\core_codegen_interface.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\create_auth_context.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\grpc_library.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\method_handler_impl.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\rpc_method.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\rpc_service_method.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\security\auth_context.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\serialization_traits.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\server_context.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\server_interface.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\service_type.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\status.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\status_code_enum.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\string_ref.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\stub_options.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\sync.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\sync_cxx11.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\sync_no_cxx11.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\sync_stream.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\time.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\byte_buffer.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\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\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" />
+  </ItemGroup>
+  <ItemGroup>
     <ClInclude Include="$(SolutionDir)\..\test\cpp\end2end\test_service_impl.h" />
     <ClInclude Include="$(SolutionDir)\..\test\cpp\util\byte_buffer_proto_helper.h" />
-    <ClInclude Include="$(SolutionDir)\..\test\cpp\util\cli_call.h" />
     <ClInclude Include="$(SolutionDir)\..\test\cpp\util\create_test_channel.h" />
     <ClInclude Include="$(SolutionDir)\..\test\cpp\util\string_ref_helper.h" />
     <ClInclude Include="$(SolutionDir)\..\test\cpp\util\subprocess.h" />
@@ -184,8 +238,6 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\cpp\util\byte_buffer_proto_helper.cc">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\test\cpp\util\cli_call.cc">
-    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\cpp\util\create_test_channel.cc">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\cpp\util\string_ref_helper.cc">
@@ -194,6 +246,8 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\cpp\util\test_credentials_provider.cc">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\cpp\codegen\codegen_init.cc">
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc++\grpc++.vcxproj">
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 b35ba1f..cc98c60 100644
--- a/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj.filters
@@ -16,9 +16,6 @@
     <ClCompile Include="$(SolutionDir)\..\test\cpp\util\byte_buffer_proto_helper.cc">
       <Filter>test\cpp\util</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\test\cpp\util\cli_call.cc">
-      <Filter>test\cpp\util</Filter>
-    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\cpp\util\create_test_channel.cc">
       <Filter>test\cpp\util</Filter>
     </ClCompile>
@@ -31,6 +28,170 @@
     <ClCompile Include="$(SolutionDir)\..\test\cpp\util\test_credentials_provider.cc">
       <Filter>test\cpp\util</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\cpp\codegen\codegen_init.cc">
+      <Filter>src\cpp\codegen</Filter>
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\async_stream.h">
+      <Filter>include\grpc++\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\async_unary_call.h">
+      <Filter>include\grpc++\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\call.h">
+      <Filter>include\grpc++\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\call_hook.h">
+      <Filter>include\grpc++\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\channel_interface.h">
+      <Filter>include\grpc++\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\client_context.h">
+      <Filter>include\grpc++\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\client_unary_call.h">
+      <Filter>include\grpc++\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\completion_queue.h">
+      <Filter>include\grpc++\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\completion_queue_tag.h">
+      <Filter>include\grpc++\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\config.h">
+      <Filter>include\grpc++\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\core_codegen_interface.h">
+      <Filter>include\grpc++\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\create_auth_context.h">
+      <Filter>include\grpc++\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\grpc_library.h">
+      <Filter>include\grpc++\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\method_handler_impl.h">
+      <Filter>include\grpc++\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\rpc_method.h">
+      <Filter>include\grpc++\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\rpc_service_method.h">
+      <Filter>include\grpc++\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\security\auth_context.h">
+      <Filter>include\grpc++\impl\codegen\security</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\serialization_traits.h">
+      <Filter>include\grpc++\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\server_context.h">
+      <Filter>include\grpc++\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\server_interface.h">
+      <Filter>include\grpc++\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\service_type.h">
+      <Filter>include\grpc++\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\status.h">
+      <Filter>include\grpc++\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\status_code_enum.h">
+      <Filter>include\grpc++\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\string_ref.h">
+      <Filter>include\grpc++\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\stub_options.h">
+      <Filter>include\grpc++\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\sync.h">
+      <Filter>include\grpc++\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\sync_cxx11.h">
+      <Filter>include\grpc++\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\sync_no_cxx11.h">
+      <Filter>include\grpc++\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\sync_stream.h">
+      <Filter>include\grpc++\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\time.h">
+      <Filter>include\grpc++\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\byte_buffer.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\byte_buffer_reader.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\compression_types.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\connectivity_state.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\grpc_types.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\propagation_bits.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\status.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\alloc.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_atomic.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_sync.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_windows.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\log.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\port_platform.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\slice.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\slice_buffer.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_generic.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_posix.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_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>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\config_protobuf.h">
+      <Filter>include\grpc++\impl\codegen</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="$(SolutionDir)\..\test\cpp\end2end\test_service_impl.h">
@@ -39,9 +200,6 @@
     <ClInclude Include="$(SolutionDir)\..\test\cpp\util\byte_buffer_proto_helper.h">
       <Filter>test\cpp\util</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\test\cpp\util\cli_call.h">
-      <Filter>test\cpp\util</Filter>
-    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\test\cpp\util\create_test_channel.h">
       <Filter>test\cpp\util</Filter>
     </ClInclude>
@@ -57,9 +215,39 @@
   </ItemGroup>
 
   <ItemGroup>
+    <Filter Include="include">
+      <UniqueIdentifier>{af3e8efd-71b5-c047-7b1f-9896ff6b9dae}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="include\grpc">
+      <UniqueIdentifier>{b8f8ac53-4ea7-9602-a5c8-592da3569a7e}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="include\grpc++">
+      <UniqueIdentifier>{e6ee8dea-0866-8e41-c115-c3a237f85295}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="include\grpc++\impl">
+      <UniqueIdentifier>{67705040-57a2-dd65-b4e9-291d6512b10a}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="include\grpc++\impl\codegen">
+      <UniqueIdentifier>{c977e49d-7e35-9e45-54c2-3ec17f4a2027}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="include\grpc++\impl\codegen\security">
+      <UniqueIdentifier>{28c9540f-2a90-17a6-a18c-c8452c2efd93}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="include\grpc\impl">
+      <UniqueIdentifier>{cb0bbb9c-2cd0-46eb-225d-8614a13f30a5}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="include\grpc\impl\codegen">
+      <UniqueIdentifier>{48b3f0ad-af42-c9fd-74ce-d47ad7ffa748}</UniqueIdentifier>
+    </Filter>
     <Filter Include="src">
       <UniqueIdentifier>{21f220cf-c756-4172-000b-e8a1f0888097}</UniqueIdentifier>
     </Filter>
+    <Filter Include="src\cpp">
+      <UniqueIdentifier>{4409f847-2173-ea03-724b-c9181ec50f07}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\cpp\codegen">
+      <UniqueIdentifier>{ba3b353d-1c24-1466-d62d-7da515f5e6f6}</UniqueIdentifier>
+    </Filter>
     <Filter Include="src\proto">
       <UniqueIdentifier>{58b0e1e0-f329-64ce-86e5-8f125c02b96e}</UniqueIdentifier>
     </Filter>
diff --git a/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj b/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj
index 895e223..03be485 100644
--- a/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj
+++ b/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj
@@ -263,14 +263,15 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\client_context.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\completion_queue.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\create_channel.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\create_channel_posix.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\generic\async_generic_service.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\generic\generic_stub.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\grpc++.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\call.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\client_unary_call.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\core_codegen.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\grpc_library.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\method_handler_impl.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\proto_utils.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\rpc_method.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\rpc_service_method.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\serialization_traits.h" />
@@ -291,10 +292,12 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\server.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\server_builder.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\server_context.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\server_posix.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\support\async_stream.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\support\async_unary_call.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\support\byte_buffer.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\support\channel_arguments.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\support\config.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\support\slice.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\support\status.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\support\status_code_enum.h" />
@@ -311,11 +314,11 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\client_unary_call.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\completion_queue.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\completion_queue_tag.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\config.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\core_codegen_interface.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\create_auth_context.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\grpc_library.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\method_handler_impl.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\proto_utils.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\rpc_method.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\rpc_service_method.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\security\auth_context.h" />
@@ -343,7 +346,7 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_atomic.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_sync.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_win32.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_windows.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\log.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\port_platform.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\slice.h" />
@@ -351,16 +354,11 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_generic.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_posix.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_win32.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_windows.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\time.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\config.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\config_protobuf.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\support\config.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\support\config_protobuf.h" />
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="$(SolutionDir)\..\src\cpp\client\create_channel_internal.h" />
-    <ClInclude Include="$(SolutionDir)\..\src\cpp\common\core_codegen.h" />
     <ClInclude Include="$(SolutionDir)\..\src\cpp\server\dynamic_thread_pool.h" />
     <ClInclude Include="$(SolutionDir)\..\src\cpp\server\thread_pool_interface.h" />
   </ItemGroup>
@@ -375,6 +373,8 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\client\create_channel_internal.cc">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\cpp\client\create_channel_posix.cc">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\client\credentials.cc">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\client\generic_stub.cc">
@@ -405,6 +405,8 @@
     </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>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\util\slice.cc">
diff --git a/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters b/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters
index ab305fa..ba99bc5 100644
--- a/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters
@@ -16,6 +16,9 @@
     <ClCompile Include="$(SolutionDir)\..\src\cpp\client\create_channel_internal.cc">
       <Filter>src\cpp\client</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\cpp\client\create_channel_posix.cc">
+      <Filter>src\cpp\client</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\client\credentials.cc">
       <Filter>src\cpp\client</Filter>
     </ClCompile>
@@ -61,6 +64,9 @@
     <ClCompile Include="$(SolutionDir)\..\src\cpp\server\server_credentials.cc">
       <Filter>src\cpp\server</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\cpp\server\server_posix.cc">
+      <Filter>src\cpp\server</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\util\byte_buffer.cc">
       <Filter>src\cpp\util</Filter>
     </ClCompile>
@@ -96,6 +102,9 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\create_channel.h">
       <Filter>include\grpc++</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\create_channel_posix.h">
+      <Filter>include\grpc++</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\generic\async_generic_service.h">
       <Filter>include\grpc++\generic</Filter>
     </ClInclude>
@@ -111,15 +120,15 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\client_unary_call.h">
       <Filter>include\grpc++\impl</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\core_codegen.h">
+      <Filter>include\grpc++\impl\codegen</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\grpc_library.h">
       <Filter>include\grpc++\impl</Filter>
     </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\method_handler_impl.h">
       <Filter>include\grpc++\impl</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\proto_utils.h">
-      <Filter>include\grpc++\impl</Filter>
-    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\rpc_method.h">
       <Filter>include\grpc++\impl</Filter>
     </ClInclude>
@@ -180,6 +189,9 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\server_context.h">
       <Filter>include\grpc++</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\server_posix.h">
+      <Filter>include\grpc++</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\support\async_stream.h">
       <Filter>include\grpc++\support</Filter>
     </ClInclude>
@@ -192,6 +204,9 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\support\channel_arguments.h">
       <Filter>include\grpc++\support</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\support\config.h">
+      <Filter>include\grpc++\support</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\support\slice.h">
       <Filter>include\grpc++\support</Filter>
     </ClInclude>
@@ -240,6 +255,9 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\completion_queue_tag.h">
       <Filter>include\grpc++\impl\codegen</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\config.h">
+      <Filter>include\grpc++\impl\codegen</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\core_codegen_interface.h">
       <Filter>include\grpc++\impl\codegen</Filter>
     </ClInclude>
@@ -252,9 +270,6 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\method_handler_impl.h">
       <Filter>include\grpc++\impl\codegen</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\proto_utils.h">
-      <Filter>include\grpc++\impl\codegen</Filter>
-    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\rpc_method.h">
       <Filter>include\grpc++\impl\codegen</Filter>
     </ClInclude>
@@ -336,7 +351,7 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_sync.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_win32.h">
+    <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">
@@ -360,32 +375,17 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_posix.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_win32.h">
+    <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.h">
-      <Filter>include\grpc++\impl\codegen</Filter>
-    </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\config_protobuf.h">
-      <Filter>include\grpc++\impl\codegen</Filter>
-    </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\support\config.h">
-      <Filter>include\grpc++\support</Filter>
-    </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\support\config_protobuf.h">
-      <Filter>include\grpc++\support</Filter>
-    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="$(SolutionDir)\..\src\cpp\client\create_channel_internal.h">
       <Filter>src\cpp\client</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\src\cpp\common\core_codegen.h">
-      <Filter>src\cpp\common</Filter>
-    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\cpp\server\dynamic_thread_pool.h">
       <Filter>src\cpp\server</Filter>
     </ClInclude>
diff --git a/vsprojects/vcxproj/grpc/grpc.vcxproj b/vsprojects/vcxproj/grpc/grpc.vcxproj
index e5379dc..1824b92 100644
--- a/vsprojects/vcxproj/grpc/grpc.vcxproj
+++ b/vsprojects/vcxproj/grpc/grpc.vcxproj
@@ -271,6 +271,7 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\byte_buffer_reader.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\compression.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\grpc.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\grpc_posix.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" />
@@ -283,7 +284,7 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_atomic.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_sync.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_win32.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_windows.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\log.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\port_platform.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\slice.h" />
@@ -291,9 +292,8 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_generic.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_posix.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_win32.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_windows.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\time.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\grpc_cronet.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\grpc_security.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\grpc_security_constants.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\census.h" />
@@ -316,6 +316,7 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\closure.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\endpoint.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\endpoint_pair.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\ev_poll_and_epoll_posix.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\ev_poll_posix.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\ev_posix.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\exec_ctx.h" />
@@ -324,6 +325,7 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\iomgr.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\iomgr_internal.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\iomgr_posix.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\polling_entity.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\pollset.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\pollset_set.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\pollset_set_windows.h" />
@@ -332,7 +334,7 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\sockaddr.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\sockaddr_posix.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\sockaddr_utils.h" />
-    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\sockaddr_win32.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\sockaddr_windows.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_utils_posix.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_windows.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_client.h" />
@@ -432,16 +434,18 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_config\subchannel_call_holder.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_config\subchannel_index.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_config\uri_parser.h" />
-    <ClInclude Include="$(SolutionDir)\..\third_party\objective_c\Cronet\cronet_c_for_grpc.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\lb_policy\grpclb\load_balancer_api.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\lb_policy\grpclb\proto\grpc\lb\v1\load_balancer.pb.h" />
     <ClInclude Include="$(SolutionDir)\..\third_party\nanopb\pb.h" />
     <ClInclude Include="$(SolutionDir)\..\third_party\nanopb\pb_common.h" />
     <ClInclude Include="$(SolutionDir)\..\third_party\nanopb\pb_decode.h" />
     <ClInclude Include="$(SolutionDir)\..\third_party\nanopb\pb_encode.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\load_reporting\load_reporting.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\load_reporting\load_reporting_filter.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\census\aggregation.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\census\census_interface.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\census\census_rpc_stats.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\census\gen\census.pb.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\census\grpc_filter.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\census\mlog.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\census\rpc_metric_id.h" />
@@ -463,7 +467,7 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\http_server_filter.c">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\lib\compression\compression_algorithm.c">
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\compression\compression.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\compression\message_compress.c">
     </ClCompile>
@@ -483,6 +487,8 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\endpoint_pair_windows.c">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\ev_poll_and_epoll_posix.c">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\ev_poll_posix.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\ev_posix.c">
@@ -499,6 +505,8 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\iomgr_windows.c">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\polling_entity.c">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\pollset_set_windows.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\pollset_windows.c">
@@ -671,7 +679,7 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\security\credentials\google_default\credentials_posix.c">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\lib\security\credentials\google_default\credentials_win32.c">
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\security\credentials\google_default\credentials_windows.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\security\credentials\google_default\google_default_credentials.c">
     </ClCompile>
@@ -753,13 +761,11 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\server\insecure\server_chttp2.c">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\server\insecure\server_chttp2_posix.c">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\client\insecure\channel_create.c">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\cronet\client\secure\cronet_channel_create.c">
-    </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\cronet\transport\cronet_api_dummy.c">
-    </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\cronet\transport\cronet_transport.c">
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\client\insecure\channel_create_posix.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\lb_policy\grpclb\load_balancer_api.c">
     </ClCompile>
@@ -779,8 +785,14 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\resolver\sockaddr\sockaddr_resolver.c">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\load_reporting\load_reporting.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\load_reporting\load_reporting_filter.c">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\census\context.c">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\census\gen\census.pb.c">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\census\grpc_context.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\census\grpc_filter.c">
diff --git a/vsprojects/vcxproj/grpc/grpc.vcxproj.filters b/vsprojects/vcxproj/grpc/grpc.vcxproj.filters
index 95a5a73..e77b79e 100644
--- a/vsprojects/vcxproj/grpc/grpc.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc/grpc.vcxproj.filters
@@ -25,7 +25,7 @@
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\http_server_filter.c">
       <Filter>src\core\lib\channel</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\lib\compression\compression_algorithm.c">
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\compression\compression.c">
       <Filter>src\core\lib\compression</Filter>
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\compression\message_compress.c">
@@ -55,6 +55,9 @@
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\endpoint_pair_windows.c">
       <Filter>src\core\lib\iomgr</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\ev_poll_and_epoll_posix.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\ev_poll_posix.c">
       <Filter>src\core\lib\iomgr</Filter>
     </ClCompile>
@@ -79,6 +82,9 @@
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\iomgr_windows.c">
       <Filter>src\core\lib\iomgr</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\polling_entity.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\pollset_set_windows.c">
       <Filter>src\core\lib\iomgr</Filter>
     </ClCompile>
@@ -337,7 +343,7 @@
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\security\credentials\google_default\credentials_posix.c">
       <Filter>src\core\lib\security\credentials\google_default</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\lib\security\credentials\google_default\credentials_win32.c">
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\security\credentials\google_default\credentials_windows.c">
       <Filter>src\core\lib\security\credentials\google_default</Filter>
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\security\credentials\google_default\google_default_credentials.c">
@@ -460,17 +466,14 @@
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\server\insecure\server_chttp2.c">
       <Filter>src\core\ext\transport\chttp2\server\insecure</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\server\insecure\server_chttp2_posix.c">
+      <Filter>src\core\ext\transport\chttp2\server\insecure</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\client\insecure\channel_create.c">
       <Filter>src\core\ext\transport\chttp2\client\insecure</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\cronet\client\secure\cronet_channel_create.c">
-      <Filter>src\core\ext\transport\cronet\client\secure</Filter>
-    </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\cronet\transport\cronet_api_dummy.c">
-      <Filter>src\core\ext\transport\cronet\transport</Filter>
-    </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\cronet\transport\cronet_transport.c">
-      <Filter>src\core\ext\transport\cronet\transport</Filter>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\client\insecure\channel_create_posix.c">
+      <Filter>src\core\ext\transport\chttp2\client\insecure</Filter>
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\lb_policy\grpclb\load_balancer_api.c">
       <Filter>src\core\ext\lb_policy\grpclb</Filter>
@@ -499,9 +502,18 @@
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\resolver\sockaddr\sockaddr_resolver.c">
       <Filter>src\core\ext\resolver\sockaddr</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\load_reporting\load_reporting.c">
+      <Filter>src\core\ext\load_reporting</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\load_reporting\load_reporting_filter.c">
+      <Filter>src\core\ext\load_reporting</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\census\context.c">
       <Filter>src\core\ext\census</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\census\gen\census.pb.c">
+      <Filter>src\core\ext\census\gen</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\census\grpc_context.c">
       <Filter>src\core\ext\census</Filter>
     </ClCompile>
@@ -543,6 +555,9 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\grpc.h">
       <Filter>include\grpc</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\grpc_posix.h">
+      <Filter>include\grpc</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\include\grpc\status.h">
       <Filter>include\grpc</Filter>
     </ClInclude>
@@ -579,7 +594,7 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_sync.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_win32.h">
+    <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">
@@ -603,15 +618,12 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_posix.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_win32.h">
+    <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_cronet.h">
-      <Filter>include\grpc</Filter>
-    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\include\grpc\grpc_security.h">
       <Filter>include\grpc</Filter>
     </ClInclude>
@@ -674,6 +686,9 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\endpoint_pair.h">
       <Filter>src\core\lib\iomgr</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\ev_poll_and_epoll_posix.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\ev_poll_posix.h">
       <Filter>src\core\lib\iomgr</Filter>
     </ClInclude>
@@ -698,6 +713,9 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\iomgr_posix.h">
       <Filter>src\core\lib\iomgr</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\polling_entity.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\pollset.h">
       <Filter>src\core\lib\iomgr</Filter>
     </ClInclude>
@@ -722,7 +740,7 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\sockaddr_utils.h">
       <Filter>src\core\lib\iomgr</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\sockaddr_win32.h">
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\sockaddr_windows.h">
       <Filter>src\core\lib\iomgr</Filter>
     </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_utils_posix.h">
@@ -1022,9 +1040,6 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_config\uri_parser.h">
       <Filter>src\core\ext\client_config</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\third_party\objective_c\Cronet\cronet_c_for_grpc.h">
-      <Filter>third_party\objective_c\Cronet</Filter>
-    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\lb_policy\grpclb\load_balancer_api.h">
       <Filter>src\core\ext\lb_policy\grpclb</Filter>
     </ClInclude>
@@ -1043,6 +1058,12 @@
     <ClInclude Include="$(SolutionDir)\..\third_party\nanopb\pb_encode.h">
       <Filter>third_party\nanopb</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\load_reporting\load_reporting.h">
+      <Filter>src\core\ext\load_reporting</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\load_reporting\load_reporting_filter.h">
+      <Filter>src\core\ext\load_reporting</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\census\aggregation.h">
       <Filter>src\core\ext\census</Filter>
     </ClInclude>
@@ -1052,6 +1073,9 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\census\census_rpc_stats.h">
       <Filter>src\core\ext\census</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\census\gen\census.pb.h">
+      <Filter>src\core\ext\census\gen</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\census\grpc_filter.h">
       <Filter>src\core\ext\census</Filter>
     </ClInclude>
@@ -1088,6 +1112,9 @@
     <Filter Include="src\core\ext\census">
       <UniqueIdentifier>{9bf70bd2-f553-11b2-c237-abd148971eea}</UniqueIdentifier>
     </Filter>
+    <Filter Include="src\core\ext\census\gen">
+      <UniqueIdentifier>{4a14dd37-5868-c656-7333-fa80574cbb07}</UniqueIdentifier>
+    </Filter>
     <Filter Include="src\core\ext\client_config">
       <UniqueIdentifier>{003725f8-37fc-80b5-deba-baae32caf915}</UniqueIdentifier>
     </Filter>
@@ -1115,6 +1142,9 @@
     <Filter Include="src\core\ext\lb_policy\round_robin">
       <UniqueIdentifier>{2472d352-cf94-f317-646e-72b769cea846}</UniqueIdentifier>
     </Filter>
+    <Filter Include="src\core\ext\load_reporting">
+      <UniqueIdentifier>{b6c863cd-a135-32e8-df03-02365f526f0d}</UniqueIdentifier>
+    </Filter>
     <Filter Include="src\core\ext\resolver">
       <UniqueIdentifier>{6bfa6808-9dcb-8990-deed-5cf58a149dda}</UniqueIdentifier>
     </Filter>
@@ -1157,18 +1187,6 @@
     <Filter Include="src\core\ext\transport\chttp2\transport">
       <UniqueIdentifier>{6f34254e-e69f-c9b4-156d-5024bade5408}</UniqueIdentifier>
     </Filter>
-    <Filter Include="src\core\ext\transport\cronet">
-      <UniqueIdentifier>{1e9c85e9-5522-7ef8-0017-7e19990a6194}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="src\core\ext\transport\cronet\client">
-      <UniqueIdentifier>{d0530883-75d9-b5f7-d594-26735a70ac7b}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="src\core\ext\transport\cronet\client\secure">
-      <UniqueIdentifier>{4fa6fe90-b7a8-5c8f-d629-db1e68d89eed}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="src\core\ext\transport\cronet\transport">
-      <UniqueIdentifier>{31518af8-5860-6d0d-ff78-4059fce29ec2}</UniqueIdentifier>
-    </Filter>
     <Filter Include="src\core\lib">
       <UniqueIdentifier>{5b2ded3f-84a5-f6b4-2060-286c7d1dc945}</UniqueIdentifier>
     </Filter>
@@ -1247,12 +1265,6 @@
     <Filter Include="third_party\nanopb">
       <UniqueIdentifier>{93d6596d-330c-1d27-6f84-3c840e57869e}</UniqueIdentifier>
     </Filter>
-    <Filter Include="third_party\objective_c">
-      <UniqueIdentifier>{3a56a516-857e-d2aa-95cc-11685baf4e8c}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="third_party\objective_c\Cronet">
-      <UniqueIdentifier>{a165c6e3-0776-6f40-7351-d7865668e220}</UniqueIdentifier>
-    </Filter>
   </ItemGroup>
 </Project>
 
diff --git a/vsprojects/vcxproj/grpc_cli_libs/grpc_cli_libs.vcxproj b/vsprojects/vcxproj/grpc_cli_libs/grpc_cli_libs.vcxproj
new file mode 100644
index 0000000..39cb1e0
--- /dev/null
+++ b/vsprojects/vcxproj/grpc_cli_libs/grpc_cli_libs.vcxproj
@@ -0,0 +1,176 @@
+<?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>{86E35862-43E8-F59E-F906-AFE0348AD3D2}</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>grpc_cli_libs</TargetName>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)'=='Release'">
+    <TargetName>grpc_cli_libs</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>Windows</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>Windows</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>Windows</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>Windows</SubSystem>
+      <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
+      <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+    </Link>
+  </ItemDefinitionGroup>
+
+  <ItemGroup>
+    <ClInclude Include="$(SolutionDir)\..\test\cpp\util\cli_call.h" />
+    <ClInclude Include="$(SolutionDir)\..\test\cpp\util\proto_file_parser.h" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="$(SolutionDir)\..\test\cpp\util\cli_call.cc">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\test\cpp\util\proto_file_parser.cc">
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc++\grpc++.vcxproj">
+      <Project>{C187A093-A0FE-489D-A40A-6E33DE0F9FEB}</Project>
+    </ProjectReference>
+    <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc_plugin_support\grpc_plugin_support.vcxproj">
+      <Project>{B6E81D84-2ACB-41B8-8781-493A944C7817}</Project>
+    </ProjectReference>
+  </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/grpc_cli_libs/grpc_cli_libs.vcxproj.filters b/vsprojects/vcxproj/grpc_cli_libs/grpc_cli_libs.vcxproj.filters
new file mode 100644
index 0000000..55ef18b
--- /dev/null
+++ b/vsprojects/vcxproj/grpc_cli_libs/grpc_cli_libs.vcxproj.filters
@@ -0,0 +1,32 @@
+<?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\cli_call.cc">
+      <Filter>test\cpp\util</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\test\cpp\util\proto_file_parser.cc">
+      <Filter>test\cpp\util</Filter>
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="$(SolutionDir)\..\test\cpp\util\cli_call.h">
+      <Filter>test\cpp\util</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\test\cpp\util\proto_file_parser.h">
+      <Filter>test\cpp\util</Filter>
+    </ClInclude>
+  </ItemGroup>
+
+  <ItemGroup>
+    <Filter Include="test">
+      <UniqueIdentifier>{16a32a9f-93aa-5812-5a5e-be659aaa76aa}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="test\cpp">
+      <UniqueIdentifier>{a6049b9f-9c4c-f814-ac67-dbd2b628b2d0}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="test\cpp\util">
+      <UniqueIdentifier>{30f91d14-0a6a-c8e8-ff23-6a83142d42fd}</UniqueIdentifier>
+    </Filter>
+  </ItemGroup>
+</Project>
+
diff --git a/vsprojects/vcxproj/grpc_plugin_support/grpc_plugin_support.vcxproj b/vsprojects/vcxproj/grpc_plugin_support/grpc_plugin_support.vcxproj
index a81d317..9828b8b 100644
--- a/vsprojects/vcxproj/grpc_plugin_support/grpc_plugin_support.vcxproj
+++ b/vsprojects/vcxproj/grpc_plugin_support/grpc_plugin_support.vcxproj
@@ -148,9 +148,6 @@
   </ItemDefinitionGroup>
 
   <ItemGroup>
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\support\config.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\support\config_protobuf.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\config.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\config_protobuf.h" />
   </ItemGroup>
   <ItemGroup>
diff --git a/vsprojects/vcxproj/grpc_plugin_support/grpc_plugin_support.vcxproj.filters b/vsprojects/vcxproj/grpc_plugin_support/grpc_plugin_support.vcxproj.filters
index b3d2dc2..27eb935 100644
--- a/vsprojects/vcxproj/grpc_plugin_support/grpc_plugin_support.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc_plugin_support/grpc_plugin_support.vcxproj.filters
@@ -21,15 +21,6 @@
     </ClCompile>
   </ItemGroup>
   <ItemGroup>
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\support\config.h">
-      <Filter>include\grpc++\support</Filter>
-    </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\support\config_protobuf.h">
-      <Filter>include\grpc++\support</Filter>
-    </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\config.h">
-      <Filter>include\grpc++\impl\codegen</Filter>
-    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\config_protobuf.h">
       <Filter>include\grpc++\impl\codegen</Filter>
     </ClInclude>
@@ -95,9 +86,6 @@
     <Filter Include="include\grpc++\impl\codegen">
       <UniqueIdentifier>{ec2a6e26-915b-ba1b-4f59-f361dc01105c}</UniqueIdentifier>
     </Filter>
-    <Filter Include="include\grpc++\support">
-      <UniqueIdentifier>{1c34d005-1ffb-8a31-881a-c6bb431cda69}</UniqueIdentifier>
-    </Filter>
     <Filter Include="src">
       <UniqueIdentifier>{94c9769a-a6cd-49fd-2b30-e52d2d02ed91}</UniqueIdentifier>
     </Filter>
diff --git a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj
index 90ad80f..bc5b153 100644
--- a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj
+++ b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj
@@ -262,6 +262,7 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\byte_buffer_reader.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\compression.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\grpc.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\grpc_posix.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" />
@@ -274,7 +275,7 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_atomic.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_sync.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_win32.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_windows.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\log.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\port_platform.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\slice.h" />
@@ -282,7 +283,7 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_generic.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_posix.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_win32.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_windows.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\time.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\census.h" />
   </ItemGroup>
@@ -304,6 +305,7 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\closure.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\endpoint.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\endpoint_pair.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\ev_poll_and_epoll_posix.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\ev_poll_posix.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\ev_posix.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\exec_ctx.h" />
@@ -312,6 +314,7 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\iomgr.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\iomgr_internal.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\iomgr_posix.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\polling_entity.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\pollset.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\pollset_set.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\pollset_set_windows.h" />
@@ -320,7 +323,7 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\sockaddr.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\sockaddr_posix.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\sockaddr_utils.h" />
-    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\sockaddr_win32.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\sockaddr_windows.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_utils_posix.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_windows.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_client.h" />
@@ -397,6 +400,8 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_config\subchannel_call_holder.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_config\subchannel_index.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_config\uri_parser.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\load_reporting\load_reporting.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\load_reporting\load_reporting_filter.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\lb_policy\grpclb\load_balancer_api.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\lb_policy\grpclb\proto\grpc\lb\v1\load_balancer.pb.h" />
     <ClInclude Include="$(SolutionDir)\..\third_party\nanopb\pb.h" />
@@ -406,6 +411,7 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\census\aggregation.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\census\census_interface.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\census\census_rpc_stats.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\census\gen\census.pb.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\census\grpc_filter.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\census\mlog.h" />
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\census\rpc_metric_id.h" />
@@ -429,7 +435,7 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\http_server_filter.c">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\lib\compression\compression_algorithm.c">
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\compression\compression.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\compression\message_compress.c">
     </ClCompile>
@@ -449,6 +455,8 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\endpoint_pair_windows.c">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\ev_poll_and_epoll_posix.c">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\ev_poll_posix.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\ev_posix.c">
@@ -465,6 +473,8 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\iomgr_windows.c">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\polling_entity.c">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\pollset_set_windows.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\pollset_windows.c">
@@ -579,6 +589,8 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\server\insecure\server_chttp2.c">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\server\insecure\server_chttp2_posix.c">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\transport\bin_encoder.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\transport\chttp2_plugin.c">
@@ -625,6 +637,8 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\client\insecure\channel_create.c">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\client\insecure\channel_create_posix.c">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_config\channel_connectivity.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_config\client_channel.c">
@@ -667,6 +681,10 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\resolver\sockaddr\sockaddr_resolver.c">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\load_reporting\load_reporting.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\load_reporting\load_reporting_filter.c">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\lb_policy\grpclb\load_balancer_api.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\lb_policy\grpclb\proto\grpc\lb\v1\load_balancer.pb.c">
@@ -683,6 +701,8 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\census\context.c">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\census\gen\census.pb.c">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\census\grpc_context.c">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\census\grpc_filter.c">
diff --git a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters
index 2b19c0f..792a2db 100644
--- a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters
@@ -28,7 +28,7 @@
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\http_server_filter.c">
       <Filter>src\core\lib\channel</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\core\lib\compression\compression_algorithm.c">
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\compression\compression.c">
       <Filter>src\core\lib\compression</Filter>
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\compression\message_compress.c">
@@ -58,6 +58,9 @@
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\endpoint_pair_windows.c">
       <Filter>src\core\lib\iomgr</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\ev_poll_and_epoll_posix.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\ev_poll_posix.c">
       <Filter>src\core\lib\iomgr</Filter>
     </ClCompile>
@@ -82,6 +85,9 @@
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\iomgr_windows.c">
       <Filter>src\core\lib\iomgr</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\polling_entity.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\pollset_set_windows.c">
       <Filter>src\core\lib\iomgr</Filter>
     </ClCompile>
@@ -253,6 +259,9 @@
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\server\insecure\server_chttp2.c">
       <Filter>src\core\ext\transport\chttp2\server\insecure</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\server\insecure\server_chttp2_posix.c">
+      <Filter>src\core\ext\transport\chttp2\server\insecure</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\transport\bin_encoder.c">
       <Filter>src\core\ext\transport\chttp2\transport</Filter>
     </ClCompile>
@@ -322,6 +331,9 @@
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\client\insecure\channel_create.c">
       <Filter>src\core\ext\transport\chttp2\client\insecure</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\transport\chttp2\client\insecure\channel_create_posix.c">
+      <Filter>src\core\ext\transport\chttp2\client\insecure</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\client_config\channel_connectivity.c">
       <Filter>src\core\ext\client_config</Filter>
     </ClCompile>
@@ -385,6 +397,12 @@
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\resolver\sockaddr\sockaddr_resolver.c">
       <Filter>src\core\ext\resolver\sockaddr</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\load_reporting\load_reporting.c">
+      <Filter>src\core\ext\load_reporting</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\load_reporting\load_reporting_filter.c">
+      <Filter>src\core\ext\load_reporting</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\lb_policy\grpclb\load_balancer_api.c">
       <Filter>src\core\ext\lb_policy\grpclb</Filter>
     </ClCompile>
@@ -409,6 +427,9 @@
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\census\context.c">
       <Filter>src\core\ext\census</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\ext\census\gen\census.pb.c">
+      <Filter>src\core\ext\census\gen</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\core\ext\census\grpc_context.c">
       <Filter>src\core\ext\census</Filter>
     </ClCompile>
@@ -450,6 +471,9 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\grpc.h">
       <Filter>include\grpc</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\grpc_posix.h">
+      <Filter>include\grpc</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\include\grpc\status.h">
       <Filter>include\grpc</Filter>
     </ClInclude>
@@ -486,7 +510,7 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_sync.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_win32.h">
+    <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">
@@ -510,7 +534,7 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_posix.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_win32.h">
+    <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">
@@ -572,6 +596,9 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\endpoint_pair.h">
       <Filter>src\core\lib\iomgr</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\ev_poll_and_epoll_posix.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\ev_poll_posix.h">
       <Filter>src\core\lib\iomgr</Filter>
     </ClInclude>
@@ -596,6 +623,9 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\iomgr_posix.h">
       <Filter>src\core\lib\iomgr</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\polling_entity.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\pollset.h">
       <Filter>src\core\lib\iomgr</Filter>
     </ClInclude>
@@ -620,7 +650,7 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\sockaddr_utils.h">
       <Filter>src\core\lib\iomgr</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\sockaddr_win32.h">
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\sockaddr_windows.h">
       <Filter>src\core\lib\iomgr</Filter>
     </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_utils_posix.h">
@@ -851,6 +881,12 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\client_config\uri_parser.h">
       <Filter>src\core\ext\client_config</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\load_reporting\load_reporting.h">
+      <Filter>src\core\ext\load_reporting</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\load_reporting\load_reporting_filter.h">
+      <Filter>src\core\ext\load_reporting</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\lb_policy\grpclb\load_balancer_api.h">
       <Filter>src\core\ext\lb_policy\grpclb</Filter>
     </ClInclude>
@@ -878,6 +914,9 @@
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\census\census_rpc_stats.h">
       <Filter>src\core\ext\census</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\ext\census\gen\census.pb.h">
+      <Filter>src\core\ext\census\gen</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\src\core\ext\census\grpc_filter.h">
       <Filter>src\core\ext\census</Filter>
     </ClInclude>
@@ -914,6 +953,9 @@
     <Filter Include="src\core\ext\census">
       <UniqueIdentifier>{3f21cd12-b8b9-18f8-8780-e21bbe2285d0}</UniqueIdentifier>
     </Filter>
+    <Filter Include="src\core\ext\census\gen">
+      <UniqueIdentifier>{dfe53168-57b0-3ac4-d8ba-07fd958cc8f5}</UniqueIdentifier>
+    </Filter>
     <Filter Include="src\core\ext\client_config">
       <UniqueIdentifier>{25fa8af3-0a05-987c-741f-fa8ff9d65d51}</UniqueIdentifier>
     </Filter>
@@ -941,6 +983,9 @@
     <Filter Include="src\core\ext\lb_policy\round_robin">
       <UniqueIdentifier>{e5fc1091-5d60-404f-775b-686ef4b3266f}</UniqueIdentifier>
     </Filter>
+    <Filter Include="src\core\ext\load_reporting">
+      <UniqueIdentifier>{2d6e3879-24c7-06e2-b415-40ab18a3b918}</UniqueIdentifier>
+    </Filter>
     <Filter Include="src\core\ext\resolver">
       <UniqueIdentifier>{88c78e27-267a-95df-07c5-50e5fbc2f40c}</UniqueIdentifier>
     </Filter>
diff --git a/vsprojects/vcxproj/qps/qps.vcxproj b/vsprojects/vcxproj/qps/qps.vcxproj
index a57b740..004cf7c 100644
--- a/vsprojects/vcxproj/qps/qps.vcxproj
+++ b/vsprojects/vcxproj/qps/qps.vcxproj
@@ -152,7 +152,7 @@
     <ClInclude Include="$(SolutionDir)\..\test\cpp\qps\histogram.h" />
     <ClInclude Include="$(SolutionDir)\..\test\cpp\qps\interarrival.h" />
     <ClInclude Include="$(SolutionDir)\..\test\cpp\qps\limit_cores.h" />
-    <ClInclude Include="$(SolutionDir)\..\test\cpp\qps\perf_db_client.h" />
+    <ClInclude Include="$(SolutionDir)\..\test\cpp\qps\parse_json.h" />
     <ClInclude Include="$(SolutionDir)\..\test\cpp\qps\qps_worker.h" />
     <ClInclude Include="$(SolutionDir)\..\test\cpp\qps\report.h" />
     <ClInclude Include="$(SolutionDir)\..\test\cpp\qps\server.h" />
@@ -201,14 +201,6 @@
     </ClCompile>
     <ClInclude Include="$(SolutionDir)\..\src\proto\grpc\testing\services.grpc.pb.h">
     </ClInclude>
-    <ClCompile Include="$(SolutionDir)\..\src\proto\grpc\testing\perf_db.pb.cc">
-    </ClCompile>
-    <ClInclude Include="$(SolutionDir)\..\src\proto\grpc\testing\perf_db.pb.h">
-    </ClInclude>
-    <ClCompile Include="$(SolutionDir)\..\src\proto\grpc\testing\perf_db.grpc.pb.cc">
-    </ClCompile>
-    <ClInclude Include="$(SolutionDir)\..\src\proto\grpc\testing\perf_db.grpc.pb.h">
-    </ClInclude>
     <ClCompile Include="$(SolutionDir)\..\test\cpp\qps\client_async.cc">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\cpp\qps\client_sync.cc">
@@ -217,7 +209,7 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\cpp\qps\limit_cores.cc">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\test\cpp\qps\perf_db_client.cc">
+    <ClCompile Include="$(SolutionDir)\..\test\cpp\qps\parse_json.cc">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\cpp\qps\qps_worker.cc">
     </ClCompile>
diff --git a/vsprojects/vcxproj/qps/qps.vcxproj.filters b/vsprojects/vcxproj/qps/qps.vcxproj.filters
index eeb9555..d3a440b 100644
--- a/vsprojects/vcxproj/qps/qps.vcxproj.filters
+++ b/vsprojects/vcxproj/qps/qps.vcxproj.filters
@@ -16,9 +16,6 @@
     <ClCompile Include="$(SolutionDir)\..\src\proto\grpc\testing\services.proto">
       <Filter>src\proto\grpc\testing</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\proto\grpc\testing\perf_db.proto">
-      <Filter>src\proto\grpc\testing</Filter>
-    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\cpp\qps\client_async.cc">
       <Filter>test\cpp\qps</Filter>
     </ClCompile>
@@ -31,7 +28,7 @@
     <ClCompile Include="$(SolutionDir)\..\test\cpp\qps\limit_cores.cc">
       <Filter>test\cpp\qps</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\test\cpp\qps\perf_db_client.cc">
+    <ClCompile Include="$(SolutionDir)\..\test\cpp\qps\parse_json.cc">
       <Filter>test\cpp\qps</Filter>
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\cpp\qps\qps_worker.cc">
@@ -69,7 +66,7 @@
     <ClInclude Include="$(SolutionDir)\..\test\cpp\qps\limit_cores.h">
       <Filter>test\cpp\qps</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\test\cpp\qps\perf_db_client.h">
+    <ClInclude Include="$(SolutionDir)\..\test\cpp\qps\parse_json.h">
       <Filter>test\cpp\qps</Filter>
     </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\test\cpp\qps\qps_worker.h">
diff --git a/vsprojects/vcxproj/test/cli_call_test/cli_call_test.vcxproj b/vsprojects/vcxproj/test/cli_call_test/cli_call_test.vcxproj
index b5d2fc6..40fe559 100644
--- a/vsprojects/vcxproj/test/cli_call_test/cli_call_test.vcxproj
+++ b/vsprojects/vcxproj/test/cli_call_test/cli_call_test.vcxproj
@@ -164,6 +164,9 @@
     </ClCompile>
   </ItemGroup>
   <ItemGroup>
+    <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc_cli_libs\grpc_cli_libs.vcxproj">
+      <Project>{86E35862-43E8-F59E-F906-AFE0348AD3D2}</Project>
+    </ProjectReference>
     <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc++_test_util\grpc++_test_util.vcxproj">
       <Project>{0BE77741-552A-929B-A497-4EF7ECE17A64}</Project>
     </ProjectReference>
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 34e939c..e608f7e 100644
--- a/vsprojects/vcxproj/test/codegen_test_full/codegen_test_full.vcxproj
+++ b/vsprojects/vcxproj/test/codegen_test_full/codegen_test_full.vcxproj
@@ -169,11 +169,11 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\client_unary_call.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\completion_queue.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\completion_queue_tag.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\config.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\core_codegen_interface.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\create_auth_context.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\grpc_library.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\method_handler_impl.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\proto_utils.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\rpc_method.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\rpc_service_method.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\security\auth_context.h" />
@@ -201,7 +201,7 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_atomic.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_sync.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_win32.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_windows.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\log.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\port_platform.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\slice.h" />
@@ -209,10 +209,8 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_generic.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_posix.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_win32.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_windows.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\time.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\config.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\config_protobuf.h" />
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="$(SolutionDir)\..\src\proto\grpc\testing\control.pb.cc">
@@ -239,14 +237,6 @@
     </ClCompile>
     <ClInclude Include="$(SolutionDir)\..\src\proto\grpc\testing\payloads.grpc.pb.h">
     </ClInclude>
-    <ClCompile Include="$(SolutionDir)\..\src\proto\grpc\testing\perf_db.pb.cc">
-    </ClCompile>
-    <ClInclude Include="$(SolutionDir)\..\src\proto\grpc\testing\perf_db.pb.h">
-    </ClInclude>
-    <ClCompile Include="$(SolutionDir)\..\src\proto\grpc\testing\perf_db.grpc.pb.cc">
-    </ClCompile>
-    <ClInclude Include="$(SolutionDir)\..\src\proto\grpc\testing\perf_db.grpc.pb.h">
-    </ClInclude>
     <ClCompile Include="$(SolutionDir)\..\src\proto\grpc\testing\services.pb.cc">
     </ClCompile>
     <ClInclude Include="$(SolutionDir)\..\src\proto\grpc\testing\services.pb.h">
@@ -265,8 +255,6 @@
     </ClInclude>
     <ClCompile Include="$(SolutionDir)\..\test\cpp\codegen\codegen_test_full.cc">
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\cpp\codegen\codegen_init.cc">
-    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc++\grpc++.vcxproj">
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 d662365..8fc8f39 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
@@ -10,9 +10,6 @@
     <ClCompile Include="$(SolutionDir)\..\src\proto\grpc\testing\payloads.proto">
       <Filter>src\proto\grpc\testing</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\proto\grpc\testing\perf_db.proto">
-      <Filter>src\proto\grpc\testing</Filter>
-    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\proto\grpc\testing\services.proto">
       <Filter>src\proto\grpc\testing</Filter>
     </ClCompile>
@@ -22,9 +19,6 @@
     <ClCompile Include="$(SolutionDir)\..\test\cpp\codegen\codegen_test_full.cc">
       <Filter>test\cpp\codegen</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\cpp\codegen\codegen_init.cc">
-      <Filter>src\cpp\codegen</Filter>
-    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\async_stream.h">
@@ -54,6 +48,9 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\completion_queue_tag.h">
       <Filter>include\grpc++\impl\codegen</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\config.h">
+      <Filter>include\grpc++\impl\codegen</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\core_codegen_interface.h">
       <Filter>include\grpc++\impl\codegen</Filter>
     </ClInclude>
@@ -66,9 +63,6 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\method_handler_impl.h">
       <Filter>include\grpc++\impl\codegen</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\proto_utils.h">
-      <Filter>include\grpc++\impl\codegen</Filter>
-    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\rpc_method.h">
       <Filter>include\grpc++\impl\codegen</Filter>
     </ClInclude>
@@ -150,7 +144,7 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_sync.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_win32.h">
+    <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">
@@ -174,18 +168,12 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_posix.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_win32.h">
+    <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.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>
   </ItemGroup>
 
   <ItemGroup>
@@ -216,12 +204,6 @@
     <Filter Include="src">
       <UniqueIdentifier>{909027fc-be54-d7d9-3e0b-b034a6f7ff8f}</UniqueIdentifier>
     </Filter>
-    <Filter Include="src\cpp">
-      <UniqueIdentifier>{0944bc3e-4288-3a9e-81df-b4eb0910e74f}</UniqueIdentifier>
-    </Filter>
-    <Filter Include="src\cpp\codegen">
-      <UniqueIdentifier>{88566202-70b0-f87e-2ce8-3cd61e5a57da}</UniqueIdentifier>
-    </Filter>
     <Filter Include="src\proto">
       <UniqueIdentifier>{84c6b0c4-1143-abcf-cc7b-3ee6ef87f16a}</UniqueIdentifier>
     </Filter>
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 890d77d..3331c61 100644
--- a/vsprojects/vcxproj/test/codegen_test_minimal/codegen_test_minimal.vcxproj
+++ b/vsprojects/vcxproj/test/codegen_test_minimal/codegen_test_minimal.vcxproj
@@ -169,11 +169,11 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\client_unary_call.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\completion_queue.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\completion_queue_tag.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\config.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\core_codegen_interface.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\create_auth_context.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\grpc_library.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\method_handler_impl.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\proto_utils.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\rpc_method.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\rpc_service_method.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\security\auth_context.h" />
@@ -201,7 +201,7 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_atomic.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_sync.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_win32.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_windows.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\log.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\port_platform.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\slice.h" />
@@ -209,10 +209,8 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_generic.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_posix.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_win32.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_windows.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\time.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\config.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\config_protobuf.h" />
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="$(SolutionDir)\..\src\proto\grpc\testing\control.pb.cc">
@@ -239,14 +237,6 @@
     </ClCompile>
     <ClInclude Include="$(SolutionDir)\..\src\proto\grpc\testing\payloads.grpc.pb.h">
     </ClInclude>
-    <ClCompile Include="$(SolutionDir)\..\src\proto\grpc\testing\perf_db.pb.cc">
-    </ClCompile>
-    <ClInclude Include="$(SolutionDir)\..\src\proto\grpc\testing\perf_db.pb.h">
-    </ClInclude>
-    <ClCompile Include="$(SolutionDir)\..\src\proto\grpc\testing\perf_db.grpc.pb.cc">
-    </ClCompile>
-    <ClInclude Include="$(SolutionDir)\..\src\proto\grpc\testing\perf_db.grpc.pb.h">
-    </ClInclude>
     <ClCompile Include="$(SolutionDir)\..\src\proto\grpc\testing\services.pb.cc">
     </ClCompile>
     <ClInclude Include="$(SolutionDir)\..\src\proto\grpc\testing\services.pb.h">
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 4e0ba65..a8ff115 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
@@ -10,9 +10,6 @@
     <ClCompile Include="$(SolutionDir)\..\src\proto\grpc\testing\payloads.proto">
       <Filter>src\proto\grpc\testing</Filter>
     </ClCompile>
-    <ClCompile Include="$(SolutionDir)\..\src\proto\grpc\testing\perf_db.proto">
-      <Filter>src\proto\grpc\testing</Filter>
-    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\proto\grpc\testing\services.proto">
       <Filter>src\proto\grpc\testing</Filter>
     </ClCompile>
@@ -54,6 +51,9 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\completion_queue_tag.h">
       <Filter>include\grpc++\impl\codegen</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\config.h">
+      <Filter>include\grpc++\impl\codegen</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\core_codegen_interface.h">
       <Filter>include\grpc++\impl\codegen</Filter>
     </ClInclude>
@@ -66,9 +66,6 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\method_handler_impl.h">
       <Filter>include\grpc++\impl\codegen</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\proto_utils.h">
-      <Filter>include\grpc++\impl\codegen</Filter>
-    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\rpc_method.h">
       <Filter>include\grpc++\impl\codegen</Filter>
     </ClInclude>
@@ -150,7 +147,7 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_sync.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_win32.h">
+    <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">
@@ -174,18 +171,12 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_posix.h">
       <Filter>include\grpc\impl\codegen</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_win32.h">
+    <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.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>
   </ItemGroup>
 
   <ItemGroup>
diff --git a/vsprojects/vcxproj/test/end2end/fixtures/h2_loadreporting_nosec_test/h2_loadreporting_nosec_test.vcxproj b/vsprojects/vcxproj/test/end2end/fixtures/h2_loadreporting_nosec_test/h2_loadreporting_nosec_test.vcxproj
new file mode 100644
index 0000000..6a6ac5e
--- /dev/null
+++ b/vsprojects/vcxproj/test/end2end/fixtures/h2_loadreporting_nosec_test/h2_loadreporting_nosec_test.vcxproj
@@ -0,0 +1,202 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.props" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\1.0.204.1.props')" />
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{679EA55C-7399-53E8-79F0-82FBDB3DDE07}</ProjectGuid>
+    <IgnoreWarnIntDirInTempDetected>true</IgnoreWarnIntDirInTempDetected>
+    <IntDir>$(SolutionDir)IntDir\$(MSBuildProjectName)\</IntDir>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(VisualStudioVersion)' == '10.0'" Label="Configuration">
+    <PlatformToolset>v100</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(VisualStudioVersion)' == '11.0'" Label="Configuration">
+    <PlatformToolset>v110</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(VisualStudioVersion)' == '12.0'" Label="Configuration">
+    <PlatformToolset>v120</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(VisualStudioVersion)' == '14.0'" Label="Configuration">
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)'=='Debug'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)'=='Release'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="$(SolutionDir)\..\vsprojects\global.props" />
+    <Import Project="$(SolutionDir)\..\vsprojects\openssl.props" />
+    <Import Project="$(SolutionDir)\..\vsprojects\winsock.props" />
+    <Import Project="$(SolutionDir)\..\vsprojects\zlib.props" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup Condition="'$(Configuration)'=='Debug'">
+    <TargetName>h2_loadreporting_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_loadreporting_nosec_test</TargetName>
+    <Linkage-grpc_dependencies_zlib>static</Linkage-grpc_dependencies_zlib>
+    <Configuration-grpc_dependencies_zlib>Release</Configuration-grpc_dependencies_zlib>
+    <Linkage-grpc_dependencies_openssl>static</Linkage-grpc_dependencies_openssl>
+    <Configuration-grpc_dependencies_openssl>Release</Configuration-grpc_dependencies_openssl>
+  </PropertyGroup>
+    <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+      <MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
+      <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+
+    <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+      <MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
+      <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+
+    <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>MaxSpeed</Optimization>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <SDLCheck>true</SDLCheck>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+      <MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
+      <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+    </Link>
+  </ItemDefinitionGroup>
+
+    <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>MaxSpeed</Optimization>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <SDLCheck>true</SDLCheck>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+      <MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
+      <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+    </Link>
+  </ItemDefinitionGroup>
+
+  <ItemGroup>
+    <ClCompile Include="$(SolutionDir)\..\test\core\end2end\fixtures\h2_loadreporting.c">
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\test/end2end/tests\end2end_nosec_tests\end2end_nosec_tests.vcxproj">
+      <Project>{47C2CB41-4E9F-58B6-F606-F6FAED5D00ED}</Project>
+    </ProjectReference>
+    <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc_test_util_unsecure\grpc_test_util_unsecure.vcxproj">
+      <Project>{0A7E7F92-FDEA-40F1-A9EC-3BA484F98BBF}</Project>
+    </ProjectReference>
+    <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc_unsecure\grpc_unsecure.vcxproj">
+      <Project>{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}</Project>
+    </ProjectReference>
+    <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\gpr_test_util\gpr_test_util.vcxproj">
+      <Project>{EAB0A629-17A9-44DB-B5FF-E91A721FE037}</Project>
+    </ProjectReference>
+    <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\gpr\gpr.vcxproj">
+      <Project>{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}</Project>
+    </ProjectReference>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="packages.config" />
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  <Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\native\grpc.dependencies.zlib.redist.targets" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\native\grpc.dependencies\grpc.dependencies.zlib.targets')" />
+  <Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.10\build\native\grpc.dependencies.zlib.targets" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.10\build\native\grpc.dependencies\grpc.dependencies.zlib.targets')" />
+  <Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\native\grpc.dependencies.openssl.redist.targets" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\native\grpc.dependencies\grpc.dependencies.openssl.targets')" />
+  <Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.targets" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies\grpc.dependencies.openssl.targets')" />
+  </ImportGroup>
+  <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
+    <PropertyGroup>
+      <ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them.  For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
+    </PropertyGroup>
+    <Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\native\grpc.dependencies.zlib.redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\native\grpc.dependencies.zlib.redist.targets')" />
+    <Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.10\build\native\grpc.dependencies.zlib.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.10\build\native\grpc.dependencies.zlib.targets')" />
+    <Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\native\grpc.dependencies.openssl.redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\native\grpc.dependencies.openssl.redist.targets')" />
+    <Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.props')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.props')" />
+    <Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.targets')" />
+  </Target>
+</Project>
+
diff --git a/vsprojects/vcxproj/test/end2end/fixtures/h2_loadreporting_nosec_test/h2_loadreporting_nosec_test.vcxproj.filters b/vsprojects/vcxproj/test/end2end/fixtures/h2_loadreporting_nosec_test/h2_loadreporting_nosec_test.vcxproj.filters
new file mode 100644
index 0000000..4ed1bb0
--- /dev/null
+++ b/vsprojects/vcxproj/test/end2end/fixtures/h2_loadreporting_nosec_test/h2_loadreporting_nosec_test.vcxproj.filters
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <ClCompile Include="$(SolutionDir)\..\test\core\end2end\fixtures\h2_loadreporting.c">
+      <Filter>test\core\end2end\fixtures</Filter>
+    </ClCompile>
+  </ItemGroup>
+
+  <ItemGroup>
+    <Filter Include="test">
+      <UniqueIdentifier>{8adc89fb-e447-77bc-c462-3dba6abcf344}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="test\core">
+      <UniqueIdentifier>{3c2c01f5-2a18-1bee-6ee0-217d415e2a95}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="test\core\end2end">
+      <UniqueIdentifier>{3efa0f41-5802-6a8e-36ee-f246a201a1a5}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="test\core\end2end\fixtures">
+      <UniqueIdentifier>{366eb24f-49e9-d57f-e20f-729d1e0fb892}</UniqueIdentifier>
+    </Filter>
+  </ItemGroup>
+</Project>
+
diff --git a/vsprojects/vcxproj/test/end2end/fixtures/h2_loadreporting_test/h2_loadreporting_test.vcxproj b/vsprojects/vcxproj/test/end2end/fixtures/h2_loadreporting_test/h2_loadreporting_test.vcxproj
new file mode 100644
index 0000000..2076548
--- /dev/null
+++ b/vsprojects/vcxproj/test/end2end/fixtures/h2_loadreporting_test/h2_loadreporting_test.vcxproj
@@ -0,0 +1,202 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.props" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\1.0.204.1.props')" />
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{B107130E-EA33-C114-9CB6-78A18C929F64}</ProjectGuid>
+    <IgnoreWarnIntDirInTempDetected>true</IgnoreWarnIntDirInTempDetected>
+    <IntDir>$(SolutionDir)IntDir\$(MSBuildProjectName)\</IntDir>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(VisualStudioVersion)' == '10.0'" Label="Configuration">
+    <PlatformToolset>v100</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(VisualStudioVersion)' == '11.0'" Label="Configuration">
+    <PlatformToolset>v110</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(VisualStudioVersion)' == '12.0'" Label="Configuration">
+    <PlatformToolset>v120</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(VisualStudioVersion)' == '14.0'" Label="Configuration">
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)'=='Debug'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)'=='Release'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="$(SolutionDir)\..\vsprojects\global.props" />
+    <Import Project="$(SolutionDir)\..\vsprojects\openssl.props" />
+    <Import Project="$(SolutionDir)\..\vsprojects\winsock.props" />
+    <Import Project="$(SolutionDir)\..\vsprojects\zlib.props" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup Condition="'$(Configuration)'=='Debug'">
+    <TargetName>h2_loadreporting_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_loadreporting_test</TargetName>
+    <Linkage-grpc_dependencies_zlib>static</Linkage-grpc_dependencies_zlib>
+    <Configuration-grpc_dependencies_zlib>Release</Configuration-grpc_dependencies_zlib>
+    <Linkage-grpc_dependencies_openssl>static</Linkage-grpc_dependencies_openssl>
+    <Configuration-grpc_dependencies_openssl>Release</Configuration-grpc_dependencies_openssl>
+  </PropertyGroup>
+    <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+      <MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
+      <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+
+    <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <SDLCheck>true</SDLCheck>
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+      <MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
+      <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
+    </Link>
+  </ItemDefinitionGroup>
+
+    <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>MaxSpeed</Optimization>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <SDLCheck>true</SDLCheck>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+      <MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
+      <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+    </Link>
+  </ItemDefinitionGroup>
+
+    <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <PrecompiledHeader>NotUsing</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>MaxSpeed</Optimization>
+      <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <SDLCheck>true</SDLCheck>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <TreatWarningAsError>true</TreatWarningAsError>
+      <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat>
+      <MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild>
+    </ClCompile>
+    <Link>
+      <SubSystem>Console</SubSystem>
+      <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation>
+      <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+    </Link>
+  </ItemDefinitionGroup>
+
+  <ItemGroup>
+    <ClCompile Include="$(SolutionDir)\..\test\core\end2end\fixtures\h2_loadreporting.c">
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\test/end2end/tests\end2end_tests\end2end_tests.vcxproj">
+      <Project>{1F1F9084-2A93-B80E-364F-5754894AFAB4}</Project>
+    </ProjectReference>
+    <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc_test_util\grpc_test_util.vcxproj">
+      <Project>{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}</Project>
+    </ProjectReference>
+    <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc\grpc.vcxproj">
+      <Project>{29D16885-7228-4C31-81ED-5F9187C7F2A9}</Project>
+    </ProjectReference>
+    <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\gpr_test_util\gpr_test_util.vcxproj">
+      <Project>{EAB0A629-17A9-44DB-B5FF-E91A721FE037}</Project>
+    </ProjectReference>
+    <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\gpr\gpr.vcxproj">
+      <Project>{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}</Project>
+    </ProjectReference>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="packages.config" />
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  <Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\native\grpc.dependencies.zlib.redist.targets" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\native\grpc.dependencies\grpc.dependencies.zlib.targets')" />
+  <Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.10\build\native\grpc.dependencies.zlib.targets" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.10\build\native\grpc.dependencies\grpc.dependencies.zlib.targets')" />
+  <Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\native\grpc.dependencies.openssl.redist.targets" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\native\grpc.dependencies\grpc.dependencies.openssl.targets')" />
+  <Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.targets" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies\grpc.dependencies.openssl.targets')" />
+  </ImportGroup>
+  <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
+    <PropertyGroup>
+      <ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them.  For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
+    </PropertyGroup>
+    <Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\native\grpc.dependencies.zlib.redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\native\grpc.dependencies.zlib.redist.targets')" />
+    <Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.10\build\native\grpc.dependencies.zlib.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.10\build\native\grpc.dependencies.zlib.targets')" />
+    <Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\native\grpc.dependencies.openssl.redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\native\grpc.dependencies.openssl.redist.targets')" />
+    <Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.props')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.props')" />
+    <Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.targets')" />
+  </Target>
+</Project>
+
diff --git a/vsprojects/vcxproj/test/end2end/fixtures/h2_loadreporting_test/h2_loadreporting_test.vcxproj.filters b/vsprojects/vcxproj/test/end2end/fixtures/h2_loadreporting_test/h2_loadreporting_test.vcxproj.filters
new file mode 100644
index 0000000..afe5432
--- /dev/null
+++ b/vsprojects/vcxproj/test/end2end/fixtures/h2_loadreporting_test/h2_loadreporting_test.vcxproj.filters
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <ClCompile Include="$(SolutionDir)\..\test\core\end2end\fixtures\h2_loadreporting.c">
+      <Filter>test\core\end2end\fixtures</Filter>
+    </ClCompile>
+  </ItemGroup>
+
+  <ItemGroup>
+    <Filter Include="test">
+      <UniqueIdentifier>{8f73760a-74dc-05ef-65e1-fa8c44ccf918}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="test\core">
+      <UniqueIdentifier>{a280079e-b626-333e-0636-8fe6eb788ca1}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="test\core\end2end">
+      <UniqueIdentifier>{c1aa73d6-503a-06c0-42b2-0793a4805e96}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="test\core\end2end\fixtures">
+      <UniqueIdentifier>{3e738e89-dc27-f929-cc8f-1aa94c24345b}</UniqueIdentifier>
+    </Filter>
+  </ItemGroup>
+</Project>
+
diff --git a/vsprojects/vcxproj/test/grpc_cli/grpc_cli.vcxproj b/vsprojects/vcxproj/test/grpc_cli/grpc_cli.vcxproj
index eeb0e8c..cd844d1 100644
--- a/vsprojects/vcxproj/test/grpc_cli/grpc_cli.vcxproj
+++ b/vsprojects/vcxproj/test/grpc_cli/grpc_cli.vcxproj
@@ -164,6 +164,9 @@
     </ClCompile>
   </ItemGroup>
   <ItemGroup>
+    <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc_cli_libs\grpc_cli_libs.vcxproj">
+      <Project>{86E35862-43E8-F59E-F906-AFE0348AD3D2}</Project>
+    </ProjectReference>
     <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc++_test_util\grpc++_test_util.vcxproj">
       <Project>{0BE77741-552A-929B-A497-4EF7ECE17A64}</Project>
     </ProjectReference>
diff --git a/vsprojects/vcxproj/test/proto_server_reflection_test/proto_server_reflection_test.vcxproj b/vsprojects/vcxproj/test/proto_server_reflection_test/proto_server_reflection_test.vcxproj
new file mode 100644
index 0000000..27fc168
--- /dev/null
+++ b/vsprojects/vcxproj/test/proto_server_reflection_test/proto_server_reflection_test.vcxproj
@@ -0,0 +1,215 @@
+<?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>{1881E6A1-EAD4-A68C-9727-FF1956B66185}</ProjectGuid>
+    <IgnoreWarnIntDirInTempDetected>true</IgnoreWarnIntDirInTempDetected>
+    <IntDir>$(SolutionDir)IntDir\$(MSBuildProjectName)\</IntDir>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(VisualStudioVersion)' == '10.0'" Label="Configuration">
+    <PlatformToolset>v100</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(VisualStudioVersion)' == '11.0'" Label="Configuration">
+    <PlatformToolset>v110</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(VisualStudioVersion)' == '12.0'" Label="Configuration">
+    <PlatformToolset>v120</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(VisualStudioVersion)' == '14.0'" Label="Configuration">
+    <PlatformToolset>v140</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)'=='Debug'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)'=='Release'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+    <Import Project="$(SolutionDir)\..\vsprojects\cpptest.props" />
+    <Import Project="$(SolutionDir)\..\vsprojects\global.props" />
+    <Import Project="$(SolutionDir)\..\vsprojects\openssl.props" />
+    <Import Project="$(SolutionDir)\..\vsprojects\protobuf.props" />
+    <Import Project="$(SolutionDir)\..\vsprojects\winsock.props" />
+    <Import Project="$(SolutionDir)\..\vsprojects\zlib.props" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup Condition="'$(Configuration)'=='Debug'">
+    <TargetName>proto_server_reflection_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>proto_server_reflection_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>
+    <ClInclude Include="$(SolutionDir)\..\test\cpp\util\proto_reflection_descriptor_database.h" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="$(SolutionDir)\..\test\cpp\end2end\proto_server_reflection_test.cc">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\test\cpp\util\proto_reflection_descriptor_database.cc">
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc++_reflection\grpc++_reflection.vcxproj">
+      <Project>{5F575402-3F89-5D1A-6910-9DB8BF5D2BAB}</Project>
+    </ProjectReference>
+    <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc++_test_util\grpc++_test_util.vcxproj">
+      <Project>{0BE77741-552A-929B-A497-4EF7ECE17A64}</Project>
+    </ProjectReference>
+    <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc_test_util\grpc_test_util.vcxproj">
+      <Project>{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}</Project>
+    </ProjectReference>
+    <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc++\grpc++.vcxproj">
+      <Project>{C187A093-A0FE-489D-A40A-6E33DE0F9FEB}</Project>
+    </ProjectReference>
+    <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc\grpc.vcxproj">
+      <Project>{29D16885-7228-4C31-81ED-5F9187C7F2A9}</Project>
+    </ProjectReference>
+    <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\gpr_test_util\gpr_test_util.vcxproj">
+      <Project>{EAB0A629-17A9-44DB-B5FF-E91A721FE037}</Project>
+    </ProjectReference>
+    <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\gpr\gpr.vcxproj">
+      <Project>{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}</Project>
+    </ProjectReference>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="packages.config" />
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  <Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\native\grpc.dependencies.zlib.redist.targets" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\native\grpc.dependencies\grpc.dependencies.zlib.targets')" />
+  <Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.10\build\native\grpc.dependencies.zlib.targets" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.10\build\native\grpc.dependencies\grpc.dependencies.zlib.targets')" />
+  <Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\native\grpc.dependencies.openssl.redist.targets" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\native\grpc.dependencies\grpc.dependencies.openssl.targets')" />
+  <Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.targets" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies\grpc.dependencies.openssl.targets')" />
+  </ImportGroup>
+  <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
+    <PropertyGroup>
+      <ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them.  For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
+    </PropertyGroup>
+    <Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\native\grpc.dependencies.zlib.redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\native\grpc.dependencies.zlib.redist.targets')" />
+    <Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.10\build\native\grpc.dependencies.zlib.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.10\build\native\grpc.dependencies.zlib.targets')" />
+    <Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\native\grpc.dependencies.openssl.redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\native\grpc.dependencies.openssl.redist.targets')" />
+    <Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.props')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.props')" />
+    <Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.targets')" />
+  </Target>
+</Project>
+
diff --git a/vsprojects/vcxproj/test/proto_server_reflection_test/proto_server_reflection_test.vcxproj.filters b/vsprojects/vcxproj/test/proto_server_reflection_test/proto_server_reflection_test.vcxproj.filters
new file mode 100644
index 0000000..6d6e5c1
--- /dev/null
+++ b/vsprojects/vcxproj/test/proto_server_reflection_test/proto_server_reflection_test.vcxproj.filters
@@ -0,0 +1,32 @@
+<?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\end2end\proto_server_reflection_test.cc">
+      <Filter>test\cpp\end2end</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\test\cpp\util\proto_reflection_descriptor_database.cc">
+      <Filter>test\cpp\util</Filter>
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="$(SolutionDir)\..\test\cpp\util\proto_reflection_descriptor_database.h">
+      <Filter>test\cpp\util</Filter>
+    </ClInclude>
+  </ItemGroup>
+
+  <ItemGroup>
+    <Filter Include="test">
+      <UniqueIdentifier>{354831a1-52fb-6364-b568-c8c49bfb8d29}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="test\cpp">
+      <UniqueIdentifier>{b4d957ef-f9fd-2a14-078c-b72f80096f70}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="test\cpp\end2end">
+      <UniqueIdentifier>{130f224c-89a5-54ea-7045-b54b4188c52b}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="test\cpp\util">
+      <UniqueIdentifier>{aae81aad-5563-fceb-1461-10fdec84c5b0}</UniqueIdentifier>
+    </Filter>
+  </ItemGroup>
+</Project>
+
diff --git a/vsprojects/vcxproj/test/qps_json_driver/qps_json_driver.vcxproj b/vsprojects/vcxproj/test/qps_json_driver/qps_json_driver.vcxproj
index 3884c10..d1dea3e 100644
--- a/vsprojects/vcxproj/test/qps_json_driver/qps_json_driver.vcxproj
+++ b/vsprojects/vcxproj/test/qps_json_driver/qps_json_driver.vcxproj
@@ -160,11 +160,6 @@
   </ItemDefinitionGroup>
 
   <ItemGroup>
-    <ClInclude Include="$(SolutionDir)\..\test\cpp\qps\parse_json.h" />
-  </ItemGroup>
-  <ItemGroup>
-    <ClCompile Include="$(SolutionDir)\..\test\cpp\qps\parse_json.cc">
-    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\cpp\qps\qps_json_driver.cc">
     </ClCompile>
   </ItemGroup>
diff --git a/vsprojects/vcxproj/test/qps_json_driver/qps_json_driver.vcxproj.filters b/vsprojects/vcxproj/test/qps_json_driver/qps_json_driver.vcxproj.filters
index cde967f..62b9be8 100644
--- a/vsprojects/vcxproj/test/qps_json_driver/qps_json_driver.vcxproj.filters
+++ b/vsprojects/vcxproj/test/qps_json_driver/qps_json_driver.vcxproj.filters
@@ -1,18 +1,10 @@
 <?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\qps\parse_json.cc">
-      <Filter>test\cpp\qps</Filter>
-    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\cpp\qps\qps_json_driver.cc">
       <Filter>test\cpp\qps</Filter>
     </ClCompile>
   </ItemGroup>
-  <ItemGroup>
-    <ClInclude Include="$(SolutionDir)\..\test\cpp\qps\parse_json.h">
-      <Filter>test\cpp\qps</Filter>
-    </ClInclude>
-  </ItemGroup>
 
   <ItemGroup>
     <Filter Include="test">