Merge pull request #7831 from thunderboltsid/remove-skipif-pypy

remove skipIf from TypeSmokeTest (issue 7672)
diff --git a/.gitignore b/.gitignore
index 75a73a1..ed015b3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,5 @@
 # C/C++ build outputs
+.build/
 bins
 gens
 libs
diff --git a/.gitmodules b/.gitmodules
index d41b8d5..92d5ac3 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -17,3 +17,6 @@
 [submodule "third_party/nanopb"]
 	path = third_party/nanopb
 	url = https://github.com/nanopb/nanopb.git
+[submodule "third_party/thrift"]
+	path = third_party/thrift
+	url = https://github.com/apache/thrift.git
diff --git a/BUILD b/BUILD
index b7044c5..e3db970 100644
--- a/BUILD
+++ b/BUILD
@@ -36,6 +36,8 @@
 
 licenses(["notice"])  # 3-clause BSD
 
+exports_files(["LICENSE"])
+
 package(default_visibility = ["//visibility:public"])
 
 
@@ -508,6 +510,7 @@
     "include/grpc/compression.h",
     "include/grpc/grpc.h",
     "include/grpc/grpc_posix.h",
+    "include/grpc/grpc_security_constants.h",
     "include/grpc/status.h",
     "include/grpc/impl/codegen/byte_buffer.h",
     "include/grpc/impl/codegen/byte_buffer_reader.h",
@@ -531,7 +534,6 @@
     "include/grpc/impl/codegen/sync_windows.h",
     "include/grpc/impl/codegen/time.h",
     "include/grpc/grpc_security.h",
-    "include/grpc/grpc_security_constants.h",
     "include/grpc/census.h",
   ],
   includes = [
@@ -867,6 +869,7 @@
     "include/grpc/compression.h",
     "include/grpc/grpc.h",
     "include/grpc/grpc_posix.h",
+    "include/grpc/grpc_security_constants.h",
     "include/grpc/status.h",
     "include/grpc/impl/codegen/byte_buffer.h",
     "include/grpc/impl/codegen/byte_buffer_reader.h",
@@ -891,7 +894,6 @@
     "include/grpc/impl/codegen/time.h",
     "include/grpc/grpc_cronet.h",
     "include/grpc/grpc_security.h",
-    "include/grpc/grpc_security_constants.h",
   ],
   includes = [
     "include",
@@ -1204,6 +1206,7 @@
     "include/grpc/compression.h",
     "include/grpc/grpc.h",
     "include/grpc/grpc_posix.h",
+    "include/grpc/grpc_security_constants.h",
     "include/grpc/status.h",
     "include/grpc/impl/codegen/byte_buffer.h",
     "include/grpc/impl/codegen/byte_buffer_reader.h",
@@ -1254,6 +1257,86 @@
     "src/cpp/common/channel_filter.h",
     "src/cpp/server/dynamic_thread_pool.h",
     "src/cpp/server/thread_pool_interface.h",
+    "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/handshaker.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/error.h",
+    "src/core/lib/iomgr/ev_epoll_linux.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/load_file.h",
+    "src/core/lib/iomgr/network_status_tracker.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/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/timeout_encoding.h",
+    "src/core/lib/transport/transport.h",
+    "src/core/lib/transport/transport_impl.h",
     "src/cpp/client/secure_credentials.cc",
     "src/cpp/common/auth_property_iterator.cc",
     "src/cpp/common/secure_auth_context.cc",
@@ -1287,6 +1370,95 @@
     "src/cpp/util/status.cc",
     "src/cpp/util/string_ref.cc",
     "src/cpp/util/time.cc",
+    "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/handshaker.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/error.c",
+    "src/core/lib/iomgr/ev_epoll_linux.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/load_file.c",
+    "src/core/lib/iomgr/network_status_tracker.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/timeout_encoding.c",
+    "src/core/lib/transport/transport.c",
+    "src/core/lib/transport/transport_op_string.c",
     "src/cpp/codegen/codegen_init.cc",
   ],
   hdrs = [
@@ -1337,6 +1509,34 @@
     "include/grpc++/support/stub_options.h",
     "include/grpc++/support/sync_stream.h",
     "include/grpc++/support/time.h",
+    "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/grpc_security_constants.h",
+    "include/grpc/status.h",
+    "include/grpc/impl/codegen/byte_buffer.h",
+    "include/grpc/impl/codegen/byte_buffer_reader.h",
+    "include/grpc/impl/codegen/compression_types.h",
+    "include/grpc/impl/codegen/connectivity_state.h",
+    "include/grpc/impl/codegen/grpc_types.h",
+    "include/grpc/impl/codegen/propagation_bits.h",
+    "include/grpc/impl/codegen/status.h",
+    "include/grpc/impl/codegen/alloc.h",
+    "include/grpc/impl/codegen/atm.h",
+    "include/grpc/impl/codegen/atm_gcc_atomic.h",
+    "include/grpc/impl/codegen/atm_gcc_sync.h",
+    "include/grpc/impl/codegen/atm_windows.h",
+    "include/grpc/impl/codegen/log.h",
+    "include/grpc/impl/codegen/port_platform.h",
+    "include/grpc/impl/codegen/slice.h",
+    "include/grpc/impl/codegen/slice_buffer.h",
+    "include/grpc/impl/codegen/sync.h",
+    "include/grpc/impl/codegen/sync_generic.h",
+    "include/grpc/impl/codegen/sync_posix.h",
+    "include/grpc/impl/codegen/sync_windows.h",
+    "include/grpc/impl/codegen/time.h",
     "include/grpc++/impl/codegen/async_stream.h",
     "include/grpc++/impl/codegen/async_unary_call.h",
     "include/grpc++/impl/codegen/call.h",
@@ -1367,27 +1567,6 @@
     "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",
@@ -1397,6 +1576,7 @@
     "//external:libssl",
     "//external:protobuf_clib",
     ":grpc",
+    ":gpr",
   ],
 )
 
@@ -1487,6 +1667,86 @@
     "src/cpp/common/channel_filter.h",
     "src/cpp/server/dynamic_thread_pool.h",
     "src/cpp/server/thread_pool_interface.h",
+    "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/handshaker.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/error.h",
+    "src/core/lib/iomgr/ev_epoll_linux.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/load_file.h",
+    "src/core/lib/iomgr/network_status_tracker.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/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/timeout_encoding.h",
+    "src/core/lib/transport/transport.h",
+    "src/core/lib/transport/transport_impl.h",
     "src/cpp/common/insecure_create_auth_context.cc",
     "src/cpp/client/channel.cc",
     "src/cpp/client/client_context.cc",
@@ -1515,6 +1775,95 @@
     "src/cpp/util/status.cc",
     "src/cpp/util/string_ref.cc",
     "src/cpp/util/time.cc",
+    "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/handshaker.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/error.c",
+    "src/core/lib/iomgr/ev_epoll_linux.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/load_file.c",
+    "src/core/lib/iomgr/network_status_tracker.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/timeout_encoding.c",
+    "src/core/lib/transport/transport.c",
+    "src/core/lib/transport/transport_op_string.c",
     "src/cpp/codegen/codegen_init.cc",
   ],
   hdrs = [
@@ -1565,6 +1914,34 @@
     "include/grpc++/support/stub_options.h",
     "include/grpc++/support/sync_stream.h",
     "include/grpc++/support/time.h",
+    "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/grpc_security_constants.h",
+    "include/grpc/status.h",
+    "include/grpc/impl/codegen/byte_buffer.h",
+    "include/grpc/impl/codegen/byte_buffer_reader.h",
+    "include/grpc/impl/codegen/compression_types.h",
+    "include/grpc/impl/codegen/connectivity_state.h",
+    "include/grpc/impl/codegen/grpc_types.h",
+    "include/grpc/impl/codegen/propagation_bits.h",
+    "include/grpc/impl/codegen/status.h",
+    "include/grpc/impl/codegen/alloc.h",
+    "include/grpc/impl/codegen/atm.h",
+    "include/grpc/impl/codegen/atm_gcc_atomic.h",
+    "include/grpc/impl/codegen/atm_gcc_sync.h",
+    "include/grpc/impl/codegen/atm_windows.h",
+    "include/grpc/impl/codegen/log.h",
+    "include/grpc/impl/codegen/port_platform.h",
+    "include/grpc/impl/codegen/slice.h",
+    "include/grpc/impl/codegen/slice_buffer.h",
+    "include/grpc/impl/codegen/sync.h",
+    "include/grpc/impl/codegen/sync_generic.h",
+    "include/grpc/impl/codegen/sync_posix.h",
+    "include/grpc/impl/codegen/sync_windows.h",
+    "include/grpc/impl/codegen/time.h",
     "include/grpc++/impl/codegen/async_stream.h",
     "include/grpc++/impl/codegen/async_unary_call.h",
     "include/grpc++/impl/codegen/call.h",
@@ -1595,27 +1972,6 @@
     "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",
@@ -1625,7 +1981,6 @@
     "//external:protobuf_clib",
     ":gpr",
     ":grpc_unsecure",
-    ":grpc",
   ],
 )
 
@@ -2001,6 +2356,7 @@
     "include/grpc/compression.h",
     "include/grpc/grpc.h",
     "include/grpc/grpc_posix.h",
+    "include/grpc/grpc_security_constants.h",
     "include/grpc/status.h",
     "include/grpc/impl/codegen/byte_buffer.h",
     "include/grpc/impl/codegen/byte_buffer_reader.h",
@@ -2024,7 +2380,6 @@
     "include/grpc/impl/codegen/sync_windows.h",
     "include/grpc/impl/codegen/time.h",
     "include/grpc/grpc_security.h",
-    "include/grpc/grpc_security_constants.h",
     "include/grpc/census.h",
     "src/core/lib/channel/channel_args.h",
     "src/core/lib/channel/channel_stack.h",
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 15e5ec9..fbcc6bb 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -48,6 +48,12 @@
 set(PACKAGE_BUGREPORT "https://github.com/grpc/grpc/issues/")
 project(${PACKAGE_NAME} C CXX)
 
+if (NOT MSVC)
+  set(gRPC_INSTALL ON CACHE BOOL "Generate installation target")
+else()
+  set(gRPC_INSTALL OFF CACHE BOOL "Generate installation target")
+endif()
+
 set(gRPC_ZLIB_PROVIDER "module" CACHE STRING "Provider of zlib library")
 set_property(CACHE gRPC_ZLIB_PROVIDER PROPERTY STRINGS "module" "package")
 
@@ -59,6 +65,10 @@
 
 set(gRPC_USE_PROTO_LITE OFF CACHE BOOL "Use the protobuf-lite library")
 
+if (MSVC)
+  add_definitions( -D_WIN32_WINNT=0x600 )
+endif()
+
 if (gRPC_USE_PROTO_LITE)
   set(_gRPC_PROTOBUF_LIBRARY_NAME "libprotobuf-lite")
   add_definitions("-DGRPC_USE_PROTO_LITE")
@@ -98,6 +108,7 @@
     set(PROTOBUF_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/third_party/protobuf)
   endif()
   if(EXISTS "${PROTOBUF_ROOT_DIR}/cmake/CMakeLists.txt")
+    set(protobuf_MSVC_STATIC_RUNTIME OFF CACHE BOOL "Link static runtime libraries")
     add_subdirectory(${PROTOBUF_ROOT_DIR}/cmake third_party/protobuf)
     if(TARGET ${_gRPC_PROTOBUF_LIBRARY_NAME})
       set(_gRPC_PROTOBUF_LIBRARIES ${_gRPC_PROTOBUF_LIBRARY_NAME})
@@ -269,11 +280,13 @@
 endforeach()
 
   
-install(TARGETS gpr EXPORT gRPCTargets
-  RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
-  LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
-  ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
-)
+if (gRPC_INSTALL)
+  install(TARGETS gpr EXPORT gRPCTargets
+    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+    ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
+  )
+endif()
 
   
 add_library(grpc
@@ -491,6 +504,7 @@
   include/grpc/compression.h
   include/grpc/grpc.h
   include/grpc/grpc_posix.h
+  include/grpc/grpc_security_constants.h
   include/grpc/status.h
   include/grpc/impl/codegen/byte_buffer.h
   include/grpc/impl/codegen/byte_buffer_reader.h
@@ -514,7 +528,6 @@
   include/grpc/impl/codegen/sync_windows.h
   include/grpc/impl/codegen/time.h
   include/grpc/grpc_security.h
-  include/grpc/grpc_security_constants.h
   include/grpc/census.h
 )
   string(REPLACE "include/" "" _path ${_hdr})
@@ -525,11 +538,13 @@
 endforeach()
 
   
-install(TARGETS grpc EXPORT gRPCTargets
-  RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
-  LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
-  ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
-)
+if (gRPC_INSTALL)
+  install(TARGETS grpc EXPORT gRPCTargets
+    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+    ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
+  )
+endif()
 
   
 add_library(grpc_cronet
@@ -720,6 +735,7 @@
   include/grpc/compression.h
   include/grpc/grpc.h
   include/grpc/grpc_posix.h
+  include/grpc/grpc_security_constants.h
   include/grpc/status.h
   include/grpc/impl/codegen/byte_buffer.h
   include/grpc/impl/codegen/byte_buffer_reader.h
@@ -744,7 +760,6 @@
   include/grpc/impl/codegen/time.h
   include/grpc/grpc_cronet.h
   include/grpc/grpc_security.h
-  include/grpc/grpc_security_constants.h
 )
   string(REPLACE "include/" "" _path ${_hdr})
   get_filename_component(_path ${_path} PATH)
@@ -754,11 +769,13 @@
 endforeach()
 
   
-install(TARGETS grpc_cronet EXPORT gRPCTargets
-  RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
-  LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
-  ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
-)
+if (gRPC_INSTALL)
+  install(TARGETS grpc_cronet EXPORT gRPCTargets
+    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+    ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
+  )
+endif()
 
   
 add_library(grpc_unsecure
@@ -945,6 +962,7 @@
   include/grpc/compression.h
   include/grpc/grpc.h
   include/grpc/grpc_posix.h
+  include/grpc/grpc_security_constants.h
   include/grpc/status.h
   include/grpc/impl/codegen/byte_buffer.h
   include/grpc/impl/codegen/byte_buffer_reader.h
@@ -977,11 +995,13 @@
 endforeach()
 
   
-install(TARGETS grpc_unsecure EXPORT gRPCTargets
-  RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
-  LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
-  ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
-)
+if (gRPC_INSTALL)
+  install(TARGETS grpc_unsecure EXPORT gRPCTargets
+    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+    ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
+  )
+endif()
 
   
 add_library(grpc++
@@ -1018,6 +1038,95 @@
   src/cpp/util/status.cc
   src/cpp/util/string_ref.cc
   src/cpp/util/time.cc
+  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/handshaker.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/error.c
+  src/core/lib/iomgr/ev_epoll_linux.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/load_file.c
+  src/core/lib/iomgr/network_status_tracker.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/timeout_encoding.c
+  src/core/lib/transport/transport.c
+  src/core/lib/transport/transport_op_string.c
   src/cpp/codegen/codegen_init.cc
 )
 
@@ -1035,6 +1144,7 @@
   ${_gRPC_SSL_LIBRARIES}
   ${_gRPC_PROTOBUF_LIBRARIES}
   grpc
+  gpr
 )
 
 foreach(_hdr
@@ -1085,6 +1195,34 @@
   include/grpc++/support/stub_options.h
   include/grpc++/support/sync_stream.h
   include/grpc++/support/time.h
+  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/grpc_security_constants.h
+  include/grpc/status.h
+  include/grpc/impl/codegen/byte_buffer.h
+  include/grpc/impl/codegen/byte_buffer_reader.h
+  include/grpc/impl/codegen/compression_types.h
+  include/grpc/impl/codegen/connectivity_state.h
+  include/grpc/impl/codegen/grpc_types.h
+  include/grpc/impl/codegen/propagation_bits.h
+  include/grpc/impl/codegen/status.h
+  include/grpc/impl/codegen/alloc.h
+  include/grpc/impl/codegen/atm.h
+  include/grpc/impl/codegen/atm_gcc_atomic.h
+  include/grpc/impl/codegen/atm_gcc_sync.h
+  include/grpc/impl/codegen/atm_windows.h
+  include/grpc/impl/codegen/log.h
+  include/grpc/impl/codegen/port_platform.h
+  include/grpc/impl/codegen/slice.h
+  include/grpc/impl/codegen/slice_buffer.h
+  include/grpc/impl/codegen/sync.h
+  include/grpc/impl/codegen/sync_generic.h
+  include/grpc/impl/codegen/sync_posix.h
+  include/grpc/impl/codegen/sync_windows.h
+  include/grpc/impl/codegen/time.h
   include/grpc++/impl/codegen/async_stream.h
   include/grpc++/impl/codegen/async_unary_call.h
   include/grpc++/impl/codegen/call.h
@@ -1115,27 +1253,6 @@
   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
 )
   string(REPLACE "include/" "" _path ${_hdr})
   get_filename_component(_path ${_path} PATH)
@@ -1145,11 +1262,13 @@
 endforeach()
 
   
-install(TARGETS grpc++ EXPORT gRPCTargets
-  RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
-  LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
-  ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
-)
+if (gRPC_INSTALL)
+  install(TARGETS grpc++ EXPORT gRPCTargets
+    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+    ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
+  )
+endif()
 
   
 add_library(grpc++_reflection
@@ -1238,11 +1357,13 @@
 endforeach()
 
   
-install(TARGETS grpc++_reflection EXPORT gRPCTargets
-  RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
-  LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
-  ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
-)
+if (gRPC_INSTALL)
+  install(TARGETS grpc++_reflection EXPORT gRPCTargets
+    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+    ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
+  )
+endif()
 
   
 add_library(grpc++_unsecure
@@ -1274,6 +1395,95 @@
   src/cpp/util/status.cc
   src/cpp/util/string_ref.cc
   src/cpp/util/time.cc
+  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/handshaker.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/error.c
+  src/core/lib/iomgr/ev_epoll_linux.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/load_file.c
+  src/core/lib/iomgr/network_status_tracker.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/timeout_encoding.c
+  src/core/lib/transport/transport.c
+  src/core/lib/transport/transport_op_string.c
   src/cpp/codegen/codegen_init.cc
 )
 
@@ -1291,7 +1501,6 @@
   ${_gRPC_PROTOBUF_LIBRARIES}
   gpr
   grpc_unsecure
-  grpc
 )
 
 foreach(_hdr
@@ -1342,6 +1551,34 @@
   include/grpc++/support/stub_options.h
   include/grpc++/support/sync_stream.h
   include/grpc++/support/time.h
+  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/grpc_security_constants.h
+  include/grpc/status.h
+  include/grpc/impl/codegen/byte_buffer.h
+  include/grpc/impl/codegen/byte_buffer_reader.h
+  include/grpc/impl/codegen/compression_types.h
+  include/grpc/impl/codegen/connectivity_state.h
+  include/grpc/impl/codegen/grpc_types.h
+  include/grpc/impl/codegen/propagation_bits.h
+  include/grpc/impl/codegen/status.h
+  include/grpc/impl/codegen/alloc.h
+  include/grpc/impl/codegen/atm.h
+  include/grpc/impl/codegen/atm_gcc_atomic.h
+  include/grpc/impl/codegen/atm_gcc_sync.h
+  include/grpc/impl/codegen/atm_windows.h
+  include/grpc/impl/codegen/log.h
+  include/grpc/impl/codegen/port_platform.h
+  include/grpc/impl/codegen/slice.h
+  include/grpc/impl/codegen/slice_buffer.h
+  include/grpc/impl/codegen/sync.h
+  include/grpc/impl/codegen/sync_generic.h
+  include/grpc/impl/codegen/sync_posix.h
+  include/grpc/impl/codegen/sync_windows.h
+  include/grpc/impl/codegen/time.h
   include/grpc++/impl/codegen/async_stream.h
   include/grpc++/impl/codegen/async_unary_call.h
   include/grpc++/impl/codegen/call.h
@@ -1372,27 +1609,6 @@
   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
 )
   string(REPLACE "include/" "" _path ${_hdr})
   get_filename_component(_path ${_path} PATH)
@@ -1402,11 +1618,13 @@
 endforeach()
 
   
-install(TARGETS grpc++_unsecure EXPORT gRPCTargets
-  RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
-  LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
-  ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
-)
+if (gRPC_INSTALL)
+  install(TARGETS grpc++_unsecure EXPORT gRPCTargets
+    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+    ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
+  )
+endif()
 
   
 add_library(grpc_plugin_support
@@ -1442,11 +1660,13 @@
 endforeach()
 
   
-install(TARGETS grpc_plugin_support EXPORT gRPCTargets
-  RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
-  LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
-  ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
-)
+if (gRPC_INSTALL)
+  install(TARGETS grpc_plugin_support EXPORT gRPCTargets
+    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+    ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
+  )
+endif()
 
   
 add_library(grpc_csharp_ext
@@ -1469,11 +1689,13 @@
 
 
   
-install(TARGETS grpc_csharp_ext EXPORT gRPCTargets
-  RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
-  LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
-  ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
-)
+if (gRPC_INSTALL)
+  install(TARGETS grpc_csharp_ext EXPORT gRPCTargets
+    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+    ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
+  )
+endif()
 
 
 
@@ -1496,11 +1718,13 @@
 )
 
 
-install(TARGETS gen_hpack_tables EXPORT gRPCTargets
-  RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
-  LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
-  ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
-)
+if (gRPC_INSTALL)
+  install(TARGETS gen_hpack_tables EXPORT gRPCTargets
+    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+    ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
+  )
+endif()
 
 
 add_executable(gen_legal_metadata_characters
@@ -1518,11 +1742,13 @@
 
 
 
-install(TARGETS gen_legal_metadata_characters EXPORT gRPCTargets
-  RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
-  LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
-  ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
-)
+if (gRPC_INSTALL)
+  install(TARGETS gen_legal_metadata_characters EXPORT gRPCTargets
+    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+    ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
+  )
+endif()
 
 
 add_executable(grpc_create_jwt
@@ -1545,11 +1771,13 @@
 )
 
 
-install(TARGETS grpc_create_jwt EXPORT gRPCTargets
-  RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
-  LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
-  ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
-)
+if (gRPC_INSTALL)
+  install(TARGETS grpc_create_jwt EXPORT gRPCTargets
+    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+    ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
+  )
+endif()
 
 
 add_executable(grpc_print_google_default_creds_token
@@ -1571,11 +1799,13 @@
 )
 
 
-install(TARGETS grpc_print_google_default_creds_token EXPORT gRPCTargets
-  RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
-  LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
-  ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
-)
+if (gRPC_INSTALL)
+  install(TARGETS grpc_print_google_default_creds_token EXPORT gRPCTargets
+    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+    ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
+  )
+endif()
 
 
 add_executable(grpc_verify_jwt
@@ -1597,11 +1827,13 @@
 )
 
 
-install(TARGETS grpc_verify_jwt EXPORT gRPCTargets
-  RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
-  LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
-  ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
-)
+if (gRPC_INSTALL)
+  install(TARGETS grpc_verify_jwt EXPORT gRPCTargets
+    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+    ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
+  )
+endif()
 
 
 add_executable(grpc_cpp_plugin
@@ -1623,11 +1855,13 @@
 )
 
 
-install(TARGETS grpc_cpp_plugin EXPORT gRPCTargets
-  RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
-  LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
-  ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
-)
+if (gRPC_INSTALL)
+  install(TARGETS grpc_cpp_plugin EXPORT gRPCTargets
+    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+    ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
+  )
+endif()
 
 
 add_executable(grpc_csharp_plugin
@@ -1649,11 +1883,13 @@
 )
 
 
-install(TARGETS grpc_csharp_plugin EXPORT gRPCTargets
-  RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
-  LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
-  ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
-)
+if (gRPC_INSTALL)
+  install(TARGETS grpc_csharp_plugin EXPORT gRPCTargets
+    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+    ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
+  )
+endif()
 
 
 add_executable(grpc_node_plugin
@@ -1675,11 +1911,13 @@
 )
 
 
-install(TARGETS grpc_node_plugin EXPORT gRPCTargets
-  RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
-  LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
-  ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
-)
+if (gRPC_INSTALL)
+  install(TARGETS grpc_node_plugin EXPORT gRPCTargets
+    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+    ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
+  )
+endif()
 
 
 add_executable(grpc_objective_c_plugin
@@ -1701,11 +1939,13 @@
 )
 
 
-install(TARGETS grpc_objective_c_plugin EXPORT gRPCTargets
-  RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
-  LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
-  ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
-)
+if (gRPC_INSTALL)
+  install(TARGETS grpc_objective_c_plugin EXPORT gRPCTargets
+    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+    ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
+  )
+endif()
 
 
 add_executable(grpc_python_plugin
@@ -1727,11 +1967,13 @@
 )
 
 
-install(TARGETS grpc_python_plugin EXPORT gRPCTargets
-  RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
-  LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
-  ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
-)
+if (gRPC_INSTALL)
+  install(TARGETS grpc_python_plugin EXPORT gRPCTargets
+    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+    ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
+  )
+endif()
 
 
 add_executable(grpc_ruby_plugin
@@ -1753,11 +1995,13 @@
 )
 
 
-install(TARGETS grpc_ruby_plugin EXPORT gRPCTargets
-  RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
-  LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
-  ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
-)
+if (gRPC_INSTALL)
+  install(TARGETS grpc_ruby_plugin EXPORT gRPCTargets
+    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+    ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
+  )
+endif()
 
 
 
@@ -1766,10 +2010,12 @@
 
 
 
-install(EXPORT gRPCTargets
-  DESTINATION ${CMAKE_INSTALL_CMAKEDIR}
-  NAMESPACE gRPC::
-)
+if (gRPC_INSTALL)
+  install(EXPORT gRPCTargets
+    DESTINATION ${CMAKE_INSTALL_CMAKEDIR}
+    NAMESPACE gRPC::
+  )
+endif()
 
 foreach(_config gRPCConfig gRPCConfigVersion)
   configure_file(tools/cmake/${_config}.cmake.in
diff --git a/Makefile b/Makefile
index 7cef08c..c7622c0 100644
--- a/Makefile
+++ b/Makefile
@@ -492,7 +492,7 @@
 OPENSSL_ALPN_CHECK_CMD = $(PKG_CONFIG) --atleast-version=1.0.2 openssl
 OPENSSL_NPN_CHECK_CMD = $(PKG_CONFIG) --atleast-version=1.0.1 openssl
 ZLIB_CHECK_CMD = $(PKG_CONFIG) --exists zlib
-PROTOBUF_CHECK_CMD = $(PKG_CONFIG) --atleast-version=3.0.0-alpha-3 protobuf
+PROTOBUF_CHECK_CMD = $(PKG_CONFIG) --atleast-version=3.0.0 protobuf
 else # HAS_PKG_CONFIG
 
 ifeq ($(SYSTEM),MINGW32)
@@ -800,13 +800,6 @@
 NO_DEPS = true
 endif
 
-INSTALL_OK = false
-ifeq ($(HAS_VALID_PROTOC),true)
-ifeq ($(HAS_SYSTEM_PROTOBUF_VERIFY),true)
-INSTALL_OK = true
-endif
-endif
-
 .SECONDARY = %.pb.h %.pb.cc
 
 ifeq ($(DEP_MISSING),)
@@ -1049,6 +1042,7 @@
 grpc_objective_c_plugin: $(BINDIR)/$(CONFIG)/grpc_objective_c_plugin
 grpc_python_plugin: $(BINDIR)/$(CONFIG)/grpc_python_plugin
 grpc_ruby_plugin: $(BINDIR)/$(CONFIG)/grpc_ruby_plugin
+grpc_tool_test: $(BINDIR)/$(CONFIG)/grpc_tool_test
 grpclb_api_test: $(BINDIR)/$(CONFIG)/grpclb_api_test
 grpclb_test: $(BINDIR)/$(CONFIG)/grpclb_test
 hybrid_end2end_test: $(BINDIR)/$(CONFIG)/hybrid_end2end_test
@@ -1407,6 +1401,7 @@
   $(BINDIR)/$(CONFIG)/generic_end2end_test \
   $(BINDIR)/$(CONFIG)/golden_file_test \
   $(BINDIR)/$(CONFIG)/grpc_cli \
+  $(BINDIR)/$(CONFIG)/grpc_tool_test \
   $(BINDIR)/$(CONFIG)/grpclb_api_test \
   $(BINDIR)/$(CONFIG)/grpclb_test \
   $(BINDIR)/$(CONFIG)/hybrid_end2end_test \
@@ -1493,6 +1488,7 @@
   $(BINDIR)/$(CONFIG)/generic_end2end_test \
   $(BINDIR)/$(CONFIG)/golden_file_test \
   $(BINDIR)/$(CONFIG)/grpc_cli \
+  $(BINDIR)/$(CONFIG)/grpc_tool_test \
   $(BINDIR)/$(CONFIG)/grpclb_api_test \
   $(BINDIR)/$(CONFIG)/grpclb_test \
   $(BINDIR)/$(CONFIG)/hybrid_end2end_test \
@@ -1784,6 +1780,8 @@
 	$(Q) $(BINDIR)/$(CONFIG)/generic_end2end_test || ( echo test generic_end2end_test failed ; exit 1 )
 	$(E) "[RUN]     Testing golden_file_test"
 	$(Q) $(BINDIR)/$(CONFIG)/golden_file_test || ( echo test golden_file_test failed ; exit 1 )
+	$(E) "[RUN]     Testing grpc_tool_test"
+	$(Q) $(BINDIR)/$(CONFIG)/grpc_tool_test || ( echo test grpc_tool_test failed ; exit 1 )
 	$(E) "[RUN]     Testing grpclb_api_test"
 	$(Q) $(BINDIR)/$(CONFIG)/grpclb_api_test || ( echo test grpclb_api_test failed ; exit 1 )
 	$(E) "[RUN]     Testing grpclb_test"
@@ -2163,7 +2161,7 @@
 	$(Q) mkdir -p `dirname $@`
 	$(Q) $(CXX) $(CPPFLAGS) $(CXXFLAGS) -MMD -MF $(addsuffix .dep, $(basename $@)) -c -o $@ $<
 
-install: install_c install_cxx install-plugins install-certs verify-install
+install: install_c install_cxx install-plugins install-certs
 
 install_c: install-headers_c install-static_c install-shared_c
 
@@ -2346,28 +2344,6 @@
 	$(Q) $(INSTALL) -d $(prefix)/share/grpc
 	$(Q) $(INSTALL) etc/roots.pem $(prefix)/share/grpc/roots.pem
 
-verify-install:
-ifeq ($(INSTALL_OK),true)
-	@echo "Your system looks ready to go."
-	@echo
-else
-	@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 "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, you can re-run this check by doing:"
-	@echo
-	@echo "   make verify-install"
-endif
-
 clean:
 	$(E) "[CLEAN]   Cleaning build directories."
 	$(Q) $(RM) -rf $(OBJDIR) $(LIBDIR) $(BINDIR) $(GENDIR) cache.mk
@@ -2727,6 +2703,7 @@
     include/grpc/compression.h \
     include/grpc/grpc.h \
     include/grpc/grpc_posix.h \
+    include/grpc/grpc_security_constants.h \
     include/grpc/status.h \
     include/grpc/impl/codegen/byte_buffer.h \
     include/grpc/impl/codegen/byte_buffer_reader.h \
@@ -2750,7 +2727,6 @@
     include/grpc/impl/codegen/sync_windows.h \
     include/grpc/impl/codegen/time.h \
     include/grpc/grpc_security.h \
-    include/grpc/grpc_security_constants.h \
     include/grpc/census.h \
 
 LIBGRPC_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC_SRC))))
@@ -2977,6 +2953,7 @@
     include/grpc/compression.h \
     include/grpc/grpc.h \
     include/grpc/grpc_posix.h \
+    include/grpc/grpc_security_constants.h \
     include/grpc/status.h \
     include/grpc/impl/codegen/byte_buffer.h \
     include/grpc/impl/codegen/byte_buffer_reader.h \
@@ -3001,7 +2978,6 @@
     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))))
 
@@ -3169,6 +3145,7 @@
     include/grpc/compression.h \
     include/grpc/grpc.h \
     include/grpc/grpc_posix.h \
+    include/grpc/grpc_security_constants.h \
     include/grpc/status.h \
     include/grpc/impl/codegen/byte_buffer.h \
     include/grpc/impl/codegen/byte_buffer_reader.h \
@@ -3431,6 +3408,7 @@
     include/grpc/compression.h \
     include/grpc/grpc.h \
     include/grpc/grpc_posix.h \
+    include/grpc/grpc_security_constants.h \
     include/grpc/status.h \
     include/grpc/impl/codegen/byte_buffer.h \
     include/grpc/impl/codegen/byte_buffer_reader.h \
@@ -3604,6 +3582,95 @@
     src/cpp/util/status.cc \
     src/cpp/util/string_ref.cc \
     src/cpp/util/time.cc \
+    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/handshaker.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/error.c \
+    src/core/lib/iomgr/ev_epoll_linux.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/load_file.c \
+    src/core/lib/iomgr/network_status_tracker.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/timeout_encoding.c \
+    src/core/lib/transport/transport.c \
+    src/core/lib/transport/transport_op_string.c \
     src/cpp/codegen/codegen_init.cc \
 
 PUBLIC_HEADERS_CXX += \
@@ -3654,6 +3721,34 @@
     include/grpc++/support/stub_options.h \
     include/grpc++/support/sync_stream.h \
     include/grpc++/support/time.h \
+    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/grpc_security_constants.h \
+    include/grpc/status.h \
+    include/grpc/impl/codegen/byte_buffer.h \
+    include/grpc/impl/codegen/byte_buffer_reader.h \
+    include/grpc/impl/codegen/compression_types.h \
+    include/grpc/impl/codegen/connectivity_state.h \
+    include/grpc/impl/codegen/grpc_types.h \
+    include/grpc/impl/codegen/propagation_bits.h \
+    include/grpc/impl/codegen/status.h \
+    include/grpc/impl/codegen/alloc.h \
+    include/grpc/impl/codegen/atm.h \
+    include/grpc/impl/codegen/atm_gcc_atomic.h \
+    include/grpc/impl/codegen/atm_gcc_sync.h \
+    include/grpc/impl/codegen/atm_windows.h \
+    include/grpc/impl/codegen/log.h \
+    include/grpc/impl/codegen/port_platform.h \
+    include/grpc/impl/codegen/slice.h \
+    include/grpc/impl/codegen/slice_buffer.h \
+    include/grpc/impl/codegen/sync.h \
+    include/grpc/impl/codegen/sync_generic.h \
+    include/grpc/impl/codegen/sync_posix.h \
+    include/grpc/impl/codegen/sync_windows.h \
+    include/grpc/impl/codegen/time.h \
     include/grpc++/impl/codegen/async_stream.h \
     include/grpc++/impl/codegen/async_unary_call.h \
     include/grpc++/impl/codegen/call.h \
@@ -3684,27 +3779,6 @@
     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 \
 
 LIBGRPC++_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC++_SRC))))
 
@@ -3741,18 +3815,18 @@
 
 
 ifeq ($(SYSTEM),MINGW32)
-$(LIBDIR)/$(CONFIG)/grpc++$(SHARED_VERSION).$(SHARED_EXT): $(LIBGRPC++_OBJS)  $(ZLIB_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/grpc.$(SHARED_EXT) $(OPENSSL_DEP)
+$(LIBDIR)/$(CONFIG)/grpc++$(SHARED_VERSION).$(SHARED_EXT): $(LIBGRPC++_OBJS)  $(ZLIB_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/grpc.$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/gpr.$(SHARED_EXT) $(OPENSSL_DEP)
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared grpc++.def -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc++$(SHARED_VERSION).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc++$(SHARED_VERSION)-dll.a -o $(LIBDIR)/$(CONFIG)/grpc++$(SHARED_VERSION).$(SHARED_EXT) $(LIBGRPC++_OBJS) $(LDLIBS) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgrpc-imp
+	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared grpc++.def -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc++$(SHARED_VERSION).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc++$(SHARED_VERSION)-dll.a -o $(LIBDIR)/$(CONFIG)/grpc++$(SHARED_VERSION).$(SHARED_EXT) $(LIBGRPC++_OBJS) $(LDLIBS) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgrpc-imp -lgpr-imp
 else
-$(LIBDIR)/$(CONFIG)/libgrpc++$(SHARED_VERSION).$(SHARED_EXT): $(LIBGRPC++_OBJS)  $(ZLIB_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/libgrpc.$(SHARED_EXT) $(OPENSSL_DEP)
+$(LIBDIR)/$(CONFIG)/libgrpc++$(SHARED_VERSION).$(SHARED_EXT): $(LIBGRPC++_OBJS)  $(ZLIB_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/libgrpc.$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/libgpr.$(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++$(SHARED_VERSION).$(SHARED_EXT) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc++$(SHARED_VERSION).$(SHARED_EXT) $(LIBGRPC++_OBJS) $(LDLIBS) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgrpc
+	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc++$(SHARED_VERSION).$(SHARED_EXT) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc++$(SHARED_VERSION).$(SHARED_EXT) $(LIBGRPC++_OBJS) $(LDLIBS) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgrpc -lgpr
 else
-	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc++.so.1 -o $(LIBDIR)/$(CONFIG)/libgrpc++$(SHARED_VERSION).$(SHARED_EXT) $(LIBGRPC++_OBJS) $(LDLIBS) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgrpc
+	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc++.so.1 -o $(LIBDIR)/$(CONFIG)/libgrpc++$(SHARED_VERSION).$(SHARED_EXT) $(LIBGRPC++_OBJS) $(LDLIBS) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgrpc -lgpr
 	$(Q) ln -sf $(SHARED_PREFIX)grpc++$(SHARED_VERSION).$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/libgrpc++$(SHARED_VERSION).so.1
 	$(Q) ln -sf $(SHARED_PREFIX)grpc++$(SHARED_VERSION).$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/libgrpc++$(SHARED_VERSION).so
 endif
@@ -4060,6 +4134,8 @@
     include/grpc/impl/codegen/time.h \
     include/grpc++/impl/codegen/proto_utils.h \
     include/grpc++/impl/codegen/config_protobuf.h \
+    include/grpc++/impl/codegen/thrift_serializer.h \
+    include/grpc++/impl/codegen/thrift_utils.h \
 
 LIBGRPC++_TEST_UTIL_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC++_TEST_UTIL_SRC))))
 
@@ -4141,6 +4217,95 @@
     src/cpp/util/status.cc \
     src/cpp/util/string_ref.cc \
     src/cpp/util/time.cc \
+    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/handshaker.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/error.c \
+    src/core/lib/iomgr/ev_epoll_linux.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/load_file.c \
+    src/core/lib/iomgr/network_status_tracker.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/timeout_encoding.c \
+    src/core/lib/transport/transport.c \
+    src/core/lib/transport/transport_op_string.c \
     src/cpp/codegen/codegen_init.cc \
 
 PUBLIC_HEADERS_CXX += \
@@ -4191,6 +4356,34 @@
     include/grpc++/support/stub_options.h \
     include/grpc++/support/sync_stream.h \
     include/grpc++/support/time.h \
+    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/grpc_security_constants.h \
+    include/grpc/status.h \
+    include/grpc/impl/codegen/byte_buffer.h \
+    include/grpc/impl/codegen/byte_buffer_reader.h \
+    include/grpc/impl/codegen/compression_types.h \
+    include/grpc/impl/codegen/connectivity_state.h \
+    include/grpc/impl/codegen/grpc_types.h \
+    include/grpc/impl/codegen/propagation_bits.h \
+    include/grpc/impl/codegen/status.h \
+    include/grpc/impl/codegen/alloc.h \
+    include/grpc/impl/codegen/atm.h \
+    include/grpc/impl/codegen/atm_gcc_atomic.h \
+    include/grpc/impl/codegen/atm_gcc_sync.h \
+    include/grpc/impl/codegen/atm_windows.h \
+    include/grpc/impl/codegen/log.h \
+    include/grpc/impl/codegen/port_platform.h \
+    include/grpc/impl/codegen/slice.h \
+    include/grpc/impl/codegen/slice_buffer.h \
+    include/grpc/impl/codegen/sync.h \
+    include/grpc/impl/codegen/sync_generic.h \
+    include/grpc/impl/codegen/sync_posix.h \
+    include/grpc/impl/codegen/sync_windows.h \
+    include/grpc/impl/codegen/time.h \
     include/grpc++/impl/codegen/async_stream.h \
     include/grpc++/impl/codegen/async_unary_call.h \
     include/grpc++/impl/codegen/call.h \
@@ -4221,27 +4414,6 @@
     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 \
 
 LIBGRPC++_UNSECURE_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC++_UNSECURE_SRC))))
 
@@ -4268,18 +4440,18 @@
 
 
 ifeq ($(SYSTEM),MINGW32)
-$(LIBDIR)/$(CONFIG)/grpc++_unsecure$(SHARED_VERSION).$(SHARED_EXT): $(LIBGRPC++_UNSECURE_OBJS)  $(ZLIB_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/gpr.$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/grpc_unsecure.$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/grpc.$(SHARED_EXT)
+$(LIBDIR)/$(CONFIG)/grpc++_unsecure$(SHARED_VERSION).$(SHARED_EXT): $(LIBGRPC++_UNSECURE_OBJS)  $(ZLIB_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/gpr.$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/grpc_unsecure.$(SHARED_EXT)
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
-	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared grpc++_unsecure.def -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc++_unsecure$(SHARED_VERSION).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc++_unsecure$(SHARED_VERSION)-dll.a -o $(LIBDIR)/$(CONFIG)/grpc++_unsecure$(SHARED_VERSION).$(SHARED_EXT) $(LIBGRPC++_UNSECURE_OBJS) $(LDLIBS) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgpr-imp -lgrpc_unsecure-imp -lgrpc-imp
+	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared grpc++_unsecure.def -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc++_unsecure$(SHARED_VERSION).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc++_unsecure$(SHARED_VERSION)-dll.a -o $(LIBDIR)/$(CONFIG)/grpc++_unsecure$(SHARED_VERSION).$(SHARED_EXT) $(LIBGRPC++_UNSECURE_OBJS) $(LDLIBS) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgpr-imp -lgrpc_unsecure-imp
 else
-$(LIBDIR)/$(CONFIG)/libgrpc++_unsecure$(SHARED_VERSION).$(SHARED_EXT): $(LIBGRPC++_UNSECURE_OBJS)  $(ZLIB_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/libgpr.$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/libgrpc.$(SHARED_EXT)
+$(LIBDIR)/$(CONFIG)/libgrpc++_unsecure$(SHARED_VERSION).$(SHARED_EXT): $(LIBGRPC++_UNSECURE_OBJS)  $(ZLIB_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/libgpr.$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.$(SHARED_EXT)
 	$(E) "[LD]      Linking $@"
 	$(Q) mkdir -p `dirname $@`
 ifeq ($(SYSTEM),Darwin)
-	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION).$(SHARED_EXT) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure$(SHARED_VERSION).$(SHARED_EXT) $(LIBGRPC++_UNSECURE_OBJS) $(LDLIBS) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgpr -lgrpc_unsecure -lgrpc
+	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION).$(SHARED_EXT) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure$(SHARED_VERSION).$(SHARED_EXT) $(LIBGRPC++_UNSECURE_OBJS) $(LDLIBS) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgpr -lgrpc_unsecure
 else
-	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc++_unsecure.so.1 -o $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure$(SHARED_VERSION).$(SHARED_EXT) $(LIBGRPC++_UNSECURE_OBJS) $(LDLIBS) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgpr -lgrpc_unsecure -lgrpc
+	$(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc++_unsecure.so.1 -o $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure$(SHARED_VERSION).$(SHARED_EXT) $(LIBGRPC++_UNSECURE_OBJS) $(LDLIBS) $(ZLIB_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgpr -lgrpc_unsecure
 	$(Q) ln -sf $(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION).$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure$(SHARED_VERSION).so.1
 	$(Q) ln -sf $(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION).$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure$(SHARED_VERSION).so
 endif
@@ -4294,6 +4466,8 @@
 
 LIBGRPC_CLI_LIBS_SRC = \
     test/cpp/util/cli_call.cc \
+    test/cpp/util/cli_credentials.cc \
+    test/cpp/util/grpc_tool.cc \
     test/cpp/util/proto_file_parser.cc \
     test/cpp/util/proto_reflection_descriptor_database.cc \
 
@@ -11331,16 +11505,16 @@
 
 else
 
-$(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++_reflection.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++_reflection.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.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_cli_libs.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.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++_reflection.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.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_cli_libs.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.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++_reflection.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_config.a
 
 deps_grpc_cli: $(GRPC_CLI_OBJS:.o=.dep)
 
@@ -11537,6 +11711,60 @@
 endif
 
 
+GRPC_TOOL_TEST_SRC = \
+    $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc \
+    $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc \
+    test/cpp/util/grpc_tool_test.cc \
+    test/cpp/util/string_ref_helper.cc \
+
+GRPC_TOOL_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(GRPC_TOOL_TEST_SRC))))
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure targets if you don't have OpenSSL.
+
+$(BINDIR)/$(CONFIG)/grpc_tool_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)/grpc_tool_test: protobuf_dep_error
+
+else
+
+$(BINDIR)/$(CONFIG)/grpc_tool_test: $(PROTOBUF_DEP) $(GRPC_TOOL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.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) $(GRPC_TOOL_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.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)/grpc_tool_test
+
+endif
+
+endif
+
+$(OBJDIR)/$(CONFIG)/src/proto/grpc/testing/echo.o:  $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.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)/src/proto/grpc/testing/echo_messages.o:  $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.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/grpc_tool_test.o:  $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.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/string_ref_helper.o:  $(LIBDIR)/$(CONFIG)/libgrpc_cli_libs.a $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.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_grpc_tool_test: $(GRPC_TOOL_TEST_OBJS:.o=.dep)
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(GRPC_TOOL_TEST_OBJS:.o=.dep)
+endif
+endif
+$(OBJDIR)/$(CONFIG)/test/cpp/util/grpc_tool_test.o: $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc
+$(OBJDIR)/$(CONFIG)/test/cpp/util/string_ref_helper.o: $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc
+
+
 GRPCLB_API_TEST_SRC = \
     $(GENDIR)/src/proto/grpc/lb/v1/load_balancer.pb.cc $(GENDIR)/src/proto/grpc/lb/v1/load_balancer.grpc.pb.cc \
     test/cpp/grpclb/grpclb_api_test.cc \
@@ -15300,7 +15528,9 @@
 test/cpp/util/benchmark_config.cc: $(OPENSSL_DEP)
 test/cpp/util/byte_buffer_proto_helper.cc: $(OPENSSL_DEP)
 test/cpp/util/cli_call.cc: $(OPENSSL_DEP)
+test/cpp/util/cli_credentials.cc: $(OPENSSL_DEP)
 test/cpp/util/create_test_channel.cc: $(OPENSSL_DEP)
+test/cpp/util/grpc_tool.cc: $(OPENSSL_DEP)
 test/cpp/util/proto_file_parser.cc: $(OPENSSL_DEP)
 test/cpp/util/proto_reflection_descriptor_database.cc: $(OPENSSL_DEP)
 test/cpp/util/string_ref_helper.cc: $(OPENSSL_DEP)
diff --git a/PYTHON-MANIFEST.in b/PYTHON-MANIFEST.in
index 96bcdb5..adeb390 100644
--- a/PYTHON-MANIFEST.in
+++ b/PYTHON-MANIFEST.in
@@ -7,7 +7,7 @@
 graft third_party/boringssl
 graft third_party/nanopb
 graft third_party/zlib
-include src/python/grpcio/_unixccompiler_patch.py
+include src/python/grpcio/_spawn_patch.py
 include src/python/grpcio/commands.py
 include src/python/grpcio/grpc_version.py
 include src/python/grpcio/grpc_core_dependencies.py
diff --git a/README.md b/README.md
index 3283517..e9b0454 100644
--- a/README.md
+++ b/README.md
@@ -23,16 +23,16 @@
 
 Libraries in different languages are in different states of development. We are seeking contributions for all of these libraries.
 
-| Language                | Source                              | Status                           |
-|-------------------------|-------------------------------------|----------------------------------|
-| Shared C [core library] | [src/core] (src/core)               | Beta - the surface API is stable |
-| C++                     | [src/cpp] (src/cpp)                 | Beta - the surface API is stable |
-| Ruby                    | [src/ruby] (src/ruby)               | Beta - the surface API is stable |
-| NodeJS                  | [src/node] (src/node)               | Beta - the surface API is stable |
-| Python                  | [src/python] (src/python)           | Beta - the surface API is stable |
-| PHP                     | [src/php] (src/php)                 | Beta - the surface API is stable |
-| C#                      | [src/csharp] (src/csharp)           | Beta - the surface API is stable |
-| Objective-C             | [src/objective-c] (src/objective-c) | Beta - the surface API is stable |
+| Language                | Source                              | Status  |
+|-------------------------|-------------------------------------|---------|
+| Shared C [core library] | [src/core] (src/core)               | 1.0     |
+| C++                     | [src/cpp] (src/cpp)                 | 1.0     |
+| Ruby                    | [src/ruby] (src/ruby)               | 1.0     |
+| NodeJS                  | [src/node] (src/node)               | 1.0     |
+| Python                  | [src/python] (src/python)           | 1.0     |
+| PHP                     | [src/php] (src/php)                 | 1.0     |
+| C#                      | [src/csharp] (src/csharp)           | 1.0     |
+| Objective-C             | [src/objective-c] (src/objective-c) | 1.0     |
 
 <small>
 Java source code is in the [grpc-java] (http://github.com/grpc/grpc-java) repository.
diff --git a/build.yaml b/build.yaml
index 6ca2e9e..506a029 100644
--- a/build.yaml
+++ b/build.yaml
@@ -152,6 +152,7 @@
   - include/grpc/compression.h
   - include/grpc/grpc.h
   - include/grpc/grpc_posix.h
+  - include/grpc/grpc_security_constants.h
   - include/grpc/status.h
   headers:
   - src/core/lib/channel/channel_args.h
@@ -435,7 +436,6 @@
 - name: grpc_secure
   public_headers:
   - include/grpc/grpc_security.h
-  - include/grpc/grpc_security_constants.h
   headers:
   - src/core/lib/security/context/security_context.h
   - src/core/lib/security/credentials/composite/composite_credentials.h
@@ -723,9 +723,8 @@
   - src/cpp/util/status.cc
   - src/cpp/util/string_ref.cc
   - src/cpp/util/time.cc
-  deps:
-  - grpc
   uses:
+  - grpc_base
   - grpc++_codegen_base
 - name: grpc++_codegen_base
   language: c++
@@ -789,6 +788,13 @@
   - src/cpp/ext/reflection.pb.cc
   uses:
   - grpc++_codegen_proto
+- name: thrift_util
+  language: c++
+  public_headers:
+  - include/grpc++/impl/codegen/thrift_serializer.h
+  - include/grpc++/impl/codegen/thrift_utils.h
+  uses:
+  - grpc++_codegen_base
 libs:
 - name: gpr
   build: all
@@ -1031,6 +1037,7 @@
   - grpc++_codegen_base_src
   - grpc++_codegen_proto
   - grpc++_config_proto
+  - thrift_util
 - name: grpc++_unsecure
   build: all
   language: c++
@@ -1052,16 +1059,21 @@
   language: c++
   headers:
   - test/cpp/util/cli_call.h
+  - test/cpp/util/cli_credentials.h
+  - test/cpp/util/config_grpc_cli.h
+  - test/cpp/util/grpc_tool.h
   - test/cpp/util/proto_file_parser.h
   - test/cpp/util/proto_reflection_descriptor_database.h
   src:
   - test/cpp/util/cli_call.cc
+  - test/cpp/util/cli_credentials.cc
+  - test/cpp/util/grpc_tool.cc
   - test/cpp/util/proto_file_parser.cc
   - test/cpp/util/proto_reflection_descriptor_database.cc
   deps:
   - grpc++_reflection
   - grpc++
-  - grpc_plugin_support
+  - grpc++_test_config
 - name: grpc_plugin_support
   build: protoc
   language: c++
@@ -2711,12 +2723,9 @@
   - test/cpp/util/grpc_cli.cc
   deps:
   - grpc_cli_libs
-  - grpc++_test_util
-  - grpc_test_util
   - grpc++_reflection
   - grpc++
   - grpc
-  - gpr_test_util
   - gpr
   - grpc++_test_config
 - name: grpc_cpp_plugin
@@ -2778,6 +2787,28 @@
   secure: false
   vs_config_type: Application
   vs_project_guid: '{069E9D05-B78B-4751-9252-D21EBAE7DE8E}'
+- name: grpc_tool_test
+  gtest: true
+  build: test
+  language: c++
+  headers:
+  - test/cpp/util/string_ref_helper.h
+  src:
+  - src/proto/grpc/testing/echo.proto
+  - src/proto/grpc/testing/echo_messages.proto
+  - test/cpp/util/grpc_tool_test.cc
+  - test/cpp/util/string_ref_helper.cc
+  deps:
+  - grpc_cli_libs
+  - grpc++_reflection
+  - grpc_test_util
+  - grpc++
+  - grpc
+  - gpr_test_util
+  - gpr
+  filegroups:
+  - grpc++_codegen_proto
+  - grpc++_config_proto
 - name: grpclb_api_test
   gtest: true
   build: test
diff --git a/doc/PROTOCOL-HTTP2.md b/doc/PROTOCOL-HTTP2.md
index 31d694b..df7585d 100644
--- a/doc/PROTOCOL-HTTP2.md
+++ b/doc/PROTOCOL-HTTP2.md
@@ -98,8 +98,11 @@
 * **Trailers-Only** → HTTP-Status Content-Type Trailers
 * **Trailers** → Status [Status-Message] \*Custom-Metadata
 * **HTTP-Status** → ":status 200"
-* **Status** → "grpc-status" <status-code-as-ASCII-string>
-* **Status-Message** → "grpc-message" <descriptive text for status as ASCII string>
+* **Status** → "grpc-status" 1\*DIGIT ; 0-9
+* **Status-Message** → "grpc-message" Percent-Encoded
+* **Percent-Encoded** → 1\*(Percent-Byte-Unencoded / Percent-Byte-Encoded)
+* **Percent-Byte-Unencoded** → 1\*( %x20-%x24 / %x26-%x7E ) ; space and VCHAR, except %
+* **Percent-Byte-Encoded** → "%" 2HEXDIGIT ; 0-9 A-F
 
 **Response-Headers** & **Trailers-Only** are each delivered in a single HTTP2 HEADERS frame block. Most responses are expected to have both headers and trailers but **Trailers-Only** is permitted for calls that produce an immediate error. Status must be sent in **Trailers** even if the status code is OK.
 
@@ -110,6 +113,21 @@
 Clients may limit the size of **Response-Headers**, **Trailers**, and
 **Trailers-Only**, with a default of 8 KiB each suggested.
 
+The value portion of **Status** is a decimal-encoded integer as an ASCII string,
+without any leading zeros.
+
+The value portion of **Status-Message** is conceptually a Unicode string
+description of the error, physically encoded as UTF-8 followed by
+percent-encoding. Percent-encoding is specified in [RFC 3986
+§2.1](https://tools.ietf.org/html/rfc3986#section-2.1), although the form used
+here has different restricted characters. When decoding invalid values,
+implementations MUST NOT error or throw away the message. At worst, the
+implementation can abort decoding the status message altogether such that the
+user would received the raw percent-encoded form. Alternatively, the
+implementation can decode valid portions while leaving broken %-encodings as-is
+or replacing them with a replacement character (e.g., '?' or the Unicode
+replacement character).
+
 ####Example
 
 Sample unary-call showing HTTP2 framing sequence
diff --git a/examples/cpp/cpptutorial.md b/examples/cpp/cpptutorial.md
index de7e4b2..ae84aba 100644
--- a/examples/cpp/cpptutorial.md
+++ b/examples/cpp/cpptutorial.md
@@ -127,7 +127,7 @@
 service definition. We do this using the protocol buffer compiler `protoc` with
 a special gRPC C++ plugin.
 
-For simplicity, we've provided a [makefile](route_guide/Makefile) that runs
+For simplicity, we've provided a [Makefile](route_guide/Makefile) that runs
 `protoc` for you with the appropriate plugin, input, and output (if you want to
 run this yourself, make sure you've installed protoc and followed the gRPC code
 [installation instructions](../../INSTALL.md) first):
diff --git a/examples/csharp/helloworld-from-cli/Greeter/Helloworld.cs b/examples/csharp/helloworld-from-cli/Greeter/Helloworld.cs
new file mode 100644
index 0000000..6477b4f
--- /dev/null
+++ b/examples/csharp/helloworld-from-cli/Greeter/Helloworld.cs
@@ -0,0 +1,259 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: helloworld.proto
+#pragma warning disable 1591, 0612, 3021
+#region Designer generated code
+
+using pb = global::Google.Protobuf;
+using pbc = global::Google.Protobuf.Collections;
+using pbr = global::Google.Protobuf.Reflection;
+using scg = global::System.Collections.Generic;
+namespace Helloworld {
+
+  /// <summary>Holder for reflection information generated from helloworld.proto</summary>
+  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+  public static partial class HelloworldReflection {
+
+    #region Descriptor
+    /// <summary>File descriptor for helloworld.proto</summary>
+    public static pbr::FileDescriptor Descriptor {
+      get { return descriptor; }
+    }
+    private static pbr::FileDescriptor descriptor;
+
+    static HelloworldReflection() {
+      byte[] descriptorData = global::System.Convert.FromBase64String(
+          string.Concat(
+            "ChBoZWxsb3dvcmxkLnByb3RvEgpoZWxsb3dvcmxkIhwKDEhlbGxvUmVxdWVz",
+            "dBIMCgRuYW1lGAEgASgJIh0KCkhlbGxvUmVwbHkSDwoHbWVzc2FnZRgBIAEo",
+            "CTJJCgdHcmVldGVyEj4KCFNheUhlbGxvEhguaGVsbG93b3JsZC5IZWxsb1Jl",
+            "cXVlc3QaFi5oZWxsb3dvcmxkLkhlbGxvUmVwbHkiAEI2Chtpby5ncnBjLmV4",
+            "YW1wbGVzLmhlbGxvd29ybGRCD0hlbGxvV29ybGRQcm90b1ABogIDSExXYgZw",
+            "cm90bzM="));
+      descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
+          new pbr::FileDescriptor[] { },
+          new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] {
+            new pbr::GeneratedClrTypeInfo(typeof(global::Helloworld.HelloRequest), global::Helloworld.HelloRequest.Parser, new[]{ "Name" }, null, null, null),
+            new pbr::GeneratedClrTypeInfo(typeof(global::Helloworld.HelloReply), global::Helloworld.HelloReply.Parser, new[]{ "Message" }, null, null, null)
+          }));
+    }
+    #endregion
+
+  }
+  #region Messages
+  /// <summary>
+  ///  The request message containing the user's name.
+  /// </summary>
+  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+  public sealed partial class HelloRequest : pb::IMessage<HelloRequest> {
+    private static readonly pb::MessageParser<HelloRequest> _parser = new pb::MessageParser<HelloRequest>(() => new HelloRequest());
+    public static pb::MessageParser<HelloRequest> Parser { get { return _parser; } }
+
+    public static pbr::MessageDescriptor Descriptor {
+      get { return global::Helloworld.HelloworldReflection.Descriptor.MessageTypes[0]; }
+    }
+
+    pbr::MessageDescriptor pb::IMessage.Descriptor {
+      get { return Descriptor; }
+    }
+
+    public HelloRequest() {
+      OnConstruction();
+    }
+
+    partial void OnConstruction();
+
+    public HelloRequest(HelloRequest other) : this() {
+      name_ = other.name_;
+    }
+
+    public HelloRequest Clone() {
+      return new HelloRequest(this);
+    }
+
+    /// <summary>Field number for the "name" field.</summary>
+    public const int NameFieldNumber = 1;
+    private string name_ = "";
+    public string Name {
+      get { return name_; }
+      set {
+        name_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
+      }
+    }
+
+    public override bool Equals(object other) {
+      return Equals(other as HelloRequest);
+    }
+
+    public bool Equals(HelloRequest other) {
+      if (ReferenceEquals(other, null)) {
+        return false;
+      }
+      if (ReferenceEquals(other, this)) {
+        return true;
+      }
+      if (Name != other.Name) return false;
+      return true;
+    }
+
+    public override int GetHashCode() {
+      int hash = 1;
+      if (Name.Length != 0) hash ^= Name.GetHashCode();
+      return hash;
+    }
+
+    public override string ToString() {
+      return pb::JsonFormatter.ToDiagnosticString(this);
+    }
+
+    public void WriteTo(pb::CodedOutputStream output) {
+      if (Name.Length != 0) {
+        output.WriteRawTag(10);
+        output.WriteString(Name);
+      }
+    }
+
+    public int CalculateSize() {
+      int size = 0;
+      if (Name.Length != 0) {
+        size += 1 + pb::CodedOutputStream.ComputeStringSize(Name);
+      }
+      return size;
+    }
+
+    public void MergeFrom(HelloRequest other) {
+      if (other == null) {
+        return;
+      }
+      if (other.Name.Length != 0) {
+        Name = other.Name;
+      }
+    }
+
+    public void MergeFrom(pb::CodedInputStream input) {
+      uint tag;
+      while ((tag = input.ReadTag()) != 0) {
+        switch(tag) {
+          default:
+            input.SkipLastField();
+            break;
+          case 10: {
+            Name = input.ReadString();
+            break;
+          }
+        }
+      }
+    }
+
+  }
+
+  /// <summary>
+  ///  The response message containing the greetings
+  /// </summary>
+  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+  public sealed partial class HelloReply : pb::IMessage<HelloReply> {
+    private static readonly pb::MessageParser<HelloReply> _parser = new pb::MessageParser<HelloReply>(() => new HelloReply());
+    public static pb::MessageParser<HelloReply> Parser { get { return _parser; } }
+
+    public static pbr::MessageDescriptor Descriptor {
+      get { return global::Helloworld.HelloworldReflection.Descriptor.MessageTypes[1]; }
+    }
+
+    pbr::MessageDescriptor pb::IMessage.Descriptor {
+      get { return Descriptor; }
+    }
+
+    public HelloReply() {
+      OnConstruction();
+    }
+
+    partial void OnConstruction();
+
+    public HelloReply(HelloReply other) : this() {
+      message_ = other.message_;
+    }
+
+    public HelloReply Clone() {
+      return new HelloReply(this);
+    }
+
+    /// <summary>Field number for the "message" field.</summary>
+    public const int MessageFieldNumber = 1;
+    private string message_ = "";
+    public string Message {
+      get { return message_; }
+      set {
+        message_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
+      }
+    }
+
+    public override bool Equals(object other) {
+      return Equals(other as HelloReply);
+    }
+
+    public bool Equals(HelloReply other) {
+      if (ReferenceEquals(other, null)) {
+        return false;
+      }
+      if (ReferenceEquals(other, this)) {
+        return true;
+      }
+      if (Message != other.Message) return false;
+      return true;
+    }
+
+    public override int GetHashCode() {
+      int hash = 1;
+      if (Message.Length != 0) hash ^= Message.GetHashCode();
+      return hash;
+    }
+
+    public override string ToString() {
+      return pb::JsonFormatter.ToDiagnosticString(this);
+    }
+
+    public void WriteTo(pb::CodedOutputStream output) {
+      if (Message.Length != 0) {
+        output.WriteRawTag(10);
+        output.WriteString(Message);
+      }
+    }
+
+    public int CalculateSize() {
+      int size = 0;
+      if (Message.Length != 0) {
+        size += 1 + pb::CodedOutputStream.ComputeStringSize(Message);
+      }
+      return size;
+    }
+
+    public void MergeFrom(HelloReply other) {
+      if (other == null) {
+        return;
+      }
+      if (other.Message.Length != 0) {
+        Message = other.Message;
+      }
+    }
+
+    public void MergeFrom(pb::CodedInputStream input) {
+      uint tag;
+      while ((tag = input.ReadTag()) != 0) {
+        switch(tag) {
+          default:
+            input.SkipLastField();
+            break;
+          case 10: {
+            Message = input.ReadString();
+            break;
+          }
+        }
+      }
+    }
+
+  }
+
+  #endregion
+
+}
+
+#endregion Designer generated code
diff --git a/examples/csharp/helloworld-from-cli/Greeter/HelloworldGrpc.cs b/examples/csharp/helloworld-from-cli/Greeter/HelloworldGrpc.cs
new file mode 100644
index 0000000..041f5a7
--- /dev/null
+++ b/examples/csharp/helloworld-from-cli/Greeter/HelloworldGrpc.cs
@@ -0,0 +1,143 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: helloworld.proto
+// 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.
+//
+#region Designer generated code
+
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+using Grpc.Core;
+
+namespace Helloworld {
+  /// <summary>
+  ///  The greeting service definition.
+  /// </summary>
+  public static class Greeter
+  {
+    static readonly string __ServiceName = "helloworld.Greeter";
+
+    static readonly Marshaller<global::Helloworld.HelloRequest> __Marshaller_HelloRequest = Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Helloworld.HelloRequest.Parser.ParseFrom);
+    static readonly Marshaller<global::Helloworld.HelloReply> __Marshaller_HelloReply = Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Helloworld.HelloReply.Parser.ParseFrom);
+
+    static readonly Method<global::Helloworld.HelloRequest, global::Helloworld.HelloReply> __Method_SayHello = new Method<global::Helloworld.HelloRequest, global::Helloworld.HelloReply>(
+        MethodType.Unary,
+        __ServiceName,
+        "SayHello",
+        __Marshaller_HelloRequest,
+        __Marshaller_HelloReply);
+
+    /// <summary>Service descriptor</summary>
+    public static global::Google.Protobuf.Reflection.ServiceDescriptor Descriptor
+    {
+      get { return global::Helloworld.HelloworldReflection.Descriptor.Services[0]; }
+    }
+
+    /// <summary>Base class for server-side implementations of Greeter</summary>
+    public abstract class GreeterBase
+    {
+      /// <summary>
+      ///  Sends a greeting
+      /// </summary>
+      public virtual global::System.Threading.Tasks.Task<global::Helloworld.HelloReply> SayHello(global::Helloworld.HelloRequest request, ServerCallContext context)
+      {
+        throw new RpcException(new Status(StatusCode.Unimplemented, ""));
+      }
+
+    }
+
+    /// <summary>Client for Greeter</summary>
+    public class GreeterClient : ClientBase<GreeterClient>
+    {
+      /// <summary>Creates a new client for Greeter</summary>
+      /// <param name="channel">The channel to use to make remote calls.</param>
+      public GreeterClient(Channel channel) : base(channel)
+      {
+      }
+      /// <summary>Creates a new client for Greeter that uses a custom <c>CallInvoker</c>.</summary>
+      /// <param name="callInvoker">The callInvoker to use to make remote calls.</param>
+      public GreeterClient(CallInvoker callInvoker) : base(callInvoker)
+      {
+      }
+      /// <summary>Protected parameterless constructor to allow creation of test doubles.</summary>
+      protected GreeterClient() : base()
+      {
+      }
+      /// <summary>Protected constructor to allow creation of configured clients.</summary>
+      /// <param name="configuration">The client configuration.</param>
+      protected GreeterClient(ClientBaseConfiguration configuration) : base(configuration)
+      {
+      }
+
+      /// <summary>
+      ///  Sends a greeting
+      /// </summary>
+      public virtual global::Helloworld.HelloReply SayHello(global::Helloworld.HelloRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      {
+        return SayHello(request, new CallOptions(headers, deadline, cancellationToken));
+      }
+      /// <summary>
+      ///  Sends a greeting
+      /// </summary>
+      public virtual global::Helloworld.HelloReply SayHello(global::Helloworld.HelloRequest request, CallOptions options)
+      {
+        return CallInvoker.BlockingUnaryCall(__Method_SayHello, null, options, request);
+      }
+      /// <summary>
+      ///  Sends a greeting
+      /// </summary>
+      public virtual AsyncUnaryCall<global::Helloworld.HelloReply> SayHelloAsync(global::Helloworld.HelloRequest request, Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+      {
+        return SayHelloAsync(request, new CallOptions(headers, deadline, cancellationToken));
+      }
+      /// <summary>
+      ///  Sends a greeting
+      /// </summary>
+      public virtual AsyncUnaryCall<global::Helloworld.HelloReply> SayHelloAsync(global::Helloworld.HelloRequest request, CallOptions options)
+      {
+        return CallInvoker.AsyncUnaryCall(__Method_SayHello, null, options, request);
+      }
+      protected override GreeterClient NewInstance(ClientBaseConfiguration configuration)
+      {
+        return new GreeterClient(configuration);
+      }
+    }
+
+    /// <summary>Creates service definition that can be registered with a server</summary>
+    public static ServerServiceDefinition BindService(GreeterBase serviceImpl)
+    {
+      return ServerServiceDefinition.CreateBuilder()
+          .AddMethod(__Method_SayHello, serviceImpl.SayHello).Build();
+    }
+
+  }
+}
+#endregion
diff --git a/examples/csharp/helloworld-from-cli/Greeter/project.json b/examples/csharp/helloworld-from-cli/Greeter/project.json
new file mode 100644
index 0000000..8774941
--- /dev/null
+++ b/examples/csharp/helloworld-from-cli/Greeter/project.json
@@ -0,0 +1,22 @@
+{
+  "title": "Greeter",
+  "version": "1.0.0-*",
+  "buildOptions": {
+    "debugType": "portable",
+  },
+  "dependencies": {
+    "Google.Protobuf": "3.0.0-beta3",
+    "Grpc": "1.0.0-pre1",
+  },
+  "frameworks": {
+    "net45": {
+      "frameworkAssemblies": {
+        "System.Runtime": "",
+        "System.IO": ""
+      },
+      "dependencies": {
+	"Microsoft.NETCore.Platforms": "1.0.1" 
+      }
+    }
+  }
+}
diff --git a/examples/csharp/helloworld-from-cli/GreeterClient/Program.cs b/examples/csharp/helloworld-from-cli/GreeterClient/Program.cs
new file mode 100644
index 0000000..444d473
--- /dev/null
+++ b/examples/csharp/helloworld-from-cli/GreeterClient/Program.cs
@@ -0,0 +1,53 @@
+// 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.
+
+using System;
+using Grpc.Core;
+using Helloworld;
+
+namespace GreeterClient
+{
+    class Program
+    {
+        public static void Main(string[] args)
+        {
+            Channel channel = new Channel("127.0.0.1:50051", ChannelCredentials.Insecure);
+
+            var client = new Greeter.GreeterClient(channel);
+            String user = "you";
+
+            var reply = client.SayHello(new HelloRequest { Name = user });
+            Console.WriteLine("Greeting: " + reply.Message);
+
+            channel.ShutdownAsync().Wait();
+            Console.WriteLine("Press any key to exit...");
+            Console.ReadKey();
+        }
+    }
+}
diff --git a/examples/csharp/helloworld-from-cli/GreeterClient/project.json b/examples/csharp/helloworld-from-cli/GreeterClient/project.json
new file mode 100644
index 0000000..c2bf694
--- /dev/null
+++ b/examples/csharp/helloworld-from-cli/GreeterClient/project.json
@@ -0,0 +1,26 @@
+{
+  "title": "GreeterClient",
+  "version": "1.0.0-*",
+  "buildOptions": {
+    "debugType": "portable",
+    "emitEntryPoint": "true"
+  },
+  "dependencies": {
+    "Google.Protobuf": "3.0.0-beta3",
+    "Grpc": "1.0.0-pre1",
+    "Greeter": {
+      "target": "project"
+    }
+  },
+  "frameworks": {
+    "net45": {
+      "frameworkAssemblies": {
+        "System.Runtime": "",
+        "System.IO": ""
+      },
+      "dependencies": {
+	"Microsoft.NETCore.Platforms": "1.0.1" 
+      }
+    }
+  }
+}
diff --git a/examples/csharp/helloworld-from-cli/GreeterServer/Program.cs b/examples/csharp/helloworld-from-cli/GreeterServer/Program.cs
new file mode 100644
index 0000000..fdab379
--- /dev/null
+++ b/examples/csharp/helloworld-from-cli/GreeterServer/Program.cs
@@ -0,0 +1,66 @@
+// 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.
+
+using System;
+using System.Threading.Tasks;
+using Grpc.Core;
+using Helloworld;
+
+namespace GreeterServer
+{
+    class GreeterImpl : Greeter.GreeterBase
+    {
+        // Server side handler of the SayHello RPC
+        public override Task<HelloReply> SayHello(HelloRequest request, ServerCallContext context)
+        {
+            return Task.FromResult(new HelloReply { Message = "Hello " + request.Name });
+        }
+    }
+
+    class Program
+    {
+        const int Port = 50051;
+
+        public static void Main(string[] args)
+        {
+            Server server = new Server
+            {
+                Services = { Greeter.BindService(new GreeterImpl()) },
+                Ports = { new ServerPort("localhost", Port, ServerCredentials.Insecure) }
+            };
+            server.Start();
+
+            Console.WriteLine("Greeter server listening on port " + Port);
+            Console.WriteLine("Press any key to stop the server...");
+            Console.ReadKey();
+
+            server.ShutdownAsync().Wait();
+        }
+    }
+}
diff --git a/examples/csharp/helloworld-from-cli/GreeterServer/project.json b/examples/csharp/helloworld-from-cli/GreeterServer/project.json
new file mode 100644
index 0000000..29a1067
--- /dev/null
+++ b/examples/csharp/helloworld-from-cli/GreeterServer/project.json
@@ -0,0 +1,26 @@
+{
+  "title": "GreeterServer",
+  "version": "1.0.0-*",
+  "buildOptions": {
+    "debugType": "portable",
+    "emitEntryPoint": "true"
+  },
+  "dependencies": {
+    "Google.Protobuf": "3.0.0-beta3",
+    "Grpc": "1.0.0-pre1",
+    "Greeter": {
+      "target": "project"
+    }
+  },
+  "frameworks": {
+    "net45": {
+      "frameworkAssemblies": {
+        "System.Runtime": "",
+        "System.IO": ""
+      },
+      "dependencies": {
+	"Microsoft.NETCore.Platforms": "1.0.1" 
+      }
+    }
+  }
+}
diff --git a/examples/csharp/helloworld-from-cli/README.md b/examples/csharp/helloworld-from-cli/README.md
new file mode 100644
index 0000000..4db0776
--- /dev/null
+++ b/examples/csharp/helloworld-from-cli/README.md
@@ -0,0 +1,59 @@
+gRPC in 3 minutes (C#)
+========================
+
+BACKGROUND
+-------------
+This is a different version of the helloworld example, using the dotnet sdk
+tools to build and run.
+
+For this sample, we've already generated the server and client stubs from [helloworld.proto][].
+
+Example projects in this directory depend on the [Grpc](https://www.nuget.org/packages/Grpc/)
+and [Google.Protobuf](https://www.nuget.org/packages/Google.Protobuf/) NuGet packages
+which have been already added to the project for you.
+
+The examples in this directory target .NET 4.5 framework, as .NET Core support is
+currently experimental.
+
+PREREQUISITES
+-------------
+
+- The DotNetCore SDK cli.
+
+- The .NET 4.5 framework.
+
+Both are available to download at https://www.microsoft.com/net/download
+
+BUILD
+-------
+
+From the `examples/csharp/helloworld-from-cli` directory:
+
+- `dotnet restore`
+
+- `dotnet build **/project.json` (this will automatically download NuGet dependencies)
+
+Try it!
+-------
+
+- Run the server
+
+  ```
+  > cd GreeterServer
+  > dotnet run
+  ```
+
+- Run the client
+
+  ```
+  > cd GreeterClient
+  > dotnet run
+  ```
+
+Tutorial
+--------
+
+You can find a more detailed tutorial about Grpc in [gRPC Basics: C#][]
+
+[helloworld.proto]:../../protos/helloworld.proto
+[gRPC Basics: C#]:http://www.grpc.io/docs/tutorials/basic/csharp.html
diff --git a/examples/csharp/helloworld/README.md b/examples/csharp/helloworld/README.md
index d13c9ac..71840ad 100644
--- a/examples/csharp/helloworld/README.md
+++ b/examples/csharp/helloworld/README.md
@@ -13,7 +13,7 @@
 -------------
 
 - Windows: .NET Framework 4.5+, Visual Studio 2013 or 2015
-- Linux: Mono 4+, MonoDevelop 5.9+ (with NuGet add-in installed)
+- Linux: Mono 4+, MonoDevelop 5.9+
 - Mac OS X: Xamarin Studio 5.9+
 
 BUILD
@@ -21,7 +21,20 @@
 
 - Open solution `Greeter.sln` with Visual Studio, Monodevelop (on Linux) or Xamarin Studio (on Mac OS X)
 
-- Build the solution (this will automatically download NuGet dependencies)
+# Using Visual Studio
+
+* Build the solution (this will automatically download NuGet dependencies)
+
+# Using Monodevelop or Xamarin Studio
+
+The nuget add-in available for Xamarin Studio and Monodevelop IDEs is too old to 
+download all of the nuget dependencies of gRPC. One alternative to is to use the dotnet command line tools instead (see [helloworld-from-cli]).
+
+Using these IDEs, a workaround is as follows:
+* Obtain a nuget executable for your platform and update it with
+ `nuget update -self`. 
+* Navigate to this directory and run `nuget restore`.
+* Now that packages have been restored into their proper package folder, build the solution from your IDE.
 
 Try it!
 -------
@@ -49,5 +62,6 @@
 
 You can find a more detailed tutorial in [gRPC Basics: C#][]
 
+[helloworld-from-cli]:../helloworld-from-cli/README.md
 [helloworld.proto]:../../protos/helloworld.proto
 [gRPC Basics: C#]:http://www.grpc.io/docs/tutorials/basic/csharp.html
diff --git a/examples/node/package.json b/examples/node/package.json
index 2cae031..6317838 100644
--- a/examples/node/package.json
+++ b/examples/node/package.json
@@ -3,8 +3,8 @@
   "version": "0.1.0",
   "dependencies": {
     "async": "^1.5.2",
-    "google-protobuf": "^3.0.0-alpha.5",
-    "grpc": "^0.14.0",
+    "google-protobuf": "^3.0.0",
+    "grpc": "^1.0.0",
     "lodash": "^4.6.1",
     "minimist": "^1.2.0"
   }
diff --git a/examples/objective-c/auth_sample/AuthTestService.podspec b/examples/objective-c/auth_sample/AuthTestService.podspec
index afccf08..59fbb5f 100644
--- a/examples/objective-c/auth_sample/AuthTestService.podspec
+++ b/examples/objective-c/auth_sample/AuthTestService.podspec
@@ -14,7 +14,7 @@
   src = "../../protos"
 
   # Run protoc with the Objective-C and gRPC plugins to generate protocol messages and gRPC clients.
-  s.dependency "!ProtoCompiler-gRPCPlugin", "~> 1.0.0-pre1.2"
+  s.dependency "!ProtoCompiler-gRPCPlugin", "~> 1.0"
 
   # Pods directory corresponding to this app's Podfile, relative to the location of this podspec.
   pods_root = 'Pods'
@@ -45,10 +45,6 @@
     ms.requires_arc = false
     # The generated files depend on the protobuf runtime.
     ms.dependency "Protobuf"
-    # This is needed by all pods that depend on Protobuf:
-    ms.pod_target_xcconfig = {
-      'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1',
-    }
   end
 
   # Files generated by the gRPC plugin
@@ -60,4 +56,11 @@
     ss.dependency "gRPC-ProtoRPC"
     ss.dependency "#{s.name}/Messages"
   end
+
+  s.pod_target_xcconfig = {
+    # This is needed by all pods that depend on Protobuf:
+    'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1',
+    # This is needed by all pods that depend on gRPC-RxLibrary:
+    'CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES' => 'YES',
+  }
 end
diff --git a/examples/objective-c/helloworld/HelloWorld.podspec b/examples/objective-c/helloworld/HelloWorld.podspec
index 9f07bd6..96a8e2e 100644
--- a/examples/objective-c/helloworld/HelloWorld.podspec
+++ b/examples/objective-c/helloworld/HelloWorld.podspec
@@ -14,7 +14,7 @@
   src = "../../protos"
 
   # Run protoc with the Objective-C and gRPC plugins to generate protocol messages and gRPC clients.
-  s.dependency "!ProtoCompiler-gRPCPlugin", "~> 1.0.0-pre1.2"
+  s.dependency "!ProtoCompiler-gRPCPlugin", "~> 1.0"
 
   # Pods directory corresponding to this app's Podfile, relative to the location of this podspec.
   pods_root = 'Pods'
@@ -45,10 +45,6 @@
     ms.requires_arc = false
     # The generated files depend on the protobuf runtime.
     ms.dependency "Protobuf"
-    # This is needed by all pods that depend on Protobuf:
-    ms.pod_target_xcconfig = {
-      'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1',
-    }
   end
 
   # Files generated by the gRPC plugin
@@ -60,4 +56,11 @@
     ss.dependency "gRPC-ProtoRPC"
     ss.dependency "#{s.name}/Messages"
   end
+
+  s.pod_target_xcconfig = {
+    # This is needed by all pods that depend on Protobuf:
+    'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1',
+    # This is needed by all pods that depend on gRPC-RxLibrary:
+    'CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES' => 'YES',
+  }
 end
diff --git a/examples/objective-c/route_guide/RouteGuide.podspec b/examples/objective-c/route_guide/RouteGuide.podspec
index 7e7e01d..768b5bf 100644
--- a/examples/objective-c/route_guide/RouteGuide.podspec
+++ b/examples/objective-c/route_guide/RouteGuide.podspec
@@ -14,7 +14,7 @@
   src = "../../protos"
 
   # Run protoc with the Objective-C and gRPC plugins to generate protocol messages and gRPC clients.
-  s.dependency "!ProtoCompiler-gRPCPlugin", "~> 1.0.0-pre1.2"
+  s.dependency "!ProtoCompiler-gRPCPlugin", "~> 1.0"
 
   # Pods directory corresponding to this app's Podfile, relative to the location of this podspec.
   pods_root = 'Pods'
@@ -45,10 +45,6 @@
     ms.requires_arc = false
     # The generated files depend on the protobuf runtime.
     ms.dependency "Protobuf"
-    # This is needed by all pods that depend on Protobuf:
-    ms.pod_target_xcconfig = {
-      'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1',
-    }
   end
 
   # Files generated by the gRPC plugin
@@ -60,4 +56,11 @@
     ss.dependency "gRPC-ProtoRPC"
     ss.dependency "#{s.name}/Messages"
   end
+
+  s.pod_target_xcconfig = {
+    # This is needed by all pods that depend on Protobuf:
+    'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1',
+    # This is needed by all pods that depend on gRPC-RxLibrary:
+    'CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES' => 'YES',
+  }
 end
diff --git a/examples/php/composer.json b/examples/php/composer.json
index d40b5db..e6409f8 100644
--- a/examples/php/composer.json
+++ b/examples/php/composer.json
@@ -1,8 +1,7 @@
 {
   "name": "grpc/grpc-demo",
   "description": "gRPC example for PHP",
-  "minimum-stability": "dev",
   "require": {
-    "grpc/grpc": "v0.15.2"
+    "grpc/grpc": "v1.0.0"
   }
 }
diff --git a/examples/ruby/greeter_client.rb b/examples/ruby/greeter_client.rb
index cb4aa19..1cdf79e 100755
--- a/examples/ruby/greeter_client.rb
+++ b/examples/ruby/greeter_client.rb
@@ -38,7 +38,7 @@
 $LOAD_PATH.unshift(lib_dir) unless $LOAD_PATH.include?(lib_dir)
 
 require 'grpc'
-require 'helloworld_services'
+require 'helloworld_services_pb'
 
 def main
   stub = Helloworld::Greeter::Stub.new('localhost:50051', :this_channel_is_insecure)
diff --git a/examples/ruby/greeter_server.rb b/examples/ruby/greeter_server.rb
index 622513d..6d82043 100755
--- a/examples/ruby/greeter_server.rb
+++ b/examples/ruby/greeter_server.rb
@@ -38,7 +38,7 @@
 $LOAD_PATH.unshift(lib_dir) unless $LOAD_PATH.include?(lib_dir)
 
 require 'grpc'
-require 'helloworld_services'
+require 'helloworld_services_pb'
 
 # GreeterServer is simple server that implements the Helloworld Greeter server.
 class GreeterServer < Helloworld::Greeter::Service
diff --git a/examples/ruby/grpc-demo.gemspec b/examples/ruby/grpc-demo.gemspec
index b1dfdae..e1b77a5 100644
--- a/examples/ruby/grpc-demo.gemspec
+++ b/examples/ruby/grpc-demo.gemspec
@@ -3,7 +3,7 @@
 
 Gem::Specification.new do |s|
   s.name          = 'grpc-demo'
-  s.version       = '0.11.0'
+  s.version       = '1.0.0'
   s.authors       = ['gRPC Authors']
   s.email         = 'temiola@google.com'
   s.homepage      = 'https://github.com/grpc/grpc'
@@ -17,7 +17,7 @@
   s.require_paths = ['lib']
   s.platform      = Gem::Platform::RUBY
 
-  s.add_dependency 'grpc', '~> 0.11'
+  s.add_dependency 'grpc', '~> 1.0.0'
 
   s.add_development_dependency 'bundler', '~> 1.7'
 end
diff --git a/examples/ruby/lib/helloworld.rb b/examples/ruby/lib/helloworld_pb.rb
similarity index 100%
rename from examples/ruby/lib/helloworld.rb
rename to examples/ruby/lib/helloworld_pb.rb
diff --git a/examples/ruby/lib/helloworld_services.rb b/examples/ruby/lib/helloworld_services_pb.rb
similarity index 98%
rename from examples/ruby/lib/helloworld_services.rb
rename to examples/ruby/lib/helloworld_services_pb.rb
index fbec667..4fee0aa 100644
--- a/examples/ruby/lib/helloworld_services.rb
+++ b/examples/ruby/lib/helloworld_services_pb.rb
@@ -32,7 +32,7 @@
 #
 
 require 'grpc'
-require 'helloworld'
+require 'helloworld_pb'
 
 module Helloworld
   module Greeter
diff --git a/examples/ruby/lib/route_guide.rb b/examples/ruby/lib/route_guide_pb.rb
similarity index 100%
rename from examples/ruby/lib/route_guide.rb
rename to examples/ruby/lib/route_guide_pb.rb
diff --git a/examples/ruby/lib/route_guide_services.rb b/examples/ruby/lib/route_guide_services_pb.rb
similarity index 98%
rename from examples/ruby/lib/route_guide_services.rb
rename to examples/ruby/lib/route_guide_services_pb.rb
index d8f123d..d43fcc6 100644
--- a/examples/ruby/lib/route_guide_services.rb
+++ b/examples/ruby/lib/route_guide_services_pb.rb
@@ -32,7 +32,7 @@
 #
 
 require 'grpc'
-require 'route_guide'
+require 'route_guide_pb'
 
 module Routeguide
   module RouteGuide
diff --git a/examples/ruby/route_guide/route_guide_client.rb b/examples/ruby/route_guide/route_guide_client.rb
index e7f802c..330725e 100755
--- a/examples/ruby/route_guide/route_guide_client.rb
+++ b/examples/ruby/route_guide/route_guide_client.rb
@@ -39,7 +39,7 @@
 
 require 'grpc'
 require 'multi_json'
-require 'route_guide_services'
+require 'route_guide_services_pb'
 
 include Routeguide
 
diff --git a/examples/ruby/route_guide/route_guide_server.rb b/examples/ruby/route_guide/route_guide_server.rb
index bebe49b..a5a73a8 100755
--- a/examples/ruby/route_guide/route_guide_server.rb
+++ b/examples/ruby/route_guide/route_guide_server.rb
@@ -40,7 +40,7 @@
 
 require 'grpc'
 require 'multi_json'
-require 'route_guide_services'
+require 'route_guide_services_pb'
 
 include Routeguide
 COORD_FACTOR = 1e7
diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec
index 200f9c2..86b811a 100644
--- a/gRPC-Core.podspec
+++ b/gRPC-Core.podspec
@@ -35,7 +35,7 @@
 
 Pod::Spec.new do |s|
   s.name     = 'gRPC-Core'
-  version = '1.0.0-pre1'
+  version = '1.0.0'
   s.version  = version
   s.summary  = 'Core cross-platform gRPC library, written in C'
   s.homepage = 'http://www.grpc.io'
@@ -44,7 +44,7 @@
 
   s.source = {
     :git => 'https://github.com/grpc/grpc.git',
-    :tag => "objective-c-v#{version}",
+    :tag => "v#{version}",
     # TODO(jcanizales): Depend explicitly on the nanopb pod, and disable submodules.
     :submodules => true,
   }
@@ -163,6 +163,7 @@
                       'include/grpc/compression.h',
                       'include/grpc/grpc.h',
                       'include/grpc/grpc_posix.h',
+                      'include/grpc/grpc_security_constants.h',
                       'include/grpc/status.h',
                       'include/grpc/impl/codegen/byte_buffer.h',
                       'include/grpc/impl/codegen/byte_buffer_reader.h',
@@ -186,14 +187,13 @@
                       'include/grpc/impl/codegen/sync_windows.h',
                       'include/grpc/impl/codegen/time.h',
                       'include/grpc/grpc_security.h',
-                      'include/grpc/grpc_security_constants.h',
                       'include/grpc/census.h'
   end
   s.subspec 'Implementation' do |ss|
     ss.header_mappings_dir = '.'
     ss.libraries = 'z'
     ss.dependency "#{s.name}/Interface", version
-    ss.dependency 'BoringSSL', '~> 5.0'
+    ss.dependency 'BoringSSL', '~> 6.0'
 
     # To save you from scrolling, this is the last part of the podspec.
     ss.source_files = 'src/core/lib/profiling/timers.h',
diff --git a/gRPC-ProtoRPC.podspec b/gRPC-ProtoRPC.podspec
index f3a8343..f6426fb 100644
--- a/gRPC-ProtoRPC.podspec
+++ b/gRPC-ProtoRPC.podspec
@@ -30,7 +30,7 @@
 
 Pod::Spec.new do |s|
   s.name     = 'gRPC-ProtoRPC'
-  version = '1.0.0-pre1'
+  version = '1.0.0'
   s.version  = version
   s.summary  = 'RPC library for Protocol Buffers, based on gRPC'
   s.homepage = 'http://www.grpc.io'
@@ -39,7 +39,7 @@
 
   s.source = {
     :git => 'https://github.com/grpc/grpc.git',
-    :tag => "objective-c-v#{version}",
+    :tag => "v#{version}",
   }
 
   s.ios.deployment_target = '7.1'
@@ -56,8 +56,10 @@
   s.dependency 'gRPC', version
   s.dependency 'gRPC-RxLibrary', version
   s.dependency 'Protobuf', '~> 3.0'
-  # This is needed by all pods that depend on Protobuf:
   s.pod_target_xcconfig = {
+    # This is needed by all pods that depend on Protobuf:
     'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1',
+    # This is needed by all pods that depend on gRPC-RxLibrary:
+    'CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES' => 'YES',
   }
 end
diff --git a/gRPC-RxLibrary.podspec b/gRPC-RxLibrary.podspec
index 9936d52..3168434 100644
--- a/gRPC-RxLibrary.podspec
+++ b/gRPC-RxLibrary.podspec
@@ -30,7 +30,7 @@
 
 Pod::Spec.new do |s|
   s.name     = 'gRPC-RxLibrary'
-  version = '1.0.0-pre1'
+  version = '1.0.0'
   s.version  = version
   s.summary  = 'Reactive Extensions library for iOS/OSX.'
   s.homepage = 'http://www.grpc.io'
@@ -39,7 +39,7 @@
 
   s.source = {
     :git => 'https://github.com/grpc/grpc.git',
-    :tag => "objective-c-v#{version}",
+    :tag => "v#{version}",
   }
 
   s.ios.deployment_target = '7.1'
diff --git a/gRPC.podspec b/gRPC.podspec
index 3f6da3b..9a47934 100644
--- a/gRPC.podspec
+++ b/gRPC.podspec
@@ -30,7 +30,7 @@
 
 Pod::Spec.new do |s|
   s.name     = 'gRPC'
-  version = '1.0.0-pre1'
+  version = '1.0.0'
   s.version  = version
   s.summary  = 'gRPC client library for iOS/OSX'
   s.homepage = 'http://www.grpc.io'
@@ -39,7 +39,7 @@
 
   s.source = {
     :git => 'https://github.com/grpc/grpc.git',
-    :tag => "objective-c-v#{version}",
+    :tag => "v#{version}",
   }
 
   s.ios.deployment_target = '7.1'
@@ -59,4 +59,9 @@
 
   # Certificates, to be able to establish TLS connections:
   s.resource_bundles = { 'gRPCCertificates' => ['etc/roots.pem'] }
+
+  s.pod_target_xcconfig = {
+    # This is needed by all pods that depend on gRPC-RxLibrary:
+    'CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES' => 'YES',
+  }
 end
diff --git a/grpc.gemspec b/grpc.gemspec
index 29d8afe..8d74e36 100755
--- a/grpc.gemspec
+++ b/grpc.gemspec
@@ -27,7 +27,7 @@
   s.require_paths = %w( src/ruby/bin src/ruby/lib src/ruby/pb )
   s.platform      = Gem::Platform::RUBY
 
-  s.add_dependency 'google-protobuf', '~> 3.0.0.alpha.5.0.3'
+  s.add_dependency 'google-protobuf', '~> 3.0'
   s.add_dependency 'googleauth',      '~> 0.5.1'
 
   s.add_development_dependency 'bundler',            '~> 1.9'
@@ -146,6 +146,7 @@
   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/grpc_security_constants.h )
   s.files += %w( include/grpc/status.h )
   s.files += %w( include/grpc/impl/codegen/byte_buffer.h )
   s.files += %w( include/grpc/impl/codegen/byte_buffer_reader.h )
@@ -169,7 +170,6 @@
   s.files += %w( include/grpc/impl/codegen/sync_windows.h )
   s.files += %w( include/grpc/impl/codegen/time.h )
   s.files += %w( include/grpc/grpc_security.h )
-  s.files += %w( include/grpc/grpc_security_constants.h )
   s.files += %w( include/grpc/census.h )
   s.files += %w( src/core/lib/channel/channel_args.h )
   s.files += %w( src/core/lib/channel/channel_stack.h )
diff --git a/include/grpc++/impl/codegen/thrift_serializer.h b/include/grpc++/impl/codegen/thrift_serializer.h
new file mode 100644
index 0000000..7308a15
--- /dev/null
+++ b/include/grpc++/impl/codegen/thrift_serializer.h
@@ -0,0 +1,219 @@
+/*
+ *
+ * Copyright 2016, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef GRPCXX_IMPL_CODEGEN_THRIFT_SERIALIZER_H
+#define GRPCXX_IMPL_CODEGEN_THRIFT_SERIALIZER_H
+
+#include <grpc/impl/codegen/byte_buffer.h>
+#include <grpc/impl/codegen/byte_buffer_reader.h>
+#include <grpc/impl/codegen/slice.h>
+#include <grpc/impl/codegen/slice_buffer.h>
+#include <thrift/protocol/TBinaryProtocol.h>
+#include <thrift/protocol/TCompactProtocol.h>
+#include <thrift/protocol/TProtocolException.h>
+#include <thrift/transport/TBufferTransports.h>
+#include <thrift/transport/TTransportUtils.h>
+#include <boost/make_shared.hpp>
+#include <memory>
+#include <stdexcept>
+#include <string>
+
+namespace apache {
+namespace thrift {
+namespace util {
+
+using apache::thrift::protocol::TBinaryProtocolT;
+using apache::thrift::protocol::TCompactProtocolT;
+using apache::thrift::protocol::TMessageType;
+using apache::thrift::protocol::TNetworkBigEndian;
+using apache::thrift::transport::TMemoryBuffer;
+using apache::thrift::transport::TBufferBase;
+using apache::thrift::transport::TTransport;
+
+template <typename Dummy, typename Protocol>
+class ThriftSerializer {
+ public:
+  ThriftSerializer()
+      : prepared_(false),
+        last_deserialized_(false),
+        serialize_version_(false) {}
+
+  virtual ~ThriftSerializer() {}
+
+  // Serialize the passed type into the internal buffer
+  // and returns a pointer to internal buffer and its size
+  template <typename T>
+  void Serialize(const T& fields, const uint8_t** serialized_buffer,
+                 size_t* serialized_len) {
+    // prepare or reset buffer
+    if (!prepared_ || last_deserialized_) {
+      prepare();
+    } else {
+      buffer_->resetBuffer();
+    }
+    last_deserialized_ = false;
+
+    // if required serialize protocol version
+    if (serialize_version_) {
+      protocol_->writeMessageBegin("", TMessageType(0), 0);
+    }
+
+    // serialize fields into buffer
+    fields.write(protocol_.get());
+
+    // write the end of message
+    if (serialize_version_) {
+      protocol_->writeMessageEnd();
+    }
+
+    uint8_t* byte_buffer;
+    uint32_t byte_buffer_size;
+    buffer_->getBuffer(&byte_buffer, &byte_buffer_size);
+    *serialized_buffer = byte_buffer;
+    *serialized_len = byte_buffer_size;
+  }
+
+  // Serialize the passed type into the byte buffer
+  template <typename T>
+  void Serialize(const T& fields, grpc_byte_buffer** bp) {
+    const uint8_t* byte_buffer;
+    size_t byte_buffer_size;
+
+    Serialize(fields, &byte_buffer, &byte_buffer_size);
+
+    gpr_slice slice = gpr_slice_from_copied_buffer(
+        reinterpret_cast<const char*>(byte_buffer), byte_buffer_size);
+
+    *bp = grpc_raw_byte_buffer_create(&slice, 1);
+
+    gpr_slice_unref(slice);
+  }
+
+  // Deserialize the passed char array into  the passed type, returns the number
+  // of bytes that have been consumed from the passed string.
+  template <typename T>
+  uint32_t Deserialize(uint8_t* serialized_buffer, size_t length, T* fields) {
+    // prepare buffer if necessary
+    if (!prepared_) {
+      prepare();
+    }
+    last_deserialized_ = true;
+
+    // reset buffer transport
+    buffer_->resetBuffer(serialized_buffer, length);
+
+    // read the protocol version if necessary
+    if (serialize_version_) {
+      std::string name = "";
+      TMessageType mt = static_cast<TMessageType>(0);
+      int32_t seq_id = 0;
+      protocol_->readMessageBegin(name, mt, seq_id);
+    }
+
+    // deserialize buffer into fields
+    uint32_t len = fields->read(protocol_.get());
+
+    // read the end of message
+    if (serialize_version_) {
+      protocol_->readMessageEnd();
+    }
+
+    return len;
+  }
+
+  // Deserialize the passed byte buffer to passed type, returns the number
+  // of bytes consumed from byte buffer
+  template <typename T>
+  uint32_t Deserialize(grpc_byte_buffer* buffer, T* msg) {
+    grpc_byte_buffer_reader reader;
+    grpc_byte_buffer_reader_init(&reader, buffer);
+
+    gpr_slice slice = grpc_byte_buffer_reader_readall(&reader);
+
+    uint32_t len =
+        Deserialize(GPR_SLICE_START_PTR(slice), GPR_SLICE_LENGTH(slice), msg);
+
+    gpr_slice_unref(slice);
+
+    grpc_byte_buffer_reader_destroy(&reader);
+
+    return len;
+  }
+
+  // set serialization version flag
+  void SetSerializeVersion(bool value) { serialize_version_ = value; }
+
+  // Set the container size limit to deserialize
+  // This function should be called after buffer_ is initialized
+  void SetContainerSizeLimit(int32_t container_limit) {
+    if (!prepared_) {
+      prepare();
+    }
+    protocol_->setContainerSizeLimit(container_limit);
+  }
+
+  // Set the string size limit to deserialize
+  // This function should be called after buffer_ is initialized
+  void SetStringSizeLimit(int32_t string_limit) {
+    if (!prepared_) {
+      prepare();
+    }
+    protocol_->setStringSizeLimit(string_limit);
+  }
+
+ private:
+  bool prepared_;
+  bool last_deserialized_;
+  boost::shared_ptr<TMemoryBuffer> buffer_;
+  std::shared_ptr<Protocol> protocol_;
+  bool serialize_version_;
+
+  void prepare() {
+    buffer_ = boost::make_shared<TMemoryBuffer>();
+    // create a protocol for the memory buffer transport
+    protocol_ = std::make_shared<Protocol>(buffer_);
+    prepared_ = true;
+  }
+
+};  // ThriftSerializer
+
+typedef ThriftSerializer<void, TBinaryProtocolT<TBufferBase, TNetworkBigEndian>>
+    ThriftSerializerBinary;
+typedef ThriftSerializer<void, TCompactProtocolT<TBufferBase>>
+    ThriftSerializerCompact;
+
+}  // namespace util
+}  // namespace thrift
+}  // namespace apache
+
+#endif
\ No newline at end of file
diff --git a/include/grpc++/impl/codegen/thrift_utils.h b/include/grpc++/impl/codegen/thrift_utils.h
new file mode 100644
index 0000000..7d19b24
--- /dev/null
+++ b/include/grpc++/impl/codegen/thrift_utils.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 GRPCXX_IMPL_CODEGEN_THRIFT_UTILS_H
+#define GRPCXX_IMPL_CODEGEN_THRIFT_UTILS_H
+
+#include <grpc++/impl/codegen/config.h>
+#include <grpc++/impl/codegen/core_codegen_interface.h>
+#include <grpc++/impl/codegen/serialization_traits.h>
+#include <grpc++/impl/codegen/status.h>
+#include <grpc++/impl/codegen/status_code_enum.h>
+#include <grpc++/impl/codegen/thrift_serializer.h>
+#include <grpc/impl/codegen/byte_buffer.h>
+#include <grpc/impl/codegen/byte_buffer_reader.h>
+#include <grpc/impl/codegen/slice.h>
+#include <grpc/impl/codegen/slice_buffer.h>
+#include <cstdint>
+#include <cstdlib>
+
+namespace grpc {
+
+using apache::thrift::util::ThriftSerializerCompact;
+
+template <class T>
+class SerializationTraits<T, typename std::enable_if<std::is_base_of<
+                                 apache::thrift::TBase, T>::value>::type> {
+ public:
+  static Status Serialize(const T& msg, grpc_byte_buffer** bp,
+                          bool* own_buffer) {
+    *own_buffer = true;
+
+    ThriftSerializerCompact serializer;
+    serializer.Serialize(msg, bp);
+
+    return Status(StatusCode::OK, "ok");
+  }
+
+  static Status Deserialize(grpc_byte_buffer* buffer, T* msg,
+                            int max_message_size) {
+    if (!buffer) {
+      return Status(StatusCode::INTERNAL, "No payload");
+    }
+
+    ThriftSerializerCompact deserializer;
+    deserializer.Deserialize(buffer, msg);
+
+    grpc_byte_buffer_destroy(buffer);
+
+    return Status(StatusCode::OK, "ok");
+  }
+};
+
+}  // namespace grpc
+
+#endif  // GRPCXX_IMPL_CODEGEN_THRIFT_UTILS_H
diff --git a/include/grpc++/support/byte_buffer.h b/include/grpc++/support/byte_buffer.h
index 20bd407..01249a0 100644
--- a/include/grpc++/support/byte_buffer.h
+++ b/include/grpc++/support/byte_buffer.h
@@ -72,6 +72,9 @@
   /// Buffer size in bytes.
   size_t Length() const;
 
+  /// Swap the state of *this and *other.
+  void Swap(ByteBuffer* other);
+
  private:
   friend class SerializationTraits<ByteBuffer, void>;
 
diff --git a/package.json b/package.json
index 0e229c9..9afba31 100644
--- a/package.json
+++ b/package.json
@@ -35,7 +35,7 @@
   "devDependencies": {
     "async": "^1.5.0",
     "google-auth-library": "^0.9.2",
-    "google-protobuf": "^3.0.0-alpha.5",
+    "google-protobuf": "^3.0.0",
     "istanbul": "^0.3.21",
     "jsdoc": "^3.3.2",
     "jshint": "^2.5.0",
diff --git a/package.xml b/package.xml
index 38b74f5..387afc3 100644
--- a/package.xml
+++ b/package.xml
@@ -10,11 +10,11 @@
   <email>grpc-packages@google.com</email>
   <active>yes</active>
  </lead>
- <date>2016-07-28</date>
+ <date>2016-08-22</date>
  <time>16:06:07</time>
  <version>
-  <release>1.1.0</release>
-  <api>1.1.0</api>
+  <release>1.1.0dev</release>
+  <api>1.1.0dev</api>
  </version>
  <stability>
   <release>stable</release>
@@ -22,7 +22,7 @@
  </stability>
  <license>BSD</license>
  <notes>
-- PHP7 Support continued, reduce code duplication #7543
+- TBD
  </notes>
  <contents>
   <dir baseinstalldir="/" name="/">
@@ -154,6 +154,7 @@
     <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/grpc_security_constants.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/status.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/impl/codegen/byte_buffer.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/impl/codegen/byte_buffer_reader.h" role="src" />
@@ -177,7 +178,6 @@
     <file baseinstalldir="/" name="include/grpc/impl/codegen/sync_windows.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/impl/codegen/time.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/grpc_security.h" role="src" />
-    <file baseinstalldir="/" name="include/grpc/grpc_security_constants.h" role="src" />
     <file baseinstalldir="/" name="include/grpc/census.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/channel/channel_args.h" role="src" />
     <file baseinstalldir="/" name="src/core/lib/channel/channel_stack.h" role="src" />
@@ -1139,5 +1139,50 @@
 - PHP7 Support continued, reduce code duplication #7543
    </notes>
   </release>
+  <release>
+   <version>
+    <release>1.0.0RC4</release>
+    <api>1.0.0RC4</api>
+   </version>
+   <stability>
+    <release>stable</release>
+    <api>stable</api>
+   </stability>
+   <date>2016-08-09</date>
+   <license>BSD</license>
+   <notes>
+- Fixed Ubuntu compile error #7571, #7642
+   </notes>
+  </release>
+  <release>
+   <version>
+    <release>1.0.0</release>
+    <api>1.0.0</api>
+   </version>
+   <stability>
+    <release>stable</release>
+    <api>stable</api>
+   </stability>
+   <date>2016-08-18</date>
+   <license>BSD</license>
+   <notes>
+- gRPC 1.0.0 release
+   </notes>
+  </release>
+  <release>
+   <version>
+    <release>1.1.0dev</release>
+    <api>1.1.0dev</api>
+   </version>
+   <stability>
+    <release>stable</release>
+    <api>stable</api>
+   </stability>
+   <date>2016-08-22</date>
+   <license>BSD</license>
+   <notes>
+- TBD
+   </notes>
+  </release>
  </changelog>
 </package>
diff --git a/setup.py b/setup.py
index fb9537f..f728095 100644
--- a/setup.py
+++ b/setup.py
@@ -28,7 +28,7 @@
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 """A setup module for the GRPC Python package."""
-
+from distutils import cygwinccompiler
 from distutils import extension as _extension
 from distutils import util
 import os
@@ -58,14 +58,12 @@
 sys.path.insert(0, os.path.abspath(PYTHON_STEM))
 
 # Break import-style to ensure we can actually find our in-repo dependencies.
-import _unixccompiler_patch
+import _spawn_patch
 import commands
 import grpc_core_dependencies
 import grpc_version
 
-if 'win32' in sys.platform:
-  _unixccompiler_patch.monkeypatch_unix_compiler()
-
+_spawn_patch.monkeypatch_spawn()
 
 LICENSE = '3-clause BSD'
 
@@ -91,8 +89,8 @@
 EXTRA_ENV_COMPILE_ARGS = os.environ.get('GRPC_PYTHON_CFLAGS', None)
 EXTRA_ENV_LINK_ARGS = os.environ.get('GRPC_PYTHON_LDFLAGS', None)
 if EXTRA_ENV_COMPILE_ARGS is None:
-  EXTRA_ENV_COMPILE_ARGS = '-fno-wrapv'
-  if 'win32' in sys.platform:
+  EXTRA_ENV_COMPILE_ARGS = ''
+  if 'win32' in sys.platform and sys.version_info < (3, 5):
     # We use define flags here and don't directly add to DEFINE_MACROS below to
     # ensure that the expert user/builder has a way of turning it off (via the
     # envvars) without adding yet more GRPC-specific envvars.
@@ -102,21 +100,21 @@
     else:
       EXTRA_ENV_COMPILE_ARGS += ' -D_ftime=_ftime64 -D_timeb=__timeb64'
   elif "linux" in sys.platform or "darwin" in sys.platform:
-    EXTRA_ENV_COMPILE_ARGS += ' -fvisibility=hidden'
+    EXTRA_ENV_COMPILE_ARGS += ' -fvisibility=hidden -fno-wrapv'
 if EXTRA_ENV_LINK_ARGS is None:
-  EXTRA_ENV_LINK_ARGS = '-lpthread'
-  if 'win32' in sys.platform:
-    # TODO(atash) check if this is actually safe to just import and call on
-    # non-Windows (to avoid breaking import style)
-    from distutils.cygwinccompiler import get_msvcr
-    msvcr = get_msvcr()[0]
+  EXTRA_ENV_LINK_ARGS = ''
+  if "linux" in sys.platform or "darwin" in sys.platform:
+    EXTRA_ENV_LINK_ARGS += ' -lpthread'
+  elif "win32" in sys.platform and sys.version_info < (3, 5):
+    msvcr = cygwinccompiler.get_msvcr()[0]
     # TODO(atash) sift through the GCC specs to see if libstdc++ can have any
     # influence on the linkage outcome on MinGW for non-C++ programs.
     EXTRA_ENV_LINK_ARGS += (
         ' -static-libgcc -static-libstdc++ -mcrtdll={msvcr} '
         '-static'.format(msvcr=msvcr))
-  elif "linux" in sys.platform:
+  if "linux" in sys.platform:
     EXTRA_ENV_LINK_ARGS += ' -Wl,-wrap,memcpy'
+
 EXTRA_COMPILE_ARGS = shlex.split(EXTRA_ENV_COMPILE_ARGS)
 EXTRA_LINK_ARGS = shlex.split(EXTRA_ENV_LINK_ARGS)
 
@@ -137,15 +135,19 @@
 if not "win32" in sys.platform:
   EXTENSION_LIBRARIES += ('m',)
 if "win32" in sys.platform:
-  EXTENSION_LIBRARIES += ('ws2_32',)
+  EXTENSION_LIBRARIES += ('advapi32', 'ws2_32',)
 
 DEFINE_MACROS = (
     ('OPENSSL_NO_ASM', 1), ('_WIN32_WINNT', 0x600),
     ('GPR_BACKWARDS_COMPATIBILITY_MODE', 1),)
 if "win32" in sys.platform:
-  DEFINE_MACROS += (('OPENSSL_WINDOWS', 1), ('WIN32_LEAN_AND_MEAN', 1),)
+  DEFINE_MACROS += (('WIN32_LEAN_AND_MEAN', 1),)
   if '64bit' in platform.architecture()[0]:
     DEFINE_MACROS += (('MS_WIN64', 1),)
+  elif sys.version_info >= (3, 5):
+    # For some reason, this is needed to get access to inet_pton/inet_ntop
+    # on msvc, but only for 32 bits
+    DEFINE_MACROS += (('NTDDI_VERSION', 0x06000000),)
 
 LDFLAGS = tuple(EXTRA_LINK_ARGS)
 CFLAGS = tuple(EXTRA_COMPILE_ARGS)
@@ -154,7 +156,6 @@
   pymodinit = '__attribute__((visibility ("default"))) {}'.format(pymodinit_type)
   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)
diff --git a/src/core/ext/transport/cronet/transport/cronet_transport.c b/src/core/ext/transport/cronet/transport/cronet_transport.c
index 25d8aca..029c150 100644
--- a/src/core/ext/transport/cronet/transport/cronet_transport.c
+++ b/src/core/ext/transport/cronet/transport/cronet_transport.c
@@ -46,189 +46,519 @@
 #include "src/core/lib/support/string.h"
 #include "src/core/lib/surface/channel.h"
 #include "src/core/lib/transport/metadata_batch.h"
+#include "src/core/lib/transport/static_metadata.h"
 #include "src/core/lib/transport/transport_impl.h"
 #include "third_party/objective_c/Cronet/cronet_c_for_grpc.h"
 
 #define GRPC_HEADER_SIZE_IN_BYTES 5
 
-// Global flag that gets set with GRPC_TRACE env variable
-int grpc_cronet_trace = 1;
+#define CRONET_LOG(...)                          \
+  do {                                           \
+    if (grpc_cronet_trace) gpr_log(__VA_ARGS__); \
+  } while (0)
 
-// Cronet transport object
+/* TODO (makdharma): Hook up into the wider tracing mechanism */
+int grpc_cronet_trace = 0;
+
+enum e_op_result {
+  ACTION_TAKEN_WITH_CALLBACK,
+  ACTION_TAKEN_NO_CALLBACK,
+  NO_ACTION_POSSIBLE
+};
+
+enum e_op_id {
+  OP_SEND_INITIAL_METADATA = 0,
+  OP_SEND_MESSAGE,
+  OP_SEND_TRAILING_METADATA,
+  OP_RECV_MESSAGE,
+  OP_RECV_INITIAL_METADATA,
+  OP_RECV_TRAILING_METADATA,
+  OP_CANCEL_ERROR,
+  OP_ON_COMPLETE,
+  OP_FAILED,
+  OP_SUCCEEDED,
+  OP_CANCELED,
+  OP_RECV_MESSAGE_AND_ON_COMPLETE,
+  OP_READ_REQ_MADE,
+  OP_NUM_OPS
+};
+
+/* Cronet callbacks. See cronet_c_for_grpc.h for documentation for each. */
+
+static void on_request_headers_sent(cronet_bidirectional_stream *);
+static void on_response_headers_received(
+    cronet_bidirectional_stream *,
+    const cronet_bidirectional_stream_header_array *, const char *);
+static void on_write_completed(cronet_bidirectional_stream *, const char *);
+static void on_read_completed(cronet_bidirectional_stream *, char *, int);
+static void on_response_trailers_received(
+    cronet_bidirectional_stream *,
+    const cronet_bidirectional_stream_header_array *);
+static void on_succeeded(cronet_bidirectional_stream *);
+static void on_failed(cronet_bidirectional_stream *, int);
+static void on_canceled(cronet_bidirectional_stream *);
+static cronet_bidirectional_stream_callback cronet_callbacks = {
+    on_request_headers_sent,
+    on_response_headers_received,
+    on_read_completed,
+    on_write_completed,
+    on_response_trailers_received,
+    on_succeeded,
+    on_failed,
+    on_canceled};
+
+/* Cronet transport object */
 struct grpc_cronet_transport {
   grpc_transport base; /* must be first element in this structure */
   cronet_engine *engine;
   char *host;
 };
-
 typedef struct grpc_cronet_transport grpc_cronet_transport;
 
-enum send_state {
-  CRONET_SEND_IDLE = 0,
-  CRONET_REQ_STARTED,
-  CRONET_SEND_HEADER,
-  CRONET_WRITE,
-  CRONET_WRITE_COMPLETED,
+/* TODO (makdharma): reorder structure for memory efficiency per
+   http://www.catb.org/esr/structure-packing/#_structure_reordering: */
+struct read_state {
+  /* vars to store data coming from server */
+  char *read_buffer;
+  bool length_field_received;
+  int received_bytes;
+  int remaining_bytes;
+  int length_field;
+  char grpc_header_bytes[GRPC_HEADER_SIZE_IN_BYTES];
+  char *payload_field;
+  bool read_stream_closed;
+
+  /* vars for holding data destined for the application */
+  struct grpc_slice_buffer_stream sbs;
+  gpr_slice_buffer read_slice_buffer;
+
+  /* vars for trailing metadata */
+  grpc_chttp2_incoming_metadata_buffer trailing_metadata;
+  bool trailing_metadata_valid;
+
+  /* vars for initial metadata */
+  grpc_chttp2_incoming_metadata_buffer initial_metadata;
 };
 
-enum recv_state {
-  CRONET_RECV_IDLE = 0,
-  CRONET_RECV_READ_LENGTH,
-  CRONET_RECV_READ_DATA,
-  CRONET_RECV_CLOSED,
+struct write_state {
+  char *write_buffer;
 };
 
-static const char *recv_state_name[] = {
-    "CRONET_RECV_IDLE", "CRONET_RECV_READ_LENGTH", "CRONET_RECV_READ_DATA,",
-    "CRONET_RECV_CLOSED"};
-
-// Enum that identifies calling function.
-enum e_caller {
-  PERFORM_STREAM_OP,
-  ON_READ_COMPLETE,
-  ON_RESPONSE_HEADERS_RECEIVED,
-  ON_RESPONSE_TRAILERS_RECEIVED
+/* track state of one stream op */
+struct op_state {
+  bool state_op_done[OP_NUM_OPS];
+  bool state_callback_received[OP_NUM_OPS];
+  /* data structure for storing data coming from server */
+  struct read_state rs;
+  /* data structure for storing data going to the server */
+  struct write_state ws;
 };
 
-enum callback_id {
-  CB_SEND_INITIAL_METADATA = 0,
-  CB_SEND_MESSAGE,
-  CB_SEND_TRAILING_METADATA,
-  CB_RECV_MESSAGE,
-  CB_RECV_INITIAL_METADATA,
-  CB_RECV_TRAILING_METADATA,
-  CB_NUM_CALLBACKS
+struct op_and_state {
+  grpc_transport_stream_op op;
+  struct op_state state;
+  bool done;
+  struct stream_obj *s;      /* Pointer back to the stream object */
+  struct op_and_state *next; /* next op_and_state in the linked list */
+};
+
+struct op_storage {
+  int num_pending_ops;
+  struct op_and_state *head;
 };
 
 struct stream_obj {
-  // we store received bytes here as they trickle in.
-  gpr_slice_buffer write_slice_buffer;
+  struct op_and_state *oas;
+  grpc_transport_stream_op *curr_op;
+  grpc_cronet_transport curr_ct;
+  grpc_stream *curr_gs;
   cronet_bidirectional_stream *cbs;
-  gpr_slice slice;
-  gpr_slice_buffer read_slice_buffer;
-  struct grpc_slice_buffer_stream sbs;
-  char *read_buffer;
-  int remaining_read_bytes;
-  int total_read_bytes;
-
-  char *write_buffer;
-  size_t write_buffer_size;
-
-  // Hold the URL
-  char *url;
-
-  bool response_headers_received;
-  bool read_requested;
-  bool response_trailers_received;
-  bool read_closed;
-
-  // Recv message stuff
-  grpc_byte_buffer **recv_message;
-  // Initial metadata stuff
-  grpc_metadata_batch *recv_initial_metadata;
-  // Trailing metadata stuff
-  grpc_metadata_batch *recv_trailing_metadata;
-  grpc_chttp2_incoming_metadata_buffer imb;
-
-  // This mutex protects receive state machine execution
-  gpr_mu recv_mu;
-  // we can queue up up to 2 callbacks for each OP
-  grpc_closure *callback_list[CB_NUM_CALLBACKS][2];
-
-  // storage for header
-  cronet_bidirectional_stream_header *headers;
-  uint32_t num_headers;
   cronet_bidirectional_stream_header_array header_array;
-  // state tracking
-  enum recv_state cronet_recv_state;
-  enum send_state cronet_send_state;
-};
 
+  /* Stream level state. Some state will be tracked both at stream and stream_op
+   * level */
+  struct op_state state;
+
+  /* OP storage */
+  struct op_storage storage;
+
+  /* Mutex to protect storage */
+  gpr_mu mu;
+};
 typedef struct stream_obj stream_obj;
 
-static void next_send_step(stream_obj *s);
-static void next_recv_step(stream_obj *s, enum e_caller caller);
+static enum e_op_result execute_stream_op(grpc_exec_ctx *exec_ctx,
+                                          struct op_and_state *oas);
 
-static void set_pollset_do_nothing(grpc_exec_ctx *exec_ctx, grpc_transport *gt,
-                                   grpc_stream *gs, grpc_pollset *pollset) {}
+/*
+  Utility function to translate enum into string for printing
+*/
+static const char *op_result_string(enum e_op_result i) {
+  switch (i) {
+    case ACTION_TAKEN_WITH_CALLBACK:
+      return "ACTION_TAKEN_WITH_CALLBACK";
+    case ACTION_TAKEN_NO_CALLBACK:
+      return "ACTION_TAKEN_NO_CALLBACK";
+    case NO_ACTION_POSSIBLE:
+      return "NO_ACTION_POSSIBLE";
+  }
+  GPR_UNREACHABLE_CODE(return "UNKNOWN");
+}
 
-static void set_pollset_set_do_nothing(grpc_exec_ctx *exec_ctx,
-                                       grpc_transport *gt, grpc_stream *gs,
-                                       grpc_pollset_set *pollset_set) {}
+static const char *op_id_string(enum e_op_id i) {
+  switch (i) {
+    case OP_SEND_INITIAL_METADATA:
+      return "OP_SEND_INITIAL_METADATA";
+    case OP_SEND_MESSAGE:
+      return "OP_SEND_MESSAGE";
+    case OP_SEND_TRAILING_METADATA:
+      return "OP_SEND_TRAILING_METADATA";
+    case OP_RECV_MESSAGE:
+      return "OP_RECV_MESSAGE";
+    case OP_RECV_INITIAL_METADATA:
+      return "OP_RECV_INITIAL_METADATA";
+    case OP_RECV_TRAILING_METADATA:
+      return "OP_RECV_TRAILING_METADATA";
+    case OP_CANCEL_ERROR:
+      return "OP_CANCEL_ERROR";
+    case OP_ON_COMPLETE:
+      return "OP_ON_COMPLETE";
+    case OP_FAILED:
+      return "OP_FAILED";
+    case OP_SUCCEEDED:
+      return "OP_SUCCEEDED";
+    case OP_CANCELED:
+      return "OP_CANCELED";
+    case OP_RECV_MESSAGE_AND_ON_COMPLETE:
+      return "OP_RECV_MESSAGE_AND_ON_COMPLETE";
+    case OP_READ_REQ_MADE:
+      return "OP_READ_REQ_MADE";
+    case OP_NUM_OPS:
+      return "OP_NUM_OPS";
+  }
+  return "UNKNOWN";
+}
 
-static void enqueue_callbacks(grpc_closure *callback_list[]) {
+/*
+  Add a new stream op to op storage.
+*/
+static void add_to_storage(struct stream_obj *s, grpc_transport_stream_op *op) {
+  struct op_storage *storage = &s->storage;
+  /* add new op at the beginning of the linked list. The memory is freed
+  in remove_from_storage */
+  struct op_and_state *new_op = gpr_malloc(sizeof(struct op_and_state));
+  memcpy(&new_op->op, op, sizeof(grpc_transport_stream_op));
+  memset(&new_op->state, 0, sizeof(new_op->state));
+  new_op->s = s;
+  new_op->done = false;
+  gpr_mu_lock(&s->mu);
+  new_op->next = storage->head;
+  storage->head = new_op;
+  storage->num_pending_ops++;
+  CRONET_LOG(GPR_DEBUG, "adding new op %p. %d in the queue.", new_op,
+             storage->num_pending_ops);
+  gpr_mu_unlock(&s->mu);
+}
+
+/*
+  Traverse the linked list and delete op and free memory
+*/
+static void remove_from_storage(struct stream_obj *s,
+                                struct op_and_state *oas) {
+  struct op_and_state *curr;
+  if (s->storage.head == NULL || oas == NULL) {
+    return;
+  }
+  if (s->storage.head == oas) {
+    s->storage.head = oas->next;
+    gpr_free(oas);
+    s->storage.num_pending_ops--;
+    CRONET_LOG(GPR_DEBUG, "Freed %p. Now %d in the queue", oas,
+               s->storage.num_pending_ops);
+  } else {
+    for (curr = s->storage.head; curr != NULL; curr = curr->next) {
+      if (curr->next == oas) {
+        curr->next = oas->next;
+        s->storage.num_pending_ops--;
+        CRONET_LOG(GPR_DEBUG, "Freed %p. Now %d in the queue", oas,
+                   s->storage.num_pending_ops);
+        gpr_free(oas);
+        break;
+      } else if (curr->next == NULL) {
+        CRONET_LOG(GPR_ERROR, "Reached end of LL and did not find op to free");
+      }
+    }
+  }
+}
+
+/*
+  Cycle through ops and try to take next action. Break when either
+  an action with callback is taken, or no action is possible.
+  This can be executed from the Cronet network thread via cronet callback
+  or on the application supplied thread via the perform_stream_op function.
+*/
+static void execute_from_storage(stream_obj *s) {
   grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
-  if (callback_list[0]) {
-    grpc_exec_ctx_sched(&exec_ctx, callback_list[0], GRPC_ERROR_NONE, NULL);
-    callback_list[0] = NULL;
+  gpr_mu_lock(&s->mu);
+  for (struct op_and_state *curr = s->storage.head; curr != NULL;) {
+    CRONET_LOG(GPR_DEBUG, "calling op at %p. done = %d", curr, curr->done);
+    GPR_ASSERT(curr->done == 0);
+    enum e_op_result result = execute_stream_op(&exec_ctx, curr);
+    CRONET_LOG(GPR_DEBUG, "execute_stream_op[%p] returns %s", curr,
+               op_result_string(result));
+    /* if this op is done, then remove it and free memory */
+    if (curr->done) {
+      struct op_and_state *next = curr->next;
+      remove_from_storage(s, curr);
+      curr = next;
+    }
+    /* continue processing the same op if ACTION_TAKEN_WITHOUT_CALLBACK */
+    if (result == NO_ACTION_POSSIBLE) {
+      curr = curr->next;
+    } else if (result == ACTION_TAKEN_WITH_CALLBACK) {
+      break;
+    }
   }
-  if (callback_list[1]) {
-    grpc_exec_ctx_sched(&exec_ctx, callback_list[1], GRPC_ERROR_NONE, NULL);
-    callback_list[1] = NULL;
-  }
+  gpr_mu_unlock(&s->mu);
   grpc_exec_ctx_finish(&exec_ctx);
 }
 
-static void on_canceled(cronet_bidirectional_stream *stream) {
-  if (grpc_cronet_trace) {
-    gpr_log(GPR_DEBUG, "on_canceled %p", stream);
-  }
-}
-
+/*
+  Cronet callback
+*/
 static void on_failed(cronet_bidirectional_stream *stream, int net_error) {
-  if (grpc_cronet_trace) {
-    gpr_log(GPR_DEBUG, "on_failed %p, error = %d", stream, net_error);
+  CRONET_LOG(GPR_DEBUG, "on_failed(%p, %d)", stream, net_error);
+  stream_obj *s = (stream_obj *)stream->annotation;
+  cronet_bidirectional_stream_destroy(s->cbs);
+  s->state.state_callback_received[OP_FAILED] = true;
+  s->cbs = NULL;
+  if (s->header_array.headers) {
+    gpr_free(s->header_array.headers);
+    s->header_array.headers = NULL;
   }
+  if (s->state.ws.write_buffer) {
+    gpr_free(s->state.ws.write_buffer);
+    s->state.ws.write_buffer = NULL;
+  }
+  execute_from_storage(s);
 }
 
+/*
+  Cronet callback
+*/
+static void on_canceled(cronet_bidirectional_stream *stream) {
+  CRONET_LOG(GPR_DEBUG, "on_canceled(%p)", stream);
+  stream_obj *s = (stream_obj *)stream->annotation;
+  cronet_bidirectional_stream_destroy(s->cbs);
+  s->state.state_callback_received[OP_CANCELED] = true;
+  s->cbs = NULL;
+  if (s->header_array.headers) {
+    gpr_free(s->header_array.headers);
+    s->header_array.headers = NULL;
+  }
+  if (s->state.ws.write_buffer) {
+    gpr_free(s->state.ws.write_buffer);
+    s->state.ws.write_buffer = NULL;
+  }
+  execute_from_storage(s);
+}
+
+/*
+  Cronet callback
+*/
 static void on_succeeded(cronet_bidirectional_stream *stream) {
-  if (grpc_cronet_trace) {
-    gpr_log(GPR_DEBUG, "on_succeeded %p", stream);
+  CRONET_LOG(GPR_DEBUG, "on_succeeded(%p)", stream);
+  stream_obj *s = (stream_obj *)stream->annotation;
+  cronet_bidirectional_stream_destroy(s->cbs);
+  s->state.state_callback_received[OP_SUCCEEDED] = true;
+  s->cbs = NULL;
+  execute_from_storage(s);
+}
+
+/*
+  Cronet callback
+*/
+static void on_request_headers_sent(cronet_bidirectional_stream *stream) {
+  CRONET_LOG(GPR_DEBUG, "W: on_request_headers_sent(%p)", stream);
+  stream_obj *s = (stream_obj *)stream->annotation;
+  s->state.state_op_done[OP_SEND_INITIAL_METADATA] = true;
+  s->state.state_callback_received[OP_SEND_INITIAL_METADATA] = true;
+  /* Free the memory allocated for headers */
+  if (s->header_array.headers) {
+    gpr_free(s->header_array.headers);
+    s->header_array.headers = NULL;
+  }
+  execute_from_storage(s);
+}
+
+/*
+  Cronet callback
+*/
+static void on_response_headers_received(
+    cronet_bidirectional_stream *stream,
+    const cronet_bidirectional_stream_header_array *headers,
+    const char *negotiated_protocol) {
+  CRONET_LOG(GPR_DEBUG, "R: on_response_headers_received(%p, %p, %s)", stream,
+             headers, negotiated_protocol);
+  stream_obj *s = (stream_obj *)stream->annotation;
+  memset(&s->state.rs.initial_metadata, 0,
+         sizeof(s->state.rs.initial_metadata));
+  grpc_chttp2_incoming_metadata_buffer_init(&s->state.rs.initial_metadata);
+  for (size_t i = 0; i < headers->count; i++) {
+    grpc_chttp2_incoming_metadata_buffer_add(
+        &s->state.rs.initial_metadata,
+        grpc_mdelem_from_metadata_strings(
+            grpc_mdstr_from_string(headers->headers[i].key),
+            grpc_mdstr_from_string(headers->headers[i].value)));
+  }
+  s->state.state_callback_received[OP_RECV_INITIAL_METADATA] = true;
+  execute_from_storage(s);
+}
+
+/*
+  Cronet callback
+*/
+static void on_write_completed(cronet_bidirectional_stream *stream,
+                               const char *data) {
+  stream_obj *s = (stream_obj *)stream->annotation;
+  CRONET_LOG(GPR_DEBUG, "W: on_write_completed(%p, %s)", stream, data);
+  if (s->state.ws.write_buffer) {
+    gpr_free(s->state.ws.write_buffer);
+    s->state.ws.write_buffer = NULL;
+  }
+  s->state.state_callback_received[OP_SEND_MESSAGE] = true;
+  execute_from_storage(s);
+}
+
+/*
+  Cronet callback
+*/
+static void on_read_completed(cronet_bidirectional_stream *stream, char *data,
+                              int count) {
+  stream_obj *s = (stream_obj *)stream->annotation;
+  CRONET_LOG(GPR_DEBUG, "R: on_read_completed(%p, %p, %d)", stream, data,
+             count);
+  s->state.state_callback_received[OP_RECV_MESSAGE] = true;
+  if (count > 0) {
+    s->state.rs.received_bytes += count;
+    s->state.rs.remaining_bytes -= count;
+    if (s->state.rs.remaining_bytes > 0) {
+      CRONET_LOG(GPR_DEBUG, "cronet_bidirectional_stream_read(%p)", s->cbs);
+      s->state.state_op_done[OP_READ_REQ_MADE] = true;
+      cronet_bidirectional_stream_read(
+          s->cbs, s->state.rs.read_buffer + s->state.rs.received_bytes,
+          s->state.rs.remaining_bytes);
+    } else {
+      execute_from_storage(s);
+    }
+  } else {
+    s->state.rs.read_stream_closed = true;
+    execute_from_storage(s);
   }
 }
 
+/*
+  Cronet callback
+*/
 static void on_response_trailers_received(
     cronet_bidirectional_stream *stream,
     const cronet_bidirectional_stream_header_array *trailers) {
-  if (grpc_cronet_trace) {
-    gpr_log(GPR_DEBUG, "R: on_response_trailers_received");
-  }
+  CRONET_LOG(GPR_DEBUG, "R: on_response_trailers_received(%p,%p)", stream,
+             trailers);
   stream_obj *s = (stream_obj *)stream->annotation;
-
-  memset(&s->imb, 0, sizeof(s->imb));
-  grpc_chttp2_incoming_metadata_buffer_init(&s->imb);
-  unsigned int i = 0;
-  for (i = 0; i < trailers->count; i++) {
+  memset(&s->state.rs.trailing_metadata, 0,
+         sizeof(s->state.rs.trailing_metadata));
+  s->state.rs.trailing_metadata_valid = false;
+  grpc_chttp2_incoming_metadata_buffer_init(&s->state.rs.trailing_metadata);
+  for (size_t i = 0; i < trailers->count; i++) {
+    CRONET_LOG(GPR_DEBUG, "trailer key=%s, value=%s", trailers->headers[i].key,
+               trailers->headers[i].value);
     grpc_chttp2_incoming_metadata_buffer_add(
-        &s->imb, grpc_mdelem_from_metadata_strings(
-                     grpc_mdstr_from_string(trailers->headers[i].key),
-                     grpc_mdstr_from_string(trailers->headers[i].value)));
+        &s->state.rs.trailing_metadata,
+        grpc_mdelem_from_metadata_strings(
+            grpc_mdstr_from_string(trailers->headers[i].key),
+            grpc_mdstr_from_string(trailers->headers[i].value)));
+    s->state.rs.trailing_metadata_valid = true;
   }
-  s->response_trailers_received = true;
-  next_recv_step(s, ON_RESPONSE_TRAILERS_RECEIVED);
+  s->state.state_callback_received[OP_RECV_TRAILING_METADATA] = true;
+  execute_from_storage(s);
 }
 
-static void on_write_completed(cronet_bidirectional_stream *stream,
-                               const char *data) {
-  if (grpc_cronet_trace) {
-    gpr_log(GPR_DEBUG, "W: on_write_completed");
-  }
-  stream_obj *s = (stream_obj *)stream->annotation;
-  enqueue_callbacks(s->callback_list[CB_SEND_MESSAGE]);
-  s->cronet_send_state = CRONET_WRITE_COMPLETED;
-  next_send_step(s);
+/*
+ Utility function that takes the data from s->write_slice_buffer and assembles
+ into a contiguous byte stream with 5 byte gRPC header prepended.
+*/
+static void create_grpc_frame(gpr_slice_buffer *write_slice_buffer,
+                              char **pp_write_buffer,
+                              size_t *p_write_buffer_size) {
+  gpr_slice slice = gpr_slice_buffer_take_first(write_slice_buffer);
+  size_t length = GPR_SLICE_LENGTH(slice);
+  *p_write_buffer_size = length + GRPC_HEADER_SIZE_IN_BYTES;
+  /* This is freed in the on_write_completed callback */
+  char *write_buffer = gpr_malloc(length + GRPC_HEADER_SIZE_IN_BYTES);
+  *pp_write_buffer = write_buffer;
+  uint8_t *p = (uint8_t *)write_buffer;
+  /* Append 5 byte header */
+  *p++ = 0;
+  *p++ = (uint8_t)(length >> 24);
+  *p++ = (uint8_t)(length >> 16);
+  *p++ = (uint8_t)(length >> 8);
+  *p++ = (uint8_t)(length);
+  /* append actual data */
+  memcpy(p, GPR_SLICE_START_PTR(slice), length);
 }
 
-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);
-  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);
+/*
+ Convert metadata in a format that Cronet can consume
+*/
+static void convert_metadata_to_cronet_headers(
+    grpc_linked_mdelem *head, const char *host, char **pp_url,
+    cronet_bidirectional_stream_header **pp_headers, size_t *p_num_headers) {
+  grpc_linked_mdelem *curr = head;
+  /* Walk the linked list and get number of header fields */
+  size_t num_headers_available = 0;
+  while (curr != NULL) {
+    curr = curr->next;
+    num_headers_available++;
   }
-  grpc_slice_buffer_stream_init(&s->sbs, &s->read_slice_buffer, 0);
-  *s->recv_message = (grpc_byte_buffer *)&s->sbs;
+  /* Allocate enough memory. It is freed in the on_request_headers_sent callback
+   */
+  cronet_bidirectional_stream_header *headers =
+      (cronet_bidirectional_stream_header *)gpr_malloc(
+          sizeof(cronet_bidirectional_stream_header) * num_headers_available);
+  *pp_headers = headers;
+
+  /* Walk the linked list again, this time copying the header fields.
+    s->num_headers can be less than num_headers_available, as some headers
+    are not used for cronet.
+    TODO (makdharma): Eliminate need to traverse the LL second time for perf.
+   */
+  curr = head;
+  size_t num_headers = 0;
+  while (num_headers < num_headers_available) {
+    grpc_mdelem *mdelem = curr->md;
+    curr = curr->next;
+    const char *key = grpc_mdstr_as_c_string(mdelem->key);
+    const char *value = grpc_mdstr_as_c_string(mdelem->value);
+    if (mdelem->key == GRPC_MDSTR_METHOD || mdelem->key == GRPC_MDSTR_SCHEME ||
+        mdelem->key == GRPC_MDSTR_AUTHORITY) {
+      /* Cronet populates these fields on its own */
+      continue;
+    }
+    if (mdelem->key == GRPC_MDSTR_PATH) {
+      /* Create URL by appending :path value to the hostname */
+      gpr_asprintf(pp_url, "https://%s%s", host, value);
+      continue;
+    }
+    CRONET_LOG(GPR_DEBUG, "header %s = %s", key, value);
+    headers[num_headers].key = key;
+    headers[num_headers].value = value;
+    num_headers++;
+    if (curr == NULL) {
+      break;
+    }
+  }
+  *p_num_headers = (size_t)num_headers;
 }
 
 static int parse_grpc_header(const uint8_t *data) {
@@ -241,422 +571,439 @@
   return length;
 }
 
-static void on_read_completed(cronet_bidirectional_stream *stream, char *data,
-                              int count) {
-  stream_obj *s = (stream_obj *)stream->annotation;
-  if (grpc_cronet_trace) {
-    gpr_log(GPR_DEBUG, "R: on_read_completed count=%d, total=%d, remaining=%d",
-            count, s->total_read_bytes, s->remaining_read_bytes);
-  }
-  if (count > 0) {
-    GPR_ASSERT(s->recv_message);
-    s->remaining_read_bytes -= count;
-    next_recv_step(s, ON_READ_COMPLETE);
-  } else {
-    s->read_closed = true;
-    next_recv_step(s, ON_READ_COMPLETE);
-  }
-}
-
-static void on_response_headers_received(
-    cronet_bidirectional_stream *stream,
-    const cronet_bidirectional_stream_header_array *headers,
-    const char *negotiated_protocol) {
-  if (grpc_cronet_trace) {
-    gpr_log(GPR_DEBUG, "R: on_response_headers_received");
-  }
-  stream_obj *s = (stream_obj *)stream->annotation;
-  enqueue_callbacks(s->callback_list[CB_RECV_INITIAL_METADATA]);
-  s->response_headers_received = true;
-  next_recv_step(s, ON_RESPONSE_HEADERS_RECEIVED);
-}
-
-static void on_request_headers_sent(cronet_bidirectional_stream *stream) {
-  if (grpc_cronet_trace) {
-    gpr_log(GPR_DEBUG, "W: on_request_headers_sent");
-  }
-  stream_obj *s = (stream_obj *)stream->annotation;
-  enqueue_callbacks(s->callback_list[CB_SEND_INITIAL_METADATA]);
-  s->cronet_send_state = CRONET_SEND_HEADER;
-  next_send_step(s);
-}
-
-// Callback function pointers (invoked by cronet in response to events)
-static cronet_bidirectional_stream_callback callbacks = {
-    on_request_headers_sent,
-    on_response_headers_received,
-    on_read_completed,
-    on_write_completed,
-    on_response_trailers_received,
-    on_succeeded,
-    on_failed,
-    on_canceled};
-
-static void invoke_closing_callback(stream_obj *s) {
-  grpc_chttp2_incoming_metadata_buffer_publish(&s->imb,
-                                               s->recv_trailing_metadata);
-  if (s->callback_list[CB_RECV_TRAILING_METADATA]) {
-    enqueue_callbacks(s->callback_list[CB_RECV_TRAILING_METADATA]);
-  }
-}
-
-static void set_recv_state(stream_obj *s, enum recv_state state) {
-  if (grpc_cronet_trace) {
-    gpr_log(GPR_DEBUG, "next_state = %s", recv_state_name[state]);
-  }
-  s->cronet_recv_state = state;
-}
-
-// This is invoked from perform_stream_op, and all on_xxxx callbacks.
-static void next_recv_step(stream_obj *s, enum e_caller caller) {
-  gpr_mu_lock(&s->recv_mu);
-  switch (s->cronet_recv_state) {
-    case CRONET_RECV_IDLE:
-      if (grpc_cronet_trace) {
-        gpr_log(GPR_DEBUG, "cronet_recv_state = CRONET_RECV_IDLE");
+/*
+  Op Execution: Decide if one of the actions contained in the stream op can be
+  executed. This is the heart of the state machine.
+*/
+static bool op_can_be_run(grpc_transport_stream_op *curr_op,
+                          struct op_state *stream_state,
+                          struct op_state *op_state, enum e_op_id op_id) {
+  bool result = true;
+  /* When call is canceled, every op can be run, except under following
+  conditions
+  */
+  bool is_canceled_of_failed = stream_state->state_op_done[OP_CANCEL_ERROR] ||
+                               stream_state->state_callback_received[OP_FAILED];
+  if (is_canceled_of_failed) {
+    if (op_id == OP_SEND_INITIAL_METADATA) result = false;
+    if (op_id == OP_SEND_MESSAGE) result = false;
+    if (op_id == OP_SEND_TRAILING_METADATA) result = false;
+    if (op_id == OP_CANCEL_ERROR) result = false;
+    /* already executed */
+    if (op_id == OP_RECV_INITIAL_METADATA &&
+        stream_state->state_op_done[OP_RECV_INITIAL_METADATA])
+      result = false;
+    if (op_id == OP_RECV_MESSAGE &&
+        stream_state->state_op_done[OP_RECV_MESSAGE])
+      result = false;
+    if (op_id == OP_RECV_TRAILING_METADATA &&
+        stream_state->state_op_done[OP_RECV_TRAILING_METADATA])
+      result = false;
+  } else if (op_id == OP_SEND_INITIAL_METADATA) {
+    /* already executed */
+    if (stream_state->state_op_done[OP_SEND_INITIAL_METADATA]) result = false;
+  } else if (op_id == OP_RECV_INITIAL_METADATA) {
+    /* already executed */
+    if (stream_state->state_op_done[OP_RECV_INITIAL_METADATA]) result = false;
+    /* we haven't sent headers yet. */
+    else if (!stream_state->state_callback_received[OP_SEND_INITIAL_METADATA])
+      result = false;
+    /* we haven't received headers yet. */
+    else if (!stream_state->state_callback_received[OP_RECV_INITIAL_METADATA])
+      result = false;
+  } else if (op_id == OP_SEND_MESSAGE) {
+    /* already executed (note we're checking op specific state, not stream
+     state) */
+    if (op_state->state_op_done[OP_SEND_MESSAGE]) result = false;
+    /* we haven't sent headers yet. */
+    else if (!stream_state->state_callback_received[OP_SEND_INITIAL_METADATA])
+      result = false;
+  } else if (op_id == OP_RECV_MESSAGE) {
+    /* already executed */
+    if (op_state->state_op_done[OP_RECV_MESSAGE]) result = false;
+    /* we haven't received headers yet. */
+    else if (!stream_state->state_callback_received[OP_RECV_INITIAL_METADATA])
+      result = false;
+  } else if (op_id == OP_RECV_TRAILING_METADATA) {
+    /* already executed */
+    if (stream_state->state_op_done[OP_RECV_TRAILING_METADATA]) result = false;
+    /* we have asked for but haven't received message yet. */
+    else if (stream_state->state_op_done[OP_READ_REQ_MADE] &&
+             !stream_state->state_op_done[OP_RECV_MESSAGE])
+      result = false;
+    /* we haven't received trailers  yet. */
+    else if (!stream_state->state_callback_received[OP_RECV_TRAILING_METADATA])
+      result = false;
+    /* we haven't received on_succeeded  yet. */
+    else if (!stream_state->state_callback_received[OP_SUCCEEDED])
+      result = false;
+  } else if (op_id == OP_SEND_TRAILING_METADATA) {
+    /* already executed */
+    if (stream_state->state_op_done[OP_SEND_TRAILING_METADATA]) result = false;
+    /* we haven't sent initial metadata yet */
+    else if (!stream_state->state_callback_received[OP_SEND_INITIAL_METADATA])
+      result = false;
+    /* we haven't sent message yet */
+    else if (curr_op->send_message &&
+             !stream_state->state_op_done[OP_SEND_MESSAGE])
+      result = false;
+    /* we haven't got on_write_completed for the send yet */
+    else if (stream_state->state_op_done[OP_SEND_MESSAGE] &&
+             !stream_state->state_callback_received[OP_SEND_MESSAGE])
+      result = false;
+  } else if (op_id == OP_CANCEL_ERROR) {
+    /* already executed */
+    if (stream_state->state_op_done[OP_CANCEL_ERROR]) result = false;
+  } else if (op_id == OP_ON_COMPLETE) {
+    /* already executed (note we're checking op specific state, not stream
+    state) */
+    if (op_state->state_op_done[OP_ON_COMPLETE]) {
+      CRONET_LOG(GPR_DEBUG, "Because");
+      result = false;
+    }
+    /* Check if every op that was asked for is done. */
+    else if (curr_op->send_initial_metadata &&
+             !stream_state->state_callback_received[OP_SEND_INITIAL_METADATA]) {
+      CRONET_LOG(GPR_DEBUG, "Because");
+      result = false;
+    } else if (curr_op->send_message &&
+               !op_state->state_op_done[OP_SEND_MESSAGE]) {
+      CRONET_LOG(GPR_DEBUG, "Because");
+      result = false;
+    } else if (curr_op->send_message &&
+               !stream_state->state_callback_received[OP_SEND_MESSAGE]) {
+      CRONET_LOG(GPR_DEBUG, "Because");
+      result = false;
+    } else if (curr_op->send_trailing_metadata &&
+               !stream_state->state_op_done[OP_SEND_TRAILING_METADATA]) {
+      CRONET_LOG(GPR_DEBUG, "Because");
+      result = false;
+    } else if (curr_op->recv_initial_metadata &&
+               !stream_state->state_op_done[OP_RECV_INITIAL_METADATA]) {
+      CRONET_LOG(GPR_DEBUG, "Because");
+      result = false;
+    } else if (curr_op->recv_message &&
+               !stream_state->state_op_done[OP_RECV_MESSAGE]) {
+      CRONET_LOG(GPR_DEBUG, "Because");
+      result = false;
+    } else if (curr_op->recv_trailing_metadata) {
+      /* We aren't done with trailing metadata yet */
+      if (!stream_state->state_op_done[OP_RECV_TRAILING_METADATA]) {
+        CRONET_LOG(GPR_DEBUG, "Because");
+        result = false;
       }
-      if (caller == PERFORM_STREAM_OP ||
-          caller == ON_RESPONSE_HEADERS_RECEIVED) {
-        if (s->read_closed && s->response_trailers_received) {
-          invoke_closing_callback(s);
-          set_recv_state(s, CRONET_RECV_CLOSED);
-        } else if (s->response_headers_received == true &&
-                   s->read_requested == true) {
-          set_recv_state(s, CRONET_RECV_READ_LENGTH);
-          s->total_read_bytes = s->remaining_read_bytes =
-              GRPC_HEADER_SIZE_IN_BYTES;
-          GPR_ASSERT(s->read_buffer);
-          if (grpc_cronet_trace) {
-            gpr_log(GPR_DEBUG, "R: cronet_bidirectional_stream_read()");
-          }
-          cronet_bidirectional_stream_read(s->cbs, s->read_buffer,
-                                           s->remaining_read_bytes);
+      /* We've asked for actual message in an earlier op, and it hasn't been
+        delivered yet. */
+      else if (stream_state->state_op_done[OP_READ_REQ_MADE]) {
+        /* If this op is not the one asking for read, (which means some earlier
+          op has asked), and the read hasn't been delivered. */
+        if (!curr_op->recv_message &&
+            !stream_state->state_callback_received[OP_SUCCEEDED]) {
+          CRONET_LOG(GPR_DEBUG, "Because");
+          result = false;
         }
       }
-      break;
-    case CRONET_RECV_READ_LENGTH:
-      if (grpc_cronet_trace) {
-        gpr_log(GPR_DEBUG, "cronet_recv_state = CRONET_RECV_READ_LENGTH");
-      }
-      if (caller == ON_READ_COMPLETE) {
-        if (s->read_closed) {
-          invoke_closing_callback(s);
-          enqueue_callbacks(s->callback_list[CB_RECV_MESSAGE]);
-          set_recv_state(s, CRONET_RECV_CLOSED);
-        } else {
-          GPR_ASSERT(s->remaining_read_bytes == 0);
-          set_recv_state(s, CRONET_RECV_READ_DATA);
-          s->total_read_bytes = s->remaining_read_bytes =
-              parse_grpc_header((const uint8_t *)s->read_buffer);
-          s->read_buffer =
-              gpr_realloc(s->read_buffer, (uint32_t)s->remaining_read_bytes);
-          GPR_ASSERT(s->read_buffer);
-          if (grpc_cronet_trace) {
-            gpr_log(GPR_DEBUG, "R: cronet_bidirectional_stream_read()");
-          }
-          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;
-    case CRONET_RECV_READ_DATA:
-      if (grpc_cronet_trace) {
-        gpr_log(GPR_DEBUG, "cronet_recv_state = CRONET_RECV_READ_DATA");
-      }
-      if (caller == ON_READ_COMPLETE) {
-        if (s->remaining_read_bytes > 0) {
-          int offset = s->total_read_bytes - s->remaining_read_bytes;
-          GPR_ASSERT(s->read_buffer);
-          if (grpc_cronet_trace) {
-            gpr_log(GPR_DEBUG, "R: cronet_bidirectional_stream_read()");
-          }
-          cronet_bidirectional_stream_read(
-              s->cbs, (char *)s->read_buffer + offset, s->remaining_read_bytes);
-        } else {
-          gpr_slice_buffer_init(&s->read_slice_buffer);
-          uint8_t *p = (uint8_t *)s->read_buffer;
-          process_recv_message(s, p);
-          set_recv_state(s, CRONET_RECV_IDLE);
-          enqueue_callbacks(s->callback_list[CB_RECV_MESSAGE]);
-        }
-      }
-      break;
-    case CRONET_RECV_CLOSED:
-      break;
-    default:
-      GPR_ASSERT(0);  // Should not reach here
-      break;
+    }
+    /* We should see at least one on_write_completed for the trailers that we
+      sent */
+    else if (curr_op->send_trailing_metadata &&
+             !stream_state->state_callback_received[OP_SEND_MESSAGE])
+      result = false;
   }
-  gpr_mu_unlock(&s->recv_mu);
+  CRONET_LOG(GPR_DEBUG, "op_can_be_run %s : %s", op_id_string(op_id),
+             result ? "YES" : "NO");
+  return result;
 }
 
-// This function takes the data from s->write_slice_buffer and assembles into
-// a contiguous byte stream with 5 byte gRPC header prepended.
-static void create_grpc_frame(stream_obj *s) {
-  gpr_slice slice = gpr_slice_buffer_take_first(&s->write_slice_buffer);
-  uint8_t *raw_data = GPR_SLICE_START_PTR(slice);
-  size_t length = GPR_SLICE_LENGTH(slice);
-  s->write_buffer_size = length + GRPC_HEADER_SIZE_IN_BYTES;
-  s->write_buffer = gpr_realloc(s->write_buffer, s->write_buffer_size);
-  uint8_t *p = (uint8_t *)s->write_buffer;
-  // Append 5 byte header
-  *p++ = 0;
-  *p++ = (uint8_t)(length >> 24);
-  *p++ = (uint8_t)(length >> 16);
-  *p++ = (uint8_t)(length >> 8);
-  *p++ = (uint8_t)(length);
-  // append actual data
-  memcpy(p, raw_data, length);
-}
-
-static void do_write(stream_obj *s) {
-  gpr_slice_buffer *sb = &s->write_slice_buffer;
-  GPR_ASSERT(sb->count <= 1);
-  if (sb->count > 0) {
-    create_grpc_frame(s);
-    if (grpc_cronet_trace) {
-      gpr_log(GPR_DEBUG, "W: cronet_bidirectional_stream_write");
-    }
-    cronet_bidirectional_stream_write(s->cbs, s->write_buffer,
-                                      (int)s->write_buffer_size, false);
-  }
-}
-
-//
-static void next_send_step(stream_obj *s) {
-  switch (s->cronet_send_state) {
-    case CRONET_SEND_IDLE:
-      GPR_ASSERT(
-          s->cbs);  // cronet_bidirectional_stream is not initialized yet.
-      s->cronet_send_state = CRONET_REQ_STARTED;
-      if (grpc_cronet_trace) {
-        gpr_log(GPR_DEBUG, "cronet_bidirectional_stream_start to %s", s->url);
-      }
-      cronet_bidirectional_stream_start(s->cbs, s->url, 0, "POST",
-                                        &s->header_array, false);
-      // we no longer need the memory that was allocated earlier.
-      gpr_free(s->header_array.headers);
-      break;
-    case CRONET_SEND_HEADER:
-      do_write(s);
-      s->cronet_send_state = CRONET_WRITE;
-      break;
-    case CRONET_WRITE_COMPLETED:
-      do_write(s);
-      break;
-    default:
-      GPR_ASSERT(0);
-      break;
-  }
-}
-
-static void convert_metadata_to_cronet_headers(grpc_linked_mdelem *head,
-                                               const char *host,
-                                               stream_obj *s) {
-  grpc_linked_mdelem *curr = head;
-  // Walk the linked list and get number of header fields
-  uint32_t num_headers_available = 0;
-  while (curr != NULL) {
-    curr = curr->next;
-    num_headers_available++;
-  }
-  // Allocate enough memory
-  s->headers = (cronet_bidirectional_stream_header *)gpr_malloc(
-      sizeof(cronet_bidirectional_stream_header) * num_headers_available);
-
-  // Walk the linked list again, this time copying the header fields.
-  // s->num_headers
-  // can be less than num_headers_available, as some headers are not used for
-  // cronet
-  curr = head;
-  s->num_headers = 0;
-  while (s->num_headers < num_headers_available) {
-    grpc_mdelem *mdelem = curr->md;
-    curr = curr->next;
-    const char *key = grpc_mdstr_as_c_string(mdelem->key);
-    const char *value = grpc_mdstr_as_c_string(mdelem->value);
-    if (strcmp(key, ":scheme") == 0 || strcmp(key, ":method") == 0 ||
-        strcmp(key, ":authority") == 0) {
-      // Cronet populates these fields on its own.
-      continue;
-    }
-    if (strcmp(key, ":path") == 0) {
-      // Create URL by appending :path value to the hostname
-      gpr_asprintf(&s->url, "https://%s%s", host, value);
-      if (grpc_cronet_trace) {
-        gpr_log(GPR_DEBUG, "extracted URL = %s", s->url);
-      }
-      continue;
-    }
-    s->headers[s->num_headers].key = key;
-    s->headers[s->num_headers].value = value;
-    s->num_headers++;
-    if (curr == NULL) {
-      break;
-    }
-  }
-}
-
-static void perform_stream_op(grpc_exec_ctx *exec_ctx, grpc_transport *gt,
-                              grpc_stream *gs, grpc_transport_stream_op *op) {
-  grpc_cronet_transport *ct = (grpc_cronet_transport *)gt;
-  GPR_ASSERT(ct->engine);
-  stream_obj *s = (stream_obj *)gs;
-  if (op->recv_trailing_metadata) {
-    if (grpc_cronet_trace) {
-      gpr_log(GPR_DEBUG,
-              "perform_stream_op - recv_trailing_metadata: on_complete=%p",
-              op->on_complete);
-    }
-    s->recv_trailing_metadata = op->recv_trailing_metadata;
-    GPR_ASSERT(!s->callback_list[CB_RECV_TRAILING_METADATA][0]);
-    s->callback_list[CB_RECV_TRAILING_METADATA][0] = op->on_complete;
-  }
-  if (op->recv_message) {
-    if (grpc_cronet_trace) {
-      gpr_log(GPR_DEBUG, "perform_stream_op - recv_message: on_complete=%p",
-              op->on_complete);
-    }
-    s->recv_message = (grpc_byte_buffer **)op->recv_message;
-    GPR_ASSERT(!s->callback_list[CB_RECV_MESSAGE][0]);
-    GPR_ASSERT(!s->callback_list[CB_RECV_MESSAGE][1]);
-    s->callback_list[CB_RECV_MESSAGE][0] = op->recv_message_ready;
-    s->callback_list[CB_RECV_MESSAGE][1] = op->on_complete;
-    s->read_requested = true;
-    next_recv_step(s, PERFORM_STREAM_OP);
-  }
-  if (op->recv_initial_metadata) {
-    if (grpc_cronet_trace) {
-      gpr_log(GPR_DEBUG, "perform_stream_op - recv_initial_metadata:=%p",
-              op->on_complete);
-    }
-    s->recv_initial_metadata = op->recv_initial_metadata;
-    GPR_ASSERT(!s->callback_list[CB_RECV_INITIAL_METADATA][0]);
-    GPR_ASSERT(!s->callback_list[CB_RECV_INITIAL_METADATA][1]);
-    s->callback_list[CB_RECV_INITIAL_METADATA][0] =
-        op->recv_initial_metadata_ready;
-    s->callback_list[CB_RECV_INITIAL_METADATA][1] = op->on_complete;
-  }
-  if (op->send_initial_metadata) {
-    if (grpc_cronet_trace) {
-      gpr_log(GPR_DEBUG,
-              "perform_stream_op - send_initial_metadata: on_complete=%p",
-              op->on_complete);
-    }
-    s->num_headers = 0;
-    convert_metadata_to_cronet_headers(op->send_initial_metadata->list.head,
-                                       ct->host, s);
-    s->header_array.count = s->num_headers;
-    s->header_array.capacity = s->num_headers;
-    s->header_array.headers = s->headers;
-    GPR_ASSERT(!s->callback_list[CB_SEND_INITIAL_METADATA][0]);
-    s->callback_list[CB_SEND_INITIAL_METADATA][0] = op->on_complete;
-  }
-  if (op->send_message) {
-    if (grpc_cronet_trace) {
-      gpr_log(GPR_DEBUG, "perform_stream_op - send_message: on_complete=%p",
-              op->on_complete);
-    }
-    grpc_byte_stream_next(exec_ctx, op->send_message, &s->slice,
-                          op->send_message->length, NULL);
-    // Check that compression flag is not ON. We don't support compression yet.
-    // TODO (makdharma): add compression support
-    GPR_ASSERT(op->send_message->flags == 0);
-    gpr_slice_buffer_add(&s->write_slice_buffer, s->slice);
-    if (s->cbs == NULL) {
-      if (grpc_cronet_trace) {
-        gpr_log(GPR_DEBUG, "cronet_bidirectional_stream_create");
-      }
-      s->cbs = cronet_bidirectional_stream_create(ct->engine, s, &callbacks);
-      GPR_ASSERT(s->cbs);
-      s->read_closed = false;
-      s->response_trailers_received = false;
-      s->response_headers_received = false;
-      s->cronet_send_state = CRONET_SEND_IDLE;
-      s->cronet_recv_state = CRONET_RECV_IDLE;
-    }
-    GPR_ASSERT(!s->callback_list[CB_SEND_MESSAGE][0]);
-    s->callback_list[CB_SEND_MESSAGE][0] = op->on_complete;
-    next_send_step(s);
-  }
-  if (op->send_trailing_metadata) {
-    if (grpc_cronet_trace) {
-      gpr_log(GPR_DEBUG,
-              "perform_stream_op - send_trailing_metadata: on_complete=%p",
-              op->on_complete);
-    }
-    GPR_ASSERT(!s->callback_list[CB_SEND_TRAILING_METADATA][0]);
-    s->callback_list[CB_SEND_TRAILING_METADATA][0] = op->on_complete;
-    if (s->cbs) {
-      // Send an "empty" write to the far end to signal that we're done.
-      // This will induce the server to send down trailers.
-      if (grpc_cronet_trace) {
-        gpr_log(GPR_DEBUG, "W: cronet_bidirectional_stream_write");
-      }
-      cronet_bidirectional_stream_write(s->cbs, "abc", 0, true);
+/*
+  TODO (makdharma): Break down this function in smaller chunks for readability.
+*/
+static enum e_op_result execute_stream_op(grpc_exec_ctx *exec_ctx,
+                                          struct op_and_state *oas) {
+  grpc_transport_stream_op *stream_op = &oas->op;
+  struct stream_obj *s = oas->s;
+  struct op_state *stream_state = &s->state;
+  enum e_op_result result = NO_ACTION_POSSIBLE;
+  if (stream_op->send_initial_metadata &&
+      op_can_be_run(stream_op, stream_state, &oas->state,
+                    OP_SEND_INITIAL_METADATA)) {
+    CRONET_LOG(GPR_DEBUG, "running: %p OP_SEND_INITIAL_METADATA", oas);
+    /* This OP is the beginning. Reset various states */
+    memset(&s->header_array, 0, sizeof(s->header_array));
+    memset(&stream_state->rs, 0, sizeof(stream_state->rs));
+    memset(&stream_state->ws, 0, sizeof(stream_state->ws));
+    memset(stream_state->state_op_done, 0, sizeof(stream_state->state_op_done));
+    memset(stream_state->state_callback_received, 0,
+           sizeof(stream_state->state_callback_received));
+    /* Start new cronet stream. It is destroyed in on_succeeded, on_canceled,
+     * on_failed */
+    GPR_ASSERT(s->cbs == NULL);
+    s->cbs = cronet_bidirectional_stream_create(s->curr_ct.engine, s->curr_gs,
+                                                &cronet_callbacks);
+    CRONET_LOG(GPR_DEBUG, "%p = cronet_bidirectional_stream_create()", s->cbs);
+    char *url;
+    s->header_array.headers = NULL;
+    convert_metadata_to_cronet_headers(
+        stream_op->send_initial_metadata->list.head, s->curr_ct.host, &url,
+        &s->header_array.headers, &s->header_array.count);
+    s->header_array.capacity = s->header_array.count;
+    CRONET_LOG(GPR_DEBUG, "cronet_bidirectional_stream_start(%p, %s)", s->cbs,
+               url);
+    cronet_bidirectional_stream_start(s->cbs, url, 0, "POST", &s->header_array,
+                                      false);
+    stream_state->state_op_done[OP_SEND_INITIAL_METADATA] = true;
+    result = ACTION_TAKEN_WITH_CALLBACK;
+  } else if (stream_op->recv_initial_metadata &&
+             op_can_be_run(stream_op, stream_state, &oas->state,
+                           OP_RECV_INITIAL_METADATA)) {
+    CRONET_LOG(GPR_DEBUG, "running: %p  OP_RECV_INITIAL_METADATA", oas);
+    if (!stream_state->state_op_done[OP_CANCEL_ERROR]) {
+      grpc_chttp2_incoming_metadata_buffer_publish(
+          &oas->s->state.rs.initial_metadata, stream_op->recv_initial_metadata);
+      grpc_exec_ctx_sched(exec_ctx, stream_op->recv_initial_metadata_ready,
+                          GRPC_ERROR_NONE, NULL);
     } else {
-      // We never created a stream. This was probably an empty request.
-      invoke_closing_callback(s);
+      grpc_exec_ctx_sched(exec_ctx, stream_op->recv_initial_metadata_ready,
+                          GRPC_ERROR_CANCELLED, NULL);
     }
+    stream_state->state_op_done[OP_RECV_INITIAL_METADATA] = true;
+    result = ACTION_TAKEN_NO_CALLBACK;
+  } else if (stream_op->send_message &&
+             op_can_be_run(stream_op, stream_state, &oas->state,
+                           OP_SEND_MESSAGE)) {
+    CRONET_LOG(GPR_DEBUG, "running: %p  OP_SEND_MESSAGE", oas);
+    gpr_slice_buffer write_slice_buffer;
+    gpr_slice slice;
+    gpr_slice_buffer_init(&write_slice_buffer);
+    grpc_byte_stream_next(NULL, stream_op->send_message, &slice,
+                          stream_op->send_message->length, NULL);
+    /* Check that compression flag is OFF. We don't support compression yet. */
+    if (stream_op->send_message->flags != 0) {
+      gpr_log(GPR_ERROR, "Compression is not supported");
+      GPR_ASSERT(stream_op->send_message->flags == 0);
+    }
+    gpr_slice_buffer_add(&write_slice_buffer, slice);
+    if (write_slice_buffer.count != 1) {
+      /* Empty request not handled yet */
+      gpr_log(GPR_ERROR, "Empty request is not supported");
+      GPR_ASSERT(write_slice_buffer.count == 1);
+    }
+    if (write_slice_buffer.count > 0) {
+      size_t write_buffer_size;
+      create_grpc_frame(&write_slice_buffer, &stream_state->ws.write_buffer,
+                        &write_buffer_size);
+      CRONET_LOG(GPR_DEBUG, "cronet_bidirectional_stream_write (%p, %p)",
+                 s->cbs, stream_state->ws.write_buffer);
+      stream_state->state_callback_received[OP_SEND_MESSAGE] = false;
+      cronet_bidirectional_stream_write(s->cbs, stream_state->ws.write_buffer,
+                                        (int)write_buffer_size, false);
+      result = ACTION_TAKEN_WITH_CALLBACK;
+    }
+    stream_state->state_op_done[OP_SEND_MESSAGE] = true;
+    oas->state.state_op_done[OP_SEND_MESSAGE] = true;
+  } else if (stream_op->recv_message &&
+             op_can_be_run(stream_op, stream_state, &oas->state,
+                           OP_RECV_MESSAGE)) {
+    CRONET_LOG(GPR_DEBUG, "running: %p  OP_RECV_MESSAGE", oas);
+    if (stream_state->state_op_done[OP_CANCEL_ERROR]) {
+      grpc_exec_ctx_sched(exec_ctx, stream_op->recv_message_ready,
+                          GRPC_ERROR_CANCELLED, NULL);
+      stream_state->state_op_done[OP_RECV_MESSAGE] = true;
+    } else if (stream_state->rs.read_stream_closed == true) {
+      /* No more data will be received */
+      CRONET_LOG(GPR_DEBUG, "read stream closed");
+      grpc_exec_ctx_sched(exec_ctx, stream_op->recv_message_ready,
+                          GRPC_ERROR_NONE, NULL);
+      stream_state->state_op_done[OP_RECV_MESSAGE] = true;
+      oas->state.state_op_done[OP_RECV_MESSAGE] = true;
+    } else if (stream_state->rs.length_field_received == false) {
+      if (stream_state->rs.received_bytes == GRPC_HEADER_SIZE_IN_BYTES &&
+          stream_state->rs.remaining_bytes == 0) {
+        /* Start a read operation for data */
+        stream_state->rs.length_field_received = true;
+        stream_state->rs.length_field = stream_state->rs.remaining_bytes =
+            parse_grpc_header((const uint8_t *)stream_state->rs.read_buffer);
+        CRONET_LOG(GPR_DEBUG, "length field = %d",
+                   stream_state->rs.length_field);
+        if (stream_state->rs.length_field > 0) {
+          stream_state->rs.read_buffer =
+              gpr_malloc((size_t)stream_state->rs.length_field);
+          GPR_ASSERT(stream_state->rs.read_buffer);
+          stream_state->rs.remaining_bytes = stream_state->rs.length_field;
+          stream_state->rs.received_bytes = 0;
+          CRONET_LOG(GPR_DEBUG, "cronet_bidirectional_stream_read(%p)", s->cbs);
+          stream_state->state_op_done[OP_READ_REQ_MADE] =
+              true; /* Indicates that at least one read request has been made */
+          cronet_bidirectional_stream_read(s->cbs, stream_state->rs.read_buffer,
+                                           stream_state->rs.remaining_bytes);
+          result = ACTION_TAKEN_WITH_CALLBACK;
+        } else {
+          stream_state->rs.remaining_bytes = 0;
+          CRONET_LOG(GPR_DEBUG, "read operation complete. Empty response.");
+          gpr_slice_buffer_init(&stream_state->rs.read_slice_buffer);
+          grpc_slice_buffer_stream_init(&stream_state->rs.sbs,
+                                        &stream_state->rs.read_slice_buffer, 0);
+          *((grpc_byte_buffer **)stream_op->recv_message) =
+              (grpc_byte_buffer *)&stream_state->rs.sbs;
+          grpc_exec_ctx_sched(exec_ctx, stream_op->recv_message_ready,
+                              GRPC_ERROR_NONE, NULL);
+          stream_state->state_op_done[OP_RECV_MESSAGE] = true;
+          oas->state.state_op_done[OP_RECV_MESSAGE] = true;
+          result = ACTION_TAKEN_NO_CALLBACK;
+        }
+      } else if (stream_state->rs.remaining_bytes == 0) {
+        /* Start a read operation for first 5 bytes (GRPC header) */
+        stream_state->rs.read_buffer = stream_state->rs.grpc_header_bytes;
+        stream_state->rs.remaining_bytes = GRPC_HEADER_SIZE_IN_BYTES;
+        stream_state->rs.received_bytes = 0;
+        CRONET_LOG(GPR_DEBUG, "cronet_bidirectional_stream_read(%p)", s->cbs);
+        stream_state->state_op_done[OP_READ_REQ_MADE] =
+            true; /* Indicates that at least one read request has been made */
+        cronet_bidirectional_stream_read(s->cbs, stream_state->rs.read_buffer,
+                                         stream_state->rs.remaining_bytes);
+      }
+      result = ACTION_TAKEN_WITH_CALLBACK;
+    } else if (stream_state->rs.remaining_bytes == 0) {
+      CRONET_LOG(GPR_DEBUG, "read operation complete");
+      gpr_slice read_data_slice =
+          gpr_slice_malloc((uint32_t)stream_state->rs.length_field);
+      uint8_t *dst_p = GPR_SLICE_START_PTR(read_data_slice);
+      memcpy(dst_p, stream_state->rs.read_buffer,
+             (size_t)stream_state->rs.length_field);
+      gpr_slice_buffer_init(&stream_state->rs.read_slice_buffer);
+      gpr_slice_buffer_add(&stream_state->rs.read_slice_buffer,
+                           read_data_slice);
+      grpc_slice_buffer_stream_init(&stream_state->rs.sbs,
+                                    &stream_state->rs.read_slice_buffer, 0);
+      *((grpc_byte_buffer **)stream_op->recv_message) =
+          (grpc_byte_buffer *)&stream_state->rs.sbs;
+      grpc_exec_ctx_sched(exec_ctx, stream_op->recv_message_ready,
+                          GRPC_ERROR_NONE, NULL);
+      stream_state->state_op_done[OP_RECV_MESSAGE] = true;
+      oas->state.state_op_done[OP_RECV_MESSAGE] = true;
+      /* Clear read state of the stream, so next read op (if it were to come)
+       * will work */
+      stream_state->rs.received_bytes = stream_state->rs.remaining_bytes =
+          stream_state->rs.length_field_received = 0;
+      result = ACTION_TAKEN_NO_CALLBACK;
+    }
+  } else if (stream_op->recv_trailing_metadata &&
+             op_can_be_run(stream_op, stream_state, &oas->state,
+                           OP_RECV_TRAILING_METADATA)) {
+    CRONET_LOG(GPR_DEBUG, "running: %p  OP_RECV_TRAILING_METADATA", oas);
+    if (oas->s->state.rs.trailing_metadata_valid) {
+      grpc_chttp2_incoming_metadata_buffer_publish(
+          &oas->s->state.rs.trailing_metadata,
+          stream_op->recv_trailing_metadata);
+      stream_state->rs.trailing_metadata_valid = false;
+    }
+    stream_state->state_op_done[OP_RECV_TRAILING_METADATA] = true;
+    result = ACTION_TAKEN_NO_CALLBACK;
+  } else if (stream_op->send_trailing_metadata &&
+             op_can_be_run(stream_op, stream_state, &oas->state,
+                           OP_SEND_TRAILING_METADATA)) {
+    CRONET_LOG(GPR_DEBUG, "running: %p  OP_SEND_TRAILING_METADATA", oas);
+    CRONET_LOG(GPR_DEBUG, "cronet_bidirectional_stream_write (%p, 0)", s->cbs);
+    stream_state->state_callback_received[OP_SEND_MESSAGE] = false;
+    cronet_bidirectional_stream_write(s->cbs, "", 0, true);
+    stream_state->state_op_done[OP_SEND_TRAILING_METADATA] = true;
+    result = ACTION_TAKEN_WITH_CALLBACK;
+  } else if (stream_op->cancel_error &&
+             op_can_be_run(stream_op, stream_state, &oas->state,
+                           OP_CANCEL_ERROR)) {
+    CRONET_LOG(GPR_DEBUG, "running: %p  OP_CANCEL_ERROR", oas);
+    CRONET_LOG(GPR_DEBUG, "W: cronet_bidirectional_stream_cancel(%p)", s->cbs);
+    if (s->cbs) {
+      cronet_bidirectional_stream_cancel(s->cbs);
+    }
+    stream_state->state_op_done[OP_CANCEL_ERROR] = true;
+    result = ACTION_TAKEN_WITH_CALLBACK;
+  } else if (stream_op->on_complete &&
+             op_can_be_run(stream_op, stream_state, &oas->state,
+                           OP_ON_COMPLETE)) {
+    /* All actions in this stream_op are complete. Call the on_complete callback
+     */
+    CRONET_LOG(GPR_DEBUG, "running: %p  OP_ON_COMPLETE", oas);
+    grpc_exec_ctx_sched(exec_ctx, stream_op->on_complete, GRPC_ERROR_NONE,
+                        NULL);
+    oas->state.state_op_done[OP_ON_COMPLETE] = true;
+    oas->done = true;
+    /* reset any send message state, only if this ON_COMPLETE is about a send.
+     */
+    if (stream_op->send_message) {
+      stream_state->state_callback_received[OP_SEND_MESSAGE] = false;
+      stream_state->state_op_done[OP_SEND_MESSAGE] = false;
+    }
+    result = ACTION_TAKEN_NO_CALLBACK;
+    /* If this is the on_complete callback being called for a received message -
+      make a note */
+    if (stream_op->recv_message)
+      stream_state->state_op_done[OP_RECV_MESSAGE_AND_ON_COMPLETE] = true;
+  } else {
+    result = NO_ACTION_POSSIBLE;
   }
+  return result;
 }
 
+/*
+  Functions used by upper layers to access transport functionality.
+*/
+
 static int init_stream(grpc_exec_ctx *exec_ctx, grpc_transport *gt,
                        grpc_stream *gs, grpc_stream_refcount *refcount,
                        const void *server_data) {
   stream_obj *s = (stream_obj *)gs;
-  memset(s->callback_list, 0, sizeof(s->callback_list));
+  memset(&s->storage, 0, sizeof(s->storage));
+  s->storage.head = NULL;
+  memset(&s->state, 0, sizeof(s->state));
+  s->curr_op = NULL;
   s->cbs = NULL;
-  gpr_mu_init(&s->recv_mu);
-  s->read_buffer = gpr_malloc(GRPC_HEADER_SIZE_IN_BYTES);
-  s->write_buffer = gpr_malloc(GRPC_HEADER_SIZE_IN_BYTES);
-  gpr_slice_buffer_init(&s->write_slice_buffer);
-  if (grpc_cronet_trace) {
-    gpr_log(GPR_DEBUG, "cronet_transport - init_stream");
-  }
+  memset(&s->header_array, 0, sizeof(s->header_array));
+  memset(&s->state.rs, 0, sizeof(s->state.rs));
+  memset(&s->state.ws, 0, sizeof(s->state.ws));
+  memset(s->state.state_op_done, 0, sizeof(s->state.state_op_done));
+  memset(s->state.state_callback_received, 0,
+         sizeof(s->state.state_callback_received));
+  gpr_mu_init(&s->mu);
   return 0;
 }
 
-static void destroy_stream(grpc_exec_ctx *exec_ctx, grpc_transport *gt,
-                           grpc_stream *gs, void *and_free_memory) {
-  if (grpc_cronet_trace) {
-    gpr_log(GPR_DEBUG, "Destroy stream");
-  }
+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 perform_stream_op(grpc_exec_ctx *exec_ctx, grpc_transport *gt,
+                              grpc_stream *gs, grpc_transport_stream_op *op) {
+  CRONET_LOG(GPR_DEBUG, "perform_stream_op");
   stream_obj *s = (stream_obj *)gs;
-  s->cbs = NULL;
-  gpr_free(s->read_buffer);
-  gpr_free(s->write_buffer);
-  gpr_free(s->url);
-  gpr_mu_destroy(&s->recv_mu);
-  if (and_free_memory) {
-    gpr_free(and_free_memory);
-  }
+  s->curr_gs = gs;
+  memcpy(&s->curr_ct, gt, sizeof(grpc_cronet_transport));
+  add_to_storage(s, op);
+  execute_from_storage(s);
 }
 
-static void destroy_transport(grpc_exec_ctx *exec_ctx, grpc_transport *gt) {
-  grpc_cronet_transport *ct = (grpc_cronet_transport *)gt;
-  gpr_free(ct->host);
-  if (grpc_cronet_trace) {
-    gpr_log(GPR_DEBUG, "Destroy transport");
-  }
+static void destroy_stream(grpc_exec_ctx *exec_ctx, grpc_transport *gt,
+                           grpc_stream *gs, void *and_free_memory) {}
+
+static void destroy_transport(grpc_exec_ctx *exec_ctx, grpc_transport *gt) {}
+
+static char *get_peer(grpc_exec_ctx *exec_ctx, grpc_transport *gt) {
+  return NULL;
 }
 
+static void perform_op(grpc_exec_ctx *exec_ctx, grpc_transport *gt,
+                       grpc_transport_op *op) {}
+
 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,
+                                                  perform_op,
                                                   destroy_stream,
                                                   destroy_transport,
-                                                  NULL};
+                                                  get_peer};
diff --git a/src/core/lib/iomgr/tcp_server_posix.c b/src/core/lib/iomgr/tcp_server_posix.c
index ea8d241..2d3f6cf 100644
--- a/src/core/lib/iomgr/tcp_server_posix.c
+++ b/src/core/lib/iomgr/tcp_server_posix.c
@@ -140,15 +140,17 @@
 };
 
 static gpr_once check_init = GPR_ONCE_INIT;
-static bool has_so_reuseport;
+static bool has_so_reuseport = false;
 
 static void init(void) {
+#ifndef GPR_MANYLINUX1
   int s = socket(AF_INET, SOCK_STREAM, 0);
   if (s >= 0) {
     has_so_reuseport = GRPC_LOG_IF_ERROR("check for SO_REUSEPORT",
                                          grpc_set_socket_reuse_port(s, 1));
     close(s);
   }
+#endif
 }
 
 grpc_error *grpc_tcp_server_create(grpc_closure *shutdown_complete,
diff --git a/src/cpp/common/channel_filter.h b/src/cpp/common/channel_filter.h
index 3fbacd8..ec2af63 100644
--- a/src/cpp/common/channel_filter.h
+++ b/src/cpp/common/channel_filter.h
@@ -35,7 +35,6 @@
 #define GRPCXX_CHANNEL_FILTER_H
 
 #include <grpc++/impl/codegen/config.h>
-#include <grpc/census.h>
 #include <grpc/grpc.h>
 #include <grpc/impl/codegen/alloc.h>
 
@@ -43,7 +42,6 @@
 #include <vector>
 
 #include "src/core/lib/channel/channel_stack.h"
-#include "src/core/lib/security/context/security_context.h"
 #include "src/core/lib/surface/channel_init.h"
 #include "src/core/lib/transport/metadata_batch.h"
 
@@ -56,6 +54,11 @@
 ///       "name-of-filter", GRPC_SERVER_CHANNEL, INT_MAX, nullptr);
 /// \endcode
 
+/// Forward declaration to avoid including the file
+/// "src/core/lib/security/context/security_context.h"
+struct grpc_client_security_context;
+struct grpc_server_security_context;
+
 namespace grpc {
 
 /// A C++ wrapper for the \c grpc_metadata_batch struct.
diff --git a/src/cpp/util/byte_buffer.cc b/src/cpp/util/byte_buffer.cc
index c2cd20e..91ed66b 100644
--- a/src/cpp/util/byte_buffer.cc
+++ b/src/cpp/util/byte_buffer.cc
@@ -37,12 +37,19 @@
 namespace grpc {
 
 ByteBuffer::ByteBuffer(const Slice* slices, size_t nslices) {
-  // TODO(yangg) maybe expose some core API to simplify this
-  std::vector<gpr_slice> c_slices(nslices);
-  for (size_t i = 0; i < nslices; i++) {
-    c_slices[i] = slices[i].slice_;
-  }
-  buffer_ = grpc_raw_byte_buffer_create(c_slices.data(), nslices);
+  // The following assertions check that the representation of a grpc::Slice is
+  // identical to that of a gpr_slice:  it has a gpr_slice field, and nothing
+  // else.
+  static_assert(std::is_same<decltype(slices[0].slice_), gpr_slice>::value,
+                "Slice must have same representation as gpr_slice");
+  static_assert(sizeof(Slice) == sizeof(gpr_slice),
+                "Slice must have same representation as gpr_slice");
+  // The const_cast is legal if grpc_raw_byte_buffer_create() does no more
+  // than its advertised side effect of increasing the reference count of the
+  // slices it processes, and such an increase does not affect the semantics
+  // seen by the caller of this constructor.
+  buffer_ = grpc_raw_byte_buffer_create(
+      reinterpret_cast<gpr_slice*>(const_cast<Slice*>(slices)), nslices);
 }
 
 ByteBuffer::~ByteBuffer() {
@@ -95,4 +102,10 @@
   return *this;
 }
 
+void ByteBuffer::Swap(ByteBuffer* other) {
+  grpc_byte_buffer* tmp = other->buffer_;
+  other->buffer_ = buffer_;
+  buffer_ = tmp;
+}
+
 }  // namespace grpc
diff --git a/src/csharp/Grpc.Auth/Grpc.Auth.csproj b/src/csharp/Grpc.Auth/Grpc.Auth.csproj
index 1fa14fc..7a69553 100644
--- a/src/csharp/Grpc.Auth/Grpc.Auth.csproj
+++ b/src/csharp/Grpc.Auth/Grpc.Auth.csproj
@@ -39,30 +39,25 @@
     <AssemblyOriginatorKeyFile>..\keys\Grpc.snk</AssemblyOriginatorKeyFile>
   </PropertyGroup>
   <ItemGroup>
-    <Reference Include="BouncyCastle.Crypto, Version=1.7.4137.9688, Culture=neutral, PublicKeyToken=a4292a325f69b123, processorArchitecture=MSIL">
-      <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\BouncyCastle.1.7.0\lib\Net40-Client\BouncyCastle.Crypto.dll</HintPath>
-    </Reference>
-    <Reference Include="Google.Apis.Auth, Version=1.11.1.0, Culture=neutral, PublicKeyToken=4b01fa6e34db77ab, processorArchitecture=MSIL">
-      <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\Google.Apis.Auth.1.11.1\lib\net45\Google.Apis.Auth.dll</HintPath>
-    </Reference>
-    <Reference Include="Google.Apis.Auth.PlatformServices, Version=1.11.1.0, Culture=neutral, PublicKeyToken=4b01fa6e34db77ab, processorArchitecture=MSIL">
-      <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\Google.Apis.Auth.1.11.1\lib\net45\Google.Apis.Auth.PlatformServices.dll</HintPath>
-    </Reference>
-    <Reference Include="Google.Apis.Core, Version=1.11.1.0, Culture=neutral, PublicKeyToken=4b01fa6e34db77ab, processorArchitecture=MSIL">
-      <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\Google.Apis.Core.1.11.1\lib\net45\Google.Apis.Core.dll</HintPath>
-    </Reference>
-    <Reference Include="Newtonsoft.Json, Version=7.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
-      <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
-    </Reference>
     <Reference Include="System" />
     <Reference Include="System.Net" />
     <Reference Include="System.Net.Http" />
     <Reference Include="System.Net.Http.WebRequest" />
+    <Reference Include="BouncyCastle.Crypto">
+      <HintPath>..\packages\BouncyCastle.1.7.0\lib\Net40-Client\BouncyCastle.Crypto.dll</HintPath>
+    </Reference>
+    <Reference Include="Newtonsoft.Json">
+      <HintPath>..\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
+    </Reference>
+    <Reference Include="Google.Apis.Core">
+      <HintPath>..\packages\Google.Apis.Core.1.15.0\lib\net45\Google.Apis.Core.dll</HintPath>
+    </Reference>
+    <Reference Include="Google.Apis.Auth">
+      <HintPath>..\packages\Google.Apis.Auth.1.15.0\lib\net45\Google.Apis.Auth.dll</HintPath>
+    </Reference>
+    <Reference Include="Google.Apis.Auth.PlatformServices">
+      <HintPath>..\packages\Google.Apis.Auth.1.15.0\lib\net45\Google.Apis.Auth.PlatformServices.dll</HintPath>
+    </Reference>
   </ItemGroup>
   <ItemGroup>
     <Compile Include="..\Grpc.Core\Version.cs">
diff --git a/src/csharp/Grpc.Auth/Grpc.Auth.nuspec b/src/csharp/Grpc.Auth/Grpc.Auth.nuspec
index 4baed37..a1f5668 100644
--- a/src/csharp/Grpc.Auth/Grpc.Auth.nuspec
+++ b/src/csharp/Grpc.Auth/Grpc.Auth.nuspec
@@ -15,7 +15,7 @@
     <copyright>Copyright 2015, Google Inc.</copyright>
     <tags>gRPC RPC Protocol HTTP/2 Auth OAuth2</tags>
 	<dependencies>
-	  <dependency id="Google.Apis.Auth" version="1.11.1" />
+	  <dependency id="Google.Apis.Auth" version="1.15.0" />
 	  <dependency id="Grpc.Core" version="$version$" />
     </dependencies>
   </metadata>
diff --git a/src/csharp/Grpc.Auth/packages.config b/src/csharp/Grpc.Auth/packages.config
index c20d9ce..738d3e6 100644
--- a/src/csharp/Grpc.Auth/packages.config
+++ b/src/csharp/Grpc.Auth/packages.config
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <packages>
   <package id="BouncyCastle" version="1.7.0" targetFramework="net45" />
-  <package id="Google.Apis.Auth" version="1.11.1" targetFramework="net45" />
-  <package id="Google.Apis.Core" version="1.11.1" targetFramework="net45" />
+  <package id="Google.Apis.Auth" version="1.15.0" targetFramework="net45" />
+  <package id="Google.Apis.Core" version="1.15.0" targetFramework="net45" />
   <package id="Newtonsoft.Json" version="7.0.1" targetFramework="net45" />
 </packages>
\ No newline at end of file
diff --git a/src/csharp/Grpc.Auth/project.json b/src/csharp/Grpc.Auth/project.json
index 6215ca3..30f0944 100644
--- a/src/csharp/Grpc.Auth/project.json
+++ b/src/csharp/Grpc.Auth/project.json
@@ -23,13 +23,13 @@
   },
   "dependencies": {
     "Grpc.Core": "1.1.0-dev",
-    "Google.Apis.Auth": "1.11.1"
+    "Google.Apis.Auth": "1.15.0"
   },
   "frameworks": {
     "net45": { },
     "netstandard1.5": {
       "imports": [
-        "net45"
+        "portable-net45"
       ],
       "dependencies": {
         "Microsoft.NETCore.Portable.Compatibility": "1.0.1",
diff --git a/src/csharp/Grpc.Core.Tests/SanityTest.cs b/src/csharp/Grpc.Core.Tests/SanityTest.cs
index df887d8..f1eb13d 100644
--- a/src/csharp/Grpc.Core.Tests/SanityTest.cs
+++ b/src/csharp/Grpc.Core.Tests/SanityTest.cs
@@ -58,9 +58,9 @@
         [Test]
         public void TestsJsonUpToDate()
         {
-            Dictionary<string, List<string>> discoveredTests = DiscoverAllTestClasses();
-			Dictionary<string, List<string>> testsFromFile 
-			    = JsonConvert.DeserializeObject<Dictionary<string, List<string>>>(ReadTestsJson());
+            var discoveredTests = DiscoverAllTestClasses();
+            var testsFromFile 
+                = JsonConvert.DeserializeObject<Dictionary<string, List<string>>>(ReadTestsJson());
 
             Assert.AreEqual(discoveredTests, testsFromFile);
         }
diff --git a/src/csharp/Grpc.Examples.MathClient/project.json b/src/csharp/Grpc.Examples.MathClient/project.json
index 764a335..ad31947 100644
--- a/src/csharp/Grpc.Examples.MathClient/project.json
+++ b/src/csharp/Grpc.Examples.MathClient/project.json
@@ -42,6 +42,11 @@
       }
     }
   },
+  "runtimes": {
+    "win7-x64": { },
+    "debian.8-x64": { },
+    "osx.10.11-x64": { }
+  },
 
   "dependencies": {
     "Grpc.Examples": {
diff --git a/src/csharp/Grpc.Examples.MathServer/project.json b/src/csharp/Grpc.Examples.MathServer/project.json
index 764a335..ad31947 100644
--- a/src/csharp/Grpc.Examples.MathServer/project.json
+++ b/src/csharp/Grpc.Examples.MathServer/project.json
@@ -42,6 +42,11 @@
       }
     }
   },
+  "runtimes": {
+    "win7-x64": { },
+    "debian.8-x64": { },
+    "osx.10.11-x64": { }
+  },
 
   "dependencies": {
     "Grpc.Examples": {
diff --git a/src/csharp/Grpc.Examples/project.json b/src/csharp/Grpc.Examples/project.json
index 5329f39..98bd5d8 100644
--- a/src/csharp/Grpc.Examples/project.json
+++ b/src/csharp/Grpc.Examples/project.json
@@ -20,11 +20,12 @@
         "System.IO": ""
       }
     },
-    "netstandard1.5": {
+    "netcoreapp1.0": {
       "imports": [
         "portable-net45"
       ],
       "dependencies": {
+        "Microsoft.NETCore.App": "1.0.0",
         "NETStandard.Library": "1.6.0"
       }
     }
diff --git a/src/csharp/Grpc.IntegrationTesting.Client/Grpc.IntegrationTesting.Client.csproj b/src/csharp/Grpc.IntegrationTesting.Client/Grpc.IntegrationTesting.Client.csproj
index 91fb3ce..6816b5c 100644
--- a/src/csharp/Grpc.IntegrationTesting.Client/Grpc.IntegrationTesting.Client.csproj
+++ b/src/csharp/Grpc.IntegrationTesting.Client/Grpc.IntegrationTesting.Client.csproj
@@ -39,30 +39,25 @@
     <AssemblyOriginatorKeyFile>..\keys\Grpc.snk</AssemblyOriginatorKeyFile>
   </PropertyGroup>
   <ItemGroup>
-    <Reference Include="BouncyCastle.Crypto, Version=1.7.4137.9688, Culture=neutral, PublicKeyToken=a4292a325f69b123, processorArchitecture=MSIL">
-      <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\BouncyCastle.1.7.0\lib\Net40-Client\BouncyCastle.Crypto.dll</HintPath>
-    </Reference>
-    <Reference Include="Google.Apis.Auth, Version=1.11.1.0, Culture=neutral, PublicKeyToken=4b01fa6e34db77ab, processorArchitecture=MSIL">
-      <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\Google.Apis.Auth.1.11.1\lib\net45\Google.Apis.Auth.dll</HintPath>
-    </Reference>
-    <Reference Include="Google.Apis.Auth.PlatformServices, Version=1.11.1.0, Culture=neutral, PublicKeyToken=4b01fa6e34db77ab, processorArchitecture=MSIL">
-      <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\Google.Apis.Auth.1.11.1\lib\net45\Google.Apis.Auth.PlatformServices.dll</HintPath>
-    </Reference>
-    <Reference Include="Google.Apis.Core, Version=1.11.1.0, Culture=neutral, PublicKeyToken=4b01fa6e34db77ab, processorArchitecture=MSIL">
-      <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\Google.Apis.Core.1.11.1\lib\net45\Google.Apis.Core.dll</HintPath>
-    </Reference>
-    <Reference Include="Newtonsoft.Json, Version=7.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
-      <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
-    </Reference>
     <Reference Include="System" />
     <Reference Include="System.Net" />
     <Reference Include="System.Net.Http" />
     <Reference Include="System.Net.Http.WebRequest" />
+    <Reference Include="BouncyCastle.Crypto">
+      <HintPath>..\packages\BouncyCastle.1.7.0\lib\Net40-Client\BouncyCastle.Crypto.dll</HintPath>
+    </Reference>
+    <Reference Include="Newtonsoft.Json">
+      <HintPath>..\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
+    </Reference>
+    <Reference Include="Google.Apis.Core">
+      <HintPath>..\packages\Google.Apis.Core.1.15.0\lib\net45\Google.Apis.Core.dll</HintPath>
+    </Reference>
+    <Reference Include="Google.Apis.Auth">
+      <HintPath>..\packages\Google.Apis.Auth.1.15.0\lib\net45\Google.Apis.Auth.dll</HintPath>
+    </Reference>
+    <Reference Include="Google.Apis.Auth.PlatformServices">
+      <HintPath>..\packages\Google.Apis.Auth.1.15.0\lib\net45\Google.Apis.Auth.PlatformServices.dll</HintPath>
+    </Reference>
   </ItemGroup>
   <ItemGroup>
     <Compile Include="..\Grpc.Core\Version.cs">
diff --git a/src/csharp/Grpc.IntegrationTesting.Client/packages.config b/src/csharp/Grpc.IntegrationTesting.Client/packages.config
index c20d9ce..738d3e6 100644
--- a/src/csharp/Grpc.IntegrationTesting.Client/packages.config
+++ b/src/csharp/Grpc.IntegrationTesting.Client/packages.config
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <packages>
   <package id="BouncyCastle" version="1.7.0" targetFramework="net45" />
-  <package id="Google.Apis.Auth" version="1.11.1" targetFramework="net45" />
-  <package id="Google.Apis.Core" version="1.11.1" targetFramework="net45" />
+  <package id="Google.Apis.Auth" version="1.15.0" targetFramework="net45" />
+  <package id="Google.Apis.Core" version="1.15.0" targetFramework="net45" />
   <package id="Newtonsoft.Json" version="7.0.1" targetFramework="net45" />
 </packages>
\ No newline at end of file
diff --git a/src/csharp/Grpc.IntegrationTesting.QpsWorker/Grpc.IntegrationTesting.QpsWorker.csproj b/src/csharp/Grpc.IntegrationTesting.QpsWorker/Grpc.IntegrationTesting.QpsWorker.csproj
index dda26a6..593bf09 100644
--- a/src/csharp/Grpc.IntegrationTesting.QpsWorker/Grpc.IntegrationTesting.QpsWorker.csproj
+++ b/src/csharp/Grpc.IntegrationTesting.QpsWorker/Grpc.IntegrationTesting.QpsWorker.csproj
@@ -58,7 +58,6 @@
     </ProjectReference>
   </ItemGroup>
   <ItemGroup>
-    <None Include="app.config" />
     <None Include="Grpc.IntegrationTesting.QpsWorker.project.json" />
   </ItemGroup>
 </Project>
\ No newline at end of file
diff --git a/src/csharp/Grpc.IntegrationTesting.QpsWorker/app.config b/src/csharp/Grpc.IntegrationTesting.QpsWorker/app.config
deleted file mode 100644
index e204447..0000000
--- a/src/csharp/Grpc.IntegrationTesting.QpsWorker/app.config
+++ /dev/null
@@ -1,15 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<configuration>
-  <runtime>
-    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
-      <dependentAssembly>
-        <assemblyIdentity name="System.Net.Http.Primitives" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
-        <bindingRedirect oldVersion="0.0.0.0-4.2.29.0" newVersion="4.2.29.0" />
-      </dependentAssembly>
-      <dependentAssembly>
-        <assemblyIdentity name="Google.Apis.Core" publicKeyToken="4b01fa6e34db77ab" culture="neutral" />
-        <bindingRedirect oldVersion="0.0.0.0-1.11.1.0" newVersion="1.11.1.0" />
-      </dependentAssembly>
-    </assemblyBinding>
-  </runtime>
-</configuration>
\ No newline at end of file
diff --git a/src/csharp/Grpc.IntegrationTesting.QpsWorker/project.json b/src/csharp/Grpc.IntegrationTesting.QpsWorker/project.json
index 9afcb30..2879507 100644
--- a/src/csharp/Grpc.IntegrationTesting.QpsWorker/project.json
+++ b/src/csharp/Grpc.IntegrationTesting.QpsWorker/project.json
@@ -44,6 +44,11 @@
       }
     }
   },
+  "runtimes": {
+    "win7-x64": { },
+    "debian.8-x64": { },
+    "osx.10.11-x64": { }
+  },
 
   "dependencies": {
     "Grpc.IntegrationTesting": {
diff --git a/src/csharp/Grpc.IntegrationTesting.Server/Grpc.IntegrationTesting.Server.csproj b/src/csharp/Grpc.IntegrationTesting.Server/Grpc.IntegrationTesting.Server.csproj
index f73d99d..987387c 100644
--- a/src/csharp/Grpc.IntegrationTesting.Server/Grpc.IntegrationTesting.Server.csproj
+++ b/src/csharp/Grpc.IntegrationTesting.Server/Grpc.IntegrationTesting.Server.csproj
@@ -39,30 +39,25 @@
     <AssemblyOriginatorKeyFile>..\keys\Grpc.snk</AssemblyOriginatorKeyFile>
   </PropertyGroup>
   <ItemGroup>
-    <Reference Include="BouncyCastle.Crypto, Version=1.7.4137.9688, Culture=neutral, PublicKeyToken=a4292a325f69b123, processorArchitecture=MSIL">
-      <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\BouncyCastle.1.7.0\lib\Net40-Client\BouncyCastle.Crypto.dll</HintPath>
-    </Reference>
-    <Reference Include="Google.Apis.Auth, Version=1.11.1.0, Culture=neutral, PublicKeyToken=4b01fa6e34db77ab, processorArchitecture=MSIL">
-      <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\Google.Apis.Auth.1.11.1\lib\net45\Google.Apis.Auth.dll</HintPath>
-    </Reference>
-    <Reference Include="Google.Apis.Auth.PlatformServices, Version=1.11.1.0, Culture=neutral, PublicKeyToken=4b01fa6e34db77ab, processorArchitecture=MSIL">
-      <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\Google.Apis.Auth.1.11.1\lib\net45\Google.Apis.Auth.PlatformServices.dll</HintPath>
-    </Reference>
-    <Reference Include="Google.Apis.Core, Version=1.11.1.0, Culture=neutral, PublicKeyToken=4b01fa6e34db77ab, processorArchitecture=MSIL">
-      <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\Google.Apis.Core.1.11.1\lib\net45\Google.Apis.Core.dll</HintPath>
-    </Reference>
-    <Reference Include="Newtonsoft.Json, Version=7.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
-      <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
-    </Reference>
     <Reference Include="System" />
     <Reference Include="System.Net" />
     <Reference Include="System.Net.Http" />
     <Reference Include="System.Net.Http.WebRequest" />
+    <Reference Include="BouncyCastle.Crypto">
+      <HintPath>..\packages\BouncyCastle.1.7.0\lib\Net40-Client\BouncyCastle.Crypto.dll</HintPath>
+    </Reference>
+    <Reference Include="Newtonsoft.Json">
+      <HintPath>..\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
+    </Reference>
+    <Reference Include="Google.Apis.Core">
+      <HintPath>..\packages\Google.Apis.Core.1.15.0\lib\net45\Google.Apis.Core.dll</HintPath>
+    </Reference>
+    <Reference Include="Google.Apis.Auth">
+      <HintPath>..\packages\Google.Apis.Auth.1.15.0\lib\net45\Google.Apis.Auth.dll</HintPath>
+    </Reference>
+    <Reference Include="Google.Apis.Auth.PlatformServices">
+      <HintPath>..\packages\Google.Apis.Auth.1.15.0\lib\net45\Google.Apis.Auth.PlatformServices.dll</HintPath>
+    </Reference>
   </ItemGroup>
   <ItemGroup>
     <Compile Include="..\Grpc.Core\Version.cs">
diff --git a/src/csharp/Grpc.IntegrationTesting.Server/packages.config b/src/csharp/Grpc.IntegrationTesting.Server/packages.config
index c20d9ce..738d3e6 100644
--- a/src/csharp/Grpc.IntegrationTesting.Server/packages.config
+++ b/src/csharp/Grpc.IntegrationTesting.Server/packages.config
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <packages>
   <package id="BouncyCastle" version="1.7.0" targetFramework="net45" />
-  <package id="Google.Apis.Auth" version="1.11.1" targetFramework="net45" />
-  <package id="Google.Apis.Core" version="1.11.1" targetFramework="net45" />
+  <package id="Google.Apis.Auth" version="1.15.0" targetFramework="net45" />
+  <package id="Google.Apis.Core" version="1.15.0" targetFramework="net45" />
   <package id="Newtonsoft.Json" version="7.0.1" targetFramework="net45" />
 </packages>
\ No newline at end of file
diff --git a/src/csharp/Grpc.IntegrationTesting.StressClient/project.json b/src/csharp/Grpc.IntegrationTesting.StressClient/project.json
index 9afcb30..2879507 100644
--- a/src/csharp/Grpc.IntegrationTesting.StressClient/project.json
+++ b/src/csharp/Grpc.IntegrationTesting.StressClient/project.json
@@ -44,6 +44,11 @@
       }
     }
   },
+  "runtimes": {
+    "win7-x64": { },
+    "debian.8-x64": { },
+    "osx.10.11-x64": { }
+  },
 
   "dependencies": {
     "Grpc.IntegrationTesting": {
diff --git a/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj b/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj
index 7512d2a..e030b21 100644
--- a/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj
+++ b/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj
@@ -38,9 +38,6 @@
     <AssemblyOriginatorKeyFile>..\keys\Grpc.snk</AssemblyOriginatorKeyFile>
   </PropertyGroup>
   <ItemGroup>
-    <Reference Include="CommandLine">
-      <HintPath>..\packages\CommandLineParser.1.9.71\lib\net45\CommandLine.dll</HintPath>
-    </Reference>
     <Reference Include="Moq">
       <HintPath>..\packages\Moq.4.2.1510.2205\lib\net40\Moq.dll</HintPath>
     </Reference>
@@ -51,15 +48,6 @@
     <Reference Include="BouncyCastle.Crypto">
       <HintPath>..\packages\BouncyCastle.1.7.0\lib\Net40-Client\BouncyCastle.Crypto.dll</HintPath>
     </Reference>
-    <Reference Include="Google.Apis.Auth">
-      <HintPath>..\packages\Google.Apis.Auth.1.11.1\lib\net45\Google.Apis.Auth.dll</HintPath>
-    </Reference>
-    <Reference Include="Google.Apis.Auth.PlatformServices">
-      <HintPath>..\packages\Google.Apis.Auth.1.11.1\lib\net45\Google.Apis.Auth.PlatformServices.dll</HintPath>
-    </Reference>
-    <Reference Include="Google.Apis.Core">
-      <HintPath>..\packages\Google.Apis.Core.1.11.1\lib\net45\Google.Apis.Core.dll</HintPath>
-    </Reference>
     <Reference Include="Google.Protobuf">
       <HintPath>..\packages\Google.Protobuf.3.0.0-beta3\lib\portable-net45+netcore45+wpa81+wp8\Google.Protobuf.dll</HintPath>
     </Reference>
@@ -75,6 +63,18 @@
     <Reference Include="nunitlite">
       <HintPath>..\packages\NUnitLite.3.2.0\lib\net45\nunitlite.dll</HintPath>
     </Reference>
+    <Reference Include="Google.Apis.Core">
+      <HintPath>..\packages\Google.Apis.Core.1.15.0\lib\net45\Google.Apis.Core.dll</HintPath>
+    </Reference>
+    <Reference Include="Google.Apis.Auth">
+      <HintPath>..\packages\Google.Apis.Auth.1.15.0\lib\net45\Google.Apis.Auth.dll</HintPath>
+    </Reference>
+    <Reference Include="Google.Apis.Auth.PlatformServices">
+      <HintPath>..\packages\Google.Apis.Auth.1.15.0\lib\net45\Google.Apis.Auth.PlatformServices.dll</HintPath>
+    </Reference>
+    <Reference Include="CommandLineParser.Unofficial">
+      <HintPath>..\packages\CommandLineParser.Unofficial.2.0.275\lib\net45\CommandLineParser.Unofficial.dll</HintPath>
+    </Reference>
   </ItemGroup>
   <ItemGroup>
     <Compile Include="..\Grpc.Core\Version.cs">
diff --git a/src/csharp/Grpc.IntegrationTesting/InteropClient.cs b/src/csharp/Grpc.IntegrationTesting/InteropClient.cs
index ec407d3..79fd18b 100644
--- a/src/csharp/Grpc.IntegrationTesting/InteropClient.cs
+++ b/src/csharp/Grpc.IntegrationTesting/InteropClient.cs
@@ -56,24 +56,24 @@
     {
         private class ClientOptions
         {
-            [Option("server_host", DefaultValue = "127.0.0.1")]
+            [Option("server_host", Default = "127.0.0.1")]
             public string ServerHost { get; set; }
 
-            [Option("server_host_override", DefaultValue = TestCredentials.DefaultHostOverride)]
+            [Option("server_host_override", Default = TestCredentials.DefaultHostOverride)]
             public string ServerHostOverride { get; set; }
 
             [Option("server_port", Required = true)]
             public int ServerPort { get; set; }
 
-            [Option("test_case", DefaultValue = "large_unary")]
+            [Option("test_case", Default = "large_unary")]
             public string TestCase { get; set; }
 
             // Deliberately using nullable bool type to allow --use_tls=true syntax (as opposed to --use_tls)
-            [Option("use_tls", DefaultValue = false)]
+            [Option("use_tls", Default = false)]
             public bool? UseTls { get; set; }
 
             // Deliberately using nullable bool type to allow --use_test_ca=true syntax (as opposed to --use_test_ca)
-            [Option("use_test_ca", DefaultValue = false)]
+            [Option("use_test_ca", Default = false)]
             public bool? UseTestCa { get; set; }
 
             [Option("default_service_account", Required = false)]
@@ -84,19 +84,6 @@
 
             [Option("service_account_key_file", Required = false)]
             public string ServiceAccountKeyFile { get; set; }
-
-            [HelpOption]
-            public string GetUsage()
-            {
-                var help = new HelpText
-                {
-                    Heading = "gRPC C# interop testing client",
-                    AddDashesToOption = true
-                };
-                help.AddPreOptionsLine("Usage:");
-                help.AddOptions(this);
-                return help;
-            }
         }
 
         ClientOptions options;
@@ -108,14 +95,13 @@
 
         public static void Run(string[] args)
         {
-            var options = new ClientOptions();
-            if (!Parser.Default.ParseArguments(args, options))
-            {
-                Environment.Exit(1);
-            }
-
-            var interopClient = new InteropClient(options);
-            interopClient.Run().Wait();
+            var parserResult = Parser.Default.ParseArguments<ClientOptions>(args)
+                .WithNotParsed(errors => Environment.Exit(1))
+                .WithParsed(options =>
+                {
+                    var interopClient = new InteropClient(options);
+                    interopClient.Run().Wait();
+                });
         }
 
         private async Task Run()
@@ -145,26 +131,16 @@
 
             if (options.TestCase == "jwt_token_creds")
             {
-#if !NETCOREAPP1_0
                 var googleCredential = await GoogleCredential.GetApplicationDefaultAsync();
                 Assert.IsTrue(googleCredential.IsCreateScopedRequired);
                 credentials = ChannelCredentials.Create(credentials, googleCredential.ToCallCredentials());
-#else
-                // TODO(jtattermusch): implement this
-                throw new NotImplementedException("Not supported on CoreCLR yet");
-#endif
             }
 
             if (options.TestCase == "compute_engine_creds")
             {
-#if !NETCOREAPP1_0
                 var googleCredential = await GoogleCredential.GetApplicationDefaultAsync();
                 Assert.IsFalse(googleCredential.IsCreateScopedRequired);
                 credentials = ChannelCredentials.Create(credentials, googleCredential.ToCallCredentials());
-#else
-                // TODO(jtattermusch): implement this
-                throw new NotImplementedException("Not supported on CoreCLR yet");
-#endif
             }
             return credentials;
         }
@@ -395,7 +371,6 @@
 
         public static async Task RunOAuth2AuthTokenAsync(TestService.TestServiceClient client, string oauthScope)
         {
-#if !NETCOREAPP1_0
             Console.WriteLine("running oauth2_auth_token");
             ITokenAccess credential = (await GoogleCredential.GetApplicationDefaultAsync()).CreateScoped(new[] { oauthScope });
             string oauth2Token = await credential.GetAccessTokenForRequestAsync();
@@ -413,15 +388,10 @@
             Assert.True(oauthScope.Contains(response.OauthScope));
             Assert.AreEqual(GetEmailFromServiceAccountFile(), response.Username);
             Console.WriteLine("Passed!");
-#else
-            // TODO(jtattermusch): implement this
-            throw new NotImplementedException("Not supported on CoreCLR yet");
-#endif
         }
 
         public static async Task RunPerRpcCredsAsync(TestService.TestServiceClient client, string oauthScope)
         {
-#if !NETCOREAPP1_0
             Console.WriteLine("running per_rpc_creds");
             ITokenAccess googleCredential = await GoogleCredential.GetApplicationDefaultAsync();
 
@@ -435,10 +405,6 @@
 
             Assert.AreEqual(GetEmailFromServiceAccountFile(), response.Username);
             Console.WriteLine("Passed!");
-#else
-            // TODO(jtattermusch): implement this
-            throw new NotImplementedException("Not supported on CoreCLR yet");
-#endif
         }
 
         public static async Task RunCancelAfterBeginAsync(TestService.TestServiceClient client)
@@ -731,17 +697,12 @@
         // extracts the client_email field from service account file used for auth test cases
         private static string GetEmailFromServiceAccountFile()
         {
-#if !NETCOREAPP1_0
             string keyFile = Environment.GetEnvironmentVariable("GOOGLE_APPLICATION_CREDENTIALS");
             Assert.IsNotNull(keyFile);
             var jobject = JObject.Parse(File.ReadAllText(keyFile));
             string email = jobject.GetValue("client_email").Value<string>();
             Assert.IsTrue(email.Length > 0);  // spec requires nonempty client email.
             return email;
-#else
-            // TODO(jtattermusch): implement this
-            throw new NotImplementedException("Not supported on CoreCLR yet");
-#endif
         }
 
         private static Metadata CreateTestMetadata()
diff --git a/src/csharp/Grpc.IntegrationTesting/InteropServer.cs b/src/csharp/Grpc.IntegrationTesting/InteropServer.cs
index cd47e31..4118f99 100644
--- a/src/csharp/Grpc.IntegrationTesting/InteropServer.cs
+++ b/src/csharp/Grpc.IntegrationTesting/InteropServer.cs
@@ -51,25 +51,12 @@
     {
         private class ServerOptions
         {
-            [Option("port", DefaultValue = 8070)]
+            [Option("port", Default = 8070)]
             public int Port { get; set; }
 
             // Deliberately using nullable bool type to allow --use_tls=true syntax (as opposed to --use_tls)
-            [Option("use_tls", DefaultValue = false)]
+            [Option("use_tls", Default = false)]
             public bool? UseTls { get; set; }
-
-            [HelpOption]
-            public string GetUsage()
-            {
-                var help = new HelpText
-                {
-                    Heading = "gRPC C# interop testing server",
-                    AddDashesToOption = true
-                };
-                help.AddPreOptionsLine("Usage:");
-                help.AddOptions(this);
-                return help;
-            }
         }
 
         ServerOptions options;
@@ -81,14 +68,13 @@
 
         public static void Run(string[] args)
         {
-            var options = new ServerOptions();
-            if (!Parser.Default.ParseArguments(args, options))
-            {
-                Environment.Exit(1);
-            }
-
-            var interopServer = new InteropServer(options);
-            interopServer.Run();
+            var parserResult = Parser.Default.ParseArguments<ServerOptions>(args)
+                .WithNotParsed(errors => Environment.Exit(1))
+                .WithParsed(options =>
+                {
+                    var interopServer = new InteropServer(options);
+                    interopServer.Run();
+                });
         }
 
         private void Run()
diff --git a/src/csharp/Grpc.IntegrationTesting/QpsWorker.cs b/src/csharp/Grpc.IntegrationTesting/QpsWorker.cs
index a7c9fa8..865556c 100644
--- a/src/csharp/Grpc.IntegrationTesting/QpsWorker.cs
+++ b/src/csharp/Grpc.IntegrationTesting/QpsWorker.cs
@@ -52,21 +52,8 @@
     {
         private class ServerOptions
         {
-            [Option("driver_port", DefaultValue = 0)]
+            [Option("driver_port", Default = 0)]
             public int DriverPort { get; set; }
-
-            [HelpOption]
-            public string GetUsage()
-            {
-                var help = new HelpText
-                {
-                    Heading = "gRPC C# performance testing worker",
-                    AddDashesToOption = true
-                };
-                help.AddPreOptionsLine("Usage:");
-                help.AddOptions(this);
-                return help;
-            }
         }
 
         ServerOptions options;
@@ -78,14 +65,13 @@
 
         public static void Run(string[] args)
         {
-            var options = new ServerOptions();
-            if (!Parser.Default.ParseArguments(args, options))
-            {
-                Environment.Exit(1);
-            }
-
-            var workerServer = new QpsWorker(options);
-            workerServer.RunAsync().Wait();
+            var parserResult = Parser.Default.ParseArguments<ServerOptions>(args)
+                .WithNotParsed((x) => Environment.Exit(1))
+                .WithParsed(options =>
+                {
+                    var workerServer = new QpsWorker(options);
+                    workerServer.RunAsync().Wait();
+                });
         }
 
         private async Task RunAsync()
diff --git a/src/csharp/Grpc.IntegrationTesting/StressTestClient.cs b/src/csharp/Grpc.IntegrationTesting/StressTestClient.cs
index 74ee040..750613b 100644
--- a/src/csharp/Grpc.IntegrationTesting/StressTestClient.cs
+++ b/src/csharp/Grpc.IntegrationTesting/StressTestClient.cs
@@ -54,36 +54,23 @@
 
         private class ClientOptions
         {
-            [Option("server_addresses", DefaultValue = "localhost:8080")]
+            [Option("server_addresses", Default = "localhost:8080")]
             public string ServerAddresses { get; set; }
 
-            [Option("test_cases", DefaultValue = "large_unary:100")]
+            [Option("test_cases", Default = "large_unary:100")]
             public string TestCases { get; set; }
 
-            [Option("test_duration_secs", DefaultValue = -1)]
+            [Option("test_duration_secs", Default = -1)]
             public int TestDurationSecs { get; set; }
 
-            [Option("num_channels_per_server", DefaultValue = 1)]
+            [Option("num_channels_per_server", Default = 1)]
             public int NumChannelsPerServer { get; set; }
 
-            [Option("num_stubs_per_channel", DefaultValue = 1)]
+            [Option("num_stubs_per_channel", Default = 1)]
             public int NumStubsPerChannel { get; set; }
 
-            [Option("metrics_port", DefaultValue = 8081)]
+            [Option("metrics_port", Default = 8081)]
             public int MetricsPort { get; set; }
-
-            [HelpOption]
-            public string GetUsage()
-            {
-                var help = new HelpText
-                {
-                    Heading = "gRPC C# stress test client",
-                    AddDashesToOption = true
-                };
-                help.AddPreOptionsLine("Usage:");
-                help.AddOptions(this);
-                return help;
-            }
         }
 
         ClientOptions options;
@@ -105,23 +92,21 @@
 
         public static void Run(string[] args)
         {
-            var options = new ClientOptions();
-            if (!Parser.Default.ParseArguments(args, options))
-            {
-                Environment.Exit(1);
-            }
+            var parserResult = Parser.Default.ParseArguments<ClientOptions>(args)
+                .WithNotParsed((x) => Environment.Exit(1))
+                .WithParsed(options => {
+                    GrpcPreconditions.CheckArgument(options.NumChannelsPerServer > 0);
+                    GrpcPreconditions.CheckArgument(options.NumStubsPerChannel > 0);
 
-            GrpcPreconditions.CheckArgument(options.NumChannelsPerServer > 0);
-            GrpcPreconditions.CheckArgument(options.NumStubsPerChannel > 0);
+                    var serverAddresses = options.ServerAddresses.Split(',');
+                    GrpcPreconditions.CheckArgument(serverAddresses.Length > 0, "You need to provide at least one server address");
 
-            var serverAddresses = options.ServerAddresses.Split(',');
-            GrpcPreconditions.CheckArgument(serverAddresses.Length > 0, "You need to provide at least one server address");
+                    var testCases = ParseWeightedTestCases(options.TestCases);
+                    GrpcPreconditions.CheckArgument(testCases.Count > 0, "You need to provide at least one test case");
 
-            var testCases = ParseWeightedTestCases(options.TestCases);
-            GrpcPreconditions.CheckArgument(testCases.Count > 0, "You need to provide at least one test case");
-
-            var interopClient = new StressTestClient(options, serverAddresses.ToList(), testCases);
-            interopClient.Run().Wait();
+                    var interopClient = new StressTestClient(options, serverAddresses.ToList(), testCases);
+                    interopClient.Run().Wait();
+                });
         }
 
         async Task Run()
diff --git a/src/csharp/Grpc.IntegrationTesting/packages.config b/src/csharp/Grpc.IntegrationTesting/packages.config
index e6e64e6..8bf9dd4 100644
--- a/src/csharp/Grpc.IntegrationTesting/packages.config
+++ b/src/csharp/Grpc.IntegrationTesting/packages.config
@@ -1,9 +1,9 @@
 <?xml version="1.0" encoding="utf-8"?>
 <packages>
   <package id="BouncyCastle" version="1.7.0" targetFramework="net45" />
-  <package id="CommandLineParser" version="1.9.71" targetFramework="net45" />
-  <package id="Google.Apis.Auth" version="1.11.1" targetFramework="net45" />
-  <package id="Google.Apis.Core" version="1.11.1" targetFramework="net45" />
+  <package id="CommandLineParser.Unofficial" version="2.0.275" targetFramework="net45" />
+  <package id="Google.Apis.Auth" version="1.15.0" targetFramework="net45" />
+  <package id="Google.Apis.Core" version="1.15.0" targetFramework="net45" />
   <package id="Google.Protobuf" version="3.0.0-beta3" targetFramework="net45" />
   <package id="System.Interactive.Async" version="3.0.0" targetFramework="net45" />
   <package id="Moq" version="4.2.1510.2205" targetFramework="net45" />
diff --git a/src/csharp/Grpc.IntegrationTesting/project.json b/src/csharp/Grpc.IntegrationTesting/project.json
index bb61a67..9d70651 100644
--- a/src/csharp/Grpc.IntegrationTesting/project.json
+++ b/src/csharp/Grpc.IntegrationTesting/project.json
@@ -58,7 +58,7 @@
       "target": "project"
     },
     "Google.Protobuf": "3.0.0-beta3",
-    "CommandLineParser": "1.9.71",
+    "CommandLineParser.Unofficial": "2.0.275",
     "NUnit": "3.2.0",
     "NUnitLite": "3.2.0-*"
   },
diff --git a/src/csharp/build_packages.bat b/src/csharp/build_packages.bat
index f05c024..b92189c 100644
--- a/src/csharp/build_packages.bat
+++ b/src/csharp/build_packages.bat
@@ -31,10 +31,7 @@
 
 @rem Current package versions
 set VERSION=1.1.0-dev
-set PROTOBUF_VERSION=3.0.0-beta3
-
-@rem Packages that depend on prerelease packages (like Google.Protobuf) need to have prerelease suffix as well.
-set VERSION_WITH_BETA=%VERSION%-beta
+set PROTOBUF_VERSION=3.0.0
 
 @rem Adjust the location of nuget.exe
 set NUGET=C:\nuget\nuget.exe
@@ -58,7 +55,6 @@
 
 @rem Fetch all dependencies
 %NUGET% restore ..\..\vsprojects\grpc_csharp_ext.sln || goto :error
-%NUGET% restore Grpc.sln || goto :error
 
 setlocal
 
@@ -73,7 +69,7 @@
 
 %NUGET% pack Grpc.Auth\Grpc.Auth.nuspec -Symbols -Version %VERSION% || goto :error
 %NUGET% pack Grpc.Core\Grpc.Core.nuspec -Symbols -Version %VERSION% || goto :error
-%NUGET% pack Grpc.HealthCheck\Grpc.HealthCheck.nuspec -Symbols -Version %VERSION_WITH_BETA% -Properties ProtobufVersion=%PROTOBUF_VERSION% || goto :error
+%NUGET% pack Grpc.HealthCheck\Grpc.HealthCheck.nuspec -Symbols -Version %VERSION% -Properties ProtobufVersion=%PROTOBUF_VERSION% || goto :error
 %NUGET% pack Grpc.nuspec -Version %VERSION% || goto :error
 %NUGET% pack Grpc.Tools.nuspec -Version %VERSION% || goto :error
 
diff --git a/src/node/health_check/package.json b/src/node/health_check/package.json
index 40e2760..e673359 100644
--- a/src/node/health_check/package.json
+++ b/src/node/health_check/package.json
@@ -15,9 +15,9 @@
     }
   ],
   "dependencies": {
-    "grpc": "^0.15.0",
+    "grpc": "^1.1.0-dev",
     "lodash": "^3.9.3",
-    "google-protobuf": "^3.0.0-alpha.5"
+    "google-protobuf": "^3.0.0"
   },
   "files": [
     "LICENSE",
diff --git a/src/node/tools/bin/protoc.js b/src/node/tools/bin/protoc.js
index 53fc5dc..7f83568 100755
--- a/src/node/tools/bin/protoc.js
+++ b/src/node/tools/bin/protoc.js
@@ -47,7 +47,11 @@
 
 var protoc = path.resolve(__dirname, 'protoc' + exe_ext);
 
-var child_process = execFile(protoc, process.argv.slice(2), function(error, stdout, stderr) {
+var plugin = path.resolve(__dirname, 'grpc_node_plugin' + exe_ext);
+
+var args = ['--plugin=protoc-gen-grpc=' + plugin].concat(process.argv.slice(2));
+
+var child_process = execFile(protoc, args, function(error, stdout, stderr) {
   if (error) {
     throw error;
   }
diff --git "a/src/objective-c/\041ProtoCompiler-gRPCPlugin.podspec" "b/src/objective-c/\041ProtoCompiler-gRPCPlugin.podspec"
index 07d62d2..0c3c321 100644
--- "a/src/objective-c/\041ProtoCompiler-gRPCPlugin.podspec"
+++ "b/src/objective-c/\041ProtoCompiler-gRPCPlugin.podspec"
@@ -36,8 +36,8 @@
   # exclamation mark ensures that other "regular" pods will be able to find it as it'll be installed
   # before them.
   s.name     = '!ProtoCompiler-gRPCPlugin'
-  v = '1.0.0-pre1'
-  s.version  = "#{v}.2" # .2 to depend on protoc 3.0.0
+  v = '1.0.0'
+  s.version  = v
   s.summary  = 'The gRPC ProtoC plugin generates Objective-C files from .proto services.'
   s.description = <<-DESC
     This podspec only downloads the gRPC protoc plugin so that local pods generating protos can use
@@ -82,10 +82,9 @@
   s.authors  = { 'The gRPC contributors' => 'grpc-packages@google.com' }
 
   repo = 'grpc/grpc'
-  release = "objective-c-v#{v}"
   file = "grpc_objective_c_plugin-#{v}-macos-x86_64.zip"
   s.source = {
-    :http => "https://github.com/#{repo}/releases/download/#{release}/#{file}",
+    :http => "https://github.com/#{repo}/releases/download/v#{v}/#{file}",
     # TODO(jcanizales): Add sha1 or sha256
     # :sha1 => '??',
   }
diff --git a/src/objective-c/BoringSSL.podspec b/src/objective-c/BoringSSL.podspec
index b759997..e14f39b 100644
--- a/src/objective-c/BoringSSL.podspec
+++ b/src/objective-c/BoringSSL.podspec
@@ -31,7 +31,7 @@
 
 Pod::Spec.new do |s|
   s.name     = 'BoringSSL'
-  version = '5.0'
+  version = '6.0'
   s.version  = version
   s.summary  = 'BoringSSL is a fork of OpenSSL that is designed to meet Google’s needs.'
   # Adapted from the homepage:
@@ -70,7 +70,7 @@
   s.source = {
     :git => 'https://boringssl.googlesource.com/boringssl',
     :tag => "version_for_cocoapods_#{version}",
-    # :commit => '8d343b44bbab829d1a28fdef650ca95f7db4412e',
+    # :commit => '4ac2dc4c0d48ca45da4f66c40e60d6b425fa94a3',
   }
 
   name = 'openssl'
@@ -388,42 +388,42 @@
           0x28340c19,
           0x283480ac,
           0x283500ea,
-          0x2c3227cb,
-          0x2c32a7d9,
-          0x2c3327eb,
-          0x2c33a7fd,
-          0x2c342811,
-          0x2c34a823,
-          0x2c35283e,
-          0x2c35a850,
-          0x2c362863,
+          0x2c322843,
+          0x2c32a851,
+          0x2c332863,
+          0x2c33a875,
+          0x2c342889,
+          0x2c34a89b,
+          0x2c3528b6,
+          0x2c35a8c8,
+          0x2c3628db,
           0x2c36832d,
-          0x2c372870,
-          0x2c37a882,
-          0x2c382895,
-          0x2c38a8ac,
-          0x2c3928ba,
-          0x2c39a8ca,
-          0x2c3a28dc,
-          0x2c3aa8f0,
-          0x2c3b2901,
-          0x2c3ba920,
-          0x2c3c2934,
-          0x2c3ca94a,
-          0x2c3d2963,
-          0x2c3da980,
-          0x2c3e2991,
-          0x2c3ea99f,
-          0x2c3f29b7,
-          0x2c3fa9cf,
-          0x2c4029dc,
+          0x2c3728e8,
+          0x2c37a8fa,
+          0x2c38290d,
+          0x2c38a924,
+          0x2c392932,
+          0x2c39a942,
+          0x2c3a2954,
+          0x2c3aa968,
+          0x2c3b2979,
+          0x2c3ba998,
+          0x2c3c29ac,
+          0x2c3ca9c2,
+          0x2c3d29db,
+          0x2c3da9f8,
+          0x2c3e2a09,
+          0x2c3eaa17,
+          0x2c3f2a2f,
+          0x2c3faa47,
+          0x2c402a54,
           0x2c4090e7,
-          0x2c4129ed,
-          0x2c41aa00,
+          0x2c412a65,
+          0x2c41aa78,
           0x2c4210c0,
-          0x2c42aa11,
+          0x2c42aa89,
           0x2c430720,
-          0x2c43a912,
+          0x2c43a98a,
           0x30320000,
           0x30328015,
           0x3033001f,
@@ -576,169 +576,174 @@
           0x403b9861,
           0x403c0064,
           0x403c8083,
-          0x403d186d,
-          0x403d9883,
-          0x403e1892,
-          0x403e98a5,
-          0x403f18bf,
-          0x403f98cd,
-          0x404018e2,
-          0x404098f6,
-          0x40411913,
-          0x4041992e,
-          0x40421947,
-          0x4042995a,
-          0x4043196e,
-          0x40439986,
-          0x4044199d,
+          0x403d1890,
+          0x403d98a6,
+          0x403e18b5,
+          0x403e98c8,
+          0x403f18e2,
+          0x403f98f0,
+          0x40401905,
+          0x40409919,
+          0x40411936,
+          0x40419951,
+          0x4042196a,
+          0x4042997d,
+          0x40431991,
+          0x404399a9,
+          0x404419c0,
           0x404480ac,
-          0x404519b2,
-          0x404599c4,
-          0x404619e8,
-          0x40469a08,
-          0x40471a16,
-          0x40479a3d,
-          0x40481a52,
-          0x40489a6b,
-          0x40491a82,
-          0x40499a9c,
-          0x404a1ab3,
-          0x404a9ad1,
-          0x404b1ae9,
-          0x404b9b00,
-          0x404c1b16,
-          0x404c9b28,
-          0x404d1b49,
-          0x404d9b6b,
-          0x404e1b7f,
-          0x404e9b8c,
-          0x404f1ba3,
-          0x404f9bb3,
-          0x40501bdd,
-          0x40509bf1,
-          0x40511c0c,
-          0x40519c1c,
-          0x40521c33,
-          0x40529c45,
-          0x40531c5d,
-          0x40539c70,
-          0x40541c85,
-          0x40549ca8,
-          0x40551cb6,
-          0x40559cd3,
-          0x40561ce0,
-          0x40569cf9,
-          0x40571d11,
-          0x40579d24,
-          0x40581d39,
-          0x40589d4b,
-          0x40591d7a,
-          0x40599d93,
-          0x405a1da7,
-          0x405a9db7,
-          0x405b1dcf,
-          0x405b9de0,
-          0x405c1df3,
-          0x405c9e04,
-          0x405d1e11,
-          0x405d9e28,
-          0x405e1e48,
+          0x404519d5,
+          0x404599e7,
+          0x40461a0b,
+          0x40469a2b,
+          0x40471a39,
+          0x40479a60,
+          0x40481a89,
+          0x40489aa2,
+          0x40491ab9,
+          0x40499ad3,
+          0x404a1aea,
+          0x404a9b08,
+          0x404b1b20,
+          0x404b9b37,
+          0x404c1b4d,
+          0x404c9b5f,
+          0x404d1b80,
+          0x404d9ba2,
+          0x404e1bb6,
+          0x404e9bc3,
+          0x404f1bf0,
+          0x404f9c19,
+          0x40501c43,
+          0x40509c57,
+          0x40511c72,
+          0x40519c82,
+          0x40521c99,
+          0x40529cbd,
+          0x40531cd5,
+          0x40539ce8,
+          0x40541cfd,
+          0x40549d20,
+          0x40551d2e,
+          0x40559d4b,
+          0x40561d58,
+          0x40569d71,
+          0x40571d89,
+          0x40579d9c,
+          0x40581db1,
+          0x40589dc3,
+          0x40591df2,
+          0x40599e0b,
+          0x405a1e1f,
+          0x405a9e2f,
+          0x405b1e47,
+          0x405b9e58,
+          0x405c1e6b,
+          0x405c9e7c,
+          0x405d1e89,
+          0x405d9ea0,
+          0x405e1ec0,
           0x405e8a95,
-          0x405f1e69,
-          0x405f9e76,
-          0x40601e84,
-          0x40609ea6,
-          0x40611ece,
-          0x40619ee3,
-          0x40621efa,
-          0x40629f0b,
-          0x40631f1c,
-          0x40639f31,
-          0x40641f48,
-          0x40649f59,
-          0x40651f74,
-          0x40659f8b,
-          0x40661fa3,
-          0x40669fcd,
-          0x40671ff8,
-          0x4067a019,
-          0x4068202c,
-          0x4068a04d,
-          0x4069207f,
-          0x4069a0ad,
-          0x406a20ce,
-          0x406aa0ee,
-          0x406b2276,
-          0x406ba299,
-          0x406c22af,
-          0x406ca4db,
-          0x406d250a,
-          0x406da532,
-          0x406e254b,
-          0x406ea563,
-          0x406f2582,
-          0x406fa597,
-          0x407025aa,
-          0x4070a5c7,
+          0x405f1ee1,
+          0x405f9eee,
+          0x40601efc,
+          0x40609f1e,
+          0x40611f46,
+          0x40619f5b,
+          0x40621f72,
+          0x40629f83,
+          0x40631f94,
+          0x40639fa9,
+          0x40641fc0,
+          0x40649fd1,
+          0x40651fec,
+          0x4065a003,
+          0x4066201b,
+          0x4066a045,
+          0x40672070,
+          0x4067a091,
+          0x406820a4,
+          0x4068a0c5,
+          0x406920f7,
+          0x4069a125,
+          0x406a2146,
+          0x406aa166,
+          0x406b22ee,
+          0x406ba311,
+          0x406c2327,
+          0x406ca553,
+          0x406d2582,
+          0x406da5aa,
+          0x406e25c3,
+          0x406ea5db,
+          0x406f25fa,
+          0x406fa60f,
+          0x40702622,
+          0x4070a63f,
           0x40710800,
-          0x4071a5d9,
-          0x407225ec,
-          0x4072a605,
-          0x4073261d,
+          0x4071a651,
+          0x40722664,
+          0x4072a67d,
+          0x40732695,
           0x4073936d,
-          0x40742631,
-          0x4074a64b,
-          0x4075265c,
-          0x4075a670,
-          0x4076267e,
+          0x407426a9,
+          0x4074a6c3,
+          0x407526d4,
+          0x4075a6e8,
+          0x407626f6,
           0x407691aa,
-          0x407726a3,
-          0x4077a6c5,
-          0x407826e0,
-          0x4078a719,
-          0x40792730,
-          0x4079a746,
-          0x407a2752,
-          0x407aa765,
-          0x407b277a,
-          0x407ba78c,
-          0x407c27a1,
-          0x407ca7aa,
-          0x407d2068,
-          0x407d9bc3,
-          0x407e26f5,
-          0x407e9d5b,
-          0x407f1a2a,
-          0x41f421a1,
-          0x41f92233,
-          0x41fe2126,
-          0x41fea302,
-          0x41ff23f3,
-          0x420321ba,
-          0x420821dc,
-          0x4208a218,
-          0x4209210a,
-          0x4209a252,
-          0x420a2161,
-          0x420aa141,
-          0x420b2181,
-          0x420ba1fa,
-          0x420c240f,
-          0x420ca2cf,
-          0x420d22e9,
-          0x420da320,
-          0x4212233a,
-          0x421723d6,
-          0x4217a37c,
-          0x421c239e,
-          0x421f2359,
-          0x42212426,
-          0x422623b9,
-          0x422b24bf,
-          0x422ba488,
-          0x422c24a7,
-          0x422ca462,
-          0x422d2441,
+          0x4077271b,
+          0x4077a73d,
+          0x40782758,
+          0x4078a791,
+          0x407927a8,
+          0x4079a7be,
+          0x407a27ca,
+          0x407aa7dd,
+          0x407b27f2,
+          0x407ba804,
+          0x407c2819,
+          0x407ca822,
+          0x407d20e0,
+          0x407d9c29,
+          0x407e276d,
+          0x407e9dd3,
+          0x407f1a4d,
+          0x407f986d,
+          0x40801c00,
+          0x40809a75,
+          0x40811cab,
+          0x40819bda,
+          0x41f42219,
+          0x41f922ab,
+          0x41fe219e,
+          0x41fea37a,
+          0x41ff246b,
+          0x42032232,
+          0x42082254,
+          0x4208a290,
+          0x42092182,
+          0x4209a2ca,
+          0x420a21d9,
+          0x420aa1b9,
+          0x420b21f9,
+          0x420ba272,
+          0x420c2487,
+          0x420ca347,
+          0x420d2361,
+          0x420da398,
+          0x421223b2,
+          0x4217244e,
+          0x4217a3f4,
+          0x421c2416,
+          0x421f23d1,
+          0x4221249e,
+          0x42262431,
+          0x422b2537,
+          0x422ba500,
+          0x422c251f,
+          0x422ca4da,
+          0x422d24b9,
           0x4432072b,
           0x4432873a,
           0x44330746,
@@ -781,69 +786,69 @@
           0x4c3d136d,
           0x4c3d937c,
           0x4c3e1389,
-          0x50322a23,
-          0x5032aa32,
-          0x50332a3d,
-          0x5033aa4d,
-          0x50342a66,
-          0x5034aa80,
-          0x50352a8e,
-          0x5035aaa4,
-          0x50362ab6,
-          0x5036aacc,
-          0x50372ae5,
-          0x5037aaf8,
-          0x50382b10,
-          0x5038ab21,
-          0x50392b36,
-          0x5039ab4a,
-          0x503a2b6a,
-          0x503aab80,
-          0x503b2b98,
-          0x503babaa,
-          0x503c2bc6,
-          0x503cabdd,
-          0x503d2bf6,
-          0x503dac0c,
-          0x503e2c19,
-          0x503eac2f,
-          0x503f2c41,
+          0x50322a9b,
+          0x5032aaaa,
+          0x50332ab5,
+          0x5033aac5,
+          0x50342ade,
+          0x5034aaf8,
+          0x50352b06,
+          0x5035ab1c,
+          0x50362b2e,
+          0x5036ab44,
+          0x50372b5d,
+          0x5037ab70,
+          0x50382b88,
+          0x5038ab99,
+          0x50392bae,
+          0x5039abc2,
+          0x503a2be2,
+          0x503aabf8,
+          0x503b2c10,
+          0x503bac22,
+          0x503c2c3e,
+          0x503cac55,
+          0x503d2c6e,
+          0x503dac84,
+          0x503e2c91,
+          0x503eaca7,
+          0x503f2cb9,
           0x503f8382,
-          0x50402c54,
-          0x5040ac64,
-          0x50412c7e,
-          0x5041ac8d,
-          0x50422ca7,
-          0x5042acc4,
-          0x50432cd4,
-          0x5043ace4,
-          0x50442cf3,
+          0x50402ccc,
+          0x5040acdc,
+          0x50412cf6,
+          0x5041ad05,
+          0x50422d1f,
+          0x5042ad3c,
+          0x50432d4c,
+          0x5043ad5c,
+          0x50442d6b,
           0x5044843f,
-          0x50452d07,
-          0x5045ad25,
-          0x50462d38,
-          0x5046ad4e,
-          0x50472d60,
-          0x5047ad75,
-          0x50482d9b,
-          0x5048ada9,
-          0x50492dbc,
-          0x5049add1,
-          0x504a2de7,
-          0x504aadf7,
-          0x504b2e17,
-          0x504bae2a,
-          0x504c2e4d,
-          0x504cae7b,
-          0x504d2e8d,
-          0x504daeaa,
-          0x504e2ec5,
-          0x504eaee1,
-          0x504f2ef3,
-          0x504faf0a,
-          0x50502f19,
+          0x50452d7f,
+          0x5045ad9d,
+          0x50462db0,
+          0x5046adc6,
+          0x50472dd8,
+          0x5047aded,
+          0x50482e13,
+          0x5048ae21,
+          0x50492e34,
+          0x5049ae49,
+          0x504a2e5f,
+          0x504aae6f,
+          0x504b2e8f,
+          0x504baea2,
+          0x504c2ec5,
+          0x504caef3,
+          0x504d2f05,
+          0x504daf22,
+          0x504e2f3d,
+          0x504eaf59,
+          0x504f2f6b,
+          0x504faf82,
+          0x50502f91,
           0x505086ef,
-          0x50512f2c,
+          0x50512fa4,
           0x58320ec9,
           0x68320e8b,
           0x68328c25,
@@ -1204,6 +1209,7 @@
           "BAD_SSL_FILETYPE\\0"
           "BAD_WRITE_RETRY\\0"
           "BIO_NOT_SET\\0"
+          "BUFFERED_MESSAGES_ON_CIPHER_CHANGE\\0"
           "CA_DN_LENGTH_MISMATCH\\0"
           "CA_DN_TOO_LONG\\0"
           "CCS_RECEIVED_EARLY\\0"
@@ -1226,6 +1232,7 @@
           "DIGEST_CHECK_FAILED\\0"
           "DOWNGRADE_DETECTED\\0"
           "DTLS_MESSAGE_TOO_BIG\\0"
+          "DUPLICATE_EXTENSION\\0"
           "ECC_CERT_NOT_FOR_SIGNING\\0"
           "EMS_STATE_INCONSISTENT\\0"
           "ENCRYPTED_LENGTH_TOO_LONG\\0"
@@ -1240,7 +1247,9 @@
           "HTTPS_PROXY_REQUEST\\0"
           "HTTP_REQUEST\\0"
           "INAPPROPRIATE_FALLBACK\\0"
+          "INVALID_ALPN_PROTOCOL\\0"
           "INVALID_COMMAND\\0"
+          "INVALID_COMPRESSION_LIST\\0"
           "INVALID_MESSAGE\\0"
           "INVALID_OUTER_RECORD_TYPE\\0"
           "INVALID_SSL_SESSION\\0"
@@ -1248,6 +1257,7 @@
           "LENGTH_MISMATCH\\0"
           "LIBRARY_HAS_NO_CIPHERS\\0"
           "MISSING_EXTENSION\\0"
+          "MISSING_KEY_SHARE\\0"
           "MISSING_RSA_CERTIFICATE\\0"
           "MISSING_TMP_DH_KEY\\0"
           "MISSING_TMP_ECDH_KEY\\0"
diff --git a/src/objective-c/GRPCClient/private/GRPCHost.m b/src/objective-c/GRPCClient/private/GRPCHost.m
index 477ddf5..9cd9593 100644
--- a/src/objective-c/GRPCClient/private/GRPCHost.m
+++ b/src/objective-c/GRPCClient/private/GRPCHost.m
@@ -49,7 +49,7 @@
 
 // TODO(jcanizales): Generate the version in a standalone header, from templates. Like
 // templates/src/core/surface/version.c.template .
-#define GRPC_OBJC_VERSION_STRING @"1.0.0-pre1"
+#define GRPC_OBJC_VERSION_STRING @"1.0.0"
 
 static NSMutableDictionary *kHostCache;
 
diff --git a/src/objective-c/README.md b/src/objective-c/README.md
index 909b12b..3624475 100644
--- a/src/objective-c/README.md
+++ b/src/objective-c/README.md
@@ -48,7 +48,7 @@
   src = '.'
 
   # We'll use protoc with the gRPC plugin.
-  s.dependency '!ProtoCompiler-gRPCPlugin', '~> 1.0.0-pre1.2'
+  s.dependency '!ProtoCompiler-gRPCPlugin', '~> 1.0'
 
   # Pods directory corresponding to this app's Podfile, relative to the location of this podspec.
   pods_root = '<path to your Podfile>/Pods'
@@ -82,10 +82,6 @@
     ms.requires_arc = false
     # The generated files depend on the protobuf runtime.
     ms.dependency 'Protobuf'
-    # This is needed by all pods that depend on Protobuf:
-    ms.pod_target_xcconfig = {
-      'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1',
-    }
   end
 
   # The --objcgrpc_out plugin generates a pair of .pbrpc.h/.pbrpc.m files for each .proto file with
@@ -98,6 +94,13 @@
     ss.dependency 'gRPC-ProtoRPC'
     ss.dependency "#{s.name}/Messages"
   end
+
+  s.pod_target_xcconfig = {
+    # This is needed by all pods that depend on Protobuf:
+    'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1',
+    # This is needed by all pods that depend on gRPC-RxLibrary:
+    'CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES' => 'YES',
+  }
 end
 ```
 
diff --git a/src/objective-c/examples/RemoteTestClient/RemoteTest.podspec b/src/objective-c/examples/RemoteTestClient/RemoteTest.podspec
index 974a676..ea61813 100644
--- a/src/objective-c/examples/RemoteTestClient/RemoteTest.podspec
+++ b/src/objective-c/examples/RemoteTestClient/RemoteTest.podspec
@@ -11,7 +11,7 @@
   s.osx.deployment_target = '10.9'
 
   # Run protoc with the Objective-C and gRPC plugins to generate protocol messages and gRPC clients.
-  s.dependency "!ProtoCompiler-gRPCPlugin", "~> 1.0.0-pre1.2"
+  s.dependency "!ProtoCompiler-gRPCPlugin"
 
   repo_root = '../../../..'
   bin_dir = "#{repo_root}/bins/$CONFIG"
@@ -35,10 +35,6 @@
     ms.header_mappings_dir = '.'
     ms.requires_arc = false
     ms.dependency 'Protobuf'
-    # This is needed by all pods that depend on Protobuf:
-    ms.pod_target_xcconfig = {
-      'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1',
-    }
   end
 
   s.subspec 'Services' do |ss|
@@ -48,4 +44,11 @@
     ss.dependency 'gRPC-ProtoRPC'
     ss.dependency "#{s.name}/Messages"
   end
+
+  s.pod_target_xcconfig = {
+    # This is needed by all pods that depend on Protobuf:
+    'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1',
+    # This is needed by all pods that depend on gRPC-RxLibrary:
+    'CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES' => 'YES',
+  }
 end
diff --git a/src/objective-c/tests/CoreCronetEnd2EndTests/CoreCronetEnd2EndTests.m b/src/objective-c/tests/CoreCronetEnd2EndTests/CoreCronetEnd2EndTests.m
deleted file mode 100644
index 58abb49..0000000
--- a/src/objective-c/tests/CoreCronetEnd2EndTests/CoreCronetEnd2EndTests.m
+++ /dev/null
@@ -1,394 +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.
- *
- */
-
-/*
- * This test file is derived from fixture h2_ssl.c in core end2end test
- * (test/core/end2end/fixture/h2_ssl.c). The structure of the fixture is
- * preserved as much as possible
- *
- * This fixture creates a server full stack using chttp2 and a client
- * full stack using Cronet. End-to-end tests are run against this
- * configuration
- *
- */
-
-
-#import <XCTest/XCTest.h>
-#include "test/core/end2end/end2end_tests.h"
-
-#include <stdio.h>
-#include <string.h>
-
-#include <grpc/support/alloc.h>
-#include <grpc/support/host_port.h>
-#include <grpc/support/log.h>
-
-#include "src/core/lib/channel/channel_args.h"
-#include "src/core/lib/security/credentials/credentials.h"
-#include "src/core/lib/support/env.h"
-#include "src/core/lib/support/string.h"
-#include "src/core/lib/support/tmpfile.h"
-#include "test/core/end2end/data/ssl_test_data.h"
-#include "test/core/util/port.h"
-#include "test/core/util/test_config.h"
-
-#include <grpc/grpc_cronet.h>
-#import <Cronet/Cronet.h>
-
-typedef struct fullstack_secure_fixture_data {
-  char *localaddr;
-} fullstack_secure_fixture_data;
-
-static grpc_end2end_test_fixture chttp2_create_fixture_secure_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_secure_fixture_data *ffd =
-  gpr_malloc(sizeof(fullstack_secure_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;
-}
-
-static void process_auth_failure(void *state, grpc_auth_context *ctx,
-                                 const grpc_metadata *md, size_t md_count,
-                                 grpc_process_auth_metadata_done_cb cb,
-                                 void *user_data) {
-  GPR_ASSERT(state == NULL);
-  cb(user_data, NULL, 0, NULL, 0, GRPC_STATUS_UNAUTHENTICATED, NULL);
-}
-
-static void cronet_init_client_secure_fullstack(
-                                                grpc_end2end_test_fixture *f, grpc_channel_args *client_args,
-                                                cronet_engine *cronetEngine) {
-  fullstack_secure_fixture_data *ffd = f->fixture_data;
-  f->client =
-  grpc_cronet_secure_channel_create(cronetEngine, ffd->localaddr, client_args, NULL);
-  GPR_ASSERT(f->client != NULL);
-}
-
-static void chttp2_init_server_secure_fullstack(
-                                                grpc_end2end_test_fixture *f, grpc_channel_args *server_args,
-                                                grpc_server_credentials *server_creds) {
-  fullstack_secure_fixture_data *ffd = f->fixture_data;
-  if (f->server) {
-    grpc_server_destroy(f->server);
-  }
-  f->server = grpc_server_create(server_args, NULL);
-  grpc_server_register_completion_queue(f->server, f->cq, NULL);
-  GPR_ASSERT(grpc_server_add_secure_http2_port(f->server, ffd->localaddr,
-                                               server_creds));
-  grpc_server_credentials_release(server_creds);
-  grpc_server_start(f->server);
-}
-
-static void chttp2_tear_down_secure_fullstack(grpc_end2end_test_fixture *f) {
-  fullstack_secure_fixture_data *ffd = f->fixture_data;
-  gpr_free(ffd->localaddr);
-  gpr_free(ffd);
-}
-
-static void cronet_init_client_simple_ssl_secure_fullstack(
-                                                           grpc_end2end_test_fixture *f, grpc_channel_args *client_args) {
-  grpc_arg ssl_name_override = {GRPC_ARG_STRING,
-    GRPC_SSL_TARGET_NAME_OVERRIDE_ARG,
-    {"foo.test.google.fr"}};
-  
-  grpc_channel_args *new_client_args =
-  grpc_channel_args_copy_and_add(client_args, &ssl_name_override, 1);
-  [Cronet setHttp2Enabled:YES];
-  [Cronet start];
-  cronet_engine *cronetEngine = [Cronet getGlobalEngine];
-  
-  cronet_init_client_secure_fullstack(f, new_client_args, cronetEngine);
-  grpc_channel_args_destroy(new_client_args);
-}
-
-static int fail_server_auth_check(grpc_channel_args *server_args) {
-  size_t i;
-  if (server_args == NULL) return 0;
-  for (i = 0; i < server_args->num_args; i++) {
-    if (strcmp(server_args->args[i].key, FAIL_AUTH_CHECK_SERVER_ARG_NAME) ==
-        0) {
-      return 1;
-    }
-  }
-  return 0;
-}
-
-static void chttp2_init_server_simple_ssl_secure_fullstack(
-                                                           grpc_end2end_test_fixture *f, grpc_channel_args *server_args) {
-  grpc_ssl_pem_key_cert_pair pem_cert_key_pair = {test_server1_key,
-    test_server1_cert};
-  grpc_server_credentials *ssl_creds =
-  grpc_ssl_server_credentials_create(NULL, &pem_cert_key_pair, 1, 0, NULL);
-  if (fail_server_auth_check(server_args)) {
-    grpc_auth_metadata_processor processor = {process_auth_failure, NULL, NULL};
-    grpc_server_credentials_set_auth_metadata_processor(ssl_creds, processor);
-  }
-  chttp2_init_server_secure_fullstack(f, server_args, ssl_creds);
-}
-
-/* All test configurations */
-
-static grpc_end2end_test_config configs[] = {
-  {"chttp2/simple_ssl_fullstack",
-    FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION |
-    FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS,
-    chttp2_create_fixture_secure_fullstack,
-    cronet_init_client_simple_ssl_secure_fullstack,
-    chttp2_init_server_simple_ssl_secure_fullstack,
-    chttp2_tear_down_secure_fullstack},
-};
-
-
-
-static char *roots_filename;
-
-@interface CoreCronetEnd2EndTests : XCTestCase
-
-@end
-
-@implementation CoreCronetEnd2EndTests
-
-
-// The setUp() function is run before the test cases run and only run once
-+ (void)setUp {
-  [super setUp];
-
-  FILE *roots_file;
-  size_t roots_size = strlen(test_root_cert);
-  
-  char *argv[] = {"CoreCronetEnd2EndTests"};
-  grpc_test_init(1, argv);
-  grpc_end2end_tests_pre_init();
-  
-  /* Set the SSL roots env var. */
-  roots_file = gpr_tmpfile("chttp2_simple_ssl_fullstack_test", &roots_filename);
-  GPR_ASSERT(roots_filename != NULL);
-  GPR_ASSERT(roots_file != NULL);
-  GPR_ASSERT(fwrite(test_root_cert, 1, roots_size, roots_file) == roots_size);
-  fclose(roots_file);
-  gpr_setenv(GRPC_DEFAULT_SSL_ROOTS_FILE_PATH_ENV_VAR, roots_filename);
-  
-  grpc_init();
-  
-}
-
-// The tearDown() function is run after all test cases finish running
-+ (void)tearDown {
-  grpc_shutdown();
-  
-  /* Cleanup. */
-  remove(roots_filename);
-  gpr_free(roots_filename);
-  
-  [super tearDown];
-}
-
-- (void)testIndividualCase:(char*)test_case {
-  char *argv[] = {"h2_ssl", test_case};
-  
-  for (int i = 0; i < sizeof(configs) / sizeof(*configs); i++) {
-    grpc_end2end_tests(sizeof(argv) / sizeof(argv[0]), argv, configs[i]);
-  }
-}
-
-// TODO(mxyan): Use NSStringFromSelector(_cmd) to acquire test name from the
-// test case method name, so that bodies of test cases can stay identical 
-- (void)testBadHostname {
-  [self testIndividualCase:"bad_hostname"];
-}
-
-- (void)testBinaryMetadata {
-  [self testIndividualCase:"binary_metadata"];
-}
-
-- (void)testCallCreds {
-  [self testIndividualCase:"call_creds"];
-}
-
-- (void)testCancelAfterAccept {
-  [self testIndividualCase:"cancel_after_accept"];
-}
-
-- (void)testCancelAfterClientDone {
-  [self testIndividualCase:"cancel_after_client_done"];
-}
-
-- (void)testCancelAfterInvoke {
-  [self testIndividualCase:"cancel_after_invoke"];
-}
-
-- (void)testCancelBeforeInvoke {
-  [self testIndividualCase:"cancel_before_invoke"];
-}
-
-- (void)testCancelInAVacuum {
-  [self testIndividualCase:"cancel_in_a_vacuum"];
-}
-
-- (void)testCancelWithStatus {
-  [self testIndividualCase:"cancel_with_status"];
-}
-
-- (void)testCompressedPayload {
-  [self testIndividualCase:"compressed_payload"];
-}
-
-- (void)testConnectivity {
-  [self testIndividualCase:"connectivity"];
-}
-
-- (void)testDefaultHost {
-  [self testIndividualCase:"default_host"];
-}
-
-- (void)testDisappearingServer {
-  [self testIndividualCase:"disappearing_server"];
-}
-
-- (void)testEmptyBatch {
-  [self testIndividualCase:"empty_batch"];
-}
-
-- (void)testFilterCausesClose {
-  [self testIndividualCase:"filter_causes_close"];
-}
-
-- (void)testGracefulServerShutdown {
-  [self testIndividualCase:"graceful_server_shutdown"];
-}
-
-- (void)testHighInitialSeqno {
-  [self testIndividualCase:"high_initial_seqno"];
-}
-
-- (void)testHpackSize {
-  [self testIndividualCase:"hpack_size"];
-}
-
-- (void)testIdempotentRequest {
-  [self testIndividualCase:"idempotent_request"];
-}
-
-- (void)testInvokeLargeRequest {
-  [self testIndividualCase:"invoke_large_request"];
-}
-
-- (void)testLargeMetadata {
-  [self testIndividualCase:"large_metadata"];
-}
-
-- (void)testMaxConcurrentStreams {
-  [self testIndividualCase:"max_concurrent_streams"];
-}
-
-- (void)testMaxMessageLength {
-  [self testIndividualCase:"max_message_length"];
-}
-
-- (void)testNegativeDeadline {
-  [self testIndividualCase:"negative_deadline"];
-}
-
-- (void)testNetworkStatusChange {
-  [self testIndividualCase:"network_status_change"];
-}
-
-- (void)testNoOp {
-  [self testIndividualCase:"no_op"];
-}
-
-- (void)testPayload {
-  [self testIndividualCase:"payload"];
-}
-
-- (void)testPing {
-  [self testIndividualCase:"ping"];
-}
-
-- (void)testPingPongStreaming {
-  [self testIndividualCase:"ping_pong_streaming"];
-}
-
-- (void)testRegisteredCall {
-  [self testIndividualCase:"registered_call"];
-}
-
-- (void)testRequestWithFlags {
-  [self testIndividualCase:"request_with_flags"];
-}
-
-- (void)testRequestWithPayload {
-  [self testIndividualCase:"request_with_payload"];
-}
-
-- (void)testServerFinishesRequest {
-  [self testIndividualCase:"server_finishes_request"];
-}
-
-- (void)testShutdownFinishesCalls {
-  [self testIndividualCase:"shutdown_finishes_calls"];
-}
-
-- (void)testShutdownFinishesTags {
-  [self testIndividualCase:"shutdown_finishes_tags"];
-}
-
-- (void)testSimpleDelayedRequest {
-  [self testIndividualCase:"simple_delayed_request"];
-}
-
-- (void)testSimpleMetadata {
-  [self testIndividualCase:"simple_metadata"];
-}
-
-- (void)testSimpleRequest {
-  [self testIndividualCase:"simple_request"];
-}
-
-- (void)testStreamingErrorResponse {
-  [self testIndividualCase:"streaming_error_response"];
-}
-
-- (void)testTrailingMetadata {
-  [self testIndividualCase:"trailing_metadata"];
-}
-
-@end
diff --git a/src/objective-c/tests/RemoteTestClient/RemoteTest.podspec b/src/objective-c/tests/RemoteTestClient/RemoteTest.podspec
index 3d28234..2e0a050 100644
--- a/src/objective-c/tests/RemoteTestClient/RemoteTest.podspec
+++ b/src/objective-c/tests/RemoteTestClient/RemoteTest.podspec
@@ -11,7 +11,7 @@
   s.osx.deployment_target = '10.9'
 
   # Run protoc with the Objective-C and gRPC plugins to generate protocol messages and gRPC clients.
-  s.dependency "!ProtoCompiler-gRPCPlugin", "~> 1.0.0-pre1.2"
+  s.dependency "!ProtoCompiler-gRPCPlugin"
 
   repo_root = '../../../..'
   bin_dir = "#{repo_root}/bins/$CONFIG"
@@ -35,10 +35,6 @@
     ms.header_mappings_dir = "."
     ms.requires_arc = false
     ms.dependency "Protobuf"
-    # This is needed by all pods that depend on Protobuf:
-    ms.pod_target_xcconfig = {
-      'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1',
-    }
   end
 
   s.subspec "Services" do |ss|
@@ -48,4 +44,11 @@
     ss.dependency "gRPC-ProtoRPC"
     ss.dependency "#{s.name}/Messages"
   end
+
+  s.pod_target_xcconfig = {
+    # This is needed by all pods that depend on Protobuf:
+    'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1',
+    # This is needed by all pods that depend on gRPC-RxLibrary:
+    'CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES' => 'YES',
+  }
 end
diff --git a/src/php/composer.json b/src/php/composer.json
index 1eacc64..571f300 100644
--- a/src/php/composer.json
+++ b/src/php/composer.json
@@ -5,7 +5,7 @@
   "keywords": ["rpc"],
   "homepage": "http://grpc.io",
   "license": "BSD-3-Clause",
-  "version": "1.0.0",
+  "version": "1.1.0",
   "require": {
     "php": ">=5.5.0",
     "stanley-cheung/protobuf-php": "v0.6"
diff --git a/src/php/ext/grpc/php7_wrapper.h b/src/php/ext/grpc/php7_wrapper.h
index fd8d356..1d78241 100644
--- a/src/php/ext/grpc/php7_wrapper.h
+++ b/src/php/ext/grpc/php7_wrapper.h
@@ -143,8 +143,7 @@
 
 #define PHP_GRPC_RETURN_STRING(val, dup) RETURN_STRING(val)
 #define PHP_GRPC_MAKE_STD_ZVAL(pzv) \
-  zval _stack_zval_##pzv; \
-  pzv = &(_stack_zval_##pzv)
+  pzv = (zval *)emalloc(sizeof(zval));
 #define PHP_GRPC_DELREF(zv)
 
 #define PHP_GRPC_WRAP_OBJECT_START(name) \
diff --git a/src/python/grpcio/_spawn_patch.py b/src/python/grpcio/_spawn_patch.py
new file mode 100644
index 0000000..24306f0
--- /dev/null
+++ b/src/python/grpcio/_spawn_patch.py
@@ -0,0 +1,73 @@
+# Copyright 2016, Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"""Patches the spawn() command for windows compilers.
+
+Windows has an 8191 character command line limit, but some compilers
+support an @command_file directive where command_file is a file
+containing the full command line.
+"""
+
+from distutils import ccompiler
+import os
+import os.path
+import shutil
+import sys
+import tempfile
+
+MAX_COMMAND_LENGTH = 8191
+
+_classic_spawn = ccompiler.CCompiler.spawn
+
+def _commandfile_spawn(self, command):
+  command_length = sum([len(arg) for arg in command])
+  if os.name == 'nt' and command_length > MAX_COMMAND_LENGTH:
+    # Even if this command doesn't support the @command_file, it will
+    # fail as is so we try blindly
+    print('Command line length exceeded, using command file')
+    print(' '.join(command))
+    temporary_directory = tempfile.mkdtemp()
+    command_filename = os.path.abspath(
+    os.path.join(temporary_directory, 'command'))
+    with open(command_filename, 'w') as command_file:
+      escaped_args = ['"' + arg.replace('\\', '\\\\') + '"' for arg in command[1:]]
+      command_file.write(' '.join(escaped_args))
+    modified_command = command[:1] + ['@{}'.format(command_filename)]
+    try:
+      _classic_spawn(self, modified_command)
+    finally:
+      shutil.rmtree(temporary_directory)
+  else:
+    _classic_spawn(self, command)
+
+
+def monkeypatch_spawn():
+  """Monkeypatching is dumb, but it's either that or we become maintainers of
+     something much, much bigger."""
+  ccompiler.CCompiler.spawn = _commandfile_spawn
diff --git a/src/python/grpcio/_unixccompiler_patch.py b/src/python/grpcio/_unixccompiler_patch.py
deleted file mode 100644
index 894c3ef..0000000
--- a/src/python/grpcio/_unixccompiler_patch.py
+++ /dev/null
@@ -1,77 +0,0 @@
-# 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.
-
-"""Covers inadequacies in distutils."""
-
-from distutils import ccompiler
-from distutils import errors
-from distutils import unixccompiler
-import os
-import os.path
-import shlex
-import shutil
-import sys
-import tempfile
-
-def _unix_commandfile_spawn(self, command):
-  """Wrapper around distutils.util.spawn that attempts to use command files.
-
-  Meant to replace the CCompiler method `spawn` on UnixCCompiler and its
-  derivatives (e.g. the MinGW32 compiler).
-
-  Some commands like `gcc` (and friends like `clang`) support command files to
-  work around shell command length limits.
-  """
-  # Sometimes distutils embeds the executables as full strings including some
-  # hard-coded flags rather than as lists.
-  command = list(shlex.split(command[0])) + list(command[1:])
-  command_base = os.path.basename(command[0].strip())
-  if command_base == 'ccache':
-    command_base = command[:2]
-    command_args = command[2:]
-  elif command_base.startswith('ccache') or command_base in ['gcc', 'clang', 'clang++', 'g++']:
-    command_base = command[:1]
-    command_args = command[1:]
-  else:
-    return ccompiler.CCompiler.spawn(self, command)
-  temporary_directory = tempfile.mkdtemp()
-  command_filename = os.path.abspath(os.path.join(temporary_directory, 'command'))
-  with open(command_filename, 'w') as command_file:
-    escaped_args = [arg.replace('\\', '\\\\') for arg in command_args]
-    command_file.write(' '.join(escaped_args))
-  modified_command = command_base + ['@{}'.format(command_filename)]
-  result = ccompiler.CCompiler.spawn(self, modified_command)
-  shutil.rmtree(temporary_directory)
-  return result
-
-
-def monkeypatch_unix_compiler():
-  """Monkeypatching is dumb, but it's either that or we become maintainers of
-     something much, much bigger."""
-  unixccompiler.UnixCCompiler.spawn = _unix_commandfile_spawn
diff --git a/src/python/grpcio_health_checking/setup.py b/src/python/grpcio_health_checking/setup.py
index 6074175..8c92ee1 100644
--- a/src/python/grpcio_health_checking/setup.py
+++ b/src/python/grpcio_health_checking/setup.py
@@ -46,12 +46,12 @@
 }
 
 SETUP_REQUIRES = (
-    'grpcio-tools>=0.15.0',
+    'grpcio-tools>={version}'.format(version=grpc_version.VERSION),
 )
 
 INSTALL_REQUIRES = (
     'protobuf>=3.0.0',
-    'grpcio>=0.15.0',
+    'grpcio>={version}'.format(version=grpc_version.VERSION),
 )
 
 COMMAND_CLASS = {
diff --git a/src/python/grpcio_tests/setup.py b/src/python/grpcio_tests/setup.py
index 5c60eac..3524355 100644
--- a/src/python/grpcio_tests/setup.py
+++ b/src/python/grpcio_tests/setup.py
@@ -60,17 +60,14 @@
     'coverage>=4.0',
     'enum34>=1.0.4',
     'futures>=2.2.0',
-    'grpcio>=0.14.0',
-    'grpcio-health-checking>=0.14.0',
+    'grpcio>={version}'.format(version=grpc_version.VERSION),
+    'grpcio-tools>={version}'.format(version=grpc_version.VERSION),
+    'grpcio-health-checking>={version}'.format(version=grpc_version.VERSION),
     'oauth2client>=1.4.7',
     'protobuf>=3.0.0',
     'six>=1.10',
 )
 
-SETUP_REQUIRES = (
-    'grpcio-tools>=0.14.0',
-)
-
 COMMAND_CLASS = {
     # Run `preprocess` *before* doing any packaging!
     'preprocess': commands.GatherProto,
@@ -115,7 +112,6 @@
   package_dir=PACKAGE_DIRECTORIES,
   package_data=PACKAGE_DATA,
   install_requires=INSTALL_REQUIRES,
-  setup_requires=SETUP_REQUIRES,
   cmdclass=COMMAND_CLASS,
   tests_require=TESTS_REQUIRE,
   test_suite=TEST_SUITE,
diff --git a/src/python/grpcio_tests/tests/interop/_insecure_interop_test.py b/src/python/grpcio_tests/tests/interop/_insecure_interop_test.py
index c753d6f..936c895 100644
--- a/src/python/grpcio_tests/tests/interop/_insecure_interop_test.py
+++ b/src/python/grpcio_tests/tests/interop/_insecure_interop_test.py
@@ -29,9 +29,10 @@
 
 """Insecure client-server interoperability as a unit test."""
 
+from concurrent import futures
 import unittest
 
-from grpc.beta import implementations
+import grpc
 from src.proto.grpc.testing import test_pb2
 
 from tests.interop import _interop_test_case
@@ -44,14 +45,13 @@
     unittest.TestCase):
 
   def setUp(self):
-    self.server = test_pb2.beta_create_TestService_server(methods.TestService())
+    self.server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
+    test_pb2.add_TestServiceServicer_to_server(
+        methods.TestService(), self.server)
     port = self.server.add_insecure_port('[::]:0')
     self.server.start()
-    self.stub = test_pb2.beta_create_TestService_stub(
-        implementations.insecure_channel('localhost', port))
-
-  def tearDown(self):
-    self.server.stop(0)
+    self.stub = test_pb2.TestServiceStub(
+        grpc.insecure_channel('localhost:{}'.format(port)))
 
 
 if __name__ == '__main__':
diff --git a/src/python/grpcio_tests/tests/interop/_secure_interop_test.py b/src/python/grpcio_tests/tests/interop/_secure_interop_test.py
index cb09f54..eaca553 100644
--- a/src/python/grpcio_tests/tests/interop/_secure_interop_test.py
+++ b/src/python/grpcio_tests/tests/interop/_secure_interop_test.py
@@ -29,17 +29,16 @@
 
 """Secure client-server interoperability as a unit test."""
 
+from concurrent import futures
 import unittest
 
-from grpc.beta import implementations
+import grpc
 from src.proto.grpc.testing import test_pb2
 
 from tests.interop import _interop_test_case
 from tests.interop import methods
 from tests.interop import resources
 
-from tests.unit.beta import test_utilities
-
 _SERVER_HOST_OVERRIDE = 'foo.test.google.fr'
 
 
@@ -48,19 +47,18 @@
     unittest.TestCase):
 
   def setUp(self):
-    self.server = test_pb2.beta_create_TestService_server(methods.TestService())
+    self.server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
+    test_pb2.add_TestServiceServicer_to_server(
+        methods.TestService(), self.server)
     port = self.server.add_secure_port(
-        '[::]:0', implementations.ssl_server_credentials(
+        '[::]:0', grpc.ssl_server_credentials(
             [(resources.private_key(), resources.certificate_chain())]))
     self.server.start()
-    self.stub = test_pb2.beta_create_TestService_stub(
-        test_utilities.not_really_secure_channel(
-            'localhost', port, implementations.ssl_channel_credentials(
-                resources.test_root_certificates()),
-                _SERVER_HOST_OVERRIDE))
-
-  def tearDown(self):
-    self.server.stop(0)
+    self.stub = test_pb2.TestServiceStub(
+        grpc.secure_channel(
+            'localhost:{}'.format(port),
+            grpc.ssl_channel_credentials(resources.test_root_certificates()),
+            (('grpc.ssl_target_name_override', _SERVER_HOST_OVERRIDE,),)))
 
 
 if __name__ == '__main__':
diff --git a/src/python/grpcio_tests/tests/interop/client.py b/src/python/grpcio_tests/tests/interop/client.py
index 8aa1ce3..9d61d18 100644
--- a/src/python/grpcio_tests/tests/interop/client.py
+++ b/src/python/grpcio_tests/tests/interop/client.py
@@ -32,14 +32,12 @@
 import argparse
 from oauth2client import client as oauth2client_client
 
+import grpc
 from grpc.beta import implementations
 from src.proto.grpc.testing import test_pb2
 
 from tests.interop import methods
 from tests.interop import resources
-from tests.unit.beta import test_utilities
-
-_ONE_DAY_IN_SECONDS = 60 * 60 * 24
 
 
 def _args():
@@ -66,41 +64,49 @@
   return parser.parse_args()
 
 
+def _application_default_credentials():
+  return oauth2client_client.GoogleCredentials.get_application_default()
+
+
 def _stub(args):
+  target = '{}:{}'.format(args.server_host, args.server_port)
   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)
+    google_credentials = _application_default_credentials()
+    scoped_credentials = google_credentials.create_scoped([args.oauth_scope])
+    access_token = scoped_credentials.get_access_token().access_token
+    call_credentials = grpc.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)
+    google_credentials = _application_default_credentials()
+    scoped_credentials = google_credentials.create_scoped([args.oauth_scope])
+    # TODO(https://github.com/grpc/grpc/issues/6799): Eliminate this last
+    # remaining use of the Beta API.
+    call_credentials = implementations.google_call_credentials(
+        scoped_credentials)
   elif args.test_case == 'jwt_token_creds':
-    creds = oauth2client_client.GoogleCredentials.get_application_default()
-    call_creds = implementations.google_call_credentials(creds)
+    google_credentials = _application_default_credentials()
+    # TODO(https://github.com/grpc/grpc/issues/6799): Eliminate this last
+    # remaining use of the Beta API.
+    call_credentials = implementations.google_call_credentials(
+        google_credentials)
   else:
-    call_creds = None
+    call_credentials = 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_credentials = grpc.ssl_channel_credentials(root_certificates)
+    if call_credentials is not None:
+      channel_credentials = grpc.composite_channel_credentials(
+          channel_credentials, call_credentials)
 
-    channel = test_utilities.not_really_secure_channel(
-        args.server_host, args.server_port, channel_creds,
-        args.server_host_override)
-    stub = test_pb2.beta_create_TestService_stub(channel)
+    channel = grpc.secure_channel(
+        target, channel_credentials,
+        (('grpc.ssl_target_name_override', args.server_host_override,),))
   else:
-    channel = implementations.insecure_channel(
-        args.server_host, args.server_port)
-    stub = test_pb2.beta_create_TestService_stub(channel)
-  return stub
+    channel = grpc.insecure_channel(target)
+  return test_pb2.TestServiceStub(channel)
 
 
 def _test_case_from_arg(test_case_arg):
diff --git a/src/python/grpcio_tests/tests/interop/methods.py b/src/python/grpcio_tests/tests/interop/methods.py
index 97e6c9e..7edd75c 100644
--- a/src/python/grpcio_tests/tests/interop/methods.py
+++ b/src/python/grpcio_tests/tests/interop/methods.py
@@ -29,8 +29,6 @@
 
 """Implementations of interoperability test methods."""
 
-from __future__ import print_function
-
 import enum
 import json
 import os
@@ -41,26 +39,21 @@
 
 import grpc
 from grpc.beta import implementations
-from grpc.beta import interfaces
-from grpc.framework.common import cardinality
-from grpc.framework.interfaces.face import face
 
 from src.proto.grpc.testing import empty_pb2
 from src.proto.grpc.testing import messages_pb2
 from src.proto.grpc.testing import test_pb2
 
-_TIMEOUT = 7
 
-
-class TestService(test_pb2.BetaTestServiceServicer):
+class TestService(test_pb2.TestServiceServicer):
 
   def EmptyCall(self, request, context):
     return empty_pb2.Empty()
 
   def UnaryCall(self, request, context):
     if request.HasField('response_status'):
-      context.code(request.response_status.code)
-      context.details(request.response_status.message)
+      context.set_code(request.response_status.code)
+      context.set_details(request.response_status.message)
     return messages_pb2.SimpleResponse(
         payload=messages_pb2.Payload(
             type=messages_pb2.COMPRESSABLE,
@@ -68,8 +61,8 @@
 
   def StreamingOutputCall(self, request, context):
     if request.HasField('response_status'):
-      context.code(request.response_status.code)
-      context.details(request.response_status.message)
+      context.set_code(request.response_status.code)
+      context.set_details(request.response_status.message)
     for response_parameters in request.response_parameters:
       yield messages_pb2.StreamingOutputCallResponse(
           payload=messages_pb2.Payload(
@@ -79,7 +72,7 @@
   def StreamingInputCall(self, request_iterator, context):
     aggregate_size = 0
     for request in request_iterator:
-      if request.payload and request.payload.body:
+      if request.payload is not None and request.payload.body:
         aggregate_size += len(request.payload.body)
     return messages_pb2.StreamingInputCallResponse(
         aggregated_payload_size=aggregate_size)
@@ -87,8 +80,8 @@
   def FullDuplexCall(self, request_iterator, context):
     for request in request_iterator:
       if request.HasField('response_status'):
-        context.code(request.response_status.code)
-        context.details(request.response_status.message)
+        context.set_code(request.response_status.code)
+        context.set_details(request.response_status.message)
       for response_parameters in request.response_parameters:
         yield messages_pb2.StreamingOutputCallResponse(
             payload=messages_pb2.Payload(
@@ -101,83 +94,80 @@
     return self.FullDuplexCall(request_iterator, context)
 
 
-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,
-                                            protocol_options=protocol_options)
-    response = response_future.result()
-    if response.payload.type is not messages_pb2.COMPRESSABLE:
-      raise ValueError(
-          'response payload type is "%s"!' % type(response.payload.type))
-    if len(response.payload.body) != 314159:
-      raise ValueError(
-          'response body of incorrect size %d!' % len(response.payload.body))
+def _large_unary_common_behavior(
+    stub, fill_username, fill_oauth_scope, call_credentials):
+  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, credentials=call_credentials)
+  response = response_future.result()
+  if response.payload.type is not messages_pb2.COMPRESSABLE:
+    raise ValueError(
+        'response payload type is "%s"!' % type(response.payload.type))
+  elif len(response.payload.body) != 314159:
+    raise ValueError(
+        'response body of incorrect size %d!' % len(response.payload.body))
+  else:
     return response
 
 
 def _empty_unary(stub):
-  with stub:
-    response = stub.EmptyCall(empty_pb2.Empty(), _TIMEOUT)
-    if not isinstance(response, empty_pb2.Empty):
-      raise TypeError(
-          'response is of type "%s", not empty_pb2.Empty!', type(response))
+  response = stub.EmptyCall(empty_pb2.Empty())
+  if not isinstance(response, empty_pb2.Empty):
+    raise TypeError(
+        'response is of type "%s", not empty_pb2.Empty!', type(response))
 
 
 def _large_unary(stub):
-  _large_unary_common_behavior(stub, False, False)
+  _large_unary_common_behavior(stub, False, False, None)
 
 
 def _client_streaming(stub):
-  with stub:
-    payload_body_sizes = (27182, 8, 1828, 45904)
-    payloads = (
-        messages_pb2.Payload(body=b'\x00' * size)
-        for size in payload_body_sizes)
-    requests = (
-        messages_pb2.StreamingInputCallRequest(payload=payload)
-        for payload in payloads)
-    response = stub.StreamingInputCall(requests, _TIMEOUT)
-    if response.aggregated_payload_size != 74922:
-      raise ValueError(
-          'incorrect size %d!' % response.aggregated_payload_size)
+  payload_body_sizes = (27182, 8, 1828, 45904,)
+  payloads = (
+      messages_pb2.Payload(body=b'\x00' * size)
+      for size in payload_body_sizes)
+  requests = (
+      messages_pb2.StreamingInputCallRequest(payload=payload)
+      for payload in payloads)
+  response = stub.StreamingInputCall(requests)
+  if response.aggregated_payload_size != 74922:
+    raise ValueError(
+        'incorrect size %d!' % response.aggregated_payload_size)
 
 
 def _server_streaming(stub):
-  sizes = (31415, 9, 2653, 58979)
+  sizes = (31415, 9, 2653, 58979,)
 
-  with stub:
-    request = messages_pb2.StreamingOutputCallRequest(
-        response_type=messages_pb2.COMPRESSABLE,
-        response_parameters=(
-            messages_pb2.ResponseParameters(size=sizes[0]),
-            messages_pb2.ResponseParameters(size=sizes[1]),
-            messages_pb2.ResponseParameters(size=sizes[2]),
-            messages_pb2.ResponseParameters(size=sizes[3]),
-        ))
-    response_iterator = stub.StreamingOutputCall(request, _TIMEOUT)
-    for index, response in enumerate(response_iterator):
-      if response.payload.type != messages_pb2.COMPRESSABLE:
-        raise ValueError(
-            'response body of invalid type %s!' % response.payload.type)
-      if len(response.payload.body) != sizes[index]:
-        raise ValueError(
-            'response body of invalid size %d!' % len(response.payload.body))
+  request = messages_pb2.StreamingOutputCallRequest(
+      response_type=messages_pb2.COMPRESSABLE,
+      response_parameters=(
+          messages_pb2.ResponseParameters(size=sizes[0]),
+          messages_pb2.ResponseParameters(size=sizes[1]),
+          messages_pb2.ResponseParameters(size=sizes[2]),
+          messages_pb2.ResponseParameters(size=sizes[3]),
+      )
+  )
+  response_iterator = stub.StreamingOutputCall(request)
+  for index, response in enumerate(response_iterator):
+    if response.payload.type != messages_pb2.COMPRESSABLE:
+      raise ValueError(
+          'response body of invalid type %s!' % response.payload.type)
+    elif len(response.payload.body) != sizes[index]:
+      raise ValueError(
+          'response body of invalid size %d!' % len(response.payload.body))
 
 def _cancel_after_begin(stub):
-  with stub:
-    sizes = (27182, 8, 1828, 45904)
-    payloads = [messages_pb2.Payload(body=b'\x00' * size) for size in sizes]
-    requests = [messages_pb2.StreamingInputCallRequest(payload=payload)
-                for payload in payloads]
-    responses = stub.StreamingInputCall.future(requests, _TIMEOUT)
-    responses.cancel()
-    if not responses.cancelled():
-      raise ValueError('expected call to be cancelled')
+  sizes = (27182, 8, 1828, 45904,)
+  payloads = (messages_pb2.Payload(body=b'\x00' * size) for size in sizes)
+  requests = (messages_pb2.StreamingInputCallRequest(payload=payload)
+              for payload in payloads)
+  response_future = stub.StreamingInputCall.future(requests)
+  response_future.cancel()
+  if not response_future.cancelled():
+    raise ValueError('expected call to be cancelled')
 
 
 class _Pipe(object):
@@ -220,18 +210,17 @@
 
 
 def _ping_pong(stub):
-  request_response_sizes = (31415, 9, 2653, 58979)
-  request_payload_sizes = (27182, 8, 1828, 45904)
+  request_response_sizes = (31415, 9, 2653, 58979,)
+  request_payload_sizes = (27182, 8, 1828, 45904,)
 
-  with stub, _Pipe() as pipe:
-    response_iterator = stub.FullDuplexCall(pipe, _TIMEOUT)
-    print('Starting ping-pong with response iterator %s' % response_iterator)
+  with _Pipe() as pipe:
+    response_iterator = stub.FullDuplexCall(pipe)
     for response_size, payload_size in zip(
         request_response_sizes, request_payload_sizes):
       request = messages_pb2.StreamingOutputCallRequest(
           response_type=messages_pb2.COMPRESSABLE,
-          response_parameters=(messages_pb2.ResponseParameters(
-              size=response_size),),
+          response_parameters=(
+              messages_pb2.ResponseParameters(size=response_size),),
           payload=messages_pb2.Payload(body=b'\x00' * payload_size))
       pipe.add(request)
       response = next(response_iterator)
@@ -244,17 +233,17 @@
 
 
 def _cancel_after_first_response(stub):
-  request_response_sizes = (31415, 9, 2653, 58979)
-  request_payload_sizes = (27182, 8, 1828, 45904)
-  with stub, _Pipe() as pipe:
-    response_iterator = stub.FullDuplexCall(pipe, _TIMEOUT)
+  request_response_sizes = (31415, 9, 2653, 58979,)
+  request_payload_sizes = (27182, 8, 1828, 45904,)
+  with _Pipe() as pipe:
+    response_iterator = stub.FullDuplexCall(pipe)
 
     response_size = request_response_sizes[0]
     payload_size = request_payload_sizes[0]
     request = messages_pb2.StreamingOutputCallRequest(
         response_type=messages_pb2.COMPRESSABLE,
-        response_parameters=(messages_pb2.ResponseParameters(
-            size=response_size),),
+        response_parameters=(
+            messages_pb2.ResponseParameters(size=response_size),),
         payload=messages_pb2.Payload(body=b'\x00' * payload_size))
     pipe.add(request)
     response = next(response_iterator)
@@ -264,16 +253,17 @@
 
     try:
       next(response_iterator)
-    except Exception:
-      pass
+    except grpc.RpcError as rpc_error:
+      if rpc_error.code() is not grpc.StatusCode.CANCELLED:
+        raise
     else:
       raise ValueError('expected call to be cancelled')
 
 
 def _timeout_on_sleeping_server(stub):
   request_payload_size = 27182
-  with stub, _Pipe() as pipe:
-    response_iterator = stub.FullDuplexCall(pipe, 0.001)
+  with _Pipe() as pipe:
+    response_iterator = stub.FullDuplexCall(pipe, timeout=0.001)
 
     request = messages_pb2.StreamingOutputCallRequest(
         response_type=messages_pb2.COMPRESSABLE,
@@ -282,15 +272,16 @@
     time.sleep(0.1)
     try:
       next(response_iterator)
-    except face.ExpirationError:
-      pass
+    except grpc.RpcError as rpc_error:
+      if rpc_error.code() is not grpc.StatusCode.DEADLINE_EXCEEDED:
+        raise
     else:
       raise ValueError('expected call to exceed deadline')
 
 
 def _empty_stream(stub):
-  with stub, _Pipe() as pipe:
-    response_iterator = stub.FullDuplexCall(pipe, _TIMEOUT)
+  with _Pipe() as pipe:
+    response_iterator = stub.FullDuplexCall(pipe)
     pipe.close()
     try:
       next(response_iterator)
@@ -300,65 +291,64 @@
 
 
 def _status_code_and_message(stub):
-  with stub:
-    message = 'test status message'
-    code = 2
-    status = grpc.StatusCode.UNKNOWN # code = 2
-    request = messages_pb2.SimpleRequest(
-        response_type=messages_pb2.COMPRESSABLE,
-        response_size=1,
-        payload=messages_pb2.Payload(body=b'\x00'),
-        response_status=messages_pb2.EchoStatus(code=code, message=message)
-        )
-    response_future = stub.UnaryCall.future(request, _TIMEOUT)
-    if response_future.code() != status:
-      raise ValueError(
-        'expected code %s, got %s' % (status, response_future.code()))
-    if response_future.details() != message:
-      raise ValueError(
-        'expected message %s, got %s' % (message, response_future.details()))
+  message = 'test status message'
+  code = 2
+  status = grpc.StatusCode.UNKNOWN # code = 2
+  request = messages_pb2.SimpleRequest(
+      response_type=messages_pb2.COMPRESSABLE,
+      response_size=1,
+      payload=messages_pb2.Payload(body=b'\x00'),
+      response_status=messages_pb2.EchoStatus(code=code, message=message)
+  )
+  response_future = stub.UnaryCall.future(request)
+  if response_future.code() != status:
+    raise ValueError(
+      'expected code %s, got %s' % (status, response_future.code()))
+  elif response_future.details() != message:
+    raise ValueError(
+      'expected message %s, got %s' % (message, response_future.details()))
 
-    request = messages_pb2.StreamingOutputCallRequest(
-        response_type=messages_pb2.COMPRESSABLE,
-        response_parameters=(
-            messages_pb2.ResponseParameters(size=1),),
-        response_status=messages_pb2.EchoStatus(code=code, message=message))
-    response_iterator = stub.StreamingOutputCall(request, _TIMEOUT)
-    if response_future.code() != status:
-      raise ValueError(
-        'expected code %s, got %s' % (status, response_iterator.code()))
-    if response_future.details() != message:
-      raise ValueError(
-        'expected message %s, got %s' % (message, response_iterator.details()))
+  request = messages_pb2.StreamingOutputCallRequest(
+      response_type=messages_pb2.COMPRESSABLE,
+      response_parameters=(
+          messages_pb2.ResponseParameters(size=1),),
+      response_status=messages_pb2.EchoStatus(code=code, message=message))
+  response_iterator = stub.StreamingOutputCall(request)
+  if response_future.code() != status:
+    raise ValueError(
+      'expected code %s, got %s' % (status, response_iterator.code()))
+  elif response_future.details() != message:
+    raise ValueError(
+      'expected message %s, got %s' % (message, response_iterator.details()))
 
 
 def _compute_engine_creds(stub, args):
-  response = _large_unary_common_behavior(stub, True, True)
+  response = _large_unary_common_behavior(stub, True, True, None)
   if args.default_service_account != response.username:
     raise ValueError(
-        'expected username %s, got %s' % (args.default_service_account,
-                                          response.username))
+        'expected username %s, got %s' % (
+            args.default_service_account, response.username))
 
 
 def _oauth2_auth_token(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, True)
+  response = _large_unary_common_behavior(stub, True, True, None)
   if wanted_email != response.username:
     raise ValueError(
         'expected username %s, got %s' % (wanted_email, response.username))
   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))
+        'expected to find oauth scope "{}" in received "{}"'.format(
+            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)
+  response = _large_unary_common_behavior(stub, True, False, None)
   if wanted_email != response.username:
     raise ValueError(
         'expected username %s, got %s' % (wanted_email, response.username))
@@ -370,11 +360,11 @@
   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)
+  # TODO(https://github.com/grpc/grpc/issues/6799): Eliminate this last
+  # remaining use of the Beta API.
+  call_credentials = implementations.google_call_credentials(
+      scoped_credentials)
+  response = _large_unary_common_behavior(stub, True, False, call_credentials)
   if wanted_email != response.username:
     raise ValueError(
         'expected username %s, got %s' % (wanted_email, response.username))
diff --git a/src/python/grpcio_tests/tests/interop/server.py b/src/python/grpcio_tests/tests/interop/server.py
index ab2c3c7..1ae83bc 100644
--- a/src/python/grpcio_tests/tests/interop/server.py
+++ b/src/python/grpcio_tests/tests/interop/server.py
@@ -30,10 +30,11 @@
 """The Python implementation of the GRPC interoperability test server."""
 
 import argparse
+from concurrent import futures
 import logging
 import time
 
-from grpc.beta import implementations
+import grpc
 from src.proto.grpc.testing import test_pb2
 
 from tests.interop import methods
@@ -51,12 +52,13 @@
       default=False, type=resources.parse_bool)
   args = parser.parse_args()
 
-  server = test_pb2.beta_create_TestService_server(methods.TestService())
+  server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
+  test_pb2.add_TestServiceServicer_to_server(methods.TestService(), server)
   if args.use_tls:
     private_key = resources.private_key()
     certificate_chain = resources.certificate_chain()
-    credentials = implementations.ssl_server_credentials(
-        [(private_key, certificate_chain)])
+    credentials = grpc.ssl_server_credentials(
+        ((private_key, certificate_chain),))
     server.add_secure_port('[::]:{}'.format(args.port), credentials)
   else:
     server.add_insecure_port('[::]:{}'.format(args.port))
@@ -68,7 +70,7 @@
       time.sleep(_ONE_DAY_IN_SECONDS)
   except BaseException as e:
     logging.info('Caught exception "%s"; stopping server...', e)
-    server.stop(0)
+    server.stop(None)
     logging.info('Server stopped; exiting.')
 
 if __name__ == '__main__':
diff --git a/src/python/grpcio_tests/tests/stress/client.py b/src/python/grpcio_tests/tests/stress/client.py
index 0de2532..975f33b 100644
--- a/src/python/grpcio_tests/tests/stress/client.py
+++ b/src/python/grpcio_tests/tests/stress/client.py
@@ -30,9 +30,10 @@
 """Entry point for running stress tests."""
 
 import argparse
+from concurrent import futures
 import threading
 
-from grpc.beta import implementations
+import grpc
 from six.moves import queue
 from src.proto.grpc.testing import metrics_pb2
 from src.proto.grpc.testing import test_pb2
@@ -92,24 +93,24 @@
 
 def run_test(args):
   test_cases = _parse_weighted_test_cases(args.test_cases)
-  test_servers = args.server_addresses.split(',')
+  test_server_targets = args.server_addresses.split(',')
   # Propagate any client exceptions with a queue
   exception_queue = queue.Queue()
   stop_event = threading.Event()
   hist = histogram.Histogram(1, 1)
   runners = []
 
-  server = metrics_pb2.beta_create_MetricsService_server(
-      metrics_server.MetricsServer(hist))
+  server = grpc.server(futures.ThreadPoolExecutor(max_workers=25))
+  metrics_pb2.add_MetricsServiceServicer_to_server(
+      metrics_server.MetricsServer(hist), server)
   server.add_insecure_port('[::]:{}'.format(args.metrics_port))
   server.start()
 
-  for test_server in test_servers:
-    host, port = test_server.split(':', 1)
+  for test_server_target in test_server_targets:
     for _ in xrange(args.num_channels_per_server):
-      channel = implementations.insecure_channel(host, int(port))
+      channel = grpc.insecure_channel(test_server_target)
       for _ in xrange(args.num_stubs_per_channel):
-        stub = test_pb2.beta_create_TestService_stub(channel)
+        stub = test_pb2.TestServiceStub(channel)
         runner = test_runner.TestRunner(stub, test_cases, hist,
                                         exception_queue, stop_event)
         runners.append(runner)
@@ -128,8 +129,8 @@
     stop_event.set()
     for runner in runners:
       runner.join()
-      runner = None
-    server.stop(0)
+    runner = None
+    server.stop(None)
 
 if __name__ == '__main__':
   run_test(_args())
diff --git a/src/python/grpcio_tests/tests/stress/metrics_server.py b/src/python/grpcio_tests/tests/stress/metrics_server.py
index b994e46..33dd1d6 100644
--- a/src/python/grpcio_tests/tests/stress/metrics_server.py
+++ b/src/python/grpcio_tests/tests/stress/metrics_server.py
@@ -36,7 +36,7 @@
 GAUGE_NAME = 'python_overall_qps'
 
 
-class MetricsServer(metrics_pb2.BetaMetricsServiceServicer):
+class MetricsServer(metrics_pb2.MetricsServiceServicer):
 
   def __init__(self, histogram):
     self._start_time = time.time()
diff --git a/src/ruby/lib/grpc/generic/bidi_call.rb b/src/ruby/lib/grpc/generic/bidi_call.rb
index 196f84f..d7cd9e6 100644
--- a/src/ruby/lib/grpc/generic/bidi_call.rb
+++ b/src/ruby/lib/grpc/generic/bidi_call.rb
@@ -62,7 +62,6 @@
       @call = call
       @marshal = marshal
       @op_notifier = nil  # signals completion on clients
-      @readq = Queue.new
       @unmarshal = unmarshal
       @metadata_received = metadata_received
       @reads_complete = false
@@ -83,8 +82,7 @@
     def run_on_client(requests, op_notifier, &blk)
       @op_notifier = op_notifier
       @enq_th = Thread.new { write_loop(requests) }
-      @loop_th = start_read_loop
-      each_queued_msg(&blk)
+      read_loop(&blk)
     end
 
     # Begins orchestration of the Bidi stream for a server generating replies.
@@ -101,14 +99,13 @@
     def run_on_server(gen_each_reply)
       # Pass in the optional call object parameter if possible
       if gen_each_reply.arity == 1
-        replys = gen_each_reply.call(each_queued_msg)
+        replys = gen_each_reply.call(read_loop(is_client: false))
       elsif gen_each_reply.arity == 2
-        replys = gen_each_reply.call(each_queued_msg, @req_view)
+        replys = gen_each_reply.call(read_loop(is_client: false), @req_view)
       else
         fail 'Illegal arity of reply generator'
       end
 
-      @loop_th = start_read_loop(is_client: false)
       write_loop(replys, is_client: false)
     end
 
@@ -145,24 +142,6 @@
       batch_result
     end
 
-    # each_queued_msg yields each message on this instances readq
-    #
-    # - messages are added to the readq by #read_loop
-    # - iteration ends when the instance itself is added
-    def each_queued_msg
-      return enum_for(:each_queued_msg) unless block_given?
-      count = 0
-      loop do
-        GRPC.logger.debug("each_queued_msg: waiting##{count}")
-        count += 1
-        req = @readq.pop
-        GRPC.logger.debug("each_queued_msg: req = #{req}")
-        fail req if req.is_a? StandardError
-        break if req.equal?(END_OF_READS)
-        yield req
-      end
-    end
-
     def write_loop(requests, is_client: true)
       GRPC.logger.debug('bidi-write-loop: starting')
       count = 0
@@ -201,47 +180,45 @@
       raise e
     end
 
-    # starts the read loop
-    def start_read_loop(is_client: true)
-      Thread.new do
-        GRPC.logger.debug('bidi-read-loop: starting')
-        begin
-          count = 0
-          # queue the initial read before beginning the loop
-          loop do
-            GRPC.logger.debug("bidi-read-loop: #{count}")
-            count += 1
-            batch_result = read_using_run_batch
+    # Provides an enumerator that yields results of remote reads
+    def read_loop(is_client: true)
+      return enum_for(:read_loop,
+                      is_client: is_client) unless block_given?
+      GRPC.logger.debug('bidi-read-loop: starting')
+      begin
+        count = 0
+        # queue the initial read before beginning the loop
+        loop do
+          GRPC.logger.debug("bidi-read-loop: #{count}")
+          count += 1
+          batch_result = read_using_run_batch
 
-            # handle the next message
-            if batch_result.message.nil?
-              GRPC.logger.debug("bidi-read-loop: null batch #{batch_result}")
+          # handle the next message
+          if batch_result.message.nil?
+            GRPC.logger.debug("bidi-read-loop: null batch #{batch_result}")
 
-              if is_client
-                batch_result = @call.run_batch(RECV_STATUS_ON_CLIENT => nil)
-                @call.status = batch_result.status
-                batch_result.check_status
-                GRPC.logger.debug("bidi-read-loop: done status #{@call.status}")
-              end
-
-              @readq.push(END_OF_READS)
-              GRPC.logger.debug('bidi-read-loop: done reading!')
-              break
+            if is_client
+              batch_result = @call.run_batch(RECV_STATUS_ON_CLIENT => nil)
+              @call.status = batch_result.status
+              batch_result.check_status
+              GRPC.logger.debug("bidi-read-loop: done status #{@call.status}")
             end
 
-            # push the latest read onto the queue and continue reading
-            res = @unmarshal.call(batch_result.message)
-            @readq.push(res)
+            GRPC.logger.debug('bidi-read-loop: done reading!')
+            break
           end
-        rescue StandardError => e
-          GRPC.logger.warn('bidi: read-loop failed')
-          GRPC.logger.warn(e)
-          @readq.push(e)  # let each_queued_msg terminate with this error
+
+          res = @unmarshal.call(batch_result.message)
+          yield res
         end
-        GRPC.logger.debug('bidi-read-loop: finished')
-        @reads_complete = true
-        finished
+      rescue StandardError => e
+        GRPC.logger.warn('bidi: read-loop failed')
+        GRPC.logger.warn(e)
+        raise e
       end
+      GRPC.logger.debug('bidi-read-loop: finished')
+      @reads_complete = true
+      finished
     end
   end
 end
diff --git a/summerofcode/2016/siddharth_shukla.md b/summerofcode/2016/siddharth_shukla.md
new file mode 100644
index 0000000..d753d8b
--- /dev/null
+++ b/summerofcode/2016/siddharth_shukla.md
@@ -0,0 +1,65 @@
+Project Overview
+================
+The project, titled 'GRPC Python compatibility support', involved 
+collaborating with the GRPC team to improve the library compatibility 
+for the GRPC Python library.
+
+Python is, originally, a specification for a programming language. This
+specification has been implemented differently in different
+implementations of the [language specification](https://docs.python.org/3/reference/). 
+
+A small, and by no means exhaustive, list of some major python implementations
+is:
+
+- [CPython](https://www.python.org/): The reference implementation
+- [Jython](http://www.jython.org/): Python implemented in Java
+- [Python for .NET](http://pythonnet.sourceforge.net/): CPython implementation that enables .NET library usage
+- [IronPython](http://ironpython.net/): Python implemented in .NET
+- [PyPy](http://pypy.org/): Python implemented completely in Python
+- [Stackless](https://bitbucket.org/stackless-dev/stackless/wiki/Home): Replaces the dependency for the C call stack with it's own stack
+
+The development in this project revolved around
+introducing changes to the codebase that enable support for latest 
+stable as well as development releases of the reference implementation 
+(CPython) of the Python programming language namely `Python 3.4`,
+`Python 3.5`,and `Python 3.6` as well as the stable releases of the 
+PyPy implementation. Special changes were required to enable PyPy 
+support because PyPy has a non-deterministic garbage collector that does
+not rely on reference counting unlike the CPython garbage collector.
+
+The changes to the codebase involved changes to the library code as well
+as changes to the tests and scripts in the test infrastructure which
+resulted in both the library as well as the testing infrastructure being
+Python 3.x and PyPy compatible.
+
+The list of merged commits, as of 22.08.2016 23:59 CEST,  is summarized 
+here for the perusal of those interested:
+
+- [Enable py35 and py36 testing](https://github.com/grpc/grpc/commit/c478214e475e103c5cdf477f0adc18bba2c03903)
+- [Make testing toolchain python 3.x compliant](https://github.com/grpc/grpc/commit/0589e533cd65a2ca9e0e610cc1b284d016986572)
+- [Add .idea folder to .gitignore](https://github.com/grpc/grpc/commit/365ef40947e22b5438a63f123679ae9a5474c47c)
+- [Fix the ThreadPoolExecutor: max_workers can't be 0](https://github.com/grpc/grpc/commit/de84d566b8fad6808e5263a25a17fa231cb5713c)
+- [Add PyPy to testing toolchain](https://github.com/grpc/grpc/commit/2135a1b557f8b992186d5317cb767ac4dbcdfe5c)
+- [Switch init/shutdown: lib-wide -> per-object](https://github.com/grpc/grpc/commit/9eedb4ffd74aed8d246a07f8007960b2bc167f55)
+- [Skip test run if running with pypy](https://github.com/grpc/grpc/commit/f0f58e68738abbc317f7f449c5104f7fbbff26bd)
+
+The list of unmerged pull requests is as follows:
+
+- [Add PyPy 5.3.1 to dockerfile and template](https://github.com/grpc/grpc/pull/7763)
+- [remove skipIf from TypeSmokeTest (issue 7672)](https://github.com/grpc/grpc/pull/7831)
+  
+The list of tasks that have pending unsubmitted pull requests is as follows:
+
+- Modify run_tests.py to enable testing of new languages without
+  affecting old branches.
+
+
+Project Details
+===============
+- Title: GRPC Python compatibility support
+- Student: [Siddharth Shukla](https://github.com/thunderboltsid)
+- Mentors: [Nathaniel Manista](https://github.com/nathanielmanistaatgoogle), [Masood Malekghassemi](https://github.com/soltanmm)
+- Duration: May 23 - August 23
+- Hat tip: [Ken Payson](https://github.com/kpayson64), [Jan Tattermusch](https://github.com/jtattermusch), [Nicolas Noble](https://github.com/nicolasnoble)
+
+
diff --git a/templates/BUILD.template b/templates/BUILD.template
index 23a656c..af23fb2 100644
--- a/templates/BUILD.template
+++ b/templates/BUILD.template
@@ -38,6 +38,8 @@
   
   licenses(["notice"])  # 3-clause BSD
   
+  exports_files(["LICENSE"])
+  
   package(default_visibility = ["//visibility:public"])
   
   <%!
diff --git a/templates/CMakeLists.txt.template b/templates/CMakeLists.txt.template
index 4e42234..2b6c0b1 100644
--- a/templates/CMakeLists.txt.template
+++ b/templates/CMakeLists.txt.template
@@ -66,6 +66,12 @@
   set(PACKAGE_BUGREPORT "https://github.com/grpc/grpc/issues/")
   project(<%text>${PACKAGE_NAME}</%text> C CXX)
 
+  if (NOT MSVC)
+    set(gRPC_INSTALL ON CACHE BOOL "Generate installation target")
+  else()
+    set(gRPC_INSTALL OFF CACHE BOOL "Generate installation target")
+  endif()
+
   set(gRPC_ZLIB_PROVIDER "module" CACHE STRING "Provider of zlib library")
   set_property(CACHE gRPC_ZLIB_PROVIDER PROPERTY STRINGS "module" "package")
 
@@ -77,6 +83,10 @@
 
   set(gRPC_USE_PROTO_LITE OFF CACHE BOOL "Use the protobuf-lite library")
 
+  if (MSVC)
+    add_definitions( -D_WIN32_WINNT=0x600 )
+  endif()
+
   if (gRPC_USE_PROTO_LITE)
     set(_gRPC_PROTOBUF_LIBRARY_NAME "libprotobuf-lite")
     add_definitions("-DGRPC_USE_PROTO_LITE")
@@ -116,6 +126,7 @@
       set(PROTOBUF_ROOT_DIR <%text>${CMAKE_CURRENT_SOURCE_DIR}</%text>/third_party/protobuf)
     endif()
     if(EXISTS "<%text>${PROTOBUF_ROOT_DIR}</%text>/cmake/CMakeLists.txt")
+      set(protobuf_MSVC_STATIC_RUNTIME OFF CACHE BOOL "Link static runtime libraries")
       add_subdirectory(<%text>${PROTOBUF_ROOT_DIR}</%text>/cmake third_party/protobuf)
       if(TARGET <%text>${_gRPC_PROTOBUF_LIBRARY_NAME}</%text>)
         set(_gRPC_PROTOBUF_LIBRARIES <%text>${_gRPC_PROTOBUF_LIBRARY_NAME}</%text>)
@@ -255,17 +266,21 @@
   </%def>
 
   <%def name="cc_install(tgt)">
-  install(TARGETS ${tgt.name} EXPORT gRPCTargets
-    RUNTIME DESTINATION <%text>${CMAKE_INSTALL_BINDIR}</%text>
-    LIBRARY DESTINATION <%text>${CMAKE_INSTALL_LIBDIR}</%text>
-    ARCHIVE DESTINATION <%text>${CMAKE_INSTALL_LIBDIR}</%text>
-  )
+  if (gRPC_INSTALL)
+    install(TARGETS ${tgt.name} EXPORT gRPCTargets
+      RUNTIME DESTINATION <%text>${CMAKE_INSTALL_BINDIR}</%text>
+      LIBRARY DESTINATION <%text>${CMAKE_INSTALL_LIBDIR}</%text>
+      ARCHIVE DESTINATION <%text>${CMAKE_INSTALL_LIBDIR}</%text>
+    )
+  endif()
   </%def>
 
-  install(EXPORT gRPCTargets
-    DESTINATION <%text>${CMAKE_INSTALL_CMAKEDIR}</%text>
-    NAMESPACE gRPC::
-  )
+  if (gRPC_INSTALL)
+    install(EXPORT gRPCTargets
+      DESTINATION <%text>${CMAKE_INSTALL_CMAKEDIR}</%text>
+      NAMESPACE gRPC::
+    )
+  endif()
 
   foreach(_config gRPCConfig gRPCConfigVersion)
     configure_file(tools/cmake/<%text>${_config}</%text>.cmake.in
diff --git a/templates/Makefile.template b/templates/Makefile.template
index 9afc656..e6a28d1 100644
--- a/templates/Makefile.template
+++ b/templates/Makefile.template
@@ -380,7 +380,7 @@
   OPENSSL_ALPN_CHECK_CMD = $(PKG_CONFIG) --atleast-version=1.0.2 openssl
   OPENSSL_NPN_CHECK_CMD = $(PKG_CONFIG) --atleast-version=1.0.1 openssl
   ZLIB_CHECK_CMD = $(PKG_CONFIG) --exists zlib
-  PROTOBUF_CHECK_CMD = $(PKG_CONFIG) --atleast-version=3.0.0-alpha-3 protobuf
+  PROTOBUF_CHECK_CMD = $(PKG_CONFIG) --atleast-version=3.0.0 protobuf
   else # HAS_PKG_CONFIG
 
   ifeq ($(SYSTEM),MINGW32)
@@ -694,13 +694,6 @@
   NO_DEPS = true
   endif
 
-  INSTALL_OK = false
-  ifeq ($(HAS_VALID_PROTOC),true)
-  ifeq ($(HAS_SYSTEM_PROTOBUF_VERIFY),true)
-  INSTALL_OK = true
-  endif
-  endif
-
   .SECONDARY = %.pb.h %.pb.cc
 
   ifeq ($(DEP_MISSING),)
@@ -1193,7 +1186,7 @@
   	$(Q) mkdir -p `dirname $@`
   	$(Q) $(CXX) $(CPPFLAGS) $(CXXFLAGS) -MMD -MF $(addsuffix .dep, $(basename $@)) -c -o $@ $<
 
-  install: install_c install_cxx install-plugins install-certs verify-install
+  install: install_c install_cxx install-plugins install-certs
 
   install_c: install-headers_c install-static_c install-shared_c
 
@@ -1311,28 +1304,6 @@
   	$(Q) $(INSTALL) -d $(prefix)/share/grpc
   	$(Q) $(INSTALL) etc/roots.pem $(prefix)/share/grpc/roots.pem
 
-  verify-install:
-  ifeq ($(INSTALL_OK),true)
-  	@echo "Your system looks ready to go."
-  	@echo
-  else
-  	@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 "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, you can re-run this check by doing:"
-  	@echo
-  	@echo "   make verify-install"
-  endif
-
   clean:
   	$(E) "[CLEAN]   Cleaning build directories."
   	$(Q) $(RM) -rf $(OBJDIR) $(LIBDIR) $(BINDIR) $(GENDIR) cache.mk
diff --git a/templates/gRPC-Core.podspec.template b/templates/gRPC-Core.podspec.template
index 644dc4a..1d5a473 100644
--- a/templates/gRPC-Core.podspec.template
+++ b/templates/gRPC-Core.podspec.template
@@ -62,7 +62,7 @@
   %>
   Pod::Spec.new do |s|
     s.name     = 'gRPC-Core'
-    version = '1.0.0-pre1'
+    version = '1.0.0'
     s.version  = version
     s.summary  = 'Core cross-platform gRPC library, written in C'
     s.homepage = 'http://www.grpc.io'
@@ -71,7 +71,7 @@
 
     s.source = {
       :git => 'https://github.com/grpc/grpc.git',
-      :tag => "objective-c-v#{version}",
+      :tag => "v#{version}",
       # TODO(jcanizales): Depend explicitly on the nanopb pod, and disable submodules.
       :submodules => true,
     }
@@ -149,7 +149,7 @@
       ss.header_mappings_dir = '.'
       ss.libraries = 'z'
       ss.dependency "#{s.name}/Interface", version
-      ss.dependency 'BoringSSL', '~> 5.0'
+      ss.dependency 'BoringSSL', '~> 6.0'
 
       # To save you from scrolling, this is the last part of the podspec.
       ss.source_files = ${ruby_multiline_list(grpc_private_files(libs), 22)}
diff --git a/templates/grpc.gemspec.template b/templates/grpc.gemspec.template
index ce775ff..f95adaf 100644
--- a/templates/grpc.gemspec.template
+++ b/templates/grpc.gemspec.template
@@ -29,7 +29,7 @@
     s.require_paths = %w( src/ruby/bin src/ruby/lib src/ruby/pb )
     s.platform      = Gem::Platform::RUBY
 
-    s.add_dependency 'google-protobuf', '~> 3.0.0.alpha.5.0.3'
+    s.add_dependency 'google-protobuf', '~> 3.0'
     s.add_dependency 'googleauth',      '~> 0.5.1'
 
     s.add_development_dependency 'bundler',            '~> 1.9'
diff --git a/templates/package.json.template b/templates/package.json.template
index f68f64d..e9596d4 100644
--- a/templates/package.json.template
+++ b/templates/package.json.template
@@ -37,7 +37,7 @@
     "devDependencies": {
       "async": "^1.5.0",
       "google-auth-library": "^0.9.2",
-      "google-protobuf": "^3.0.0-alpha.5",
+      "google-protobuf": "^3.0.0",
       "istanbul": "^0.3.21",
       "jsdoc": "^3.3.2",
       "jshint": "^2.5.0",
diff --git a/templates/package.xml.template b/templates/package.xml.template
index 87b1038..65fef18 100644
--- a/templates/package.xml.template
+++ b/templates/package.xml.template
@@ -12,7 +12,7 @@
     <email>grpc-packages@google.com</email>
     <active>yes</active>
    </lead>
-   <date>2016-07-28</date>
+   <date>2016-08-22</date>
    <time>16:06:07</time>
    <version>
     <release>${settings.php_version.php()}</release>
@@ -24,7 +24,7 @@
    </stability>
    <license>BSD</license>
    <notes>
-  - PHP7 Support continued, reduce code duplication #7543
+  - TBD
    </notes>
    <contents>
     <dir baseinstalldir="/" name="/">
@@ -249,5 +249,50 @@
   - PHP7 Support continued, reduce code duplication #7543
      </notes>
     </release>
+    <release>
+     <version>
+      <release>1.0.0RC4</release>
+      <api>1.0.0RC4</api>
+     </version>
+     <stability>
+      <release>stable</release>
+      <api>stable</api>
+     </stability>
+     <date>2016-08-09</date>
+     <license>BSD</license>
+     <notes>
+  - Fixed Ubuntu compile error #7571, #7642
+     </notes>
+    </release>
+    <release>
+     <version>
+      <release>1.0.0</release>
+      <api>1.0.0</api>
+     </version>
+     <stability>
+      <release>stable</release>
+      <api>stable</api>
+     </stability>
+     <date>2016-08-18</date>
+     <license>BSD</license>
+     <notes>
+  - gRPC 1.0.0 release
+     </notes>
+    </release>
+    <release>
+     <version>
+      <release>${settings.php_version.php()}</release>
+      <api>${settings.php_version.php()}</api>
+     </version>
+     <stability>
+      <release>stable</release>
+      <api>stable</api>
+     </stability>
+     <date>2016-08-22</date>
+     <license>BSD</license>
+     <notes>
+  - TBD
+     </notes>
+    </release>
    </changelog>
   </package>
diff --git a/templates/src/csharp/Grpc.Auth/project.json.template b/templates/src/csharp/Grpc.Auth/project.json.template
index b3244e4..19d4b42 100644
--- a/templates/src/csharp/Grpc.Auth/project.json.template
+++ b/templates/src/csharp/Grpc.Auth/project.json.template
@@ -25,13 +25,13 @@
     },
     "dependencies": {
       "Grpc.Core": "${settings.csharp_version}",
-      "Google.Apis.Auth": "1.11.1"
+      "Google.Apis.Auth": "1.15.0"
     },
     "frameworks": {
       "net45": { },
       "netstandard1.5": {
         "imports": [
-          "net45"
+          "portable-net45"
         ],
         "dependencies": {
           "Microsoft.NETCore.Portable.Compatibility": "1.0.1",
diff --git a/templates/src/csharp/Grpc.Examples.MathClient/project.json.template b/templates/src/csharp/Grpc.Examples.MathClient/project.json.template
index 51c5e85..67151db 100644
--- a/templates/src/csharp/Grpc.Examples.MathClient/project.json.template
+++ b/templates/src/csharp/Grpc.Examples.MathClient/project.json.template
@@ -1,7 +1,7 @@
 %YAML 1.2
 --- |
   {
-    <%include file="../build_options.include" args="executable=True,includeRuntimes=False"/>
+    <%include file="../build_options.include" args="executable=True"/>
     "dependencies": {
       "Grpc.Examples": {
         "target": "project"
diff --git a/templates/src/csharp/Grpc.Examples.MathServer/project.json.template b/templates/src/csharp/Grpc.Examples.MathServer/project.json.template
index 51c5e85..67151db 100644
--- a/templates/src/csharp/Grpc.Examples.MathServer/project.json.template
+++ b/templates/src/csharp/Grpc.Examples.MathServer/project.json.template
@@ -1,7 +1,7 @@
 %YAML 1.2
 --- |
   {
-    <%include file="../build_options.include" args="executable=True,includeRuntimes=False"/>
+    <%include file="../build_options.include" args="executable=True"/>
     "dependencies": {
       "Grpc.Examples": {
         "target": "project"
diff --git a/templates/src/csharp/Grpc.Examples/project.json.template b/templates/src/csharp/Grpc.Examples/project.json.template
index d5d63f6..117f842 100644
--- a/templates/src/csharp/Grpc.Examples/project.json.template
+++ b/templates/src/csharp/Grpc.Examples/project.json.template
@@ -15,11 +15,12 @@
           "System.IO": ""
         }
       },
-      "netstandard1.5": {
+      "netcoreapp1.0": {
         "imports": [
           "portable-net45"
         ],
         "dependencies": {
+          "Microsoft.NETCore.App": "1.0.0",
           "NETStandard.Library": "1.6.0"
         }
       }
diff --git a/templates/src/csharp/Grpc.IntegrationTesting.QpsWorker/project.json.template b/templates/src/csharp/Grpc.IntegrationTesting.QpsWorker/project.json.template
index af1ee42..93151f2 100644
--- a/templates/src/csharp/Grpc.IntegrationTesting.QpsWorker/project.json.template
+++ b/templates/src/csharp/Grpc.IntegrationTesting.QpsWorker/project.json.template
@@ -1,7 +1,7 @@
 %YAML 1.2
 --- |
   {
-    <%include file="../build_options.include" args="executable=True,includeData=True,includeRuntimes=False"/>
+    <%include file="../build_options.include" args="executable=True,includeData=True"/>
     "dependencies": {
       "Grpc.IntegrationTesting": {
         "target": "project"
diff --git a/templates/src/csharp/Grpc.IntegrationTesting.StressClient/project.json.template b/templates/src/csharp/Grpc.IntegrationTesting.StressClient/project.json.template
index af1ee42..93151f2 100644
--- a/templates/src/csharp/Grpc.IntegrationTesting.StressClient/project.json.template
+++ b/templates/src/csharp/Grpc.IntegrationTesting.StressClient/project.json.template
@@ -1,7 +1,7 @@
 %YAML 1.2
 --- |
   {
-    <%include file="../build_options.include" args="executable=True,includeData=True,includeRuntimes=False"/>
+    <%include file="../build_options.include" args="executable=True,includeData=True"/>
     "dependencies": {
       "Grpc.IntegrationTesting": {
         "target": "project"
diff --git a/templates/src/csharp/Grpc.IntegrationTesting/project.json.template b/templates/src/csharp/Grpc.IntegrationTesting/project.json.template
index 0a7d5e9..1cb5ca4 100644
--- a/templates/src/csharp/Grpc.IntegrationTesting/project.json.template
+++ b/templates/src/csharp/Grpc.IntegrationTesting/project.json.template
@@ -10,7 +10,7 @@
         "target": "project"
       },
       "Google.Protobuf": "3.0.0-beta3",
-      "CommandLineParser": "1.9.71",
+      "CommandLineParser.Unofficial": "2.0.275",
       "NUnit": "3.2.0",
       "NUnitLite": "3.2.0-*"
     },
diff --git a/templates/src/csharp/build_options.include b/templates/src/csharp/build_options.include
index a200897..8597ae3 100644
--- a/templates/src/csharp/build_options.include
+++ b/templates/src/csharp/build_options.include
@@ -1,4 +1,4 @@
-<%page args="executable=False,includeData=False,includeRuntimes=True"/>\
+<%page args="executable=False,includeData=False"/>\
 "buildOptions": {
   % if executable:
     "emitEntryPoint": true
@@ -52,10 +52,8 @@
     }
   },
   %endif
-  % if includeRuntimes:
   "runtimes": {
     "win7-x64": { },
     "debian.8-x64": { },
     "osx.10.11-x64": { }
   },
-  % endif
\ No newline at end of file
diff --git a/templates/src/csharp/build_packages.bat.template b/templates/src/csharp/build_packages.bat.template
index ea2acb6..5cbd8e3 100644
--- a/templates/src/csharp/build_packages.bat.template
+++ b/templates/src/csharp/build_packages.bat.template
@@ -33,10 +33,7 @@
   
   @rem Current package versions
   set VERSION=${settings.csharp_version}
-  set PROTOBUF_VERSION=3.0.0-beta3
-  
-  @rem Packages that depend on prerelease packages (like Google.Protobuf) need to have prerelease suffix as well.
-  set VERSION_WITH_BETA=%VERSION%-beta
+  set PROTOBUF_VERSION=3.0.0
   
   @rem Adjust the location of nuget.exe
   set NUGET=C:\nuget\nuget.exe
@@ -60,7 +57,6 @@
   
   @rem Fetch all dependencies
   %%NUGET% restore ..\..\vsprojects\grpc_csharp_ext.sln || goto :error
-  %%NUGET% restore Grpc.sln || goto :error
   
   setlocal
   
@@ -75,7 +71,7 @@
   
   %%NUGET% pack Grpc.Auth\Grpc.Auth.nuspec -Symbols -Version %VERSION% || goto :error
   %%NUGET% pack Grpc.Core\Grpc.Core.nuspec -Symbols -Version %VERSION% || goto :error
-  %%NUGET% pack Grpc.HealthCheck\Grpc.HealthCheck.nuspec -Symbols -Version %VERSION_WITH_BETA% -Properties ProtobufVersion=%PROTOBUF_VERSION% || goto :error
+  %%NUGET% pack Grpc.HealthCheck\Grpc.HealthCheck.nuspec -Symbols -Version %VERSION% -Properties ProtobufVersion=%PROTOBUF_VERSION% || goto :error
   %%NUGET% pack Grpc.nuspec -Version %VERSION% || goto :error
   %%NUGET% pack Grpc.Tools.nuspec -Version %VERSION% || goto :error
   
diff --git a/templates/src/node/health_check/package.json.template b/templates/src/node/health_check/package.json.template
index 96b9748..c2bb232 100644
--- a/templates/src/node/health_check/package.json.template
+++ b/templates/src/node/health_check/package.json.template
@@ -17,9 +17,9 @@
       }
     ],
     "dependencies": {
-      "grpc": "^0.15.0",
+      "grpc": "^${settings.node_version}",
       "lodash": "^3.9.3",
-      "google-protobuf": "^3.0.0-alpha.5"
+      "google-protobuf": "^3.0.0"
     },
     "files": [
       "LICENSE",
diff --git a/templates/src/php/composer.json.template b/templates/src/php/composer.json.template
new file mode 100644
index 0000000..bf876f3
--- /dev/null
+++ b/templates/src/php/composer.json.template
@@ -0,0 +1,23 @@
+%YAML 1.2
+--- |
+  {
+    "name": "grpc/grpc",
+    "type": "library",
+    "description": "gRPC library for PHP",
+    "keywords": ["rpc"],
+    "homepage": "http://grpc.io",
+    "license": "BSD-3-Clause",
+    "version": "${settings.php_version.php_composer()}",
+    "require": {
+      "php": ">=5.5.0",
+      "stanley-cheung/protobuf-php": "v0.6"
+    },
+    "require-dev": {
+      "google/auth": "v0.9"
+    },
+    "autoload": {
+      "psr-4": {
+        "Grpc\\": "lib/Grpc/"
+      }
+    }
+  }
diff --git a/templates/tools/dockerfile/apt_get_pyenv.include b/templates/tools/dockerfile/apt_get_pyenv.include
index 70e9028..816b279 100644
--- a/templates/tools/dockerfile/apt_get_pyenv.include
+++ b/templates/tools/dockerfile/apt_get_pyenv.include
@@ -15,4 +15,5 @@
 RUN pyenv update
 RUN pyenv install 3.5-dev
 RUN pyenv install 3.6-dev
-RUN pyenv local 3.5-dev 3.6-dev
+RUN pyenv install pypy-5.3.1
+RUN pyenv local 3.5-dev 3.6-dev pypy-5.3.1
diff --git a/test/core/end2end/cq_verifier.c b/test/core/end2end/cq_verifier.c
index b775680..5331049 100644
--- a/test/core/end2end/cq_verifier.c
+++ b/test/core/end2end/cq_verifier.c
@@ -61,7 +61,6 @@
    list to detail other expectations */
 typedef struct expectation {
   struct expectation *next;
-  struct expectation *prev;
   grpc_completion_type type;
   void *tag;
   int success;
@@ -71,17 +70,14 @@
 struct cq_verifier {
   /* bound completion queue */
   grpc_completion_queue *cq;
-  /* the root/sentinal expectation */
-  expectation expect;
+  /* start of expectation list */
+  expectation *first_expectation;
 };
 
 cq_verifier *cq_verifier_create(grpc_completion_queue *cq) {
   cq_verifier *v = gpr_malloc(sizeof(cq_verifier));
-  v->expect.type = ROOT_EXPECTATION;
-  v->expect.tag = NULL;
-  v->expect.next = &v->expect;
-  v->expect.prev = &v->expect;
   v->cq = cq;
+  v->first_expectation = NULL;
   return v;
 }
 
@@ -198,7 +194,7 @@
 static void expectations_to_strvec(gpr_strvec *buf, cq_verifier *v) {
   expectation *e;
 
-  for (e = v->expect.next; e != &v->expect; e = e->next) {
+  for (e = v->first_expectation; e != NULL; e = e->next) {
     expectation_to_strvec(buf, e);
     gpr_strvec_add(buf, gpr_strdup("\n"));
   }
@@ -226,30 +222,32 @@
 
   gpr_strvec_init(&have_tags);
 
-  while (v->expect.next != &v->expect) {
+  while (v->first_expectation != NULL) {
     ev = grpc_completion_queue_next(v->cq, deadline, NULL);
     if (ev.type == GRPC_QUEUE_TIMEOUT) {
       fail_no_event_received(v);
       break;
     }
 
-    for (e = v->expect.next; e != &v->expect; e = e->next) {
+    expectation *prev = NULL;
+    for (e = v->first_expectation; e != NULL; e = e->next) {
       gpr_asprintf(&s, " %p", e->tag);
       gpr_strvec_add(&have_tags, s);
       if (e->tag == ev.tag) {
         verify_matches(e, &ev);
-        e->next->prev = e->prev;
-        e->prev->next = e->next;
+        if (e == v->first_expectation) v->first_expectation = e->next;
+        if (prev != NULL) prev->next = e->next;
         gpr_free(e);
         break;
       }
+      prev = e;
     }
-    if (e == &v->expect) {
+    if (e == NULL) {
       s = grpc_event_string(&ev);
-      gpr_log(GPR_ERROR, "event not found: %s", s);
+      gpr_log(GPR_ERROR, "cq returned unexpected event: %s", s);
       gpr_free(s);
       s = gpr_strvec_flatten(&have_tags, NULL);
-      gpr_log(GPR_ERROR, "have tags:%s", s);
+      gpr_log(GPR_ERROR, "expected tags:%s", s);
       gpr_free(s);
       gpr_strvec_destroy(&have_tags);
       abort();
@@ -265,7 +263,7 @@
                    gpr_time_from_seconds(timeout_sec, GPR_TIMESPAN));
   grpc_event ev;
 
-  GPR_ASSERT(v->expect.next == &v->expect && "expectation queue must be empty");
+  GPR_ASSERT(v->first_expectation == NULL && "expectation queue must be empty");
 
   ev = grpc_completion_queue_next(v->cq, deadline, NULL);
   if (ev.type != GRPC_QUEUE_TIMEOUT) {
@@ -278,16 +276,16 @@
 
 void cq_verify_empty(cq_verifier *v) { cq_verify_empty_timeout(v, 1); }
 
-static expectation *add(cq_verifier *v, grpc_completion_type type, void *tag) {
+static void add(cq_verifier *v, grpc_completion_type type, void *tag,
+                bool success) {
   expectation *e = gpr_malloc(sizeof(expectation));
   e->type = type;
   e->tag = tag;
-  e->next = &v->expect;
-  e->prev = e->next->prev;
-  e->next->prev = e->prev->next = e;
-  return e;
+  e->success = success;
+  e->next = v->first_expectation;
+  v->first_expectation = e;
 }
 
 void cq_expect_completion(cq_verifier *v, void *tag, bool success) {
-  add(v, GRPC_OP_COMPLETE, tag)->success = success;
+  add(v, GRPC_OP_COMPLETE, tag, success);
 }
diff --git a/test/cpp/qps/driver.cc b/test/cpp/qps/driver.cc
index 2aeaea5..93f9271 100644
--- a/test/cpp/qps/driver.cc
+++ b/test/cpp/qps/driver.cc
@@ -310,6 +310,7 @@
   // clients is array rather than std::vector to avoid gcc-4.4 issues
   // where class contained in std::vector must have a copy constructor
   auto* clients = new ClientData[num_clients];
+  size_t channels_allocated = 0;
   for (size_t i = 0; i < num_clients; i++) {
     const auto& worker = workers[i + num_servers];
     gpr_log(GPR_INFO, "Starting client on %s (worker #%" PRIuPTR ")",
@@ -345,6 +346,16 @@
       }
     }
 
+    // Reduce channel count so that total channels specified is held regardless
+    // of the number of clients available
+    size_t num_channels =
+        (client_config.client_channels() - channels_allocated) /
+        (num_clients - i);
+    channels_allocated += num_channels;
+    gpr_log(GPR_DEBUG, "Client %" PRIdPTR " gets %" PRIdPTR " channels", i,
+            num_channels);
+    per_client_config.set_client_channels(num_channels);
+
     ClientArgs args;
     *args.mutable_setup() = per_client_config;
     clients[i].stream =
diff --git a/test/cpp/util/cli_credentials.cc b/test/cpp/util/cli_credentials.cc
new file mode 100644
index 0000000..8de9393
--- /dev/null
+++ b/test/cpp/util/cli_credentials.cc
@@ -0,0 +1,63 @@
+/*
+ *
+ * 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/cli_credentials.h"
+
+#include <gflags/gflags.h>
+
+DEFINE_bool(enable_ssl, false, "Whether to use ssl/tls.");
+DEFINE_bool(use_auth, false, "Whether to create default google credentials.");
+
+namespace grpc {
+namespace testing {
+
+std::shared_ptr<grpc::ChannelCredentials> CliCredentials::GetCredentials()
+    const {
+  if (!FLAGS_enable_ssl) {
+    return grpc::InsecureChannelCredentials();
+  } else {
+    if (FLAGS_use_auth) {
+      return grpc::GoogleDefaultCredentials();
+    } else {
+      return grpc::SslCredentials(grpc::SslCredentialsOptions());
+    }
+  }
+}
+
+const grpc::string CliCredentials::GetCredentialUsage() const {
+  return "    --enable_ssl             ; Set whether to use tls\n"
+         "    --use_auth               ; Set whether to create default google"
+         " credentials\n";
+}
+}  // namespace testing
+}  // namespace grpc
diff --git a/test/cpp/util/cli_credentials.h b/test/cpp/util/cli_credentials.h
new file mode 100644
index 0000000..581b77a
--- /dev/null
+++ b/test/cpp/util/cli_credentials.h
@@ -0,0 +1,53 @@
+/*
+ *
+ * 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_CLI_CREDENTIALS_H
+#define GRPC_TEST_CPP_UTIL_CLI_CREDENTIALS_H
+
+#include <grpc++/security/credentials.h>
+#include <grpc++/support/config.h>
+
+namespace grpc {
+namespace testing {
+
+class CliCredentials {
+ public:
+  virtual ~CliCredentials() {}
+  virtual std::shared_ptr<grpc::ChannelCredentials> GetCredentials() const;
+  virtual const grpc::string GetCredentialUsage() const;
+};
+
+}  // namespace testing
+}  // namespace grpc
+
+#endif  // GRPC_TEST_CPP_UTIL_CLI_CREDENTIALS_H
diff --git a/test/cpp/util/config_grpc_cli.h b/test/cpp/util/config_grpc_cli.h
new file mode 100644
index 0000000..ea8231a
--- /dev/null
+++ b/test/cpp/util/config_grpc_cli.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_CONFIG_GRPC_CLI_H
+#define GRPC_TEST_CPP_UTIL_CONFIG_GRPC_CLI_H
+
+#include <grpc++/impl/codegen/config_protobuf.h>
+
+#ifndef GRPC_CUSTOM_DYNAMICMESSAGEFACTORY
+#include <google/protobuf/dynamic_message.h>
+#define GRPC_CUSTOM_DYNAMICMESSAGEFACTORY \
+  ::google::protobuf::DynamicMessageFactory
+#endif
+
+#ifndef GRPC_CUSTOM_DESCRIPTORPOOLDATABASE
+#include <google/protobuf/descriptor.h>
+#define GRPC_CUSTOM_DESCRIPTORPOOLDATABASE \
+  ::google::protobuf::DescriptorPoolDatabase
+#define GRPC_CUSTOM_MERGEDDESCRIPTORDATABASE \
+  ::google::protobuf::MergedDescriptorDatabase
+#endif
+
+#ifndef GRPC_CUSTOM_TEXTFORMAT
+#include <google/protobuf/text_format.h>
+#define GRPC_CUSTOM_TEXTFORMAT ::google::protobuf::TextFormat
+#endif
+
+#ifndef GRPC_CUSTOM_DISKSOURCETREE
+#include <google/protobuf/compiler/importer.h>
+#define GRPC_CUSTOM_DISKSOURCETREE ::google::protobuf::compiler::DiskSourceTree
+#define GRPC_CUSTOM_IMPORTER ::google::protobuf::compiler::Importer
+#define GRPC_CUSTOM_MULTIFILEERRORCOLLECTOR \
+  ::google::protobuf::compiler::MultiFileErrorCollector
+#endif
+
+namespace grpc {
+namespace protobuf {
+
+typedef GRPC_CUSTOM_DYNAMICMESSAGEFACTORY DynamicMessageFactory;
+
+typedef GRPC_CUSTOM_DESCRIPTORPOOLDATABASE DescriptorPoolDatabase;
+typedef GRPC_CUSTOM_MERGEDDESCRIPTORDATABASE MergedDescriptorDatabase;
+
+typedef GRPC_CUSTOM_TEXTFORMAT TextFormat;
+
+namespace compiler {
+typedef GRPC_CUSTOM_DISKSOURCETREE DiskSourceTree;
+typedef GRPC_CUSTOM_IMPORTER Importer;
+typedef GRPC_CUSTOM_MULTIFILEERRORCOLLECTOR MultiFileErrorCollector;
+}  // namespace importer
+
+}  // namespace protobuf
+}  // namespace grpc
+
+#endif  // GRPC_TEST_CPP_UTIL_CONFIG_GRPC_CLI_H
diff --git a/test/cpp/util/grpc_cli.cc b/test/cpp/util/grpc_cli.cc
index 53529da..fe24860 100644
--- a/test/cpp/util/grpc_cli.cc
+++ b/test/cpp/util/grpc_cli.cc
@@ -33,12 +33,14 @@
 
 /*
   A command line tool to talk to a grpc server.
+  Run `grpc_cli help` command to see its usage information.
+
   Example of talking to grpc interop server:
   grpc_cli call localhost:50051 UnaryCall "response_size:10" \
       --protofiles=src/proto/grpc/testing/test.proto --enable_ssl=false
 
   Options:
-    1. --protofiles, use this flag to provide a proto file if the server does
+    1. --protofiles, use this flag to provide proto files if the server does
        does not have the reflection service.
     2. --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
@@ -48,15 +50,17 @@
        --metadata="MyHeaderKey1:Value1:MyHeaderKey2:Value2"
     4. --enable_ssl, whether to use tls.
     5. --use_auth, if set to true, attach a GoogleDefaultCredentials to the call
-    6. --input_binary_file, a file containing the serialized request. The file
-       can be generated by calling something like:
+    6. --infile, input filename (defaults to stdin)
+    7. --outfile, output filename (defaults to stdout)
+    8. --binary_input, use the serialized request as input. The serialized
+       request 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.
-    7. --output_binary_file, a file to write binary format response into, it can
+    9. --binary_output, use binary format response as output, it can
        be later decoded using protoc:
        protoc --proto_path=src/proto/grpc/testing/ \
        --decode=grpc.testing.SimpleResponse \
@@ -64,182 +68,34 @@
        < output.bin > output.txt
 */
 
-#include <unistd.h>
 #include <fstream>
+#include <functional>
 #include <iostream>
-#include <sstream>
 
 #include <gflags/gflags.h>
-#include <grpc++/channel.h>
-#include <grpc++/create_channel.h>
-#include <grpc++/security/credentials.h>
-#include <grpc++/support/string_ref.h>
-#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 <grpc++/support/config.h>
+#include "test/cpp/util/cli_credentials.h"
+#include "test/cpp/util/grpc_tool.h"
 #include "test/cpp/util/test_config.h"
 
-DEFINE_bool(enable_ssl, true, "Whether to use ssl/tls.");
-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, "",
-              "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.");
-// TODO(zyc): support a list of input proto files
-DEFINE_string(protofiles, "", "Name of the proto file.");
+DEFINE_string(outfile, "", "Output file (default is stdout)");
 
-void ParseMetadataFlag(
-    std::multimap<grpc::string, grpc::string>* client_metadata) {
-  if (FLAGS_metadata.empty()) {
-    return;
+static bool SimplePrint(const grpc::string& outfile,
+                        const grpc::string& output) {
+  if (outfile.empty()) {
+    std::cout << output;
+  } else {
+    std::ofstream output_file(outfile, std::ios::trunc | std::ios::binary);
+    output_file << output;
+    output_file.close();
   }
-  std::vector<grpc::string> fields;
-  const char* delim = ":";
-  size_t cur, next = -1;
-  do {
-    cur = next + 1;
-    next = FLAGS_metadata.find_first_of(delim, cur);
-    fields.push_back(FLAGS_metadata.substr(cur, next - cur));
-  } while (next != grpc::string::npos);
-  if (fields.size() % 2) {
-    std::cout << "Failed to parse metadata flag" << std::endl;
-    exit(1);
-  }
-  for (size_t i = 0; i < fields.size(); i += 2) {
-    client_metadata->insert(
-        std::pair<grpc::string, grpc::string>(fields[i], fields[i + 1]));
-  }
-}
-
-template <typename T>
-void PrintMetadata(const T& m, const grpc::string& message) {
-  if (m.empty()) {
-    return;
-  }
-  std::cout << message << std::endl;
-  grpc::string pair;
-  for (typename T::const_iterator iter = m.begin(); iter != m.end(); ++iter) {
-    pair.clear();
-    pair.append(iter->first.data(), iter->first.size());
-    pair.append(" : ");
-    pair.append(iter->second.data(), iter->second.size());
-    std::cout << pair << std::endl;
-  }
+  return true;
 }
 
 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 method_name "
-              << "[proto file] [text format request] [<options>]" << std::endl;
-    return 1;
-  }
-
-  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 == 5) {
-    request_text = argv[4];
-  }
-
-  std::shared_ptr<grpc::ChannelCredentials> creds;
-  if (!FLAGS_enable_ssl) {
-    creds = grpc::InsecureChannelCredentials();
-  } else {
-    if (FLAGS_use_auth) {
-      creds = grpc::GoogleDefaultCredentials();
-    } else {
-      creds = grpc::SslCredentials(grpc::SslCredentialsOptions());
-    }
-  }
-  std::shared_ptr<grpc::Channel> channel =
-      grpc::CreateChannel(server_address, creds);
-
-  if (request_text.empty() && FLAGS_input_binary_file.empty()) {
-    if (isatty(STDIN_FILENO)) {
-      std::cout << "reading request message from stdin..." << std::endl;
-    }
-    std::stringstream input_stream;
-    input_stream << std::cin.rdbuf();
-    request_text = input_stream.str();
-  }
-
-  if (!request_text.empty()) {
-    if (!FLAGS_protofiles.empty()) {
-      parser.reset(new grpc::testing::ProtoFileParser(
-          FLAGS_proto_path, FLAGS_protofiles, method_name));
-    } else {
-      parser.reset(new grpc::testing::ProtoFileParser(channel, method_name));
-    }
-    method_name = parser->GetFullMethodName();
-    if (parser->HasError()) {
-      return 1;
-    }
-
-    if (!FLAGS_input_binary_file.empty()) {
-      std::cout
-          << "warning: request given in argv, ignoring --input_binary_file"
-          << std::endl;
-    }
-  }
-
-  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;
-
-  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_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 (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 << serialized_response_proto;
-    }
-  } else {
-    std::cout << "Rpc failed with status code " << s.error_code()
-              << ", error message: " << s.error_message() << std::endl;
-  }
-
-  return 0;
+  return grpc::testing::GrpcToolMainLib(
+      argc, (const char**)argv, grpc::testing::CliCredentials(),
+      std::bind(SimplePrint, FLAGS_outfile, std::placeholders::_1));
 }
diff --git a/test/cpp/util/grpc_tool.cc b/test/cpp/util/grpc_tool.cc
new file mode 100644
index 0000000..f06053c
--- /dev/null
+++ b/test/cpp/util/grpc_tool.cc
@@ -0,0 +1,365 @@
+/*
+ *
+ * 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/grpc_tool.h"
+
+#include <unistd.h>
+#include <fstream>
+#include <iostream>
+#include <memory>
+#include <sstream>
+#include <string>
+
+#include <gflags/gflags.h>
+#include <grpc++/channel.h>
+#include <grpc++/create_channel.h>
+#include <grpc++/grpc++.h>
+#include <grpc++/security/credentials.h>
+#include <grpc++/support/string_ref.h>
+#include <grpc/grpc.h>
+
+#include "test/cpp/util/cli_call.h"
+#include "test/cpp/util/proto_file_parser.h"
+#include "test/cpp/util/proto_reflection_descriptor_database.h"
+#include "test/cpp/util/test_config.h"
+
+DEFINE_bool(remotedb, true, "Use server types to parse and format messages");
+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.");
+DEFINE_string(proto_file, "", "Name of the proto file.");
+DEFINE_bool(binary_input, false, "Input in binary format");
+DEFINE_bool(binary_output, false, "Output in binary format");
+DEFINE_string(infile, "", "Input file (default is stdin)");
+
+namespace grpc {
+namespace testing {
+namespace {
+
+class GrpcTool {
+ public:
+  explicit GrpcTool();
+  virtual ~GrpcTool() {}
+
+  bool Help(int argc, const char** argv, CliCredentials cred,
+            GrpcToolOutputCallback callback);
+  bool CallMethod(int argc, const char** argv, CliCredentials cred,
+                  GrpcToolOutputCallback callback);
+  // TODO(zyc): implement the following methods
+  // bool ListServices(int argc, const char** argv, GrpcToolOutputCallback
+  // callback);
+  // bool PrintType(int argc, const char** argv, GrpcToolOutputCallback
+  // callback);
+  // bool PrintTypeId(int argc, const char** argv, GrpcToolOutputCallback
+  // callback);
+  // bool ParseMessage(int argc, const char** argv, GrpcToolOutputCallback
+  // callback);
+  // bool ToText(int argc, const char** argv, GrpcToolOutputCallback callback);
+  // bool ToBinary(int argc, const char** argv, GrpcToolOutputCallback
+  // callback);
+
+  void SetPrintCommandMode(int exit_status) {
+    print_command_usage_ = true;
+    usage_exit_status_ = exit_status;
+  }
+
+ private:
+  void CommandUsage(const grpc::string& usage) const;
+  bool print_command_usage_;
+  int usage_exit_status_;
+  const grpc::string cred_usage_;
+};
+
+template <typename T>
+std::function<bool(GrpcTool*, int, const char**, const CliCredentials,
+                   GrpcToolOutputCallback)>
+BindWith5Args(T&& func) {
+  return std::bind(std::forward<T>(func), std::placeholders::_1,
+                   std::placeholders::_2, std::placeholders::_3,
+                   std::placeholders::_4, std::placeholders::_5);
+}
+
+template <typename T>
+size_t ArraySize(T& a) {
+  return ((sizeof(a) / sizeof(*(a))) /
+          static_cast<size_t>(!(sizeof(a) % sizeof(*(a)))));
+}
+
+void ParseMetadataFlag(
+    std::multimap<grpc::string, grpc::string>* client_metadata) {
+  if (FLAGS_metadata.empty()) {
+    return;
+  }
+  std::vector<grpc::string> fields;
+  const char* delim = ":";
+  size_t cur, next = -1;
+  do {
+    cur = next + 1;
+    next = FLAGS_metadata.find_first_of(delim, cur);
+    fields.push_back(FLAGS_metadata.substr(cur, next - cur));
+  } while (next != grpc::string::npos);
+  if (fields.size() % 2) {
+    fprintf(stderr, "Failed to parse metadata flag.\n");
+    exit(1);
+  }
+  for (size_t i = 0; i < fields.size(); i += 2) {
+    client_metadata->insert(
+        std::pair<grpc::string, grpc::string>(fields[i], fields[i + 1]));
+  }
+}
+
+template <typename T>
+void PrintMetadata(const T& m, const grpc::string& message) {
+  if (m.empty()) {
+    return;
+  }
+  fprintf(stderr, "%s\n", message.c_str());
+  grpc::string pair;
+  for (typename T::const_iterator iter = m.begin(); iter != m.end(); ++iter) {
+    pair.clear();
+    pair.append(iter->first.data(), iter->first.size());
+    pair.append(" : ");
+    pair.append(iter->second.data(), iter->second.size());
+    fprintf(stderr, "%s\n", pair.c_str());
+  }
+}
+
+struct Command {
+  const char* command;
+  std::function<bool(GrpcTool*, int, const char**, const CliCredentials,
+                     GrpcToolOutputCallback)>
+      function;
+  int min_args;
+  int max_args;
+};
+
+const Command ops[] = {
+    {"help", BindWith5Args(&GrpcTool::Help), 0, INT_MAX},
+    // {"ls", BindWith5Args(&GrpcTool::ListServices), 1, 3},
+    // {"list", BindWith5Args(&GrpcTool::ListServices), 1, 3},
+    {"call", BindWith5Args(&GrpcTool::CallMethod), 2, 3},
+    // {"type", BindWith5Args(&GrpcTool::PrintType), 2, 2},
+    // {"parse", BindWith5Args(&GrpcTool::ParseMessage), 2, 3},
+    // {"totext", BindWith5Args(&GrpcTool::ToText), 2, 3},
+    // {"tobinary", BindWith5Args(&GrpcTool::ToBinary), 2, 3},
+};
+
+void Usage(const grpc::string& msg) {
+  fprintf(
+      stderr,
+      "%s\n"
+      // "  grpc_cli ls ...         ; List services\n"
+      "  grpc_cli call ...       ; Call method\n"
+      // "  grpc_cli type ...       ; Print type\n"
+      // "  grpc_cli parse ...      ; Parse message\n"
+      // "  grpc_cli totext ...     ; Convert binary message to text\n"
+      // "  grpc_cli tobinary ...   ; Convert text message to binary\n"
+      "  grpc_cli help ...       ; Print this message, or per-command usage\n"
+      "\n",
+      msg.c_str());
+
+  exit(1);
+}
+
+const Command* FindCommand(const grpc::string& name) {
+  for (int i = 0; i < (int)ArraySize(ops); i++) {
+    if (name == ops[i].command) {
+      return &ops[i];
+    }
+  }
+  return NULL;
+}
+}  // namespace
+
+int GrpcToolMainLib(int argc, const char** argv, const CliCredentials cred,
+                    GrpcToolOutputCallback callback) {
+  if (argc < 2) {
+    Usage("No command specified");
+  }
+
+  grpc::string command = argv[1];
+  argc -= 2;
+  argv += 2;
+
+  const Command* cmd = FindCommand(command);
+  if (cmd != NULL) {
+    GrpcTool grpc_tool;
+    if (argc < cmd->min_args || argc > cmd->max_args) {
+      // Force the command to print its usage message
+      fprintf(stderr, "\nWrong number of arguments for %s\n", command.c_str());
+      grpc_tool.SetPrintCommandMode(1);
+      return cmd->function(&grpc_tool, -1, NULL, cred, callback);
+    }
+    const bool ok = cmd->function(&grpc_tool, argc, argv, cred, callback);
+    return ok ? 0 : 1;
+  } else {
+    Usage("Invalid command '" + grpc::string(command.c_str()) + "'");
+  }
+  return 1;
+}
+
+GrpcTool::GrpcTool() : print_command_usage_(false), usage_exit_status_(0) {}
+
+void GrpcTool::CommandUsage(const grpc::string& usage) const {
+  if (print_command_usage_) {
+    fprintf(stderr, "\n%s%s\n", usage.c_str(),
+            (usage.empty() || usage[usage.size() - 1] != '\n') ? "\n" : "");
+    exit(usage_exit_status_);
+  }
+}
+
+bool GrpcTool::Help(int argc, const char** argv, const CliCredentials cred,
+                    GrpcToolOutputCallback callback) {
+  CommandUsage(
+      "Print help\n"
+      "  grpc_cli help [subcommand]\n");
+
+  if (argc == 0) {
+    Usage("");
+  } else {
+    const Command* cmd = FindCommand(argv[0]);
+    if (cmd == NULL) {
+      Usage("Unknown command '" + grpc::string(argv[0]) + "'");
+    }
+    SetPrintCommandMode(0);
+    cmd->function(this, -1, NULL, cred, callback);
+  }
+  return true;
+}
+
+bool GrpcTool::CallMethod(int argc, const char** argv,
+                          const CliCredentials cred,
+                          GrpcToolOutputCallback callback) {
+  CommandUsage(
+      "Call method\n"
+      "  grpc_cli call <address> <service>[.<method>] <request>\n"
+      "    <address>                ; host:port\n"
+      "    <service>                ; Exported service name\n"
+      "    <method>                 ; Method name\n"
+      "    <request>                ; Text protobuffer (overrides infile)\n"
+      "    --proto_file             ; Comma separated proto files used as a"
+      " fallback when parsing request/response\n"
+      "    --proto_path             ; The search path of proto files, valid"
+      " only when --proto_file is given\n"
+      "    --metadata               ; The metadata to be sent to the server\n"
+      "    --infile                 ; Input filename (defaults to stdin)\n"
+      "    --outfile                ; Output filename (defaults to stdout)\n"
+      "    --binary_input           ; Input in binary format\n"
+      "    --binary_output          ; Output in binary format\n" +
+      cred.GetCredentialUsage());
+
+  std::stringstream output_ss;
+  grpc::string request_text;
+  grpc::string server_address(argv[0]);
+  grpc::string method_name(argv[1]);
+  std::unique_ptr<grpc::testing::ProtoFileParser> parser;
+  grpc::string serialized_request_proto;
+
+  if (argc == 3) {
+    request_text = argv[2];
+    if (!FLAGS_infile.empty()) {
+      fprintf(stderr, "warning: request given in argv, ignoring --infile\n");
+    }
+  } else {
+    std::stringstream input_stream;
+    if (FLAGS_infile.empty()) {
+      if (isatty(STDIN_FILENO)) {
+        fprintf(stderr, "reading request message from stdin...\n");
+      }
+      input_stream << std::cin.rdbuf();
+    } else {
+      std::ifstream input_file(FLAGS_infile, std::ios::in | std::ios::binary);
+      input_stream << input_file.rdbuf();
+      input_file.close();
+    }
+    request_text = input_stream.str();
+  }
+
+  std::shared_ptr<grpc::Channel> channel =
+      grpc::CreateChannel(server_address, cred.GetCredentials());
+  if (!FLAGS_binary_input || !FLAGS_binary_output) {
+    parser.reset(
+        new grpc::testing::ProtoFileParser(FLAGS_remotedb ? channel : nullptr,
+                                           FLAGS_proto_path, FLAGS_proto_file));
+    if (parser->HasError()) {
+      return false;
+    }
+  }
+
+  if (FLAGS_binary_input) {
+    serialized_request_proto = request_text;
+  } else {
+    serialized_request_proto = parser->GetSerializedProtoFromMethod(
+        method_name, request_text, true /* is_request */);
+    if (parser->HasError()) {
+      return false;
+    }
+  }
+  fprintf(stderr, "connecting to %s\n", server_address.c_str());
+
+  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 status = grpc::testing::CliCall::Call(
+      channel, parser->GetFormatedMethodName(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 (status.ok()) {
+    fprintf(stderr, "Rpc succeeded with OK status\n");
+    if (FLAGS_binary_output) {
+      output_ss << serialized_response_proto;
+    } else {
+      grpc::string response_text = parser->GetTextFormatFromMethod(
+          method_name, serialized_response_proto, false /* is_request */);
+      if (parser->HasError()) {
+        return false;
+      }
+      output_ss << "Response: \n " << response_text << std::endl;
+    }
+  } else {
+    fprintf(stderr, "Rpc failed with status code %d, error message: %s\n",
+            status.error_code(), status.error_message().c_str());
+  }
+
+  return callback(output_ss.str());
+}
+
+}  // namespace testing
+}  // namespace grpc
diff --git a/test/cpp/util/grpc_tool.h b/test/cpp/util/grpc_tool.h
new file mode 100644
index 0000000..3da8693
--- /dev/null
+++ b/test/cpp/util/grpc_tool.h
@@ -0,0 +1,54 @@
+/*
+ *
+ * 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_GRPC_TOOL_H
+#define GRPC_TEST_CPP_UTIL_GRPC_TOOL_H
+
+#include <functional>
+
+#include <grpc++/support/config.h>
+
+#include "test/cpp/util/cli_credentials.h"
+
+namespace grpc {
+namespace testing {
+
+typedef std::function<bool(const grpc::string &)> GrpcToolOutputCallback;
+
+int GrpcToolMainLib(int argc, const char **argv, CliCredentials cred,
+                    GrpcToolOutputCallback callback);
+
+}  // namespace testing
+}  // namespace grpc
+
+#endif  // GRPC_TEST_CPP_UTIL_GRPC_TOOL_H
diff --git a/test/cpp/util/grpc_tool_test.cc b/test/cpp/util/grpc_tool_test.cc
new file mode 100644
index 0000000..b96afaf
--- /dev/null
+++ b/test/cpp/util/grpc_tool_test.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 "test/cpp/util/grpc_tool.h"
+
+#include <sstream>
+
+#include <grpc++/channel.h>
+#include <grpc++/client_context.h>
+#include <grpc++/create_channel.h>
+#include <grpc++/ext/proto_server_reflection_plugin.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 "src/proto/grpc/testing/echo.pb.h"
+#include "test/core/util/port.h"
+#include "test/core/util/test_config.h"
+#include "test/cpp/util/cli_credentials.h"
+#include "test/cpp/util/string_ref_helper.h"
+
+using grpc::testing::EchoRequest;
+using grpc::testing::EchoResponse;
+
+namespace grpc {
+namespace testing {
+namespace {
+
+class TestCliCredentials GRPC_FINAL : public grpc::testing::CliCredentials {
+ public:
+  std::shared_ptr<grpc::ChannelCredentials> GetCredentials() const
+      GRPC_OVERRIDE {
+    return InsecureChannelCredentials();
+  }
+  const grpc::string GetCredentialUsage() const GRPC_OVERRIDE { return ""; }
+};
+
+}  // namespame
+
+class TestServiceImpl : public ::grpc::testing::EchoTestService::Service {
+ public:
+  Status Echo(ServerContext* context, const EchoRequest* request,
+              EchoResponse* response) GRPC_OVERRIDE {
+    if (!context->client_metadata().empty()) {
+      for (std::multimap<grpc::string_ref, grpc::string_ref>::const_iterator
+               iter = context->client_metadata().begin();
+           iter != context->client_metadata().end(); ++iter) {
+        context->AddInitialMetadata(ToString(iter->first),
+                                    ToString(iter->second));
+      }
+    }
+    context->AddTrailingMetadata("trailing_key", "trailing_value");
+    response->set_message(request->message());
+    return Status::OK;
+  }
+};
+
+class GrpcToolTest : public ::testing::Test {
+ protected:
+  GrpcToolTest() {}
+
+  // SetUpServer cannot be used with EXPECT_EXIT. grpc_pick_unused_port_or_die()
+  // uses atexit() to free chosen ports, and it will spawn a new thread in
+  // resolve_address_posix.c:192 at exit time.
+  const grpc::string SetUpServer() {
+    std::ostringstream server_address;
+    int port = grpc_pick_unused_port_or_die();
+    server_address << "localhost:" << port;
+    // Setup server
+    ServerBuilder builder;
+    builder.AddListeningPort(server_address.str(), InsecureServerCredentials());
+    builder.RegisterService(&service_);
+    server_ = builder.BuildAndStart();
+    return server_address.str();
+  }
+
+  void ShutdownServer() { server_->Shutdown(); }
+
+  std::unique_ptr<Server> server_;
+  TestServiceImpl service_;
+  reflection::ProtoServerReflectionPlugin plugin_;
+};
+
+static bool PrintStream(std::stringstream* ss, const grpc::string& output) {
+  (*ss) << output << std::endl;
+  return true;
+}
+
+template <typename T>
+static size_t ArraySize(T& a) {
+  return ((sizeof(a) / sizeof(*(a))) /
+          static_cast<size_t>(!(sizeof(a) % sizeof(*(a)))));
+}
+
+#define USAGE_REGEX "(  grpc_cli .+\n){2,10}"
+
+TEST_F(GrpcToolTest, NoCommand) {
+  // Test input "grpc_cli"
+  std::stringstream output_stream;
+  const char* argv[] = {"grpc_cli"};
+  // Exit with 1, print usage instruction in stderr
+  EXPECT_EXIT(
+      GrpcToolMainLib(
+          ArraySize(argv), argv, TestCliCredentials(),
+          std::bind(PrintStream, &output_stream, std::placeholders::_1)),
+      ::testing::ExitedWithCode(1), "No command specified\n" USAGE_REGEX);
+  // No output
+  EXPECT_TRUE(0 == output_stream.tellp());
+}
+
+TEST_F(GrpcToolTest, InvalidCommand) {
+  // Test input "grpc_cli"
+  std::stringstream output_stream;
+  const char* argv[] = {"grpc_cli", "abc"};
+  // Exit with 1, print usage instruction in stderr
+  EXPECT_EXIT(
+      GrpcToolMainLib(
+          ArraySize(argv), argv, TestCliCredentials(),
+          std::bind(PrintStream, &output_stream, std::placeholders::_1)),
+      ::testing::ExitedWithCode(1), "Invalid command 'abc'\n" USAGE_REGEX);
+  // No output
+  EXPECT_TRUE(0 == output_stream.tellp());
+}
+
+TEST_F(GrpcToolTest, HelpCommand) {
+  // Test input "grpc_cli help"
+  std::stringstream output_stream;
+  const char* argv[] = {"grpc_cli", "help"};
+  // Exit with 1, print usage instruction in stderr
+  EXPECT_EXIT(GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(),
+                              std::bind(PrintStream, &output_stream,
+                                        std::placeholders::_1)),
+              ::testing::ExitedWithCode(1), USAGE_REGEX);
+  // No output
+  EXPECT_TRUE(0 == output_stream.tellp());
+}
+
+TEST_F(GrpcToolTest, CallCommand) {
+  // Test input "grpc_cli call Echo"
+  std::stringstream output_stream;
+
+  const grpc::string server_address = SetUpServer();
+  const char* argv[] = {"grpc_cli", "call", server_address.c_str(), "Echo",
+                        "message: 'Hello'"};
+
+  EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(),
+                                   std::bind(PrintStream, &output_stream,
+                                             std::placeholders::_1)));
+  // Expected output: "message: \"Hello\""
+  EXPECT_TRUE(NULL !=
+              strstr(output_stream.str().c_str(), "message: \"Hello\""));
+  ShutdownServer();
+}
+
+TEST_F(GrpcToolTest, TooFewArguments) {
+  // Test input "grpc_cli call localhost:<port> Echo "message: 'Hello'"
+  std::stringstream output_stream;
+  const char* argv[] = {"grpc_cli", "call", "Echo"};
+
+  // Exit with 1
+  EXPECT_EXIT(
+      GrpcToolMainLib(
+          ArraySize(argv), argv, TestCliCredentials(),
+          std::bind(PrintStream, &output_stream, std::placeholders::_1)),
+      ::testing::ExitedWithCode(1), ".*Wrong number of arguments for call.*");
+  // No output
+  EXPECT_TRUE(0 == output_stream.tellp());
+}
+
+TEST_F(GrpcToolTest, TooManyArguments) {
+  // Test input "grpc_cli call localhost:<port> Echo Echo "message: 'Hello'"
+  std::stringstream output_stream;
+  const char* argv[] = {"grpc_cli", "call", "localhost:10000",
+                        "Echo",     "Echo", "message: 'Hello'"};
+
+  // Exit with 1
+  EXPECT_EXIT(
+      GrpcToolMainLib(
+          ArraySize(argv), argv, TestCliCredentials(),
+          std::bind(PrintStream, &output_stream, std::placeholders::_1)),
+      ::testing::ExitedWithCode(1), ".*Wrong number of arguments for call.*");
+  // No output
+  EXPECT_TRUE(0 == output_stream.tellp());
+}
+
+}  // namespace testing
+}  // namespace grpc
+
+int main(int argc, char** argv) {
+  grpc_test_init(argc, argv);
+  ::testing::InitGoogleTest(&argc, argv);
+  ::testing::FLAGS_gtest_death_test_style = "threadsafe";
+  return RUN_ALL_TESTS();
+}
diff --git a/test/cpp/util/proto_file_parser.cc b/test/cpp/util/proto_file_parser.cc
index 5b0d925..0c88c24 100644
--- a/test/cpp/util/proto_file_parser.cc
+++ b/test/cpp/util/proto_file_parser.cc
@@ -37,7 +37,6 @@
 #include <iostream>
 #include <sstream>
 
-#include <google/protobuf/text_format.h>
 #include <grpc++/support/config.h>
 
 namespace grpc {
@@ -56,8 +55,7 @@
 }
 }  // namespace
 
-class ErrorPrinter
-    : public google::protobuf::compiler::MultiFileErrorCollector {
+class ErrorPrinter : public protobuf::compiler::MultiFileErrorCollector {
  public:
   explicit ErrorPrinter(ProtoFileParser* parser) : parser_(parser) {}
 
@@ -71,7 +69,7 @@
 
   void AddWarning(const grpc::string& filename, int line, int column,
                   const grpc::string& message) GRPC_OVERRIDE {
-    std::cout << "warning " << filename << " " << line << " " << column << " "
+    std::cerr << "warning " << filename << " " << line << " " << column << " "
               << message << std::endl;
   }
 
@@ -79,62 +77,69 @@
   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()));
-
-  std::vector<const google::protobuf::ServiceDescriptor*> service_desc_list;
-  for (int i = 0; i < file_desc->service_count(); i++) {
-    service_desc_list.push_back(file_desc->service(i));
-  }
-  InitProtoFileParser(method, service_desc_list);
-}
-
 ProtoFileParser::ProtoFileParser(std::shared_ptr<grpc::Channel> channel,
-                                 const grpc::string& method)
-    : has_error_(false),
-      desc_db_(new grpc::ProtoReflectionDescriptorDatabase(channel)),
-      desc_pool_(new google::protobuf::DescriptorPool(desc_db_.get())) {
+                                 const grpc::string& proto_path,
+                                 const grpc::string& protofiles)
+    : has_error_(false) {
   std::vector<std::string> service_list;
-  if (!desc_db_->GetServices(&service_list)) {
-    LogError(
-        "Failed to get services from the server, "
-        "it may not have the reflection service.\n"
-        "Please try to use the --protofiles option to provide a proto file.");
+  if (channel) {
+    reflection_db_.reset(new grpc::ProtoReflectionDescriptorDatabase(channel));
+    reflection_db_->GetServices(&service_list);
   }
-  if (has_error_) {
+
+  if (!protofiles.empty()) {
+    source_tree_.MapPath("", proto_path);
+    error_printer_.reset(new ErrorPrinter(this));
+    importer_.reset(
+        new protobuf::compiler::Importer(&source_tree_, error_printer_.get()));
+
+    grpc::string file_name;
+    std::stringstream ss(protofiles);
+    while (std::getline(ss, file_name, ',')) {
+      const auto* file_desc = importer_->Import(file_name);
+      if (file_desc) {
+        for (int i = 0; i < file_desc->service_count(); i++) {
+          service_desc_list_.push_back(file_desc->service(i));
+        }
+      } else {
+        std::cerr << file_name << " not found" << std::endl;
+      }
+    }
+
+    file_db_.reset(new protobuf::DescriptorPoolDatabase(*importer_->pool()));
+  }
+
+  if (!reflection_db_ && !file_db_) {
+    LogError("No available proto database");
     return;
   }
-  dynamic_factory_.reset(
-      new google::protobuf::DynamicMessageFactory(desc_pool_.get()));
 
-  std::vector<const google::protobuf::ServiceDescriptor*> service_desc_list;
-  for (auto it = service_list.begin(); it != service_list.end(); it++) {
-    service_desc_list.push_back(desc_pool_->FindServiceByName(*it));
+  if (!reflection_db_) {
+    desc_db_ = std::move(file_db_);
+  } else if (!file_db_) {
+    desc_db_ = std::move(reflection_db_);
+  } else {
+    desc_db_.reset(new protobuf::MergedDescriptorDatabase(reflection_db_.get(),
+                                                          file_db_.get()));
   }
-  InitProtoFileParser(method, service_desc_list);
+
+  desc_pool_.reset(new protobuf::DescriptorPool(desc_db_.get()));
+  dynamic_factory_.reset(new protobuf::DynamicMessageFactory(desc_pool_.get()));
+
+  for (auto it = service_list.begin(); it != service_list.end(); it++) {
+    if (const protobuf::ServiceDescriptor* service_desc =
+            desc_pool_->FindServiceByName(*it)) {
+      service_desc_list_.push_back(service_desc);
+    }
+  }
 }
 
 ProtoFileParser::~ProtoFileParser() {}
 
-void ProtoFileParser::InitProtoFileParser(
-    const grpc::string& method,
-    const std::vector<const google::protobuf::ServiceDescriptor*>
-        service_desc_list) {
-  const google::protobuf::MethodDescriptor* method_descriptor = nullptr;
-  for (auto it = service_desc_list.begin(); it != service_desc_list.end();
+grpc::string ProtoFileParser::GetFullMethodName(const grpc::string& method) {
+  has_error_ = false;
+  const protobuf::MethodDescriptor* method_descriptor = nullptr;
+  for (auto it = service_desc_list_.begin(); it != service_desc_list_.end();
        it++) {
     const auto* service_desc = *it;
     for (int j = 0; j < service_desc->method_count(); j++) {
@@ -154,28 +159,82 @@
     LogError("Method name not found");
   }
   if (has_error_) {
-    return;
+    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());
+  return method_descriptor->full_name();
 }
 
-grpc::string ProtoFileParser::GetSerializedProto(
-    const grpc::string& text_format_proto, bool is_request) {
+grpc::string ProtoFileParser::GetFormatedMethodName(
+    const grpc::string& method) {
+  has_error_ = false;
+  grpc::string formated_method_name = GetFullMethodName(method);
+  if (has_error_) {
+    return "";
+  }
+  size_t last_dot = formated_method_name.find_last_of('.');
+  if (last_dot != grpc::string::npos) {
+    formated_method_name[last_dot] = '/';
+  }
+  formated_method_name.insert(formated_method_name.begin(), '/');
+  return formated_method_name;
+}
+
+grpc::string ProtoFileParser::GetMessageTypeFromMethod(
+    const grpc::string& method, bool is_request) {
+  has_error_ = false;
+  grpc::string full_method_name = GetFullMethodName(method);
+  if (has_error_) {
+    return "";
+  }
+  const protobuf::MethodDescriptor* method_desc =
+      desc_pool_->FindMethodByName(full_method_name);
+  if (!method_desc) {
+    LogError("Method not found");
+    return "";
+  }
+
+  return is_request ? method_desc->input_type()->full_name()
+                    : method_desc->output_type()->full_name();
+}
+
+grpc::string ProtoFileParser::GetSerializedProtoFromMethod(
+    const grpc::string& method, const grpc::string& text_format_proto,
+    bool is_request) {
+  has_error_ = false;
+  grpc::string message_type_name = GetMessageTypeFromMethod(method, is_request);
+  if (has_error_) {
+    return "";
+  }
+  return GetSerializedProtoFromMessageType(message_type_name,
+                                           text_format_proto);
+}
+
+grpc::string ProtoFileParser::GetTextFormatFromMethod(
+    const grpc::string& method, const grpc::string& serialized_proto,
+    bool is_request) {
+  has_error_ = false;
+  grpc::string message_type_name = GetMessageTypeFromMethod(method, is_request);
+  if (has_error_) {
+    return "";
+  }
+  return GetTextFormatFromMessageType(message_type_name, serialized_proto);
+}
+
+grpc::string ProtoFileParser::GetSerializedProtoFromMessageType(
+    const grpc::string& message_type_name,
+    const grpc::string& text_format_proto) {
+  has_error_ = false;
   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);
+  const protobuf::Descriptor* desc =
+      desc_pool_->FindMessageTypeByName(message_type_name);
+  if (!desc) {
+    LogError("Message type not found");
+    return "";
+  }
+  std::unique_ptr<grpc::protobuf::Message> msg(
+      dynamic_factory_->GetPrototype(desc)->New());
+  bool ok = protobuf::TextFormat::ParseFromString(text_format_proto, msg.get());
   if (!ok) {
     LogError("Failed to parse text format to proto.");
     return "";
@@ -188,16 +247,24 @@
   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();
+grpc::string ProtoFileParser::GetTextFormatFromMessageType(
+    const grpc::string& message_type_name,
+    const grpc::string& serialized_proto) {
+  has_error_ = false;
+  const protobuf::Descriptor* desc =
+      desc_pool_->FindMessageTypeByName(message_type_name);
+  if (!desc) {
+    LogError("Message type not found");
+    return "";
+  }
+  std::unique_ptr<grpc::protobuf::Message> msg(
+      dynamic_factory_->GetPrototype(desc)->New());
   if (!msg->ParseFromString(serialized_proto)) {
     LogError("Failed to deserialize proto.");
     return "";
   }
   grpc::string text_format;
-  if (!google::protobuf::TextFormat::PrintToString(*msg, &text_format)) {
+  if (!protobuf::TextFormat::PrintToString(*msg.get(), &text_format)) {
     LogError("Failed to print proto message to text format");
     return "";
   }
@@ -206,7 +273,7 @@
 
 void ProtoFileParser::LogError(const grpc::string& error_msg) {
   if (!error_msg.empty()) {
-    std::cout << error_msg << std::endl;
+    std::cerr << error_msg << std::endl;
   }
   has_error_ = true;
 }
diff --git a/test/cpp/util/proto_file_parser.h b/test/cpp/util/proto_file_parser.h
index b442d77..eda3991 100644
--- a/test/cpp/util/proto_file_parser.h
+++ b/test/cpp/util/proto_file_parser.h
@@ -36,11 +36,9 @@
 
 #include <memory>
 
-#include <google/protobuf/compiler/importer.h>
-#include <google/protobuf/dynamic_message.h>
 #include <grpc++/channel.h>
 
-#include "src/compiler/config.h"
+#include "test/cpp/util/config_grpc_cli.h"
 #include "test/cpp/util/proto_reflection_descriptor_database.h"
 
 namespace grpc {
@@ -50,44 +48,63 @@
 // 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);
-
+  // The parser will search proto files using the server reflection service
+  // provided on the given channel. The given protofiles in a source tree rooted
+  // from proto_path will also be searched.
   ProtoFileParser(std::shared_ptr<grpc::Channel> channel,
-                  const grpc::string& method);
+                  const grpc::string& proto_path,
+                  const grpc::string& protofiles);
+
   ~ProtoFileParser();
 
-  grpc::string GetFullMethodName() const { return full_method_name_; }
+  // The input method name in the following four functions could be a partial
+  // string such as Service.Method or even just Method. It will log an error if
+  // there is ambiguity.
+  // Full method name is in the form of Service.Method, it's good to be used in
+  // descriptor database queries.
+  grpc::string GetFullMethodName(const grpc::string& method);
 
-  grpc::string GetSerializedProto(const grpc::string& text_format_proto,
-                                  bool is_request);
+  // Formated method name is in the form of /Service/Method, it's good to be
+  // used as the argument of Stub::Call()
+  grpc::string GetFormatedMethodName(const grpc::string& method);
 
-  grpc::string GetTextFormat(const grpc::string& serialized_proto,
-                             bool is_request);
+  grpc::string GetSerializedProtoFromMethod(
+      const grpc::string& method, const grpc::string& text_format_proto,
+      bool is_request);
+
+  grpc::string GetTextFormatFromMethod(const grpc::string& method,
+                                       const grpc::string& serialized_proto,
+                                       bool is_request);
+
+  grpc::string GetSerializedProtoFromMessageType(
+      const grpc::string& message_type_name,
+      const grpc::string& text_format_proto);
+
+  grpc::string GetTextFormatFromMessageType(
+      const grpc::string& message_type_name,
+      const grpc::string& serialized_proto);
 
   bool HasError() const { return has_error_; }
 
   void LogError(const grpc::string& error_msg);
 
  private:
-  void InitProtoFileParser(
-      const grpc::string& method,
-      const std::vector<const google::protobuf::ServiceDescriptor*> services);
+  grpc::string GetMessageTypeFromMethod(const grpc::string& method,
+                                        bool is_request);
 
   bool has_error_;
   grpc::string request_text_;
-  grpc::string full_method_name_;
-  google::protobuf::compiler::DiskSourceTree source_tree_;
+  protobuf::compiler::DiskSourceTree source_tree_;
   std::unique_ptr<ErrorPrinter> error_printer_;
-  std::unique_ptr<google::protobuf::compiler::Importer> importer_;
-  std::unique_ptr<grpc::ProtoReflectionDescriptorDatabase> desc_db_;
-  std::unique_ptr<google::protobuf::DescriptorPool> desc_pool_;
-  std::unique_ptr<google::protobuf::DynamicMessageFactory> dynamic_factory_;
+  std::unique_ptr<protobuf::compiler::Importer> importer_;
+  std::unique_ptr<grpc::ProtoReflectionDescriptorDatabase> reflection_db_;
+  std::unique_ptr<protobuf::DescriptorPoolDatabase> file_db_;
+  std::unique_ptr<protobuf::DescriptorDatabase> desc_db_;
+  std::unique_ptr<protobuf::DescriptorPool> desc_pool_;
+  std::unique_ptr<protobuf::DynamicMessageFactory> dynamic_factory_;
   std::unique_ptr<grpc::protobuf::Message> request_prototype_;
   std::unique_ptr<grpc::protobuf::Message> response_prototype_;
+  std::vector<const protobuf::ServiceDescriptor*> service_desc_list_;
 };
 
 }  // namespace testing
diff --git a/test/cpp/util/proto_reflection_descriptor_database.cc b/test/cpp/util/proto_reflection_descriptor_database.cc
index 8fd466f..f0d14c6 100644
--- a/test/cpp/util/proto_reflection_descriptor_database.cc
+++ b/test/cpp/util/proto_reflection_descriptor_database.cc
@@ -58,7 +58,7 @@
     stream_->WritesDone();
     Status status = stream_->Finish();
     if (!status.ok()) {
-      gpr_log(GPR_ERROR,
+      gpr_log(GPR_INFO,
               "ServerReflectionInfo rpc failed. Error code: %d, details: %s",
               (int)status.error_code(), status.error_message().c_str());
     }
diff --git a/test/distrib/csharp/DistribTest/App.config b/test/distrib/csharp/DistribTest/App.config
deleted file mode 100644
index 30d3e09..0000000
--- a/test/distrib/csharp/DistribTest/App.config
+++ /dev/null
@@ -1,14 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<configuration>
-    <startup> 
-        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
-    </startup>
-  <runtime>
-    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
-      <dependentAssembly>
-        <assemblyIdentity name="System.Net.Http.Primitives" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
-        <bindingRedirect oldVersion="0.0.0.0-4.2.29.0" newVersion="4.2.29.0" />
-      </dependentAssembly>
-    </assemblyBinding>
-  </runtime>
-</configuration>
\ No newline at end of file
diff --git a/test/distrib/csharp/DistribTest/DistribTest.csproj b/test/distrib/csharp/DistribTest/DistribTest.csproj
index 1acb34d..6ca03b2 100644
--- a/test/distrib/csharp/DistribTest/DistribTest.csproj
+++ b/test/distrib/csharp/DistribTest/DistribTest.csproj
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
   <PropertyGroup>
     <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@@ -41,6 +41,8 @@
     <ErrorReport>prompt</ErrorReport>
     <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
     <Prefer32Bit>true</Prefer32Bit>
+    <WarningLevel>4</WarningLevel>
+    <Optimize>false</Optimize>
   </PropertyGroup>
   <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
     <OutputPath>bin\x64\Release\</OutputPath>
@@ -51,39 +53,15 @@
     <ErrorReport>prompt</ErrorReport>
     <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
     <Prefer32Bit>true</Prefer32Bit>
+    <WarningLevel>4</WarningLevel>
   </PropertyGroup>
   <ItemGroup>
-    <Reference Include="BouncyCastle.Crypto">
-      <HintPath>..\packages\BouncyCastle.1.7.0\lib\Net40-Client\BouncyCastle.Crypto.dll</HintPath>
-    </Reference>
-    <Reference Include="Google.Apis.Auth">
-      <HintPath>..\packages\Google.Apis.Auth.1.9.3\lib\net40\Google.Apis.Auth.dll</HintPath>
-    </Reference>
-    <Reference Include="Google.Apis.Auth.PlatformServices">
-      <HintPath>..\packages\Google.Apis.Auth.1.9.3\lib\net40\Google.Apis.Auth.PlatformServices.dll</HintPath>
-    </Reference>
-    <Reference Include="Google.Apis.Core">
-      <HintPath>..\packages\Google.Apis.Core.1.9.3\lib\portable-net40+sl50+win+wpa81+wp80\Google.Apis.Core.dll</HintPath>
-    </Reference>
     <Reference Include="Grpc.Auth">
       <HintPath>..\packages\Grpc.Auth.__GRPC_NUGET_VERSION__\lib\net45\Grpc.Auth.dll</HintPath>
     </Reference>
     <Reference Include="Grpc.Core">
       <HintPath>..\packages\Grpc.Core.__GRPC_NUGET_VERSION__\lib\net45\Grpc.Core.dll</HintPath>
     </Reference>
-    <Reference Include="Microsoft.Threading.Tasks">
-      <HintPath>..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.dll</HintPath>
-    </Reference>
-    <Reference Include="Microsoft.Threading.Tasks.Extensions">
-      <HintPath>..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.dll</HintPath>
-    </Reference>
-    <Reference Include="Microsoft.Threading.Tasks.Extensions.Desktop">
-      <HintPath>..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.Extensions.Desktop.dll</HintPath>
-    </Reference>
-    <Reference Include="Newtonsoft.Json, Version=7.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
-      <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
-    </Reference>
     <Reference Include="System" />
     <Reference Include="System.Core" />
     <Reference Include="System.Interactive.Async">
@@ -91,25 +69,33 @@
     </Reference>
     <Reference Include="System.Net" />
     <Reference Include="System.Net.Http" />
-    <Reference Include="System.Net.Http.Extensions">
-      <HintPath>..\packages\Microsoft.Net.Http.2.2.29\lib\net45\System.Net.Http.Extensions.dll</HintPath>
-    </Reference>
-    <Reference Include="System.Net.Http.Primitives">
-      <HintPath>..\packages\Microsoft.Net.Http.2.2.29\lib\net45\System.Net.Http.Primitives.dll</HintPath>
-    </Reference>
     <Reference Include="System.Net.Http.WebRequest" />
     <Reference Include="System.Xml.Linq" />
     <Reference Include="System.Data.DataSetExtensions" />
     <Reference Include="Microsoft.CSharp" />
     <Reference Include="System.Data" />
     <Reference Include="System.Xml" />
+    <Reference Include="BouncyCastle.Crypto">
+      <HintPath>..\packages\BouncyCastle.1.7.0\lib\Net40-Client\BouncyCastle.Crypto.dll</HintPath>
+    </Reference>
+    <Reference Include="Newtonsoft.Json">
+      <HintPath>..\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
+    </Reference>
+    <Reference Include="Google.Apis.Core">
+      <HintPath>..\packages\Google.Apis.Core.1.15.0\lib\net45\Google.Apis.Core.dll</HintPath>
+    </Reference>
+    <Reference Include="Google.Apis.Auth">
+      <HintPath>..\packages\Google.Apis.Auth.1.15.0\lib\net45\Google.Apis.Auth.dll</HintPath>
+    </Reference>
+    <Reference Include="Google.Apis.Auth.PlatformServices">
+      <HintPath>..\packages\Google.Apis.Auth.1.15.0\lib\net45\Google.Apis.Auth.PlatformServices.dll</HintPath>
+    </Reference>
   </ItemGroup>
   <ItemGroup>
     <Compile Include="Program.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
   </ItemGroup>
   <ItemGroup>
-    <None Include="App.config" />
     <None Include="packages.config" />
   </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
@@ -119,9 +105,7 @@
       <ErrorText>This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them.  For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
     </PropertyGroup>
     <Error Condition="!Exists('..\packages\Grpc.Core.__GRPC_NUGET_VERSION__\build\net45\Grpc.Core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Grpc.Core.__GRPC_NUGET_VERSION__\build\net45\Grpc.Core.targets'))" />
-    <Error Condition="!Exists('..\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets'))" />
   </Target>
-  <Import Project="..\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets" Condition="Exists('..\packages\Microsoft.Bcl.Build.1.0.21\build\Microsoft.Bcl.Build.targets')" />
   <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
        Other similar extension points exist, see Microsoft.Common.targets.
   <Target Name="BeforeBuild">
diff --git a/test/distrib/csharp/DistribTest/packages.config b/test/distrib/csharp/DistribTest/packages.config
index 6963019..e5d2d9d 100644
--- a/test/distrib/csharp/DistribTest/packages.config
+++ b/test/distrib/csharp/DistribTest/packages.config
@@ -1,15 +1,11 @@
 <?xml version="1.0" encoding="utf-8"?>
 <packages>
   <package id="BouncyCastle" version="1.7.0" targetFramework="net45" />
-  <package id="Google.Apis.Auth" version="1.9.3" targetFramework="net45" />
-  <package id="Google.Apis.Core" version="1.9.3" targetFramework="net45" />
+  <package id="Google.Apis.Auth" version="1.15.0" targetFramework="net45" />
+  <package id="Google.Apis.Core" version="1.15.0" targetFramework="net45" />
   <package id="Grpc" version="__GRPC_NUGET_VERSION__" targetFramework="net45" />
   <package id="Grpc.Auth" version="__GRPC_NUGET_VERSION__" targetFramework="net45" />
   <package id="Grpc.Core" version="__GRPC_NUGET_VERSION__" targetFramework="net45" />
   <package id="Ix-Async" version="1.2.3" targetFramework="net45" />
-  <package id="Microsoft.Bcl" version="1.1.10" targetFramework="net45" />
-  <package id="Microsoft.Bcl.Async" version="1.0.168" targetFramework="net45" />
-  <package id="Microsoft.Bcl.Build" version="1.0.21" targetFramework="net45" />
-  <package id="Microsoft.Net.Http" version="2.2.29" targetFramework="net45" />
   <package id="Newtonsoft.Json" version="7.0.1" targetFramework="net45" />
 </packages>
diff --git a/test/distrib/python/distribtest.py b/test/distrib/python/distribtest.py
index dc20688..0125ee6 100644
--- a/test/distrib/python/distribtest.py
+++ b/test/distrib/python/distribtest.py
@@ -27,10 +27,10 @@
 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-from grpc.beta import implementations
+import grpc
 
 # This code doesn't do much but makes sure the native extension is loaded
 # which is what we are testing here.
-channel = implementations.insecure_channel('localhost', 1000)
+channel = grpc.insecure_channel('localhost:1000')
 del channel
 print 'Success!'
diff --git a/third_party/thrift b/third_party/thrift
new file mode 160000
index 0000000..bcad917
--- /dev/null
+++ b/third_party/thrift
@@ -0,0 +1 @@
+Subproject commit bcad91771b7f0bff28a1cac1981d7ef2b9bcef3c
diff --git a/tools/buildgen/plugins/expand_version.py b/tools/buildgen/plugins/expand_version.py
index c6cc562..6098cca 100755
--- a/tools/buildgen/plugins/expand_version.py
+++ b/tools/buildgen/plugins/expand_version.py
@@ -85,10 +85,21 @@
       return '%d.%d.%d' % (self.major, self.minor, self.patch)
 
   def php(self):
-    """Version string in PHP style"""
-    """PECL does not allow tag in version string"""
-    return '%d.%d.%d' % (self.major, self.minor, self.patch)
+    """Version string for PHP PECL package"""
+    s = '%d.%d.%d' % (self.major, self.minor, self.patch)
+    if self.tag:
+      if self.tag == 'dev':
+        s += 'dev'
+      elif len(self.tag) >= 3 and self.tag[0:3] == 'pre':
+        s += 'RC%d' % int(self.tag[3:])
+      else:
+        raise Exception('Don\'t know how to translate version tag "%s" to PECL version' % self.tag)
+    return s
 
+  def php_composer(self):
+    """Version string for PHP Composer package"""
+    return '%d.%d.%d' % (self.major, self.minor, self.patch)
+    
 def mako_plugin(dictionary):
   """Expand version numbers:
      - for each language, ensure there's a language_version tag in
diff --git a/tools/distrib/python/grpcio_tools/setup.py b/tools/distrib/python/grpcio_tools/setup.py
index e810599..a07a586 100644
--- a/tools/distrib/python/grpcio_tools/setup.py
+++ b/tools/distrib/python/grpcio_tools/setup.py
@@ -27,6 +27,7 @@
 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
+from distutils import cygwinccompiler
 from distutils import extension
 from distutils import util
 import errno
@@ -68,26 +69,35 @@
 EXTRA_ENV_COMPILE_ARGS = os.environ.get('GRPC_PYTHON_CFLAGS', None)
 EXTRA_ENV_LINK_ARGS = os.environ.get('GRPC_PYTHON_LDFLAGS', None)
 if EXTRA_ENV_COMPILE_ARGS is None:
-  EXTRA_ENV_COMPILE_ARGS = '-fno-wrapv -frtti -std=c++11'
+  EXTRA_ENV_COMPILE_ARGS = '-std=c++11'
   if 'win32' in sys.platform:
-    # We use define flags here and don't directly add to DEFINE_MACROS below to
-    # ensure that the expert user/builder has a way of turning it off (via the
-    # envvars) without adding yet more GRPC-specific envvars.
-    # See https://sourceforge.net/p/mingw-w64/bugs/363/
-    if '32' in platform.architecture()[0]:
-      EXTRA_ENV_COMPILE_ARGS += ' -D_ftime=_ftime32 -D_timeb=__timeb32 -D_ftime_s=_ftime32_s'
+    if sys.version_info < (3, 5):
+      # We use define flags here and don't directly add to DEFINE_MACROS below to
+      # ensure that the expert user/builder has a way of turning it off (via the
+      # envvars) without adding yet more GRPC-specific envvars.
+      # See https://sourceforge.net/p/mingw-w64/bugs/363/
+      if '32' in platform.architecture()[0]:
+        EXTRA_ENV_COMPILE_ARGS += ' -D_ftime=_ftime32 -D_timeb=__timeb32 -D_ftime_s=_ftime32_s'
+      else:
+        EXTRA_ENV_COMPILE_ARGS += ' -D_ftime=_ftime64 -D_timeb=__timeb64'
     else:
-      EXTRA_ENV_COMPILE_ARGS += ' -D_ftime=_ftime64 -D_timeb=__timeb64'
+      # We need to statically link the C++ Runtime, only the C runtime is
+      # available dynamically
+      EXTRA_ENV_COMPILE_ARGS += ' /MT'
+  elif "linux" in sys.platform or "darwin" in sys.platform:
+    EXTRA_ENV_COMPILE_ARGS += ' -fno-wrapv -frtti'
 if EXTRA_ENV_LINK_ARGS is None:
-  EXTRA_ENV_LINK_ARGS = '-lpthread'
-  if 'win32' in sys.platform:
-    # TODO(atash) check if this is actually safe to just import and call on
-    # non-Windows (to avoid breaking import style)
-    from distutils.cygwinccompiler import get_msvcr
-    msvcr = get_msvcr()[0]
+  EXTRA_ENV_LINK_ARGS = ''
+  if "linux" in sys.platform or "darwin" in sys.platform:
+    EXTRA_ENV_LINK_ARGS += ' -lpthread'
+  elif "win32" in sys.platform and sys.version_info < (3, 5):
+    msvcr = cygwinccompiler.get_msvcr()[0]
+    # TODO(atash) sift through the GCC specs to see if libstdc++ can have any
+    # influence on the linkage outcome on MinGW for non-C++ programs.
     EXTRA_ENV_LINK_ARGS += (
         ' -static-libgcc -static-libstdc++ -mcrtdll={msvcr} '
         '-static'.format(msvcr=msvcr))
+
 EXTRA_COMPILE_ARGS = shlex.split(EXTRA_ENV_COMPILE_ARGS)
 EXTRA_LINK_ARGS = shlex.split(EXTRA_ENV_LINK_ARGS)
 
@@ -101,9 +111,13 @@
 GRPC_PYTHON_TOOLS_PACKAGE = 'grpc.tools'
 GRPC_PYTHON_PROTO_RESOURCES_NAME = '_proto'
 
-DEFINE_MACROS = (('HAVE_PTHREAD', 1),)
-if "win32" in sys.platform and '64bit' in platform.architecture()[0]:
-  DEFINE_MACROS += (('MS_WIN64', 1),)
+DEFINE_MACROS = ()
+if "win32" in sys.platform:
+  DEFINE_MACROS += (('WIN32_LEAN_AND_MEAN', 1),)
+  if '64bit' in platform.architecture()[0]:
+    DEFINE_MACROS += (('MS_WIN64', 1),)
+elif "linux" in sys.platform or "darwin" in sys.platform:
+  DEFINE_MACROS += (('HAVE_PTHREAD', 1),)
 
 # By default, Python3 distutils enforces compatibility of
 # c plugins (.so files) with the OSX version Python3 was built with.
@@ -178,7 +192,7 @@
   namespace_packages=['grpc'],
   install_requires=[
     'protobuf>=3.0.0',
-    'grpcio>=0.15.0',
+    'grpcio>={version}'.format(version=grpc_version.VERSION),
   ],
   package_data=package_data(),
 )
diff --git a/tools/distrib/python/make_grpcio_tools.py b/tools/distrib/python/make_grpcio_tools.py
index adf5844..7413928 100755
--- a/tools/distrib/python/make_grpcio_tools.py
+++ b/tools/distrib/python/make_grpcio_tools.py
@@ -88,22 +88,23 @@
     os.path.join(os.path.dirname(os.path.abspath(__file__)),
                  '..', '..', '..'))
 
-GRPC_PYTHON_ROOT = os.path.join(GRPC_ROOT, 'tools/distrib/python/grpcio_tools')
+GRPC_PYTHON_ROOT = os.path.join(GRPC_ROOT, 'tools', 'distrib',
+                                'python', 'grpcio_tools')
 
-GRPC_PYTHON_PROTOBUF_RELATIVE_ROOT = 'third_party/protobuf/src'
+GRPC_PYTHON_PROTOBUF_RELATIVE_ROOT = os.path.join('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')
-GRPC_PYTHON_PROTOC_PLUGINS = os.path.join(GRPC_PYTHON_ROOT,
-                                          'grpc_root/src/compiler')
+GRPC_PROTOC_PLUGINS = os.path.join(GRPC_ROOT, 'src', 'compiler')
+GRPC_PYTHON_PROTOBUF = os.path.join(GRPC_PYTHON_ROOT, 'third_party', 'protobuf',
+                                    'src')
+GRPC_PYTHON_PROTOC_PLUGINS = os.path.join(GRPC_PYTHON_ROOT, 'grpc_root', 'src',
+                                          'compiler')
 GRPC_PYTHON_PROTOC_LIB_DEPS = os.path.join(GRPC_PYTHON_ROOT,
                                            'protoc_lib_deps.py')
 
 GRPC_INCLUDE = os.path.join(GRPC_ROOT, 'include')
-GRPC_PYTHON_INCLUDE = os.path.join(GRPC_PYTHON_ROOT, 'grpc_root/include')
+GRPC_PYTHON_INCLUDE = os.path.join(GRPC_PYTHON_ROOT, 'grpc_root', 'include')
 
-BAZEL_DEPS = os.path.join(GRPC_ROOT, 'tools/distrib/python/bazel_deps.sh')
+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'
 
@@ -136,64 +137,6 @@
   else:
     return path
 
-def atomic_file_copy(src, dst):
-  """Based on the lock-free-whack-a-mole algorithm, depending on filesystem
-     renaming being atomic. Described at http://stackoverflow.com/a/28090883.
-  """
-  try:
-    if filecmp.cmp(src, dst):
-      return
-  except:
-    pass
-  dst_dir = os.path.abspath(os.path.dirname(dst))
-  dst_base = os.path.basename(dst)
-  this_id = str(uuid.uuid4()).replace('.', '-')
-  temporary_file = os.path.join(dst_dir, '{}.{}.tmp'.format(dst_base, this_id))
-  mole_file = os.path.join(dst_dir, '{}.{}.mole.tmp'.format(dst_base, this_id))
-  mole_pattern = os.path.join(dst_dir, '{}.*.mole.tmp'.format(dst_base))
-  src = long_path(src)
-  dst = long_path(dst)
-  temporary_file = long_path(temporary_file)
-  mole_file = long_path(mole_file)
-  mole_pattern = long_path(mole_pattern)
-  shutil.copy2(src, temporary_file)
-  try:
-    os.rename(temporary_file, mole_file)
-  except:
-    print('Error moving temporary file {} to {}'.format(temporary_file, mole_file), file=sys.stderr)
-    print('while trying to copy file {} to {}'.format(src, dst), file=sys.stderr)
-    raise
-  for other_file in glob.glob(mole_pattern):
-    other_id = other_file.split('.')[-3]
-    if this_id == other_id:
-      pass
-    elif this_id < other_id:
-      try:
-        os.remove(other_file)
-      except:
-        pass
-    else:
-      try:
-        os.remove(mole_file)
-      except:
-        pass
-      this_id = other_id
-      mole_file = other_file
-  try:
-    if filecmp.cmp(src, dst):
-      try:
-        os.remove(mole_file)
-      except:
-        pass
-      return
-  except:
-    pass
-  try:
-    os.rename(mole_file, dst)
-  except:
-    pass
-
-
 def main():
   os.chdir(GRPC_ROOT)
 
@@ -211,7 +154,7 @@
       for relative_file in files:
         source_file = os.path.abspath(os.path.join(source_dir, relative_file))
         target_file = os.path.abspath(os.path.join(target_dir, relative_file))
-        atomic_file_copy(source_file, target_file)
+        shutil.copyfile(source_file, target_file)
 
   try:
     protoc_lib_deps_content = get_deps()
diff --git a/tools/dockerfile/test/python_pyenv_x64/Dockerfile b/tools/dockerfile/test/python_pyenv_x64/Dockerfile
index abb5f3c..ecd785a 100644
--- a/tools/dockerfile/test/python_pyenv_x64/Dockerfile
+++ b/tools/dockerfile/test/python_pyenv_x64/Dockerfile
@@ -95,7 +95,8 @@
 RUN pyenv update
 RUN pyenv install 3.5-dev
 RUN pyenv install 3.6-dev
-RUN pyenv local 3.5-dev 3.6-dev
+RUN pyenv install pypy-5.3.1
+RUN pyenv local 3.5-dev 3.6-dev pypy-5.3.1
 
 # Prepare ccache
 RUN ln -s /usr/bin/ccache /usr/local/bin/gcc
diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++
index a2415e1..314a42d 100644
--- a/tools/doxygen/Doxyfile.c++
+++ b/tools/doxygen/Doxyfile.c++
@@ -807,6 +807,34 @@
 include/grpc++/support/stub_options.h \
 include/grpc++/support/sync_stream.h \
 include/grpc++/support/time.h \
+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/grpc_security_constants.h \
+include/grpc/status.h \
+include/grpc/impl/codegen/byte_buffer.h \
+include/grpc/impl/codegen/byte_buffer_reader.h \
+include/grpc/impl/codegen/compression_types.h \
+include/grpc/impl/codegen/connectivity_state.h \
+include/grpc/impl/codegen/grpc_types.h \
+include/grpc/impl/codegen/propagation_bits.h \
+include/grpc/impl/codegen/status.h \
+include/grpc/impl/codegen/alloc.h \
+include/grpc/impl/codegen/atm.h \
+include/grpc/impl/codegen/atm_gcc_atomic.h \
+include/grpc/impl/codegen/atm_gcc_sync.h \
+include/grpc/impl/codegen/atm_windows.h \
+include/grpc/impl/codegen/log.h \
+include/grpc/impl/codegen/port_platform.h \
+include/grpc/impl/codegen/slice.h \
+include/grpc/impl/codegen/slice_buffer.h \
+include/grpc/impl/codegen/sync.h \
+include/grpc/impl/codegen/sync_generic.h \
+include/grpc/impl/codegen/sync_posix.h \
+include/grpc/impl/codegen/sync_windows.h \
+include/grpc/impl/codegen/time.h \
 include/grpc++/impl/codegen/async_stream.h \
 include/grpc++/impl/codegen/async_unary_call.h \
 include/grpc++/impl/codegen/call.h \
@@ -836,28 +864,7 @@
 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/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 95c0e85..12eb651 100644
--- a/tools/doxygen/Doxyfile.c++.internal
+++ b/tools/doxygen/Doxyfile.c++.internal
@@ -807,6 +807,34 @@
 include/grpc++/support/stub_options.h \
 include/grpc++/support/sync_stream.h \
 include/grpc++/support/time.h \
+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/grpc_security_constants.h \
+include/grpc/status.h \
+include/grpc/impl/codegen/byte_buffer.h \
+include/grpc/impl/codegen/byte_buffer_reader.h \
+include/grpc/impl/codegen/compression_types.h \
+include/grpc/impl/codegen/connectivity_state.h \
+include/grpc/impl/codegen/grpc_types.h \
+include/grpc/impl/codegen/propagation_bits.h \
+include/grpc/impl/codegen/status.h \
+include/grpc/impl/codegen/alloc.h \
+include/grpc/impl/codegen/atm.h \
+include/grpc/impl/codegen/atm_gcc_atomic.h \
+include/grpc/impl/codegen/atm_gcc_sync.h \
+include/grpc/impl/codegen/atm_windows.h \
+include/grpc/impl/codegen/log.h \
+include/grpc/impl/codegen/port_platform.h \
+include/grpc/impl/codegen/slice.h \
+include/grpc/impl/codegen/slice_buffer.h \
+include/grpc/impl/codegen/sync.h \
+include/grpc/impl/codegen/sync_generic.h \
+include/grpc/impl/codegen/sync_posix.h \
+include/grpc/impl/codegen/sync_windows.h \
+include/grpc/impl/codegen/time.h \
 include/grpc++/impl/codegen/async_stream.h \
 include/grpc++/impl/codegen/async_unary_call.h \
 include/grpc++/impl/codegen/call.h \
@@ -837,27 +865,6 @@
 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/core_codegen.h \
 src/cpp/client/secure_credentials.h \
 src/cpp/common/secure_auth_context.h \
@@ -866,6 +873,86 @@
 src/cpp/common/channel_filter.h \
 src/cpp/server/dynamic_thread_pool.h \
 src/cpp/server/thread_pool_interface.h \
+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/handshaker.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/error.h \
+src/core/lib/iomgr/ev_epoll_linux.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/load_file.h \
+src/core/lib/iomgr/network_status_tracker.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/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/timeout_encoding.h \
+src/core/lib/transport/transport.h \
+src/core/lib/transport/transport_impl.h \
 src/cpp/client/secure_credentials.cc \
 src/cpp/common/auth_property_iterator.cc \
 src/cpp/common/secure_auth_context.cc \
@@ -899,6 +986,95 @@
 src/cpp/util/status.cc \
 src/cpp/util/string_ref.cc \
 src/cpp/util/time.cc \
+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/handshaker.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/error.c \
+src/core/lib/iomgr/ev_epoll_linux.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/load_file.c \
+src/core/lib/iomgr/network_status_tracker.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/timeout_encoding.c \
+src/core/lib/transport/transport.c \
+src/core/lib/transport/transport_op_string.c \
 src/cpp/codegen/codegen_init.cc
 
 # This tag can be used to specify the character encoding of the source files
diff --git a/tools/doxygen/Doxyfile.core b/tools/doxygen/Doxyfile.core
index e631c96..27f878e 100644
--- a/tools/doxygen/Doxyfile.core
+++ b/tools/doxygen/Doxyfile.core
@@ -765,6 +765,7 @@
 include/grpc/compression.h \
 include/grpc/grpc.h \
 include/grpc/grpc_posix.h \
+include/grpc/grpc_security_constants.h \
 include/grpc/status.h \
 include/grpc/impl/codegen/byte_buffer.h \
 include/grpc/impl/codegen/byte_buffer_reader.h \
@@ -788,7 +789,6 @@
 include/grpc/impl/codegen/sync_windows.h \
 include/grpc/impl/codegen/time.h \
 include/grpc/grpc_security.h \
-include/grpc/grpc_security_constants.h \
 include/grpc/census.h \
 include/grpc/support/alloc.h \
 include/grpc/support/atm.h \
diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal
index dcb11bd..426c6d9 100644
--- a/tools/doxygen/Doxyfile.core.internal
+++ b/tools/doxygen/Doxyfile.core.internal
@@ -765,6 +765,7 @@
 include/grpc/compression.h \
 include/grpc/grpc.h \
 include/grpc/grpc_posix.h \
+include/grpc/grpc_security_constants.h \
 include/grpc/status.h \
 include/grpc/impl/codegen/byte_buffer.h \
 include/grpc/impl/codegen/byte_buffer_reader.h \
@@ -788,7 +789,6 @@
 include/grpc/impl/codegen/sync_windows.h \
 include/grpc/impl/codegen/time.h \
 include/grpc/grpc_security.h \
-include/grpc/grpc_security_constants.h \
 include/grpc/census.h \
 src/core/lib/channel/channel_args.h \
 src/core/lib/channel/channel_stack.h \
diff --git a/tools/gource/gen-all-logs.sh b/tools/gource/gen-all-logs.sh
index 85352c5..ab60c3c 100755
--- a/tools/gource/gen-all-logs.sh
+++ b/tools/gource/gen-all-logs.sh
@@ -41,7 +41,6 @@
   git clone https://github.com/grpc/$repo.git
   cd $repo
   gource --output-custom-log $tmpdir/logs/$repo
-  sed -i .backup "s,\|/,\|/$repo/,g" $tmpdir/logs/$repo
+  sed -i "s,|/,|/$repo/,g" $tmpdir/logs/$repo
 done
-rm $tmpdir/logs/*.backup
 cat $tmpdir/logs/* | sort -n > $outdir/all-logs.txt
diff --git a/tools/gource/gource.sh b/tools/gource/gource.sh
index b3dad5d..5529b32 100755
--- a/tools/gource/gource.sh
+++ b/tools/gource/gource.sh
@@ -34,7 +34,7 @@
   --max-file-lag 0.05           \
   --max-files 0                 \
   -e 0.01                       \
-  --hide filenames,dirnames     \
+  --hide filenames,dirnames,mouse,progress     \
   --disable-auto-rotate         \
   --file-filter '/grpc/doc/ref' \
   $*
diff --git a/tools/gource/make-video.sh b/tools/gource/make-video.sh
index 02d79df..cde0437 100755
--- a/tools/gource/make-video.sh
+++ b/tools/gource/make-video.sh
@@ -37,7 +37,7 @@
   --stop-at-end         \
   --output-ppm-stream - \
   $@ |                  \
-ffmpeg                  \
+avconv                  \
   -y                    \
   -r 60                 \
   -f image2pipe         \
diff --git a/examples/ruby/lib/helloworld_services.rb b/tools/grift/Dockerfile
similarity index 60%
copy from examples/ruby/lib/helloworld_services.rb
copy to tools/grift/Dockerfile
index fbec667..223ee93 100644
--- a/examples/ruby/lib/helloworld_services.rb
+++ b/tools/grift/Dockerfile
@@ -1,7 +1,4 @@
-# Generated by the protocol buffer compiler.  DO NOT EDIT!
-# Source: helloworld.proto for package 'helloworld'
-# Original file comments:
-# Copyright 2015, Google Inc.
+# Copyright 2016, Google Inc.
 # All rights reserved.
 #
 # Redistribution and use in source and binary forms, with or without
@@ -29,26 +26,42 @@
 # 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'
+FROM ubuntu:14.04
 
-module Helloworld
-  module Greeter
-    # The greeting service definition.
-    class Service
+RUN apt-get update && \
+  apt-get install -y \
+  git build-essential \
+  pkg-config flex \
+  bison \
+  libkrb5-dev \
+  libsasl2-dev \
+  libnuma-dev \
+  pkg-config \
+  libssl-dev \
+  autoconf libtool \
+  cmake \
+  libiberty-dev \
+  g++ unzip \
+  curl make automake libtool libboost-dev
 
-      include GRPC::GenericService
+# Configure git
+RUN git config --global user.name "Jenkins" && \
+  git config --global user.email "jenkins@grpc"
 
-      self.marshal_class_method = :encode
-      self.unmarshal_class_method = :decode
-      self.service_name = 'helloworld.Greeter'
+# Clone gRPC
+RUN git clone https://github.com/grpc/grpc
 
-      # Sends a greeting
-      rpc :SayHello, HelloRequest, HelloReply
-    end
+# Update Submodules
+RUN cd grpc && git submodule update --init
 
-    Stub = Service.rpc_stub_class
-  end
-end
+# Install protobuf
+RUN cd grpc/third_party/protobuf && ./autogen.sh && ./configure && \
+  make -j && make check -j && make install && ldconfig
+
+# Install gRPC
+RUN cd grpc && make -j && make install
+
+# Install thrift
+RUN cd grpc/third_party/thrift && git am --signoff < ../../tools/grift/grpc_plugins_generator.patch && \
+  ./bootstrap.sh && ./configure && make -j && make install
\ No newline at end of file
diff --git a/tools/grift/README.md b/tools/grift/README.md
new file mode 100644
index 0000000..7cbbdc5
--- /dev/null
+++ b/tools/grift/README.md
@@ -0,0 +1,26 @@
+Copyright 2016 Google Inc.
+
+#Documentation
+
+grift is integration of [Apache Thrift](https://github.com/apache/thrift.git) Serializer with gRPC.
+
+This integration allows you to use grpc to send thrift messages in C++ and java.
+
+grift uses Compact Protocol to serialize thrift messages. 
+
+##generating grpc plugins for thrift services
+
+###CPP
+```sh
+ $ thrift --gen cpp <thrift-file>
+```
+
+###JAVA
+```sh
+ $ thrift --gen java <thrift-file>
+```
+
+#Installation
+
+Before Installing thrift make sure to apply this [patch](grpc_plugins_generator.patch) to third_party/thrift.
+Go to third_party/thrift and follow the [INSTALLATION](https://github.com/apache/thrift.git) instructions to install thrift with commit id bcad91771b7f0bff28a1cac1981d7ef2b9bcef3c.
\ No newline at end of file
diff --git a/tools/grift/grpc_plugins_generator.patch b/tools/grift/grpc_plugins_generator.patch
new file mode 100644
index 0000000..de82a01
--- /dev/null
+++ b/tools/grift/grpc_plugins_generator.patch
@@ -0,0 +1,2505 @@
+From 0894590b5020c38106d4ebb2291994668c64f9dd Mon Sep 17 00:00:00 2001
+From: chedeti <chedeti@google.com>
+Date: Sun, 31 Jul 2016 15:47:47 -0700
+Subject: [PATCH 1/3] don't build tests
+
+---
+ Makefile.am         | 7 ++-----
+ lib/cpp/Makefile.am | 7 ++-----
+ 2 files changed, 4 insertions(+), 10 deletions(-)
+
+diff --git a/Makefile.am b/Makefile.am
+index 10fe49a..d49caac 100755
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -21,10 +21,6 @@ ACLOCAL_AMFLAGS = -I ./aclocal
+ 
+ SUBDIRS = compiler/cpp lib
+ 
+-if WITH_TESTS
+-SUBDIRS += test
+-endif
+-
+ if WITH_TUTORIAL
+ SUBDIRS += tutorial
+ endif
+@@ -117,4 +113,5 @@ EXTRA_DIST = \
+ 	CHANGES \
+ 	NOTICE \
+ 	README.md \
+-	Thrift.podspec
++	Thrift.podspec \
++	test
+diff --git a/lib/cpp/Makefile.am b/lib/cpp/Makefile.am
+index 6fd15d2..7de1fad 100755
+--- a/lib/cpp/Makefile.am
++++ b/lib/cpp/Makefile.am
+@@ -27,10 +27,6 @@ moc__%.cpp: %.h
+ 
+ SUBDIRS = .
+ 
+-if WITH_TESTS
+-SUBDIRS += test
+-endif
+-
+ pkgconfigdir = $(libdir)/pkgconfig
+ 
+ lib_LTLIBRARIES = libthrift.la
+@@ -277,7 +273,8 @@ EXTRA_DIST = \
+              thrift-qt.pc.in \
+              thrift-qt5.pc.in \
+              src/thrift/qt/CMakeLists.txt \
+-             $(WINDOWS_DIST)
++             $(WINDOWS_DIST) \
++             test
+ 
+ style-local:
+ 	$(CPPSTYLE_CMD)
+-- 
+2.8.0.rc3.226.g39d4020
+
+
+From 387e4300bc9d98176a92a7c010621443a538e7f2 Mon Sep 17 00:00:00 2001
+From: chedeti <chedeti@google.com>
+Date: Sun, 31 Jul 2016 16:16:40 -0700
+Subject: [PATCH 2/3] grpc cpp plugins generator with example
+
+---
+ compiler/cpp/src/generate/t_cpp_generator.cc | 489 +++++++++++++++++++++++----
+ tutorial/cpp/CMakeLists.txt                  |  53 ---
+ tutorial/cpp/CppClient.cpp                   |  80 -----
+ tutorial/cpp/CppServer.cpp                   | 181 ----------
+ tutorial/cpp/GriftClient.cpp                 |  93 +++++
+ tutorial/cpp/GriftServer.cpp                 |  93 +++++
+ tutorial/cpp/Makefile.am                     |  66 ++--
+ tutorial/cpp/test.thrift                     |  13 +
+ 8 files changed, 652 insertions(+), 416 deletions(-)
+ delete mode 100644 tutorial/cpp/CMakeLists.txt
+ delete mode 100644 tutorial/cpp/CppClient.cpp
+ delete mode 100644 tutorial/cpp/CppServer.cpp
+ create mode 100644 tutorial/cpp/GriftClient.cpp
+ create mode 100644 tutorial/cpp/GriftServer.cpp
+ create mode 100644 tutorial/cpp/test.thrift
+
+diff --git a/compiler/cpp/src/generate/t_cpp_generator.cc b/compiler/cpp/src/generate/t_cpp_generator.cc
+index 6c04899..1557241 100644
+--- a/compiler/cpp/src/generate/t_cpp_generator.cc
++++ b/compiler/cpp/src/generate/t_cpp_generator.cc
+@@ -162,6 +162,8 @@ public:
+                                  bool specialized = false);
+   void generate_function_helpers(t_service* tservice, t_function* tfunction);
+   void generate_service_async_skeleton(t_service* tservice);
++  void generate_service_stub_interface(t_service* tservice);
++  void generate_service_stub(t_service* tservice);
+ 
+   /**
+    * Serialization constructs
+@@ -883,10 +885,10 @@ void t_cpp_generator::generate_struct_declaration(ofstream& out,
+                                                   bool is_user_struct) {
+   string extends = "";
+   if (is_exception) {
+-    extends = " : public ::apache::thrift::TException";
++    extends = " : public apache::thrift::TException";
+   } else {
+-    if (is_user_struct && !gen_templates_) {
+-      extends = " : public virtual ::apache::thrift::TBase";
++    if (!gen_templates_) {
++      extends = " : public virtual apache::thrift::TBase";
+     }
+   }
+ 
+@@ -1130,9 +1132,15 @@ void t_cpp_generator::generate_struct_definition(ofstream& out,
+   vector<t_field*>::const_iterator m_iter;
+   const vector<t_field*>& members = tstruct->get_members();
+ 
++  string method_prefix = "";
++  if (service_name_ != "") {
++    method_prefix = service_name_ + "::";
++  }
++
+   // Destructor
+   if (tstruct->annotations_.find("final") == tstruct->annotations_.end()) {
+-    force_cpp_out << endl << indent() << tstruct->get_name() << "::~" << tstruct->get_name()
++    force_cpp_out << endl << indent() << method_prefix <<
++    tstruct->get_name() << "::~" << tstruct->get_name()
+                   << "() throw() {" << endl;
+     indent_up();
+ 
+@@ -1145,12 +1153,14 @@ void t_cpp_generator::generate_struct_definition(ofstream& out,
+     for (m_iter = members.begin(); m_iter != members.end(); ++m_iter) {
+       if (is_reference((*m_iter))) {
+         std::string type = type_name((*m_iter)->get_type());
+-        out << endl << indent() << "void " << tstruct->get_name() << "::__set_"
++        out << endl << indent() << "void " << method_prefix
++            << tstruct->get_name() << "::__set_"
+             << (*m_iter)->get_name() << "(boost::shared_ptr<"
+             << type_name((*m_iter)->get_type(), false, false) << ">";
+         out << " val) {" << endl;
+       } else {
+-        out << endl << indent() << "void " << tstruct->get_name() << "::__set_"
++        out << endl << indent() << "void " << method_prefix
++            << tstruct->get_name() << "::__set_"
+             << (*m_iter)->get_name() << "(" << type_name((*m_iter)->get_type(), false, true);
+         out << " val) {" << endl;
+       }
+@@ -1177,11 +1187,16 @@ void t_cpp_generator::generate_struct_definition(ofstream& out,
+  * @param tstruct The struct
+  */
+ void t_cpp_generator::generate_struct_reader(ofstream& out, t_struct* tstruct, bool pointers) {
++  string method_prefix = "";
++  if (service_name_ != "") {
++    method_prefix = service_name_ + "::";
++  }
++
+   if (gen_templates_) {
+     out << indent() << "template <class Protocol_>" << endl << indent() << "uint32_t "
+-        << tstruct->get_name() << "::read(Protocol_* iprot) {" << endl;
++        << method_prefix << tstruct->get_name() << "::read(Protocol_* iprot) {" << endl;
+   } else {
+-    indent(out) << "uint32_t " << tstruct->get_name()
++    indent(out) << "uint32_t " << method_prefix << tstruct->get_name()
+                 << "::read(::apache::thrift::protocol::TProtocol* iprot) {" << endl;
+   }
+   indent_up();
+@@ -1301,14 +1316,18 @@ void t_cpp_generator::generate_struct_reader(ofstream& out, t_struct* tstruct, b
+  */
+ void t_cpp_generator::generate_struct_writer(ofstream& out, t_struct* tstruct, bool pointers) {
+   string name = tstruct->get_name();
++  string method_prefix = "";
++  if (service_name_ != "") {
++    method_prefix = service_name_ + "::";
++  }
+   const vector<t_field*>& fields = tstruct->get_sorted_members();
+   vector<t_field*>::const_iterator f_iter;
+ 
+   if (gen_templates_) {
+     out << indent() << "template <class Protocol_>" << endl << indent() << "uint32_t "
+-        << tstruct->get_name() << "::write(Protocol_* oprot) const {" << endl;
++        << method_prefix << tstruct->get_name() << "::write(Protocol_* oprot) const {" << endl;
+   } else {
+-    indent(out) << "uint32_t " << tstruct->get_name()
++    indent(out) << "uint32_t " << method_prefix << tstruct->get_name()
+                 << "::write(::apache::thrift::protocol::TProtocol* oprot) const {" << endl;
+   }
+   indent_up();
+@@ -1369,14 +1388,18 @@ void t_cpp_generator::generate_struct_result_writer(ofstream& out,
+                                                     t_struct* tstruct,
+                                                     bool pointers) {
+   string name = tstruct->get_name();
++  string method_prefix = "";
++  if (service_name_ != "") {
++    method_prefix = service_name_ + "::";
++  }
+   const vector<t_field*>& fields = tstruct->get_sorted_members();
+   vector<t_field*>::const_iterator f_iter;
+ 
+   if (gen_templates_) {
+     out << indent() << "template <class Protocol_>" << endl << indent() << "uint32_t "
+-        << tstruct->get_name() << "::write(Protocol_* oprot) const {" << endl;
++        << method_prefix << tstruct->get_name() << "::write(Protocol_* oprot) const {" << endl;
+   } else {
+-    indent(out) << "uint32_t " << tstruct->get_name()
++    indent(out) << "uint32_t " << method_prefix << tstruct->get_name()
+                 << "::write(::apache::thrift::protocol::TProtocol* oprot) const {" << endl;
+   }
+   indent_up();
+@@ -1385,18 +1408,7 @@ void t_cpp_generator::generate_struct_result_writer(ofstream& out,
+ 
+   indent(out) << "xfer += oprot->writeStructBegin(\"" << name << "\");" << endl;
+ 
+-  bool first = true;
+   for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
+-    if (first) {
+-      first = false;
+-      out << endl << indent() << "if ";
+-    } else {
+-      out << " else if ";
+-    }
+-
+-    out << "(this->__isset." << (*f_iter)->get_name() << ") {" << endl;
+-
+-    indent_up();
+ 
+     // Write field header
+     out << indent() << "xfer += oprot->writeFieldBegin("
+@@ -1410,9 +1422,6 @@ void t_cpp_generator::generate_struct_result_writer(ofstream& out,
+     }
+     // Write field closer
+     indent(out) << "xfer += oprot->writeFieldEnd();" << endl;
+-
+-    indent_down();
+-    indent(out) << "}";
+   }
+ 
+   // Write the struct map
+@@ -1478,9 +1487,13 @@ void t_cpp_generator::generate_struct_ostream_operator(std::ofstream& out, t_str
+ }
+ 
+ void t_cpp_generator::generate_struct_print_method_decl(std::ofstream& out, t_struct* tstruct) {
++  string method_prefix = "";
++  if (service_name_ != "") {
++    method_prefix = service_name_ + "::";
++  }
+   out << "void ";
+   if (tstruct) {
+-    out << tstruct->get_name() << "::";
++    out << method_prefix << tstruct->get_name() << "::";
+   }
+   out << "printTo(std::ostream& out) const";
+ }
+@@ -1601,11 +1614,13 @@ void t_cpp_generator::generate_exception_what_method(std::ofstream& out, t_struc
+  */
+ void t_cpp_generator::generate_service(t_service* tservice) {
+   string svcname = tservice->get_name();
++  string ns = tservice->get_program()->get_namespace("cpp");
+ 
+   // Make output files
+-  string f_header_name = get_out_dir() + svcname + ".h";
++  string f_header_name = get_out_dir() + svcname + ".grpc.thrift.h";
+   f_header_.open(f_header_name.c_str());
+ 
++
+   // Print header file includes
+   f_header_ << autogen_comment();
+   f_header_ << "#ifndef " << svcname << "_H" << endl << "#define " << svcname << "_H" << endl
+@@ -1621,15 +1636,38 @@ void t_cpp_generator::generate_service(t_service* tservice) {
+     f_header_ << "#include <thrift/async/TAsyncDispatchProcessor.h>" << endl;
+   }
+   f_header_ << "#include <thrift/async/TConcurrentClientSyncInfo.h>" << endl;
++
+   f_header_ << "#include \"" << get_include_prefix(*get_program()) << program_name_ << "_types.h\""
+             << endl;
+ 
+   t_service* extends_service = tservice->get_extends();
+-  if (extends_service != NULL) {
++  if (extends_service) {
+     f_header_ << "#include \"" << get_include_prefix(*(extends_service->get_program()))
+-              << extends_service->get_name() << ".h\"" << endl;
++              << extends_service->get_name() << ".grpc.thrift.h\"" << endl;
+   }
+ 
++
++  f_header_  <<
++      "#include <grpc++/impl/codegen/async_stream.h>" << endl <<
++      "#include <grpc++/impl/codegen/async_unary_call.h>"  << endl <<
++      "#include <grpc++/impl/codegen/thrift_utils.h>" << endl <<
++      "#include <grpc++/impl/codegen/rpc_method.h>"  << endl <<
++      "#include <grpc++/impl/codegen/service_type.h>"  << endl <<
++      "#include <grpc++/impl/codegen/status.h>" << endl <<
++      "#include <grpc++/impl/codegen/stub_options.h>" << endl <<
++      "#include <grpc++/impl/codegen/sync_stream.h>" << endl;
++
++
++  f_header_  <<
++      endl <<
++      "namespace grpc {" << endl <<
++      "class CompletionQueue;"  << endl <<
++      "class Channel;"  << endl <<
++      "class RpcService;"  << endl <<
++      "class ServerCompletionQueue;"  << endl <<
++      "class ServerContext;" << endl <<
++      "}" << endl;
++
+   f_header_ << endl << ns_open_ << endl << endl;
+ 
+   f_header_ << "#ifdef _WIN32\n"
+@@ -1638,10 +1676,13 @@ void t_cpp_generator::generate_service(t_service* tservice) {
+                "#endif\n\n";
+ 
+   // Service implementation file includes
+-  string f_service_name = get_out_dir() + svcname + ".cpp";
++  string f_service_name = get_out_dir() + svcname + ".grpc.thrift.cpp";
+   f_service_.open(f_service_name.c_str());
+   f_service_ << autogen_comment();
+-  f_service_ << "#include \"" << get_include_prefix(*get_program()) << svcname << ".h\"" << endl;
++
++  f_service_ << "#include \"" <<
++    get_include_prefix(*get_program()) << svcname << ".grpc.thrift.h\"" << endl;
++
+   if (gen_cob_style_) {
+     f_service_ << "#include \"thrift/async/TAsyncChannel.h\"" << endl;
+   }
+@@ -1652,7 +1693,7 @@ void t_cpp_generator::generate_service(t_service* tservice) {
+     string f_service_tcc_name = get_out_dir() + svcname + ".tcc";
+     f_service_tcc_.open(f_service_tcc_name.c_str());
+     f_service_tcc_ << autogen_comment();
+-    f_service_tcc_ << "#include \"" << get_include_prefix(*get_program()) << svcname << ".h\""
++    f_service_tcc_ << "#include \"" << get_include_prefix(*get_program()) << svcname << ".grpc.thrift.h\""
+                    << endl;
+ 
+     f_service_tcc_ << "#ifndef " << svcname << "_TCC" << endl << "#define " << svcname << "_TCC"
+@@ -1663,19 +1704,69 @@ void t_cpp_generator::generate_service(t_service* tservice) {
+     }
+   }
+ 
++  f_service_ <<
++    endl <<
++    "#include <grpc++/impl/codegen/async_stream.h>" << endl <<
++    "#include <grpc++/impl/codegen/async_unary_call.h>" << endl <<
++    "#include <grpc++/impl/codegen/channel_interface.h>" << endl <<
++    "#include <grpc++/impl/codegen/client_unary_call.h>" << endl <<
++    "#include <grpc++/impl/codegen/method_handler_impl.h>" << endl <<
++    "#include <grpc++/impl/codegen/rpc_service_method.h>" << endl <<
++    "#include <grpc++/impl/codegen/service_type.h>" << endl <<
++    "#include <grpc++/impl/codegen/sync_stream.h>" << endl <<
++    endl;
++
+   f_service_ << endl << ns_open_ << endl << endl;
+   f_service_tcc_ << endl << ns_open_ << endl << endl;
+ 
++  vector<t_function*> functions = tservice->get_functions();
++  vector<t_function*>::iterator f_iter;
++
++  f_service_ <<
++    "static const char* " << service_name_ << "_method_names[] = {" << endl;
++
++
++  indent_up();
++
++  for(f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
++    f_service_ <<
++      indent() << "\"/" << ns << "." << service_name_ << "/" << (*f_iter)->get_name() << "\"," << endl;
++  }
++
++
++  t_service* service_iter = extends_service;  
++  while (service_iter) {
++    vector<t_function*> functions = service_iter->get_functions();
++    vector<t_function*>::iterator f_iter;
++
++    for ( f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
++      f_service_ <<
++      indent() << "\"/" << service_iter->get_program()->get_namespace("cpp") <<
++      "." << service_iter->get_name() << "/" << (*f_iter)->get_name() << "\"," << endl;
++    }
++    service_iter = service_iter->get_extends();
++  }
++
++  indent_down();
++  f_service_ <<
++  "};" << endl;
++
++  // Generate service class
++  if ( extends_service) {
++    f_header_ << "class " << service_name_ << " : public " <<
++      type_name(extends_service) << " {" << endl <<
++      "public:" << endl;
++  }
++  else {
++    f_header_ << "class " << service_name_ << "{" << endl <<
++      "public:" << endl;
++  }
++
+   // Generate all the components
+-  generate_service_interface(tservice, "");
+-  generate_service_interface_factory(tservice, "");
+-  generate_service_null(tservice, "");
+   generate_service_helpers(tservice);
+-  generate_service_client(tservice, "");
+-  generate_service_processor(tservice, "");
+-  generate_service_multiface(tservice);
+-  generate_service_skeleton(tservice);
+-  generate_service_client(tservice, "Concurrent");
++  generate_service_interface(tservice, "");
++  generate_service_stub_interface(tservice);
++  generate_service_stub(tservice);
+ 
+   // Generate all the cob components
+   if (gen_cob_style_) {
+@@ -1688,10 +1779,14 @@ void t_cpp_generator::generate_service(t_service* tservice) {
+     generate_service_async_skeleton(tservice);
+   }
+ 
++   // Close service class
++  f_header_ << "};" << endl;
++
+   f_header_ << "#ifdef _WIN32\n"
+                "  #pragma warning( pop )\n"
+                "#endif\n\n";
+ 
++
+   // Close the namespace
+   f_service_ << ns_close_ << endl << endl;
+   f_service_tcc_ << ns_close_ << endl << endl;
+@@ -1729,15 +1824,11 @@ void t_cpp_generator::generate_service_helpers(t_service* tservice) {
+     string name_orig = ts->get_name();
+ 
+     // TODO(dreiss): Why is this stuff not in generate_function_helpers?
+-    ts->set_name(tservice->get_name() + "_" + (*f_iter)->get_name() + "_args");
++    ts->set_name((*f_iter)->get_name() + "Req");
+     generate_struct_declaration(f_header_, ts, false);
+-    generate_struct_definition(out, f_service_, ts, false);
++    generate_struct_definition(out, f_service_, ts, true);
+     generate_struct_reader(out, ts);
+     generate_struct_writer(out, ts);
+-    ts->set_name(tservice->get_name() + "_" + (*f_iter)->get_name() + "_pargs");
+-    generate_struct_declaration(f_header_, ts, false, true, false, true);
+-    generate_struct_definition(out, f_service_, ts, false);
+-    generate_struct_writer(out, ts, true);
+     ts->set_name(name_orig);
+ 
+     generate_function_helpers(tservice, *f_iter);
+@@ -1745,13 +1836,218 @@ void t_cpp_generator::generate_service_helpers(t_service* tservice) {
+ }
+ 
+ /**
++ *  Generates a service Stub Interface
++ *
++ * @param tservice The service to generate a stub for.
++ *
++ */
++void t_cpp_generator::generate_service_stub_interface(t_service* tservice) {
++
++    string extends = "";
++    if (tservice->get_extends()) {
++      extends = " : virtual public " + type_name(tservice->get_extends()) + "::StubInterface";
++    }
++
++    f_header_ <<
++    endl <<
++    "class StubInterface " << extends << " {" << endl;
++    indent_up();
++    f_header_ <<
++    " public:" << endl <<
++    indent() << "virtual ~StubInterface() {}" << endl;
++
++    vector<t_function*> functions = tservice->get_functions();
++    vector<t_function*>::iterator f_iter;
++    for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
++      string function_name = (*f_iter)->get_name();
++      f_header_ <<
++        indent() << "virtual ::grpc::Status " << function_name <<
++        "(::grpc::ClientContext* context, const " << function_name <<
++        "Req& request, " << function_name << "Resp* response) = 0;" << endl;
++    }
++    indent_down();
++    f_header_ <<
++      "};" << endl << endl;
++
++}
++void t_cpp_generator::generate_service_stub(t_service* tservice) {
++    f_header_ <<
++    endl <<
++    "class Stub : public StubInterface {" <<
++    endl;
++
++    indent_up();
++    f_header_ <<
++    " public:" << endl <<
++    indent() << "Stub(const std::shared_ptr< ::grpc::ChannelInterface>& channel);" <<
++    endl;
++
++    vector<t_function*> functions = tservice->get_functions();
++    vector<t_function*>::iterator f_iter;
++    for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
++      string function_name = (*f_iter)->get_name();
++      f_header_ <<
++        indent() << "::grpc::Status " << function_name <<
++        "(::grpc::ClientContext* context, const " << function_name <<
++        "Req& request, " << function_name << "Resp* response) override;" << endl;
++    }
++
++    t_service* extends_service = tservice->get_extends();
++    t_service* service_iter = extends_service;
++    while (service_iter) {
++      // generate inherited methods
++      vector<t_function*> functions = service_iter->get_functions();
++      vector<t_function*>::iterator f_iter;
++      for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
++        string function_name = (*f_iter)->get_name();
++        f_header_ <<
++          indent() << "::grpc::Status " << function_name <<
++          "(::grpc::ClientContext* context, const " << function_name <<
++          "Req& request, " << function_name << "Resp* response) override;" << endl;
++      }
++      service_iter = service_iter->get_extends();
++    }
++
++    f_header_ <<
++    endl <<
++    " private:" << endl <<
++    indent() << "std::shared_ptr< ::grpc::ChannelInterface> channel_;" <<
++    endl;
++
++    for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
++      f_header_ <<
++        indent() << "const ::grpc::RpcMethod rpcmethod_" << (*f_iter)->get_name() << "_;" << endl;
++    }
++
++    service_iter = extends_service;
++    while (service_iter) {
++      // generate inherited methods
++      vector<t_function*> functions = service_iter->get_functions();
++      vector<t_function*>::iterator f_iter;
++      for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
++        f_header_ <<
++          indent() << "const ::grpc::RpcMethod rpcmethod_" << (*f_iter)->get_name() << "_;" << endl;
++      }
++      service_iter = service_iter->get_extends();
++    }
++
++    indent_down();
++    f_header_ <<
++      "};" << endl << endl;
++
++    // generate the implementaion of Stub
++    f_service_ <<
++      endl <<
++      service_name_ << "::Stub::Stub(const std::shared_ptr< ::grpc::ChannelInterface>& channel)" << endl;
++
++    indent_up();
++    f_service_ <<
++    indent() << ": channel_(channel)" << endl;
++    int i=0;
++    for(f_iter = functions.begin(); f_iter != functions.end(); ++f_iter , ++i) {
++      f_service_ <<
++        indent() <<
++        ", rpcmethod_" << (*f_iter)->get_name() << "_(" <<
++        service_name_ << "_method_names[" << i << "], ::grpc::RpcMethod::NORMAL_RPC, channel)" << endl;
++    }
++
++    service_iter = extends_service;
++    while (service_iter) {
++      // generate inherited methods
++      vector<t_function*> functions = service_iter->get_functions();
++      vector<t_function*>::iterator f_iter;
++      for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter, ++i) {
++        f_service_ <<
++        indent() <<
++        ", rpcmethod_" << (*f_iter)->get_name() << "_(" <<
++        service_name_ << "_method_names[" << i << "], ::grpc::RpcMethod::NORMAL_RPC, channel)" << endl;
++      }
++      service_iter = service_iter->get_extends();
++    }
++    f_service_ <<
++    indent() << "{}" << endl;
++    indent_down();
++
++    // generate NewStub
++    f_header_ <<
++    endl <<
++    "static std::unique_ptr<Stub> NewStub(const std::shared_ptr\
++    < ::grpc::ChannelInterface>& channel, const ::grpc::StubOptions& options = ::grpc::StubOptions());" <<
++    endl;
++
++    // generate NewStub Implementation
++    f_service_ <<
++    endl <<
++    "std::unique_ptr< " << service_name_ << "::Stub> " << service_name_ << "::NewStub(const std::shared_ptr\
++    < ::grpc::ChannelInterface>& channel, const ::grpc::StubOptions& options) {" << endl;
++
++    indent_up();
++    f_service_ <<
++    indent() << "std::unique_ptr< " << service_name_ << "::Stub> stub(new " << service_name_ <<
++    "::Stub(channel));" << endl <<
++    indent() << "return stub;" << endl;
++    indent_down();
++    f_service_ <<
++    "}" << endl;
++
++    // generate stub methods
++    for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
++      string function_name = (*f_iter)->get_name();
++      f_service_ <<
++        endl <<
++        "::grpc::Status " << service_name_ << "::Stub::" <<  function_name <<
++        "(::grpc::ClientContext* context, const " << service_name_ << "::" <<
++        function_name << "Req& request, " << service_name_ << "::" <<
++        function_name << "Resp* response) {" << endl;
++
++      indent_up();
++      f_service_ <<
++      indent() << "return ::grpc::BlockingUnaryCall(channel_.get(), rpcmethod_" <<
++      function_name << "_, context, request, response);" << endl;
++      indent_down();
++
++      f_service_ <<
++      "}" << endl;
++
++    }
++
++    service_iter = extends_service;
++    while (service_iter) {
++      vector<t_function*> functions = service_iter->get_functions();
++      vector<t_function*>::iterator f_iter;
++      for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
++        string function_name = (*f_iter)->get_name();
++        f_service_ <<
++          endl <<
++          "::grpc::Status " << service_name_ << "::Stub::" <<  function_name <<
++          "(::grpc::ClientContext* context, const " << service_name_ << "::" <<
++          function_name << "Req& request, " << service_name_ << "::" <<
++          function_name << "Resp* response) {" << endl;
++
++        indent_up();
++        f_service_ <<
++        indent() << "return ::grpc::BlockingUnaryCall(channel_.get(), rpcmethod_" <<
++        function_name << "_, context, request, response);" << endl;
++        indent_down();
++
++        f_service_ <<
++        "}" << endl;
++
++      }
++      service_iter = service_iter->get_extends();
++    }
++
++}
++
++
++/**
+  * Generates a service interface definition.
+  *
+  * @param tservice The service to generate a header definition for
+  */
+ void t_cpp_generator::generate_service_interface(t_service* tservice, string style) {
+ 
+-  string service_if_name = service_name_ + style + "If";
++  string service_if_name = "Service";
+   if (style == "CobCl") {
+     // Forward declare the client.
+     string client_name = service_name_ + "CobClient";
+@@ -1764,13 +2060,15 @@ void t_cpp_generator::generate_service_interface(t_service* tservice, string sty
+   }
+ 
+   string extends = "";
+-  if (tservice->get_extends() != NULL) {
+-    extends = " : virtual public " + type_name(tservice->get_extends()) + style + "If";
++  if (tservice->get_extends()) {
++    extends = " : virtual public " + type_name(tservice->get_extends()) + style + "::Service";
+     if (style == "CobCl" && gen_templates_) {
+       // TODO(simpkins): If gen_templates_ is enabled, we currently assume all
+       // parent services were also generated with templates enabled.
+       extends += "T<Protocol_>";
+     }
++  } else {
++    extends = " : public ::grpc::Service";
+   }
+ 
+   if (style == "CobCl" && gen_templates_) {
+@@ -1778,7 +2076,9 @@ void t_cpp_generator::generate_service_interface(t_service* tservice, string sty
+   }
+   f_header_ << "class " << service_if_name << extends << " {" << endl << " public:" << endl;
+   indent_up();
+-  f_header_ << indent() << "virtual ~" << service_if_name << "() {}" << endl;
++
++  f_header_ << indent() << "Service();" << endl;
++  f_header_ << indent() << "virtual ~Service();" << endl;
+ 
+   vector<t_function*> functions = tservice->get_functions();
+   vector<t_function*>::iterator f_iter;
+@@ -1786,7 +2086,12 @@ void t_cpp_generator::generate_service_interface(t_service* tservice, string sty
+     if ((*f_iter)->has_doc())
+       f_header_ << endl;
+     generate_java_doc(f_header_, *f_iter);
+-    f_header_ << indent() << "virtual " << function_signature(*f_iter, style) << " = 0;" << endl;
++
++    string function_name = (*f_iter)->get_name();
++    f_header_ <<
++      indent() << "virtual ::grpc::Status " << function_name <<
++      "(::grpc::ServerContext* context, const "<< function_name <<
++      "Req* request, "<< function_name << "Resp* response);" << endl;
+   }
+   indent_down();
+   f_header_ << "};" << endl << endl;
+@@ -1797,6 +2102,66 @@ void t_cpp_generator::generate_service_interface(t_service* tservice, string sty
+     f_header_ << "typedef " << service_if_name << "< ::apache::thrift::protocol::TProtocol> "
+               << service_name_ << style << "If;" << endl << endl;
+   }
++
++   // generate the service interface implementations
++
++    f_service_ <<
++    endl <<
++    service_name_ << "::Service::Service() {" << endl;
++    indent_up();
++    f_service_ <<
++    indent() << "(void)" << service_name_ << "_method_names;" << endl;
++    uint32_t i=0;
++    for(i=0;i<functions.size(); i++) {
++      string function_name = functions[i]->get_name();
++      f_service_ <<
++        endl <<
++        indent() << "AddMethod(new ::grpc::RpcServiceMethod(" << endl;
++        indent_up();
++
++      f_service_ <<
++        indent() << service_name_ << "_method_names[" << i << "]," << endl <<
++        indent() << "::grpc::RpcMethod::NORMAL_RPC," << endl <<
++        indent() << "new ::grpc::RpcMethodHandler< " << service_name_ << "::Service, " <<
++        service_name_ << "::" << function_name << "Req, " << service_name_ << "::" <<
++        function_name << "Resp>(" << endl;
++
++      indent_up();
++      f_service_ <<
++        indent() << "std::mem_fn(&" << service_name_ << "::Service::" << function_name << "), this)));" << endl;
++
++      indent_down();
++      indent_down();
++    }
++
++    indent_down();
++    f_service_ <<
++    "}" << endl;
++
++    f_service_ <<
++    endl <<
++    service_name_ << "::Service::~Service() {" << endl <<
++    "}" << endl;
++
++    for(f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
++      string function_name = (*f_iter)->get_name();
++      f_service_ <<
++        endl <<
++        "::grpc::Status " << service_name_ << "::Service::" << function_name <<
++        "(::grpc::ServerContext* context, const " << service_name_ << "::" << function_name <<
++        "Req* request, " << service_name_ << "::" << function_name << "Resp* response) {" << endl;
++      indent_up();
++      f_service_ <<
++      indent() << "(void) context;" << endl <<
++      indent() << "(void) request;" << endl <<
++      indent() << "(void) response;" << endl <<
++      indent() << "return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED,\"\");" << endl;
++      indent_down();
++
++      f_service_ <<
++      "}" << endl;
++    }
++
+ }
+ 
+ /**
+@@ -3095,7 +3460,7 @@ void t_cpp_generator::generate_function_helpers(t_service* tservice, t_function*
+ 
+   std::ofstream& out = (gen_templates_ ? f_service_tcc_ : f_service_);
+ 
+-  t_struct result(program_, tservice->get_name() + "_" + tfunction->get_name() + "_result");
++  t_struct result(program_, tfunction->get_name() + "Resp");
+   t_field success(tfunction->get_returntype(), "success", 0);
+   if (!tfunction->get_returntype()->is_void()) {
+     result.append(&success);
+@@ -3109,17 +3474,9 @@ void t_cpp_generator::generate_function_helpers(t_service* tservice, t_function*
+   }
+ 
+   generate_struct_declaration(f_header_, &result, false);
+-  generate_struct_definition(out, f_service_, &result, false);
++  generate_struct_definition(out, f_service_, &result, true);
+   generate_struct_reader(out, &result);
+   generate_struct_result_writer(out, &result);
+-
+-  result.set_name(tservice->get_name() + "_" + tfunction->get_name() + "_presult");
+-  generate_struct_declaration(f_header_, &result, false, true, true, gen_cob_style_);
+-  generate_struct_definition(out, f_service_, &result, false);
+-  generate_struct_reader(out, &result, true);
+-  if (gen_cob_style_) {
+-    generate_struct_writer(out, &result, true);
+-  }
+ }
+ 
+ /**
+@@ -3162,8 +3519,8 @@ void t_cpp_generator::generate_process_function(t_service* tservice,
+         << endl;
+     scope_up(out);
+ 
+-    string argsname = tservice->get_name() + "_" + tfunction->get_name() + "_args";
+-    string resultname = tservice->get_name() + "_" + tfunction->get_name() + "_result";
++    string argsname = tfunction->get_name() + "Req";
++    string resultname = tfunction->get_name() + "Resp";
+ 
+     if (tfunction->is_oneway() && !unnamed_oprot_seqid) {
+       out << indent() << "(void) seqid;" << endl << indent() << "(void) oprot;" << endl;
+@@ -3320,7 +3677,7 @@ void t_cpp_generator::generate_process_function(t_service* tservice,
+       out << indent() << "(void) seqid;" << endl << indent() << "(void) oprot;" << endl;
+     }
+ 
+-    out << indent() << tservice->get_name() + "_" + tfunction->get_name() << "_args args;" << endl
++    out << indent() << tfunction->get_name() << "Req args;" << endl
+         << indent() << "void* ctx = NULL;" << endl << indent()
+         << "if (this->eventHandler_.get() != NULL) {" << endl << indent()
+         << "  ctx = this->eventHandler_->getContext(" << service_func_name << ", NULL);" << endl
+@@ -3487,7 +3844,7 @@ void t_cpp_generator::generate_process_function(t_service* tservice,
+           << "this->eventHandler_.get(), ctx, " << service_func_name << ");" << endl << endl;
+ 
+       // Throw the TDelayedException, and catch the result
+-      out << indent() << tservice->get_name() << "_" << tfunction->get_name() << "_result result;"
++      out << indent() << tfunction->get_name() << "Resp result;"
+           << endl << endl << indent() << "try {" << endl;
+       indent_up();
+       out << indent() << "_throw->throw_it();" << endl << indent() << "return cob(false);"
+diff --git a/tutorial/cpp/CMakeLists.txt b/tutorial/cpp/CMakeLists.txt
+deleted file mode 100644
+index 8a3d085..0000000
+--- a/tutorial/cpp/CMakeLists.txt
++++ /dev/null
+@@ -1,53 +0,0 @@
+-#
+-# Licensed to the Apache Software Foundation (ASF) under one
+-# or more contributor license agreements. See the NOTICE file
+-# distributed with this work for additional information
+-# regarding copyright ownership. The ASF licenses this file
+-# to you under the Apache License, Version 2.0 (the
+-# "License"); you may not use this file except in compliance
+-# with the License. You may obtain a copy of the License at
+-#
+-#   http://www.apache.org/licenses/LICENSE-2.0
+-#
+-# Unless required by applicable law or agreed to in writing,
+-# software distributed under the License is distributed on an
+-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+-# KIND, either express or implied. See the License for the
+-# specific language governing permissions and limitations
+-# under the License.
+-#
+-
+-find_package(Boost 1.53.0 REQUIRED)
+-include_directories(SYSTEM "${Boost_INCLUDE_DIRS}")
+-
+-#Make sure gen-cpp files can be included
+-include_directories("${CMAKE_CURRENT_BINARY_DIR}")
+-include_directories("${CMAKE_CURRENT_BINARY_DIR}/gen-cpp")
+-include_directories("${PROJECT_SOURCE_DIR}/lib/cpp/src")
+-
+-include(ThriftMacros)
+-
+-set(tutorialgencpp_SOURCES 
+-    gen-cpp/Calculator.cpp
+-    gen-cpp/SharedService.cpp
+-    gen-cpp/shared_constants.cpp
+-    gen-cpp/shared_types.cpp
+-    gen-cpp/tutorial_constants.cpp
+-    gen-cpp/tutorial_types.cpp
+-)
+-add_library(tutorialgencpp STATIC ${tutorialgencpp_SOURCES})
+-LINK_AGAINST_THRIFT_LIBRARY(tutorialgencpp thrift)
+-
+-add_custom_command(OUTPUT gen-cpp/Calculator.cpp gen-cpp/SharedService.cpp gen-cpp/shared_constants.cpp gen-cpp/shared_types.cpp gen-cpp/tutorial_constants.cpp gen-cpp/tutorial_types.cpp
+-    COMMAND ${THRIFT_COMPILER} --gen cpp -r ${PROJECT_SOURCE_DIR}/tutorial/tutorial.thrift
+-)
+-
+-add_executable(TutorialServer CppServer.cpp)
+-target_link_libraries(TutorialServer tutorialgencpp)
+-LINK_AGAINST_THRIFT_LIBRARY(TutorialServer thrift)
+-target_link_libraries(TutorialServer ${ZLIB_LIBRARIES})
+-
+-add_executable(TutorialClient CppClient.cpp)
+-target_link_libraries(TutorialClient tutorialgencpp)
+-LINK_AGAINST_THRIFT_LIBRARY(TutorialClient thrift)
+-target_link_libraries(TutorialClient ${ZLIB_LIBRARIES})
+diff --git a/tutorial/cpp/CppClient.cpp b/tutorial/cpp/CppClient.cpp
+deleted file mode 100644
+index 2763fee..0000000
+--- a/tutorial/cpp/CppClient.cpp
++++ /dev/null
+@@ -1,80 +0,0 @@
+-/*
+- * Licensed to the Apache Software Foundation (ASF) under one
+- * or more contributor license agreements. See the NOTICE file
+- * distributed with this work for additional information
+- * regarding copyright ownership. The ASF licenses this file
+- * to you under the Apache License, Version 2.0 (the
+- * "License"); you may not use this file except in compliance
+- * with the License. You may obtain a copy of the License at
+- *
+- *   http://www.apache.org/licenses/LICENSE-2.0
+- *
+- * Unless required by applicable law or agreed to in writing,
+- * software distributed under the License is distributed on an
+- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+- * KIND, either express or implied. See the License for the
+- * specific language governing permissions and limitations
+- * under the License.
+- */
+-
+-#include <iostream>
+-
+-#include <thrift/protocol/TBinaryProtocol.h>
+-#include <thrift/transport/TSocket.h>
+-#include <thrift/transport/TTransportUtils.h>
+-
+-#include "../gen-cpp/Calculator.h"
+-
+-using namespace std;
+-using namespace apache::thrift;
+-using namespace apache::thrift::protocol;
+-using namespace apache::thrift::transport;
+-
+-using namespace tutorial;
+-using namespace shared;
+-
+-int main() {
+-  boost::shared_ptr<TTransport> socket(new TSocket("localhost", 9090));
+-  boost::shared_ptr<TTransport> transport(new TBufferedTransport(socket));
+-  boost::shared_ptr<TProtocol> protocol(new TBinaryProtocol(transport));
+-  CalculatorClient client(protocol);
+-
+-  try {
+-    transport->open();
+-
+-    client.ping();
+-    cout << "ping()" << endl;
+-
+-    cout << "1 + 1 = " << client.add(1, 1) << endl;
+-
+-    Work work;
+-    work.op = Operation::DIVIDE;
+-    work.num1 = 1;
+-    work.num2 = 0;
+-
+-    try {
+-      client.calculate(1, work);
+-      cout << "Whoa? We can divide by zero!" << endl;
+-    } catch (InvalidOperation& io) {
+-      cout << "InvalidOperation: " << io.why << endl;
+-      // or using generated operator<<: cout << io << endl;
+-      // or by using std::exception native method what(): cout << io.what() << endl;
+-    }
+-
+-    work.op = Operation::SUBTRACT;
+-    work.num1 = 15;
+-    work.num2 = 10;
+-    int32_t diff = client.calculate(1, work);
+-    cout << "15 - 10 = " << diff << endl;
+-
+-    // Note that C++ uses return by reference for complex types to avoid
+-    // costly copy construction
+-    SharedStruct ss;
+-    client.getStruct(ss, 1);
+-    cout << "Received log: " << ss << endl;
+-
+-    transport->close();
+-  } catch (TException& tx) {
+-    cout << "ERROR: " << tx.what() << endl;
+-  }
+-}
+diff --git a/tutorial/cpp/CppServer.cpp b/tutorial/cpp/CppServer.cpp
+deleted file mode 100644
+index eafffa9..0000000
+--- a/tutorial/cpp/CppServer.cpp
++++ /dev/null
+@@ -1,181 +0,0 @@
+-/*
+- * Licensed to the Apache Software Foundation (ASF) under one
+- * or more contributor license agreements. See the NOTICE file
+- * distributed with this work for additional information
+- * regarding copyright ownership. The ASF licenses this file
+- * to you under the Apache License, Version 2.0 (the
+- * "License"); you may not use this file except in compliance
+- * with the License. You may obtain a copy of the License at
+- *
+- *   http://www.apache.org/licenses/LICENSE-2.0
+- *
+- * Unless required by applicable law or agreed to in writing,
+- * software distributed under the License is distributed on an
+- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+- * KIND, either express or implied. See the License for the
+- * specific language governing permissions and limitations
+- * under the License.
+- */
+-
+-#include <thrift/concurrency/ThreadManager.h>
+-#include <thrift/concurrency/PlatformThreadFactory.h>
+-#include <thrift/protocol/TBinaryProtocol.h>
+-#include <thrift/server/TSimpleServer.h>
+-#include <thrift/server/TThreadPoolServer.h>
+-#include <thrift/server/TThreadedServer.h>
+-#include <thrift/transport/TServerSocket.h>
+-#include <thrift/transport/TSocket.h>
+-#include <thrift/transport/TTransportUtils.h>
+-#include <thrift/TToString.h>
+-
+-#include <boost/make_shared.hpp>
+-
+-#include <iostream>
+-#include <stdexcept>
+-#include <sstream>
+-
+-#include "../gen-cpp/Calculator.h"
+-
+-using namespace std;
+-using namespace apache::thrift;
+-using namespace apache::thrift::concurrency;
+-using namespace apache::thrift::protocol;
+-using namespace apache::thrift::transport;
+-using namespace apache::thrift::server;
+-
+-using namespace tutorial;
+-using namespace shared;
+-
+-class CalculatorHandler : public CalculatorIf {
+-public:
+-  CalculatorHandler() {}
+-
+-  void ping() { cout << "ping()" << endl; }
+-
+-  int32_t add(const int32_t n1, const int32_t n2) {
+-    cout << "add(" << n1 << ", " << n2 << ")" << endl;
+-    return n1 + n2;
+-  }
+-
+-  int32_t calculate(const int32_t logid, const Work& work) {
+-    cout << "calculate(" << logid << ", " << work << ")" << endl;
+-    int32_t val;
+-
+-    switch (work.op) {
+-    case Operation::ADD:
+-      val = work.num1 + work.num2;
+-      break;
+-    case Operation::SUBTRACT:
+-      val = work.num1 - work.num2;
+-      break;
+-    case Operation::MULTIPLY:
+-      val = work.num1 * work.num2;
+-      break;
+-    case Operation::DIVIDE:
+-      if (work.num2 == 0) {
+-        InvalidOperation io;
+-        io.whatOp = work.op;
+-        io.why = "Cannot divide by 0";
+-        throw io;
+-      }
+-      val = work.num1 / work.num2;
+-      break;
+-    default:
+-      InvalidOperation io;
+-      io.whatOp = work.op;
+-      io.why = "Invalid Operation";
+-      throw io;
+-    }
+-
+-    SharedStruct ss;
+-    ss.key = logid;
+-    ss.value = to_string(val);
+-
+-    log[logid] = ss;
+-
+-    return val;
+-  }
+-
+-  void getStruct(SharedStruct& ret, const int32_t logid) {
+-    cout << "getStruct(" << logid << ")" << endl;
+-    ret = log[logid];
+-  }
+-
+-  void zip() { cout << "zip()" << endl; }
+-
+-protected:
+-  map<int32_t, SharedStruct> log;
+-};
+-
+-/*
+-  CalculatorIfFactory is code generated.
+-  CalculatorCloneFactory is useful for getting access to the server side of the
+-  transport.  It is also useful for making per-connection state.  Without this
+-  CloneFactory, all connections will end up sharing the same handler instance.
+-*/
+-class CalculatorCloneFactory : virtual public CalculatorIfFactory {
+- public:
+-  virtual ~CalculatorCloneFactory() {}
+-  virtual CalculatorIf* getHandler(const ::apache::thrift::TConnectionInfo& connInfo)
+-  {
+-    boost::shared_ptr<TSocket> sock = boost::dynamic_pointer_cast<TSocket>(connInfo.transport);
+-    cout << "Incoming connection\n";
+-    cout << "\tSocketInfo: "  << sock->getSocketInfo() << "\n";
+-    cout << "\tPeerHost: "    << sock->getPeerHost() << "\n";
+-    cout << "\tPeerAddress: " << sock->getPeerAddress() << "\n";
+-    cout << "\tPeerPort: "    << sock->getPeerPort() << "\n";
+-    return new CalculatorHandler;
+-  }
+-  virtual void releaseHandler( ::shared::SharedServiceIf* handler) {
+-    delete handler;
+-  }
+-};
+-
+-int main() {
+-  TThreadedServer server(
+-    boost::make_shared<CalculatorProcessorFactory>(boost::make_shared<CalculatorCloneFactory>()),
+-    boost::make_shared<TServerSocket>(9090), //port
+-    boost::make_shared<TBufferedTransportFactory>(),
+-    boost::make_shared<TBinaryProtocolFactory>());
+-
+-  /*
+-  // if you don't need per-connection state, do the following instead
+-  TThreadedServer server(
+-    boost::make_shared<CalculatorProcessor>(boost::make_shared<CalculatorHandler>()),
+-    boost::make_shared<TServerSocket>(9090), //port
+-    boost::make_shared<TBufferedTransportFactory>(),
+-    boost::make_shared<TBinaryProtocolFactory>());
+-  */
+-
+-  /**
+-   * Here are some alternate server types...
+-
+-  // This server only allows one connection at a time, but spawns no threads
+-  TSimpleServer server(
+-    boost::make_shared<CalculatorProcessor>(boost::make_shared<CalculatorHandler>()),
+-    boost::make_shared<TServerSocket>(9090),
+-    boost::make_shared<TBufferedTransportFactory>(),
+-    boost::make_shared<TBinaryProtocolFactory>());
+-
+-  const int workerCount = 4;
+-
+-  boost::shared_ptr<ThreadManager> threadManager =
+-    ThreadManager::newSimpleThreadManager(workerCount);
+-  threadManager->threadFactory(
+-    boost::make_shared<PlatformThreadFactory>());
+-  threadManager->start();
+-
+-  // This server allows "workerCount" connection at a time, and reuses threads
+-  TThreadPoolServer server(
+-    boost::make_shared<CalculatorProcessorFactory>(boost::make_shared<CalculatorCloneFactory>()),
+-    boost::make_shared<TServerSocket>(9090),
+-    boost::make_shared<TBufferedTransportFactory>(),
+-    boost::make_shared<TBinaryProtocolFactory>(),
+-    threadManager);
+-  */
+-
+-  cout << "Starting the server..." << endl;
+-  server.serve();
+-  cout << "Done." << endl;
+-  return 0;
+-}
+diff --git a/tutorial/cpp/GriftClient.cpp b/tutorial/cpp/GriftClient.cpp
+new file mode 100644
+index 0000000..647a683
+--- /dev/null
++++ b/tutorial/cpp/GriftClient.cpp
+@@ -0,0 +1,93 @@
++/*
++ *
++ * 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 <iostream>
++#include <memory>
++#include <string>
++
++#include <grpc++/grpc++.h>
++
++#include "gen-cpp/Greeter.grpc.thrift.h"
++
++using grpc::Channel;
++using grpc::ClientContext;
++using grpc::Status;
++using test::Greeter;
++
++class GreeterClient {
++ public:
++  GreeterClient(std::shared_ptr<Channel> channel)
++      : stub_(Greeter::NewStub(channel)) {}
++
++  // Assembles the client's payload, sends it and presents the response back
++  // from the server.
++  std::string SayHello(const std::string& user) {
++    // Data we are sending to the server.
++    Greeter::SayHelloReq req;
++    req.request.name = user;
++
++    // Container for the data we expect from the server.
++    Greeter::SayHelloResp reply;
++
++    // Context for the client. It could be used to convey extra information to
++    // the server and/or tweak certain RPC behaviors.
++    ClientContext context;
++
++    // The actual RPC.
++    Status status = stub_->SayHello(&context, req, &reply);
++
++    // Act upon its status.
++    if (status.ok()) {
++      return reply.success.message;
++    } else {
++      return "RPC failed";
++    }
++  }
++
++ private:
++  std::unique_ptr<Greeter::Stub> stub_;
++};
++
++int main() {
++  // Instantiate the client. It requires a channel, out of which the actual RPCs
++  // are created. This channel models a connection to an endpoint (in this case,
++  // localhost at port 50051). We indicate that the channel isn't authenticated
++  // (use of InsecureChannelCredentials()).
++  GreeterClient greeter(grpc::CreateChannel(
++      "localhost:50051", grpc::InsecureChannelCredentials()));
++  std::string user("world");
++  std::string reply = greeter.SayHello(user);
++  std::cout << "Greeter received: " << reply << std::endl;
++
++  return 0;
++}
+diff --git a/tutorial/cpp/GriftServer.cpp b/tutorial/cpp/GriftServer.cpp
+new file mode 100644
+index 0000000..7c01606
+--- /dev/null
++++ b/tutorial/cpp/GriftServer.cpp
+@@ -0,0 +1,93 @@
++/*
++ *
++ * 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 <iostream>
++#include <memory>
++#include <string>
++
++#include <grpc++/grpc++.h>
++
++#include "gen-cpp/Greeter.grpc.thrift.h"
++#include <grpc++/server_builder.h>
++
++using grpc::Server;
++using grpc::ServerBuilder;
++using grpc::ServerContext;
++using grpc::Status;
++using test::Greeter;
++
++// Logic and data behind the server's behavior.
++class GreeterServiceImpl final : public Greeter::Service {
++ public:
++  ~GreeterServiceImpl() {
++    // shutdown server
++    server->Shutdown();
++  }
++
++  Status SayHello(ServerContext* context,const Greeter::SayHelloReq* request,
++                  Greeter::SayHelloResp* reply) override {
++    std::string prefix("Hello ");
++
++    reply->success.message = prefix + request->request.name;
++
++    return Status::OK;
++  }
++
++  void RunServer() {
++    std::string server_address("0.0.0.0:50051");
++
++    ServerBuilder builder;
++    // Listen on the given address without any authentication mechanism.
++    builder.AddListeningPort(server_address, grpc::InsecureServerCredentials());
++    // Register "service" as the instance through which we'll communicate with
++    // clients. In this case it corresponds to an *synchronous* service.
++    builder.RegisterService(this);
++    // Finally assemble the server.
++    server = builder.BuildAndStart();
++    std::cout << "Server listening on " << server_address << std::endl;
++
++    // Wait for the server to shutdown. Note that some other thread must be
++    // responsible for shutting down the server for this call to ever return.
++    server->Wait();
++  }
++
++ private:
++  std::unique_ptr<Server> server;
++};
++
++int main() {
++  GreeterServiceImpl service;
++  service.RunServer();
++
++  return 0;
++}
+diff --git a/tutorial/cpp/Makefile.am b/tutorial/cpp/Makefile.am
+index 184a69d..6f91e28 100755
+--- a/tutorial/cpp/Makefile.am
++++ b/tutorial/cpp/Makefile.am
+@@ -18,44 +18,38 @@
+ #
+ AUTOMAKE_OPTIONS = subdir-objects serial-tests
+ 
+-BUILT_SOURCES = gen-cpp/shared_types.cpp \
+-                gen-cpp/tutorial_types.cpp
++BUILT_SOURCES = gen-cpp/test_types.cpp
+ 
+-noinst_LTLIBRARIES = libtutorialgencpp.la
+-nodist_libtutorialgencpp_la_SOURCES = \
+-	gen-cpp/Calculator.cpp \
+-	gen-cpp/Calculator.h \
+-	gen-cpp/SharedService.cpp \
+-	gen-cpp/SharedService.h \
+-	gen-cpp/shared_constants.cpp \
+-	gen-cpp/shared_constants.h \
+-	gen-cpp/shared_types.cpp \
+-	gen-cpp/shared_types.h \
+-	gen-cpp/tutorial_constants.cpp \
+-	gen-cpp/tutorial_constants.h \
+-	gen-cpp/tutorial_types.cpp \
+-	gen-cpp/tutorial_types.h
++#noinst_LTLIBRARIES = libtutorialgencpp.la
++noinst_LTLIBRARIES = libtestgencpp.la
++nodist_libtestgencpp_la_SOURCES = \
++	gen-cpp/Greeter.grpc.thrift.cpp \
++	gen-cpp/Greeter.grpc.thrift.h \
++	gen-cpp/test_constants.cpp \
++	gen-cpp/test_constants.h \
++	gen-cpp/test_types.cpp \
++	gen-cpp/test_types.h
+ 
+ 
+ 
+-libtutorialgencpp_la_LIBADD = $(top_builddir)/lib/cpp/libthrift.la
++libtestgencpp_la_LIBADD = $(top_builddir)/lib/cpp/libthrift.la
+ 
+ noinst_PROGRAMS = \
+-	TutorialServer \
+-	TutorialClient
++	TestServer \
++	TestClient
+ 
+-TutorialServer_SOURCES = \
+-	CppServer.cpp
++TestServer_SOURCES = \
++	GriftServer.cpp
+ 
+-TutorialServer_LDADD = \
+-	libtutorialgencpp.la \
++TestServer_LDADD = \
++	libtestgencpp.la \
+ 	$(top_builddir)/lib/cpp/libthrift.la
+ 
+-TutorialClient_SOURCES = \
+-	CppClient.cpp
++TestClient_SOURCES = \
++	GriftClient.cpp
+ 
+-TutorialClient_LDADD = \
+-	libtutorialgencpp.la \
++TestClient_LDADD = \
++	libtestgencpp.la \
+ 	$(top_builddir)/lib/cpp/libthrift.la
+ 
+ #
+@@ -63,26 +57,26 @@ TutorialClient_LDADD = \
+ #
+ THRIFT = $(top_builddir)/compiler/cpp/thrift
+ 
+-gen-cpp/Calculator.cpp gen-cpp/SharedService.cpp gen-cpp/shared_constants.cpp gen-cpp/shared_types.cpp gen-cpp/tutorial_constants.cpp gen-cpp/tutorial_types.cpp: $(top_srcdir)/tutorial/tutorial.thrift
++gen-cpp/Greeter.grpc.thrift.cpp gen-cpp/test_constants.cpp gen-cpp/test_types.cpp: $(top_srcdir)/tutorial/cpp/test.thrift
+ 	$(THRIFT) --gen cpp -r $<
+ 
+ AM_CPPFLAGS = $(BOOST_CPPFLAGS) $(LIBEVENT_CPPFLAGS) -I$(top_srcdir)/lib/cpp/src -Igen-cpp
+ AM_CXXFLAGS = -Wall -Wextra -pedantic
+-AM_LDFLAGS = $(BOOST_LDFLAGS) $(LIBEVENT_LDFLAGS)
++AM_LDFLAGS = $(BOOST_LDFLAGS) $(LIBEVENT_LDFLAGS) `pkg-config --libs grpc++ grpc` -lpthread -ldl -lgrpc
+ 
+ clean-local:
+-	$(RM) gen-cpp/*
++	$(RM) -r gen-cpp
+ 
+-tutorialserver: all
+-	./TutorialServer
++testserver: all
++	./TestServer
+ 
+-tutorialclient: all
+-	./TutorialClient
++testclient: all
++	./TestClient
+ 
+ style-local:
+ 	$(CPPSTYLE_CMD)
+ 
+ EXTRA_DIST = \
+ 	CMakeLists.txt \
+-	CppClient.cpp \
+-	CppServer.cpp
++	GriftClient.cpp \
++	GriftServer.cpp
+diff --git a/tutorial/cpp/test.thrift b/tutorial/cpp/test.thrift
+new file mode 100644
+index 0000000..de3c9a4
+--- /dev/null
++++ b/tutorial/cpp/test.thrift
+@@ -0,0 +1,13 @@
++namespace cpp test
++
++struct HelloRequest {
++	1:string name
++}
++
++struct HelloResponse {
++	1:string message
++}
++
++service Greeter {
++	HelloResponse SayHello(1:HelloRequest request);
++}
+\ No newline at end of file
+-- 
+2.8.0.rc3.226.g39d4020
+
+
+From 3e4d75a2e2c474ee7700e7c9acaf89fdb768bedc Mon Sep 17 00:00:00 2001
+From: chedeti <chedeti@google.com>
+Date: Sun, 31 Jul 2016 16:23:53 -0700
+Subject: [PATCH 3/3] grpc java plugins generator
+
+for examples refer to https://github.com/grpc/grpc-java/tree/master/examples/thrift
+---
+ compiler/cpp/src/generate/t_java_generator.cc | 906 +++++++++++++++++++++++++-
+ tutorial/Makefile.am                          |   8 +-
+ 2 files changed, 887 insertions(+), 27 deletions(-)
+
+diff --git a/compiler/cpp/src/generate/t_java_generator.cc b/compiler/cpp/src/generate/t_java_generator.cc
+index 2db8cb8..8b28fe2 100644
+--- a/compiler/cpp/src/generate/t_java_generator.cc
++++ b/compiler/cpp/src/generate/t_java_generator.cc
+@@ -97,10 +97,10 @@ public:
+         } else if(iter->second.compare("suppress") == 0) {
+           suppress_generated_annotations_ = true;
+         } else {
+-          throw "unknown option java:" + iter->first + "=" + iter->second; 
++          throw "unknown option java:" + iter->first + "=" + iter->second;
+         }
+       } else {
+-        throw "unknown option java:" + iter->first; 
++        throw "unknown option java:" + iter->first;
+       }
+     }
+ 
+@@ -195,6 +195,17 @@ public:
+   void generate_service_async_server(t_service* tservice);
+   void generate_process_function(t_service* tservice, t_function* tfunction);
+   void generate_process_async_function(t_service* tservice, t_function* tfunction);
++  void generate_service_impl_base(t_service* tservice);
++  void generate_method_descriptors(t_service* tservice);
++  void generate_stub(t_service* tservice);
++  void generate_blocking_stub(t_service* tservice);
++  void generate_future_stub(t_service* tservice);
++  void generate_method_ids(t_service* tservice);
++  void generate_method_handlers(t_service* tservice);
++  void generate_service_descriptors(t_service* tservice);
++  void generate_service_builder(t_service* tservice);
++  void generate_arg_ids(t_service* tservice);
++  void generate_message_factory(t_service* tservice);
+ 
+   void generate_java_union(t_struct* tstruct);
+   void generate_union_constructor(ofstream& out, t_struct* tstruct);
+@@ -307,6 +318,8 @@ public:
+   std::string java_package();
+   std::string java_type_imports();
+   std::string java_suppressions();
++  std::string grpc_imports();
++  std::string import_extended_service(t_service* tservice);
+   std::string type_name(t_type* ttype,
+                         bool in_container = false,
+                         bool in_init = false,
+@@ -368,7 +381,7 @@ private:
+   bool use_option_type_;
+   bool undated_generated_annotations_;
+   bool suppress_generated_annotations_;
+-  
++
+ };
+ 
+ /**
+@@ -456,6 +469,35 @@ string t_java_generator::java_suppressions() {
+   return "@SuppressWarnings({\"cast\", \"rawtypes\", \"serial\", \"unchecked\", \"unused\"})\n";
+ }
+ 
++string t_java_generator::grpc_imports() {
++  return
++    string() +
++    "import static io.grpc.stub.ClientCalls.asyncUnaryCall;\n" +
++    "import static io.grpc.stub.ClientCalls.asyncServerStreamingCall;\n" +
++    "import static io.grpc.stub.ClientCalls.asyncClientStreamingCall;\n" +
++    "import static io.grpc.stub.ClientCalls.asyncBidiStreamingCall;\n" +
++    "import static io.grpc.stub.ClientCalls.blockingUnaryCall;\n" +
++    "import static io.grpc.stub.ClientCalls.blockingServerStreamingCall;\n" +
++    "import static io.grpc.stub.ClientCalls.futureUnaryCall;\n" +
++    "import static io.grpc.MethodDescriptor.generateFullMethodName;\n" +
++    "import static io.grpc.stub.ServerCalls.asyncUnaryCall;\n" +
++    "import static io.grpc.stub.ServerCalls.asyncServerStreamingCall;\n" +
++    "import static io.grpc.stub.ServerCalls.asyncClientStreamingCall;\n" +
++    "import static io.grpc.stub.ServerCalls.asyncBidiStreamingCall;\n" +
++    "import static io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall;\n" +
++    "import static io.grpc.stub.ServerCalls.asyncUnimplementedStreamingCall;\n" +
++    "import io.grpc.thrift.ThriftUtils;\n\n";
++}
++
++string t_java_generator::import_extended_service(t_service* tservice) {
++  if (!tservice) {
++    return string() + "\n";
++  }
++  string ns = tservice->get_program()->get_namespace("java");
++  string extend_service_name = tservice->get_name() + "Grpc";
++  return string() + "import " + ns + "." + extend_service_name + ";\n\n";
++}
++
+ /**
+  * Nothing in Java
+  */
+@@ -2772,25 +2814,51 @@ void t_java_generator::generate_field_value_meta_data(std::ofstream& out, t_type
+  */
+ void t_java_generator::generate_service(t_service* tservice) {
+   // Make output file
+-  string f_service_name = package_dir_ + "/" + make_valid_java_filename(service_name_) + ".java";
++  string f_service_name = package_dir_ + "/" + make_valid_java_filename(service_name_) + "Grpc.java";
+   f_service_.open(f_service_name.c_str());
+ 
+-  f_service_ << autogen_comment() << java_package() << java_type_imports() << java_suppressions();
++  f_service_ <<
++      autogen_comment() <<
++      java_package() <<
++      java_type_imports() <<
++      grpc_imports() <<
++      import_extended_service(tservice->get_extends());
++      java_suppressions();
++
++  f_service_ <<
++    "public class " << service_name_ << "Grpc {" << endl <<
++    endl;
+ 
+-  if (!suppress_generated_annotations_) {
+-    generate_javax_generated_annotation(f_service_);
+-  }
+-  f_service_ << "public class " << service_name_ << " {" << endl << endl;
+   indent_up();
+ 
++  // generate constructor
++  f_service_ <<
++    indent() << "private " << service_name_ <<
++    "Grpc() {}" << endl << endl;
++
++  f_service_ <<
++    indent() << "public static final String SERVICE_NAME = " <<
++    "\"" << package_name_ << "." << service_name_ << "\";" << endl << endl;
++
+   // Generate the three main parts of the service
+   generate_service_interface(tservice);
+-  generate_service_async_interface(tservice);
+-  generate_service_client(tservice);
+-  generate_service_async_client(tservice);
+-  generate_service_server(tservice);
+-  generate_service_async_server(tservice);
++  generate_arg_ids(tservice);
++  generate_message_factory(tservice);
++  generate_service_impl_base(tservice);
++  //generate_service_async_interface(tservice);
++  //generate_service_client(tservice);
++  //generate_service_async_client(tservice);
++  //generate_service_server(tservice);
++  //generate_service_async_server(tservice);
+   generate_service_helpers(tservice);
++  generate_method_descriptors(tservice);
++  generate_stub(tservice);
++  generate_blocking_stub(tservice);
++  generate_future_stub(tservice);
++  generate_method_ids(tservice);
++  generate_method_handlers(tservice);
++  generate_service_descriptors(tservice);
++  generate_service_builder(tservice);
+ 
+   indent_down();
+   f_service_ << "}" << endl;
+@@ -2805,24 +2873,820 @@ void t_java_generator::generate_service(t_service* tservice) {
+ void t_java_generator::generate_service_interface(t_service* tservice) {
+   string extends = "";
+   string extends_iface = "";
+-  if (tservice->get_extends() != NULL) {
+-    extends = type_name(tservice->get_extends());
+-    extends_iface = " extends " + extends + ".Iface";
+-  }
+ 
+   generate_java_doc(f_service_, tservice);
+-  f_service_ << indent() << "public interface Iface" << extends_iface << " {" << endl << endl;
++  f_service_ << indent() <<
++    "@java.lang.Deprecated public static interface " << service_name_;
++
++  if (tservice->get_extends()) {
++    f_service_ << " extends " << tservice->get_extends()->get_name() + "Grpc." <<
++      tservice->get_extends()->get_name() << endl;
++  }
++  f_service_ << " {" << endl;
++
++  indent_up();
++  vector<t_function*> functions = tservice->get_functions();
++  vector<t_function*>::iterator f_iter;
++  for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
++    //generate_java_doc(f_service_, *f_iter);
++    f_service_ <<
++      indent() << "public void " << (*f_iter)->get_name() << "(" << (*f_iter)->get_name() <<
++      "_args request," << endl <<
++      indent() << "    io.grpc.stub.StreamObserver<" << (*f_iter)->get_name() <<
++      "_result> responseObserver);" << endl << endl;
++  }
++  indent_down();
++  f_service_ << indent() << "}" << endl << endl;
++}
++
++void t_java_generator::generate_arg_ids(t_service* tservice) {
++  vector<t_function*> functions = tservice->get_functions();
++  vector<t_function*>::iterator f_iter;
++  int i=0;
++  for(f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
++    f_service_ << indent() <<
++      "private static final int ARG_IN_METHOD_" <<
++      (*f_iter)->get_name() << " = " << ++i << ";" << endl;
++    f_service_ << indent() <<
++      "private static final int ARG_OUT_METHOD_" <<
++      (*f_iter)->get_name() << " = " << ++i << ";" << endl;
++  }
++  f_service_ << endl;
++
++  if (tservice->get_extends()) {
++    f_service_ << indent() << "// ARG IDs for extended service" << endl;
++    t_service* extend_service = tservice->get_extends();
++    functions = extend_service->get_functions();
++    for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
++      f_service_ << indent() <<
++        "private static final int ARG_IN_METHOD_" <<
++        (*f_iter)->get_name() << " = " << ++i << ";" << endl;
++      f_service_ << indent() <<
++        "private static final int ARG_OUT_METHOD_" <<
++        (*f_iter)->get_name() << " = " << ++i << ";" << endl;
++    }
++    f_service_ << endl;
++  }
++}
++
++void t_java_generator::generate_message_factory(t_service* tservice) {
++  f_service_ << indent() <<
++    "private static final class ThriftMessageFactory<T extends " <<
++    "org.apache.thrift.TBase<T,?>>" << endl << indent() <<
++    "    implements io.grpc.thrift.MessageFactory<T> {" << endl;
++  indent_up();
++  f_service_ << indent() <<
++      "private final int id;" << endl << endl;
++  f_service_ << endl;
++
++  f_service_ << indent() <<
++    "ThriftMessageFactory(int id) {" << endl <<
++    indent() << "  this.id = id;" << endl <<
++    indent() << "}" << endl;
++
++  f_service_ << indent() <<
++    "@java.lang.Override" << endl <<
++    indent() << "public T newInstance() {" << endl;
++  indent_up();
++
++  f_service_ << indent() <<
++    "Object o;" << endl <<
++    indent() << "switch (id) {" << endl;
++
++  vector<t_function*> functions = tservice->get_functions();
++  vector<t_function*>::iterator f_iter;
++  for(f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
++    f_service_ << indent() <<
++      "case ARG_IN_METHOD_" << (*f_iter)->get_name() << ":" << endl <<
++      indent() << "  o = new " << (*f_iter)->get_name() << "_args();" <<
++      endl << indent() << "  break;" << endl;
++    f_service_ << indent() <<
++      "case ARG_OUT_METHOD_" << (*f_iter)->get_name() << ":" << endl <<
++      indent() << " o = new " << (*f_iter)->get_name() << "_result();" <<
++      endl << indent() << "  break;" << endl;
++  }
++
++  if (tservice->get_extends()) {
++    t_service* extend_service = tservice->get_extends();
++    functions = extend_service->get_functions();
++    string extend_service_name = extend_service->get_name() + "Grpc";
++    for (f_iter = functions.begin(); f_iter!= functions.end(); ++f_iter) {
++      f_service_ << indent() <<
++        "case ARG_IN_METHOD_" << (*f_iter)->get_name() << ":" << endl <<
++        indent() << "  o = new " << extend_service_name << "." << (*f_iter)->get_name() << "_args();" <<
++        endl << indent() << "  break;" << endl;
++      f_service_ << indent() <<
++        "case ARG_OUT_METHOD_" << (*f_iter)->get_name() << ":" << endl <<
++        indent() << " o = new " << extend_service_name << "." << (*f_iter)->get_name() << "_result();" <<
++        endl << indent() << "  break;" << endl;
++    }
++  }
++
++  f_service_  << indent() <<
++    "default:" << endl << indent() <<
++    "  throw new AssertionError();" << endl << indent() <<
++    "}" << endl;
++
++  f_service_ << indent() <<
++    "@java.lang.SuppressWarnings(\"unchecked\")" << endl <<
++    indent() << "T t = (T) o;" << endl << indent() <<
++    "return t;" << endl;
++
++  indent_down();
++  f_service_ <<
++    indent() << "}" << endl;
++
++  indent_down();
++  f_service_ << indent() << "}" << endl;
++}
++
++void t_java_generator::generate_service_impl_base(t_service* tservice) {
++  f_service_ <<
++    indent() << "public static abstract class " << service_name_ <<
++    "ImplBase implements " << service_name_ << ", io.grpc.BindableService {" << endl;
++  indent_up();
++
++  vector<t_function*> functions = tservice->get_functions();
++  vector<t_function*>::iterator f_iter;
++  for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
++    f_service_ <<
++      indent() << "@java.lang.Override" << endl <<
++      indent() << "public void " << (*f_iter)->get_name() << "(" << (*f_iter)->get_name() <<
++      "_args request, " << endl <<
++      indent() << "    io.grpc.stub.StreamObserver<" << (*f_iter)->get_name() <<
++      "_result> responseObserver) {" << endl;
++    indent_up();
++    f_service_ <<
++      indent() << "asyncUnimplementedUnaryCall(METHOD_" << (*f_iter)->get_name() <<
++      ", responseObserver);" << endl;
++    indent_down();
++    f_service_ <<
++      indent() << "}" << endl << endl;
++  }
++
++  if (tservice->get_extends()) {
++    t_service* extend_service = tservice->get_extends();
++    functions = extend_service->get_functions();
++    string extend_service_name = extend_service->get_name() + "Grpc" ;
++    for(f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
++      f_service_ <<
++        indent() << "@java.lang.Override" << endl <<
++        indent() << "public void " << (*f_iter)->get_name() << "(" <<
++        extend_service_name << "." << (*f_iter)->get_name() <<
++        "_args request, " << endl <<
++        indent() << "    io.grpc.stub.StreamObserver<" << extend_service_name
++        << "." << (*f_iter)->get_name() << "_result> responseObserver) {" << endl;
++      indent_up();
++      f_service_ <<
++        indent() << "asyncUnimplementedUnaryCall(METHOD_" << (*f_iter)->get_name() <<
++        ", responseObserver);" << endl;
++      indent_down();
++      f_service_ <<
++        indent() << "}" << endl << endl;
++    }
++  }
++
++  f_service_ <<
++    indent() << "@java.lang.Override" <<
++    " public io.grpc.ServerServiceDefinition bindService() {" << endl;
+   indent_up();
++  f_service_ <<
++    indent() << "return " << service_name_ << "Grpc.bindService(this);" << endl;
++  indent_down();
++  f_service_ <<
++    indent() << "}" << endl << endl;
++
++  indent_down();
++  f_service_ <<
++    indent() << "}" << endl << endl;
++
++  // generate Abstract Service
++  f_service_ <<
++    indent() << "@java.lang.Deprecated public static abstract class Abstract" << service_name_ <<
++    " extends " << service_name_ << "ImplBase {}" << endl << endl;
++}
++
++void t_java_generator::generate_method_descriptors(t_service* tservice) {
++  vector<t_function*> functions = tservice->get_functions();
++  vector<t_function*>::iterator f_iter;
++  for( f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
++    f_service_ <<
++      indent() << "public static final io.grpc.MethodDescriptor<" <<
++      (*f_iter)->get_name() << "_args," << endl <<
++      indent() << "    " << (*f_iter)->get_name() << "_result> METHOD_" << (*f_iter)->get_name() <<
++      " = " << endl << indent() << "    io.grpc.MethodDescriptor.create(" << endl;
++    indent_up();
++    f_service_ <<
++      indent() << "    io.grpc.MethodDescriptor.MethodType.UNARY," << endl <<
++      indent() << "    generateFullMethodName(" << "\"" << package_name_ << "." <<
++      service_name_ << "\" , \"" << (*f_iter)->get_name() << "\")," << endl <<
++      indent() << "    io.grpc.thrift.ThriftUtils.marshaller(" << endl <<
++      indent() << "    new ThriftMessageFactory<" << (*f_iter)->get_name() <<
++      "_args>( ARG_IN_METHOD_" << (*f_iter)->get_name() << "))," << endl <<
++      indent() << "    io.grpc.thrift.ThriftUtils.marshaller(" << endl <<
++      indent() << "    new ThriftMessageFactory<" << (*f_iter)->get_name() <<
++      "_result>( ARG_OUT_METHOD_" << (*f_iter)->get_name() << ")));" << endl << endl;
++    indent_down();
++  }
++
++  if(tservice->get_extends()) {
++    t_service* extends_service = tservice->get_extends();
++    functions = extends_service->get_functions();
++    string extend_service_name = extends_service->get_name() + "Grpc";
++    for(f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
++      f_service_ <<
++        indent() << "public static final io.grpc.MethodDescriptor<" << extend_service_name << "." <<
++        (*f_iter)->get_name() << "_args," << endl <<
++        indent() << "    " << extend_service_name << "." << (*f_iter)->get_name() << "_result> METHOD_"
++        << (*f_iter)->get_name() << " = " << endl << indent() <<
++        "    io.grpc.MethodDescriptor.create(" << endl;
++      indent_up();
++      f_service_ <<
++        indent() << "    io.grpc.MethodDescriptor.MethodType.UNARY," << endl <<
++        indent() << "    generateFullMethodName(" << "\"" << package_name_ << "." <<
++        service_name_ << "\" , \"" << (*f_iter)->get_name() << "\")," << endl <<
++        indent() << "    io.grpc.thrift.ThriftUtils.marshaller(" << endl <<
++        indent() << "    new ThriftMessageFactory<" << extend_service_name << "." <<
++        (*f_iter)->get_name() << "_args>( ARG_IN_METHOD_" << (*f_iter)->get_name() << "))," << endl <<
++        indent() << "    io.grpc.thrift.ThriftUtils.marshaller(" << endl <<
++        indent() << "    new ThriftMessageFactory<" << extend_service_name << "." << (*f_iter)->get_name() <<
++        "_result>( ARG_OUT_METHOD_" << (*f_iter)->get_name() << ")));" << endl << endl;
++      indent_down();
++    }
++  }
++}
++
++void t_java_generator::generate_stub(t_service* tservice) {
++  f_service_ <<
++    indent() <<
++    "public static " << service_name_ <<
++    "Stub newStub(io.grpc.Channel channel) {" <<
++    endl;
++
++  indent_up();
++  f_service_ <<
++    indent() <<
++    "return new " << service_name_ << "Stub(channel);" << endl;
++  indent_down();
++  f_service_ <<
++    indent() << "}" << endl << endl;
++
++  // generate Stub impl
++
++  f_service_ <<
++    indent() << "public static class " <<
++    service_name_ << "Stub extends io.grpc.stub.AbstractStub<" <<
++    service_name_ << "Stub>" << endl <<
++    indent() << "    implements " << service_name_ << "{" << endl;
++  indent_up();
++
++  f_service_ <<
++    indent() << "private " << service_name_ << "Stub(io.grpc.Channel channel) {" << endl;
++  indent_up();
++  f_service_ <<
++    indent() << "super(channel);" << endl;
++  indent_down();
++  f_service_ <<
++    indent() << "}" << endl << endl;
++
++  f_service_ <<
++    indent() << "private " << service_name_ << "Stub(io.grpc.Channel channel, " << endl <<
++    indent() << "    io.grpc.CallOptions callOptions) {" << endl;
++  indent_up();
++  f_service_ <<
++    indent() << "super(channel, callOptions);" << endl;
++  indent_down();
++  f_service_ <<
++    indent() << "}" << endl << endl;
++
++  f_service_ <<
++    indent() << "@java.lang.Override" << endl <<
++    indent() << "protected " << service_name_ << "Stub build(io.grpc.Channel channel, " <<
++    endl << indent() << "    io.grpc.CallOptions callOptions) {" << endl;
++  indent_up();
++  f_service_ <<
++    indent() << "return new " << service_name_ << "Stub(channel, callOptions);" << endl;
++  indent_down();
++  f_service_ <<
++    indent() << "}" << endl << endl;
++
++  vector<t_function*> functions = tservice->get_functions();
++  vector<t_function*>::iterator f_iter;
++  for(f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
++    f_service_ <<
++      indent() << "@java.lang.Override" << endl <<
++      indent() << "public void " << (*f_iter)->get_name() << "(" <<
++      (*f_iter)->get_name() << "_args request," << endl << indent() <<
++      "    io.grpc.stub.StreamObserver<" << (*f_iter)->get_name() <<
++      "_result> responseObserver) {" << endl;
++    indent_up();
++    f_service_ <<
++      indent() << "asyncUnaryCall(" << endl <<
++      indent() << "    getChannel().newCall(METHOD_" << (*f_iter)->get_name() <<
++      ", getCallOptions()), request, responseObserver);" << endl;
++    indent_down();
++    f_service_ <<
++      indent() << "}" << endl << endl;
++  }
++
++  if (tservice->get_extends()) {
++    t_service* extend_service = tservice->get_extends();
++    functions = extend_service->get_functions();
++    string extend_service_name = extend_service->get_name() + "Grpc";
++    for(f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
++      f_service_ <<
++        indent() << "@java.lang.Override" << endl <<
++        indent() << "public void " << (*f_iter)->get_name() << "(" <<
++        extend_service_name << "." << (*f_iter)->get_name() << "_args request,"
++        << endl << indent() << "    io.grpc.stub.StreamObserver<" <<
++        extend_service_name << "." << (*f_iter)->get_name() <<
++        "_result> responseObserver) {" << endl;
++      indent_up();
++      f_service_ <<
++        indent() << "asyncUnaryCall(" << endl <<
++        indent() << "    getChannel().newCall(METHOD_" << (*f_iter)->get_name() <<
++        ", getCallOptions()), request, responseObserver);" << endl;
++      indent_down();
++      f_service_ <<
++        indent() << "}" << endl << endl;
++    }
++  }
++  indent_down();
++  f_service_ <<
++    indent() << "}" << endl << endl;
++}
++
++void t_java_generator::generate_blocking_stub(t_service* tservice) {
++  f_service_ <<
++    indent() << "public static " << service_name_ <<
++    "BlockingStub newBlockingStub(" << endl <<
++    indent() << "    io.grpc.Channel channel) {" << endl;
++  indent_up();
++  f_service_ <<
++    indent() << "return new " << service_name_ << "BlockingStub(channel);" << endl;
++  indent_down();
++  f_service_ <<
++    indent() << "}" << endl << endl;
++
++  // generate Blocking Client
++  f_service_ <<
++    indent() << "@java.lang.Deprecated public static interface " << service_name_ <<
++    "BlockingClient " ;
++  
++  if (tservice->get_extends()) {
++    string extend_service_name = tservice->get_extends()->get_name();
++    f_service_ << endl << indent() << "    extends " << extend_service_name << "Grpc." <<
++        extend_service_name << "BlockingClient " ;
++  }
++
++  f_service_ << "{" << endl;
++
++  indent_up();
++
+   vector<t_function*> functions = tservice->get_functions();
+   vector<t_function*>::iterator f_iter;
+   for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
+-    generate_java_doc(f_service_, *f_iter);
+-    indent(f_service_) << "public " << function_signature(*f_iter) << ";" << endl << endl;
++    f_service_ <<
++      indent() << "public " << (*f_iter)->get_name() << "_result " <<
++      (*f_iter)->get_name() << "(" << (*f_iter)->get_name() << "_args request);" << endl << endl;
++  }
++  indent_down();
++  f_service_ <<
++    indent() << "}" << endl << endl;
++
++  // generate Blocking Stub impl
++
++  f_service_ <<
++    indent() << "public static class " <<
++    service_name_ << "BlockingStub extends io.grpc.stub.AbstractStub<" <<
++    service_name_ << "BlockingStub>" << endl <<
++    indent() << "    implements " << service_name_ << "BlockingClient {";
++
++  indent_up();
++
++  f_service_ <<
++    indent() << "private " << service_name_ << "BlockingStub(io.grpc.Channel channel) {" << endl;
++  indent_up();
++  f_service_ <<
++    indent() << "super(channel);" << endl;
++  indent_down();
++  f_service_ <<
++    indent() << "}" << endl << endl;
++
++  f_service_ <<
++    indent() << "private " << service_name_ << "BlockingStub(io.grpc.Channel channel, " << endl <<
++    indent() << "    io.grpc.CallOptions callOptions) {" << endl;
++  indent_up();
++  f_service_ <<
++    indent() << "super(channel, callOptions);" << endl;
++  indent_down();
++  f_service_ <<
++    indent() << "}" << endl << endl;
++
++  f_service_ <<
++    indent() << "@java.lang.Override" << endl <<
++    indent() << "protected " << service_name_ << "BlockingStub build(io.grpc.Channel channel, " <<
++    endl << indent() << "    io.grpc.CallOptions callOptions) {" << endl;
++  indent_up();
++  f_service_ <<
++    indent() << "return new " << service_name_ << "BlockingStub(channel, callOptions);" << endl;
++  indent_down();
++  f_service_ <<
++    indent() << "}" << endl << endl;
++
++  for(f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
++    f_service_ <<
++      indent() << "@java.lang.Override" << endl <<
++      indent() << "public " << (*f_iter)->get_name() << "_result " << (*f_iter)->get_name() << "(" <<
++      (*f_iter)->get_name() << "_args request) {" << endl;
++    indent_up();
++    f_service_ <<
++      indent() << "return blockingUnaryCall(" << endl <<
++      indent() << "    getChannel(), METHOD_" << (*f_iter)->get_name() <<
++      ", getCallOptions(), request);" << endl;
++    indent_down();
++    f_service_ <<
++      indent() << "}" << endl << endl;
++  }
++
++  if (tservice->get_extends()) {
++    t_service* extend_service = tservice->get_extends();
++    functions = extend_service->get_functions();
++    string extend_service_name = extend_service->get_name() + "Grpc";
++    for(f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
++      f_service_ <<
++        indent() << "@java.lang.Override" << endl <<
++        indent() << "public " << extend_service_name << "." << (*f_iter)->get_name() <<
++        "_result " << (*f_iter)->get_name() << "(" << extend_service_name << "." <<
++        (*f_iter)->get_name() << "_args request) {" << endl;
++      indent_up();
++      f_service_ <<
++        indent() << "return blockingUnaryCall(" << endl <<
++        indent() << "    getChannel(), METHOD_" << (*f_iter)->get_name() <<
++        ", getCallOptions(), request);" << endl;
++      indent_down();
++      f_service_ <<
++        indent() << "}" << endl << endl;
++    }
++  }
++  indent_down();
++  f_service_ <<
++    indent() << "}" << endl << endl;
++}
++
++void t_java_generator::generate_future_stub(t_service* tservice) {
++  f_service_ <<
++    indent() << "public static " << service_name_ <<
++    "FutureStub newFutureStub(" << endl <<
++    indent() << "    io.grpc.Channel channel) {" << endl;
++  indent_up();
++  f_service_ <<
++    indent() << "return new " << service_name_ << "FutureStub(channel);" << endl;
++  indent_down();
++  f_service_ <<
++    indent() << "}" << endl << endl;
++
++  // generate Future Client
++  f_service_ <<
++    indent() << "@java.lang.Deprecated public static interface " << service_name_ <<
++    "FutureClient " ;
++
++  if (tservice->get_extends()) {
++    string extend_service_name = tservice->get_extends()->get_name();
++    f_service_ << endl << indent() << "    extends " << extend_service_name << "Grpc." <<
++        extend_service_name << "FutureClient " ; 
++  }
++  f_service_ << "{" << endl;
++
++  indent_up();
++
++  vector<t_function*> functions = tservice->get_functions();
++  vector<t_function*>::iterator f_iter;
++  for(f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
++    f_service_ <<
++      indent() << "public com.google.common.util.concurrent.ListenableFuture<" <<
++      (*f_iter)->get_name() << "_result> " << (*f_iter)->get_name() << "(" << endl <<
++      indent() << "    " << (*f_iter)->get_name() << "_args request);" << endl << endl;
++  }
++
++  if (tservice->get_extends()) {
++    t_service* extend_service = tservice->get_extends();
++    functions = extend_service->get_functions();
++    string extend_service_name = extend_service->get_name() + "Grpc";
++    for(f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
++      f_service_ <<
++        indent() << "public com.google.common.util.concurrent.ListenableFuture<" <<
++        extend_service_name << "." << (*f_iter)->get_name() << "_result> " <<
++        (*f_iter)->get_name() << "(" << endl <<
++        indent() << "    " << extend_service_name << "." << (*f_iter)->get_name() <<
++        "_args request);" << endl << endl;
++    }
++  }
++  indent_down();
++  f_service_ <<
++    indent() << "}" << endl << endl;
++
++  // generate Stub impl
++
++  f_service_ <<
++    indent() << "public static class " <<
++    service_name_ << "FutureStub extends io.grpc.stub.AbstractStub<" <<
++    service_name_ << "FutureStub>" << endl <<
++    indent() << "    implements " << service_name_ << "FutureClient {" << endl;
++  indent_up();
++
++  f_service_ <<
++    indent() << "private " << service_name_ << "FutureStub(io.grpc.Channel channel) {" << endl;
++  indent_up();
++  f_service_ <<
++    indent() << "super(channel);" << endl;
++  indent_down();
++  f_service_ <<
++    indent() << "}" << endl << endl;
++
++  f_service_ <<
++    indent() << "private " << service_name_ << "FutureStub(io.grpc.Channel channel, " << endl <<
++    indent() << "    io.grpc.CallOptions callOptions) {" << endl;
++  indent_up();
++  f_service_ <<
++    indent() << "super(channel, callOptions);" << endl;
++  indent_down();
++  f_service_ <<
++    indent() << "}" << endl << endl;
++
++  f_service_ <<
++    indent() << "@java.lang.Override" << endl <<
++    indent() << "protected " << service_name_ << "FutureStub build(io.grpc.Channel channel, " <<
++    endl << indent() << "    io.grpc.CallOptions callOptions) {" << endl;
++  indent_up();
++  f_service_ <<
++    indent() << "return new " << service_name_ << "FutureStub(channel, callOptions);" << endl;
++  indent_down();
++  f_service_ <<
++    indent() << "}" << endl << endl;
++
++  functions = tservice->get_functions();
++  for(f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
++    f_service_ <<
++      indent() << "@java.lang.Override" << endl <<
++      indent() << "public com.google.common.util.concurrent.ListenableFuture<" <<
++      (*f_iter)->get_name() << "_result> " << (*f_iter)->get_name() << "(" <<
++      endl << indent() << "    " << (*f_iter)->get_name() << "_args request) {" << endl;
++    indent_up();
++    f_service_ <<
++      indent() << "return futureUnaryCall(" << endl <<
++      indent() << "    getChannel().newCall(METHOD_" << (*f_iter)->get_name() <<
++      ", getCallOptions()), request);" << endl;
++    indent_down();
++    f_service_ <<
++      indent() << "}" << endl << endl;
++  }
++
++  if (tservice->get_extends()) {
++    t_service* extend_service = tservice->get_extends();
++    functions = extend_service->get_functions();
++    string extend_service_name = extend_service->get_name() + "Grpc";
++    for(f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
++      f_service_ <<
++        indent() << "@java.lang.Override" << endl <<
++        indent() << "public com.google.common.util.concurrent.ListenableFuture<" <<
++        extend_service_name << "." << (*f_iter)->get_name() << "_result> " <<
++        (*f_iter)->get_name() << "(" << endl << indent() << "    " <<
++        extend_service_name << "." << (*f_iter)->get_name() << "_args request) {" << endl;
++      indent_up();
++      f_service_ <<
++        indent() << "return futureUnaryCall(" << endl <<
++        indent() << "    getChannel().newCall(METHOD_" << (*f_iter)->get_name() <<
++        ", getCallOptions()), request);" << endl;
++      indent_down();
++      f_service_ <<
++        indent() << "}" << endl << endl;
++    }
++  }
++  indent_down();
++  f_service_ <<
++    indent() << "}" << endl << endl;
++}
++
++void t_java_generator::generate_method_ids(t_service* tservice) {
++  vector<t_function*> functions = tservice->get_functions();
++  vector<t_function*>::iterator f_iter;
++  int i=0;
++  for(f_iter = functions.begin(); f_iter != functions.end(); ++f_iter, ++i) {
++    f_service_ <<
++      indent() << "private static final int METHODID_" <<
++      (*f_iter)->get_name() << " = " << i << ";" << endl;
++  }
++  if (tservice->get_extends()) {
++    t_service* extend_service = tservice->get_extends();
++    functions = extend_service->get_functions();
++    string extend_service_name = extend_service->get_name() + "Grpc";
++    for(f_iter = functions.begin(); f_iter != functions.end(); ++f_iter, ++i) {
++      f_service_ <<
++        indent() << "private static final int METHODID_" <<
++        (*f_iter)->get_name() << " = " << i << ";" << endl;
++    }
++  }
++  f_service_ << endl;
++}
++
++void t_java_generator::generate_method_handlers(t_service* tservice) {
++  f_service_ <<
++    indent() << "private static class MethodHandlers<Req, Resp> implements" <<
++    endl << indent() << "    io.grpc.stub.ServerCalls.UnaryMethod<Req, Resp>," <<
++    endl << indent() << "    io.grpc.stub.ServerCalls.ServerStreamingMethod<Req, Resp>," <<
++    endl << indent() << "    io.grpc.stub.ServerCalls.ClientStreamingMethod<Req, Resp>," <<
++    endl << indent() << "    io.grpc.stub.ServerCalls.BidiStreamingMethod<Req, Resp> {" <<
++    endl;
++  indent_up();
++  f_service_ <<
++    indent() << "private final " << service_name_ << " serviceImpl;" << endl <<
++    indent() << "private final int methodId;" << endl << endl;
++
++  f_service_ <<
++    indent() << "public MethodHandlers(" << service_name_ << " serviceImpl, int " <<
++    "methodId) {" << endl;
++  indent_up();
++  f_service_ <<
++    indent() << "this.serviceImpl = serviceImpl;" << endl <<
++    indent() << "this.methodId = methodId;" << endl;
++  indent_down();
++  f_service_ <<
++    indent() << "}" << endl << endl;
++
++  // invoke
++  f_service_ <<
++    indent() << "@java.lang.Override" << endl <<
++    indent() << "@java.lang.SuppressWarnings(\"unchecked\")" << endl <<
++    indent() << "public void invoke(Req request, io.grpc.stub.StreamObserver<Resp> responseObserver) {" <<
++    endl;
++  indent_up();
++  f_service_ <<
++    indent() << "switch (methodId) {" << endl;
++  indent_up();
++
++  vector<t_function*> functions = tservice->get_functions();
++  vector<t_function*>::iterator f_iter;
++  for(f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
++    f_service_ <<
++      indent() << "case METHODID_" << (*f_iter)->get_name() << ":" << endl;
++    indent_up();
++    f_service_ <<
++      indent() << "serviceImpl." << (*f_iter)->get_name() << "((" << (*f_iter)->get_name() <<
++      "_args) request," << endl <<
++      indent() << "    (io.grpc.stub.StreamObserver<" << (*f_iter)->get_name() << "_result>)" <<
++      " responseObserver);" << endl <<
++      indent() << "break;" << endl << endl;
++    indent_down();
++  }
++  if (tservice->get_extends()) {
++    t_service* extend_service = tservice->get_extends();
++    functions = extend_service->get_functions();
++    string extend_service_name = extend_service->get_name() + "Grpc";
++    for (f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
++      f_service_ <<
++        indent() << "case METHODID_" << (*f_iter)->get_name() << ":" << endl;
++      indent_up();
++      f_service_ <<
++        indent() << "serviceImpl." << (*f_iter)->get_name() << "((" << extend_service_name <<
++        "." << (*f_iter)->get_name() << "_args) request," << endl <<
++        indent() << "    (io.grpc.stub.StreamObserver<" << extend_service_name << "." <<
++        (*f_iter)->get_name() << "_result>)" << " responseObserver);" << endl <<
++        indent() << "break;" << endl << endl;
++      indent_down();
++    }
+   }
++  f_service_ <<
++    indent() << "default:" << endl <<
++    indent() << "  throw new AssertionError();" << endl;
++  indent_down();
++  f_service_ <<
++    indent() << "}" << endl;
++  indent_down();
++  f_service_ <<
++    indent() << "}" << endl << endl;
++
++  // invoke
++  f_service_ <<
++    indent() << "@java.lang.Override" << endl <<
++    indent() << "@java.lang.SuppressWarnings(\"unchecked\")" << endl <<
++    indent() << "public io.grpc.stub.StreamObserver<Req> invoke(" << endl <<
++    indent() << "    io.grpc.stub.StreamObserver<Resp> responseObserver) {" << endl;
++  indent_up();
++  f_service_ <<
++    indent() << "switch (methodId) {" << endl;
++  indent_up();
++  f_service_ <<
++    indent() << "default:" << endl;
++  f_service_ <<
++    indent() << "  throw new AssertionError();" << endl;
++  indent_down();
++  f_service_ << indent() << "}" << endl;
+   indent_down();
+   f_service_ << indent() << "}" << endl << endl;
++  indent_down();
++  f_service_ << indent() << "}" << endl << endl;
++
+ }
+ 
++void t_java_generator::generate_service_descriptors(t_service* tservice) {
++  // generate service descriptor
++  vector<t_function*> functions = tservice->get_functions();
++  vector<t_function*>::iterator f_iter;
++  f_service_ <<
++    indent() << "public static io.grpc.ServiceDescriptor getServiceDescriptor() {" <<
++    endl;
++  indent_up();
++  f_service_ <<
++    indent() << "return new io.grpc.ServiceDescriptor(SERVICE_NAME";
++  for(f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
++    f_service_ <<
++      indent() << "," << endl <<
++      indent() << "    METHOD_" << (*f_iter)->get_name();
++  }
++  if (tservice->get_extends()) {
++    t_service* extend_service = tservice->get_extends();
++    functions = extend_service->get_functions();
++    for(f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
++      f_service_ <<
++        indent() << "," << endl <<
++        indent() << "    METHOD_" << (*f_iter)->get_name();
++    }
++  }
++  f_service_ << ");" << endl;
++  indent_down();
++  f_service_ << indent() << "}" << endl << endl;
++}
++
++void t_java_generator::generate_service_builder(t_service* tservice) {
++  // bind Service
++  vector<t_function*> functions = tservice->get_functions();
++  vector<t_function*>::iterator f_iter;
++  f_service_ <<
++    indent() << "@java.lang.Deprecated public static io.grpc.ServerServiceDefinition" <<
++    " bindService(" << endl <<
++    indent() << "    final " << service_name_ << " serviceImpl) {" << endl;
++  indent_up();
++  f_service_ <<
++    indent() << "return io.grpc.ServerServiceDefinition.builder(getServiceDescriptor())" <<
++    endl;
++  for(f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
++    f_service_ <<
++      indent() << "    .addMethod(" << endl;
++    indent_up();
++    f_service_ <<
++      indent() << "    METHOD_" << (*f_iter)->get_name() << "," << endl <<
++      indent() << "    asyncUnaryCall(" << endl;
++    indent_up();
++    f_service_ <<
++      indent() << "    new MethodHandlers<" << endl;
++    indent_up();
++    f_service_ <<
++      indent() << "    " << (*f_iter)->get_name() << "_args," << endl <<
++      indent() << "    " << (*f_iter)->get_name() << "_result>(" << endl;
++    indent_up();
++    f_service_ <<
++      indent() << "    serviceImpl, METHODID_" << (*f_iter)->get_name() << ")))" << endl;
++    indent_down();
++    indent_down();
++    indent_down();
++    indent_down();
++  }
++
++  if (tservice->get_extends()) {
++    t_service* extend_service = tservice->get_extends();
++    functions = extend_service->get_functions();
++    string extend_service_name = extend_service->get_name() + "Grpc";
++    for(f_iter = functions.begin(); f_iter != functions.end(); ++f_iter) {
++      f_service_ <<
++        indent() << "    .addMethod(" << endl;
++      indent_up();
++      f_service_ <<
++        indent() << "    METHOD_" << (*f_iter)->get_name() << "," << endl <<
++        indent() << "    asyncUnaryCall(" << endl;
++      indent_up();
++      f_service_ <<
++        indent() << "    new MethodHandlers<" << endl;
++      indent_up();
++      f_service_ <<
++        indent() << "    " << extend_service_name << "." << (*f_iter)->get_name() << "_args," << endl <<
++        indent() << "    " << extend_service_name << "." << (*f_iter)->get_name() << "_result>(" << endl;
++      indent_up();
++      f_service_ <<
++        indent() << "    serviceImpl, METHODID_" << (*f_iter)->get_name() << ")))" << endl;
++      indent_down();
++      indent_down();
++      indent_down();
++      indent_down();
++    }
++  }
++  f_service_ <<
++    indent() << "    .build();" << endl;
++  indent_down();
++  f_service_ << indent() << "}" << endl << endl;
++}
++
++
+ void t_java_generator::generate_service_async_interface(t_service* tservice) {
+   string extends = "";
+   string extends_iface = "";
+diff --git a/tutorial/Makefile.am b/tutorial/Makefile.am
+index 5865c54..1cffbe6 100755
+--- a/tutorial/Makefile.am
++++ b/tutorial/Makefile.am
+@@ -35,11 +35,6 @@ if WITH_D
+ SUBDIRS += d
+ endif
+ 
+-if WITH_JAVA
+-SUBDIRS += java
+-SUBDIRS += js
+-endif
+-
+ if WITH_PYTHON
+ SUBDIRS += py
+ SUBDIRS += py.twisted
+@@ -95,4 +90,5 @@ EXTRA_DIST = \
+ 	php \
+ 	shared.thrift \
+ 	tutorial.thrift \
+-	README.md
++	README.md \
++	java
+-- 
+2.8.0.rc3.226.g39d4020
+
diff --git a/tools/jenkins/run_interop.sh b/tools/jenkins/run_interop.sh
index a424aea..4a7bff3 100755
--- a/tools/jenkins/run_interop.sh
+++ b/tools/jenkins/run_interop.sh
@@ -31,6 +31,8 @@
 # This script is invoked by Jenkins and runs interop test suite.
 set -ex
 
+export LANG=en_US.UTF-8
+
 # Enter the gRPC repo root
 cd $(dirname $0)/../..
 
diff --git a/tools/run_tests/artifact_targets.py b/tools/run_tests/artifact_targets.py
index 8550ee7..d36f963 100644
--- a/tools/run_tests/artifact_targets.py
+++ b/tools/run_tests/artifact_targets.py
@@ -31,6 +31,8 @@
 """Definition of targets to build artifacts."""
 
 import os.path
+import random
+import string
 import sys
 
 import jobset
@@ -79,27 +81,16 @@
   'x64': '-m64'
 }
 
-python_windows_version_arch_map = {
-  ('x86', '2.7'): 'Python27_32bits',
-  ('x64', '2.7'): 'Python27',
-  ('x86', '3.4'): 'Python34_32bits',
-  ('x64', '3.4'): 'Python34',
-}
 
 class PythonArtifact:
   """Builds Python artifacts."""
 
-  def __init__(self, platform, arch, python_version, manylinux_build=None):
-    if manylinux_build:
-      self.name = 'python%s_%s_%s_%s' % (python_version, platform, arch, manylinux_build)
-    else:
-      self.name = 'python%s_%s_%s' % (python_version, platform, arch)
+  def __init__(self, platform, arch, py_version):
+    self.name = 'python_%s_%s_%s' % (platform, arch, py_version)
     self.platform = platform
     self.arch = arch
-    self.labels = ['artifact', 'python', python_version, platform, arch]
-    self.python_version = python_version
-    self.python_windows_prefix = python_windows_version_arch_map[arch, python_version]
-    self.manylinux_build = manylinux_build
+    self.labels = ['artifact', 'python', platform, arch, py_version]
+    self.py_version = py_version
 
   def pre_build_jobspecs(self):
     return []
@@ -111,8 +102,8 @@
         environ['SETARCH_CMD'] = 'linux32'
       # Inside the manylinux container, the python installations are located in
       # special places...
-      environ['PYTHON'] = '/opt/python/{}/bin/python'.format(self.manylinux_build)
-      environ['PIP'] = '/opt/python/{}/bin/pip'.format(self.manylinux_build)
+      environ['PYTHON'] = '/opt/python/{}/bin/python'.format(self.py_version)
+      environ['PIP'] = '/opt/python/{}/bin/pip'.format(self.py_version)
       # Platform autodetection for the manylinux1 image breaks so we set the
       # defines ourselves.
       # TODO(atash) get better platform-detection support in core so we don't
@@ -126,14 +117,24 @@
           environ=environ,
           timeout_seconds=60*60)
     elif self.platform == 'windows':
+      if 'Python27' in self.py_version or 'Python34' in self.py_version:
+        environ['EXT_COMPILER'] = 'mingw32'
+      else:
+        environ['EXT_COMPILER'] = 'msvc'
+      # For some reason, the batch script %random% always runs with the same
+      # seed.  We create a random temp-dir here
+      dir = ''.join(random.choice(string.ascii_uppercase) for _ in range(10))
       return create_jobspec(self.name,
                             ['tools\\run_tests\\build_artifact_python.bat',
-                             self.python_windows_prefix,
-                             '32' if self.arch == 'x86' else '64'
+                             self.py_version,
+                             '32' if self.arch == 'x86' else '64',
+                             dir
                             ],
+                            environ=environ,
                             shell=True)
     else:
-      environ['PYTHON'] = 'python{}'.format(self.python_version)
+      environ['PYTHON'] = self.py_version
+      environ['SKIP_PIP_INSTALL'] = 'TRUE'
       return create_jobspec(self.name,
                             ['tools/run_tests/build_artifact_python.sh'],
                             environ=environ)
@@ -330,18 +331,23 @@
            for Cls in (CSharpExtArtifact, NodeExtArtifact, ProtocArtifact)
            for platform in ('linux', 'macos', 'windows')
            for arch in ('x86', 'x64')] +
-          [PythonArtifact('linux', 'x86', '2.7', 'cp27-cp27m'),
-           PythonArtifact('linux', 'x86', '2.7', 'cp27-cp27mu'),
-           PythonArtifact('linux', 'x64', '2.7', 'cp27-cp27m'),
-           PythonArtifact('linux', 'x64', '2.7', 'cp27-cp27mu'),
-           PythonArtifact('macos', 'x64', '2.7'),
-           PythonArtifact('windows', 'x86', '2.7'),
-           PythonArtifact('windows', 'x64', '2.7'),
-           PythonArtifact('linux', 'x86', '3.4', 'cp34-cp34m'),
-           PythonArtifact('linux', 'x64', '3.4', 'cp34-cp34m'),
-           PythonArtifact('macos', 'x64', '3.4'),
-           PythonArtifact('windows', 'x86', '3.4'),
-           PythonArtifact('windows', 'x64', '3.4'),
+          [PythonArtifact('linux', 'x86', 'cp27-cp27m'),
+           PythonArtifact('linux', 'x86', 'cp27-cp27mu'),
+           PythonArtifact('linux', 'x86', 'cp34-cp34m'),
+           PythonArtifact('linux', 'x86', 'cp35-cp35m'),
+           PythonArtifact('linux', 'x64', 'cp27-cp27m'),
+           PythonArtifact('linux', 'x64', 'cp27-cp27mu'),
+           PythonArtifact('linux', 'x64', 'cp34-cp34m'),
+           PythonArtifact('linux', 'x64', 'cp35-cp35m'),
+           PythonArtifact('macos', 'x64', 'python2.7'),
+           PythonArtifact('macos', 'x64', 'python3.4'),
+           PythonArtifact('macos', 'x64', 'python3.5'),
+           PythonArtifact('windows', 'x86', 'Python27_32bits'),
+           PythonArtifact('windows', 'x86', 'Python34_32bits'),
+           PythonArtifact('windows', 'x86', 'Python35_32bits'),
+           PythonArtifact('windows', 'x64', 'Python27'),
+           PythonArtifact('windows', 'x64', 'Python34'),
+           PythonArtifact('windows', 'x64', 'Python35'),
            RubyArtifact('linux', 'x86'),
            RubyArtifact('linux', 'x64'),
            RubyArtifact('macos', 'x64'),
diff --git a/tools/run_tests/build_artifact_python.bat b/tools/run_tests/build_artifact_python.bat
index 074a3c6..246713a 100644
--- a/tools/run_tests/build_artifact_python.bat
+++ b/tools/run_tests/build_artifact_python.bat
@@ -36,31 +36,43 @@
 
 set GRPC_PYTHON_BUILD_WITH_CYTHON=1
 
+@rem Multiple builds are running simultaneously, so to avoid distutils
+@rem file collisions, we build everything in a tmp directory
+if not exist "artifacts" mkdir "artifacts"
+set ARTIFACT_DIR=%cd%\artifacts
+set BUILD_DIR=C:\Windows\Temp\pygrpc-%3\
+mkdir %BUILD_DIR%
+xcopy /s/e/q %cd%\* %BUILD_DIR%
+pushd %BUILD_DIR%
+
 
 @rem Set up gRPC Python tools
 python tools\distrib\python\make_grpcio_tools.py
 
 @rem Build gRPC Python extensions
-python setup.py build_ext -c mingw32
+python setup.py build_ext -c %EXT_COMPILER% || goto :error
 
 pushd tools\distrib\python\grpcio_tools
-python setup.py build_ext -c mingw32
+python setup.py build_ext -c %EXT_COMPILER% || goto :error
 popd
 
-
 @rem Build gRPC Python distributions
-python setup.py bdist_wheel
+python setup.py bdist_wheel || goto :error
 
 pushd tools\distrib\python\grpcio_tools
-python setup.py bdist_wheel
+python setup.py bdist_wheel || goto :error
 popd
 
 
-mkdir artifacts
-xcopy /Y /I /S dist\* artifacts\ || goto :error
-xcopy /Y /I /S tools\distrib\python\grpcio_tools\dist\* artifacts\ || goto :error
+xcopy /Y /I /S dist\* %ARTIFACT_DIR% || goto :error
+xcopy /Y /I /S tools\distrib\python\grpcio_tools\dist\* %ARTIFACT_DIR% || goto :error
+
+popd
+rmdir /s /q %BUILD_DIR%
 
 goto :EOF
 
 :error
+popd
+rmdir /s /q %BUILD_DIR%
 exit /b 1
diff --git a/tools/run_tests/build_artifact_python.sh b/tools/run_tests/build_artifact_python.sh
index 8f8330e..9fed7c5 100755
--- a/tools/run_tests/build_artifact_python.sh
+++ b/tools/run_tests/build_artifact_python.sh
@@ -38,38 +38,42 @@
 export PIP=${PIP:-pip}
 export AUDITWHEEL=${AUDITWHEEL:-auditwheel}
 
+# Because multiple builds run in parallel, some distutils file
+# operations may collide.  To avoid this, each build is run in
+# a temp directory
+mkdir -p artifacts
+ARTIFACT_DIR="$PWD/artifacts"
+BUILD_DIR=`mktemp -d "${TMPDIR:-/tmp}/pygrpc.XXXXXX"`
+trap "rm -rf $BUILD_DIR" EXIT
+cp -r * "$BUILD_DIR"
+cd "$BUILD_DIR"
 
 # Build the source distribution first because MANIFEST.in cannot override
 # exclusion of built shared objects among package resources (for some
 # inexplicable reason).
-${SETARCH_CMD} ${PYTHON} setup.py  \
-    sdist
+${SETARCH_CMD} ${PYTHON} setup.py sdist
 
 # Wheel has a bug where directories don't get excluded.
 # https://bitbucket.org/pypa/wheel/issues/99/cannot-exclude-directory
-${SETARCH_CMD} ${PYTHON} setup.py  \
-    bdist_wheel
+${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
+${SETARCH_CMD} ${PYTHON} tools/distrib/python/grpcio_tools/setup.py sdist
 
 # Build gRPC tools package binary distribution
-CFLAGS="$CFLAGS -fno-wrapv" ${SETARCH_CMD} \
-  ${PYTHON} tools/distrib/python/grpcio_tools/setup.py bdist_wheel
+${SETARCH_CMD} ${PYTHON} tools/distrib/python/grpcio_tools/setup.py bdist_wheel
 
-mkdir -p artifacts
 if [ "$BUILD_MANYLINUX_WHEEL" != "" ]
 then
   for wheel in dist/*.whl; do
-    ${AUDITWHEEL} repair $wheel -w artifacts/
+    ${AUDITWHEEL} repair $wheel -w "$ARTIFACT_DIR"
     rm $wheel
   done
   for wheel in tools/distrib/python/grpcio_tools/dist/*.whl; do
-    ${AUDITWHEEL} repair $wheel -w artifacts/
+    ${AUDITWHEEL} repair $wheel -w "$ARTIFACT_DIR"
     rm $wheel
   done
 fi
@@ -81,14 +85,14 @@
 if [ "$BUILD_HEALTH_CHECKING" != "" ]
 then
   ${PIP} install -rrequirements.txt
-  ${PIP} install grpcio --no-index --find-links "file://${PWD}/artifacts/"
-  ${PIP} install grpcio-tools --no-index --find-links "file://${PWD}/artifacts/"
+  ${PIP} install grpcio --no-index --find-links "file://$ARTIFACT_DIR/"
+  ${PIP} install grpcio-tools --no-index --find-links "file://$ARTIFACT_DIR/"
 
   # Build gRPC health check source distribution
   ${SETARCH_CMD} ${PYTHON} src/python/grpcio_health_checking/setup.py \
       preprocess build_package_protos sdist
-  cp -r src/python/grpcio_health_checking/dist/* artifacts
+  cp -r src/python/grpcio_health_checking/dist/* "$ARTIFACT_DIR"
 fi
 
-cp -r dist/* artifacts
-cp -r tools/distrib/python/grpcio_tools/dist/* artifacts
+cp -r dist/* "$ARTIFACT_DIR"
+cp -r tools/distrib/python/grpcio_tools/dist/* "$ARTIFACT_DIR"
diff --git a/tools/run_tests/build_package_node.sh b/tools/run_tests/build_package_node.sh
index f20daea..a5636cf 100755
--- a/tools/run_tests/build_package_node.sh
+++ b/tools/run_tests/build_package_node.sh
@@ -50,7 +50,6 @@
 mkdir -p bin
 
 cd $base/src/node/health_check
-npm update
 npm pack
 cp grpc-health-check-*.tgz $artifacts/
 
diff --git a/tools/run_tests/build_stats_schema.json b/tools/run_tests/build_stats_schema.json
new file mode 100644
index 0000000..021a349
--- /dev/null
+++ b/tools/run_tests/build_stats_schema.json
@@ -0,0 +1,56 @@
+[
+  {
+    "name": "build_number",
+    "type": "INTEGER",
+    "mode": "NULLABLE"
+  },
+  {
+    "name": "timestamp",
+    "type": "TIMESTAMP",
+    "mode": "NULLABLE"
+  },
+  {
+    "name": "matrix",
+    "type": "RECORD",
+    "mode": "REPEATED",
+    "fields": [
+      {
+        "name": "name",
+        "type": "STRING",
+        "mode": "NULLABLE"
+      },
+      {
+        "name": "duration",
+        "type": "FLOAT",
+        "mode": "NULLABLE"
+      },
+      {
+        "name": "pass_count",
+        "type": "INTEGER",
+        "mode": "NULLABLE"
+      },
+      {
+        "name": "failure_count",
+        "type": "INTEGER",
+        "mode": "NULLABLE"
+      },
+      {
+        "name": "error",
+        "type": "RECORD",
+        "mode": "REPEATED",
+        "fields": [
+          {
+            "name": "description",
+            "type": "STRING",
+            "mode": "NULLABLE"
+          },
+          {
+            "name": "count",
+            "type": "INTEGER",
+            "mode": "NULLABLE"
+          }
+        ]
+      }
+    ]
+  }
+]  
diff --git a/tools/run_tests/build_stats_schema_no_matrix.json b/tools/run_tests/build_stats_schema_no_matrix.json
new file mode 100644
index 0000000..42650e3
--- /dev/null
+++ b/tools/run_tests/build_stats_schema_no_matrix.json
@@ -0,0 +1,44 @@
+[
+  {
+    "name": "build_number",
+    "type": "INTEGER",
+    "mode": "NULLABLE"
+  },
+  {
+    "name": "timestamp",
+    "type": "TIMESTAMP",
+    "mode": "NULLABLE"
+  },
+  {
+    "name": "duration",
+    "type": "FLOAT",
+    "mode": "NULLABLE"
+  },
+  {
+    "name": "pass_count",
+    "type": "INTEGER",
+    "mode": "NULLABLE"
+  },
+  {
+    "name": "failure_count",
+    "type": "INTEGER",
+    "mode": "NULLABLE"
+  },
+  {
+    "name": "error",
+    "type": "RECORD",
+    "mode": "REPEATED",
+    "fields": [
+      {
+        "name": "description",
+        "type": "STRING",
+        "mode": "NULLABLE"
+      },
+      {
+        "name": "count",
+        "type": "INTEGER",
+        "mode": "NULLABLE"
+      }
+    ]
+  }
+]  
diff --git a/tools/run_tests/package_targets.py b/tools/run_tests/package_targets.py
index ce3f08d..5e6de2e 100644
--- a/tools/run_tests/package_targets.py
+++ b/tools/run_tests/package_targets.py
@@ -81,7 +81,14 @@
       self.labels += ['windows']
 
   def pre_build_jobspecs(self):
-    return []
+    if 'windows' in self.labels:
+      return [create_jobspec('prebuild_%s' % self.name,
+                             ['tools\\run_tests\\pre_build_csharp.bat'],
+                             shell=True,
+                             flake_retries=5,
+                             timeout_retries=2)]
+    else:
+      return []
 
   def build_jobspec(self):
     if self.use_coreclr:
diff --git a/tools/run_tests/run_build_statistics.py b/tools/run_tests/run_build_statistics.py
new file mode 100755
index 0000000..92c5378
--- /dev/null
+++ b/tools/run_tests/run_build_statistics.py
@@ -0,0 +1,204 @@
+#!/usr/bin/env python2.7
+# Copyright 2016, Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"""Tool to get build statistics from Jenkins and upload to BigQuery."""
+
+import argparse
+import jenkinsapi
+from jenkinsapi.custom_exceptions import JenkinsAPIException
+from jenkinsapi.jenkins import Jenkins
+import json
+import os
+import re
+import sys
+import urllib
+
+
+gcp_utils_dir = os.path.abspath(os.path.join(
+    os.path.dirname(__file__), '../gcp/utils'))
+sys.path.append(gcp_utils_dir)
+import big_query_utils
+
+
+_HAS_MATRIX=True
+_PROJECT_ID = 'grpc-testing'
+_HAS_MATRIX = True
+_BUILDS = {'gRPC_master': _HAS_MATRIX, 
+           'gRPC_interop_master': not _HAS_MATRIX, 
+           'gRPC_pull_requests': _HAS_MATRIX, 
+           'gRPC_interop_pull_requests': not _HAS_MATRIX,
+}
+_URL_BASE = 'https://grpc-testing.appspot.com/job'
+_KNOWN_ERRORS = [
+    'Failed to build workspace Tests with scheme AllTests',
+    'Build timed out',
+    'FATAL: Unable to produce a script file',
+    'FAILED: Failed to build interop docker images',
+    'LLVM ERROR: IO failure on output stream.',
+    'MSBUILD : error MSB1009: Project file does not exist.',
+]
+_UNKNOWN_ERROR = 'Unknown error'
+_DATASET_ID = 'build_statistics'
+
+
+def _scrape_for_known_errors(html):
+  error_list = []
+  known_error_count = 0
+  for known_error in _KNOWN_ERRORS:
+    errors = re.findall(known_error, html)
+    this_error_count = len(errors)
+    if this_error_count > 0: 
+      known_error_count += this_error_count
+      error_list.append({'description': known_error,
+                         'count': this_error_count})
+      print('====> %d failures due to %s' % (this_error_count, known_error))
+  return error_list, known_error_count
+
+
+def _get_last_processed_buildnumber(build_name):
+  query = 'SELECT max(build_number) FROM [%s:%s.%s];' % (
+      _PROJECT_ID, _DATASET_ID, build_name)
+  query_job = big_query_utils.sync_query_job(bq, _PROJECT_ID, query)
+  page = bq.jobs().getQueryResults(
+      pageToken=None,
+      **query_job['jobReference']).execute(num_retries=3)
+  if page['rows'][0]['f'][0]['v']:
+    return int(page['rows'][0]['f'][0]['v'])
+  return 0
+
+
+def _process_matrix(build, url_base):
+  matrix_list = []
+  for matrix in build.get_matrix_runs():
+    matrix_str = re.match('.*\\xc2\\xbb ((?:[^,]+,?)+) #.*', 
+                          matrix.name).groups()[0]
+    matrix_tuple = matrix_str.split(',')
+    json_url = '%s/config=%s,language=%s,platform=%s/testReport/api/json' % (
+        url_base, matrix_tuple[0], matrix_tuple[1], matrix_tuple[2])
+    console_url = '%s/config=%s,language=%s,platform=%s/consoleFull' % (
+        url_base, matrix_tuple[0], matrix_tuple[1], matrix_tuple[2])
+    matrix_dict = {'name': matrix_str,
+                   'duration': matrix.get_duration().total_seconds()}
+    matrix_dict.update(_process_build(json_url, console_url))
+    matrix_list.append(matrix_dict)
+
+  return matrix_list 
+
+
+def _process_build(json_url, console_url):
+  build_result = {}
+  error_list = []
+  try:
+    html = urllib.urlopen(json_url).read()
+    test_result = json.loads(html)
+    print('====> Parsing result from %s' % json_url)
+    failure_count = test_result['failCount']
+    build_result['pass_count'] = test_result['passCount']
+    build_result['failure_count'] = failure_count
+    if failure_count > 0:
+      error_list, known_error_count = _scrape_for_known_errors(html)
+      unknown_error_count = failure_count - known_error_count
+      # This can happen if the same error occurs multiple times in one test.
+      if failure_count < known_error_count:
+        print('====> Some errors are duplicates.')
+        unknown_error_count = 0
+      error_list.append({'description': _UNKNOWN_ERROR, 
+                         'count': unknown_error_count})
+  except Exception as e:
+    print('====> Got exception for %s: %s.' % (json_url, str(e)))   
+    print('====> Parsing errors from %s.' % console_url)
+    html = urllib.urlopen(console_url).read()
+    build_result['pass_count'] = 0  
+    build_result['failure_count'] = 1
+    error_list, _ = _scrape_for_known_errors(html)
+    if error_list:
+      error_list.append({'description': _UNKNOWN_ERROR, 'count': 0})
+    else:
+      error_list.append({'description': _UNKNOWN_ERROR, 'count': 1})
+ 
+  if error_list:
+    build_result['error'] = error_list
+
+  return build_result 
+
+
+# parse command line
+argp = argparse.ArgumentParser(description='Get build statistics.')
+argp.add_argument('-u', '--username', default='jenkins')
+argp.add_argument('-b', '--builds', 
+                  choices=['all'] + sorted(_BUILDS.keys()),
+                  nargs='+',
+                  default=['all'])
+args = argp.parse_args()
+
+J = Jenkins('https://grpc-testing.appspot.com', args.username, 'apiToken')
+bq = big_query_utils.create_big_query()
+
+for build_name in _BUILDS.keys() if 'all' in args.builds else args.builds:
+  print('====> Build: %s' % build_name)
+  # Since get_last_completed_build() always fails due to malformatted string
+  # error, we use get_build_metadata() instead.
+  job = None
+  try:
+    job = J[build_name]
+  except Exception as e:
+    print('====> Failed to get build %s: %s.' % (build_name, str(e)))
+    continue
+  last_processed_build_number = _get_last_processed_buildnumber(build_name)
+  last_complete_build_number = job.get_last_completed_buildnumber()
+  # To avoid processing all builds for a project never looked at. In this case,
+  # only examine 10 latest builds.
+  starting_build_number = max(last_processed_build_number+1, 
+                              last_complete_build_number-9)
+  for build_number in xrange(starting_build_number, 
+                             last_complete_build_number+1):
+    print('====> Processing %s build %d.' % (build_name, build_number))
+    build = None
+    try:
+      build = job.get_build_metadata(build_number)
+    except KeyError:
+      print('====> Build %s is missing. Skip.' % build_number)
+      continue
+    build_result = {'build_number': build_number, 
+                    'timestamp': str(build.get_timestamp())}
+    url_base = json_url = '%s/%s/%d' % (_URL_BASE, build_name, build_number)
+    if _BUILDS[build_name]:  # The build has matrix, such as gRPC_master.
+      build_result['matrix'] = _process_matrix(build, url_base)
+    else:
+      json_url = '%s/testReport/api/json' % url_base
+      console_url = '%s/consoleFull' % url_base
+      build_result['duration'] = build.get_duration().total_seconds()
+      build_result.update(_process_build(json_url, console_url))
+    rows = [big_query_utils.make_row(build_number, build_result)]
+    if not big_query_utils.insert_rows(bq, _PROJECT_ID, _DATASET_ID, build_name, 
+                                       rows):
+      print '====> Error uploading result to bigquery.'
+      sys.exit(1)
+
diff --git a/tools/run_tests/sanity/check_submodules.sh b/tools/run_tests/sanity/check_submodules.sh
index 04123ee..d2ab5b0 100755
--- a/tools/run_tests/sanity/check_submodules.sh
+++ b/tools/run_tests/sanity/check_submodules.sh
@@ -47,6 +47,7 @@
  f8ac463766281625ad710900479130c7fcb4d63b third_party/nanopb (nanopb-0.3.4-29-gf8ac463)
  e8ae137c96444ea313485ed1118c5e43b2099cf1 third_party/protobuf (v3.0.0-beta-4-74-ge8ae137)
  50893291621658f355bc5b4d450a8d06a563053d third_party/zlib (v1.2.8)
+ bcad91771b7f0bff28a1cac1981d7ef2b9bcef3c third_party/thrift
 EOF
 
 diff -u $submodules $want_submodules
diff --git a/tools/run_tests/sources_and_headers.json b/tools/run_tests/sources_and_headers.json
index 4071eba..11daf24 100644
--- a/tools/run_tests/sources_and_headers.json
+++ b/tools/run_tests/sources_and_headers.json
@@ -2164,14 +2164,11 @@
   {
     "deps": [
       "gpr", 
-      "gpr_test_util", 
       "grpc", 
       "grpc++", 
       "grpc++_reflection", 
       "grpc++_test_config", 
-      "grpc++_test_util", 
-      "grpc_cli_libs", 
-      "grpc_test_util"
+      "grpc_cli_libs"
     ], 
     "headers": [], 
     "language": "c++", 
@@ -2262,6 +2259,35 @@
   }, 
   {
     "deps": [
+      "gpr", 
+      "gpr_test_util", 
+      "grpc", 
+      "grpc++", 
+      "grpc++_codegen_proto", 
+      "grpc++_config_proto", 
+      "grpc++_reflection", 
+      "grpc_cli_libs", 
+      "grpc_test_util"
+    ], 
+    "headers": [
+      "src/proto/grpc/testing/echo.grpc.pb.h", 
+      "src/proto/grpc/testing/echo.pb.h", 
+      "src/proto/grpc/testing/echo_messages.grpc.pb.h", 
+      "src/proto/grpc/testing/echo_messages.pb.h", 
+      "test/cpp/util/string_ref_helper.h"
+    ], 
+    "language": "c++", 
+    "name": "grpc_tool_test", 
+    "src": [
+      "test/cpp/util/grpc_tool_test.cc", 
+      "test/cpp/util/string_ref_helper.cc", 
+      "test/cpp/util/string_ref_helper.h"
+    ], 
+    "third_party": false, 
+    "type": "target"
+  }, 
+  {
+    "deps": [
       "grpc", 
       "grpc++", 
       "grpc++_test_util", 
@@ -4387,6 +4413,7 @@
   }, 
   {
     "deps": [
+      "gpr", 
       "grpc", 
       "grpc++_base", 
       "grpc++_codegen_base", 
@@ -4468,7 +4495,8 @@
       "grpc++_codegen_base_src", 
       "grpc++_codegen_proto", 
       "grpc++_config_proto", 
-      "grpc_test_util"
+      "grpc_test_util", 
+      "thrift_util"
     ], 
     "headers": [
       "src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.h", 
@@ -4506,7 +4534,6 @@
   {
     "deps": [
       "gpr", 
-      "grpc", 
       "grpc++_base", 
       "grpc++_codegen_base", 
       "grpc++_codegen_base_src", 
@@ -4525,10 +4552,13 @@
     "deps": [
       "grpc++", 
       "grpc++_reflection", 
-      "grpc_plugin_support"
+      "grpc++_test_config"
     ], 
     "headers": [
       "test/cpp/util/cli_call.h", 
+      "test/cpp/util/cli_credentials.h", 
+      "test/cpp/util/config_grpc_cli.h", 
+      "test/cpp/util/grpc_tool.h", 
       "test/cpp/util/proto_file_parser.h", 
       "test/cpp/util/proto_reflection_descriptor_database.h"
     ], 
@@ -4537,6 +4567,11 @@
     "src": [
       "test/cpp/util/cli_call.cc", 
       "test/cpp/util/cli_call.h", 
+      "test/cpp/util/cli_credentials.cc", 
+      "test/cpp/util/cli_credentials.h", 
+      "test/cpp/util/config_grpc_cli.h", 
+      "test/cpp/util/grpc_tool.cc", 
+      "test/cpp/util/grpc_tool.h", 
       "test/cpp/util/proto_file_parser.cc", 
       "test/cpp/util/proto_file_parser.h", 
       "test/cpp/util/proto_reflection_descriptor_database.cc", 
@@ -5780,6 +5815,7 @@
       "include/grpc/compression.h", 
       "include/grpc/grpc.h", 
       "include/grpc/grpc_posix.h", 
+      "include/grpc/grpc_security_constants.h", 
       "include/grpc/status.h", 
       "src/core/lib/channel/channel_args.h", 
       "src/core/lib/channel/channel_stack.h", 
@@ -5870,6 +5906,7 @@
       "include/grpc/compression.h", 
       "include/grpc/grpc.h", 
       "include/grpc/grpc_posix.h", 
+      "include/grpc/grpc_security_constants.h", 
       "include/grpc/status.h", 
       "src/core/lib/channel/channel_args.c", 
       "src/core/lib/channel/channel_args.h", 
@@ -6250,7 +6287,6 @@
     ], 
     "headers": [
       "include/grpc/grpc_security.h", 
-      "include/grpc/grpc_security_constants.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", 
@@ -6275,7 +6311,6 @@
     "name": "grpc_secure", 
     "src": [
       "include/grpc/grpc_security.h", 
-      "include/grpc/grpc_security_constants.h", 
       "src/core/lib/http/httpcli_security_connector.c", 
       "src/core/lib/security/context/security_context.c", 
       "src/core/lib/security/context/security_context.h", 
@@ -6596,8 +6631,9 @@
   }, 
   {
     "deps": [
-      "grpc", 
-      "grpc++_codegen_base"
+      "gpr", 
+      "grpc++_codegen_base", 
+      "grpc_base"
     ], 
     "headers": [
       "include/grpc++/alarm.h", 
@@ -6870,5 +6906,22 @@
     ], 
     "third_party": false, 
     "type": "filegroup"
+  }, 
+  {
+    "deps": [
+      "grpc++_codegen_base"
+    ], 
+    "headers": [
+      "include/grpc++/impl/codegen/thrift_serializer.h", 
+      "include/grpc++/impl/codegen/thrift_utils.h"
+    ], 
+    "language": "c++", 
+    "name": "thrift_util", 
+    "src": [
+      "include/grpc++/impl/codegen/thrift_serializer.h", 
+      "include/grpc++/impl/codegen/thrift_utils.h"
+    ], 
+    "third_party": false, 
+    "type": "filegroup"
   }
 ]
diff --git a/tools/run_tests/tests.json b/tools/run_tests/tests.json
index 11fb460..b0c09ac 100644
--- a/tools/run_tests/tests.json
+++ b/tools/run_tests/tests.json
@@ -2324,6 +2324,27 @@
     "flaky": false, 
     "gtest": true, 
     "language": "c++", 
+    "name": "grpc_tool_test", 
+    "platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ]
+  }, 
+  {
+    "args": [], 
+    "ci_platforms": [
+      "linux", 
+      "mac", 
+      "posix", 
+      "windows"
+    ], 
+    "cpu_cost": 1.0, 
+    "exclude_configs": [], 
+    "flaky": false, 
+    "gtest": true, 
+    "language": "c++", 
     "name": "grpclb_api_test", 
     "platforms": [
       "linux", 
diff --git a/vsprojects/README.md b/vsprojects/README.md
index b95b468..56d9f56 100644
--- a/vsprojects/README.md
+++ b/vsprojects/README.md
@@ -89,3 +89,18 @@
 2. Open solution `third_party\protobuf\cmake\protobuf.sln` and build it in Release mode. That will build libraries `libprotobuf.lib` and `libprotoc.lib` needed for the next step.
 
 3. Open solution `vsprojects\grpc_protoc_plugins.sln` and build it in Release mode. As a result, you should obtain a set of gRPC protoc plugin binaries (`grpc_cpp_plugin.exe`, `grpc_csharp_plugin.exe`, ...)
+
+#Building using CMake (with BoringSSL)
+1. Install [Active State Perl](http://www.activestate.com/activeperl/) (`choco install activeperl`)
+2. Install [Ninja](https://ninja-build.org/) (`choco install ninja`)
+2. Install [Go](https://golang.org/dl/) (`choco install golang`)
+3. Install [yasm](http://yasm.tortall.net/) and add it to `PATH` (`choco install yasm`)
+4. Update boringssl sumbodule to `master`
+5. Run this commads in grpc directory:
+```
+> md .build
+> cd .build
+> call "%VS140COMNTOOLS%..\..\VC\vcvarsall.bat" x64
+> cmake .. -GNinja -DCMAKE_BUILD_TYPE=Release
+> cmake --build .
+```
diff --git a/vsprojects/grpc.sln b/vsprojects/grpc.sln
index 8472091..8fccc64 100644
--- a/vsprojects/grpc.sln
+++ b/vsprojects/grpc.sln
@@ -49,6 +49,7 @@
 	EndProjectSection
 	ProjectSection(ProjectDependencies) = postProject
 		{29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9}
+		{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} = {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}
 	EndProjectSection
 EndProject
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "grpc++_reflection", "vcxproj\.\grpc++_reflection\grpc++_reflection.vcxproj", "{5F575402-3F89-5D1A-6910-9DB8BF5D2BAB}"
@@ -66,7 +67,6 @@
 	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}"
diff --git a/vsprojects/vcxproj/grpc++/grpc++.vcxproj b/vsprojects/vcxproj/grpc++/grpc++.vcxproj
index 835e252..321a403 100644
--- a/vsprojects/vcxproj/grpc++/grpc++.vcxproj
+++ b/vsprojects/vcxproj/grpc++/grpc++.vcxproj
@@ -305,6 +305,34 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\support\stub_options.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\support\sync_stream.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\support\time.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\byte_buffer.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\byte_buffer_reader.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\compression.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\grpc.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\grpc_posix.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\grpc_security_constants.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\status.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\byte_buffer.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\byte_buffer_reader.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\compression_types.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\connectivity_state.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\grpc_types.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\propagation_bits.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\status.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\alloc.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_atomic.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_sync.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_windows.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\log.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\port_platform.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\slice.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\slice_buffer.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_generic.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_posix.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_windows.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\time.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\async_stream.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\async_unary_call.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\call.h" />
@@ -335,27 +363,6 @@
     <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" />
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\core_codegen.h" />
@@ -366,6 +373,86 @@
     <ClInclude Include="$(SolutionDir)\..\src\cpp\common\channel_filter.h" />
     <ClInclude Include="$(SolutionDir)\..\src\cpp\server\dynamic_thread_pool.h" />
     <ClInclude Include="$(SolutionDir)\..\src\cpp\server\thread_pool_interface.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\channel_args.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\channel_stack.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\channel_stack_builder.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\compress_filter.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\connected_channel.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\context.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\handshaker.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\http_client_filter.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\http_server_filter.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\compression\algorithm_metadata.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\compression\message_compress.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\debug\trace.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\http\format_request.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\http\httpcli.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\http\parser.h" />
+    <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\error.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\ev_epoll_linux.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" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\executor.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\iocp_windows.h" />
+    <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\load_file.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\network_status_tracker.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" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\pollset_windows.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\resolve_address.h" />
+    <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_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" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_posix.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_server.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_windows.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\time_averaged_stats.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\timer.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\timer_heap.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\udp_server.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\unix_sockets_posix.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\wakeup_fd_pipe.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\wakeup_fd_posix.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\workqueue.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\workqueue_posix.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\workqueue_windows.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\json\json.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\json\json_common.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\json\json_reader.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\json\json_writer.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\api_trace.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\call.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\call_test_only.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\channel.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\channel_init.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\channel_stack_type.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\completion_queue.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\event_string.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\init.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\lame_client.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\server.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\byte_stream.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\connectivity_state.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\metadata.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\metadata_batch.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\static_metadata.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\timeout_encoding.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\transport.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\transport_impl.h" />
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\client\secure_credentials.cc">
@@ -434,6 +521,184 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\util\time.cc">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\channel_args.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\channel_stack.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\channel_stack_builder.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\compress_filter.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\connected_channel.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\handshaker.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\http_client_filter.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\http_server_filter.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\compression\compression.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\compression\message_compress.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\debug\trace.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\http\format_request.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\http\httpcli.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\http\parser.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\closure.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\endpoint.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\endpoint_pair_posix.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\endpoint_pair_windows.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\error.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\ev_epoll_linux.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">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\exec_ctx.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\executor.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\iocp_windows.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\iomgr.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\iomgr_posix.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\iomgr_windows.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\load_file.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\network_status_tracker.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">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\resolve_address_posix.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\resolve_address_windows.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\sockaddr_utils.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_utils_common_posix.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_utils_linux.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_utils_posix.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_windows.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_client_posix.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_client_windows.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_posix.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_server_posix.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_server_windows.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_windows.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\time_averaged_stats.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\timer.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\timer_heap.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\udp_server.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\unix_sockets_posix.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\unix_sockets_posix_noop.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\wakeup_fd_eventfd.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\wakeup_fd_nospecial.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\wakeup_fd_pipe.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\wakeup_fd_posix.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\workqueue_posix.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\workqueue_windows.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\json\json.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\json\json_reader.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\json\json_string.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\json\json_writer.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\alarm.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\api_trace.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\byte_buffer.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\byte_buffer_reader.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\call.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\call_details.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\call_log_batch.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\channel.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\channel_init.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\channel_ping.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\channel_stack_type.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\completion_queue.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\event_string.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\lame_client.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\metadata_array.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\server.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\validate_metadata.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\version.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\byte_stream.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\connectivity_state.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\metadata.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\metadata_batch.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\static_metadata.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\timeout_encoding.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\transport.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\transport_op_string.c">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\codegen\codegen_init.cc">
     </ClCompile>
   </ItemGroup>
@@ -441,6 +706,9 @@
     <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc\grpc.vcxproj">
       <Project>{29D16885-7228-4C31-81ED-5F9187C7F2A9}</Project>
     </ProjectReference>
+    <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\gpr\gpr.vcxproj">
+      <Project>{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}</Project>
+    </ProjectReference>
   </ItemGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">
diff --git a/vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters b/vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters
index 883e66e..b34ca03 100644
--- a/vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters
@@ -100,6 +100,273 @@
     <ClCompile Include="$(SolutionDir)\..\src\cpp\util\time.cc">
       <Filter>src\cpp\util</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\channel_args.c">
+      <Filter>src\core\lib\channel</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\channel_stack.c">
+      <Filter>src\core\lib\channel</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\channel_stack_builder.c">
+      <Filter>src\core\lib\channel</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\compress_filter.c">
+      <Filter>src\core\lib\channel</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\connected_channel.c">
+      <Filter>src\core\lib\channel</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\handshaker.c">
+      <Filter>src\core\lib\channel</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\http_client_filter.c">
+      <Filter>src\core\lib\channel</Filter>
+    </ClCompile>
+    <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.c">
+      <Filter>src\core\lib\compression</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\compression\message_compress.c">
+      <Filter>src\core\lib\compression</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\debug\trace.c">
+      <Filter>src\core\lib\debug</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\http\format_request.c">
+      <Filter>src\core\lib\http</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\http\httpcli.c">
+      <Filter>src\core\lib\http</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\http\parser.c">
+      <Filter>src\core\lib\http</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\closure.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\endpoint.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\endpoint_pair_posix.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <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\error.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\ev_epoll_linux.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>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\ev_posix.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\exec_ctx.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\executor.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\iocp_windows.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\iomgr.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\iomgr_posix.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\iomgr_windows.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\load_file.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\network_status_tracker.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>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\pollset_windows.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\resolve_address_posix.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\resolve_address_windows.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\sockaddr_utils.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_utils_common_posix.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_utils_linux.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_utils_posix.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_windows.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_client_posix.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_client_windows.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_posix.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_server_posix.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_server_windows.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_windows.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\time_averaged_stats.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\timer.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\timer_heap.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\udp_server.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\unix_sockets_posix.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\unix_sockets_posix_noop.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\wakeup_fd_eventfd.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\wakeup_fd_nospecial.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\wakeup_fd_pipe.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\wakeup_fd_posix.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\workqueue_posix.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\workqueue_windows.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\json\json.c">
+      <Filter>src\core\lib\json</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\json\json_reader.c">
+      <Filter>src\core\lib\json</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\json\json_string.c">
+      <Filter>src\core\lib\json</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\json\json_writer.c">
+      <Filter>src\core\lib\json</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\alarm.c">
+      <Filter>src\core\lib\surface</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\api_trace.c">
+      <Filter>src\core\lib\surface</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\byte_buffer.c">
+      <Filter>src\core\lib\surface</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\byte_buffer_reader.c">
+      <Filter>src\core\lib\surface</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\call.c">
+      <Filter>src\core\lib\surface</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\call_details.c">
+      <Filter>src\core\lib\surface</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\call_log_batch.c">
+      <Filter>src\core\lib\surface</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\channel.c">
+      <Filter>src\core\lib\surface</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\channel_init.c">
+      <Filter>src\core\lib\surface</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\channel_ping.c">
+      <Filter>src\core\lib\surface</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\channel_stack_type.c">
+      <Filter>src\core\lib\surface</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\completion_queue.c">
+      <Filter>src\core\lib\surface</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\event_string.c">
+      <Filter>src\core\lib\surface</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\lame_client.c">
+      <Filter>src\core\lib\surface</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\metadata_array.c">
+      <Filter>src\core\lib\surface</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\server.c">
+      <Filter>src\core\lib\surface</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\validate_metadata.c">
+      <Filter>src\core\lib\surface</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\version.c">
+      <Filter>src\core\lib\surface</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\byte_stream.c">
+      <Filter>src\core\lib\transport</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\connectivity_state.c">
+      <Filter>src\core\lib\transport</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\metadata.c">
+      <Filter>src\core\lib\transport</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\metadata_batch.c">
+      <Filter>src\core\lib\transport</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\static_metadata.c">
+      <Filter>src\core\lib\transport</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\timeout_encoding.c">
+      <Filter>src\core\lib\transport</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\transport.c">
+      <Filter>src\core\lib\transport</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\transport_op_string.c">
+      <Filter>src\core\lib\transport</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\codegen\codegen_init.cc">
       <Filter>src\cpp\codegen</Filter>
     </ClCompile>
@@ -246,6 +513,90 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\support\time.h">
       <Filter>include\grpc++\support</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\byte_buffer.h">
+      <Filter>include\grpc</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\byte_buffer_reader.h">
+      <Filter>include\grpc</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\compression.h">
+      <Filter>include\grpc</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\grpc.h">
+      <Filter>include\grpc</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\grpc_posix.h">
+      <Filter>include\grpc</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\grpc_security_constants.h">
+      <Filter>include\grpc</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\status.h">
+      <Filter>include\grpc</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\byte_buffer.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
+    <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\async_stream.h">
       <Filter>include\grpc++\impl\codegen</Filter>
     </ClInclude>
@@ -336,69 +687,6 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\time.h">
       <Filter>include\grpc++\impl\codegen</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\byte_buffer.h">
-      <Filter>include\grpc\impl\codegen</Filter>
-    </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\byte_buffer_reader.h">
-      <Filter>include\grpc\impl\codegen</Filter>
-    </ClInclude>
-    <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>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\core_codegen.h">
@@ -425,6 +713,246 @@
     <ClInclude Include="$(SolutionDir)\..\src\cpp\server\thread_pool_interface.h">
       <Filter>src\cpp\server</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\channel_args.h">
+      <Filter>src\core\lib\channel</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\channel_stack.h">
+      <Filter>src\core\lib\channel</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\channel_stack_builder.h">
+      <Filter>src\core\lib\channel</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\compress_filter.h">
+      <Filter>src\core\lib\channel</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\connected_channel.h">
+      <Filter>src\core\lib\channel</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\context.h">
+      <Filter>src\core\lib\channel</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\handshaker.h">
+      <Filter>src\core\lib\channel</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\http_client_filter.h">
+      <Filter>src\core\lib\channel</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\http_server_filter.h">
+      <Filter>src\core\lib\channel</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\compression\algorithm_metadata.h">
+      <Filter>src\core\lib\compression</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\compression\message_compress.h">
+      <Filter>src\core\lib\compression</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\debug\trace.h">
+      <Filter>src\core\lib\debug</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\http\format_request.h">
+      <Filter>src\core\lib\http</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\http\httpcli.h">
+      <Filter>src\core\lib\http</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\http\parser.h">
+      <Filter>src\core\lib\http</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\closure.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\endpoint.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\endpoint_pair.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\error.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\ev_epoll_linux.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>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\ev_posix.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\exec_ctx.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\executor.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\iocp_windows.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\iomgr.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\iomgr_internal.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\iomgr_posix.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\load_file.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\network_status_tracker.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>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\pollset_set.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\pollset_set_windows.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\pollset_windows.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\resolve_address.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\sockaddr.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\sockaddr_posix.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <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_windows.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_utils_posix.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_windows.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_client.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_posix.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_server.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_windows.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\time_averaged_stats.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\timer.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\timer_heap.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\udp_server.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\unix_sockets_posix.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\wakeup_fd_pipe.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\wakeup_fd_posix.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\workqueue.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\workqueue_posix.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\workqueue_windows.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\json\json.h">
+      <Filter>src\core\lib\json</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\json\json_common.h">
+      <Filter>src\core\lib\json</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\json\json_reader.h">
+      <Filter>src\core\lib\json</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\json\json_writer.h">
+      <Filter>src\core\lib\json</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\api_trace.h">
+      <Filter>src\core\lib\surface</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\call.h">
+      <Filter>src\core\lib\surface</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\call_test_only.h">
+      <Filter>src\core\lib\surface</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\channel.h">
+      <Filter>src\core\lib\surface</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\channel_init.h">
+      <Filter>src\core\lib\surface</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\channel_stack_type.h">
+      <Filter>src\core\lib\surface</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\completion_queue.h">
+      <Filter>src\core\lib\surface</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\event_string.h">
+      <Filter>src\core\lib\surface</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\init.h">
+      <Filter>src\core\lib\surface</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\lame_client.h">
+      <Filter>src\core\lib\surface</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\server.h">
+      <Filter>src\core\lib\surface</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\byte_stream.h">
+      <Filter>src\core\lib\transport</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\connectivity_state.h">
+      <Filter>src\core\lib\transport</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\metadata.h">
+      <Filter>src\core\lib\transport</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\metadata_batch.h">
+      <Filter>src\core\lib\transport</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\static_metadata.h">
+      <Filter>src\core\lib\transport</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\timeout_encoding.h">
+      <Filter>src\core\lib\transport</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\transport.h">
+      <Filter>src\core\lib\transport</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\transport_impl.h">
+      <Filter>src\core\lib\transport</Filter>
+    </ClInclude>
   </ItemGroup>
 
   <ItemGroup>
@@ -464,6 +992,36 @@
     <Filter Include="src">
       <UniqueIdentifier>{328ff211-2886-406e-56f9-18ba1686f363}</UniqueIdentifier>
     </Filter>
+    <Filter Include="src\core">
+      <UniqueIdentifier>{d02f1155-7e7e-3736-3c69-dc9146dc523d}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\core\lib">
+      <UniqueIdentifier>{80567a8f-622f-a3ce-c12d-aebb63984b07}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\core\lib\channel">
+      <UniqueIdentifier>{e769265c-8abd-cd64-2cc2-a52da484fe7b}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\core\lib\compression">
+      <UniqueIdentifier>{701b2d46-11c6-3640-b189-45287f00bee3}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\core\lib\debug">
+      <UniqueIdentifier>{ada68fd5-8e51-98cb-71a7-baf7989d8ffa}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\core\lib\http">
+      <UniqueIdentifier>{e770844e-61d4-555e-59be-81288e21a35f}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\core\lib\iomgr">
+      <UniqueIdentifier>{04dfa1c8-7ffe-4f06-4a7c-37441dc75764}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\core\lib\json">
+      <UniqueIdentifier>{a5d5bddf-6f19-b655-a03a-f30ff5c253a5}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\core\lib\surface">
+      <UniqueIdentifier>{fb2276d7-5a11-f1d9-82c3-e7c7f1155523}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\core\lib\transport">
+      <UniqueIdentifier>{4bd7971a-68f7-0d5a-f502-6dea3099caaa}</UniqueIdentifier>
+    </Filter>
     <Filter Include="src\cpp">
       <UniqueIdentifier>{2420a905-e4f1-a5aa-a364-6a112878a39e}</UniqueIdentifier>
     </Filter>
diff --git a/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj b/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj
index d0fca9b..c2c7d00 100644
--- a/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj
+++ b/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj
@@ -200,6 +200,8 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\time.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\proto_utils.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\config_protobuf.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\thrift_serializer.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\thrift_utils.h" />
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="$(SolutionDir)\..\test\cpp\end2end\test_service_impl.h" />
diff --git a/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj.filters b/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj.filters
index cc98c60..9b8c8dd 100644
--- a/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj.filters
@@ -192,6 +192,12 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\config_protobuf.h">
       <Filter>include\grpc++\impl\codegen</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\thrift_serializer.h">
+      <Filter>include\grpc++\impl\codegen</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\thrift_utils.h">
+      <Filter>include\grpc++\impl\codegen</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="$(SolutionDir)\..\test\cpp\end2end\test_service_impl.h">
diff --git a/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj b/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj
index e71180f..a7bb3ef 100644
--- a/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj
+++ b/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj
@@ -305,6 +305,34 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\support\stub_options.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\support\sync_stream.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\support\time.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\byte_buffer.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\byte_buffer_reader.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\compression.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\grpc.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\grpc_posix.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\grpc_security_constants.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\status.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\byte_buffer.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\byte_buffer_reader.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\compression_types.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\connectivity_state.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\grpc_types.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\propagation_bits.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\status.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\alloc.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_atomic.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_gcc_sync.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\atm_windows.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\log.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\port_platform.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\slice.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\slice_buffer.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_generic.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_posix.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_windows.h" />
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\time.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\async_stream.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\async_unary_call.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\call.h" />
@@ -335,33 +363,92 @@
     <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" />
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="$(SolutionDir)\..\src\cpp\client\create_channel_internal.h" />
     <ClInclude Include="$(SolutionDir)\..\src\cpp\common\channel_filter.h" />
     <ClInclude Include="$(SolutionDir)\..\src\cpp\server\dynamic_thread_pool.h" />
     <ClInclude Include="$(SolutionDir)\..\src\cpp\server\thread_pool_interface.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\channel_args.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\channel_stack.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\channel_stack_builder.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\compress_filter.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\connected_channel.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\context.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\handshaker.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\http_client_filter.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\http_server_filter.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\compression\algorithm_metadata.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\compression\message_compress.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\debug\trace.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\http\format_request.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\http\httpcli.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\http\parser.h" />
+    <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\error.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\ev_epoll_linux.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" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\executor.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\iocp_windows.h" />
+    <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\load_file.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\network_status_tracker.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" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\pollset_windows.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\resolve_address.h" />
+    <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_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" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_posix.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_server.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_windows.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\time_averaged_stats.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\timer.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\timer_heap.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\udp_server.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\unix_sockets_posix.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\wakeup_fd_pipe.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\wakeup_fd_posix.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\workqueue.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\workqueue_posix.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\workqueue_windows.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\json\json.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\json\json_common.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\json\json_reader.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\json\json_writer.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\api_trace.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\call.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\call_test_only.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\channel.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\channel_init.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\channel_stack_type.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\completion_queue.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\event_string.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\init.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\lame_client.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\server.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\byte_stream.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\connectivity_state.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\metadata.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\metadata_batch.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\static_metadata.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\timeout_encoding.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\transport.h" />
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\transport_impl.h" />
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\common\insecure_create_auth_context.cc">
@@ -420,6 +507,184 @@
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\util\time.cc">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\channel_args.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\channel_stack.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\channel_stack_builder.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\compress_filter.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\connected_channel.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\handshaker.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\http_client_filter.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\http_server_filter.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\compression\compression.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\compression\message_compress.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\debug\trace.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\http\format_request.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\http\httpcli.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\http\parser.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\closure.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\endpoint.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\endpoint_pair_posix.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\endpoint_pair_windows.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\error.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\ev_epoll_linux.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">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\exec_ctx.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\executor.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\iocp_windows.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\iomgr.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\iomgr_posix.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\iomgr_windows.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\load_file.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\network_status_tracker.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">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\resolve_address_posix.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\resolve_address_windows.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\sockaddr_utils.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_utils_common_posix.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_utils_linux.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_utils_posix.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_windows.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_client_posix.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_client_windows.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_posix.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_server_posix.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_server_windows.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_windows.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\time_averaged_stats.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\timer.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\timer_heap.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\udp_server.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\unix_sockets_posix.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\unix_sockets_posix_noop.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\wakeup_fd_eventfd.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\wakeup_fd_nospecial.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\wakeup_fd_pipe.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\wakeup_fd_posix.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\workqueue_posix.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\workqueue_windows.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\json\json.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\json\json_reader.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\json\json_string.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\json\json_writer.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\alarm.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\api_trace.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\byte_buffer.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\byte_buffer_reader.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\call.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\call_details.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\call_log_batch.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\channel.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\channel_init.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\channel_ping.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\channel_stack_type.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\completion_queue.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\event_string.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\lame_client.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\metadata_array.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\server.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\validate_metadata.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\version.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\byte_stream.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\connectivity_state.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\metadata.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\metadata_batch.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\static_metadata.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\timeout_encoding.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\transport.c">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\transport_op_string.c">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\codegen\codegen_init.cc">
     </ClCompile>
   </ItemGroup>
@@ -430,9 +695,6 @@
     <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc_unsecure\grpc_unsecure.vcxproj">
       <Project>{46CEDFFF-9692-456A-AA24-38B5D6BCF4C5}</Project>
     </ProjectReference>
-    <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc\grpc.vcxproj">
-      <Project>{29D16885-7228-4C31-81ED-5F9187C7F2A9}</Project>
-    </ProjectReference>
   </ItemGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
   <ImportGroup Label="ExtensionTargets">
diff --git a/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters b/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters
index a9aa147..4ad0ae3 100644
--- a/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters
@@ -85,6 +85,273 @@
     <ClCompile Include="$(SolutionDir)\..\src\cpp\util\time.cc">
       <Filter>src\cpp\util</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\channel_args.c">
+      <Filter>src\core\lib\channel</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\channel_stack.c">
+      <Filter>src\core\lib\channel</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\channel_stack_builder.c">
+      <Filter>src\core\lib\channel</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\compress_filter.c">
+      <Filter>src\core\lib\channel</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\connected_channel.c">
+      <Filter>src\core\lib\channel</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\handshaker.c">
+      <Filter>src\core\lib\channel</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\channel\http_client_filter.c">
+      <Filter>src\core\lib\channel</Filter>
+    </ClCompile>
+    <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.c">
+      <Filter>src\core\lib\compression</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\compression\message_compress.c">
+      <Filter>src\core\lib\compression</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\debug\trace.c">
+      <Filter>src\core\lib\debug</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\http\format_request.c">
+      <Filter>src\core\lib\http</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\http\httpcli.c">
+      <Filter>src\core\lib\http</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\http\parser.c">
+      <Filter>src\core\lib\http</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\closure.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\endpoint.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\endpoint_pair_posix.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <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\error.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\ev_epoll_linux.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>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\ev_posix.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\exec_ctx.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\executor.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\iocp_windows.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\iomgr.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\iomgr_posix.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\iomgr_windows.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\load_file.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\network_status_tracker.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>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\pollset_windows.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\resolve_address_posix.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\resolve_address_windows.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\sockaddr_utils.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_utils_common_posix.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_utils_linux.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_utils_posix.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_windows.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_client_posix.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_client_windows.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_posix.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_server_posix.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_server_windows.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_windows.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\time_averaged_stats.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\timer.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\timer_heap.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\udp_server.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\unix_sockets_posix.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\unix_sockets_posix_noop.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\wakeup_fd_eventfd.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\wakeup_fd_nospecial.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\wakeup_fd_pipe.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\wakeup_fd_posix.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\workqueue_posix.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\iomgr\workqueue_windows.c">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\json\json.c">
+      <Filter>src\core\lib\json</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\json\json_reader.c">
+      <Filter>src\core\lib\json</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\json\json_string.c">
+      <Filter>src\core\lib\json</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\json\json_writer.c">
+      <Filter>src\core\lib\json</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\alarm.c">
+      <Filter>src\core\lib\surface</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\api_trace.c">
+      <Filter>src\core\lib\surface</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\byte_buffer.c">
+      <Filter>src\core\lib\surface</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\byte_buffer_reader.c">
+      <Filter>src\core\lib\surface</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\call.c">
+      <Filter>src\core\lib\surface</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\call_details.c">
+      <Filter>src\core\lib\surface</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\call_log_batch.c">
+      <Filter>src\core\lib\surface</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\channel.c">
+      <Filter>src\core\lib\surface</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\channel_init.c">
+      <Filter>src\core\lib\surface</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\channel_ping.c">
+      <Filter>src\core\lib\surface</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\channel_stack_type.c">
+      <Filter>src\core\lib\surface</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\completion_queue.c">
+      <Filter>src\core\lib\surface</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\event_string.c">
+      <Filter>src\core\lib\surface</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\lame_client.c">
+      <Filter>src\core\lib\surface</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\metadata_array.c">
+      <Filter>src\core\lib\surface</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\server.c">
+      <Filter>src\core\lib\surface</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\validate_metadata.c">
+      <Filter>src\core\lib\surface</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\surface\version.c">
+      <Filter>src\core\lib\surface</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\byte_stream.c">
+      <Filter>src\core\lib\transport</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\connectivity_state.c">
+      <Filter>src\core\lib\transport</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\metadata.c">
+      <Filter>src\core\lib\transport</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\metadata_batch.c">
+      <Filter>src\core\lib\transport</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\static_metadata.c">
+      <Filter>src\core\lib\transport</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\timeout_encoding.c">
+      <Filter>src\core\lib\transport</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\transport.c">
+      <Filter>src\core\lib\transport</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\core\lib\transport\transport_op_string.c">
+      <Filter>src\core\lib\transport</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\src\cpp\codegen\codegen_init.cc">
       <Filter>src\cpp\codegen</Filter>
     </ClCompile>
@@ -231,6 +498,90 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\support\time.h">
       <Filter>include\grpc++\support</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\byte_buffer.h">
+      <Filter>include\grpc</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\byte_buffer_reader.h">
+      <Filter>include\grpc</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\compression.h">
+      <Filter>include\grpc</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\grpc.h">
+      <Filter>include\grpc</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\grpc_posix.h">
+      <Filter>include\grpc</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\grpc_security_constants.h">
+      <Filter>include\grpc</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\status.h">
+      <Filter>include\grpc</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\byte_buffer.h">
+      <Filter>include\grpc\impl\codegen</Filter>
+    </ClInclude>
+    <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\async_stream.h">
       <Filter>include\grpc++\impl\codegen</Filter>
     </ClInclude>
@@ -321,69 +672,6 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\codegen\time.h">
       <Filter>include\grpc++\impl\codegen</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\byte_buffer.h">
-      <Filter>include\grpc\impl\codegen</Filter>
-    </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\byte_buffer_reader.h">
-      <Filter>include\grpc\impl\codegen</Filter>
-    </ClInclude>
-    <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>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="$(SolutionDir)\..\src\cpp\client\create_channel_internal.h">
@@ -398,6 +686,246 @@
     <ClInclude Include="$(SolutionDir)\..\src\cpp\server\thread_pool_interface.h">
       <Filter>src\cpp\server</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\channel_args.h">
+      <Filter>src\core\lib\channel</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\channel_stack.h">
+      <Filter>src\core\lib\channel</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\channel_stack_builder.h">
+      <Filter>src\core\lib\channel</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\compress_filter.h">
+      <Filter>src\core\lib\channel</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\connected_channel.h">
+      <Filter>src\core\lib\channel</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\context.h">
+      <Filter>src\core\lib\channel</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\handshaker.h">
+      <Filter>src\core\lib\channel</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\http_client_filter.h">
+      <Filter>src\core\lib\channel</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\channel\http_server_filter.h">
+      <Filter>src\core\lib\channel</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\compression\algorithm_metadata.h">
+      <Filter>src\core\lib\compression</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\compression\message_compress.h">
+      <Filter>src\core\lib\compression</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\debug\trace.h">
+      <Filter>src\core\lib\debug</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\http\format_request.h">
+      <Filter>src\core\lib\http</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\http\httpcli.h">
+      <Filter>src\core\lib\http</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\http\parser.h">
+      <Filter>src\core\lib\http</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\closure.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\endpoint.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\endpoint_pair.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\error.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\ev_epoll_linux.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>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\ev_posix.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\exec_ctx.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\executor.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\iocp_windows.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\iomgr.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\iomgr_internal.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\iomgr_posix.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\load_file.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\network_status_tracker.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>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\pollset_set.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\pollset_set_windows.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\pollset_windows.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\resolve_address.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\sockaddr.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\sockaddr_posix.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <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_windows.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_utils_posix.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\socket_windows.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_client.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_posix.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_server.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\tcp_windows.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\time_averaged_stats.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\timer.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\timer_heap.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\udp_server.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\unix_sockets_posix.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\wakeup_fd_pipe.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\wakeup_fd_posix.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\workqueue.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\workqueue_posix.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\iomgr\workqueue_windows.h">
+      <Filter>src\core\lib\iomgr</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\json\json.h">
+      <Filter>src\core\lib\json</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\json\json_common.h">
+      <Filter>src\core\lib\json</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\json\json_reader.h">
+      <Filter>src\core\lib\json</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\json\json_writer.h">
+      <Filter>src\core\lib\json</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\api_trace.h">
+      <Filter>src\core\lib\surface</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\call.h">
+      <Filter>src\core\lib\surface</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\call_test_only.h">
+      <Filter>src\core\lib\surface</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\channel.h">
+      <Filter>src\core\lib\surface</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\channel_init.h">
+      <Filter>src\core\lib\surface</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\channel_stack_type.h">
+      <Filter>src\core\lib\surface</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\completion_queue.h">
+      <Filter>src\core\lib\surface</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\event_string.h">
+      <Filter>src\core\lib\surface</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\init.h">
+      <Filter>src\core\lib\surface</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\lame_client.h">
+      <Filter>src\core\lib\surface</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\surface\server.h">
+      <Filter>src\core\lib\surface</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\byte_stream.h">
+      <Filter>src\core\lib\transport</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\connectivity_state.h">
+      <Filter>src\core\lib\transport</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\metadata.h">
+      <Filter>src\core\lib\transport</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\metadata_batch.h">
+      <Filter>src\core\lib\transport</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\static_metadata.h">
+      <Filter>src\core\lib\transport</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\timeout_encoding.h">
+      <Filter>src\core\lib\transport</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\transport.h">
+      <Filter>src\core\lib\transport</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\src\core\lib\transport\transport_impl.h">
+      <Filter>src\core\lib\transport</Filter>
+    </ClInclude>
   </ItemGroup>
 
   <ItemGroup>
@@ -437,6 +965,36 @@
     <Filter Include="src">
       <UniqueIdentifier>{cce6a85d-1111-3834-6825-31e170d93cff}</UniqueIdentifier>
     </Filter>
+    <Filter Include="src\core">
+      <UniqueIdentifier>{595f2ea0-aafb-87e5-c938-db3ff0b0c69a}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\core\lib">
+      <UniqueIdentifier>{cf8fd5d8-ff54-331d-2d20-36d6cae0e14b}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\core\lib\channel">
+      <UniqueIdentifier>{7e0225af-000b-4873-1c16-caffffbfd084}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\core\lib\compression">
+      <UniqueIdentifier>{0bbdbf56-83ad-bb4b-c4e2-a6d38c342179}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\core\lib\debug">
+      <UniqueIdentifier>{3875f7d7-ff11-c91d-0f98-810260cb554b}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\core\lib\http">
+      <UniqueIdentifier>{4bd405b9-af65-f0a6-d67a-433f75900668}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\core\lib\iomgr">
+      <UniqueIdentifier>{f4b146e4-8fba-83a6-1cc1-1262ebb785e8}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\core\lib\json">
+      <UniqueIdentifier>{b83c8e70-e491-f6f9-a08c-85f632bb61d2}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\core\lib\surface">
+      <UniqueIdentifier>{1d59dcef-3358-d0ab-fa42-64da74065785}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\core\lib\transport">
+      <UniqueIdentifier>{ba865739-5dd9-6731-6772-48c25d45134f}</UniqueIdentifier>
+    </Filter>
     <Filter Include="src\cpp">
       <UniqueIdentifier>{1e5fd68c-bd87-e803-42b0-75a7fa19b91d}</UniqueIdentifier>
     </Filter>
diff --git a/vsprojects/vcxproj/grpc/grpc.vcxproj b/vsprojects/vcxproj/grpc/grpc.vcxproj
index ed010c5..2527047 100644
--- a/vsprojects/vcxproj/grpc/grpc.vcxproj
+++ b/vsprojects/vcxproj/grpc/grpc.vcxproj
@@ -272,6 +272,7 @@
     <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\grpc_security_constants.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\status.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\byte_buffer.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\byte_buffer_reader.h" />
@@ -295,7 +296,6 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\sync_windows.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\time.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\grpc_security.h" />
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\grpc_security_constants.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\census.h" />
   </ItemGroup>
   <ItemGroup>
diff --git a/vsprojects/vcxproj/grpc/grpc.vcxproj.filters b/vsprojects/vcxproj/grpc/grpc.vcxproj.filters
index b310172..1fdf0f5 100644
--- a/vsprojects/vcxproj/grpc/grpc.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc/grpc.vcxproj.filters
@@ -588,6 +588,9 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\grpc_posix.h">
       <Filter>include\grpc</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\grpc_security_constants.h">
+      <Filter>include\grpc</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\include\grpc\status.h">
       <Filter>include\grpc</Filter>
     </ClInclude>
@@ -657,9 +660,6 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\grpc_security.h">
       <Filter>include\grpc</Filter>
     </ClInclude>
-    <ClInclude Include="$(SolutionDir)\..\include\grpc\grpc_security_constants.h">
-      <Filter>include\grpc</Filter>
-    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\include\grpc\census.h">
       <Filter>include\grpc</Filter>
     </ClInclude>
diff --git a/vsprojects/vcxproj/grpc_cli_libs/grpc_cli_libs.vcxproj b/vsprojects/vcxproj/grpc_cli_libs/grpc_cli_libs.vcxproj
index d25c692..425b66f 100644
--- a/vsprojects/vcxproj/grpc_cli_libs/grpc_cli_libs.vcxproj
+++ b/vsprojects/vcxproj/grpc_cli_libs/grpc_cli_libs.vcxproj
@@ -148,12 +148,19 @@
 
   <ItemGroup>
     <ClInclude Include="$(SolutionDir)\..\test\cpp\util\cli_call.h" />
+    <ClInclude Include="$(SolutionDir)\..\test\cpp\util\cli_credentials.h" />
+    <ClInclude Include="$(SolutionDir)\..\test\cpp\util\config_grpc_cli.h" />
+    <ClInclude Include="$(SolutionDir)\..\test\cpp\util\grpc_tool.h" />
     <ClInclude Include="$(SolutionDir)\..\test\cpp\util\proto_file_parser.h" />
     <ClInclude Include="$(SolutionDir)\..\test\cpp\util\proto_reflection_descriptor_database.h" />
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="$(SolutionDir)\..\test\cpp\util\cli_call.cc">
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\test\cpp\util\cli_credentials.cc">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\test\cpp\util\grpc_tool.cc">
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\cpp\util\proto_file_parser.cc">
     </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\cpp\util\proto_reflection_descriptor_database.cc">
@@ -166,8 +173,8 @@
     <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 Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc++_test_config\grpc++_test_config.vcxproj">
+      <Project>{3F7D093D-11F9-C4BC-BEB7-18EB28E3F290}</Project>
     </ProjectReference>
   </ItemGroup>
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
diff --git a/vsprojects/vcxproj/grpc_cli_libs/grpc_cli_libs.vcxproj.filters b/vsprojects/vcxproj/grpc_cli_libs/grpc_cli_libs.vcxproj.filters
index 4add8ed..b2128c2 100644
--- a/vsprojects/vcxproj/grpc_cli_libs/grpc_cli_libs.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc_cli_libs/grpc_cli_libs.vcxproj.filters
@@ -4,6 +4,12 @@
     <ClCompile Include="$(SolutionDir)\..\test\cpp\util\cli_call.cc">
       <Filter>test\cpp\util</Filter>
     </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\test\cpp\util\cli_credentials.cc">
+      <Filter>test\cpp\util</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\test\cpp\util\grpc_tool.cc">
+      <Filter>test\cpp\util</Filter>
+    </ClCompile>
     <ClCompile Include="$(SolutionDir)\..\test\cpp\util\proto_file_parser.cc">
       <Filter>test\cpp\util</Filter>
     </ClCompile>
@@ -15,6 +21,15 @@
     <ClInclude Include="$(SolutionDir)\..\test\cpp\util\cli_call.h">
       <Filter>test\cpp\util</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\test\cpp\util\cli_credentials.h">
+      <Filter>test\cpp\util</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\test\cpp\util\config_grpc_cli.h">
+      <Filter>test\cpp\util</Filter>
+    </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\test\cpp\util\grpc_tool.h">
+      <Filter>test\cpp\util</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\test\cpp\util\proto_file_parser.h">
       <Filter>test\cpp\util</Filter>
     </ClInclude>
diff --git a/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj b/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj
index 84a71d2..80dd6b2 100644
--- a/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj
+++ b/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj
@@ -152,6 +152,7 @@
     <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\grpc_security_constants.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\status.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\byte_buffer.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\byte_buffer_reader.h" />
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 18fe926..8dc28d1 100644
--- a/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj.filters
@@ -336,6 +336,9 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\grpc_posix.h">
       <Filter>include\grpc</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\grpc_security_constants.h">
+      <Filter>include\grpc</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\include\grpc\status.h">
       <Filter>include\grpc</Filter>
     </ClInclude>
diff --git a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj
index 7a5f858..fffb409 100644
--- a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj
+++ b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj
@@ -263,6 +263,7 @@
     <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\grpc_security_constants.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\status.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\byte_buffer.h" />
     <ClInclude Include="$(SolutionDir)\..\include\grpc\impl\codegen\byte_buffer_reader.h" />
diff --git a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters
index 99db98e..8c8afb6 100644
--- a/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters
@@ -501,6 +501,9 @@
     <ClInclude Include="$(SolutionDir)\..\include\grpc\grpc_posix.h">
       <Filter>include\grpc</Filter>
     </ClInclude>
+    <ClInclude Include="$(SolutionDir)\..\include\grpc\grpc_security_constants.h">
+      <Filter>include\grpc</Filter>
+    </ClInclude>
     <ClInclude Include="$(SolutionDir)\..\include\grpc\status.h">
       <Filter>include\grpc</Filter>
     </ClInclude>
diff --git a/vsprojects/vcxproj/test/grpc_cli/grpc_cli.vcxproj b/vsprojects/vcxproj/test/grpc_cli/grpc_cli.vcxproj
index 9c8cdc5..78a0a63 100644
--- a/vsprojects/vcxproj/test/grpc_cli/grpc_cli.vcxproj
+++ b/vsprojects/vcxproj/test/grpc_cli/grpc_cli.vcxproj
@@ -167,12 +167,6 @@
     <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>
-    <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++_reflection\grpc++_reflection.vcxproj">
       <Project>{5F575402-3F89-5D1A-6910-9DB8BF5D2BAB}</Project>
     </ProjectReference>
@@ -182,9 +176,6 @@
     <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>
diff --git a/vsprojects/vcxproj/test/grpc_tool_test/grpc_tool_test.vcxproj b/vsprojects/vcxproj/test/grpc_tool_test/grpc_tool_test.vcxproj
new file mode 100644
index 0000000..c6f65aa
--- /dev/null
+++ b/vsprojects/vcxproj/test/grpc_tool_test/grpc_tool_test.vcxproj
@@ -0,0 +1,286 @@
+<?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>{F00D82D4-E988-6D2F-F0B9-9E82BCC2A2B2}</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>grpc_tool_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>grpc_tool_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)\..\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)\..\test\cpp\util\string_ref_helper.h" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="$(SolutionDir)\..\src\proto\grpc\testing\echo.pb.cc">
+    </ClCompile>
+    <ClInclude Include="$(SolutionDir)\..\src\proto\grpc\testing\echo.pb.h">
+    </ClInclude>
+    <ClCompile Include="$(SolutionDir)\..\src\proto\grpc\testing\echo.grpc.pb.cc">
+    </ClCompile>
+    <ClInclude Include="$(SolutionDir)\..\src\proto\grpc\testing\echo.grpc.pb.h">
+    </ClInclude>
+    <ClCompile Include="$(SolutionDir)\..\src\proto\grpc\testing\echo_messages.pb.cc">
+    </ClCompile>
+    <ClInclude Include="$(SolutionDir)\..\src\proto\grpc\testing\echo_messages.pb.h">
+    </ClInclude>
+    <ClCompile Include="$(SolutionDir)\..\src\proto\grpc\testing\echo_messages.grpc.pb.cc">
+    </ClCompile>
+    <ClInclude Include="$(SolutionDir)\..\src\proto\grpc\testing\echo_messages.grpc.pb.h">
+    </ClInclude>
+    <ClCompile Include="$(SolutionDir)\..\test\cpp\util\grpc_tool_test.cc">
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\test\cpp\util\string_ref_helper.cc">
+    </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++_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>{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/grpc_tool_test/grpc_tool_test.vcxproj.filters b/vsprojects/vcxproj/test/grpc_tool_test/grpc_tool_test.vcxproj.filters
new file mode 100644
index 0000000..731eb2e
--- /dev/null
+++ b/vsprojects/vcxproj/test/grpc_tool_test/grpc_tool_test.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\proto\grpc\testing\echo.proto">
+      <Filter>src\proto\grpc\testing</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\src\proto\grpc\testing\echo_messages.proto">
+      <Filter>src\proto\grpc\testing</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\test\cpp\util\grpc_tool_test.cc">
+      <Filter>test\cpp\util</Filter>
+    </ClCompile>
+    <ClCompile Include="$(SolutionDir)\..\test\cpp\util\string_ref_helper.cc">
+      <Filter>test\cpp\util</Filter>
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <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)\..\test\cpp\util\string_ref_helper.h">
+      <Filter>test\cpp\util</Filter>
+    </ClInclude>
+  </ItemGroup>
+
+  <ItemGroup>
+    <Filter Include="include">
+      <UniqueIdentifier>{89fed779-17c5-23da-c8a2-9e868ff34480}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="include\grpc">
+      <UniqueIdentifier>{96e4a1a8-0b91-1a6d-ae4d-ddf33abb93c0}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="include\grpc++">
+      <UniqueIdentifier>{1d9dcc6f-7c1b-cdc3-4c35-73d5968dfd92}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="include\grpc++\impl">
+      <UniqueIdentifier>{5eca7690-973a-c8ed-84d6-5325f8de43ac}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="include\grpc++\impl\codegen">
+      <UniqueIdentifier>{5789073e-5b84-0ec9-af06-47866647874d}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="include\grpc++\impl\codegen\security">
+      <UniqueIdentifier>{d3f3293f-204f-7771-fcdf-de673f6b06b6}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="include\grpc\impl">
+      <UniqueIdentifier>{7e90f37b-f9cc-0725-b2c1-12aa7d4809ba}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="include\grpc\impl\codegen">
+      <UniqueIdentifier>{7e4b71ef-8125-6446-bfc1-9bc90beed59c}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src">
+      <UniqueIdentifier>{169774bd-5c6c-6827-66a4-326b4aef44d6}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\proto">
+      <UniqueIdentifier>{1b609b37-ef2a-e5eb-e1ba-ad9e79c77438}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\proto\grpc">
+      <UniqueIdentifier>{cd1e35d8-8a61-62fe-6ce1-c8936872d1ef}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="src\proto\grpc\testing">
+      <UniqueIdentifier>{f7ee4df5-1f47-1e7f-c91e-350382c1b729}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="test">
+      <UniqueIdentifier>{f2166b83-6b0b-d53b-b58b-627bd9efcad2}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="test\cpp">
+      <UniqueIdentifier>{bbe36cbc-7fbe-2817-0bd0-d03726f323e6}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="test\cpp\util">
+      <UniqueIdentifier>{e106cd7b-cfa0-0645-f1a9-2acedc23afe7}</UniqueIdentifier>
+    </Filter>
+  </ItemGroup>
+</Project>
+